]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/bind.c
Add search no-op support.
[openldap] / servers / slapd / bind.c
index d2747a0b67e16469e516b39cd189f2239eca83ee..142bf0f7a95f4a74c9d1868a7a120c2d6ce23d95 100644 (file)
@@ -1,7 +1,7 @@
 /* bind.c - decode an ldap bind operation and pass it to a backend db */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -36,10 +36,11 @@ do_bind(
        BerElement *ber = op->o_ber;
        ber_int_t version;
        ber_tag_t method;
-       char *mech = NULL;
+       struct berval mech = { 0, NULL };
        struct berval dn = { 0, NULL };
-       struct berval *pdn = NULL;
-       struct berval *ndn = NULL;
+       struct berval pdn = { 0, NULL };
+       struct berval ndn = { 0, NULL };
+       struct berval edn = { 0, NULL };
        ber_tag_t tag;
        int     rc = LDAP_SUCCESS;
        const char *text;
@@ -60,14 +61,16 @@ do_bind(
        connection2anonymous( conn );
        ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
 
-       if ( op->o_dn != NULL ) {
-               free( op->o_dn );
-               op->o_dn = ch_strdup( "" );
+       if ( op->o_dn.bv_val != NULL ) {
+               free( op->o_dn.bv_val );
+               op->o_dn.bv_val = ch_strdup( "" );
+               op->o_dn.bv_len = 0;
        }
 
-       if ( op->o_ndn != NULL ) {
-               free( op->o_ndn );
-               op->o_ndn = ch_strdup( "" );
+       if ( op->o_ndn.bv_val != NULL ) {
+               free( op->o_ndn.bv_val );
+               op->o_ndn.bv_val = ch_strdup( "" );
+               op->o_ndn.bv_len = 0;
        }
 
        /*
@@ -90,7 +93,7 @@ do_bind(
         *      }
         */
 
-       tag = ber_scanf( ber, "{iot" /*}*/, &version, &dn, &method );
+       tag = ber_scanf( ber, "{imt" /*}*/, &version, &dn, &method );
 
        if ( tag == LBER_ERROR ) {
 #ifdef NEW_LOGGING
@@ -108,17 +111,17 @@ do_bind(
        op->o_protocol = version;
 
        if( method != LDAP_AUTH_SASL ) {
-               tag = ber_scanf( ber, /*{*/ "o}", &cred );
+               tag = ber_scanf( ber, /*{*/ "m}", &cred );
 
        } else {
-               tag = ber_scanf( ber, "{a" /*}*/, &mech );
+               tag = ber_scanf( ber, "{o" /*}*/, &mech );
 
                if ( tag != LBER_ERROR ) {
                        ber_len_t len;
                        tag = ber_peek_tag( ber, &len );
 
                        if ( tag == LDAP_TAG_LDAPCRED ) { 
-                               tag = ber_scanf( ber, "o", &cred );
+                               tag = ber_scanf( ber, "m", &cred );
                        } else {
                                tag = LDAP_TAG_LDAPCRED;
                                cred.bv_val = NULL;
@@ -149,22 +152,7 @@ do_bind(
                goto cleanup;
        } 
 
-       rc = dnPretty( NULL, &dn, &pdn );
-       if ( rc != LDAP_SUCCESS ) {
-#ifdef NEW_LOGGING
-               LDAP_LOG(( "operation", LDAP_LEVEL_INFO,
-                       "do_bind: conn %d  invalid dn (%s)\n",
-                       conn->c_connid, dn.bv_val ));
-#else
-               Debug( LDAP_DEBUG_ANY, "bind: invalid dn (%s)\n",
-                       dn.bv_val, 0, 0 );
-#endif
-               send_ldap_result( conn, op, rc = LDAP_INVALID_DN_SYNTAX, NULL,
-                   "invalid DN", NULL, NULL );
-               goto cleanup;
-       }
-
-       rc = dnNormalize( NULL, &dn, &ndn );
+       rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn );
        if ( rc != LDAP_SUCCESS ) {
 #ifdef NEW_LOGGING
                LDAP_LOG(( "operation", LDAP_LEVEL_INFO,
@@ -183,10 +171,10 @@ do_bind(
 #ifdef NEW_LOGGING
                LDAP_LOG(( "operation",  LDAP_LEVEL_DETAIL1,
                        "do_sasl_bind: conn %d  dn (%s) mech %s\n", conn->c_connid,
-                       pdn->bv_val, mech ));
+                       pdn.bv_val, mech.bv_val ));
 #else
                Debug( LDAP_DEBUG_TRACE, "do_sasl_bind: dn (%s) mech %s\n",
-                       pdn->bv_val, mech, NULL );
+                       pdn.bv_val, mech.bv_val, NULL );
 #endif
 
        } else {
@@ -194,17 +182,17 @@ do_bind(
                LDAP_LOG(( "operation", LDAP_LEVEL_DETAIL1,
                        "do_bind: conn %d  version=%ld dn=\"%s\" method=%ld\n",
                        conn->c_connid, (unsigned long) version,
-                       pdn->bv_val, (unsigned long)method ));
+                       pdn.bv_val, (unsigned long)method ));
 #else
                Debug( LDAP_DEBUG_TRACE,
                        "do_bind: version=%ld dn=\"%s\" method=%ld\n",
                        (unsigned long) version,
-                       pdn->bv_val, (unsigned long) method );
+                       pdn.bv_val, (unsigned long) method );
 #endif
        }
 
        Statslog( LDAP_DEBUG_STATS, "conn=%ld op=%d BIND dn=\"%s\" method=%ld\n",
-           op->o_connid, op->o_opid, pdn->bv_val, (unsigned long) method, 0 );
+           op->o_connid, op->o_opid, pdn.bv_val, (unsigned long) method, 0 );
 
        if ( version < LDAP_VERSION_MIN || version > LDAP_VERSION_MAX ) {
 #ifdef NEW_LOGGING
@@ -234,8 +222,16 @@ do_bind(
        conn->c_protocol = version;
        ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
 
+       /* check for inappropriate controls */
+       if( get_manageDSAit( op ) == SLAP_CRITICAL_CONTROL ) {
+               send_ldap_result( conn, op,
+                       rc = LDAP_UNAVAILABLE_CRITICAL_EXTENSION,
+                       NULL, "manageDSAit control inappropriate",
+                       NULL, NULL );
+               goto cleanup;
+       }
+
        if ( method == LDAP_AUTH_SASL ) {
-               char *edn;
                slap_ssf_t ssf = 0;
 
                if ( version < LDAP_VERSION3 ) {
@@ -253,7 +249,7 @@ do_bind(
                        goto cleanup;
                }
 
-               if( mech == NULL || *mech == '\0' ) {
+               if( mech.bv_len == 0 ) {
 #ifdef NEW_LOGGING
                        LDAP_LOG(( "operation", LDAP_LEVEL_INFO,
                                   "do_bind: conn %d  no SASL mechanism provided\n",
@@ -269,7 +265,7 @@ do_bind(
                }
 
                /* check restrictions */
-               rc = backend_check_restrictions( NULL, conn, op, mech, &text );
+               rc = backend_check_restrictions( NULL, conn, op, mech.bv_val, &text );
                if( rc != LDAP_SUCCESS ) {
                        send_ldap_result( conn, op, rc,
                                NULL, text, NULL, NULL );
@@ -278,30 +274,31 @@ do_bind(
 
                ldap_pvt_thread_mutex_lock( &conn->c_mutex );
                if ( conn->c_sasl_bind_in_progress ) {
-                       if((strcmp(conn->c_sasl_bind_mech, mech) != 0)) {
+                       if((ber_bvcmp(&conn->c_sasl_bind_mech, &mech) != 0)) {
                                /* mechanism changed between bind steps */
                                slap_sasl_reset(conn);
                        }
                } else {
                        conn->c_sasl_bind_mech = mech;
-                       mech = NULL;
+                       mech.bv_val = NULL;
+                       mech.bv_len = 0;
                }
                ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
 
-               edn = NULL;
                rc = slap_sasl_bind( conn, op,
-                       pdn->bv_val, ndn->bv_val,
+                       &pdn, &ndn,
                        &cred, &edn, &ssf );
 
                ldap_pvt_thread_mutex_lock( &conn->c_mutex );
                if( rc == LDAP_SUCCESS ) {
                        conn->c_dn = edn;
-                       if( edn != NULL ) {
-                               conn->c_ndn = ch_strdup( edn );
-                               dn_normalize( conn->c_ndn );
+                       if( edn.bv_len != 0 ) {
+                               /* edn is always normalized already */
+                               ber_dupbv( &conn->c_ndn, &conn->c_dn );
                        }
                        conn->c_authmech = conn->c_sasl_bind_mech;
-                       conn->c_sasl_bind_mech = NULL;
+                       conn->c_sasl_bind_mech.bv_val = NULL;
+                       conn->c_sasl_bind_mech.bv_len = 0;
                        conn->c_sasl_bind_in_progress = 0;
 
                        conn->c_sasl_ssf = ssf;
@@ -309,7 +306,7 @@ do_bind(
                                conn->c_ssf = ssf;
                        }
 
-                       if( conn->c_dn != NULL ) {
+                       if( conn->c_dn.bv_len != 0 ) {
                                ber_len_t max = sockbuf_max_incoming;
                                ber_sockbuf_ctrl( conn->c_sb,
                                        LBER_SB_OPT_SET_MAX_INCOMING, &max );
@@ -319,9 +316,10 @@ do_bind(
                        conn->c_sasl_bind_in_progress = 1;
 
                } else {
-                       if ( conn->c_sasl_bind_mech ) {
-                               free( conn->c_sasl_bind_mech );
-                               conn->c_sasl_bind_mech = NULL;
+                       if ( conn->c_sasl_bind_mech.bv_val ) {
+                               free( conn->c_sasl_bind_mech.bv_val );
+                               conn->c_sasl_bind_mech.bv_val = NULL;
+                               conn->c_sasl_bind_mech.bv_len = 0;
                        }
                        conn->c_sasl_bind_in_progress = 0;
                }
@@ -333,9 +331,10 @@ do_bind(
                /* Not SASL, cancel any in-progress bind */
                ldap_pvt_thread_mutex_lock( &conn->c_mutex );
 
-               if ( conn->c_sasl_bind_mech != NULL ) {
-                       free(conn->c_sasl_bind_mech);
-                       conn->c_sasl_bind_mech = NULL;
+               if ( conn->c_sasl_bind_mech.bv_val != NULL ) {
+                       free(conn->c_sasl_bind_mech.bv_val);
+                       conn->c_sasl_bind_mech.bv_val = NULL;
+                       conn->c_sasl_bind_mech.bv_len = 0;
                }
                conn->c_sasl_bind_in_progress = 0;
 
@@ -345,7 +344,7 @@ do_bind(
 
        if ( method == LDAP_AUTH_SIMPLE ) {
                /* accept "anonymous" binds */
-               if ( cred.bv_len == 0 || ndn->bv_len == 0 ) {
+               if ( cred.bv_len == 0 || ndn.bv_len == 0 ) {
                        rc = LDAP_SUCCESS;
                        text = NULL;
 
@@ -355,7 +354,7 @@ do_bind(
                                /* cred is not empty, disallow */
                                rc = LDAP_INVALID_CREDENTIALS;
 
-                       } else if ( ndn->bv_len &&
+                       } else if ( ndn.bv_len &&
                                !( global_allows & SLAP_ALLOW_BIND_ANON_DN ))
                        {
                                /* DN is not empty, disallow */
@@ -368,7 +367,7 @@ do_bind(
                                text = "anonymous bind disallowed";
 
                        } else {
-                               rc = backend_check_restrictions( NULL, conn, op, mech, &text );
+                               rc = backend_check_restrictions( NULL, conn, op, mech.bv_val, &text );
                        }
 
                        /*
@@ -397,11 +396,11 @@ do_bind(
 #ifdef NEW_LOGGING
                        LDAP_LOG(( "operation", LDAP_LEVEL_INFO,
                                   "do_bind: conn %d  v%d simple bind(%s) disallowed\n",
-                                  conn->c_connid, version, ndn ));
+                                  conn->c_connid, version, ndn.bv_val ));
 #else
                        Debug( LDAP_DEBUG_TRACE,
                                "do_bind: v%d simple bind(%s) disallowed\n",
-                               version, ndn, 0 );
+                               version, ndn.bv_val, 0 );
 #endif
                        goto cleanup;
                }
@@ -451,15 +450,15 @@ do_bind(
         * if we don't hold it.
         */
 
-       if ( (be = select_backend( ndn->bv_val, 0, 0 )) == NULL ) {
+       if ( (be = select_backend( &ndn, 0, 0 )) == NULL ) {
                if ( default_referral ) {
-                       struct berval **ref = referral_rewrite( default_referral,
-                               NULL, pdn->bv_val, LDAP_SCOPE_DEFAULT );
+                       BerVarray ref = referral_rewrite( default_referral,
+                               NULL, &pdn, LDAP_SCOPE_DEFAULT );
 
                        send_ldap_result( conn, op, rc = LDAP_REFERRAL,
                                NULL, NULL, ref ? ref : default_referral, NULL );
 
-                       ber_bvecfree( ref );
+                       ber_bvarray_free( ref );
 
                } else {
                        /* noSuchObject is not allowed to be returned by bind */
@@ -482,34 +481,30 @@ do_bind(
 
        if ( be->be_bind ) {
                int ret;
-               /* alias suffix */
-               char *edn = NULL;
 
                /* deref suffix alias if appropriate */
-               ndn->bv_val = suffix_alias( be, ndn->bv_val );
-               ndn->bv_len = strlen( ndn->bv_val );
+               suffix_alias( be, &ndn );
 
                ret = (*be->be_bind)( be, conn, op,
-                       pdn->bv_val, ndn->bv_val,
-                       method, &cred, &edn );
+                       &pdn, &ndn, method, &cred, &edn );
 
                if ( ret == 0 ) {
                        ldap_pvt_thread_mutex_lock( &conn->c_mutex );
 
-                       conn->c_cdn = pdn->bv_val;
-                       dn.bv_val = NULL;
-                       dn.bv_len = 0;
-
-                       if(edn != NULL) {
+                       if(edn.bv_len) {
                                conn->c_dn = edn;
                        } else {
-                               conn->c_dn = ch_strdup( conn->c_cdn );
+                               ber_dupbv( &conn->c_dn, &pdn );
                        }
-                       conn->c_ndn = ndn->bv_val;
-                       ndn->bv_val = NULL;
-                       ndn->bv_len = 0;
+                       conn->c_cdn = pdn;
+                       pdn.bv_val = NULL;
+                       pdn.bv_len = 0;
 
-                       if( conn->c_dn != NULL ) {
+                       conn->c_ndn = ndn;
+                       ndn.bv_val = NULL;
+                       ndn.bv_len = 0;
+
+                       if( conn->c_dn.bv_len != 0 ) {
                                ber_len_t max = sockbuf_max_incoming;
                                ber_sockbuf_ctrl( conn->c_sb,
                                        LBER_SB_OPT_SET_MAX_INCOMING, &max );
@@ -518,11 +513,11 @@ do_bind(
 #ifdef NEW_LOGGING
                        LDAP_LOG(( "operation", LDAP_LEVEL_DETAIL1,
                                "do_bind: conn %d  v%d bind: \"%s\" to \"%s\" \n",
-                               conn->c_connid, version, conn->c_cdn, conn->c_dn ));
+                               conn->c_connid, version, conn->c_cdn.bv_val, conn->c_dn.bv_val ));
 #else
                        Debug( LDAP_DEBUG_TRACE,
                                "do_bind: v%d bind: \"%s\" to \"%s\"\n",
-                               version, conn->c_cdn, conn->c_dn );
+                               version, conn->c_cdn.bv_val, conn->c_dn.bv_val );
 #endif
 
                        ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
@@ -531,8 +526,8 @@ do_bind(
                        send_ldap_result( conn, op, LDAP_SUCCESS,
                                NULL, NULL, NULL, NULL );
 
-               } else if (edn != NULL) {
-                       free( edn );
+               } else if (edn.bv_val != NULL) {
+                       free( edn.bv_val );
                }
 
        } else {
@@ -542,18 +537,14 @@ do_bind(
        }
 
 cleanup:
-       free( dn.bv_val );
-       if( pdn != NULL ) {
-               ber_bvfree( pdn );
-       }
-       if( ndn != NULL ) {
-               ber_bvfree( ndn );
+       if( pdn.bv_val != NULL ) {
+               free( pdn.bv_val );
        }
-       if ( mech != NULL ) {
-               free( mech );
+       if( ndn.bv_val != NULL ) {
+               free( ndn.bv_val );
        }
-       if ( cred.bv_val != NULL ) {
-               free( cred.bv_val );
+       if ( mech.bv_val != NULL ) {
+               free( mech.bv_val );
        }
 
        return rc;