]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/back-ldap/chain.c
cleanup version parsing
[openldap] / servers / slapd / back-ldap / chain.c
index bf8353c00da26bebde2471622b671162b9c902a2..6c041620757a5bd803cda79a3ee8377fff2ef9a6 100644 (file)
@@ -2,7 +2,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 2003-2005 The OpenLDAP Foundation.
+ * Copyright 2003-2006 The OpenLDAP Foundation.
  * Portions Copyright 2003 Howard Chu.
  * All rights reserved.
  *
@@ -78,7 +78,7 @@ typedef struct ldap_chain_t {
         * the tree?  Should be all configurable.
         */
 
-       /* "common" configuration info (all occurring before an "uri") */
+       /* "common" configuration info (anything occurring before an "uri") */
        ldapinfo_t              *lc_common_li;
 
        /* current configuration info */
@@ -219,25 +219,6 @@ ldap_chain_uri_dup( void *c1, void *c2 )
        return 0;
 }
 
-static int
-ldap_chain_operational( Operation *op, SlapReply *rs )
-{
-       /* Trap entries generated by back-ldap.
-        * 
-        * FIXME: we need a better way to recognize them; a cleaner
-        * solution would be to be able to intercept the response
-        * of be_operational(), so that we can divert only those
-        * calls that fail because operational attributes were
-        * requested for entries that do not belong to the underlying
-        * database.  This fix is likely to intercept also entries
-        * generated by back-perl and so. */
-       if ( rs->sr_entry->e_private == NULL ) {
-               return 0;
-       }
-
-       return SLAP_CB_CONTINUE;
-}
-
 /*
  * Search specific response that strips entryDN from entries
  */
@@ -269,6 +250,10 @@ ldap_chain_cb_search_response( Operation *op, SlapReply *rs )
                                break;
                        }
                }
+
+               /* tell the frontend not to add generated
+                * operational attributes */
+               rs->sr_flags |= REP_NO_OPERATIONALS;
                
                return SLAP_CB_CONTINUE;
 
@@ -355,7 +340,7 @@ static int
 ldap_chain_op(
        Operation       *op,
        SlapReply       *rs,
-       int             ( *op_f )( Operation *op, SlapReply *rs ), 
+       BI_op_func      *op_f,
        BerVarray       ref )
 {
        slap_overinst   *on = (slap_overinst *) op->o_bd->bd_info;
@@ -461,7 +446,7 @@ Document: draft-ietf-ldapbis-protocol-27.txt
                        }
                }
 
-               rc = ( *op_f )( op, rs );
+               rc = op_f( op, rs );
 
 cleanup:;
                ldap_memfree( li.li_uri );
@@ -748,7 +733,16 @@ cleanup:;
                        }
                        
                } else {
-                       rc = ldap_chain_op( op, rs, lback->bi_op_search, ref );
+                       /* we might get here before any database actually 
+                        * performed a search; in those cases, we need
+                        * to check limits, to make sure safe defaults
+                        * are in place */
+                       if ( op->ors_limit != NULL || limits_check( op, rs ) == 0 ) {
+                               rc = ldap_chain_op( op, rs, lback->bi_op_search, ref );
+
+                       } else {
+                               rc = SLAP_CB_CONTINUE;
+                       }
                }
                break;
 
@@ -757,7 +751,7 @@ cleanup:;
                /* FIXME: ldap_back_extended() by design 
                 * doesn't send result; frontend is expected
                 * to send it... */
