From 1129df533d912278413ec9dea6a4f155933d9b96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Kuzn=C3=ADk?= Date: Wed, 17 Jun 2020 10:20:10 +0100 Subject: [PATCH] ITS#8701 Expose account usability in libldap --- include/ldap.h | 39 ++++++++ libraries/libldap/Makefile.in | 6 +- libraries/libldap/account_usability.c | 128 ++++++++++++++++++++++++++ 3 files changed, 171 insertions(+), 2 deletions(-) create mode 100644 libraries/libldap/account_usability.c diff --git a/include/ldap.h b/include/ldap.h index 62f8cbcee6..a009ec144c 100644 --- a/include/ldap.h +++ b/include/ldap.h @@ -380,6 +380,18 @@ typedef struct ldapcontrol { #define LDAP_CONTROL_VLVREQUEST "2.16.840.1.113730.3.4.9" #define LDAP_CONTROL_VLVRESPONSE "2.16.840.1.113730.3.4.10" +/* Sun's analogue to ppolicy */ +#define LDAP_CONTROL_X_ACCOUNT_USABILITY "1.3.6.1.4.1.42.2.27.9.5.8" + +#define LDAP_TAG_X_ACCOUNT_USABILITY_AVAILABLE ((ber_tag_t) 0x80U) /* primitive + 0 */ +#define LDAP_TAG_X_ACCOUNT_USABILITY_NOT_AVAILABLE ((ber_tag_t) 0xA1U) /* constructed + 1 */ + +#define LDAP_TAG_X_ACCOUNT_USABILITY_INACTIVE ((ber_tag_t) 0x80U) /* primitive + 0 */ +#define LDAP_TAG_X_ACCOUNT_USABILITY_RESET ((ber_tag_t) 0x81U) /* primitive + 1 */ +#define LDAP_TAG_X_ACCOUNT_USABILITY_EXPIRED ((ber_tag_t) 0x82U) /* primitive + 2 */ +#define LDAP_TAG_X_ACCOUNT_USABILITY_REMAINING_GRACE ((ber_tag_t) 0x83U) /* primitive + 3 */ +#define LDAP_TAG_X_ACCOUNT_USABILITY_UNTIL_UNLOCK ((ber_tag_t) 0x84U) /* primitive + 4 */ + /* LDAP Unsolicited Notifications */ #define LDAP_NOTICE_OF_DISCONNECTION "1.3.6.1.4.1.1466.20036" /* RFC 4511 */ #define LDAP_NOTICE_DISCONNECT LDAP_NOTICE_OF_DISCONNECTION @@ -2685,6 +2697,33 @@ ldap_parse_entrychange_control LDAP_P(( int *chgnumpresentp, long *chgnump )); +/* in account_usability.c */ + +LDAP_F( int ) +ldap_create_accountusability_control LDAP_P(( + LDAP *ld, + LDAPControl **ctrlp )); + +typedef struct LDAPAccountUsabilityMoreInfo { + ber_int_t inactive; + ber_int_t reset; + ber_int_t expired; + ber_int_t remaining_grace; + ber_int_t seconds_before_unlock; +} LDAPAccountUsabilityMoreInfo; + +typedef union LDAPAccountUsability { + ber_int_t seconds_remaining; + LDAPAccountUsabilityMoreInfo more_info; +} LDAPAccountUsability; + +LDAP_F( int ) +ldap_parse_accountusability_control LDAP_P(( + LDAP *ld, + LDAPControl *ctrl, + int *availablep, + LDAPAccountUsability *usabilityp )); + /* * high level LDIF to LDAP structure support diff --git a/libraries/libldap/Makefile.in b/libraries/libldap/Makefile.in index 5ae45de007..1bb7518093 100644 --- a/libraries/libldap/Makefile.in +++ b/libraries/libldap/Makefile.in @@ -30,7 +30,8 @@ SRCS = bind.c open.c result.c error.c compare.c search.c \ turn.c ppolicy.c dds.c txn.c ldap_sync.c stctrl.c \ assertion.c deref.c ldifutil.c ldif.c fetch.c lbase64.c \ msctrl.c psearchctrl.c threads.c rdwr.c tpool.c rq.c \ - thr_posix.c thr_thr.c thr_nt.c thr_pth.c thr_debug.c + thr_posix.c thr_thr.c thr_nt.c thr_pth.c thr_debug.c \ + account_usability.c OBJS = bind.lo open.lo result.lo error.lo compare.lo search.lo \ controls.lo messages.lo references.lo extended.lo cyrus.lo \ @@ -45,7 +46,8 @@ OBJS = bind.lo open.lo result.lo error.lo compare.lo search.lo \ turn.lo ppolicy.lo dds.lo txn.lo ldap_sync.lo stctrl.lo \ assertion.lo deref.lo ldifutil.lo ldif.lo fetch.lo lbase64.lo \ msctrl.lo psearchctrl.lo threads.lo rdwr.lo tpool.lo rq.lo \ - thr_posix.lo thr_thr.lo thr_nt.lo thr_pth.lo thr_debug.lo + thr_posix.lo thr_thr.lo thr_nt.lo thr_pth.lo thr_debug.lo \ + account_usability.lo LDAP_INCDIR= ../../include LDAP_LIBDIR= ../../libraries diff --git a/libraries/libldap/account_usability.c b/libraries/libldap/account_usability.c new file mode 100644 index 0000000000..77f3fb03e1 --- /dev/null +++ b/libraries/libldap/account_usability.c @@ -0,0 +1,128 @@ +/* $OpenLDAP$ */ +/* This work is part of OpenLDAP Software . + * + * Copyright 2004-2020 The OpenLDAP Foundation. + * Portions Copyright 2004 Hewlett-Packard Company. + * Portions Copyright 2004 Howard Chu, Symas Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. + * + * A copy of this license is available in the file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * . + */ +/* ACKNOWLEDGEMENTS: + * This work was developed by Howard Chu for inclusion in + * OpenLDAP Software, based on prior work by Neil Dunbar (HP). + * This work was sponsored by the Hewlett-Packard Company. + */ + +#include "portable.h" + +#include "ldap-int.h" + +#ifdef LDAP_CONTROL_X_ACCOUNT_USABILITY + +int +ldap_create_accountusability_control( LDAP *ld, + LDAPControl **ctrlp ) +{ + assert( ld != NULL ); + assert( LDAP_VALID( ld ) ); + assert( ctrlp != NULL ); + + ld->ld_errno = ldap_control_create( LDAP_CONTROL_X_ACCOUNT_USABILITY, + 0, NULL, 0, ctrlp ); + + return ld->ld_errno; +} + +int +ldap_parse_accountusability_control( + LDAP *ld, + LDAPControl *ctrl, + int *availablep, + LDAPAccountUsability *usabilityp ) +{ + BerElement *ber; + int available = 0; + ber_tag_t tag; + ber_len_t berLen; + char *last; + + assert( ld != NULL ); + assert( LDAP_VALID( ld ) ); + assert( ctrl != NULL ); + + if ( !ctrl->ldctl_value.bv_val ) { + ld->ld_errno = LDAP_DECODING_ERROR; + return(ld->ld_errno); + } + + /* Create a BerElement from the berval returned in the control. */ + ber = ber_init(&ctrl->ldctl_value); + + if (ber == NULL) { + ld->ld_errno = LDAP_NO_MEMORY; + return(ld->ld_errno); + } + + tag = ber_peek_tag( ber, &berLen ); + + if ( tag == LDAP_TAG_X_ACCOUNT_USABILITY_AVAILABLE ) { + available = 1; + + if ( usabilityp != NULL ) { + if (ber_get_int( ber, &usabilityp->seconds_remaining ) == LBER_DEFAULT) goto exit; + } + } else if ( tag == LDAP_TAG_X_ACCOUNT_USABILITY_NOT_AVAILABLE ) { + available = 0; + LDAPAccountUsabilityMoreInfo more_info = { 0, 0, 0, -1, -1 }; + + ber_skip_tag( ber, &berLen ); + while ( (tag = ber_peek_tag( ber, &berLen )) != LBER_DEFAULT ) { + switch (tag) { + case LDAP_TAG_X_ACCOUNT_USABILITY_INACTIVE: + if (ber_get_boolean( ber, &more_info.inactive ) == LBER_DEFAULT) goto exit; + break; + case LDAP_TAG_X_ACCOUNT_USABILITY_RESET: + if (ber_get_boolean( ber, &more_info.reset ) == LBER_DEFAULT) goto exit; + break; + case LDAP_TAG_X_ACCOUNT_USABILITY_EXPIRED: + if (ber_get_boolean( ber, &more_info.expired ) == LBER_DEFAULT) goto exit; + break; + case LDAP_TAG_X_ACCOUNT_USABILITY_REMAINING_GRACE: + if (ber_get_int( ber, &more_info.remaining_grace ) == LBER_DEFAULT) goto exit; + break; + case LDAP_TAG_X_ACCOUNT_USABILITY_UNTIL_UNLOCK: + if (ber_get_int( ber, &more_info.seconds_before_unlock ) == LBER_DEFAULT) goto exit; + break; + default: + goto exit; + } + } + if ( usabilityp != NULL ) { + usabilityp->more_info = more_info; + } + } else { + goto exit; + } + if ( availablep != NULL ) { + *availablep = available; + } + + ber_free(ber, 1); + + ld->ld_errno = LDAP_SUCCESS; + return(ld->ld_errno); + + exit: + ber_free(ber, 1); + ld->ld_errno = LDAP_DECODING_ERROR; + return(ld->ld_errno); +} + +#endif /* LDAP_CONTROL_X_ACCOUNT_USABILITY */