/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
- * Copyright 2003-2010 The OpenLDAP Foundation.
+ * Copyright 2003-2011 The OpenLDAP Foundation.
* Portions Copyright 2003 Howard Chu.
* All rights reserved.
*
assert( !BER_BVISNULL( &li2->li_bvuri[ 0 ] ) );
assert( BER_BVISNULL( &li2->li_bvuri[ 1 ] ) );
- /* If local DNs don't match, it is definitely not a match */
return ber_bvcmp( &li1->li_bvuri[ 0 ], &li2->li_bvuri[ 0 ] );
}
assert( !BER_BVISNULL( &li2->li_bvuri[ 0 ] ) );
assert( BER_BVISNULL( &li2->li_bvuri[ 1 ] ) );
- /* Cannot have more than one shared session with same DN */
if ( ber_bvcmp( &li1->li_bvuri[ 0 ], &li2->li_bvuri[ 0 ] ) == 0 ) {
return -1;
}
-
+
return 0;
}
* proto://[host][:port]/ only */
rc = ldap_url_parse_ext( ref->bv_val, &srv, LDAP_PVT_URL_PARSE_NONE );
if ( rc != LDAP_URL_SUCCESS ) {
+ Debug( LDAP_DEBUG_TRACE, "%s ldap_chain_op: unable to parse ref=\"%s\"\n",
+ op->o_log_prefix, ref->bv_val, 0 );
+
/* try next */
rc = LDAP_OTHER;
continue;
filter2bv_x( op, tmp_oq_search.rs_filter, &tmp_oq_search.rs_filterstr );
} else {
+ Debug( LDAP_DEBUG_TRACE, "%s ldap_chain_op: ref=\"%s\": unable to parse filter=\"%s\"\n",
+ op->o_log_prefix, ref->bv_val, srv->lud_filter );
rc = LDAP_OTHER;
}
}
}
if ( li.li_uri == NULL ) {
+ Debug( LDAP_DEBUG_TRACE, "%s ldap_chain_op: ref=\"%s\" unable to reconstruct URI\n",
+ op->o_log_prefix, ref->bv_val, 0 );
+
/* try next */
rc = LDAP_OTHER;
goto further_cleanup;
}
+ Debug( LDAP_DEBUG_TRACE, "%s ldap_chain_op: ref=\"%s\" -> \"%s\"\n",
+ op->o_log_prefix, ref->bv_val, li.li_uri );
+
op->o_req_dn = pdn;
op->o_req_ndn = ndn;
if ( lip != NULL ) {
op->o_bd->be_private = (void *)lip;
+ Debug( LDAP_DEBUG_TRACE, "%s ldap_chain_op: ref=\"%s\": URI=\"%s\" found in cache\n",
+ op->o_log_prefix, ref->bv_val, li.li_uri );
+
} else {
rc = ldap_chain_db_init_one( op->o_bd );
if ( rc != 0 ) {
+ Debug( LDAP_DEBUG_TRACE, "%s ldap_chain_op: ref=\"%s\" unable to init back-ldap for URI=\"%s\"\n",
+ op->o_log_prefix, ref->bv_val, li.li_uri );
goto cleanup;
}
lip = (ldapinfo_t *)op->o_bd->be_private;
lip->li_bvuri = bvuri;
rc = ldap_chain_db_open_one( op->o_bd );
if ( rc != 0 ) {
+ Debug( LDAP_DEBUG_TRACE, "%s ldap_chain_op: ref=\"%s\" unable to open back-ldap for URI=\"%s\"\n",
+ op->o_log_prefix, ref->bv_val, li.li_uri );
lip->li_uri = NULL;
lip->li_bvuri = NULL;
(void)ldap_chain_db_destroy_one( op->o_bd, NULL);
} else {
temporary = 1;
}
+
+ Debug( LDAP_DEBUG_TRACE, "%s ldap_chain_op: ref=\"%s\" %s\n",
+ op->o_log_prefix, ref->bv_val, temporary ? "temporary" : "caching" );
}
lb->lb_op_f = op_f;
* to be set once for all (correct?) */
li.li_bvuri = bvuri;
for ( ; !BER_BVISNULL( &ref[0] ); ref++ ) {
- SlapReply rs2 = { 0 };
+ SlapReply rs2 = { REP_RESULT };
LDAPURLDesc *srv;
req_search_s save_oq_search = op->oq_search,
tmp_oq_search = { 0 };
* proto://[host][:port]/ only */
rc = ldap_url_parse_ext( ref[0].bv_val, &srv, LDAP_PVT_URL_PARSE_NONE );
if ( rc != LDAP_URL_SUCCESS ) {
+ Debug( LDAP_DEBUG_TRACE, "%s ldap_chain_search: unable to parse ref=\"%s\"\n",
+ op->o_log_prefix, ref->bv_val, 0 );
+
/* try next */
rs->sr_err = LDAP_OTHER;
continue;
} else {
/* RFC 4511: if scope is absent, use original */
- tmp_oq_search.rs_scope = op->ors_scope;
+ /* Section 4.5.3: if scope is onelevel, use base */
+ if ( op->ors_scope == LDAP_SCOPE_ONELEVEL )
+ tmp_oq_search.rs_scope = LDAP_SCOPE_BASE;
+ else
+ tmp_oq_search.rs_scope = op->ors_scope;
}
rc = LDAP_SUCCESS;
filter2bv_x( op, tmp_oq_search.rs_filter, &tmp_oq_search.rs_filterstr );
} else {
+ Debug( LDAP_DEBUG_TRACE, "%s ldap_chain_search: ref=\"%s\": unable to parse filter=\"%s\"\n",
+ op->o_log_prefix, ref->bv_val, srv->lud_filter );
rc = LDAP_OTHER;
}
}
ldap_free_urldesc( srv );
if ( rc != LDAP_SUCCESS || li.li_uri == NULL ) {
+ Debug( LDAP_DEBUG_TRACE, "%s ldap_chain_search: ref=\"%s\" unable to reconstruct URI\n",
+ op->o_log_prefix, ref->bv_val, 0 );
+
/* try next */
rc = LDAP_OTHER;
goto further_cleanup;
}
+ Debug( LDAP_DEBUG_TRACE, "%s ldap_chain_search: ref=\"%s\" -> \"%s\"\n",
+ op->o_log_prefix, ref->bv_val, li.li_uri );
+
op->o_req_dn = pdn;
op->o_req_ndn = ndn;
op->ors_scope = tmp_oq_search.rs_scope;
if ( lip != NULL ) {
op->o_bd->be_private = (void *)lip;
+ Debug( LDAP_DEBUG_TRACE, "%s ldap_chain_search: ref=\"%s\": URI=\"%s\" found in cache\n",
+ op->o_log_prefix, ref->bv_val, li.li_uri );
+
} else {
/* if none is found, create a temporary... */
rc = ldap_chain_db_init_one( op->o_bd );
if ( rc != 0 ) {
+ Debug( LDAP_DEBUG_TRACE, "%s ldap_chain_search: ref=\"%s\" unable to init back-ldap for URI=\"%s\"\n",
+ op->o_log_prefix, ref->bv_val, li.li_uri );
goto cleanup;
}
lip = (ldapinfo_t *)op->o_bd->be_private;
lip->li_bvuri = bvuri;
rc = ldap_chain_db_open_one( op->o_bd );
if ( rc != 0 ) {
+ Debug( LDAP_DEBUG_TRACE, "%s ldap_chain_search: ref=\"%s\" unable to open back-ldap for URI=\"%s\"\n",
+ op->o_log_prefix, ref->bv_val, li.li_uri );
lip->li_uri = NULL;
lip->li_bvuri = NULL;
(void)ldap_chain_db_destroy_one( op->o_bd, NULL );
} else {
temporary = 1;
}
+
+ Debug( LDAP_DEBUG_TRACE, "%s ldap_chain_search: ref=\"%s\" %s\n",
+ op->o_log_prefix, ref->bv_val, temporary ? "temporary" : "caching" );
}
lb->lb_op_f = lback->bi_op_search;
static ConfigDriver chain_cf_gen;
static ConfigCfAdd chain_cfadd;
static ConfigLDAPadd chain_ldadd;
+#ifdef SLAP_CONFIG_DELETE
+static ConfigLDAPdel chain_lddel;
+#endif
static ConfigTable chaincfg[] = {
#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
"NAME 'olcChainDatabase' "
"DESC 'Chain remote server configuration' "
"AUXILIARY )",
- Cft_Misc, olcDatabaseDummy, chain_ldadd },
+ Cft_Misc, olcDatabaseDummy, chain_ldadd
+#ifdef SLAP_CONFIG_DELETE
+ , NULL, chain_lddel
+#endif
+ },
{ NULL, 0, NULL }
};
assert( rc == LDAP_SUCCESS );
at = attr_find( e->e_attrs, ad );
+#if 0
if ( lc->lc_common_li == NULL && at != NULL ) {
/* FIXME: we should generate an empty default entry
* if none is supplied */
rc = LDAP_CONSTRAINT_VIOLATION;
goto done;
- } else if ( lc->lc_common_li != NULL && at == NULL ) {
+ } else
+#endif
+ if ( lc->lc_common_li != NULL && at == NULL ) {
/* FIXME: we should generate an empty default entry
* if none is supplied */
Debug( LDAP_DEBUG_ANY, "slapd-chain: "
return 0;
}
+#ifdef SLAP_CONFIG_DELETE
+static int
+chain_lddel( CfEntryInfo *ce, Operation *op )
+{
+ CfEntryInfo *pe = ce->ce_parent;
+ slap_overinst *on = (slap_overinst *)pe->ce_bi;
+ ldap_chain_t *lc = (ldap_chain_t *)on->on_bi.bi_private;
+ ldapinfo_t *li = (ldapinfo_t *) ce->ce_be->be_private;
+
+ if ( li != lc->lc_common_li ) {
+ if (! avl_delete( &lc->lc_lai.lai_tree, li, ldap_chain_uri_cmp ) ) {
+ Debug( LDAP_DEBUG_ANY, "slapd-chain: avl_delete failed. "
+ "\"%s\" not found.\n", li->li_uri, 0, 0 );
+ return -1;
+ }
+ } else if ( lc->lc_lai.lai_tree ) {
+ Debug( LDAP_DEBUG_ANY, "slapd-chain: cannot delete first underlying "
+ "LDAP database when other databases are still present.\n", 0, 0, 0 );
+ return -1;
+ } else {
+ lc->lc_common_li = NULL;
+ }
+
+ ce->ce_be->bd_info = lback;
+
+ if ( ce->ce_be->bd_info->bi_db_close ) {
+ ce->ce_be->bd_info->bi_db_close( ce->ce_be, NULL );
+ }
+ if ( ce->ce_be->bd_info->bi_db_destroy ) {
+ ce->ce_be->bd_info->bi_db_destroy( ce->ce_be, NULL );
+ }
+
+ ch_free(ce->ce_be);
+ ce->ce_be = NULL;
+
+ return LDAP_SUCCESS;
+}
+#endif /* SLAP_CONFIG_DELETE */
+
#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
static slap_verbmasks chaining_mode[] = {
{ BER_BVC("referralsRequired"), LDAP_REFERRALS_REQUIRED },
ldap_chain_t *lc = (ldap_chain_t *)on->on_bi.bi_private;
int rc = SLAP_CONF_UNKNOWN;
-
+
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;
+ BackendDB db = *be;
+ ldap_chain_db_init_common( &db );
+ lc->lc_common_li = lc->lc_cfg_li = (ldapinfo_t *)db.be_private;
}
/* Something for the chain database? */
if ( strncasecmp( argv[ 0 ], "chain-", STRLENOF( "chain-" ) ) == 0 ) {
char *save_argv0 = argv[ 0 ];
- BackendInfo *bd_info = be->bd_info;
- void *be_private = be->be_private;
- ConfigOCs *be_cf_ocs = be->be_cf_ocs;
+ BackendDB db = *be;
static char *allowed_argv[] = {
/* special: put URI here, so in the meanwhile
* it detects whether a new URI is being provided */
}
if ( which_argv == 0 ) {
- rc = ldap_chain_db_init_one( be );
+ rc = ldap_chain_db_init_one( &db );
if ( rc != 0 ) {
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"underlying slapd-ldap initialization failed.\n.",
fname, lineno, 0 );
return 1;
}
- lc->lc_cfg_li = be->be_private;
+ lc->lc_cfg_li = db.be_private;
}
/* TODO: add checks on what other slapd-ldap(5) args
* be warned.
*/
- be->bd_info = lback;
- be->be_private = (void *)lc->lc_cfg_li;
- be->be_cf_ocs = lback->bi_cf_ocs;
+ db.bd_info = lback;
+ db.be_private = (void *)lc->lc_cfg_li;
+ db.be_cf_ocs = lback->bi_cf_ocs;
- rc = config_generic_wrapper( be, fname, lineno, argc, argv );
+ rc = config_generic_wrapper( &db, fname, lineno, argc, argv );
argv[ 0 ] = save_argv0;
- be->be_cf_ocs = be_cf_ocs;
- be->be_private = be_private;
- be->bd_info = bd_info;
if ( which_argv == 0 ) {
private_destroy:;
if ( rc != 0 ) {
- BackendDB db = *be;
-
db.bd_info = lback;
db.be_private = (void *)lc->lc_cfg_li;
ldap_chain_db_destroy_one( &db, NULL );
lc->lc_cfg_li = NULL;
-
} else {
if ( lc->lc_cfg_li->li_bvuri == NULL
|| BER_BVISNULL( &lc->lc_cfg_li->li_bvuri[ 0 ] )
}
}
}
-
+
return rc;
}