From 4dede094f422ceaa735ec08e43bb7e8f6d63581b Mon Sep 17 00:00:00 2001 From: "anton.bobrov%sun.com" Date: Mon, 13 Nov 2006 13:52:52 +0000 Subject: [PATCH] Bug 357668: merging Sun and Mozilla libldap: bring new srcs unique to Sun branch --- directory/c-sdk/ldap/include/ldap-extension.h | 101 +++++- directory/c-sdk/ldap/include/ldaprot.h | 2 +- directory/c-sdk/ldap/libraries/libldap.ex | 27 +- .../c-sdk/ldap/libraries/libldap/Makefile.in | 7 +- .../ldap/libraries/libldap/authzidctrl.c | 157 +++++++++ .../c-sdk/ldap/libraries/libldap/cldap.c | 2 +- .../c-sdk/ldap/libraries/libldap/control.c | 25 +- .../libldap/geteffectiverightsctrl.c | 109 ++++++ directory/c-sdk/ldap/libraries/libldap/open.c | 2 +- .../c-sdk/ldap/libraries/libldap/pwmodext.c | 4 +- .../c-sdk/ldap/libraries/libldap/pwpctrl.c | 315 ++++++++++++++++++ .../ldap/libraries/libldap/userstatusctrl.c | 229 +++++++++++++ .../c-sdk/ldap/libraries/libldap/whoami.c | 132 ++++++++ 13 files changed, 1096 insertions(+), 16 deletions(-) create mode 100644 directory/c-sdk/ldap/libraries/libldap/authzidctrl.c create mode 100644 directory/c-sdk/ldap/libraries/libldap/geteffectiverightsctrl.c create mode 100644 directory/c-sdk/ldap/libraries/libldap/pwpctrl.c create mode 100644 directory/c-sdk/ldap/libraries/libldap/userstatusctrl.c create mode 100644 directory/c-sdk/ldap/libraries/libldap/whoami.c diff --git a/directory/c-sdk/ldap/include/ldap-extension.h b/directory/c-sdk/ldap/include/ldap-extension.h index a2869e744104..7f4fb0d5432b 100644 --- a/directory/c-sdk/ldap/include/ldap-extension.h +++ b/directory/c-sdk/ldap/include/ldap-extension.h @@ -46,8 +46,7 @@ extern "C" { #define LDAP_PORT_MAX 65535 /* API extension */ #define LDAP_VERSION1 1 /* API extension */ -#define LDAP_VERSION LDAP_VERSION2 /* API extension */ - +#define LDAP_VERSION LDAP_VERSION3 /* API extension */ /* * C LDAP features we support that are not (yet) part of the LDAP C API @@ -105,20 +104,29 @@ extern "C" { #define LDAP_CONTROL_PROXIEDAUTH "2.16.840.1.113730.3.4.18" /* version 2 */ +/* Authorization Identity Request and Response Controls */ +#define LDAP_CONTROL_AUTHZID_REQ "2.16.840.1.113730.3.4.16" +#define LDAP_CONTROL_AUTHZID_RES "2.16.840.1.113730.3.4.15" + /* Authentication request and response controls */ -#define LDAP_CONTROL_AUTH_REQUEST "2.16.840.1.113730.3.4.16" -#define LDAP_CONTROL_AUTH_RESPONSE "2.16.840.1.113730.3.4.15" +#define LDAP_CONTROL_AUTH_REQUEST LDAP_CONTROL_AUTHZID_REQ +#define LDAP_CONTROL_AUTH_RESPONSE LDAP_CONTROL_AUTHZID_RES /* Password information sent back to client */ #define LDAP_CONTROL_PWEXPIRED "2.16.840.1.113730.3.4.4" #define LDAP_CONTROL_PWEXPIRING "2.16.840.1.113730.3.4.5" -/* Proposed standard password policy controls */ -#define LDAP_X_CONTROL_PWPOLICY_REQUEST "1.3.6.1.4.1.42.2.27.8.5.1" -#define LDAP_X_CONTROL_PWPOLICY_RESPONSE "1.3.6.1.4.1.42.2.27.8.5.1" +/* Password Policy Control */ +#define LDAP_CONTROL_PASSWD_POLICY "1.3.6.1.4.1.42.2.27.8.5.1" + +/* Password Policy Control compatibility macros */ +#define LDAP_X_CONTROL_PWPOLICY_REQUEST LDAP_CONTROL_PASSWD_POLICY +#define LDAP_X_CONTROL_PWPOLICY_RESPONSE LDAP_CONTROL_PASSWD_POLICY +#define LDAP_CONTROL_PASSWORDPOLICYREQUEST LDAP_CONTROL_PASSWD_POLICY +#define LDAP_CONTROL_PASSWORDPOLICYRESPONSE LDAP_CONTROL_PASSWD_POLICY /* Password Modify Extended Operation */ -#define LDAP_CONTROL_EXT_PASSWD_MODIFY "1.3.6.1.4.1.4203.1.11.1" +#define LDAP_EXOP_MODIFY_PASSWD "1.3.6.1.4.1.4203.1.11.1" /* Suppress virtual/inherited attribute values */ #define LDAP_CONTROL_REAL_ATTRS_ONLY "2.16.840.1.113730.3.4.17" @@ -126,9 +134,20 @@ extern "C" { /* Only return virtual/inherited attribute values */ #define LDAP_CONTROL_VIRTUAL_ATTRS_ONLY "2.16.840.1.113730.3.4.19" +/* getEffectiveRights request */ +#define LDAP_CONTROL_GETEFFECTIVERIGHTS_REQUEST "1.3.6.1.4.1.42.2.27.9.5.2" + +/* Password Policy Control to get account availability */ +#define LDAP_CONTROL_ACCOUNT_USABLE "1.3.6.1.4.1.42.2.27.9.5.8" + +/* "Who am I?" Extended Operation */ +#define LDAP_EXOP_WHO_AM_I "1.3.6.1.4.1.4203.1.11.3" LDAP_API(void) LDAP_CALL ldap_ber_free( BerElement *ber, int freebuf ); +LDAP_API(LDAPControl *) LDAP_CALL ldap_find_control( const char *oid, + LDAPControl **ctrls ); + /* * Server side sorting of search results (an LDAPv3 extension -- * LDAP_API_FEATURE_SERVER_SIDE_SORT) @@ -139,6 +158,39 @@ typedef struct LDAPsortkey { /* structure for a sort-key */ int sk_reverseorder; } LDAPsortkey; +/* where LDAP_CONTROL_ACCOUNT_USABLE control parse results */ +typedef struct LDAPuserstatus { /* user account availability */ + unsigned int us_available; /* availability status */ +#define LDAP_US_ACCOUNT_USABLE 1 +#define LDAP_US_ACCOUNT_NOT_USABLE 0 + int us_expire; /* will expire in seconds */ + int us_inactive; /* boolean inactivation status */ +#define LDAP_US_ACCOUNT_ACTIVE 0 +#define LDAP_US_ACCOUNT_INACTIVE 1 + int us_reset; /* boolean password reset */ +#define LDAP_US_ACCOUNT_NOT_RESET 0 +#define LDAP_US_ACCOUNT_RESET 1 + int us_expired; /* boolean password expired */ +#define LDAP_US_ACCOUNT_NOT_EXPIRED 0 +#define LDAP_US_ACCOUNT_EXPIRED 1 + int us_remaining; /* remaining logins */ + int us_seconds; /* will unlock in seconds */ +} LDAPuserstatus; + +/* LDAP_CONTROL_PASSWD_POLICY results */ +typedef enum passpolicyerror_enum { + PP_passwordExpired = 0, + PP_accountLocked = 1, + PP_changeAfterReset = 2, + PP_passwordModNotAllowed = 3, + PP_mustSupplyOldPassword = 4, + PP_insufficientPasswordQuality = 5, + PP_passwordTooShort = 6, + PP_passwordTooYoung = 7, + PP_passwordInHistory = 8, + PP_noError = 65535 +} LDAPPasswordPolicyError; + LDAP_API(int) LDAP_CALL ldap_create_sort_control( LDAP *ld, LDAPsortkey **sortKeyList, const char ctl_iscritical, LDAPControl **ctrlp ); @@ -149,6 +201,39 @@ LDAP_API(void) LDAP_CALL ldap_free_sort_keylist( LDAPsortkey **sortKeyList ); LDAP_API(int) LDAP_CALL ldap_create_sort_keylist( LDAPsortkey ***sortKeyList, const char *string_rep ); +LDAP_API(int) LDAP_CALL ldap_create_userstatus_control( + LDAP *ld, const char ctl_iscritical, LDAPControl **ctrlp ); +LDAP_API(int) LDAP_CALL ldap_parse_userstatus_control( LDAP *ld, + LDAPControl **ctrlp, LDAPuserstatus *us ); + +LDAP_API(int) LDAP_CALL ldap_create_passwordpolicy_control( LDAP *ld, + LDAPControl **ctrlp ); +LDAP_API(int) LDAP_CALL ldap_create_passwordpolicy_control_ext( LDAP *ld, + const char ctl_iscritical, LDAPControl **ctrlp ); +LDAP_API(int) LDAP_CALL ldap_parse_passwordpolicy_control( LDAP *ld, + LDAPControl *ctrlp, ber_int_t *expirep, ber_int_t *gracep, + LDAPPasswordPolicyError *errorp ); +LDAP_API(int) LDAP_CALL ldap_parse_passwordpolicy_control_ext ( LDAP *ld, + LDAPControl **ctrlp, ber_int_t *expirep, ber_int_t *gracep, + LDAPPasswordPolicyError *errorp ); +LDAP_API(const char *) LDAP_CALL ldap_passwordpolicy_err2txt( + LDAPPasswordPolicyError err ); + +LDAP_API(int) LDAP_CALL ldap_create_authzid_control( LDAP *ld, + const char ctl_iscritical, LDAPControl **ctrlp ); +LDAP_API(int) LDAP_CALL ldap_parse_authzid_control( LDAP *ld, + LDAPControl **ctrlp, char **authzid ); + +LDAP_API(int) LDAP_CALL ldap_whoami( LDAP *ld, LDAPControl **serverctrls, + LDAPControl **clientctrls, int *msgidp ); +LDAP_API(int) LDAP_CALL ldap_whoami_s( LDAP *ld, struct berval **authzid, + LDAPControl **serverctrls, LDAPControl **clientctrls ); +LDAP_API(int) LDAP_CALL ldap_parse_whoami( LDAP *ld, LDAPMessage *result, + struct berval **authzid ); + +LDAP_API(int) LDAP_CALL ldap_create_geteffectiveRights_control( LDAP *ld, + const char *authzid, const char **attrlist, const char ctl_iscritical, + LDAPControl **ctrlp ); /* * Virtual list view (an LDAPv3 extension -- LDAP_API_FEATURE_VIRTUAL_LIST_VIEW) diff --git a/directory/c-sdk/ldap/include/ldaprot.h b/directory/c-sdk/ldap/include/ldaprot.h index 6da9205b9f54..98aec13c8df1 100644 --- a/directory/c-sdk/ldap/include/ldaprot.h +++ b/directory/c-sdk/ldap/include/ldaprot.h @@ -45,7 +45,7 @@ extern "C" { #define LDAP_VERSION1 1 #define LDAP_VERSION2 2 #define LDAP_VERSION3 3 -#define LDAP_VERSION LDAP_VERSION2 +#define LDAP_VERSION LDAP_VERSION3 #define COMPAT20 #define COMPAT30 diff --git a/directory/c-sdk/ldap/libraries/libldap.ex b/directory/c-sdk/ldap/libraries/libldap.ex index 0075ca32226c..963ea0feb2be 100644 --- a/directory/c-sdk/ldap/libraries/libldap.ex +++ b/directory/c-sdk/ldap/libraries/libldap.ex @@ -177,6 +177,10 @@ 150 ber_sockbuf_free 151 ber_get_next_buffer_ext 152 ber_svecfree +153 ber_get_buf_datalen +154 ber_get_buf_databegin +155 ber_stack_init +156 ber_sockbuf_free_data 200 ldap_memfree 201 ldap_ber_free @@ -297,7 +301,21 @@ 533 ldap_x_calloc 534 ldap_x_realloc 535 ldap_x_free -536 ldap_create_proxiedauth_control +# +536 ldap_create_proxiedauth_control +# +537 ldap_create_geteffectiveRights_control +# +538 ldap_find_control +# +550 ldap_create_userstatus_control +551 ldap_parse_userstatus_control +# +560 ldap_create_passwordpolicy_control +561 ldap_create_passwordpolicy_control_ext +562 ldap_parse_passwordpolicy_control +563 ldap_parse_passwordpolicy_control_ext +564 ldap_passwordpolicy_err2txt # 570 ldap_passwd 571 ldap_parse_passwd @@ -306,6 +324,13 @@ 580 ldap_delete_result_entry 581 ldap_add_result_entry # +590 ldap_whoami +591 ldap_parse_whoami +592 ldap_whoami_s +# +600 ldap_create_authzid_control +601 ldap_parse_authzid_control +# 1000 ldap_memcache_init 1001 ldap_memcache_set 1002 ldap_memcache_get diff --git a/directory/c-sdk/ldap/libraries/libldap/Makefile.in b/directory/c-sdk/ldap/libraries/libldap/Makefile.in index 3c3c2c0d9bb0..31483edb728b 100644 --- a/directory/c-sdk/ldap/libraries/libldap/Makefile.in +++ b/directory/c-sdk/ldap/libraries/libldap/Makefile.in @@ -47,6 +47,7 @@ include $(topsrcdir)/build.mk SRCS = abandon.c \ add.c \ + authzidctrl.c \ bind.c \ cache.c \ charray.c \ @@ -66,6 +67,7 @@ SRCS = abandon.c \ getattr.c \ getdn.c \ getdxbyname.c \ + geteffectiverightsctrl.c \ getentry.c \ getfilter.c \ getoption.c \ @@ -78,6 +80,7 @@ SRCS = abandon.c \ proxyauthctrl.c \ psearch.c \ pwmodext.c \ + pwpctrl.c \ referral.c \ regex.c \ rename.c \ @@ -96,8 +99,10 @@ SRCS = abandon.c \ unbind.c \ unescape.c \ url.c \ + userstatusctrl.c \ utf8.c \ - vlistctrl.c + vlistctrl.c \ + whoami.c ifeq ($(HAVE_SASL), 1) SRCS += saslio.c diff --git a/directory/c-sdk/ldap/libraries/libldap/authzidctrl.c b/directory/c-sdk/ldap/libraries/libldap/authzidctrl.c new file mode 100644 index 000000000000..31f342ed215a --- /dev/null +++ b/directory/c-sdk/ldap/libraries/libldap/authzidctrl.c @@ -0,0 +1,157 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Sun LDAP C SDK. + * + * The Initial Developer of the Original Code is Sun Microsystems, Inc. + * + * Portions created by Sun Microsystems, Inc are Copyright (C) 2005 + * Sun Microsystems, Inc. All Rights Reserved. + * + * Contributor(s): abobrov@sun.com + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "ldap-int.h" + +/* ldap_create_authzid_control: + +Parameters are + +ld LDAP pointer to the desired connection + +ctl_iscritical Indicates whether the control is critical of not. + If this field is non-zero, the operation will only be + carried out if the control is recognized by the server + and/or client + +ctrlp the address of a place to put the constructed control +*/ + +int +LDAP_CALL +ldap_create_authzid_control ( + LDAP *ld, + const char ctl_iscritical, + LDAPControl **ctrlp + ) +{ + int rc; + + if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) { + return( LDAP_PARAM_ERROR ); + } + + if ( ctrlp == NULL ) { + LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL ); + return ( LDAP_PARAM_ERROR ); + } + + rc = nsldapi_build_control( LDAP_CONTROL_AUTHZID_REQ, + NULL, NULL, ctl_iscritical, ctrlp ); + + LDAP_SET_LDERRNO( ld, rc, NULL, NULL ); + return( rc ); +} + +/* ldap_parse_authzid_control: + +Parameters are + +ld LDAP pointer to the desired connection + +ctrlp An array of controls obtained from calling + ldap_parse_result on the set of results + returned by the server + +authzid authorization identity, as defined in + RFC 2829, section 9. +*/ + +int +LDAP_CALL +ldap_parse_authzid_control ( + LDAP *ld, + LDAPControl **ctrlp, + char **authzid + ) +{ + int i, foundAUTHZIDControl; + char *authzidp = NULL; + LDAPControl *AUTHZIDCtrlp = NULL; + + if ( !NSLDAPI_VALID_LDAP_POINTER( ld ) ) { + return( LDAP_PARAM_ERROR ); + } + + /* find the control in the list of controls if it exists */ + if ( ctrlp == NULL ) { + LDAP_SET_LDERRNO( ld, LDAP_CONTROL_NOT_FOUND, NULL, NULL ); + return ( LDAP_CONTROL_NOT_FOUND ); + } + foundAUTHZIDControl = 0; + for ( i = 0; (( ctrlp[i] != NULL ) && ( !foundAUTHZIDControl )); i++ ) { + foundAUTHZIDControl = !strcmp( ctrlp[i]->ldctl_oid, + LDAP_CONTROL_AUTHZID_RES ); + } + + /* + * The control is only included in a bind response if the resultCode + * for the bind operation is success. + */ + if ( !foundAUTHZIDControl ) { + LDAP_SET_LDERRNO( ld, LDAP_CONTROL_NOT_FOUND, NULL, NULL ); + return ( LDAP_CONTROL_NOT_FOUND ); + } else { + /* let local var point to the control */ + AUTHZIDCtrlp = ctrlp[i-1]; + } + + /* + * If the bind request succeeded and resulted in an identity (not anonymous), + * the controlValue contains the authorization identity (authzid), as + * defined in [AUTH] section 9, granted to the requestor. If the bind + * request resulted in an anonymous association, the controlValue field + * is a string of zero length. If the bind request resulted in more + * than one authzid, the primary authzid is returned in the controlValue + * field. + */ + if ( AUTHZIDCtrlp && AUTHZIDCtrlp->ldctl_value.bv_val && + AUTHZIDCtrlp->ldctl_value.bv_len ) { + authzidp = ( (char *)NSLDAPI_MALLOC( + ( AUTHZIDCtrlp->ldctl_value.bv_len + 1 ) ) ); + if ( authzidp == NULL ) { + LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL ); + return( LDAP_NO_MEMORY ); + } + STRLCPY( authzidp, AUTHZIDCtrlp->ldctl_value.bv_val, + ( AUTHZIDCtrlp->ldctl_value.bv_len + 1 ) ); + *authzid = authzidp; + } else { + authzid = NULL; + } + + return( LDAP_SUCCESS ); +} diff --git a/directory/c-sdk/ldap/libraries/libldap/cldap.c b/directory/c-sdk/ldap/libraries/libldap/cldap.c index 762e4e04e6e3..829d34c287e1 100644 --- a/directory/c-sdk/ldap/libraries/libldap/cldap.c +++ b/directory/c-sdk/ldap/libraries/libldap/cldap.c @@ -152,7 +152,7 @@ cldap_open( char *host, int port ) } ld->ld_sbp->sb_sd = s; ld->ld_sbp->sb_naddr = 0; - ld->ld_version = LDAP_VERSION; + ld->ld_version = LDAP_VERSION2; sock.sin_family = AF_INET; sock.sin_port = htons( port ); diff --git a/directory/c-sdk/ldap/libraries/libldap/control.c b/directory/c-sdk/ldap/libraries/libldap/control.c index 7599c3fe5608..2113cce3ac8d 100644 --- a/directory/c-sdk/ldap/libraries/libldap/control.c +++ b/directory/c-sdk/ldap/libraries/libldap/control.c @@ -303,7 +303,30 @@ ldap_controls_free( LDAPControl **ctrls ) } } - +LDAPControl * +LDAP_CALL +ldap_find_control( const char *oid, LDAPControl **ctrls ) +{ + int i, foundControl; + LDAPControl *Ctrlp = NULL; + + /* find the control in the list of controls if it exists */ + if ( ctrls == NULL ) { + return ( NULL ); + } + foundControl = 0; + for ( i = 0; (( ctrls[i] != NULL ) && ( !foundControl )); i++ ) { + foundControl = !strcmp( ctrls[i]->ldctl_oid, oid ); + } + if ( !foundControl ) { + return ( NULL ); + } else { + /* let local var point to the control */ + Ctrlp = ctrls[i-1]; + } + + return( Ctrlp ); +} #if 0 LDAPControl ** diff --git a/directory/c-sdk/ldap/libraries/libldap/geteffectiverightsctrl.c b/directory/c-sdk/ldap/libraries/libldap/geteffectiverightsctrl.c new file mode 100644 index 000000000000..f03fdc44165c --- /dev/null +++ b/directory/c-sdk/ldap/libraries/libldap/geteffectiverightsctrl.c @@ -0,0 +1,109 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Sun LDAP C SDK. + * + * The Initial Developer of the Original Code is Sun Microsystems, Inc. + * + * Portions created by Sun Microsystems, Inc are Copyright (C) 2005 + * Sun Microsystems, Inc. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "ldap-int.h" + +/* ldap_create_geteffectiveRights_control + + Create Effective Rights control. + + Parameters are + + ld LDAP pointer to the desired connection + + authzid RFC2829 section 9, eg "dn:". + NULL or empty string means get bound user's rights, + just "dn:" means get anonymous user's rights. + + attrlist additional attributes for which rights info is + requrested. NULL means "just the ones returned + with the search operation". + + ctl_iscritical Indicates whether the control is critical of not. If + this field is non-zero, the operation will only be car- + ried out if the control is recognized by the server + and/or client + + ctrlp the address of a place to put the constructed control +*/ + +int +LDAP_CALL +ldap_create_geteffectiveRights_control ( + LDAP *ld, + const char *authzid, + const char **attrlist, + const char ctl_iscritical, + LDAPControl **ctrlp +) +{ + BerElement *ber; + int rc; + + if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) { + return( LDAP_PARAM_ERROR ); + } + + if ( ctrlp == NULL ) { + LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL ); + return ( LDAP_PARAM_ERROR ); + } + if (NULL == authzid) + { + authzid = ""; + } + + /* create a ber package to hold the controlValue */ + if ( ( nsldapi_alloc_ber_with_options( ld, &ber ) ) != LDAP_SUCCESS ) { + LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL ); + return( LDAP_NO_MEMORY ); + } + + if ( LBER_ERROR == ber_printf( ber, "{s{v}}", authzid, attrlist ) ) { + LDAP_SET_LDERRNO( ld, LDAP_ENCODING_ERROR, NULL, NULL ); + ber_free( ber, 1 ); + return( LDAP_ENCODING_ERROR ); + } + + rc = nsldapi_build_control( LDAP_CONTROL_GETEFFECTIVERIGHTS_REQUEST, ber, 1, + ctl_iscritical, ctrlp ); + + LDAP_SET_LDERRNO( ld, rc, NULL, NULL ); + return( rc ); + +} + + diff --git a/directory/c-sdk/ldap/libraries/libldap/open.c b/directory/c-sdk/ldap/libraries/libldap/open.c index d4bf5b7c80b3..9007ee2d3dc8 100644 --- a/directory/c-sdk/ldap/libraries/libldap/open.c +++ b/directory/c-sdk/ldap/libraries/libldap/open.c @@ -398,7 +398,7 @@ nsldapi_initialize_defaults( void ) memset( &nsldapi_memalloc_fns, 0, sizeof( nsldapi_memalloc_fns )); memset( &nsldapi_ld_defaults, 0, sizeof( nsldapi_ld_defaults )); nsldapi_ld_defaults.ld_options = LDAP_BITOPT_REFERRALS; - nsldapi_ld_defaults.ld_version = LDAP_VERSION2; + nsldapi_ld_defaults.ld_version = LDAP_VERSION3; nsldapi_ld_defaults.ld_lberoptions = LBER_OPT_USE_DER; nsldapi_ld_defaults.ld_refhoplimit = LDAP_DEFAULT_REFHOPLIMIT; diff --git a/directory/c-sdk/ldap/libraries/libldap/pwmodext.c b/directory/c-sdk/ldap/libraries/libldap/pwmodext.c index d487d4b5af16..fd737c4a3fe4 100644 --- a/directory/c-sdk/ldap/libraries/libldap/pwmodext.c +++ b/directory/c-sdk/ldap/libraries/libldap/pwmodext.c @@ -130,8 +130,8 @@ ldap_passwd ( requestdata = NULL; } - rc = ldap_extended_operation( ld, LDAP_CONTROL_EXT_PASSWD_MODIFY, - requestdata, serverctrls, clientctrls, msgidp ); + rc = ldap_extended_operation( ld, LDAP_EXOP_MODIFY_PASSWD, requestdata, + serverctrls, clientctrls, msgidp ); /* the ber encoding is no longer needed */ if ( requestdata ) { diff --git a/directory/c-sdk/ldap/libraries/libldap/pwpctrl.c b/directory/c-sdk/ldap/libraries/libldap/pwpctrl.c new file mode 100644 index 000000000000..9607bf76c3e0 --- /dev/null +++ b/directory/c-sdk/ldap/libraries/libldap/pwpctrl.c @@ -0,0 +1,315 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Sun LDAP C SDK. + * + * The Initial Developer of the Original Code is Sun Microsystems, Inc. + * + * Portions created by Sun Microsystems, Inc are Copyright (C) 2005 + * Sun Microsystems, Inc. All Rights Reserved. + * + * Contributor(s): abobrov@sun.com + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "ldap-int.h" + +/* ldap_create_passwordpolicy_control: + +Parameters are + +ld LDAP pointer to the desired connection + +ctrlp the address of a place to put the constructed control +*/ + +int +LDAP_CALL +ldap_create_passwordpolicy_control ( + LDAP *ld, + LDAPControl **ctrlp + ) +{ + int rc; + + if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) { + return( LDAP_PARAM_ERROR ); + } + + if ( ctrlp == NULL ) { + LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL ); + return ( LDAP_PARAM_ERROR ); + } + + rc = nsldapi_build_control( LDAP_CONTROL_PASSWD_POLICY, + NULL, NULL, 0, ctrlp ); + + LDAP_SET_LDERRNO( ld, rc, NULL, NULL ); + return( rc ); +} + +/* ldap_create_passwordpolicy_control_ext: + +Parameters are + +ld LDAP pointer to the desired connection + +ctl_iscritical Indicates whether the control is critical of not. If + this field is non-zero, the operation will only be car- + ried out if the control is recognized by the server + and/or client + +ctrlp the address of a place to put the constructed control +*/ + +int +LDAP_CALL +ldap_create_passwordpolicy_control_ext ( + LDAP *ld, + const char ctl_iscritical, + LDAPControl **ctrlp + ) +{ + int rc; + + if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) { + return( LDAP_PARAM_ERROR ); + } + + if ( ctrlp == NULL ) { + LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL ); + return ( LDAP_PARAM_ERROR ); + } + + rc = nsldapi_build_control( LDAP_CONTROL_PASSWD_POLICY, + NULL, NULL, ctl_iscritical, ctrlp ); + + LDAP_SET_LDERRNO( ld, rc, NULL, NULL ); + return( rc ); +} + +/* ldap_parse_passwordpolicy_control: + +Parameters are + +ld LDAP pointer to the desired connection + +ctrlp pointer to LDAPControl structure, obtained from + calling ldap_find_control() or by other means. + +exptimep result parameter is filled in with the number of seconds before + the password will expire. + +gracep result parameter is filled in with the number of grace logins + after the password has expired. + +errorcodep result parameter is filled in with the error code of the + password operation. +*/ + +int +LDAP_CALL +ldap_parse_passwordpolicy_control ( + LDAP *ld, + LDAPControl *ctrlp, + ber_int_t *expirep, + ber_int_t *gracep, + LDAPPasswordPolicyError *errorp + ) +{ + ber_len_t len; + ber_tag_t tag; + ber_int_t pp_exp = -1; + ber_int_t pp_grace = -1; + ber_int_t pp_warning = -1; + ber_int_t pp_err = PP_noError; + BerElement *ber = NULL; + + if ( !NSLDAPI_VALID_LDAP_POINTER( ld ) ) { + return( LDAP_PARAM_ERROR ); + } + + if ( ctrlp == NULL ) { + LDAP_SET_LDERRNO( ld, LDAP_CONTROL_NOT_FOUND, NULL, NULL ); + return ( LDAP_CONTROL_NOT_FOUND ); + } + + /* allocate a Ber element with the contents of the control's struct berval */ + if ( ( ber = ber_init( &ctrlp->ldctl_value ) ) == NULL ) { + LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL ); + return( LDAP_NO_MEMORY ); + } + + /* + * The control value should look like this: + * + * PasswordPolicyResponseValue ::= SEQUENCE { + * warning [0] CHOICE { + * timeBeforeExpiration [0] INTEGER (0 .. maxInt), + * graceLoginsRemaining [1] INTEGER (0 .. maxInt) } OPTIONAL + * error [1] ENUMERATED { + * passwordExpired (0), + * accountLocked (1), + * changeAfterReset (2), + * passwordModNotAllowed (3), + * mustSupplyOldPassword (4), + * insufficientPasswordQuality (5), + * passwordTooShort (6), + * passwordTooYoung (7), + * passwordInHistory (8) } OPTIONAL } + */ + + if ( ber_scanf( ber, "{" ) == LBER_ERROR ) { + LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL ); + ber_free( ber, 1 ); + return( LDAP_DECODING_ERROR ); + } + + tag = ber_peek_tag( ber, &len ); + + while ( (tag != LBER_ERROR) && (tag != LBER_END_OF_SEQORSET) ) { + if ( tag == ( LBER_CONSTRUCTED | LBER_CLASS_CONTEXT ) ) { + ber_skip_tag( ber, &len ); + if ( ber_scanf( ber, "ti", &tag, &pp_warning ) == LBER_ERROR ) { + LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL ); + ber_free( ber, 1 ); + return( LDAP_DECODING_ERROR ); + } + if ( tag == ( LBER_CLASS_CONTEXT | 0x01 ) ) { + pp_exp = pp_warning; + } else if ( tag == ( LBER_CLASS_CONTEXT | 0x02 ) ) { + pp_grace = pp_warning; + } + } else if ( tag == ( LBER_CLASS_CONTEXT | 0x01 ) ) { + if ( ber_scanf( ber, "ti", &tag, &pp_err ) == LBER_ERROR ) { + LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL ); + ber_free( ber, 1 ); + return( LDAP_DECODING_ERROR ); + } + } + if ( tag == LBER_DEFAULT ) { + LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL ); + ber_free( ber, 1 ); + return( LDAP_DECODING_ERROR ); + } + tag = ber_skip_tag( ber, &len ); + } + + if (expirep) *expirep = pp_exp; + if (gracep) *gracep = pp_grace; + if (errorp) *errorp = pp_err; + + /* the ber encoding is no longer needed */ + ber_free( ber, 1 ); + return( LDAP_SUCCESS ); +} + +/* ldap_parse_passwordpolicy_control_ext: + +Parameters are + +ld LDAP pointer to the desired connection + +ctrlp An array of controls obtained from calling + ldap_parse_result on the set of results + returned by the server + +exptimep result parameter is filled in with the number of seconds before + the password will expire. + +gracep result parameter is filled in with the number of grace logins + after the password has expired. + +errorcodep result parameter is filled in with the error code of the + password operation. +*/ + +int +LDAP_CALL +ldap_parse_passwordpolicy_control_ext ( + LDAP *ld, + LDAPControl **ctrlp, + ber_int_t *expirep, + ber_int_t *gracep, + LDAPPasswordPolicyError *errorp + ) +{ + int i, foundPPControl; + LDAPControl *PPCtrlp = NULL; + + if ( !NSLDAPI_VALID_LDAP_POINTER( ld ) || pp == NULL ) { + return( LDAP_PARAM_ERROR ); + } + + /* find the control in the list of controls if it exists */ + if ( ctrlp == NULL ) { + LDAP_SET_LDERRNO( ld, LDAP_CONTROL_NOT_FOUND, NULL, NULL ); + return ( LDAP_CONTROL_NOT_FOUND ); + } + foundPPControl = 0; + for ( i = 0; (( ctrlp[i] != NULL ) && ( !foundPPControl )); i++ ) { + foundPPControl = !strcmp( ctrlp[i]->ldctl_oid, LDAP_CONTROL_PASSWD_POLICY ); + } + if ( !foundPPControl ) { + LDAP_SET_LDERRNO( ld, LDAP_CONTROL_NOT_FOUND, NULL, NULL ); + return ( LDAP_CONTROL_NOT_FOUND ); + } else { + /* let local var point to the control */ + PPCtrlp = ctrlp[i-1]; + } + + return ( + ldap_parse_passwordpolicy_control( ld, PPCtrlp, expirep, gracep, errorp )); +} + +const char * +LDAP_CALL +ldap_passwordpolicy_err2txt( LDAPPasswordPolicyError err ) +{ + switch(err) { + case PP_passwordExpired: + return "Password expired"; + case PP_accountLocked: + return "Account locked"; + case PP_changeAfterReset: + return "Password must be changed"; + case PP_passwordModNotAllowed: + return "Policy prevents password modification"; + case PP_mustSupplyOldPassword: + return "Policy requires old password in order to change password"; + case PP_insufficientPasswordQuality: + return "Password fails quality checks"; + case PP_passwordTooShort: + return "Password is too short for policy"; + case PP_passwordTooYoung: + return "Password has been changed too recently"; + case PP_passwordInHistory: + return "New password is in list of old passwords"; + case PP_noError: + return "No error"; + default: + return "Unknown error code"; + } +} diff --git a/directory/c-sdk/ldap/libraries/libldap/userstatusctrl.c b/directory/c-sdk/ldap/libraries/libldap/userstatusctrl.c new file mode 100644 index 000000000000..d2be487f226c --- /dev/null +++ b/directory/c-sdk/ldap/libraries/libldap/userstatusctrl.c @@ -0,0 +1,229 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Sun LDAP C SDK. + * + * The Initial Developer of the Original Code is Sun Microsystems, Inc. + * + * Portions created by Sun Microsystems, Inc are Copyright (C) 2005 + * Sun Microsystems, Inc. All Rights Reserved. + * + * Contributor(s): abobrov@sun.com + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "ldap-int.h" + +/* ldap_create_userstatus_control: + + Parameters are + + ld LDAP pointer to the desired connection + + ctl_iscritical Indicates whether the control is critical of not. If + this field is non-zero, the operation will only be car- + ried out if the control is recognized by the server + and/or client + + ctrlp the address of a place to put the constructed control +*/ + +int +LDAP_CALL +ldap_create_userstatus_control ( + LDAP *ld, + const char ctl_iscritical, + LDAPControl **ctrlp + ) +{ + int rc; + + if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) { + return( LDAP_PARAM_ERROR ); + } + + if ( ctrlp == NULL ) { + LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL ); + return ( LDAP_PARAM_ERROR ); + } + + rc = nsldapi_build_control( LDAP_CONTROL_ACCOUNT_USABLE, + NULL, NULL, ctl_iscritical, ctrlp ); + + LDAP_SET_LDERRNO( ld, rc, NULL, NULL ); + return( rc ); +} + +/* ldap_parse_userstatus_control: + + Parameters are + + ld LDAP pointer to the desired connection + + ctrlp An array of controls obtained from calling + ldap_parse_result on the set of results + returned by the server + + us the address of struct LDAPuserstatus + to parse control results to +*/ + +int +LDAP_CALL +ldap_parse_userstatus_control ( + LDAP *ld, + LDAPControl **ctrlp, + LDAPuserstatus *us + ) +{ + BerElement *ber = NULL; + int i, foundUSControl; + LDAPControl *USCtrlp = NULL; + ber_len_t len; + ber_tag_t tag; + + if ( !NSLDAPI_VALID_LDAP_POINTER( ld ) || us == NULL ) { + return( LDAP_PARAM_ERROR ); + } + + /* find the control in the list of controls if it exists */ + if ( ctrlp == NULL ) { + LDAP_SET_LDERRNO( ld, LDAP_CONTROL_NOT_FOUND, NULL, NULL ); + return ( LDAP_CONTROL_NOT_FOUND ); + } + foundUSControl = 0; + for ( i = 0; (( ctrlp[i] != NULL ) && ( !foundUSControl )); i++ ) { + foundUSControl = !strcmp( ctrlp[i]->ldctl_oid, LDAP_CONTROL_ACCOUNT_USABLE ); + } + if ( !foundUSControl ) { + LDAP_SET_LDERRNO( ld, LDAP_CONTROL_NOT_FOUND, NULL, NULL ); + return ( LDAP_CONTROL_NOT_FOUND ); + } else { + /* let local var point to the control */ + USCtrlp = ctrlp[i-1]; + } + + /* allocate a Ber element with the contents of the control's struct berval */ + if ( ( ber = ber_init( &USCtrlp->ldctl_value ) ) == NULL ) { + LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL ); + return( LDAP_NO_MEMORY ); + } + + memset( us, 0, sizeof(struct LDAPuserstatus) ); + + /* + * The control value should look like this: + * + * ACCOUNT_USABLE_RESPONSE::= CHOICE { + * is_available [0] INTEGER, ** seconds before expiration ** + * is_not_available [1] More_info + * } + * More_info::= SEQUENCE { + * inactive [0] BOOLEAN DEFAULT FALSE, + * reset [1] BOOLEAN DEFAULT FALSE, + * expired [2] BOOLEAN DEFAULT FALSE, + * remaining_grace [3] INTEGER OPTIONAL, + * seconds_before_unlock [4] INTEGER OPTIONAL + * } + */ + + if ( ( ber_scanf( ber, "t", &tag ) ) == LBER_ERROR ) { + LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL ); + ber_free( ber, 1 ); + return( LDAP_DECODING_ERROR ); + } + + tag = (( tag & LBER_CONSTRUCTED ) == LBER_CONSTRUCTED ) ? 1 : 0; + + if ( !tag ) { + us->us_available = 1; + if ( ber_scanf( ber, "i", &us->us_expire ) == LBER_ERROR ) { + LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL ); + ber_free( ber, 1 ); + return( LDAP_DECODING_ERROR ); + } + } else { + us->us_available = 0; + tag = 0; + if ( ( ber_scanf( ber, "{t", &tag ) ) == LBER_ERROR ) { + LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL ); + ber_free( ber, 1 ); + return( LDAP_DECODING_ERROR ); + } + while ( tag != LBER_ERROR && tag != LBER_END_OF_SEQORSET ) { + tag = tag & (~LBER_CLASS_CONTEXT); + switch (tag) + { + case 0: + if ( ber_scanf( ber, "b", &us->us_inactive ) == LBER_ERROR ) { + LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL ); + ber_free( ber, 1 ); + return( LDAP_DECODING_ERROR ); + } + us->us_inactive = ( us->us_inactive != 0 ) ? 1 : 0; + break; + case 1: + if ( ber_scanf( ber, "b", &us->us_reset ) == LBER_ERROR ) { + LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL ); + ber_free( ber, 1 ); + return( LDAP_DECODING_ERROR ); + } + us->us_reset = ( us->us_reset != 0 ) ? 1 : 0; + break; + case 2: + if ( ber_scanf( ber, "b", &us->us_expired ) == LBER_ERROR ) { + LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL ); + ber_free( ber, 1 ); + return( LDAP_DECODING_ERROR ); + } + us->us_expired = ( us->us_expired != 0 ) ? 1 : 0; + break; + case 3: + if ( ber_scanf( ber, "i", &us->us_remaining ) == LBER_ERROR ) { + LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL ); + ber_free( ber, 1 ); + return( LDAP_DECODING_ERROR ); + } + break; + case 4: + if ( ber_scanf( ber, "i", &us->us_seconds ) == LBER_ERROR ) { + LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL ); + ber_free( ber, 1 ); + return( LDAP_DECODING_ERROR ); + } + break; + default: + LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL ); + ber_free( ber, 1 ); + return( LDAP_DECODING_ERROR ); + } + ber_scanf( ber, "t", &tag ); + } + } + + /* the ber encoding is no longer needed */ + ber_free( ber, 1 ); + return( LDAP_SUCCESS ); +} diff --git a/directory/c-sdk/ldap/libraries/libldap/whoami.c b/directory/c-sdk/ldap/libraries/libldap/whoami.c new file mode 100644 index 000000000000..720ab6dfe909 --- /dev/null +++ b/directory/c-sdk/ldap/libraries/libldap/whoami.c @@ -0,0 +1,132 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Sun LDAP C SDK. + * + * The Initial Developer of the Original Code is Sun Microsystems, Inc. + * + * Portions created by Sun Microsystems, Inc are Copyright (C) 2005 + * Sun Microsystems, Inc. All Rights Reserved. + * + * Contributor(s): abobrov@sun.com + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "ldap-int.h" + +/* ldap_whoami */ +int +LDAP_CALL +ldap_whoami ( + LDAP *ld, + LDAPControl **serverctrls, + LDAPControl **clientctrls, + int *msgidp + ) +{ + int rc; + struct berval *requestdata = NULL; + + if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) { + LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL ); + return( LDAP_PARAM_ERROR ); + } + + rc = ldap_extended_operation( ld, LDAP_EXOP_WHO_AM_I, requestdata, + serverctrls, clientctrls, msgidp ); + + return( rc ); +} + +/* ldap_parse_whoami */ +int +LDAP_CALL +ldap_parse_whoami ( + LDAP *ld, + LDAPMessage *result, + struct berval **authzid + ) +{ + int rc; + char *retoidp = NULL; + char *authzidp = NULL; + struct berval *retdatap = NULL; + + if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) { + LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL ); + return( LDAP_PARAM_ERROR ); + } + if ( !result ) { + LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL ); + return( LDAP_PARAM_ERROR ); + } + + *authzid = NULL; + + rc = ldap_parse_extended_result( ld, result, &retoidp, authzid, 0 ); + + if ( rc != LDAP_SUCCESS ) { + return( rc ); + } + + ldap_memfree( retoidp ); + return( LDAP_SUCCESS ); +} + +/* ldap_whoami_s */ +int +LDAP_CALL +ldap_whoami_s ( + LDAP *ld, + struct berval **authzid, + LDAPControl **serverctrls, + LDAPControl **clientctrls + ) +{ + int rc; + int msgid; + LDAPMessage *result = NULL; + + if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) { + LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL ); + return( LDAP_PARAM_ERROR ); + } + + rc = ldap_whoami( ld, serverctrls, clientctrls, &msgid ); + if ( rc != LDAP_SUCCESS ) { + return( rc ); + } + + rc = ldap_result( ld, msgid, LDAP_MSG_ALL, NULL, &result ); + if ( rc == -1 ) { + return( LDAP_GET_LDERRNO( ld, NULL, NULL ) ); + } + + rc = ldap_parse_whoami( ld, result, authzid ); + + ldap_msgfree( result ); + + return( rc ); +}