]> git.sur5r.net Git - openldap/commitdiff
uniformly exploit rootdn bind; add support for rootdn bind to backends that didn...
authorPierangelo Masarati <ando@openldap.org>
Thu, 16 Aug 2007 09:38:15 +0000 (09:38 +0000)
committerPierangelo Masarati <ando@openldap.org>
Thu, 16 Aug 2007 09:38:15 +0000 (09:38 +0000)
14 files changed:
servers/slapd/back-bdb/bind.c
servers/slapd/back-dnssrv/bind.c
servers/slapd/back-ldap/bind.c
servers/slapd/back-ldif/ldif.c
servers/slapd/back-meta/bind.c
servers/slapd/back-monitor/bind.c
servers/slapd/back-perl/bind.c
servers/slapd/back-relay/op.c
servers/slapd/back-shell/bind.c
servers/slapd/back-sql/bind.c
servers/slapd/backend.c
servers/slapd/bconfig.c
servers/slapd/overlays/retcode.c
servers/slapd/proto-slap.h

index 84f3a38a0ef33ca47c4e8ed6aa0cd29b95eae216..634d398b07ac0cd7cabdc5a5048decae68838712 100644 (file)
@@ -40,10 +40,14 @@ bdb_bind( Operation *op, SlapReply *rs )
                op->o_req_dn.bv_val, 0, 0);
 
        /* allow noauth binds */
