]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/backend.c
Silently restrict index_intlen to 4-255.
[openldap] / servers / slapd / backend.c
index f7f214e1874e4e9b262122f5a098187b1d6e90be..3eb2a679d4bfeefa6dc3a3371d9dcef9968b8be1 100644 (file)
@@ -34,6 +34,7 @@
 #include <sys/stat.h>
 
 #include "slap.h"
+#include "config.h"
 #include "lutil.h"
 #include "lber_pvt.h"
 
@@ -189,7 +190,7 @@ backend_set_controls( BackendDB *be )
 }
 
 /* startup a specific backend database */
-int backend_startup_one(Backend *be)
+int backend_startup_one(Backend *be, ConfigReply *cr)
 {
        int             rc = 0;
 
@@ -208,8 +209,19 @@ int backend_startup_one(Backend *be)
        /* set database controls */
        (void)backend_set_controls( be );
 
+#if 0
+       if ( !BER_BVISEMPTY( &be->be_rootndn )
+               && select_backend( &be->be_rootndn, 0 ) == be
+               && BER_BVISNULL( &be->be_rootpw ) )
+       {
+               /* warning: if rootdn entry is created,
+                * it can take rootdn privileges;
+                * set empty rootpw to prevent */
+       }
+#endif
+
        if ( be->bd_info->bi_db_open ) {
-               rc = be->bd_info->bi_db_open( be );
+               rc = be->bd_info->bi_db_open( be, cr );
                if ( rc == 0 ) {
                        (void)backend_set_controls( be );
 
@@ -228,6 +240,7 @@ int backend_startup(Backend *be)
        int i;
        int rc = 0;
        BackendInfo *bi;
+       ConfigReply cr={0, ""};
 
        if( ! ( nBackendDB > 0 ) ) {
                /* no databases */
@@ -251,12 +264,12 @@ int backend_startup(Backend *be)
                /* append global access controls */
                acl_append( &be->be_acl, frontendDB->be_acl, -1 );
 
-               return backend_startup_one( be );
+               return backend_startup_one( be, &cr );
        }
 
        /* open frontend, if required */
        if ( frontendDB->bd_info->bi_db_open ) {
-               rc = frontendDB->bd_info->bi_db_open( frontendDB );
+               rc = frontendDB->bd_info->bi_db_open( frontendDB, NULL );
                if ( rc != 0 ) {
                        Debug( LDAP_DEBUG_ANY,
                                "backend_startup: bi_db_open(frontend) failed! (%d)\n",
@@ -300,7 +313,7 @@ int backend_startup(Backend *be)
                /* append global access controls */
                acl_append( &be->be_acl, frontendDB->be_acl, -1 );
 
-               rc = backend_startup_one( be );
+               rc = backend_startup_one( be, &cr );
 
                if ( rc ) return rc;
        }
@@ -336,7 +349,7 @@ int backend_shutdown( Backend *be )
                }
 
                if ( be->bd_info->bi_db_close ) {
-                       be->bd_info->bi_db_close( be );
+                       be->bd_info->bi_db_close( be, NULL );
                }
 
                if( be->bd_info->bi_close ) {
@@ -349,7 +362,7 @@ int backend_shutdown( Backend *be )
        /* close each backend database */
        LDAP_STAILQ_FOREACH( be, &backendDB, be_next ) {
                if ( be->bd_info->bi_db_close ) {
-                       be->bd_info->bi_db_close( be );
+                       be->bd_info->bi_db_close( be, NULL );
                }
 
                if(rc != 0) {
@@ -373,7 +386,7 @@ int backend_shutdown( Backend *be )
 
        /* close frontend, if required */
        if ( frontendDB->bd_info->bi_db_close ) {
-               rc = frontendDB->bd_info->bi_db_close ( frontendDB );
+               rc = frontendDB->bd_info->bi_db_close ( frontendDB, NULL );
                if ( rc != 0 ) {
                        Debug( LDAP_DEBUG_ANY,
                                "backend_startup: bi_db_close(frontend) failed! (%d)\n",
@@ -411,14 +424,14 @@ backend_stopdown_one( BackendDB *bd )
        }
 
        if ( bd->bd_info->bi_db_destroy ) {
-               bd->bd_info->bi_db_destroy( bd );
+               bd->bd_info->bi_db_destroy( bd, NULL );
        }
 }
 
 void backend_destroy_one( BackendDB *bd, int dynamic )
 {
        if ( dynamic ) {
-               LDAP_STAILQ_REMOVE(&backendDB, bd, slap_backend_db, be_next );
+               LDAP_STAILQ_REMOVE(&backendDB, bd, BackendDB, be_next );
        }
 
        if ( bd->be_syncinfo ) {
@@ -440,16 +453,6 @@ void backend_destroy_one( BackendDB *bd, int dynamic )
        }
        acl_destroy( bd->be_acl, frontendDB->be_acl );
        limits_destroy( bd->be_limits );
-       if ( bd->be_replogfile ) {
-               ch_free( bd->be_replogfile );
-       }
-       if ( bd->be_replica_argsfile ) {
-               ch_free( bd->be_replica_argsfile );
-       }
-       if ( bd->be_replica_pidfile ) {
-               ch_free( bd->be_replica_pidfile );
-       }
-       destroy_replica_info( bd );
        if ( !BER_BVISNULL( &bd->be_update_ndn ) ) {
                ch_free( bd->be_update_ndn.bv_val );
        }
@@ -486,7 +489,7 @@ int backend_destroy(void)
        bd = frontendDB;
        if ( bd ) {
                if ( bd->bd_info->bi_db_destroy ) {
-                       bd->bd_info->bi_db_destroy( bd );
+                       bd->bd_info->bi_db_destroy( bd, NULL );
                }
                ber_bvarray_free( bd->be_suffix );
                ber_bvarray_free( bd->be_nsuffix );
@@ -500,17 +503,6 @@ int backend_destroy(void)
                        free( bd->be_rootpw.bv_val );
                }
                acl_destroy( bd->be_acl, frontendDB->be_acl );
-
-               if ( bd->be_replogfile != NULL ) {
-                       free( bd->be_replogfile );
-               }
-               if ( bd->be_replica_argsfile ) {
-                       ch_free( bd->be_replica_argsfile );
-               }
-               if ( bd->be_replica_pidfile ) {
-                       ch_free( bd->be_replica_pidfile );
-               }
-               assert( bd->be_replica == NULL );
        }
 
        return 0;
@@ -560,7 +552,7 @@ backend_db_move(
        int idx
 )
 {
-       LDAP_STAILQ_REMOVE(&backendDB, be, slap_backend_db, be_next);
+       LDAP_STAILQ_REMOVE(&backendDB, be, BackendDB, be_next);
        backend_db_insert(be, idx);
 }
 
@@ -568,7 +560,8 @@ BackendDB *
 backend_db_init(
     const char *type,
        BackendDB *b0,
-       int idx )
+       int idx,
+       ConfigReply *cr)
 {
        BackendInfo *bi = backend_info(type);
        BackendDB *be = b0;
@@ -607,14 +600,14 @@ backend_db_init(
        be->be_max_deref_depth = SLAPD_DEFAULT_MAXDEREFDEPTH; 
 
        if ( bi->bi_db_init ) {
-               rc = bi->bi_db_init( be );
+               rc = bi->bi_db_init( be, cr );
        }
 
        if ( rc != 0 ) {
                fprintf( stderr, "database init failed (%s)\n", type );
                /* If we created and linked this be, remove it and free it */
                if ( !b0 ) {
-                       LDAP_STAILQ_REMOVE(&backendDB, be, slap_backend_db, be_next);
+                       LDAP_STAILQ_REMOVE(&backendDB, be, BackendDB, be_next);
                        ch_free( be );
                        be = NULL;
                        nbackends--;
@@ -632,12 +625,12 @@ be_db_close( void )
 
        LDAP_STAILQ_FOREACH( be, &backendDB, be_next ) {
                if ( be->bd_info->bi_db_close ) {
-                       be->bd_info->bi_db_close( be );
+                       be->bd_info->bi_db_close( be, NULL );
                }
        }
 
        if ( frontendDB->bd_info->bi_db_close ) {
-               frontendDB->bd_info->bi_db_close( frontendDB );
+               frontendDB->bd_info->bi_db_close( frontendDB, NULL );
        }
 
 }
@@ -645,12 +638,11 @@ be_db_close( void )
 Backend *
 select_backend(
        struct berval * dn,
-       int manageDSAit,
        int noSubs )
 {
        int             j;
        ber_len_t       len, dnlen = dn->bv_len;
-       Backend         *be, *b2 = NULL;
+       Backend         *be;
 
        LDAP_STAILQ_FOREACH( be, &backendDB, be_next ) {
                if ( be->be_nsuffix == NULL || SLAP_DBHIDDEN( be )) {
@@ -684,28 +676,12 @@ select_backend(
                        if ( strcmp( be->be_nsuffix[j].bv_val,
                                &dn->bv_val[dnlen-len] ) == 0 )
                        {
-                               if( b2 == NULL ) {
-                                       b2 = be;
-
-                                       if( manageDSAit && len == dnlen &&
-                                               !SLAP_GLUE_SUBORDINATE( be ) ) {
-                                               continue;
-                                       }
-                               } else {
-                                       /* If any parts of the tree are glued, use the first
-                                        * match regardless of manageDSAit. Otherwise use the
-                                        * last match.
-                                        */
-                                       if( !( SLAP_DBFLAGS( be ) & ( SLAP_DBFLAG_GLUE_INSTANCE |
-                                               SLAP_DBFLAG_GLUE_SUBORDINATE )))
-                                               b2 = be;
-                               }
-                               return b2;
+                               return be;
                        }
                }
        }
 
-       return b2;
+       return be;
 }
 
 int
@@ -728,6 +704,26 @@ be_issuffix(
        return 0;
 }
 
+int
+be_issubordinate(
+    Backend *be,
+    struct berval *bvsubordinate )
+{
+       int     i;
+
+       if ( be->be_nsuffix == NULL ) {
+               return 0;
+       }
+
+       for ( i = 0; !BER_BVISNULL( &be->be_nsuffix[i] ); i++ ) {
+               if ( dnIsSuffix( bvsubordinate, &be->be_nsuffix[i] ) ) {
+                       return 1;
+               }
+       }
+
+       return 0;
+}
+
 int
 be_isroot_dn( Backend *be, struct berval *ndn )
 {
@@ -780,14 +776,46 @@ 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_BVISNULL( &op->o_bd->be_rootpw ) ) {
+               /* give the database a chance */
+               return SLAP_CB_CONTINUE;
        }
 
        if ( BER_BVISEMPTY( &op->o_bd->be_rootpw ) ) {
-               return 0;
+               /* rootdn bind explicitly disallowed */
+               rc = LDAP_INVALID_CREDENTIALS;
+               if ( rs ) {
+                       goto send_result;
+               }
+
+               return rc;
        }
 
 #ifdef SLAPD_SPASSWD
@@ -795,13 +823,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
@@ -1300,7 +1346,7 @@ fe_acl_group(
        GroupAssertion *g;
        Backend *be = op->o_bd;
 
-       op->o_bd = select_backend( gr_ndn, 0, 0 );
+       op->o_bd = select_backend( gr_ndn, 0 );
 
        for ( g = op->o_groups; g; g = g->ga_next ) {
                if ( g->ga_be != op->o_bd || g->ga_oc != group_oc ||
@@ -1418,7 +1464,7 @@ fe_acl_group(
                                                if ( user == NULL ) {   
                                                        int rc2;
 
-                                                       op->o_bd = select_backend( op_ndn, 0, 0 );
+                                                       op->o_bd = select_backend( op_ndn, 0 );
                                                        op->o_private = NULL;
                                                        rc2 = be_entry_get_rw( op, op_ndn, NULL, NULL, 0, &user );
                                                        user_priv = op->o_private;
@@ -1455,10 +1501,10 @@ loopit:
                                op->o_bd = b2;
 
                        } else {
-                               rc = value_find_ex( group_at,
+                               rc = attr_valfind( a,
                                        SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH |
                                        SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH,
-                                       a->a_nvals, op_ndn, op->o_tmpmemctx );
+                                       op_ndn, NULL, op->o_tmpmemctx );
                                if ( rc == LDAP_NO_SUCH_ATTRIBUTE ) {
                                        rc = LDAP_COMPARE_FALSE;
                                }
@@ -1537,7 +1583,7 @@ fe_acl_attribute(
        AccessControlState      acl_state = ACL_STATE_INIT;
        Backend                 *be = op->o_bd;
 
-       op->o_bd = select_backend( edn, 0, 0 );
+       op->o_bd = select_backend( edn, 0 );
 
        if ( target && dn_match( &target->e_nname, edn ) ) {
                e = target;
@@ -1602,9 +1648,7 @@ fe_acl_attribute(
                                goto freeit;
                        }
 
-                       for ( i = 0; !BER_BVISNULL( &a->a_vals[i] ); i++ )
-                               ;
-                       
+                       i = a->a_numvals;
                        v = op->o_tmpalloc( sizeof(struct berval) * ( i + 1 ),
                                op->o_tmpmemctx );
                        for ( i = 0, j = 0; !BER_BVISNULL( &a->a_vals[i] ); i++ )
@@ -1690,7 +1734,7 @@ backend_access(
        assert( edn != NULL );
        assert( access > ACL_NONE );
 
-       op->o_bd = select_backend( edn, 0, 0 );
+       op->o_bd = select_backend( edn, 0 );
 
        if ( target && dn_match( &target->e_nname, edn ) ) {
                e = target;
@@ -1812,7 +1856,7 @@ fe_aux_operational(
                BackendDB               *be_orig = op->o_bd;
 
                /* Let the overlays have a chance at this */
-               op->o_bd = select_backend( &op->o_req_ndn, 0, 0 );
+               op->o_bd = select_backend( &op->o_req_ndn, 0 );
                if ( op->o_bd != NULL && !be_match( op->o_bd, frontendDB ) &&
                        ( SLAP_OPATTRS( rs->sr_attr_flags ) || rs->sr_attrs ) &&
                        op->o_bd->be_operational != NULL )