X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fbind.c;h=778471118278005e13599982e1b837367e2baaeb;hb=dc07e765f263ef459dcd2afd1ece01cfc85a0edd;hp=8d3979992c57bca3e662fffebbc0c3de67f42878;hpb=8761bbb6e93a36ddb333775cb2ff3c3c9c7d8669;p=openldap diff --git a/servers/slapd/bind.c b/servers/slapd/bind.c index 8d3979992c..7784711182 100644 --- a/servers/slapd/bind.c +++ b/servers/slapd/bind.c @@ -21,11 +21,6 @@ #include "slap.h" -extern Backend *select_backend(); -extern char *suffixAlias(); - -extern char *default_referral; - void do_bind( Connection *conn, @@ -33,9 +28,9 @@ do_bind( ) { BerElement *ber = op->o_ber; - int version, method, len; + int version, method; + char *cdn, *ndn; unsigned long rc; - char *dn; struct berval cred; Backend *be; @@ -62,24 +57,27 @@ do_bind( */ { - BerElement tber; + BerElement *tber; unsigned long tlen, ttag; - tber = *op->o_ber; - ttag = ber_skip_tag( &tber, &tlen ); - if ( ber_peek_tag( &tber, &tlen ) == LBER_SEQUENCE ) { - Debug( LDAP_DEBUG_ANY, "version 3.0 detected\n", 0, 0, 0 ); + tber = ber_dup( op->o_ber ); + ttag = ber_skip_tag( tber, &tlen ); + if ( ber_peek_tag( tber, &tlen ) == LBER_SEQUENCE ) { + Debug( LDAP_DEBUG_ANY, "bind: version 3.0 detected\n", 0, 0, 0 ); conn->c_version = 30; - rc = ber_scanf(ber, "{{iato}}", &version, &dn, &method, &cred); + rc = ber_scanf(ber, "{{iato}}", &version, &cdn, &method, &cred); } else { - rc = ber_scanf( ber, "{iato}", &version, &dn, &method, &cred ); + rc = ber_scanf( ber, "{iato}", &version, &cdn, &method, &cred ); } + + ber_free( tber, 1 ); } #else - rc = ber_scanf( ber, "{iato}", &version, &dn, &method, &cred ); + rc = ber_scanf( ber, "{iato}", &version, &cdn, &method, &cred ); #endif + if ( rc == LBER_ERROR ) { - Debug( LDAP_DEBUG_ANY, "ber_scanf failed\n", 0, 0, 0 ); + Debug( LDAP_DEBUG_ANY, "bind: ber_scanf failed\n", 0, 0, 0 ); send_ldap_result( conn, op, LDAP_PROTOCOL_ERROR, NULL, "decoding error" ); return; @@ -101,14 +99,21 @@ do_bind( } } #endif /* compat30 */ - dn_normalize( dn ); + + Debug( LDAP_DEBUG_TRACE, "do_bind: version %d dn (%s) method %d\n", + version, cdn, method ); + + ndn = dn_normalize_case( ch_strdup( cdn ) ); Statslog( LDAP_DEBUG_STATS, "conn=%d op=%d BIND dn=\"%s\" method=%d\n", - conn->c_connid, op->o_opid, dn, method, 0 ); + conn->c_connid, op->o_opid, ndn, method, 0 ); if ( version != LDAP_VERSION2 ) { - if ( dn != NULL ) { - free( dn ); + if ( cdn != NULL ) { + free( cdn ); + } + if ( ndn != NULL ) { + free( ndn ); } if ( cred.bv_val != NULL ) { free( cred.bv_val ); @@ -120,18 +125,34 @@ do_bind( return; } - Debug( LDAP_DEBUG_TRACE, "do_bind: version %d dn (%s) method %d\n", - version, dn, method ); - /* accept null binds */ - if ( dn == NULL || *dn == '\0' ) { - if ( dn != NULL ) { - free( dn ); + if ( ndn == NULL || *ndn == '\0' ) { + if ( cdn != NULL ) { + free( cdn ); + } + if ( ndn != NULL ) { + free( ndn ); } if ( cred.bv_val != NULL ) { free( cred.bv_val ); } + ldap_pvt_thread_mutex_lock( &conn->c_mutex ); + + conn->c_protocol = version; + + if ( conn->c_cdn != NULL ) { + free( conn->c_cdn ); + conn->c_cdn = NULL; + } + + if ( conn->c_dn != NULL ) { + free( conn->c_dn ); + conn->c_dn = NULL; + } + + ldap_pvt_thread_mutex_unlock( &conn->c_mutex ); + send_ldap_result( conn, op, LDAP_SUCCESS, NULL, NULL ); return; } @@ -142,12 +163,29 @@ do_bind( * if we don't hold it. */ - if ( (be = select_backend( dn )) == NULL ) { - free( dn ); + if ( (be = select_backend( ndn )) == NULL ) { + free( cdn ); + free( ndn ); if ( cred.bv_val != NULL ) { free( cred.bv_val ); } if ( cred.bv_len == 0 ) { + ldap_pvt_thread_mutex_lock( &conn->c_mutex ); + + conn->c_protocol = version; + + if ( conn->c_cdn != NULL ) { + free( conn->c_cdn ); + conn->c_cdn = NULL; + } + + if ( conn->c_dn != NULL ) { + free( conn->c_dn ); + conn->c_dn = NULL; + } + + ldap_pvt_thread_mutex_unlock( &conn->c_mutex ); + send_ldap_result( conn, op, LDAP_SUCCESS, NULL, NULL ); } else if ( default_referral && *default_referral ) { @@ -160,27 +198,58 @@ do_bind( return; } - /* alias suffix */ - dn = suffixAlias ( dn, op, be ); + if ( be->be_bind ) { + /* alias suffix */ + char *edn; + + ndn = suffixAlias( ndn, op, be ); + + if ( (*be->be_bind)( be, conn, op, ndn, method, &cred, &edn ) == 0 ) { + ldap_pvt_thread_mutex_lock( &conn->c_mutex ); + + conn->c_protocol = version; + + if ( conn->c_cdn != NULL ) { + free( conn->c_cdn ); + } + + conn->c_cdn = cdn; + cdn = NULL; - if ( be->be_bind != NULL ) { - if ( (*be->be_bind)( be, conn, op, dn, method, &cred ) == 0 ) { - pthread_mutex_lock( &conn->c_dnmutex ); if ( conn->c_dn != NULL ) { free( conn->c_dn ); } - conn->c_dn = strdup( dn ); - pthread_mutex_unlock( &conn->c_dnmutex ); + + if(edn != NULL) { + conn->c_dn = edn; + } else { + conn->c_dn = ndn; + ndn = NULL; + } + + Debug( LDAP_DEBUG_TRACE, "do_bind: bound \"%s\" to \"%s\"\n", + conn->c_cdn, conn->c_dn, method ); + + ldap_pvt_thread_mutex_unlock( &conn->c_mutex ); /* send this here to avoid a race condition */ send_ldap_result( conn, op, LDAP_SUCCESS, NULL, NULL ); + + } else if (edn != NULL) { + free( edn ); } + } else { send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM, NULL, "Function not implemented" ); } - free( dn ); + if( cdn != NULL ) { + free( cdn ); + } + if( ndn != NULL ) { + free( ndn ); + } if ( cred.bv_val != NULL ) { free( cred.bv_val ); }