size_t textlen = sizeof( textbuf );
int rc = 0;
int freevals = 1;
+ OpExtraDB oex;
Debug( LDAP_DEBUG_TRACE, "%s do_add\n",
op->o_log_prefix, 0, 0 );
freevals = 0;
+ oex.oe.oe_key = (void *)do_add;
+ oex.oe_db = NULL;
+ LDAP_SLIST_INSERT_HEAD(&op->o_extra, &oex.oe, oe_next);
+
op->o_bd = frontendDB;
rc = frontendDB->be_add( op, rs );
+ LDAP_SLIST_REMOVE(&op->o_extra, &oex.oe, OpExtra, oe_next);
#ifdef LDAP_X_TXN
if ( rc == LDAP_X_TXN_SPECIFY_OKAY ) {
} else
#endif
if ( rc == 0 ) {
- if ( op->ora_e != NULL && op->o_private != NULL ) {
+ if ( op->ora_e != NULL && oex.oe_db != NULL ) {
BackendDB *bd = op->o_bd;
- op->o_bd = (BackendDB *)op->o_private;
- op->o_private = NULL;
+ op->o_bd = oex.oe_db;
be_entry_release_w( op, op->ora_e );
op->ora_e = NULL;
op->o_bd = bd;
- op->o_private = NULL;
}
}
rc = op->o_bd->be_add( op, rs );
if ( rc == LDAP_SUCCESS ) {
+ OpExtra *oex;
/* NOTE: be_entry_release_w() is
* called by do_add(), so that global
* overlays on the way back can
* at least read the entry */
- op->o_private = op->o_bd;
+ LDAP_SLIST_FOREACH(oex, &op->o_extra, oe_next) {
+ if ( oex->oe_key == (void *)do_add ) {
+ ((OpExtraDB *)oex)->oe_db = op->o_bd;
+ break;
+ }
+ }
}
} else {
}
be->bd_info = bi;
+ be->bd_orig = be;
be->be_def_limit = frontendDB->be_def_limit;
be->be_dfltaccess = frontendDB->be_dfltaccess;
int rc;
GroupAssertion *g;
Backend *be = op->o_bd;
+ OpExtra *oex;
- op->o_bd = select_backend( gr_ndn, 0 );
+ 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;
+ else
+ 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 ||
AttributeDescription *group_at )
{
int rc;
- BackendDB *be_orig;
+ BackendDB *be_orig;
+ OpExtraDB oex;
if ( op->o_abandon ) {
return SLAPD_ABANDON;
}
+ if ( op->o_bd && SLAP_ISOVERLAY( op->o_bd ))
+ oex.oe_db = op->o_bd->bd_orig;
+ else
+ 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;
}
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;
+ else
+ op->o_bd = select_backend( edn, 0 );
if ( target && dn_match( &target->e_nname, edn ) ) {
e = target;
slap_access_t access )
{
int rc;
- BackendDB *be_orig;
+ BackendDB *be_orig;
+ OpExtraDB oex;
+
+ if ( op->o_bd && SLAP_ISOVERLAY( op->o_bd ))
+ oex.oe_db = op->o_bd->bd_orig;
+ else
+ 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;
}
assert( edn != NULL );
assert( access > ACL_NONE );
- op->o_bd = select_backend( edn, 0 );
+ if ( op->o_bd ) {
+ if ( SLAP_ISOVERLAY( op->o_bd ))
+ op->o_bd = op->o_bd->bd_orig;
+ } else {
+ op->o_bd = select_backend( edn, 0 );
+ }
if ( target && dn_match( &target->e_nname, edn ) ) {
e = target;
{
Attribute **ap;
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 */ ;
ap = &(*ap)->a_next;
}
- if ( op->o_bd != NULL ) {
- BackendDB *be_orig = op->o_bd;
-
- /* Let the overlays have a chance at this */
+ /* Let the overlays have a chance at this */
+ if ( oex && ((OpExtraDB *)oex)->oe_db ) {
+ op->o_bd = ((OpExtraDB *)oex)->oe_db;
+ } else {
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;
}
{
int rc;
BackendDB *be_orig;
+ OpExtraDB oex;
+
+ if ( op->o_bd && SLAP_ISOVERLAY( op->o_bd ))
+ oex.oe_db = op->o_bd->bd_orig;
+ else
+ 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 */
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;
}
struct BackendDB {
BackendInfo *bd_info; /* pointer to shared backend info */
+ BackendDB *bd_orig; /* pointer to original backend, for overlays */
/* fields in this structure (and routines acting on this structure)
should be renamed from be_ to bd_ */
req_pwdexop_s oq_pwdexop;
} OpRequest;
+/* This is only a header. Actual users should define their own
+ * structs with the oe_next / oe_key fields at the top and
+ * whatever else they need following.
+ */
+typedef struct OpExtra {
+ LDAP_SLIST_ENTRY(OpExtra) oe_next;
+ void *oe_key;
+} OpExtra;
+
+typedef struct OpExtraDB {
+ OpExtra oe;
+ BackendDB *oe_db;
+} OpExtraDB;
+
struct Operation {
Opheader *o_hdr;
LDAPControl **o_ctrls; /* controls */
struct berval o_csn;
+ /* DEPRECATE o_private - use o_extra instead */
void *o_private; /* anything the backend needs */
+ LDAP_SLIST_HEAD(o_e, OpExtra) o_extra; /* anything the backend needs */
LDAP_STAILQ_ENTRY(Operation) o_next; /* next operation in list */
};
{
SlapReply *rs;
Slapi_Entry *entry_orig = NULL;
+ OpExtraDB oex;
+ int rc;
if ( pb == NULL ) {
return -1;
goto cleanup;
}
- if ( slapi_int_func_internal_pb( pb, op_add ) == 0 ) {
- if ( pb->pb_op->ora_e != NULL && pb->pb_op->o_private != NULL ) {
+ oex.oe.oe_key = (void *)do_add;
+ oex.oe_db = NULL;
+ LDAP_SLIST_INSERT_HEAD(&pb->pb_op->o_extra, &oex.oe, oe_next);
+ rc = slapi_int_func_internal_pb( pb, op_add );
+ LDAP_SLIST_REMOVE(&pb->pb_op->o_extra, &oex.oe, OpExtra, oe_next);
+
+ if ( !rc ) {
+ if ( pb->pb_op->ora_e != NULL && oex.oe_db != NULL ) {
BackendDB *bd = pb->pb_op->o_bd;
- pb->pb_op->o_bd = (BackendDB *)pb->pb_op->o_private;
- pb->pb_op->o_private = NULL;
+ pb->pb_op->o_bd = oex.oe_db;
be_entry_release_w( pb->pb_op, pb->pb_op->ora_e );
pb->pb_op->ora_e = NULL;
pb->pb_op->o_bd = bd;
- pb->pb_op->o_private = NULL;
}
}