From: Kurt Zeilenga Date: Fri, 10 Dec 1999 04:52:32 +0000 (+0000) Subject: Fix slapd SASL/ExternalOps encoding X-Git-Tag: UCDATA_2_4~106 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=431dad371ca4b53e06cc3af3a5b44cbf7d1b4a3b;p=openldap Fix slapd SASL/ExternalOps encoding Add controls to extended ops API signatures, need impl. Update password to support optional server side generation of new password, verification of old password, and changing of non-bound user's passwords. --- diff --git a/clients/tools/ldappasswd.c b/clients/tools/ldappasswd.c index 5e97373479..0deb9f95d9 100644 --- a/clients/tools/ldappasswd.c +++ b/clients/tools/ldappasswd.c @@ -34,6 +34,7 @@ usage(const char *s) " -n\t\tmake no modifications\n" " -p port\tldap port\n" " -s secret\tnew password\n" + " -S\t\tprompt for new password\n" " -v\t\tincrease verbosity\n" " -W\t\tprompt for bind password\n" " -w passwd\tbind password (for simple authentication)\n" @@ -46,20 +47,26 @@ int main( int argc, char *argv[] ) { int rc; + char *ldaphost = NULL; + char *dn = NULL; char *binddn = NULL; + char *bindpw = NULL; - char *ldaphost = NULL; char *newpw = NULL; + char *oldpw = NULL; + + int want_bindpw = 0; + int want_newpw = 0; + int want_oldpw = 0; + int noupdates = 0; int i; int ldapport = 0; int debug = 0; int version = -1; - int want_bindpw = 0; LDAP *ld; struct berval *bv = NULL; - BerElement *ber; char *retoid; struct berval *retdata; @@ -68,9 +75,23 @@ main( int argc, char *argv[] ) usage (argv[0]); while( (i = getopt( argc, argv, - "D:d:h:np:s:vWw:" )) != EOF ) + "Aa:D:d:h:np:Ss:vWw:" )) != EOF ) { switch (i) { + case 'A': /* prompt for oldr password */ + want_oldpw++; + break; + case 'a': /* old password (secret) */ + oldpw = strdup (optarg); + + { + char* p; + + for( p = optarg; *p == '\0'; p++ ) { + *p = '*'; + } + } + break; case 'D': /* bind distinguished name */ binddn = strdup (optarg); break; @@ -91,8 +112,20 @@ main( int argc, char *argv[] ) ldapport = strtol( optarg, NULL, 10 ); break; + case 'S': /* prompt for user password */ + want_newpw++; + break; + case 's': /* new password (secret) */ newpw = strdup (optarg); + + { + char* p; + + for( p = optarg; *p == '\0'; p++ ) { + *p = '*'; + } + } break; case 'v': /* verbose */ @@ -105,6 +138,7 @@ main( int argc, char *argv[] ) case 'w': /* bind password */ bindpw = strdup (optarg); + { char* p; @@ -126,7 +160,19 @@ main( int argc, char *argv[] ) dn = strdup( argv[optind] ); - if( newpw == NULL ) { + if( want_oldpw && oldpw == NULL ) { + /* prompt for old password */ + char *ckoldpw; + newpw = strdup(getpass("Old password: ")); + ckoldpw = getpass("Re-enter old password: "); + + if( strncmp( oldpw, ckoldpw, strlen(oldpw) )) { + fprintf( stderr, "passwords do not match\n" ); + return EXIT_FAILURE; + } + } + + if( want_newpw && newpw == NULL ) { /* prompt for new password */ char *cknewpw; newpw = strdup(getpass("New password: ")); @@ -138,13 +184,15 @@ main( int argc, char *argv[] ) } } - if( binddn == NULL ) { + if( binddn == NULL && dn != NULL ) { binddn = dn; dn = NULL; + + if( bindpw == NULL ) bindpw = oldpw; } - /* handle bind password */ - if (want_bindpw) { + if (want_bindpw && bindpw == NULL ) { + /* handle bind password */ fprintf( stderr, "Bind DN: %s\n", binddn ); bindpw = strdup( getpass("Enter bind password: ")); } @@ -186,39 +234,45 @@ main( int argc, char *argv[] ) return EXIT_FAILURE; } - /* build change password control */ - ber = ber_alloc_t( LBER_USE_DER ); + if( dn != NULL || oldpw != NULL || newpw != NULL ) { + /* build change password control */ + BerElement *ber = ber_alloc_t( LBER_USE_DER ); - if( ber == NULL ) { - perror( "ber_alloc_t" ); - ldap_unbind( ld ); - return EXIT_FAILURE; - } + if( ber == NULL ) { + perror( "ber_alloc_t" ); + ldap_unbind( ld ); + return EXIT_FAILURE; + } - if( dn != NULL ) { - ber_printf( ber, "{tsts}", - LDAP_TAG_EXOP_X_MODIFY_PASSWD_ID, dn, - LDAP_TAG_EXOP_X_MODIFY_PASSWD_NEW, newpw ); + if( dn != NULL ) { + ber_printf( ber, "ts", + LDAP_TAG_EXOP_X_MODIFY_PASSWD_ID, dn ); + free(dn); + } - free(dn); + if( oldpw != NULL ) { + ber_printf( ber, "ts", + LDAP_TAG_EXOP_X_MODIFY_PASSWD_NEW, oldpw ); + free(oldpw); + } - } else { - ber_printf( ber, "{ts}", - LDAP_TAG_EXOP_X_MODIFY_PASSWD_NEW, newpw ); - } + if( newpw != NULL ) { + ber_printf( ber, "ts", + LDAP_TAG_EXOP_X_MODIFY_PASSWD_NEW, newpw ); + free(newpw); + } - free(newpw); + rc = ber_flatten( ber, &bv ); - rc = ber_flatten( ber, &bv ); + if( rc < 0 ) { + perror( "ber_flatten" ); + ldap_unbind( ld ); + return EXIT_FAILURE; + } - if( rc < 0 ) { - perror( "ber_flatten" ); - ldap_unbind( ld ); - return EXIT_FAILURE; + ber_free( ber, 1 ); } - ber_free( ber, 1 ); - rc = ldap_extended_operation_s( ld, LDAP_EXOP_X_MODIFY_PASSWD, bv, NULL, NULL, @@ -226,6 +280,30 @@ main( int argc, char *argv[] ) ber_bvfree( bv ); + if( retdata != NULL ) { + ber_tag_t tag; + char *s; + BerElement *ber = ber_init( retdata ); + + if( ber == NULL ) { + perror( "ber_init" ); + ldap_unbind( ld ); + return EXIT_FAILURE; + } + + /* we should check the tag */ + tag = ber_scanf( ber, "a", &s); + + if( tag == LBER_ERROR ) { + perror( "ber_scanf" ); + } else { + printf("New password: %s\n", s); + free( s ); + } + + ber_free( ber, 1 ); + } + if ( rc != LDAP_SUCCESS ) { ldap_perror( ld, "ldap_extended_operation" ); ldap_unbind( ld ); diff --git a/include/lutil.h b/include/lutil.h index 9a385aca3d..9e6336d840 100644 --- a/include/lutil.h +++ b/include/lutil.h @@ -65,7 +65,10 @@ lutil_passwd LDAP_P(( const char **methods )); LIBLUTIL_F( struct berval * ) -lutil_passwd_generate LDAP_P(( +lutil_passwd_generate LDAP_P(( int )); + +LIBLUTIL_F( struct berval * ) +lutil_passwd_hash LDAP_P(( const struct berval *passwd, const char *method )); diff --git a/libraries/libldap/extended.c b/libraries/libldap/extended.c index c3b382d18d..fe6f549f22 100644 --- a/libraries/libldap/extended.c +++ b/libraries/libldap/extended.c @@ -202,7 +202,7 @@ ldap_parse_extended_result ( } rc = ber_scanf( ber, "{iaa" /*}*/, &errcode, - &ld->ld_matched, &ld->ld_matched ); + &ld->ld_matched, &ld->ld_error ); if( rc == LBER_ERROR ) { ld->ld_errno = LDAP_DECODING_ERROR; @@ -237,7 +237,7 @@ ldap_parse_extended_result ( if( tag == LDAP_TAG_EXOP_RES_VALUE ) { /* we have a resdata */ - if( ber_scanf( ber, "O", &resoid ) == LBER_ERROR ) { + if( ber_scanf( ber, "O", &resdata ) == LBER_ERROR ) { ld->ld_errno = LDAP_DECODING_ERROR; ber_free( ber, 0 ); if( resoid != NULL ) LDAP_FREE( resoid ); diff --git a/libraries/liblutil/passwd.c b/libraries/liblutil/passwd.c index efab836b87..c610c2bd10 100644 --- a/libraries/liblutil/passwd.c +++ b/libraries/liblutil/passwd.c @@ -35,6 +35,9 @@ # include #endif +static const unsigned char crypt64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890./"; + struct pw_scheme; typedef int (*PASSWD_CHK_FUNC)( @@ -42,14 +45,14 @@ typedef int (*PASSWD_CHK_FUNC)( const struct berval *passwd, const struct berval *cred ); -typedef struct berval * (*PASSWD_GEN_FUNC) ( +typedef struct berval * (*PASSWD_HASH_FUNC) ( const struct pw_scheme *scheme, const struct berval *passwd ); struct pw_scheme { struct berval name; PASSWD_CHK_FUNC chk_fn; - PASSWD_GEN_FUNC gen_fn; + PASSWD_HASH_FUNC hash_fn; }; /* password check routines */ @@ -84,38 +87,38 @@ static int chk_unix( const struct berval *cred ); -/* password generation routines */ -static struct berval *gen_sha1( +/* password hash routines */ +static struct berval *hash_sha1( const struct pw_scheme *scheme, const struct berval *passwd ); -static struct berval *gen_ssha1( +static struct berval *hash_ssha1( const struct pw_scheme *scheme, const struct berval *passwd ); -static struct berval *gen_smd5( +static struct berval *hash_smd5( const struct pw_scheme *scheme, const struct berval *passwd ); -static struct berval *gen_md5( +static struct berval *hash_md5( const struct pw_scheme *scheme, const struct berval *passwd ); -static struct berval *gen_crypt( +static struct berval *hash_crypt( const struct pw_scheme *scheme, const struct berval *passwd ); static const struct pw_scheme pw_schemes[] = { - { {sizeof("{SSHA}")-1, "{SSHA}"}, chk_ssha1, gen_ssha1 }, - { {sizeof("{SHA}")-1, "{SHA}"}, chk_sha1, gen_sha1 }, + { {sizeof("{SSHA}")-1, "{SSHA}"}, chk_ssha1, hash_ssha1 }, + { {sizeof("{SHA}")-1, "{SHA}"}, chk_sha1, hash_sha1 }, - { {sizeof("{SMD5}")-1, "{SMD5}"}, chk_smd5, gen_smd5 }, - { {sizeof("{MD5}")-1, "{MD5}"}, chk_md5, gen_md5 }, + { {sizeof("{SMD5}")-1, "{SMD5}"}, chk_smd5, hash_smd5 }, + { {sizeof("{MD5}")-1, "{MD5}"}, chk_md5, hash_md5 }, #ifdef SLAPD_CRYPT - { {sizeof("{CRYPT}")-1, "{CRYPT}"}, chk_crypt, gen_crypt }, + { {sizeof("{CRYPT}")-1, "{CRYPT}"}, chk_crypt, hash_crypt }, #endif # if defined( HAVE_GETSPNAM ) \ || ( defined( HAVE_GETPWNAM ) && defined( HAVE_PW_PASSWD ) ) @@ -247,16 +250,48 @@ lutil_passwd( } -struct berval * lutil_passwd_generate( +struct berval * lutil_passwd_generate( int len ) +{ + struct berval *pw; + + if( len < 1 ) return NULL; + + pw = ber_memalloc( sizeof( struct berval ) ); + if( pw == NULL ) return NULL; + + pw->bv_len = len; + pw->bv_val = ber_memalloc( len + 1 ); + + if( pw->bv_val == NULL ) { + ber_memfree( pw ); + return NULL; + } + + if( lutil_entropy( pw->bv_val, pw->bv_len) < 0 ) { + ber_bvfree( pw ); + return NULL; + } + + for( len = 0; len < pw->bv_len; len++ ) { + pw->bv_val[len] = crypt64[ + pw->bv_val[len] % (sizeof(crypt64)-1) ]; + } + + pw->bv_val[len] = '\0'; + + return pw; +} + +struct berval * lutil_passwd_hash( const struct berval * passwd, const char * method ) { const struct pw_scheme *sc = get_scheme( method ); if( sc == NULL ) return NULL; - if( ! sc->gen_fn ) return NULL; + if( ! sc->hash_fn ) return NULL; - return (sc->gen_fn)( sc, passwd ); + return (sc->hash_fn)( sc, passwd ); } static struct berval * pw_string( @@ -579,7 +614,7 @@ static int chk_unix( #endif /* PASSWORD CHECK ROUTINES */ -static struct berval *gen_ssha1( +static struct berval *hash_ssha1( const struct pw_scheme *scheme, const struct berval *passwd ) { @@ -608,7 +643,7 @@ static struct berval *gen_ssha1( return pw_string64( scheme, &digest, &salt); } -static struct berval *gen_sha1( +static struct berval *hash_sha1( const struct pw_scheme *scheme, const struct berval *passwd ) { @@ -626,7 +661,7 @@ static struct berval *gen_sha1( return pw_string64( scheme, &digest, NULL); } -static struct berval *gen_smd5( +static struct berval *hash_smd5( const struct pw_scheme *scheme, const struct berval *passwd ) { @@ -655,7 +690,7 @@ static struct berval *gen_smd5( return pw_string64( scheme, &digest, &salt ); } -static struct berval *gen_md5( +static struct berval *hash_md5( const struct pw_scheme *scheme, const struct berval *passwd ) { @@ -677,13 +712,10 @@ static struct berval *gen_md5( } #ifdef SLAPD_CRYPT -static struct berval *gen_crypt( +static struct berval *hash_crypt( const struct pw_scheme *scheme, const struct berval *passwd ) { - static const unsigned char crypt64[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890./"; - struct berval hash; unsigned char salt[3]; int i; diff --git a/servers/slapd/back-ldbm/extended.c b/servers/slapd/back-ldbm/extended.c index eb55797d8f..bc172df0d8 100644 --- a/servers/slapd/back-ldbm/extended.c +++ b/servers/slapd/back-ldbm/extended.c @@ -32,6 +32,7 @@ ldbm_back_extended( char *oid, struct berval *reqdata, struct berval **rspdata, + LDAPControl *** rspctrls, char** text ) { @@ -40,8 +41,8 @@ ldbm_back_extended( for( i=0; exop_table[i].oid != NULL; i++ ) { if( strcmp( exop_table[i].oid, oid ) == 0 ) { return (exop_table[i].extended)( - be, conn, op, - oid, reqdata, rspdata, text ); + be, conn, op, oid, + reqdata, rspdata, rspctrls, text ); } } diff --git a/servers/slapd/back-ldbm/external.h b/servers/slapd/back-ldbm/external.h index 24ca3560a8..aeac346579 100644 --- a/servers/slapd/back-ldbm/external.h +++ b/servers/slapd/back-ldbm/external.h @@ -27,6 +27,7 @@ extern int ldbm_back_extended LDAP_P(( BackendDB *bd, char *reqoid, struct berval *reqdata, struct berval **rspdata, + LDAPControl *** rspctrls, char **text )); extern int ldbm_back_bind LDAP_P(( BackendDB *bd, diff --git a/servers/slapd/back-ldbm/passwd.c b/servers/slapd/back-ldbm/passwd.c index c8980768b6..7ab5e18766 100644 --- a/servers/slapd/back-ldbm/passwd.c +++ b/servers/slapd/back-ldbm/passwd.c @@ -24,6 +24,7 @@ ldbm_back_exop_passwd( char *oid, struct berval *reqdata, struct berval **rspdata, + LDAPControl *** rspctrls, char** text ) { @@ -51,15 +52,21 @@ ldbm_back_exop_passwd( } if( new == NULL || new->bv_len == 0 ) { - *text = ch_strdup("no password provided"); - rc = LDAP_OPERATIONS_ERROR; - goto done; + new = slap_passwd_generate(); + + if( new == NULL || new->bv_len == 0 ) { + *text = ch_strdup("password generation failed."); + rc = LDAP_OPERATIONS_ERROR; + goto done; + } + + *rspdata = slap_passwd_return( new ); } - hash = slap_passwd_generate( new ); + hash = slap_passwd_hash( new ); if( hash == NULL || hash->bv_len == 0 ) { - *text = ch_strdup("password generation failed"); + *text = ch_strdup("password hash failed"); rc = LDAP_OPERATIONS_ERROR; goto done; } @@ -75,9 +82,7 @@ ldbm_back_exop_passwd( goto done; } - e = dn2entry_w( be, - id ? id->bv_val : op->o_dn, - NULL ); + e = dn2entry_w( be, dn, NULL ); if( e == NULL ) { *text = ch_strdup("could not locate authorization entry"); diff --git a/servers/slapd/back-ldbm/proto-back-ldbm.h b/servers/slapd/back-ldbm/proto-back-ldbm.h index c6aeaa519f..89aae2a432 100644 --- a/servers/slapd/back-ldbm/proto-back-ldbm.h +++ b/servers/slapd/back-ldbm/proto-back-ldbm.h @@ -151,6 +151,7 @@ extern int ldbm_back_exop_passwd LDAP_P(( BackendDB *bd, char *oid, struct berval *reqdata, struct berval **rspdata, + LDAPControl ***rspctrls, char **text )); diff --git a/servers/slapd/extended.c b/servers/slapd/extended.c index 55620e6109..f907dc808d 100644 --- a/servers/slapd/extended.c +++ b/servers/slapd/extended.c @@ -93,6 +93,7 @@ do_extended( extop_list_t *ext; char *text; struct berval *rspdata; + LDAPControl **rspctrls; Debug( LDAP_DEBUG_TRACE, "do_extended\n", 0, 0, 0 ); @@ -144,14 +145,15 @@ do_extended( Debug( LDAP_DEBUG_ARGS, "do_extended: oid=%s\n", oid, 0 ,0 ); rspdata = NULL; + rspctrls = NULL; text = NULL; rc = (ext->ext_main)( extop_callback, conn, op, - oid, reqdata, &rspdata, &text ); + oid, reqdata, &rspdata, &rspctrls, &text ); if( rc != SLAPD_ABANDON ) { send_ldap_extended( conn, op, rc, NULL, text, - oid, rspdata ); + oid, rspdata, rspctrls ); } if ( rspdata != NULL ) diff --git a/servers/slapd/passwd.c b/servers/slapd/passwd.c index 875bdf6fd0..7a57bce129 100644 --- a/servers/slapd/passwd.c +++ b/servers/slapd/passwd.c @@ -21,7 +21,10 @@ int passwd_extop( SLAP_EXTOP_CALLBACK_FN ext_callback, Connection *conn, Operation *op, char *oid, - struct berval *reqdata, struct berval **rspdata, char **text ) + struct berval *reqdata, + struct berval **rspdata, + LDAPControl ***rspctrls, + char **text ) { int rc; @@ -33,17 +36,12 @@ int passwd_extop( return LDAP_STRONG_AUTH_REQUIRED; } - if( reqdata == NULL || reqdata->bv_len == 0 ) { - *text = ch_strdup("request data missing"); - return LDAP_PROTOCOL_ERROR; - } - if( conn->c_authz_backend != NULL && conn->c_authz_backend->be_extended ) { rc = conn->c_authz_backend->be_extended( conn->c_authz_backend, - conn, op, oid, reqdata, rspdata, text ); + conn, op, oid, reqdata, rspdata, rspctrls, text ); } else { *text = ch_strdup("operation not supported for current user"); @@ -64,7 +62,9 @@ int slap_passwd_parse( struct berval *reqdata, ber_len_t len; BerElement *ber; - assert( reqdata != NULL ); + if( reqdata == NULL ) { + return LDAP_SUCCESS; + } ber = ber_init( reqdata ); @@ -75,12 +75,6 @@ int slap_passwd_parse( struct berval *reqdata, return LDAP_PROTOCOL_ERROR; } - tag = ber_scanf(ber, "{" /*}*/); - - if( tag == LBER_ERROR ) { - goto decoding_error; - } - tag = ber_peek_tag( ber, &len ); if( tag == LDAP_TAG_EXOP_X_MODIFY_PASSWD_ID ) { @@ -175,6 +169,35 @@ done: return rc; } +struct berval * slap_passwd_return( + struct berval *cred ) +{ + int rc; + struct berval *bv; + BerElement *ber = ber_alloc_t(LBER_USE_DER); + + assert( cred != NULL ); + + Debug( LDAP_DEBUG_TRACE, "slap_passwd_return: %ld\n", + (long) cred->bv_len, 0, 0 ); + + if( ber == NULL ) return NULL; + + rc = ber_printf( ber, "tO", + LDAP_TAG_EXOP_X_MODIFY_PASSWD_NEW, cred ); + + if( rc == -1 ) { + ber_free( ber, 1 ); + return NULL; + } + + (void) ber_flatten( ber, &bv ); + + ber_free( ber, 1 ); + + return bv; +} + int slap_passwd_check( Attribute *a, @@ -200,7 +223,13 @@ slap_passwd_check( return( 1 ); } -struct berval * slap_passwd_generate( +struct berval * slap_passwd_generate( void ) +{ + Debug( LDAP_DEBUG_TRACE, "slap_passwd_generate\n", 0, 0, 0 ); + return lutil_passwd_generate( 8 ); +} + +struct berval * slap_passwd_hash( struct berval * cred ) { char* hash = default_passwd_hash ? default_passwd_hash : "{SSHA}"; @@ -211,7 +240,7 @@ struct berval * slap_passwd_generate( ldap_pvt_thread_mutex_lock( &crypt_mutex ); #endif - new = lutil_passwd_generate( cred , hash ); + new = lutil_passwd_hash( cred , hash ); #ifdef SLAPD_CRYPT ldap_pvt_thread_mutex_unlock( &crypt_mutex ); diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index 33d608892f..fe4dc39f5d 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -259,6 +259,7 @@ typedef int (*SLAP_EXTOP_MAIN_FN) LDAP_P(( char * oid, struct berval * reqdata, struct berval ** rspdata, + LDAPControl *** rspctrls, char ** text )); typedef int (*SLAP_EXTOP_GETOID_FN) LDAP_P(( @@ -376,6 +377,7 @@ LIBSLAPD_F (void) send_ldap_sasl LDAP_P(( Connection *conn, Operation *op, ber_int_t err, const char *matched, const char *text, + LDAPControl **ctrls, struct berval *cred )); LIBSLAPD_F (void) send_ldap_disconnect LDAP_P(( @@ -386,7 +388,8 @@ LIBSLAPD_F (void) send_ldap_extended LDAP_P(( Connection *conn, Operation *op, ber_int_t err, const char *matched, const char *text, - char *rspoid, struct berval *rspdata )); + char *rspoid, struct berval *rspdata, + LDAPControl **ctrls )); LIBSLAPD_F (void) send_search_result LDAP_P(( Connection *conn, Operation *op, @@ -465,6 +468,7 @@ LIBSLAPD_F (int) starttls_extop LDAP_P(( char * oid, struct berval * reqdata, struct berval ** rspdata, + LDAPControl ***rspctrls, char ** text )); @@ -505,13 +509,19 @@ LIBSLAPD_F (int) passwd_extop LDAP_P(( char * oid, struct berval * reqdata, struct berval ** rspdata, + LDAPControl *** rspctrls, char ** text )); LIBSLAPD_F (int) slap_passwd_check( Attribute *attr, struct berval *cred ); -LIBSLAPD_F (struct berval *) slap_passwd_generate( +LIBSLAPD_F (struct berval *) slap_passwd_generate( void ); + +LIBSLAPD_F (struct berval *) slap_passwd_hash( + struct berval *cred ); + +LIBSLAPD_F (struct berval *) slap_passwd_return( struct berval *cred ); LIBSLAPD_F (int) slap_passwd_parse( diff --git a/servers/slapd/result.c b/servers/slapd/result.c index bc8dc7aa61..204ba41db1 100644 --- a/servers/slapd/result.c +++ b/servers/slapd/result.c @@ -243,7 +243,8 @@ send_ldap_response( const char *text, struct berval **ref, const char *resoid, - struct berval *data, + struct berval *resdata, + struct berval *sasldata, LDAPControl **ctrls ) { @@ -279,12 +280,19 @@ send_ldap_response( rc = ber_printf( ber, "{V}", ref ); } + if( rc != -1 && sasldata != NULL ) { + rc = ber_printf( ber, "tO", + LDAP_TAG_SASL_RES_CREDS, sasldata ); + } + if( rc != -1 && resoid != NULL ) { - rc = ber_printf( ber, "s", resoid ); + rc = ber_printf( ber, "ts", + LDAP_TAG_EXOP_RES_OID, resoid ); } - if( rc != -1 && data != NULL ) { - rc = ber_printf( ber, "O", data ); + if( rc != -1 && resdata != NULL ) { + rc = ber_printf( ber, "tO", + LDAP_TAG_EXOP_RES_VALUE, resdata ); } if( rc != -1 ) { @@ -361,9 +369,10 @@ send_ldap_disconnect( 0 ); } #endif + send_ldap_response( conn, op, tag, msgid, err, NULL, text, NULL, - reqoid, NULL, NULL ); + reqoid, NULL, NULL, NULL ); Statslog( LDAP_DEBUG_STATS, "conn=%ld op=%ld DISCONNECT err=%ld tag=%lu text=%s\n", @@ -429,7 +438,7 @@ send_ldap_result( send_ldap_response( conn, op, tag, msgid, err, matched, text, ref, - NULL, NULL, ctrls ); + NULL, NULL, NULL, ctrls ); Statslog( LDAP_DEBUG_STATS, "conn=%ld op=%ld RESULT tag=%lu err=%ld text=%s\n", @@ -448,6 +457,7 @@ send_ldap_sasl( ber_int_t err, const char *matched, const char *text, + LDAPControl **ctrls, struct berval *cred ) { @@ -473,7 +483,7 @@ send_ldap_sasl( send_ldap_response( conn, op, tag, msgid, err, matched, text, NULL, - NULL, cred, NULL ); + NULL, NULL, cred, ctrls ); } void @@ -484,15 +494,18 @@ send_ldap_extended( const char *matched, const char *text, char *rspoid, - struct berval *rspdata + struct berval *rspdata, + LDAPControl **ctrls ) { ber_tag_t tag; ber_int_t msgid; Debug( LDAP_DEBUG_TRACE, - "send_ldap_extended %ld:%s\n", - (long) err, rspoid ? rspoid : "", NULL ); + "send_ldap_extended %ld:%s (%ld)\n", + (long) err, + rspoid ? rspoid : "", + rspdata != NULL ? (long) rspdata->bv_len : (long) 0 ); tag = req2res( op->o_tag ); msgid = (tag != LBER_SEQUENCE) ? op->o_msgid : 0; @@ -507,9 +520,10 @@ send_ldap_extended( 0 ); } #endif + send_ldap_response( conn, op, tag, msgid, err, matched, text, NULL, - rspoid, rspdata, NULL ); + rspoid, rspdata, NULL, ctrls ); } @@ -572,7 +586,7 @@ send_search_result( send_ldap_response( conn, op, tag, msgid, err, matched, text, refs, - NULL, NULL, ctrls ); + NULL, NULL, NULL, ctrls ); Statslog( LDAP_DEBUG_STATS, "conn=%ld op=%ld SEARCH RESULT tag=%lu err=%ld text=%s\n", diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index de59ee4061..88a0b6418e 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -538,6 +538,7 @@ typedef int (*SLAP_EXTENDED_FN) LDAP_P(( char *oid, struct berval * reqdata, struct berval ** rspdata, + LDAPControl ***rspctrls, char** text )); struct slap_backend_info { diff --git a/servers/slapd/starttls.c b/servers/slapd/starttls.c index 6cee1c2964..410e450733 100644 --- a/servers/slapd/starttls.c +++ b/servers/slapd/starttls.c @@ -26,6 +26,7 @@ starttls_extop ( char * oid, struct berval * reqdata, struct berval ** rspdata, + LDAPControl ***rspctrls, char ** text ) { if ( reqdata != NULL ) { @@ -62,6 +63,7 @@ starttls_extop ( conn->c_is_tls = 1; conn->c_needs_tls_accept = 1; + return(LDAP_SUCCESS); } diff --git a/servers/slapd/tools/mimic.c b/servers/slapd/tools/mimic.c index caea1a5135..a3a7d60309 100644 --- a/servers/slapd/tools/mimic.c +++ b/servers/slapd/tools/mimic.c @@ -47,7 +47,8 @@ send_ldap_extended( const char *matched, const char *text, char *rspoid, - struct berval *rspdata + struct berval *rspdata, + LDAPControl **ctrls ) { assert(0); @@ -60,6 +61,7 @@ send_ldap_sasl( ber_int_t err, const char *matched, const char *text, + LDAPControl **ctrls, struct berval *cred ) {