-               /* FIXME: what aboit chaining? */
+               /* FIXME: what about chaining? */
                if ( rc != SLAPD_ABANDON ) {
                        send_ldap_extended( op, rs );
                        rc = LDAP_SUCCESS;
@@ -777,7 +771,13 @@ cleanup:;
        case LDAP_SUCCESS:
        case LDAP_REFERRAL:
                /* slapd-ldap sent response */
-               assert( sc2.sc_private == LDAP_CH_RES );
+               if ( !op->o_abandon && sc2.sc_private != LDAP_CH_RES ) {
+                       /* FIXME: should we send response? */
+                       Debug( LDAP_DEBUG_ANY,
+                               "%s: ldap_chain_response: "
+                               "overlay should have sent result.\n",
+                               op->o_log_prefix, 0, 0 );
+               }
                break;
 
        default:
@@ -875,9 +875,9 @@ static ConfigTable chaincfg[] = {
                        "DESC 'Chaining behavior control parameters (draft-sermersheim-ldap-chaining)' "
                        "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
 #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
-       { "chain-cache-uris", "TRUE/FALSE",
+       { "chain-cache-uri", "TRUE/FALSE",
                2, 2, 0, ARG_MAGIC|ARG_ON_OFF|CH_CACHE_URI, chain_cf_gen,
-               "( OLcfgOvAt:3.2 NAME 'olcCacheURIs' "
+               "( OLcfgOvAt:3.2 NAME 'olcCacheURI' "
                        "DESC 'Enables caching of URIs not present in configuration' "
                        "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
        { NULL, NULL, 0, 0, 0, ARG_IGNORED }
@@ -890,9 +890,9 @@ static ConfigOCs chainocs[] = {
                "SUP olcOverlayConfig "
                "MAY ( "
 #ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
-                       "olcChainingBehavior "
+                       "olcChainingBehavior "
 #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
-                       "$ olcCacheURIs "
+                       "olcCacheURI "
                        ") )",
                Cft_Overlay, chaincfg, NULL, chain_cfadd },
        { "( OLcfgOvOc:3.2 "
@@ -1284,6 +1284,7 @@ ldap_chain_db_init(
                return 1;
        }
        memset( lc, 0, sizeof( ldap_chain_t ) );
+       ldap_pvt_thread_mutex_init( &lc->lc_lai.lai_mutex );
 
        on->on_bi.bi_private = (void *)lc;
 
@@ -1313,14 +1314,47 @@ ldap_chain_db_config(
        /* Something for the chain database? */
        if ( strncasecmp( argv[ 0 ], "chain-", STRLENOF( "chain-" ) ) == 0 ) {
                char            *save_argv0 = argv[ 0 ];
-               BackendInfo     *bd_info = bd_info;
+               BackendInfo     *bd_info = be->bd_info;
                void            *be_private = be->be_private;
                ConfigOCs       *be_cf_ocs = be->be_cf_ocs;
-               int             is_uri = 0;
+               static char     *allowed_argv[] = {
+                       /* special: put URI here, so in the meanwhile
+                        * it detects whether a new URI is being provided */
+                       "uri",
+                       "nretries",
+                       "timeout",
+                       /* flags */
+                       "tls",
+                       /* FIXME: maybe rebind-as-user should be allowed
+                        * only within known URIs... */
+                       "rebind-as-user",
+                       "chase-referrals",
+                       "t-f-support",
+                       "proxy-whoami",
+                       NULL
+               };
+               int             which_argv = -1;
 
                argv[ 0 ] += STRLENOF( "chain-" );
 
-               if ( strcasecmp( argv[ 0 ], "uri" ) == 0 ) {
+               for ( which_argv = 0; allowed_argv[ which_argv ]; which_argv++ ) {
+                       if ( strcasecmp( argv[ 0 ], allowed_argv[ which_argv ] ) == 0 ) {
+                               break;
+                       }
+               }
+
+               if ( allowed_argv[ which_argv ] == NULL ) {
+                       which_argv = -1;
+
+                       if ( lc->lc_cfg_li == lc->lc_common_li ) {
+                               Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+                                       "\"%s\" only allowed within a URI directive.\n.",
+                                       fname, lineno, argv[ 0 ] );
+                               return 1;
+                       }
+               }
+
+               if ( which_argv == 0 ) {
                        rc = ldap_chain_db_init_one( be );
                        if ( rc != 0 ) {
                                Debug( LDAP_DEBUG_ANY, "%s: line %d: "
@@ -1329,7 +1363,6 @@ ldap_chain_db_config(
                                return 1;
                        }
                        lc->lc_cfg_li = be->be_private;
-                       is_uri = 1;
                }
 
                /* TODO: add checks on what other slapd-ldap(5) args
@@ -1350,7 +1383,7 @@ ldap_chain_db_config(
                be->be_private = be_private;
                be->bd_info = bd_info;
 
-               if ( is_uri ) {
+               if ( which_argv == 0 ) {
 private_destroy:;
                        if ( rc != 0 ) {
                                BackendDB               db = *be;
@@ -1459,6 +1492,9 @@ static int
 ldap_chain_db_open(
        BackendDB       *be )
 {
+       slap_overinst   *on = (slap_overinst *) be->bd_info;
+       ldap_chain_t    *lc = (ldap_chain_t *)on->on_bi.bi_private;
+
 #ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
        int     rc = 0;
 
@@ -1468,6 +1504,13 @@ ldap_chain_db_open(
        }
 #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
 
+       if ( lc->lc_common_li == NULL ) {
+               void    *be_private = be->be_private;
+               ldap_chain_db_init_common( be );
+               lc->lc_common_li = lc->lc_cfg_li = (ldapinfo_t *)be->be_private;
+               be->be_private = be_private;
+       }
+
        return ldap_chain_db_func( be, db_open );
 }
 
@@ -1491,6 +1534,7 @@ ldap_chain_db_destroy(
 
        if ( lc ) {
                avl_free( lc->lc_lai.lai_tree, NULL );
+               ldap_pvt_thread_mutex_destroy( &lc->lc_lai.lai_mutex );
                ch_free( lc );
        }
 
@@ -1730,7 +1774,7 @@ ldap_chain_parse_ctrl(
 static slap_overinst ldapchain;
 
 int
-chain_init( void )
+chain_initialize( void )
 {
        int     rc;
 
@@ -1756,17 +1800,6 @@ chain_init( void )
        ldapchain.on_bi.bi_db_close = ldap_chain_db_close;
        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 the backend;
-        * part by the frontend; back-ldap should receive all the available
-        * 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;