]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/backend.c
ITS#2888 don't return LDAP_SIZELIMIT_EXCEEDED prematurely
[openldap] / servers / slapd / backend.c
index a8682b255581d91c95c4379842affe0797e04178..79eb82d7c9b762c23684d7865e0f6b4813c26e8e 100644 (file)
@@ -1,9 +1,28 @@
+/* backend.c - routines for dealing with back-end databases */
 /* $OpenLDAP$ */
-/*
- * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
- * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 1998-2003 The OpenLDAP Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+/* Portions Copyright (c) 1995 Regents of the University of Michigan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and that due credit is given
+ * to the University of Michigan at Ann Arbor. The name of the University
+ * may not be used to endorse or promote products derived from this
+ * software without specific prior written permission. This software
+ * is provided ``as is'' without express or implied warranty.
  */
-/* backend.c - routines for dealing with back-end databases */
 
 
 #include "portable.h"
@@ -244,8 +263,6 @@ int backend_startup(Backend *be)
        int i;
        int rc = 0;
 
-       init_syncrepl();
-
        if( ! ( nBackendDB > 0 ) ) {
                /* no databases */
 #ifdef NEW_LOGGING
@@ -336,23 +353,6 @@ int backend_startup(Backend *be)
 
        /* open each backend database */
        for( i = 0; i < nBackendDB; i++ ) {
-               if ( backendDB[i].be_update_ndn.bv_val && (
-                       !backendDB[i].be_update_refs &&
-                       !backendDB[i].syncinfo &&
-                       !default_referral ) ) {
-#ifdef NEW_LOGGING
-                       LDAP_LOG( BACKEND, CRIT, 
-                               "backend_startup: slave \"%s\" updateref missing\n",
-                               backendDB[i].be_suffix[0].bv_val, 0, 0 );
-                               
-#else
-                       Debug( LDAP_DEBUG_ANY,
-                               "backend_startup: slave \"%s\" updateref missing\n",
-                               backendDB[i].be_suffix[0].bv_val, 0, 0 );
-#endif
-                       return -1;
-               }
-
                /* append global access controls */
                acl_append( &backendDB[i].be_acl, global_acl );
 
@@ -374,13 +374,16 @@ int backend_startup(Backend *be)
                        }
                }
 
-               if ( backendDB[i].syncinfo != NULL ) {
-                       syncinfo_t *si = ( syncinfo_t * ) backendDB[i].syncinfo;
-                       si->be = &backendDB[i];
-                       ldap_pvt_thread_mutex_lock( &syncrepl_rq.rq_mutex );
-                       ldap_pvt_runqueue_insert( &syncrepl_rq, si->interval,
-                                                       do_syncrepl, (void *) backendDB[i].syncinfo );
-                       ldap_pvt_thread_mutex_unlock( &syncrepl_rq.rq_mutex );
+               if ( !LDAP_STAILQ_EMPTY( &backendDB[i].be_syncinfo )) {
+                       syncinfo_t *si;
+                       LDAP_STAILQ_FOREACH( si, &backendDB[i].be_syncinfo, si_next ) {
+                               si->si_be = &backendDB[i];
+                               init_syncrepl( si );
+                               ldap_pvt_thread_mutex_lock( &syncrepl_rq.rq_mutex );
+                               ldap_pvt_runqueue_insert( &syncrepl_rq,
+                                               si->si_interval, do_syncrepl, (void *) si );
+                               ldap_pvt_thread_mutex_unlock( &syncrepl_rq.rq_mutex );
+                       }
                }
        }
 
