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"
.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
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
.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
.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
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,
{
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;
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
#ifdef LDAP_CONTROL_SUBENTRIES
LDAP_CONTROL_SUBENTRIES,
#endif
- LDAP_CONTROL_VALUESRETURNFILTER,
#ifdef LDAP_CONTROL_X_PERMISSIVE_MODIFY
LDAP_CONTROL_X_PERMISSIVE_MODIFY,
#endif
{
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;
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 )
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;
}
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;
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;
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 );
#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;
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
*/
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 )
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(
#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 );
} 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 ) {
/* 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;
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;
{
static char *controls[] = {
LDAP_CONTROL_MANAGEDSAIT,
- LDAP_CONTROL_VALUESRETURNFILTER,
#ifdef LDAP_CONTROL_X_PERMISSIVE_MODIFY
LDAP_CONTROL_X_PERMISSIVE_MODIFY,
#endif
monitor_subsys_t *ms;
static char *controls[] = {
LDAP_CONTROL_MANAGEDSAIT,
- LDAP_CONTROL_VALUESRETURNFILTER,
NULL
};
#include "portable.h"
#include <stdio.h>
+#include <ac/string.h>
#include "slap.h"
#include "back-relay.h"
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;
#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
};
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;
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 */
{
}
}
+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 );
}
}
}
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",
return rc;
}
}
+
+ (void)backend_init_controls( &backendInfo[i] );
}
ldap_pvt_thread_mutex_init( &slapd_rq.rq_mutex );
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 );
return 0;
}
-static int
+int
backend_check_controls(
Operation *op,
SlapReply *rs )
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 */
(*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;
}
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;
}
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;
op_extended,
op_aux_operational,
op_aux_chk_referrals,
+ op_aux_chk_controls,
op_last
};
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 */
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
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
{
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;
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;
*/
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;
}
} 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
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;
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),
}
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 );
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(
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;
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++ ) {
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++ ) {
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 )
{
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:
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;
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 );
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;
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 );
}
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;
}
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 =
}
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;
/* 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;
* 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;
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;
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,
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
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:;
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 );
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 );
}
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++ ) {
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;
}
}
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;
}
}
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 */
#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
*/
#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
#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 */
(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)
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,
/* 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;
#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 */
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;
} while (1);
ldap_pvt_thread_mutex_unlock( &put_mutex1 );
+ return NULL;
}
int
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
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
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
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
#