]> git.sur5r.net Git - openldap/commitdiff
Sync with HEAD OPENLDAP_REL_ENG_2_3_1ALPHA
authorKurt Zeilenga <kurt@openldap.org>
Wed, 2 Feb 2005 18:32:43 +0000 (18:32 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Wed, 2 Feb 2005 18:32:43 +0000 (18:32 +0000)
ready for 1alpha release

38 files changed:
build/version.var
doc/man/man5/slapd-ldap.5
doc/man/man5/slapo-glue.5
libraries/libldap/os-ip.c
servers/slapd/back-bdb/idl.c
servers/slapd/back-bdb/init.c
servers/slapd/back-dnssrv/init.c
servers/slapd/back-dnssrv/referral.c
servers/slapd/back-dnssrv/search.c
servers/slapd/back-ldap/back-ldap.h
servers/slapd/back-ldap/bind.c
servers/slapd/back-ldap/chain.c
servers/slapd/back-ldap/config.c
servers/slapd/back-ldap/init.c
servers/slapd/back-ldap/search.c
servers/slapd/back-ldbm/init.c
servers/slapd/back-monitor/init.c
servers/slapd/back-relay/init.c
servers/slapd/back-sql/init.c
servers/slapd/backend.c
servers/slapd/backover.c
servers/slapd/compare.c
servers/slapd/config.h
servers/slapd/controls.c
servers/slapd/frontend.c
servers/slapd/init.c
servers/slapd/overlays/glue.c
servers/slapd/overlays/refint.c
servers/slapd/overlays/rwm.c
servers/slapd/overlays/unique.c
servers/slapd/proto-slap.h
servers/slapd/result.c
servers/slapd/root_dse.c
servers/slapd/schema_init.c
servers/slapd/slap.h
servers/slapd/slapadd.c
tests/scripts/defines.sh
tests/scripts/test032-chain

index 598c9009bde5c2713d73b88c2f8390619f81f43e..3c6fb5bc5c1d0e24a29c47c002e18a73aed5d276 100644 (file)
@@ -15,9 +15,9 @@
 ol_package=OpenLDAP
 ol_major=2
 ol_minor=3
-ol_patch=X
-ol_api_inc=20300
+ol_patch=1alpha
+ol_api_inc=20301
 ol_api_current=0
-ol_api_revision=0
+ol_api_revision=1
 ol_api_age=0
-ol_release_date="2004/12/31"
+ol_release_date="2005/02/02"
index 893861c504a4fda15ea6e1b5c563e1cb29ab9240..c9253f9d1f99fc2f4ff15fc999577875c95ac837 100644 (file)
@@ -47,7 +47,7 @@ Other database options are described in the
 .BR slapd.conf (5)
 manual page.
 .LP
-Note: It is strongly recommended to set
+Note: In early versions of back-ldap it was recommended to always set
 .LP
 .RS
 .nf
@@ -63,6 +63,8 @@ database.
 This is because operational attributes related to entry creation and
 modification should not be used, as they could be passed to the target
 servers, generating an error.
+The current implementation automatically sets ldapmod to off, so its use
+is redundant and can be safely omitted.
 .TP
 .B uri <ldapurl>
 LDAP server to use.  Multiple URIs can be set in in a single
@@ -234,7 +236,30 @@ in conjunction with Proxy Authorization.
 .TP
 .B rebind-as-user
 If this option is given, the client's bind credentials are remembered
-for rebinds when chasing referrals.
+for rebinds when chasing referrals.  Useful in conjunction with
+\fBchase-referrals\fP, useless if \fBdont-chase-referrals\fP is set.
+.LP
+.B chase-referrals
+.br
+.B dont-chase-referrals
+.RS
+enable/disable automatic referral chasing, which is delegated to the
+underlying libldap, with rebinding eventually performed if the
+\fBrebind-as-user\fP directive is used.  The default is to chase referrals.
+.RE
+
+.LP
+.B start-tls
+.br
+.B try-start-tls
+.RS
+execute the start TLS extended operation when the connection is initialized.
+\fBtry-start-tls\fP continues operations if start TLS fails.
+.RE
+
+
+
+
 .TP
 .\".B suffixmassage <suffix> <massaged (remote) suffix>
 .\"DNs ending with <suffix> in a request are changed to end with <remote
index 4d106695da02d79e9291518c610cde12cb171692..a8083366391e4970a4fa5ff147720024b818930a 100644 (file)
@@ -30,11 +30,13 @@ directive and before any subsequent
 .B database
 directive.
 .TP
-.B glue-sub <suffix-DN> [async]
+.B glue-sub <suffix-DN> [async] [advertise]
 Specify the suffix of a database to attach as a subordinate to the root
 database. The specified database must have already been configured. If the
-optional "async" keyword is supplied, searches against this database may
-be spawned in a separate thread to run concurrently with other operations.
+optional \fBasync\fP keyword is supplied, searches against this database may
+be spawned in a separate thread to run concurrently with other operations
+(currently not implemented).  If the optional \fBadvertise\fI flag 
+is supplied, the naming context is advertised in the rootDSE.
 .SH FILES
 .TP
 ETCDIR/slapd.conf
index dad33ed000da23d5e89af2845a49c8756c719e14..ae5225ca00cccec0054dced619f1f8ffd985b8d8 100644 (file)
@@ -291,15 +291,16 @@ ldap_pvt_connect(LDAP *ld, ber_socket_t s,
                        return rc;
                }
 #endif
-               FD_ZERO(&wfds);
-               FD_SET(s, &wfds );
+
+               do {
+                       FD_ZERO(&wfds);
+                       FD_SET(s, &wfds );
 
 #ifdef HAVE_WINSOCK
-               FD_ZERO(&efds);
-               FD_SET(s, &efds );
+                       FD_ZERO(&efds);
+                       FD_SET(s, &efds );
 #endif
 
-               do {
                        rc = select(ldap_int_tblsize, z, &wfds,
 #ifdef HAVE_WINSOCK
                                &efds,
index 29a337218d3baa4facd6bbdd1bba9186caafe58c..038de21ef2507f619824241d24f9b30470344533 100644 (file)
@@ -292,6 +292,7 @@ bdb_idl_cache_get(
 {
        bdb_idl_cache_entry_t idl_tmp;
        bdb_idl_cache_entry_t *matched_idl_entry;
+       int rc = LDAP_NO_SUCH_OBJECT;
 
        DBT2bv( key, &idl_tmp.kstr );
        idl_tmp.db = db;
@@ -301,19 +302,18 @@ bdb_idl_cache_get(
        if ( matched_idl_entry != NULL ) {
                if ( matched_idl_entry->idl && ids )
                        BDB_IDL_CPY( ids, matched_idl_entry->idl );
-               ldap_pvt_thread_rdwr_runlock( &bdb->bi_idl_tree_rwlock );
                ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_lrulock );
                IDL_LRU_DELETE( bdb, matched_idl_entry );
                IDL_LRU_ADD( bdb, matched_idl_entry );
                ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock );
                if ( matched_idl_entry->idl )
-                       return LDAP_SUCCESS;
+                       rc = LDAP_SUCCESS;
                else
-                       return DB_NOTFOUND;
+                       rc = DB_NOTFOUND;
        }
        ldap_pvt_thread_rdwr_runlock( &bdb->bi_idl_tree_rwlock );
 
-       return LDAP_NO_SUCH_OBJECT;
+       return rc;
 }
 
 void
index 32892d6014fb71e05e1f4c02ae3a4f78ea8db674..39e92390929c3db31e038b005d74b7b1962c1d2f 100644 (file)
@@ -472,7 +472,6 @@ bdb_back_initialize(
 #ifdef LDAP_CONTROL_SUBENTRIES
                LDAP_CONTROL_SUBENTRIES,
 #endif
-               LDAP_CONTROL_VALUESRETURNFILTER,
 #ifdef LDAP_CONTROL_X_PERMISSIVE_MODIFY
                LDAP_CONTROL_X_PERMISSIVE_MODIFY,
 #endif
index e3f26d4aa0c4e4ab80e20d71bf3fb40061c18edd..980d231200509f2cb137e937d8bf3fe5f2622dfb 100644 (file)
@@ -34,13 +34,12 @@ dnssrv_back_initialize(
 {
        static char *controls[] = {
                LDAP_CONTROL_MANAGEDSAIT,
-               LDAP_CONTROL_VALUESRETURNFILTER,
                NULL
        };
 
        bi->bi_controls = controls;
 
-       bi->bi_open = 0;
+       bi->bi_open = dnssrv_back_open;
        bi->bi_config = 0;
        bi->bi_close = 0;
        bi->bi_destroy = 0;
@@ -71,6 +70,21 @@ dnssrv_back_initialize(
        return 0;
 }
 
+AttributeDescription   *ad_dc;
+AttributeDescription   *ad_associatedDomain;
+
+int
+dnssrv_back_open(
+    BackendInfo *bi )
+{
+       const char *text;
+
+       (void)slap_str2ad( "dc", &ad_dc, &text );
+       (void)slap_str2ad( "associatedDomain", &ad_associatedDomain, &text );
+
+       return 0;
+}
+
 int
 dnssrv_back_db_init(
     Backend    *be )
index 76b3372227c2da0b17e263d2b57b795078c9347b..77cd3fcc3f159e849af0b6d2d1677dfa0f439f01 100644 (file)
@@ -41,7 +41,15 @@ dnssrv_back_referrals(
        char **hosts = NULL;
        BerVarray urls = NULL;
 
-       if( op->o_req_dn.bv_len == 0 ) {
+       if ( BER_BVISEMPTY( &op->o_req_dn ) ) {
+#ifdef LDAP_DEVEL
+               /* FIXME: need some means to determine whether the database
+                * is a glue instance */
+               if ( SLAP_GLUE_INSTANCE( op->o_bd ) ) {
+                       return LDAP_SUCCESS;
+               }
+#endif /* LDAP_DEVEL */
+
                rs->sr_text = "DNS SRV operation upon null (empty) DN disallowed";
                return LDAP_UNWILLING_TO_PERFORM;
        }
index b191fca7fa523b0db4cc27e28ec52665c654963d..26fc1a32cd8823721710ed2bf59939fd25bd03e5 100644 (file)
@@ -47,11 +47,27 @@ dnssrv_back_search(
 
        rs->sr_ref = NULL;
 
+       if ( BER_BVISEMPTY( &op->o_req_ndn ) ) {
+#ifdef LDAP_DEVEL
+               /* FIXME: need some means to determine whether the database
+                * is a glue instance; if we got here with empty DN, then
+                * we passed this same test in dnssrv_back_referrals() */
+               if ( !SLAP_GLUE_INSTANCE( op->o_bd ) ) {
+                       rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+                       rs->sr_text = "DNS SRV operation upon null (empty) DN disallowed";
+
+               } else {
+                       rs->sr_err = LDAP_SUCCESS;
+               }
+               goto done;
+#endif /* LDAP_DEVEL */
+       }
+
        manageDSAit = get_manageDSAit( op );
        /*
         * FIXME: we may return a referral if manageDSAit is not set
         */
-       if ( ! manageDSAit ) {
+       if ( !manageDSAit ) {
                send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
                                "manageDSAit must be set" );
                goto done;
@@ -151,7 +167,6 @@ dnssrv_back_search(
                send_ldap_error( op, rs, LDAP_SUCCESS, NULL );
 
        } else {
-               struct berval   vals[2];
                Entry *e = ch_calloc( 1, sizeof(Entry) );
                AttributeDescription *ad_objectClass
                        = slap_schema.si_ad_objectClass;
@@ -164,54 +179,36 @@ dnssrv_back_search(
                e->e_attrs = NULL;
                e->e_private = NULL;
 
-               vals[1].bv_val = NULL;
-
-               vals[0].bv_val = "top";
-               vals[0].bv_len = sizeof("top")-1;
-               attr_mergeit( e, ad_objectClass, vals );
-
-               vals[0].bv_val = "referral";
-               vals[0].bv_len = sizeof("referral")-1;
-               attr_mergeit( e, ad_objectClass, vals );
+               attr_mergeit_one( e, ad_objectClass, &slap_schema.si_oc_top->soc_cname );
+               attr_mergeit_one( e, ad_objectClass, &slap_schema.si_oc_referral->soc_cname );
+               attr_mergeit_one( e, ad_objectClass, &slap_schema.si_oc_extensibleObject->soc_cname );
 
-               vals[0].bv_val = "extensibleObject";
-               vals[0].bv_len = sizeof("extensibleObject")-1;
-               attr_mergeit( e, ad_objectClass, vals );
+               if ( ad_dc ) {
+                       char            *p;
+                       struct berval   bv;
 
-               {
-                       AttributeDescription *ad = NULL;
-                       const char *text;
+                       bv.bv_val = domain;
 
-                       rc = slap_str2ad( "dc", &ad, &text );
+                       p = strchr( bv.bv_val, '.' );
+                                       
+                       if ( p == bv.bv_val ) {
+                               bv.bv_len = 1;
 
-                       if( rc == LDAP_SUCCESS ) {
-                               char *p;
-                               vals[0].bv_val = ch_strdup( domain );
+                       } else if ( p != NULL ) {
+                               bv.bv_len = p - bv.bv_val;
 
-                               p = strchr( vals[0].bv_val, '.' );
-                                       
-                               if( p == vals[0].bv_val ) {
-                                       vals[0].bv_val[1] = '\0';
-                               } else if ( p != NULL ) {
-                                       *p = '\0';
-                               }
-
-                               vals[0].bv_len = strlen(vals[0].bv_val);
-                               attr_mergeit( e, ad, vals );
+                       } else {
+                               bv.bv_len = strlen( bv.bv_val );
                        }
-               }
 
-               {
-                       AttributeDescription *ad = NULL;
-                       const char *text;
+                       attr_mergeit_one( e, ad_dc, &bv );
+               }
 
-                       rc = slap_str2ad( "associatedDomain", &ad, &text );
+               if ( ad_associatedDomain ) {
+                       struct berval   bv;
 
-                       if( rc == LDAP_SUCCESS ) {
-                               vals[0].bv_val = domain;
-                               vals[0].bv_len = strlen(domain);
-                               attr_mergeit( e, ad, vals );
-                       }
+                       ber_str2bv( domain, 0, 0, &bv );
+                       attr_mergeit_one( e, ad_associatedDomain, &bv );
                }
 
                attr_mergeit( e, ad_ref, urls );
index 174a7039c580685be77921ebb4e0ed18345279d9..f881c387495f499e684b0cf691884c8682b04d35 100644 (file)
@@ -95,6 +95,7 @@ struct ldapinfo {
 #define LDAP_BACK_F_SAVECRED           0x01U
 #define LDAP_BACK_F_USE_TLS            0x02U
 #define LDAP_BACK_F_TLS_CRITICAL       ( 0x04U | LDAP_BACK_F_USE_TLS )
+#define LDAP_BACK_F_CHASE_REFERRALS    0x8U
        Avlnode         *conntree;
 
        int             rwm_started;
index bdf8078e2f25b9665ce0ae4062ccd498e207bef8..817235ee3a36d7d957bac16540b95c534bbe6111 100644 (file)
@@ -68,7 +68,7 @@ ldap_back_bind( Operation *op, SlapReply *rs )
        rs->sr_err = ldap_sasl_bind( lc->lc_ld, op->o_req_dn.bv_val,
                        LDAP_SASL_SIMPLE,
                        &op->orb_cred, op->o_ctrls, NULL, &msgid );
-       rc = ldap_back_op_result( lc, op, rs, msgid, LDAP_BACK_SENDRESULT );
+       rc = ldap_back_op_result( lc, op, rs, msgid, LDAP_BACK_SENDERR );
 
        if ( rc == LDAP_SUCCESS ) {
                /* If defined, proxyAuthz will be used also when
@@ -241,15 +241,12 @@ ldap_back_prepare_conn( struct ldapconn **lcp, Operation *op, SlapReply *rs, lda
         */
        ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, (const void *)&vers );
 
-       /* Set LDAP version. This will always succeed: If the client
-        * bound with a particular version, then so can we.
-        */
-       ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION,
-                       (const void *)&vers );
-
-       /* FIXME: configurable? */
-       ldap_set_option( ld, LDAP_OPT_REFERRALS, LDAP_OPT_ON );
+       /* automatically chase referrals ("chase-referrals"/"dont-chase-referrals" statement) */
+       if ( li->flags & LDAP_BACK_F_CHASE_REFERRALS ) {
+               ldap_set_option( ld, LDAP_OPT_REFERRALS, LDAP_OPT_ON );
+       }
 
+       /* start TLS ("start-tls"/"try-start-tls" statements) */
        if ( ( li->flags & LDAP_BACK_F_USE_TLS )
                        && !ldap_is_ldaps_url( li->url )
                        && ( rs->sr_err = ldap_start_tls_s( ld, NULL, NULL ) ) != LDAP_SUCCESS )
index d481abb7a486707060f8b820c0896d517adeec95..7dcb95f29fc1d36a5c1c76e6fc8b8910d4f01bf1 100644 (file)
@@ -614,6 +614,23 @@ ldap_chain_db_destroy(
        return rc;
 }
 
+static int
+ldap_chain_connection_destroy(
+       BackendDB *be,
+       Connection *conn
+)
+{
+       slap_overinst *on = (slap_overinst *) be->bd_info;
+       void *private = be->be_private;
+       int rc;
+
+       be->be_private = on->on_bi.bi_private;
+       rc = lback->bi_connection_destroy( be, conn );
+       on->on_bi.bi_private = be->be_private;
+       be->be_private = private;
+       return rc;
+}
+
 #ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
 static int
 ldap_chain_parse_ctrl(
@@ -766,18 +783,20 @@ chain_init( void )
 #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
        ldapchain.on_bi.bi_db_config = ldap_chain_db_config;
        ldapchain.on_bi.bi_db_destroy = ldap_chain_db_destroy;
-       
+
        /* ... otherwise the underlying backend's function would be called,
         * likely passing an invalid entry; on the contrary, the requested
         * operational attributes should have been returned while chasing
         * the referrals.  This all in all is a bit messy, because part
-        * of the operational attributes are generated by they backend;
+        * of the operational attributes are generated by the backend;
         * part by the frontend; back-ldap should receive all the available
-        * ones from the remote server, but then, on it own, it strips those
+        * ones from the remote server, but then, on its own, it strips those
         * it assumes will be (re)generated by the frontend (e.g.
         * subschemaSubentry.) */
        ldapchain.on_bi.bi_operational = ldap_chain_operational;
        
+       ldapchain.on_bi.bi_connection_destroy = ldap_chain_connection_destroy;
+
        ldapchain.on_response = ldap_chain_response;
 
        return overlay_register( &ldapchain );
index 470becaa3cef9d773b84355b1799bcf7192142d1..afd8f712041c8a4b2f86764607f3ed35516be5a8 100644 (file)
@@ -289,12 +289,32 @@ ldap_back_db_config(
        } else if ( strcasecmp( argv[0], "rebind-as-user" ) == 0 ) {
                if ( argc != 1 ) {
                        fprintf( stderr,
-       "%s: line %d: rebind-as-user takes no arguments\n",
+       "%s: line %d: \"rebind-as-user\" takes no arguments\n",
                                        fname, lineno );
                        return( 1 );
                }
                li->flags |= LDAP_BACK_F_SAVECRED;
-       
+
+       } else if ( strcasecmp( argv[0], "chase-referrals" ) == 0 ) {
+               if ( argc != 1 ) {
+                       fprintf( stderr,
+       "%s: line %d: \"chase-referrals\" takes no arguments\n",
+                                       fname, lineno );
+                       return( 1 );
+               }
+
+               li->flags |= LDAP_BACK_F_CHASE_REFERRALS;
+
+       } else if ( strcasecmp( argv[0], "dont-chase-referrals" ) == 0 ) {
+               if ( argc != 1 ) {
+                       fprintf( stderr,
+       "%s: line %d: \"dont-chase-referrals\" takes no arguments\n",
+                                       fname, lineno );
+                       return( 1 );
+               }
+
+               li->flags &= ~LDAP_BACK_F_CHASE_REFERRALS;
+
        /* intercept exop_who_am_i? */
        } else if ( strcasecmp( argv[0], "proxy-whoami" ) == 0 ) {
                if ( argc != 1 ) {
index 84f47becbd447c63b667605bb9a207c04a4fbf7f..08767a481123c2e4264e0c34ffd67c5a10518f20 100644 (file)
@@ -109,6 +109,9 @@ ldap_back_db_init( Backend *be )
        /* by default, use proxyAuthz control on each operation */
        li->idassert_flags = LDAP_BACK_AUTH_NONE;
 
+       /* initialize flags */
+       li->flags = LDAP_BACK_F_CHASE_REFERRALS;
+
        ldap_pvt_thread_mutex_init( &li->conn_mutex );
 
        be->be_private = li;
index cd84f8dcda2be003f328acfe53f3e26170b9609d..8c610a57980b1c18b1006a4c2a060a51f58a5f17 100644 (file)
@@ -573,8 +573,8 @@ ldap_back_entry_get(
        
 retry:
        rc = ldap_search_ext_s( lc->lc_ld, ndn->bv_val, LDAP_SCOPE_BASE, filter,
-                               at ? gattr : NULL, 0, ctrls, NULL, LDAP_NO_LIMIT,
-                               LDAP_NO_LIMIT, &result );
+                               at ? gattr : NULL, 0, ctrls, NULL,
+                               LDAP_NO_LIMIT, LDAP_NO_LIMIT, &result );
        if ( rc != LDAP_SUCCESS ) {
                if ( rc == LDAP_SERVER_DOWN && do_retry ) {
                        do_retry = 0;
index 424e621b16c35193caefa0ab906f11f918c883eb..85802bff9d3d9424ad07fd0d4b7c64d0a723ddc9 100644 (file)
@@ -31,7 +31,6 @@ ldbm_back_initialize(
 {
        static char *controls[] = {
                LDAP_CONTROL_MANAGEDSAIT,
-               LDAP_CONTROL_VALUESRETURNFILTER,
 #ifdef LDAP_CONTROL_X_PERMISSIVE_MODIFY
                LDAP_CONTROL_X_PERMISSIVE_MODIFY,
 #endif
index 437815779cbd87a62caf26c0bdf4cffc7685cdb2..6fed315d2f2c7cfce77139683fe845877c6fad87 100644 (file)
@@ -671,7 +671,6 @@ monitor_back_initialize(
        monitor_subsys_t        *ms;
        static char             *controls[] = {
                LDAP_CONTROL_MANAGEDSAIT,
-               LDAP_CONTROL_VALUESRETURNFILTER,
                NULL
        };
 
index d5a3d9ac15a5d4abacad01c05896079954e688ba..d3b19e6d496d8fafb53b88c47a697f9a1d745e6e 100644 (file)
@@ -21,6 +21,7 @@
 #include "portable.h"
 
 #include <stdio.h>
+#include <ac/string.h>
 
 #include "slap.h"
 #include "back-relay.h"
@@ -102,15 +103,11 @@ relay_back_db_open( Backend *be )
                assert( ri->ri_bd );
 
                /* inherit controls */
-               if ( ri->ri_bd->be_controls ) {
-                       be->be_controls = ldap_charray_dup( ri->ri_bd->be_controls );
-               }
+               AC_MEMCPY( be->be_ctrls, ri->ri_bd->be_ctrls, sizeof( be->be_ctrls ) );
 
        } else {
                /* inherit all? */
-               if ( frontendDB->be_controls ) {
-                       be->be_controls = ldap_charray_dup( frontendDB->be_controls );
-               }
+               AC_MEMCPY( be->be_ctrls, frontendDB->be_ctrls, sizeof( be->be_ctrls ) );
        }
 
        return 0;
index 69c72e85c70ed20574274acc6ca80e14388de1f0..4a236a17183f2407a281676d4e44ad93c53804b0 100644 (file)
@@ -42,9 +42,6 @@ sql_back_initialize(
 #ifdef LDAP_CONTROL_X_TREE_DELETE
                LDAP_CONTROL_X_TREE_DELETE,
 #endif /* LDAP_CONTROL_X_TREE_DELETE */
-#ifdef LDAP_CONTROL_VALUESRETURNFILTER
-               LDAP_CONTROL_VALUESRETURNFILTER,
-#endif /* LDAP_CONTROL_VALUESRETURNFILTER */
                NULL
        };
 
index 084a82568855d6c7b41a0eec3bbe0e25aa20358b..daaf2454397826605978ef0564331bfd818314de 100644 (file)
@@ -65,6 +65,32 @@ BackendDB            *backendDB = NULL;
 ldap_pvt_thread_pool_t syncrepl_pool;
 int                    syncrepl_pool_max = SLAP_MAX_SYNCREPL_THREADS;
 
+static int
+backend_init_controls( BackendInfo *bi )
+{
+       if ( bi->bi_controls ) {
+               int     i;
+
+               for ( i = 0; bi->bi_controls[ i ]; i++ ) {
+                       int     cid;
+
+                       if ( slap_find_control_id( bi->bi_controls[ i ], &cid )
+                                       == LDAP_CONTROL_NOT_FOUND )
+                       {
+                               if ( !( slapMode & SLAP_TOOL_MODE ) ) {
+                                       assert( 0 );
+                               }
+
+                               return -1;
+                       }
+
+                       bi->bi_ctrls[ cid ] = 1;
+               }
+       }
+
+       return 0;
+}
+
 int backend_init(void)
 {
        int rc = -1;
@@ -132,12 +158,15 @@ int backend_add(BackendInfo *aBackendInfo)
                return -1;
        }
 
-   if ((rc = aBackendInfo->bi_init(aBackendInfo)) != 0) {
+       rc = aBackendInfo->bi_init(aBackendInfo);
+       if ( rc != 0) {
                Debug( LDAP_DEBUG_ANY,
                        "backend_add:  initialization for type \"%s\" failed\n",
                        aBackendInfo->bi_type, 0, 0 );
                return rc;
-   }
+       }
+
+       (void)backend_init_controls( aBackendInfo );
 
        /* now add the backend type to the Backend Info List */
        {
@@ -161,65 +190,66 @@ int backend_add(BackendInfo *aBackendInfo)
        }
 }
 
+static int
+backend_set_controls( BackendDB *be )
+{
+       BackendInfo     *bi = be->bd_info;
+
+       /* back-relay takes care of itself; so may do other */
+       if ( overlay_is_over( be ) ) {
+               bi = ((slap_overinfo *)be->bd_info->bi_private)->oi_orig;
+       }
+
+       if ( bi->bi_controls ) {
+               if ( be->be_ctrls[ SLAP_MAX_CIDS ] == 0 ) {
+                       AC_MEMCPY( be->be_ctrls, bi->bi_ctrls,
+                                       sizeof( be->be_ctrls ) );
+                       be->be_ctrls[ SLAP_MAX_CIDS ] = 1;
+                       
+               } else {
+                       int     i;
+                       
+                       for ( i = 0; i < SLAP_MAX_CIDS; i++ ) {
+                               if ( bi->bi_ctrls[ i ] ) {
+                                       be->be_ctrls[ i ] = bi->bi_ctrls[ i ];
+                               }
+                       }
+               }
+
+       }
+
+       return 0;
+}
+
 /* startup a specific backend database */
 int backend_startup_one(Backend *be)
 {
        int             rc = 0;
-       BackendInfo     *bi = be->bd_info;
 
-       assert(be);
+       assert( be );
 
        be->be_pending_csn_list = (struct be_pcl *)
                ch_calloc( 1, sizeof( struct be_pcl ));
 
        LDAP_TAILQ_INIT( be->be_pending_csn_list );
 
-       /* back-relay takes care of itself; so may do other */
-       if ( be->be_controls == NULL ) {
-               if ( overlay_is_over( be ) ) {
-                       bi = ((slap_overinfo *)be->bd_info->bi_private)->oi_orig;
-               }
-
-               if ( bi->bi_controls ) {
-                       be->be_controls = ldap_charray_dup( bi->bi_controls );
-               }
-       }
-
        Debug( LDAP_DEBUG_TRACE,
-               "backend_startup: starting \"%s\"\n",
+               "backend_startup_one: starting \"%s\"\n",
                be->be_suffix ? be->be_suffix[0].bv_val : "(unknown)",
                0, 0 );
-       if ( be->bd_info->bi_db_open ) {
-               rc = be->bd_info->bi_db_open( be );
-               if ( rc != 0 ) {
-                       Debug( LDAP_DEBUG_ANY,
-                               "backend_startup: bi_db_open failed! (%d)\n",
-                               rc, 0, 0 );
-               }
-       }
 
-       /* back-relay takes care of itself; so may do other */
-       bi = be->bd_info;
-       if ( overlay_is_over( be ) ) {
-               bi = ((slap_overinfo *)be->bd_info->bi_private)->oi_orig;
-       }
+       /* set database controls */
+       (void)backend_set_controls( be );
 
-       if ( bi->bi_controls ) {
-               if ( be->be_controls == NULL ) {
-                       be->be_controls = ldap_charray_dup( bi->bi_controls );
+       if ( be->bd_info->bi_db_open ) {
+               rc = be->bd_info->bi_db_open( be );
+               if ( rc == 0 ) {
+                       (void)backend_set_controls( be );
 
                } else {
-                       int     i;
-
-                       /* maybe not efficient, but it's startup and few dozens of controls... */
-                       for ( i = 0; bi->bi_controls[ i ]; i++ ) {
-                               if ( !ldap_charray_inlist( be->be_controls, bi->bi_controls[ i ] ) ) {
-                                       rc = ldap_charray_add( &be->be_controls, bi->bi_controls[ i ] );
-                                       if ( rc != 0 ) {
-                                               break;
-                                       }
-                               }
-                       }
+                       Debug( LDAP_DEBUG_ANY,
+                               "backend_startup_one: bi_db_open failed! (%d)\n",
+                               rc, 0, 0 );
                }
        }
 
@@ -273,8 +303,7 @@ int backend_startup(Backend *be)
                }
 
                if( backendInfo[i].bi_open ) {
-                       rc = backendInfo[i].bi_open(
-                               &backendInfo[i] );
+                       rc = backendInfo[i].bi_open( &backendInfo[i] );
                        if ( rc != 0 ) {
                                Debug( LDAP_DEBUG_ANY,
                                        "backend_startup: bi_open %d failed!\n",
@@ -282,6 +311,8 @@ int backend_startup(Backend *be)
                                return rc;
                        }
                }
+
+               (void)backend_init_controls( &backendInfo[i] );
        }
 
        ldap_pvt_thread_mutex_init( &slapd_rq.rq_mutex );
@@ -448,9 +479,6 @@ int backend_destroy(void)
                        free( bd->be_rootpw.bv_val );
                }
                acl_destroy( bd->be_acl, frontendDB->be_acl );
-               if ( bd->be_controls ) {
-                       ldap_charray_free( bd->be_controls );
-               }
        }
        free( backendDB );
 
@@ -836,7 +864,7 @@ backend_connection_destroy(
        return 0;
 }
 
-static int
+int
 backend_check_controls(
        Operation *op,
        SlapReply *rs )
@@ -847,9 +875,9 @@ backend_check_controls(
        if( ctrls ) {
                for( ; *ctrls != NULL ; ctrls++ ) {
                        int cid;
-                       if( slap_find_control_id( (*ctrls)->ldctl_oid, &cid ) ==
-                               LDAP_CONTROL_NOT_FOUND )
-                       {
+
+                       switch ( slap_global_control( op, (*ctrls)->ldctl_oid, &cid ) ) {
+                       case LDAP_CONTROL_NOT_FOUND:
                                /* unrecognized control */ 
                                if ( (*ctrls)->ldctl_iscritical ) {
                                        /* should not be reachable */ 
@@ -858,27 +886,39 @@ backend_check_controls(
                                                (*ctrls)->ldctl_oid, 0, 0 );
                                        assert( 0 );
                                }
+                               break;
 
-                       } else if ( !slap_global_control( op, (*ctrls)->ldctl_oid ) &&
-                               !ldap_charray_inlist( op->o_bd->be_controls,
-                                       (*ctrls)->ldctl_oid ) )
-                       {
-                               /* Per RFC 2251 (and LDAPBIS discussions), if the control
-                                * is recognized and appropriate for the operation (which
-                                * we've already verified), then the server should make
-                                * use of the control when performing the operation.
-                                * 
-                                * Here we find that operation extended by the control
-                                * is not unavailable in a particular context, hence the
-                                * return of unwillingToPerform.
-                                */
-                               rs->sr_text = "control unavailable in context";
-                               rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+                       case LDAP_COMPARE_FALSE:
+                               if ( !op->o_bd->be_ctrls[ cid ] )
+                               {
+                                       /* Per RFC 2251 (and LDAPBIS discussions), if the control
+                                        * is recognized and appropriate for the operation (which
+                                        * we've already verified), then the server should make
+                                        * use of the control when performing the operation.
+                                        * 
+                                        * Here we find that operation extended by the control
+                                        * is not unavailable in a particular context, hence the
+                                        * return of unwillingToPerform.
+                                        */
+                                       rs->sr_text = "control unavailable in context";
+                                       rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+                                       goto done;
+                               }
                                break;
+
+                       case LDAP_COMPARE_TRUE:
+                               break;
+
+                       default:
+                               /* unreachable */
+                               rs->sr_text = "unable to check control";
+                               rs->sr_err = LDAP_OTHER;
+                               goto done;
                        }
                }
        }
 
+done:;
        return rs->sr_err;
 }
 
@@ -897,8 +937,18 @@ backend_check_restrictions(
        int starttls = 0;
        int session = 0;
 
-       if( op->o_bd ) {
-               if ( backend_check_controls( op, rs ) != LDAP_SUCCESS ) {
+       if ( op->o_bd ) {
+               int     rc = SLAP_CB_CONTINUE;
+
+               if ( op->o_bd->be_chk_controls ) {
+                       rc = ( *op->o_bd->be_chk_controls )( op, rs );
+               }
+
+               if ( rc == SLAP_CB_CONTINUE ) {
+                       rc = backend_check_controls( op, rs );
+               }
+
+               if ( rc != LDAP_SUCCESS ) {
                        return rs->sr_err;
                }
 
@@ -1759,18 +1809,7 @@ int backend_operational(
        if (( SLAP_OPATTRS( rs->sr_attr_flags ) || rs->sr_attrs ) &&
                op->o_bd && op->o_bd->be_operational != NULL )
        {
-               Attribute       *a;
-               
-               a = rs->sr_operational_attrs;
-               rs->sr_operational_attrs = NULL;
                rc = op->o_bd->be_operational( op, rs );
-               *ap = rs->sr_operational_attrs;
-               if ( a != NULL ) {
-                       rs->sr_operational_attrs = a;
-               }
-
-               for ( ; *ap; ap = &(*ap)->a_next )
-                       /* just count them */ ;
        }
        op->o_bd = be_orig;
 
index 4f0082b0d6cebf23ccdbfa8b06d782977cf44375..f7e572071ce4f7e143b8cdf2d4f03fbcd39b9810 100644 (file)
@@ -223,6 +223,7 @@ enum op_which {
        op_extended,
        op_aux_operational,
        op_aux_chk_referrals,
+       op_aux_chk_controls,
        op_last
 };
 
@@ -234,7 +235,7 @@ static int op_rc[] = {
        LDAP_UNWILLING_TO_PERFORM,      /* bind */
        LDAP_UNWILLING_TO_PERFORM,      /* unbind */
        LDAP_UNWILLING_TO_PERFORM,      /* search */
-       LDAP_UNWILLING_TO_PERFORM,      /* compare */
+       SLAP_CB_CONTINUE,               /* compare; pass to frontend */
        LDAP_UNWILLING_TO_PERFORM,      /* modify */
        LDAP_UNWILLING_TO_PERFORM,      /* modrdn */
        LDAP_UNWILLING_TO_PERFORM,      /* add */
@@ -243,7 +244,8 @@ static int op_rc[] = {
        LDAP_UNWILLING_TO_PERFORM,      /* cancel */
        LDAP_UNWILLING_TO_PERFORM,      /* extended */
        LDAP_SUCCESS,                   /* aux_operational */
-       LDAP_SUCCESS                    /* aux_chk_referrals */
+       LDAP_SUCCESS,                   /* aux_chk_referrals */
+       SLAP_CB_CONTINUE                /* aux_chk_controls; pass to frontend */
 };
 
 static int
@@ -377,6 +379,56 @@ over_aux_chk_referrals( Operation *op, SlapReply *rs )
        return over_op_func( op, rs, op_aux_chk_referrals );
 }
 
+static int
+over_aux_chk_controls( Operation *op, SlapReply *rs )
+{
+       return over_op_func( op, rs, op_aux_chk_controls );
+}
+
+static int
+over_connection_destroy(
+       BackendDB       *bd,
+       Connection      *conn
+)
+{
+       slap_overinfo *oi;
+       slap_overinst *on;
+       BackendDB db;
+       int rc = SLAP_CB_CONTINUE;
+
+       /* FIXME: used to happen for instance during abandon
+        * when global overlays are used... */
+       assert( bd != NULL );
+
+       oi = bd->bd_info->bi_private;
+       on = oi->oi_list;
+
+       if ( !SLAP_ISOVERLAY( bd )) {
+               db = *bd;
+               db.be_flags |= SLAP_DBFLAG_OVERLAY;
+               bd = &db;
+       }
+
+       for (; on; on=on->on_next ) {
+               if ( on->on_bi.bi_connection_destroy ) {
+                       bd->bd_info = (BackendInfo *)on;
+                       rc = on->on_bi.bi_connection_destroy( bd, conn );
+                       if ( rc != SLAP_CB_CONTINUE ) break;
+               }
+       }
+
+       if ( oi->oi_orig->bi_connection_destroy && rc == SLAP_CB_CONTINUE ) {
+               bd->bd_info = oi->oi_orig;
+               rc = oi->oi_orig->bi_connection_destroy( bd, conn );
+       }
+       /* should not fall thru this far without anything happening... */
+       if ( rc == SLAP_CB_CONTINUE ) {
+               rc = LDAP_UNWILLING_TO_PERFORM;
+       }
+
+       return rc;
+}
+
 int
 overlay_register(
        slap_overinst *on
@@ -472,6 +524,11 @@ overlay_register_control( BackendDB *be, const char *oid )
 {
        int             rc = 0;
        int             gotit = 0;
+       int             cid;
+
+       if ( slap_find_control_id( oid, &cid ) == LDAP_CONTROL_NOT_FOUND ) {
+               return -1;
+       }
 
        if ( SLAP_DBFLAGS( be ) & SLAP_DBFLAG_GLOBAL_OVERLAY ) {
                int     i;
@@ -484,23 +541,15 @@ overlay_register_control( BackendDB *be, const char *oid )
                                gotit = 1;
                        }
 
-                       if ( bd->be_controls == NULL ||
-                               !ldap_charray_inlist( bd->be_controls, oid ) )
-                       {
-                               rc = ldap_charray_add( &bd->be_controls, oid );
-                               if ( rc ) {
-                                       break;
-                               }
-                       }
+                       bd->be_ctrls[ cid ] = 1;
+                       bd->be_ctrls[ SLAP_MAX_CIDS ] = 1;
                }
 
        }
        
-       if ( rc == 0 && !gotit && !ldap_charray_inlist( be->be_controls, oid ) ) {
-               rc = ldap_charray_add( &be->be_controls, oid );
-               if ( rc ) {
-                       return rc;
-               }
+       if ( rc == 0 && !gotit ) {
+               be->be_ctrls[ cid ] = 1;
+               be->be_ctrls[ SLAP_MAX_CIDS ] = 1;
        }
 
        return rc;
@@ -569,6 +618,9 @@ overlay_config( BackendDB *be, const char *ov )
                 */
                bi->bi_operational = over_aux_operational;
                bi->bi_chk_referrals = over_aux_chk_referrals;
+               bi->bi_chk_controls = over_aux_chk_controls;
+               
+               bi->bi_connection_destroy = over_connection_destroy;
 
                be->bd_info = bi;
 
index 9c41d57d411f96c30c813d1946e1be621c464dd7..3541118d033c86cd8da46b0b8ddfd0d0267a2db2 100644 (file)
@@ -326,10 +326,14 @@ fe_op_compare( Operation *op, SlapReply *rs )
                }
 
        } else if ( op->o_bd->be_compare ) {
-               op->o_bd->be_compare( op, rs );
+               rs->sr_err = op->o_bd->be_compare( op, rs );
 
 #endif /* ! SLAP_COMPARE_IN_FRONTEND */
        } else {
+               rs->sr_err = SLAP_CB_CONTINUE;
+       }
+
+       if ( rs->sr_err == SLAP_CB_CONTINUE ) {
                /* do our best to compare that AVA
                 * 
                 * NOTE: this code is used only
index 0abd270013dec9350448289962ccb256b451ed04..acc04f7a933681ea5c5bab0200ca9c9c69ae5162 100644 (file)
@@ -28,31 +28,31 @@ typedef struct config_table_s {
        void *notify;
 } ConfigTable;
 
-#define ARGS_USERLAND  0x0000ffffL
-#define ARGS_TYPES     0x00ff0000L
-#define ARGS_POINTER   0x001f0000L
-#define ARGS_NUMERIC   0x000f0000L
-#define ARG_INT                0x00010000L
-#define ARG_LONG       0x00020000L
-#define ARG_BER_LEN_T  0x00040000L
-#define ARG_ON_OFF     0x00080000L
-#define ARG_STRING     0x00100000L
-#define ARG_BERVAL     0x00200000L     /* XXX not yet */
-#define ARG_EXISTS     0x00400000L     /* XXX not yet */
-#define ARG_IGNORED    0x00800000L
+#define ARGS_USERLAND  0x0000ffff
+#define ARGS_TYPES     0x00ff0000
+#define ARGS_POINTER   0x001f0000
+#define ARGS_NUMERIC   0x000f0000
+#define ARG_INT                0x00010000
+#define ARG_LONG       0x00020000
+#define ARG_BER_LEN_T  0x00040000
+#define ARG_ON_OFF     0x00080000
+#define ARG_STRING     0x00100000
+#define ARG_BERVAL     0x00200000      /* XXX not yet */
+#define ARG_EXISTS     0x00400000      /* XXX not yet */
+#define ARG_IGNORED    0x00800000
 
-#define ARGS_SYNTAX    0xff000000L
-#define ARG_DB         0x01000000L
-#define ARG_PRE_DB     0x02000000L
-#define ARG_PAREN      0x04000000L
-#define ARG_NONZERO    0x08000000L
-#define ARG_UNIQUE     0x10000000L     /* XXX not yet */
-#define ARG_SPECIAL    0x20000000L     /* one special case */
-#define ARG_OFFSET     0x40000000L
-#define ARG_MAGIC      0x80000000L
+#define ARGS_SYNTAX    0xff000000
+#define ARG_DB         0x01000000
+#define ARG_PRE_DB     0x02000000
+#define ARG_PAREN      0x04000000
+#define ARG_NONZERO    0x08000000
+#define ARG_UNIQUE     0x10000000      /* XXX not yet */
+#define ARG_SPECIAL    0x20000000      /* one special case */
+#define ARG_OFFSET     0x40000000
+#define ARG_MAGIC      0x80000000
 
-#define ARG_BAD_CONF   0xdead0000L     /* overload return values */
-#define ARG_UNKNOWN    0xc0de0000L
+#define ARG_BAD_CONF   0xdead0000      /* overload return values */
+#define ARG_UNKNOWN    0xc0de0000
 
 typedef struct config_args_s {
        int argc;
index c201273eb579f44430bcba861f4e04fab2ad8d58..f67c7e8f81448aed7499a05ff036d4a0be5c7eaa 100644 (file)
@@ -106,7 +106,7 @@ static struct slap_control control_defs[] = {
                parsePostRead, LDAP_SLIST_ENTRY_INITIALIZER(next) },
        { LDAP_CONTROL_VALUESRETURNFILTER,
                (int)offsetof(struct slap_control_ids, sc_valuesReturnFilter),
-               SLAP_CTRL_SEARCH, NULL,
+               SLAP_CTRL_GLOBAL|SLAP_CTRL_SEARCH, NULL,
                parseValuesReturnFilter, LDAP_SLIST_ENTRY_INITIALIZER(next) },
        { LDAP_CONTROL_PAGEDRESULTS,
                (int)offsetof(struct slap_control_ids, sc_pagedResults),
@@ -381,7 +381,7 @@ slap_find_control_id(
 }
 
 int
-slap_global_control( Operation *op, const char *oid )
+slap_global_control( Operation *op, const char *oid, int *cid )
 {
        struct slap_control *ctrl = find_ctrl( oid );
 
@@ -390,22 +390,23 @@ slap_global_control( Operation *op, const char *oid )
                Debug( LDAP_DEBUG_ANY,
                        "slap_global_control: unrecognized control: %s\n",      
                        oid, 0, 0 );
-               assert( 0 );
-               return 0;
+               return LDAP_CONTROL_NOT_FOUND;
        }
 
-       if ( ctrl->sc_mask & SLAP_CTRL_GLOBAL ) return 1;
+       if ( cid ) *cid = ctrl->sc_cid;
 
-       if (( op->o_tag & LDAP_REQ_SEARCH ) &&
-               ( ctrl->sc_mask & SLAP_CTRL_GLOBAL_SEARCH ))
+       if ( ( ctrl->sc_mask & SLAP_CTRL_GLOBAL ) ||
+                       ( ( op->o_tag & LDAP_REQ_SEARCH ) &&
+                       ( ctrl->sc_mask & SLAP_CTRL_GLOBAL_SEARCH ) ) )
        {
-               return 1;
+               return LDAP_COMPARE_TRUE;
        }
 
-       Debug( LDAP_DEBUG_ANY,
+       Debug( LDAP_DEBUG_TRACE,
                "slap_global_control: unavailable control: %s\n",      
                oid, 0, 0 );
-       return 0;
+
+       return LDAP_COMPARE_FALSE;
 }
 
 void slap_free_ctrls(
index bf9635b8755a659ef468f279e7d15a0f71b24d08..f9cfe6f466137c0110dc178e324dc7c27704b8ae 100644 (file)
@@ -86,8 +86,25 @@ frontend_init( void )
        frontendDB->bd_info->bi_type = "frontend";
 
        /* known controls */
-       frontendDB->bd_info->bi_controls = slap_known_controls;
-       frontendDB->be_controls = ldap_charray_dup( slap_known_controls );
+       if ( slap_known_controls ) {
+               int     i;
+
+               frontendDB->bd_info->bi_controls = slap_known_controls;
+
+               for ( i = 0; slap_known_controls[ i ]; i++ ) {
+                       int     cid;
+
+                       if ( slap_find_control_id( slap_known_controls[ i ], &cid )
+                                       == LDAP_CONTROL_NOT_FOUND )
+                       {
+                               assert( 0 );
+                               return -1;
+                       }
+
+                       frontendDB->bd_info->bi_ctrls[ cid ] = 1;
+                       frontendDB->be_ctrls[ cid ] = 1;
+               }
+       }
 
        /* calls */
        frontendDB->bd_info->bi_op_abandon = fe_op_abandon;
index 1c34f10d3ed526714d827c571029479e5e95ffbb..e606e3da9ee898c5e2a641f9b66931ec6a890be6 100644 (file)
@@ -126,8 +126,8 @@ slap_init( int mode, const char *name )
                ldap_pvt_mp_init( slap_counters.sc_entries );
                ldap_pvt_mp_init( slap_counters.sc_refs );
 
-               ldap_pvt_mp_init( slap_counters.sc_ops_completed );
                ldap_pvt_mp_init( slap_counters.sc_ops_initiated );
+               ldap_pvt_mp_init( slap_counters.sc_ops_completed );
 
 #ifdef SLAPD_MONITOR
                for ( i = 0; i < SLAP_OP_LAST; i++ ) {
@@ -239,8 +239,8 @@ int slap_destroy(void)
                ldap_pvt_mp_clear( slap_counters.sc_pdu );
                ldap_pvt_mp_clear( slap_counters.sc_entries );
                ldap_pvt_mp_clear( slap_counters.sc_refs );
-               ldap_pvt_mp_clear( slap_counters.sc_ops_completed );
                ldap_pvt_mp_clear( slap_counters.sc_ops_initiated );
+               ldap_pvt_mp_clear( slap_counters.sc_ops_completed );
 
 #ifdef SLAPD_MONITOR
                for ( i = 0; i < SLAP_OP_LAST; i++ ) {
index c5852e8914bd1fbcde388114edfc553031f102ee..a09176e5c71f45dc92fc10cdd8f688b698b0a602 100644 (file)
@@ -193,6 +193,58 @@ glue_op_func ( Operation *op, SlapReply *rs )
        return rc;
 }
 
+static int
+glue_chk_referrals ( Operation *op, SlapReply *rs )
+{
+       slap_overinst   *on = (slap_overinst *)op->o_bd->bd_info;
+       glueinfo                *gi = (glueinfo *)on->on_bi.bi_private;
+       BackendDB *b0 = op->o_bd;
+       BackendInfo *bi0 = op->o_bd->bd_info;
+       int rc;
+
+       op->o_bd = glue_back_select (b0, &op->o_req_ndn);
+       b0->bd_info = on->on_info->oi_orig;
+
+       if ( op->o_bd->bd_info->bi_chk_referrals )
+               rc = ( *op->o_bd->bd_info->bi_chk_referrals )( op, rs );
+       else
+               rc = SLAP_CB_CONTINUE;
+
+       op->o_bd = b0;
+       op->o_bd->bd_info = bi0;
+       return rc;
+}
+
+static int
+glue_chk_controls ( Operation *op, SlapReply *rs )
+{
+       slap_overinst   *on = (slap_overinst *)op->o_bd->bd_info;
+       glueinfo                *gi = (glueinfo *)on->on_bi.bi_private;
+       BackendDB *b0 = op->o_bd;
+       BackendInfo *bi0 = op->o_bd->bd_info;
+       int rc = SLAP_CB_CONTINUE;
+
+       op->o_bd = glue_back_select (b0, &op->o_req_ndn);
+       b0->bd_info = on->on_info->oi_orig;
+
+       /* if the subordinate database has overlays, the bi_chk_controls()
+        * hook is actually over_aux_chk_controls(); in case it actually
+        * wraps a missing hok, we need to mimic the behavior
+        * of the frontend applied to that database */
+       if ( op->o_bd->bd_info->bi_chk_controls ) {
+               rc = ( *op->o_bd->bd_info->bi_chk_controls )( op, rs );
+       }
+
+       
+       if ( rc == SLAP_CB_CONTINUE ) {
+               rc = backend_check_controls( op, rs );
+       }
+
+       op->o_bd = b0;
+       op->o_bd->bd_info = bi0;
+       return rc;
+}
+
 static int
 glue_op_search ( Operation *op, SlapReply *rs )
 {
@@ -326,6 +378,9 @@ glue_op_search ( Operation *op, SlapReply *rs )
                        case LDAP_TIMELIMIT_EXCEEDED:
                        case LDAP_ADMINLIMIT_EXCEEDED:
                        case LDAP_NO_SUCH_OBJECT:
+#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
+                       case LDAP_CANNOT_CHAIN:
+#endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
                                goto end_of_loop;
                        
                        default:
@@ -679,6 +734,8 @@ glue_db_open (
        int i;
 
        for ( i=0; i<gi->gi_nodes; i++ ) {
+               int j;
+
                gi->gi_n[i].gn_be = backendDB + gi->gi_n[i].gn_bx;
        }
        return 0;
@@ -707,23 +764,30 @@ glue_db_config(
        slap_overinst   *on = (slap_overinst *)be->bd_info;
        glueinfo                *gi = (glueinfo *)on->on_bi.bi_private;
 
+       /* redundant; could be applied just once */
+       SLAP_DBFLAGS( be ) |= SLAP_DBFLAG_GLUE_INSTANCE;
+
        if ( strcasecmp( argv[0], "glue-sub" ) == 0 ) {
-               int async = 0;
+               int i, async = 0, advertise = 0;
                BackendDB *b2;
                struct berval bv, dn;
                gluenode *gn;
 
                if ( argc < 2 ) {
                        fprintf( stderr, "%s: line %d: too few arguments in "
-                               "\"glue-sub <suffixDN> [async]\"\n", fname, lineno );
+                               "\"glue-sub <suffixDN> [async] [advertise]\"\n", fname, lineno );
                        return -1;
                }
-               if ( argc == 3 ) {
-                       if ( strcasecmp( argv[2], "async" )) {
-                               fprintf( stderr, "%s: line %d: unrecognized option "
-                                       "\"%s\" ignored.\n", fname, lineno, argv[2] );
-                       } else {
+               for ( i = 2; i < argc; i++ ) {
+                       if ( strcasecmp( argv[i], "async" ) == 0 ) {
                                async = 1;
+
+                       } else if ( strcasecmp( argv[i], "advertise" ) == 0 ) {
+                               advertise = 1;
+
+                       } else {
+                               fprintf( stderr, "%s: line %d: unrecognized option "
+                                       "\"%s\" ignored.\n", fname, lineno, argv[i] );
                        }
                }
                ber_str2bv( argv[1], 0, 0, &bv );
@@ -738,6 +802,9 @@ glue_db_config(
                        return -1;
                }
                SLAP_DBFLAGS(b2) |= SLAP_DBFLAG_GLUE_SUBORDINATE;
+               if ( advertise ) {
+                       SLAP_DBFLAGS(b2) |= SLAP_DBFLAG_GLUE_ADVERTISE;
+               }
                gi = (glueinfo *)ch_realloc( gi, sizeof(glueinfo) +
                        gi->gi_nodes * sizeof(gluenode));
                gi->gi_n[gi->gi_nodes].gn_bx = b2 - backendDB;
@@ -767,6 +834,9 @@ glue_init()
        glue.on_bi.bi_op_add = glue_op_func;
        glue.on_bi.bi_op_delete = glue_op_func;
 
+       glue.on_bi.bi_chk_referrals = glue_chk_referrals;
+       glue.on_bi.bi_chk_controls = glue_chk_controls;
+
        return overlay_register( &glue );
 }
 
index 4f522d789c6ff850844aa037f6e5c5ee36b40b24..ff6cb833506bd1c643774c64f89e26c9aad421ae 100644 (file)
@@ -551,6 +551,7 @@ refint_response(
        nop.o_tag       = LDAP_REQ_SEARCH;
        nop.ors_scope   = LDAP_SCOPE_SUBTREE;
        nop.ors_deref   = LDAP_DEREF_NEVER;
+       nop.ors_limit   = NULL;
        nop.ors_slimit  = SLAP_NO_LIMIT;
        nop.ors_tlimit  = SLAP_NO_LIMIT;
 
index d9ca042554945b0fef7b05c07cfd9004f7c6080a..00227172c6c4db13531027568fcdc80d37acff28 100644 (file)
@@ -785,7 +785,7 @@ rwm_matched( Operation *op, SlapReply *rs )
 }
 
 static int
-rwm_attrs( Operation *op, SlapReply *rs, Attribute** a_first )
+rwm_attrs( Operation *op, SlapReply *rs, Attribute** a_first, int stripEntryDN )
 {
        slap_overinst           *on = (slap_overinst *) op->o_bd->bd_info;
        struct ldaprwmap        *rwmap = 
@@ -852,11 +852,13 @@ rwm_attrs( Operation *op, SlapReply *rs, Attribute** a_first )
                }
 
                if ( (*ap)->a_desc == slap_schema.si_ad_entryDN ) {
-                       /* will be generated by frontend */
-                       goto cleanup_attr;
-               }
-
-               if ( !isupdate && (*ap)->a_desc->ad_type->sat_no_user_mod 
+                       if ( stripEntryDN ) {
+                               /* will be generated by frontend */
+                               goto cleanup_attr;
+                       }
+                       
+               } else if ( !isupdate
+                       && (*ap)->a_desc->ad_type->sat_no_user_mod 
                        && (*ap)->a_desc->ad_type != slap_schema.si_at_undefined )
                {
                        goto next_attr;
@@ -1029,7 +1031,13 @@ rwm_send_entry( Operation *op, SlapReply *rs )
        /* FIXME: the entries are in the remote mapping form;
         * so we need to select those attributes we are willing
         * to return, and remap them accordingly */
-       (void)rwm_attrs( op, rs, &e->e_attrs );
+       (void)rwm_attrs( op, rs, &e->e_attrs, 1 );
+
+#if 0
+       if ( rs->sr_operational_attrs ) {
+               (void)rwm_attrs( op, rs, &rs->sr_operational_attrs, 0 );
+       }
+#endif
 
        rs->sr_entry = e;
        rs->sr_flags = flags;
@@ -1059,7 +1067,7 @@ rwm_operational( Operation *op, SlapReply *rs )
         * so we need to select those attributes we are willing
         * to return, and remap them accordingly */
        if ( rs->sr_operational_attrs ) {
-               rwm_attrs( op, rs, &rs->sr_operational_attrs );
+               rwm_attrs( op, rs, &rs->sr_operational_attrs, 1 );
        }
 
        return SLAP_CB_CONTINUE;
index e9f60fb8e1e0dd9fddec51bc18880a4ac7317ee9..d44e205fdf7003441d8d1409be58d8ca916eac9a 100644 (file)
@@ -328,6 +328,7 @@ static int unique_search(
        nop->o_tag      = LDAP_REQ_SEARCH;
        nop->ors_scope  = LDAP_SCOPE_SUBTREE;
        nop->ors_deref  = LDAP_DEREF_NEVER;
+       nop->ors_limit  = NULL;
        nop->ors_slimit = SLAP_NO_LIMIT;
        nop->ors_tlimit = SLAP_NO_LIMIT;
        nop->ors_attrs  = slap_anlist_no_attrs;
index 133ecb8d00daf4cd2f744205ac5a79cfc04c9714..bfb41fb18f4fd86888821615c460ba2305bb8ea8 100644 (file)
@@ -264,6 +264,9 @@ LDAP_SLAPD_F (int) backend_unbind LDAP_P((Operation *op, SlapReply *rs));
 LDAP_SLAPD_F (int) backend_connection_init LDAP_P((Connection *conn));
 LDAP_SLAPD_F (int) backend_connection_destroy LDAP_P((Connection *conn));
 
+LDAP_SLAPD_F( int ) backend_check_controls LDAP_P((
+       Operation *op,
+       SlapReply *rs ));
 LDAP_SLAPD_F( int )    backend_check_restrictions LDAP_P((
        Operation *op,
        SlapReply *rs,
@@ -430,7 +433,7 @@ LDAP_SLAPD_F (int) get_supported_controls LDAP_P ((
 LDAP_SLAPD_F (int) slap_find_control_id LDAP_P ((
        const char *oid, int *cid ));
 LDAP_SLAPD_F (int) slap_global_control LDAP_P ((
-       Operation *op, const char *oid ));
+       Operation *op, const char *oid, int *cid ));
 
 /*
  * config.c
index 9c9d2ea587cc8660726e6a8f70e2c3fdbe8186ad..c2efc492fd8dc75a0f76a1f7872098e3451c280a 100644 (file)
@@ -453,7 +453,7 @@ send_ldap_response(
 
        ldap_pvt_thread_mutex_lock( &slap_counters.sc_sent_mutex );
        ldap_pvt_mp_add_ulong( slap_counters.sc_pdu, 1 );
-       ldap_pvt_mp_add_ulong( slap_counters.sc_bytes, bytes );
+       ldap_pvt_mp_add_ulong( slap_counters.sc_bytes, (unsigned long)bytes );
        ldap_pvt_thread_mutex_unlock( &slap_counters.sc_sent_mutex );
 
 cleanup:;
@@ -1180,7 +1180,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
                rs->sr_nentries++;
 
                ldap_pvt_thread_mutex_lock( &slap_counters.sc_sent_mutex );
-               ldap_pvt_mp_add_ulong( slap_counters.sc_bytes, bytes );
+               ldap_pvt_mp_add_ulong( slap_counters.sc_bytes, (unsigned long)bytes );
                ldap_pvt_mp_add_ulong( slap_counters.sc_entries, 1 );
                ldap_pvt_mp_add_ulong( slap_counters.sc_pdu, 1 );
                ldap_pvt_thread_mutex_unlock( &slap_counters.sc_sent_mutex );
@@ -1369,7 +1369,7 @@ slap_send_search_reference( Operation *op, SlapReply *rs )
        ber_free_buf( ber );
 
        ldap_pvt_thread_mutex_lock( &slap_counters.sc_sent_mutex );
-       ldap_pvt_mp_add_ulong( slap_counters.sc_bytes, bytes );
+       ldap_pvt_mp_add_ulong( slap_counters.sc_bytes, (unsigned long)bytes );
        ldap_pvt_mp_add_ulong( slap_counters.sc_refs, 1 );
        ldap_pvt_mp_add_ulong( slap_counters.sc_pdu, 1 );
        ldap_pvt_thread_mutex_unlock( &slap_counters.sc_sent_mutex );
index 46e77968ce0b33418d6264eea9167986bc654a45..8d18760abea0ecb53ed64d4c39a7a1f52e280f05 100644 (file)
@@ -128,7 +128,7 @@ root_dse_info(
                        }
                        continue;
                }
-               if ( SLAP_GLUE_SUBORDINATE( &backends[i] ) ) {
+               if ( SLAP_GLUE_SUBORDINATE( &backends[i] ) && !SLAP_GLUE_ADVERTISE( &backends[i] ) ) {
                        continue;
                }
                for ( j = 0; backends[i].be_suffix[j].bv_val != NULL; j++ ) {
index a9df65cf9612e29045e32396b5acf082d7f44d9e..5d373374397479658ec9cd727cac7c939bc66ae4 100644 (file)
@@ -537,7 +537,7 @@ octetStringSubstringsFilter (
                if ( sa->sa_initial.bv_len > index_substr_if_maxlen &&
                        ( flags & SLAP_INDEX_SUBSTR_ANY ))
                {
-                       nkeys += (sa->sa_initial.bv_len - index_substr_if_maxlen) / index_substr_any_step;
+                       nkeys += 1 + (sa->sa_initial.bv_len - index_substr_if_maxlen) / index_substr_any_step;
                }
        }
 
@@ -560,7 +560,7 @@ octetStringSubstringsFilter (
                if ( sa->sa_final.bv_len > index_substr_if_maxlen &&
                        ( flags & SLAP_INDEX_SUBSTR_ANY ))
                {
-                       nkeys += (sa->sa_final.bv_len - index_substr_if_maxlen) / index_substr_any_step;
+                       nkeys += 1 + (sa->sa_final.bv_len - index_substr_if_maxlen) / index_substr_any_step;
                }
        }
 
index 08566e473071d1903dd03efd7aed33dc286d023f..ee65e32dc81c33908795d0c604ef750b98123bfc 100644 (file)
@@ -1527,6 +1527,10 @@ typedef struct syncinfo_s {
 
 LDAP_TAILQ_HEAD( be_pcl, slap_csn_entry );
 
+#ifndef SLAP_MAX_CIDS
+#define        SLAP_MAX_CIDS   32      /* Maximum number of supported controls */
+#endif
+
 struct slap_backend_db {
        BackendInfo     *bd_info;       /* pointer to shared backend info */
 
@@ -1551,6 +1555,7 @@ struct slap_backend_db {
 #define                be_extended     bd_info->bi_extended
 
 #define                be_chk_referrals        bd_info->bi_chk_referrals
+#define                be_chk_controls         bd_info->bi_chk_controls
 #define                be_fetch        bd_info->bi_entry_get_rw
 #define                be_release      bd_info->bi_entry_release_rw
 #define                be_group        bd_info->bi_acl_group
@@ -1564,12 +1569,6 @@ struct slap_backend_db {
  */
 #define                be_has_subordinates bd_info->bi_has_subordinates
 
-       /* supported controls */
-       /* NOTE: this stores a duplicate of the control OIDs as listed
-        * in bd_info->bi_controls at database startup; later on,
-        * controls may be added run-time, e.g. by overlays */
-       char            **be_controls;
-
 #define                be_connection_init      bd_info->bi_connection_init
 #define                be_connection_destroy   bd_info->bi_connection_destroy
 
@@ -1587,14 +1586,20 @@ struct slap_backend_db {
 #define                be_entry_modify bd_info->bi_tool_entry_modify
 #endif
 
+       /* supported controls */
+       /* note: set to 0 if the database does not support the control;
+        * be_ctrls[SLAP_MAX_CIDS] is set to 1 if initialized */
+       char            be_ctrls[SLAP_MAX_CIDS + 1];
+
 /* Database flags */
 #define SLAP_DBFLAG_NOLASTMOD          0x0001U
 #define SLAP_DBFLAG_NO_SCHEMA_CHECK    0x0002U
 #define        SLAP_DBFLAG_GLUE_INSTANCE       0x0010U /* a glue backend */
 #define        SLAP_DBFLAG_GLUE_SUBORDINATE    0x0020U /* child of a glue hierarchy */
 #define        SLAP_DBFLAG_GLUE_LINKED         0x0040U /* child is connected to parent */
-#define SLAP_DBFLAG_OVERLAY            0x0080U /* this db struct is an overlay */
-#define        SLAP_DBFLAG_GLOBAL_OVERLAY      0x0100U /* this db struct is a global overlay */
+#define SLAP_DBFLAG_GLUE_ADVERTISE     0x0080U /* advertise in rootDSE */
+#define SLAP_DBFLAG_OVERLAY            0x0100U /* this db struct is an overlay */
+#define        SLAP_DBFLAG_GLOBAL_OVERLAY      0x0200U /* this db struct is a global overlay */
 #define SLAP_DBFLAG_SHADOW             0x8000U /* a shadow */
 #define SLAP_DBFLAG_SYNC_SHADOW                0x1000U /* a sync shadow */
 #define SLAP_DBFLAG_SLURP_SHADOW       0x2000U /* a slurp shadow */
@@ -1611,6 +1616,8 @@ struct slap_backend_db {
        (SLAP_DBFLAGS(be) & SLAP_DBFLAG_GLUE_SUBORDINATE)
 #define        SLAP_GLUE_LINKED(be)            \
        (SLAP_DBFLAGS(be) & SLAP_DBFLAG_GLUE_LINKED)
+#define        SLAP_GLUE_ADVERTISE(be) \
+       (SLAP_DBFLAGS(be) & SLAP_DBFLAG_GLUE_ADVERTISE)
 #define SLAP_SHADOW(be)                                (SLAP_DBFLAGS(be) & SLAP_DBFLAG_SHADOW)
 #define SLAP_SYNC_SHADOW(be)                   (SLAP_DBFLAGS(be) & SLAP_DBFLAG_SYNC_SHADOW)
 #define SLAP_SLURP_SHADOW(be)                  (SLAP_DBFLAGS(be) & SLAP_DBFLAG_SLURP_SHADOW)
@@ -1873,6 +1880,8 @@ typedef int (BI_op_extended) LDAP_P((
        struct slap_op *op, struct slap_rep *rs ));
 typedef int (BI_chk_referrals) LDAP_P((
        struct slap_op *op, struct slap_rep *rs ));
+typedef int (BI_chk_controls) LDAP_P((
+       struct slap_op *op, struct slap_rep *rs ));
 typedef int (BI_entry_release_rw)
        LDAP_P(( struct slap_op *op, Entry *e, int rw ));
 typedef int (BI_entry_get_rw) LDAP_P(( struct slap_op *op, struct berval *ndn,
@@ -1974,6 +1983,7 @@ struct slap_backend_info {
        /* Auxilary Functions */
        BI_operational          *bi_operational;
        BI_chk_referrals        *bi_chk_referrals;
+       BI_chk_controls         *bi_chk_controls;
        BI_entry_get_rw         *bi_entry_get_rw;
        BI_entry_release_rw     *bi_entry_release_rw;
 
@@ -2017,7 +2027,8 @@ struct slap_backend_info {
 #define SLAP_NOLASTMODCMD(be)  (SLAP_BFLAGS(be) & SLAP_BFLAG_NOLASTMODCMD)
 #define SLAP_LASTMODCMD(be)    (!SLAP_NOLASTMODCMD(be))
 
-       char **bi_controls;             /* supported controls */
+       char    **bi_controls;          /* supported controls */
+       char    bi_ctrls[SLAP_MAX_CIDS + 1];
 
        unsigned int bi_nDB;    /* number of databases of this type */
        void    *bi_private;    /* anything the backend type needs */
@@ -2103,10 +2114,6 @@ typedef struct slap_gacl {
        char ga_ndn[1];
 } GroupAssertion;
 
-#ifndef SLAP_MAX_CIDS
-#define        SLAP_MAX_CIDS   32      /* Maximum number of supported controls */
-#endif
-
 struct slap_control_ids {
        int sc_assert;
        int sc_preRead;
index 1d45cd8a736fc660da063ce1771355700b370a35..09734c6a2d22000af907ce35efd47e8008440b3e 100644 (file)
@@ -99,6 +99,7 @@ static void *do_put(void *ptr)
 
        } while (1);
        ldap_pvt_thread_mutex_unlock( &put_mutex1 );
+       return NULL;
 }
 
 int
index bb6d4011d4bb622ea12fd090081bbc96dff7bde4..1bf43a34d1bbf03dbdabb17246e0b3439f63b1e5 100755 (executable)
@@ -39,7 +39,10 @@ DBDIR1A=$TESTDIR/db.1.a
 DBDIR1B=$TESTDIR/db.1.b
 DBDIR1C=$TESTDIR/db.1.c
 DBDIR1=$DBDIR1A
-DBDIR2=$TESTDIR/db.2.a
+DBDIR2A=$TESTDIR/db.2.a
+DBDIR2B=$TESTDIR/db.2.b
+DBDIR2C=$TESTDIR/db.2.c
+DBDIR2=$DBDIR2A
 DBDIR3=$TESTDIR/db.3.a
 DBDIR4=$TESTDIR/db.4.a
 DBDIR5=$TESTDIR/db.5.a
@@ -79,6 +82,8 @@ LDAPGLUECONF3=$DATADIR/slapd-ldapgluegroups.conf
 RWMCONF=$DATADIR/slapd-relay.conf
 CHAINCONF1=$DATADIR/slapd-chain1.conf
 CHAINCONF2=$DATADIR/slapd-chain2.conf
+GLUESYNCCONF1=$DATADIR/slapd-glue-syncrepl1.conf
+GLUESYNCCONF2=$DATADIR/slapd-glue-syncrepl2.conf
 SQLCONF=$DATADIR/slapd-sql.conf
 
 CONF1=$TESTDIR/slapd.1.conf
@@ -237,6 +242,7 @@ RELAYOUT=$DATADIR/relay.out
 CHAINOUT=$DATADIR/chain.out
 CHAINREFOUT=$DATADIR/chainref.out
 CHAINMODOUT=$DATADIR/chainmod.out
+GLUESYNCOUT=$DATADIR/gluesync.out
 SQLREAD=$DATADIR/sql-read.out
 SQLWRITE=$DATADIR/sql-write.out
 
index 7bf073a3fdb7ac50fdc3beff4c88b6bbb99f4690..0d930ceef838fa3e10a5a7240c8f0c025acadccc 100755 (executable)
@@ -133,8 +133,31 @@ for P in $PORT1 $PORT2 ; do
                echo "comparison failed - chained search didn't succeed"
                test $KILLSERVERS != no && kill -HUP $KILLPIDS
                exit 1
-fi
+       fi
 
+       DN="cn=Mark Elliot,ou=Alumni Association,ou=People,$BASEDN"
+       echo "Comparing \"$DN\" on port $P..."
+       $LDAPCOMPARE -h $LOCALHOST -p $P "$DN" "cn:Mark Elliot"
+                > $TESTOUT 2>&1
+
+       RC=$?
+       if test $RC != 0 ; then
+               echo "ldapcompare failed ($RC)!"
+               test $KILLSERVERS != no && kill -HUP $KILLPIDS
+               exit $RC
+       fi
+
+       DN="ou=Other,$BASEDN"
+       echo "Comparing \"$DN\" on port $P with manageDSAit control..."
+       $LDAPCOMPARE -h $LOCALHOST -p $P -M "$DN" "ou:Other"
+                > $TESTOUT 2>&1
+
+       RC=$?
+       if test $RC != 0 ; then
+               echo "ldapcompare failed ($RC)!"
+               test $KILLSERVERS != no && kill -HUP $KILLPIDS
+               exit $RC
+       fi
 done
 
 #