-       if ( op->oq_bind.rb_method == LDAP_AUTH_SIMPLE && be_isroot_pw( op )) {
-               ber_dupbv( &op->oq_bind.rb_edn, be_root_dn( op->o_bd ) );
-               /* front end will send result */
-               return LDAP_SUCCESS;
+       switch ( be_rootdn_bind( op, rs ) ) {
+       case SLAP_CB_CONTINUE:
+               break;
+
+       default:
+               /* in case of success, frontend will send result;
+                * otherwise, be_rootdn_bind() did */
+               return rs->sr_err;
        }
 
        rs->sr_err = LOCK_ID(bdb->bi_dbenv, &locker);
index 20fd959fc591aa8f28babe399e2e22333b7a292a..6bf68fda5d9d7c39b3bdfbe22037fa1a7b013da7 100644 (file)
 
 int
 dnssrv_back_bind(
-    Operation          *op,
-    SlapReply          *rs )
+       Operation       *op,
+       SlapReply       *rs )
 {
-       Debug( LDAP_DEBUG_TRACE, "DNSSRV: bind %s (%d)\n",
-               op->o_req_dn.bv_val == NULL ? "" : op->o_req_dn.bv_val, 
-               op->oq_bind.rb_method, NULL );
-               
-       if ( op->oq_bind.rb_method == LDAP_AUTH_SIMPLE &&
-               !BER_BVISNULL( &op->oq_bind.rb_cred ) &&
-               !BER_BVISEMPTY( &op->oq_bind.rb_cred ) )
+       Debug( LDAP_DEBUG_TRACE, "DNSSRV: bind dn=\"%s\" (%d)\n",
+               BER_BVISNULL( &op->o_req_dn ) ? "" : op->o_req_dn.bv_val, 
+               op->orb_method, 0 );
+
+       /* allow rootdn as a means to auth without the need to actually
+        * contact the proxied DSA */
+       switch ( be_rootdn_bind( op, NULL ) ) {
+       case LDAP_SUCCESS:
+               /* frontend will send result */
+               return rs->sr_err;
+
+       default:
+               /* treat failure and like any other bind, otherwise
+                * it could reveal the DN of the rootdn */
+               break;
+       }
+
+       if ( !BER_BVISNULL( &op->orb_cred ) &&
+               !BER_BVISEMPTY( &op->orb_cred ) )
        {
+               /* simple bind */
                Statslog( LDAP_DEBUG_STATS,
-                       "%s DNSSRV BIND dn=\"%s\" provided passwd\n",
+                       "%s DNSSRV BIND dn=\"%s\" provided cleartext passwd\n",
                        op->o_log_prefix,
                        BER_BVISNULL( &op->o_req_dn ) ? "" : op->o_req_dn.bv_val , 0, 0, 0 );
 
-               Debug( LDAP_DEBUG_TRACE,
-                       "DNSSRV: BIND dn=\"%s\" provided cleartext password\n",
-                       BER_BVISNULL( &op->o_req_dn ) ? "" : op->o_req_dn.bv_val, 0, 0 );
-
                send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
                        "you shouldn't send strangers your password" );
 
        } else {
+               /* unauthenticated bind */
+               /* NOTE: we're not going to get here anyway:
+                * unauthenticated bind is dealt with by the frontend */
                Debug( LDAP_DEBUG_TRACE, "DNSSRV: BIND dn=\"%s\"\n",
                        BER_BVISNULL( &op->o_req_dn ) ? "" : op->o_req_dn.bv_val, 0, 0 );
 
index 9d122e36a20c632d777b27af9bd43c7e3162163c..ebc51bdbd0da072fa4c774d009ddc35a8d4200ea 100644 (file)
@@ -177,6 +177,16 @@ ldap_back_bind( Operation *op, SlapReply *rs )
        ber_int_t               msgid;
        ldap_back_send_t        retrying = LDAP_BACK_RETRYING;
 
+       /* allow rootdn as a means to auth without the need to actually
+        * contact the proxied DSA */
+       switch ( be_rootdn_bind( op, rs ) ) {
+       case SLAP_CB_CONTINUE:
+               break;
+
+       default:
+               return rs->sr_err;
+       }
+
        lc = ldap_back_getconn( op, rs, LDAP_BACK_BIND_SERR, NULL, NULL );
        if ( !lc ) {
                return rs->sr_err;
index 5bbd8fe4ffeafd11cbf50402816f5822fe6fd604..6adee351adf17d935886db14cf29f68404790b55 100644 (file)
@@ -773,17 +773,23 @@ ldif_back_bind( Operation *op, SlapReply *rs )
        int return_val = 0;
        Entry * entry = NULL;
 
+       switch ( be_rootdn_bind( op, rs ) ) {
+       case SLAP_CB_CONTINUE:
+               break;
+
+       default:
+               /* in case of success, front end will send result;
+                * otherwise, be_rootdn_bind() did */
+               return rs->sr_err;
+       }
+
        li = (struct ldif_info *) op->o_bd->be_private;
        ldap_pvt_thread_rdwr_rlock(&li->li_rdwr);
        entry = get_entry(op, &li->li_base_path);
 
        /* no object is found for them */
        if(entry == NULL) {
-               if(be_isroot_pw(op)) {
-                       rs->sr_err = return_val = LDAP_SUCCESS;
-               } else {
-                       rs->sr_err = return_val = LDAP_INVALID_CREDENTIALS;
-               }
+               rs->sr_err = return_val = LDAP_INVALID_CREDENTIALS;
                goto return_result;
        }
 
index 143411236237972a1b09e446d6a2f8fb853e8aef..252e7264416ffec42d7f40ed9086ee6745b70523 100644 (file)
@@ -72,24 +72,22 @@ meta_back_bind( Operation *op, SlapReply *rs )
                op->o_log_prefix, op->o_req_dn.bv_val, 0 );
 
        /* the test on the bind method should be superfluous */
-       if ( op->orb_method == LDAP_AUTH_SIMPLE
-               && be_isroot_dn( op->o_bd, &op->o_req_ndn ) )
-       {
-               if ( !be_isroot_pw( op ) ) {
-                       rs->sr_err = LDAP_INVALID_CREDENTIALS;
-                       rs->sr_text = NULL;
-                       send_ldap_result( op, rs );
-                       return rs->sr_err;
-               }
-
+       switch ( be_rootdn_bind( op, rs ) ) {
+       case LDAP_SUCCESS:
                if ( META_BACK_DEFER_ROOTDN_BIND( mi ) ) {
-                       rs->sr_err = LDAP_SUCCESS;
-                       rs->sr_text = NULL;
                        /* frontend will return success */
                        return rs->sr_err;
                }
 
                isroot = 1;
+               /* fallthru */
+
+       case SLAP_CB_CONTINUE:
+               break;
+
+       default:
+               /* be_rootdn_bind() sent result */
+               return rs->sr_err;
        }
 
        /* we need meta_back_getconn() not send result even on error,
index bc7dbc5298874172f67dd9176199c03671dee393..984253479b3922cdc63d35802760a08f20f16cb9 100644 (file)
@@ -35,11 +35,8 @@ monitor_back_bind( Operation *op, SlapReply *rs )
 {
        Debug(LDAP_DEBUG_ARGS, "==> monitor_back_bind: dn: %s\n", 
                        op->o_req_dn.bv_val, 0, 0 );
-       
-       if ( op->oq_bind.rb_method == LDAP_AUTH_SIMPLE 
-                       && be_isroot_pw( op ) )
-       {
-               ber_dupbv( &op->oq_bind.rb_edn, be_root_dn( op->o_bd ) );
+
+       if ( be_isroot_pw( op ) ) {
                return LDAP_SUCCESS;
        }
 
index 2e19370f49a15a75140341ca3c79c606ca475875..878c48dfb04a0b9a4eec3e3e6ab569677e48b299 100644 (file)
@@ -32,6 +32,16 @@ perl_back_bind(
 
        PerlBackend *perl_back = (PerlBackend *) op->o_bd->be_private;
 
+       /* allow rootdn as a means to auth without the need to actually
+        * contact the proxied DSA */
+       switch ( be_rootdn_bind( op, rs ) ) {
+       case SLAP_CB_CONTINUE:
+               break;
+
+       default:
+               return rs->sr_err;
+       }
+
 #if defined(HAVE_WIN32_ASPERL) || defined(USE_ITHREADS)
        PERL_SET_CONTEXT( PERL_INTERPRETER );
 #endif
index e3a40db3a36dda01d68849e854568c7ea73e07cb..0616472458cd3600b2fb7e0bd8104da13ed2d888 100644 (file)
@@ -111,6 +111,16 @@ relay_back_op_bind( Operation *op, SlapReply *rs )
        BackendDB               *bd;
        int                     rc = 1;
 
+       /* allow rootdn as a means to auth without the need to actually
+        * contact the proxied DSA */
+       switch ( be_rootdn_bind( op, rs ) ) {
+       case SLAP_CB_CONTINUE:
+               break;
+
+       default:
+               return rs->sr_err;
+       }
+
        bd = relay_back_select_backend( op, rs, LDAP_INVALID_CREDENTIALS, 1 );
        if ( bd == NULL ) {
                return rc;
index 32d8865e3ddd7071330d0a0ee4156e22724d6804..dcbbcd4ba8274e271ea1e4b7e57d15c31ad1c001 100644 (file)
@@ -49,6 +49,16 @@ shell_back_bind(
        FILE                    *rfp, *wfp;
        int                     rc;
 
+       /* allow rootdn as a means to auth without the need to actually
+        * contact the proxied DSA */
+       switch ( be_rootdn_bind( op, rs ) ) {
+       case SLAP_CB_CONTINUE:
+               break;
+
+       default:
+               return rs->sr_err;
+       }
+
        if ( si->si_bind == NULL ) {
                send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
                    "bind not implemented" );
index 7db1ac8e5dbf88dca9b463ec654bf6352c22209f..4c8f710c0bdf59ff76b679b7af389536137bf47b 100644 (file)
@@ -40,25 +40,18 @@ backsql_bind( Operation *op, SlapReply *rs )
  
        Debug( LDAP_DEBUG_TRACE, "==>backsql_bind()\n", 0, 0, 0 );
 
-       if ( be_isroot_pw( op ) ) {
-               ber_dupbv( &op->oq_bind.rb_edn, be_root_dn( op->o_bd ) );
-               Debug( LDAP_DEBUG_TRACE, "<==backsql_bind() root bind\n", 
-                               0, 0, 0 );
-               return LDAP_SUCCESS;
-       }
-
-       ber_dupbv( &op->oq_bind.rb_edn, &op->o_req_ndn );
-
-       if ( op->oq_bind.rb_method != LDAP_AUTH_SIMPLE ) {
-               rs->sr_err = LDAP_STRONG_AUTH_NOT_SUPPORTED;
-               rs->sr_text = "authentication method not supported"; 
-               send_ldap_result( op, rs );
+       switch ( be_rootdn_bind( op, rs ) ) {
+       case SLAP_CB_CONTINUE:
+               break;
+
+       default:
+               /* in case of success, front end will send result;
+                * otherwise, be_rootdn_bind() did */
+               Debug( LDAP_DEBUG_TRACE, "<==backsql_bind(%d)\n",
+                       rs->sr_err, 0, 0 );
                return rs->sr_err;
        }
 
-       /*
-        * method = LDAP_AUTH_SIMPLE
-        */
        rs->sr_err = backsql_get_db_conn( op, &dbh );
        if ( !dbh ) {
                Debug( LDAP_DEBUG_TRACE, "backsql_bind(): "
index ab0ccd1f9555f95d3b8a6fb5387d6c518506f71d..ca1914fb2ad92fd2272e9c90aa7adeb449586f8c 100644 (file)
@@ -765,14 +765,40 @@ be_isroot( Operation *op )
 int
 be_isroot_pw( Operation *op )
 {
-       int result;
+       return be_rootdn_bind( op, NULL ) == LDAP_SUCCESS;
+}
 
-       if ( ! be_isroot_dn( op->o_bd, &op->o_req_ndn ) ) {
-               return 0;
+/*
+ * checks if binding as rootdn
+ *
+ * return value:
+ *     SLAP_CB_CONTINUE                if not the rootdn
+ *     LDAP_SUCCESS                    if rootdn & rootpw
+ *     LDAP_INVALID_CREDENTIALS        if rootdn & !rootpw
+ *
+ * if rs != NULL
+ *     if LDAP_SUCCESS, op->orb_edn is set
+ *     if LDAP_INVALID_CREDENTIALS, response is sent to client
+ */
+int
+be_rootdn_bind( Operation *op, SlapReply *rs )
+{
+       int             rc;
+
+       assert( op->o_tag == LDAP_REQ_BIND );
+       assert( op->orb_method == LDAP_AUTH_SIMPLE );
+
+       if ( !be_isroot_dn( op->o_bd, &op->o_req_ndn ) ) {
+               return SLAP_CB_CONTINUE;
        }
 
        if ( BER_BVISEMPTY( &op->o_bd->be_rootpw ) ) {
-               return 0;
+               rc = LDAP_INVALID_CREDENTIALS;
+               if ( rs ) {
+                       goto send_result;
+               }
+
+               return rc;
        }
 
 #ifdef SLAPD_SPASSWD
@@ -780,13 +806,31 @@ be_isroot_pw( Operation *op )
                op->o_conn->c_sasl_authctx, NULL );
 #endif
 
-       result = lutil_passwd( &op->o_bd->be_rootpw, &op->orb_cred, NULL, NULL );
+       rc = lutil_passwd( &op->o_bd->be_rootpw, &op->orb_cred, NULL, NULL );
 
 #ifdef SLAPD_SPASSWD
        ldap_pvt_thread_pool_setkey( op->o_threadctx, slap_sasl_bind, NULL, NULL );
 #endif
 
-       return result == 0;
+       rc = ( rc == 0 ? LDAP_SUCCESS : LDAP_INVALID_CREDENTIALS );
+       if ( rs ) {
+send_result:;
+               rs->sr_err = rc;
+
+               Debug( LDAP_DEBUG_TRACE, "%s: rootdn=\"%s\" bind%s\n", 
+                       op->o_log_prefix, op->o_bd->be_rootdn.bv_val,
+                       rc == LDAP_SUCCESS ? " succeeded" : " failed" );
+
+               if ( rc == LDAP_SUCCESS ) {
+                       /* Set to the pretty rootdn */
+                       ber_dupbv( &op->orb_edn, &op->o_bd->be_rootdn );
+
+               } else {
+                       send_ldap_result( op, rs );
+               }
+       }
+
+       return rc;
 }
 
 int
index c18d94333f34c59aaad396e0a23f01b44c333448..1829a74af8e0b996457eb21a4ab309da28f491d8 100644 (file)
@@ -3306,7 +3306,7 @@ done:
 static int
 config_back_bind( Operation *op, SlapReply *rs )
 {
-       if ( op->orb_method == LDAP_AUTH_SIMPLE && be_isroot_pw( op )) {
+       if ( be_isroot_pw( op ) ) {
                ber_dupbv( &op->orb_edn, be_root_dn( op->o_bd ));
                /* frontend sends result */
                return LDAP_SUCCESS;
index f5bca0ab1d85761a7a49b4453f736e2021eac54b..76b70d7be7b88b74dccdf018169e151adacddd65 100644 (file)
@@ -305,6 +305,7 @@ retcode_op_func( Operation *op, SlapReply *rs )
 
                        case LDAP_REQ_BIND:
                                /* skip if rootdn */
+                               /* FIXME: better give the db a chance? */
                                if ( be_isroot_pw( op ) ) {
                                        return LDAP_SUCCESS;
                                }
index 19b86837ec644ba38f1f6a376d29ee90239fff00..2e796c08d49801186b2612a14a2153b46696fe34 100644 (file)
@@ -345,6 +345,7 @@ LDAP_SLAPD_F (int) be_issubordinate LDAP_P(( Backend *be,
 LDAP_SLAPD_F (int) be_isroot LDAP_P(( Operation *op ));
 LDAP_SLAPD_F (int) be_isroot_dn LDAP_P(( Backend *be, struct berval *ndn ));
 LDAP_SLAPD_F (int) be_isroot_pw LDAP_P(( Operation *op ));
+LDAP_SLAPD_F (int) be_rootdn_bind LDAP_P(( Operation *op, SlapReply *rs ));
 LDAP_SLAPD_F (int) be_slurp_update LDAP_P(( Operation *op ));
 #define be_isupdate( op ) be_slurp_update( (op) )
 LDAP_SLAPD_F (int) be_shadow_update LDAP_P(( Operation *op ));