X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fbackend.c;h=b003354219566b2c49ee8321537d4f698eef2960;hb=4105ee462dac31f490b383d6c35e2f1bb0a1bccf;hp=7d6884a848d82f2d34343de09b677c7c77b14018;hpb=cd63a0c43bfefbdd22e75e62e3dd5b5df79355f7;p=openldap
diff --git a/servers/slapd/backend.c b/servers/slapd/backend.c
index 7d6884a848..b003354219 100644
--- a/servers/slapd/backend.c
+++ b/servers/slapd/backend.c
@@ -2,7 +2,7 @@
/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software .
*
- * Copyright 1998-2008 The OpenLDAP Foundation.
+ * Copyright 1998-2009 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -226,9 +226,22 @@ int backend_startup_one(Backend *be, ConfigReply *cr)
(void)backend_set_controls( be );
} else {
+ char *type = be->bd_info->bi_type;
+ char *suffix = "(null)";
+
+ if ( overlay_is_over( be ) ) {
+ slap_overinfo *oi = (slap_overinfo *)be->bd_info->bi_private;
+ type = oi->oi_orig->bi_type;
+ }
+
+ if ( be->be_suffix != NULL && !BER_BVISNULL( &be->be_suffix[0] ) ) {
+ suffix = be->be_suffix[0].bv_val;
+ }
+
Debug( LDAP_DEBUG_ANY,
- "backend_startup_one: bi_db_open failed! (%d)\n",
- rc, 0, 0 );
+ "backend_startup_one (type=%s, suffix=\"%s\"): "
+ "bi_db_open failed! (%d)\n",
+ type, suffix, rc );
}
}
@@ -261,15 +274,13 @@ int backend_startup(Backend *be)
return rc;
}
}
- /* append global access controls */
- acl_append( &be->be_acl, frontendDB->be_acl, -1 );
return backend_startup_one( be, &cr );
}
/* open frontend, if required */
if ( frontendDB->bd_info->bi_db_open ) {
- rc = frontendDB->bd_info->bi_db_open( frontendDB, NULL );
+ rc = frontendDB->bd_info->bi_db_open( frontendDB, &cr );
if ( rc != 0 ) {
Debug( LDAP_DEBUG_ANY,
"backend_startup: bi_db_open(frontend) failed! (%d)\n",
@@ -310,8 +321,6 @@ int backend_startup(Backend *be)
"has no suffix\n",
i, be->bd_info->bi_type, 0 );
}
- /* append global access controls */
- acl_append( &be->be_acl, frontendDB->be_acl, -1 );
rc = backend_startup_one( be, &cr );
@@ -349,11 +358,13 @@ int backend_shutdown( Backend *be )
}
if ( be->bd_info->bi_db_close ) {
- be->bd_info->bi_db_close( be, NULL );
+ rc = be->bd_info->bi_db_close( be, NULL );
+ if ( rc ) return rc;
}
if( be->bd_info->bi_close ) {
- be->bd_info->bi_close( be->bd_info );
+ rc = be->bd_info->bi_close( be->bd_info );
+ if ( rc ) return rc;
}
return 0;
@@ -451,7 +462,7 @@ void backend_destroy_one( BackendDB *bd, int dynamic )
if ( !BER_BVISNULL( &bd->be_rootpw ) ) {
free( bd->be_rootpw.bv_val );
}
- acl_destroy( bd->be_acl, frontendDB->be_acl );
+ acl_destroy( bd->be_acl );
limits_destroy( bd->be_limits );
if ( !BER_BVISNULL( &bd->be_update_ndn ) ) {
ch_free( bd->be_update_ndn.bv_val );
@@ -502,7 +513,8 @@ int backend_destroy(void)
if ( !BER_BVISNULL( &bd->be_rootpw ) ) {
free( bd->be_rootpw.bv_val );
}
- acl_destroy( bd->be_acl, frontendDB->be_acl );
+ acl_destroy( bd->be_acl );
+ frontendDB = NULL;
}
return 0;
@@ -585,6 +597,7 @@ backend_db_init(
}
be->bd_info = bi;
+ be->bd_self = be;
be->be_def_limit = frontendDB->be_def_limit;
be->be_dfltaccess = frontendDB->be_dfltaccess;
@@ -593,8 +606,7 @@ backend_db_init(
be->be_requires = frontendDB->be_requires;
be->be_ssf_set = frontendDB->be_ssf_set;
- be->be_pcl_mutexp = &be->be_pcl_mutex;
- ldap_pvt_thread_mutex_init( be->be_pcl_mutexp );
+ ldap_pvt_thread_mutex_init( &be->be_pcl_mutex );
/* assign a default depth limit for alias deref */
be->be_max_deref_depth = SLAPD_DEFAULT_MAXDEREFDEPTH;
@@ -613,6 +625,9 @@ backend_db_init(
nbackends--;
}
} else {
+ if ( !bi->bi_nDB ) {
+ backend_init_controls( bi );
+ }
bi->bi_nDB++;
}
return( be );
@@ -744,10 +759,10 @@ be_slurp_update( Operation *op )
int
be_shadow_update( Operation *op )
{
- /* This assumes that all internal ops (connid == -1) on a syncrepl
+ /* This assumes that all internal ops (connid <= -1000) on a syncrepl
* database are syncrepl operations.
*/
- return (( SLAP_SYNC_SHADOW( op->o_bd ) && op->o_connid == -1 ) ||
+ return (( SLAP_SYNC_SHADOW( op->o_bd ) && op->o_connid <= -1000 ) ||
( SLAP_SHADOW( op->o_bd ) && be_isupdate_dn( op->o_bd, &op->o_ndn ) ) );
}
@@ -945,6 +960,14 @@ backend_check_controls(
case LDAP_COMPARE_FALSE:
if ( !op->o_bd->be_ctrls[cid] && (*ctrls)->ldctl_iscritical ) {
+#ifdef SLAP_CONTROL_X_WHATFAILED
+ if ( get_whatFailed( op ) ) {
+ char *oids[ 2 ];
+ oids[ 0 ] = (*ctrls)->ldctl_oid;
+ oids[ 1 ] = NULL;
+ slap_ctrl_whatFailed_add( op, rs, oids );
+ }
+#endif
/* RFC 4511 allows unavailableCriticalExtension to be
* returned when the server is unwilling to perform
* an operation extended by a recognized critical
@@ -995,13 +1018,19 @@ backend_check_restrictions(
slap_mask_t requires;
slap_mask_t opflag;
slap_mask_t exopflag = 0;
- slap_ssf_set_t *ssf;
+ slap_ssf_set_t ssfs, *ssf;
int updateop = 0;
int starttls = 0;
int session = 0;
+ restrictops = frontendDB->be_restrictops;
+ requires = frontendDB->be_requires;
+ ssfs = frontendDB->be_ssf_set;
+ ssf = &ssfs;
+
if ( op->o_bd ) {
- int rc = SLAP_CB_CONTINUE;
+ slap_ssf_t *fssf, *bssf;
+ int rc = SLAP_CB_CONTINUE, i;
if ( op->o_bd->be_chk_controls ) {
rc = ( *op->o_bd->be_chk_controls )( op, rs );
@@ -1015,14 +1044,13 @@ backend_check_restrictions(
return rs->sr_err;
}
- restrictops = op->o_bd->be_restrictops;
- requires = op->o_bd->be_requires;
- ssf = &op->o_bd->be_ssf_set;
-
- } else {
- restrictops = frontendDB->be_restrictops;
- requires = frontendDB->be_requires;
- ssf = &frontendDB->be_ssf_set;
+ restrictops |= op->o_bd->be_restrictops;
+ requires |= op->o_bd->be_requires;
+ bssf = &op->o_bd->be_ssf_set.sss_ssf;
+ fssf = &ssfs.sss_ssf;
+ for ( i=0; io_tag ) {
@@ -1281,7 +1309,8 @@ backend_check_restrictions(
}
if( ( restrictops & opflag )
- || ( exopflag && ( restrictops & exopflag ) ) ) {
+ || ( exopflag && ( restrictops & exopflag ) )
+ || (( restrictops & SLAP_RESTRICT_READONLY ) && updateop )) {
if( ( restrictops & SLAP_RESTRICT_OP_MASK) == SLAP_RESTRICT_OP_READS ) {
rs->sr_text = "read operations restricted";
} else if ( restrictops & exopflag ) {
@@ -1349,8 +1378,18 @@ fe_acl_group(
int rc;
GroupAssertion *g;
Backend *be = op->o_bd;
+ OpExtra *oex;
+
+ LDAP_SLIST_FOREACH(oex, &op->o_extra, oe_next) {
+ if ( oex->oe_key == (void *)backend_group )
+ break;
+ }
+
+ if ( oex && ((OpExtraDB *)oex)->oe_db )
+ op->o_bd = ((OpExtraDB *)oex)->oe_db;
- op->o_bd = select_backend( gr_ndn, 0 );
+ if ( !op->o_bd || !SLAP_DBHIDDEN( op->o_bd ))
+ op->o_bd = select_backend( gr_ndn, 0 );
for ( g = op->o_groups; g; g = g->ga_next ) {
if ( g->ga_be != op->o_bd || g->ga_oc != group_oc ||
@@ -1485,7 +1524,7 @@ fe_acl_group(
{
rc = 0;
}
- filter_free_x( op, filter );
+ filter_free_x( op, filter, 1 );
}
loopit:
ldap_free_urldesc( ludp );
@@ -1556,17 +1595,23 @@ backend_group(
AttributeDescription *group_at )
{
int rc;
- BackendDB *be_orig;
+ BackendDB *be_orig;
+ OpExtraDB oex;
if ( op->o_abandon ) {
return SLAPD_ABANDON;
}
+ oex.oe_db = op->o_bd;
+ oex.oe.oe_key = (void *)backend_group;
+ LDAP_SLIST_INSERT_HEAD(&op->o_extra, &oex.oe, oe_next);
+
be_orig = op->o_bd;
op->o_bd = frontendDB;
rc = frontendDB->be_group( op, target, gr_ndn,
op_ndn, group_oc, group_at );
op->o_bd = be_orig;
+ LDAP_SLIST_REMOVE(&op->o_extra, &oex.oe, OpExtra, oe_next);
return rc;
}
@@ -1586,8 +1631,18 @@ fe_acl_attribute(
int freeattr = 0, i, j, rc = LDAP_SUCCESS;
AccessControlState acl_state = ACL_STATE_INIT;
Backend *be = op->o_bd;
+ OpExtra *oex;
+
+ LDAP_SLIST_FOREACH(oex, &op->o_extra, oe_next) {
+ if ( oex->oe_key == (void *)backend_attribute )
+ break;
+ }
- op->o_bd = select_backend( edn, 0 );
+ if ( oex && ((OpExtraDB *)oex)->oe_db )
+ op->o_bd = ((OpExtraDB *)oex)->oe_db;
+
+ if ( !op->o_bd || !SLAP_DBHIDDEN( op->o_bd ))
+ op->o_bd = select_backend( edn, 0 );
if ( target && dn_match( &target->e_nname, edn ) ) {
e = target;
@@ -1706,13 +1761,19 @@ backend_attribute(
slap_access_t access )
{
int rc;
- BackendDB *be_orig;
+ BackendDB *be_orig;
+ OpExtraDB oex;
+
+ oex.oe_db = op->o_bd;
+ oex.oe.oe_key = (void *)backend_attribute;
+ LDAP_SLIST_INSERT_HEAD(&op->o_extra, &oex.oe, oe_next);
be_orig = op->o_bd;
op->o_bd = frontendDB;
rc = frontendDB->be_attribute( op, target, edn,
entry_at, vals, access );
op->o_bd = be_orig;
+ LDAP_SLIST_REMOVE(&op->o_extra, &oex.oe, OpExtra, oe_next);
return rc;
}
@@ -1738,7 +1799,9 @@ backend_access(
assert( edn != NULL );
assert( access > ACL_NONE );
- op->o_bd = select_backend( edn, 0 );
+ if ( !op->o_bd ) {
+ op->o_bd = select_backend( edn, 0 );
+ }
if ( target && dn_match( &target->e_nname, edn ) ) {
e = target;
@@ -1830,7 +1893,14 @@ fe_aux_operational(
SlapReply *rs )
{
Attribute **ap;
- int rc = 0;
+ int rc = LDAP_SUCCESS;
+ BackendDB *be_orig = op->o_bd;
+ OpExtra *oex;
+
+ LDAP_SLIST_FOREACH(oex, &op->o_extra, oe_next) {
+ if ( oex->oe_key == (void *)backend_operational )
+ break;
+ }
for ( ap = &rs->sr_operational_attrs; *ap; ap = &(*ap)->a_next )
/* just count them */ ;
@@ -1856,19 +1926,20 @@ fe_aux_operational(
ap = &(*ap)->a_next;
}
- if ( op->o_bd != NULL ) {
- BackendDB *be_orig = op->o_bd;
+ /* Let the overlays have a chance at this */
+ if ( oex && ((OpExtraDB *)oex)->oe_db )
+ op->o_bd = ((OpExtraDB *)oex)->oe_db;
- /* Let the overlays have a chance at this */
+ if ( !op->o_bd || !SLAP_DBHIDDEN( op->o_bd ))
op->o_bd = select_backend( &op->o_req_ndn, 0 );
- if ( op->o_bd != NULL && !be_match( op->o_bd, frontendDB ) &&
- ( SLAP_OPATTRS( rs->sr_attr_flags ) || rs->sr_attrs ) &&
- op->o_bd->be_operational != NULL )
- {
- rc = op->o_bd->be_operational( op, rs );
- }
- op->o_bd = be_orig;
+
+ if ( op->o_bd != NULL && !be_match( op->o_bd, frontendDB ) &&
+ ( SLAP_OPATTRS( rs->sr_attr_flags ) || rs->sr_attrs ) &&
+ op->o_bd->be_operational != NULL )
+ {
+ rc = op->o_bd->be_operational( op, rs );
}
+ op->o_bd = be_orig;
return rc;
}
@@ -1877,6 +1948,11 @@ int backend_operational( Operation *op, SlapReply *rs )
{
int rc;
BackendDB *be_orig;
+ OpExtraDB oex;
+
+ oex.oe_db = op->o_bd;
+ oex.oe.oe_key = (void *)backend_operational;
+ LDAP_SLIST_INSERT_HEAD(&op->o_extra, &oex.oe, oe_next);
/* Moved this into the frontend so global overlays are called */
@@ -1884,6 +1960,7 @@ int backend_operational( Operation *op, SlapReply *rs )
op->o_bd = frontendDB;
rc = frontendDB->be_operational( op, rs );
op->o_bd = be_orig;
+ LDAP_SLIST_REMOVE(&op->o_extra, &oex.oe, OpExtra, oe_next);
return rc;
}