@@ -550,7 +553,7 @@ backend_db_init(
        ldap_pvt_thread_mutex_init( &be->be_pcl_mutex );
        ldap_pvt_thread_mutex_init( &be->be_context_csn_mutex );
 
-       be->syncinfo = NULL;
+       LDAP_STAILQ_INIT( &be->be_syncinfo );
 
        /* assign a default depth limit for alias deref */
        be->be_max_deref_depth = SLAPD_DEFAULT_MAXDEREFDEPTH; 
@@ -743,31 +746,29 @@ int
 backend_unbind( Operation *op, SlapReply *rs )
 {
        int             i;
-#if defined( LDAP_SLAPI )
-       Slapi_PBlock *pb = op->o_pb;
-
-       int     rc;
-       slapi_x_pblock_set_operation( pb, op );
-#endif /* defined( LDAP_SLAPI ) */
 
        for ( i = 0; i < nbackends; i++ ) {
 #if defined( LDAP_SLAPI )
-               slapi_pblock_set( pb, SLAPI_BACKEND, (void *)&backends[i] );
-               rc = doPluginFNs( &backends[i], SLAPI_PLUGIN_PRE_UNBIND_FN,
-                               (Slapi_PBlock *)pb );
-               if ( rc < 0 ) {
-                       /*
-                        * A preoperation plugin failure will abort the
-                        * entire operation.
-                        */
+               if ( op->o_pb ) {
+                       int rc;
+                       if ( i == 0 ) slapi_int_pblock_set_operation( op->o_pb, op );
+                       slapi_pblock_set( op->o_pb, SLAPI_BACKEND, (void *)&backends[i] );
+                       rc = doPluginFNs( &backends[i], SLAPI_PLUGIN_PRE_UNBIND_FN,
+                                       (Slapi_PBlock *)op->o_pb );
+                       if ( rc < 0 ) {
+                               /*
+                                * A preoperation plugin failure will abort the
+                                * entire operation.
+                                */
 #ifdef NEW_LOGGING
-                       LDAP_LOG( OPERATION, INFO, "do_bind: Unbind preoperation plugin "
-                                       "failed\n", 0, 0, 0);
+                               LDAP_LOG( OPERATION, INFO, "do_bind: Unbind preoperation plugin "
+                                               "failed\n", 0, 0, 0);
 #else
-                       Debug(LDAP_DEBUG_TRACE, "do_bind: Unbind preoperation plugin "
-                                       "failed.\n", 0, 0, 0);
+                               Debug(LDAP_DEBUG_TRACE, "do_bind: Unbind preoperation plugin "
+                                               "failed.\n", 0, 0, 0);
 #endif
-                       return 0;
+                               return 0;
+                       }
                }
 #endif /* defined( LDAP_SLAPI ) */
 
@@ -777,8 +778,8 @@ backend_unbind( Operation *op, SlapReply *rs )
                }
 
 #if defined( LDAP_SLAPI )
-               if ( doPluginFNs( &backends[i], SLAPI_PLUGIN_POST_UNBIND_FN,
-                               (Slapi_PBlock *)pb ) < 0 ) {
+               if ( op->o_pb && doPluginFNs( &backends[i], SLAPI_PLUGIN_POST_UNBIND_FN,
+                               (Slapi_PBlock *)op->o_pb ) < 0 ) {
 #ifdef NEW_LOGGING
                        LDAP_LOG( OPERATION, INFO, "do_unbind: Unbind postoperation plugins "
                                        "failed\n", 0, 0, 0);
@@ -1034,7 +1035,7 @@ backend_check_restrictions(
                if( requires & SLAP_REQUIRE_STRONG ) {
                        /* should check mechanism */
                        if( ( op->o_transport_ssf < ssf->sss_transport
-                               && op->o_authmech.bv_len == 0 ) || op->o_dn.bv_len == 0 )
+                               && op->o_authtype == LDAP_AUTH_SIMPLE ) || op->o_dn.bv_len == 0 )
                        {
                                rs->sr_text = "strong authentication required";
                                rs->sr_err = LDAP_STRONG_AUTH_REQUIRED;
@@ -1043,7 +1044,7 @@ backend_check_restrictions(
                }
 
                if( requires & SLAP_REQUIRE_SASL ) {
-                       if( op->o_authmech.bv_len == 0 || op->o_dn.bv_len == 0 ) {
+                       if( op->o_authtype != LDAP_AUTH_SASL || op->o_dn.bv_len == 0 ) {
                                rs->sr_text = "SASL authentication required";
                                rs->sr_err = LDAP_STRONG_AUTH_REQUIRED;
                                return rs->sr_err;
@@ -1176,9 +1177,7 @@ backend_group(
 
        op->o_bd = select_backend( gr_ndn, 0, 0 );
 
-       ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
-
-       for (g = op->o_conn->c_groups; g; g=g->ga_next) {
+       for (g = op->o_groups; g; g=g->ga_next) {
                if (g->ga_be != op->o_bd || g->ga_oc != group_oc ||
                        g->ga_at != group_at || g->ga_len != gr_ndn->bv_len)
                        continue;
@@ -1186,8 +1185,6 @@ backend_group(
                        break;
        }
 
-       ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
-
        if (g) {
                rc = g->ga_res;
                goto done;
@@ -1195,6 +1192,7 @@ backend_group(
 
        if ( target && dn_match( &target->e_nname, gr_ndn ) ) {
                e = target;
+               rc = 0;
        } else {
                rc = be_entry_get_rw(op, gr_ndn, group_oc, group_at, 0, &e );
        }
@@ -1235,15 +1233,21 @@ backend_group(
                                                        goto loopit;
                                                switch(ludp->lud_scope) {
                                                case LDAP_SCOPE_BASE:
-                                                       if ( !dn_match(&nbase, op_ndn)) goto loopit;
+                                                       if ( !dn_match( &nbase, op_ndn )) goto loopit;
                                                        break;
                                                case LDAP_SCOPE_ONELEVEL:
                                                        dnParent(op_ndn, &bv );
-                                                       if ( !dn_match(&nbase, &bv)) goto loopit;
+                                                       if ( !dn_match( &nbase, &bv )) goto loopit;
                                                        break;
                                                case LDAP_SCOPE_SUBTREE:
-                                                       if ( !dnIsSuffix(op_ndn, &nbase)) goto loopit;
+                                                       if ( !dnIsSuffix( op_ndn, &nbase )) goto loopit;
                                                        break;
+                                               case LDAP_SCOPE_SUBORDINATE:
+                                                       if ( dn_match( &nbase, op_ndn ) &&
+                                                               !dnIsSuffix(op_ndn, &nbase ))
+                                                       {
+                                                               goto loopit;
+                                                       }
                                                }
                                                filter = str2filter_x( op, ludp->lud_filter );
                                                if ( filter ) {
@@ -1282,17 +1286,15 @@ backend_group(
        }
 
        if ( op->o_tag != LDAP_REQ_BIND && !op->o_do_not_cache ) {
-               g = ch_malloc(sizeof(GroupAssertion) + gr_ndn->bv_len);
+               g = sl_malloc(sizeof(GroupAssertion) + gr_ndn->bv_len, op->o_tmpmemctx);
                g->ga_be = op->o_bd;
                g->ga_oc = group_oc;
                g->ga_at = group_at;
                g->ga_res = rc;
                g->ga_len = gr_ndn->bv_len;
                strcpy(g->ga_ndn, gr_ndn->bv_val);
-               ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
-               g->ga_next = op->o_conn->c_groups;
-               op->o_conn->c_groups = g;
-               ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
+               g->ga_next = op->o_groups;
+               op->o_groups = g;
        }
 done:
        op->o_bd = be;