From e25cba04af8567b7720287b57f70a7591411475e Mon Sep 17 00:00:00 2001 From: Howard Chu <hyc@openldap.org> Date: Fri, 21 Mar 2008 02:01:07 +0000 Subject: [PATCH] ITS#5419 OpExtra --- servers/slapd/add.c | 20 ++++++-- servers/slapd/backend.c | 90 +++++++++++++++++++++++++++------ servers/slapd/slap.h | 17 +++++++ servers/slapd/slapi/slapi_ops.c | 16 ++++-- 4 files changed, 117 insertions(+), 26 deletions(-) diff --git a/servers/slapd/add.c b/servers/slapd/add.c index aed74d39a2..2561152d0b 100644 --- a/servers/slapd/add.c +++ b/servers/slapd/add.c @@ -48,6 +48,7 @@ do_add( Operation *op, SlapReply *rs ) 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 ); @@ -185,8 +186,13 @@ do_add( Operation *op, SlapReply *rs ) 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 ) { @@ -195,17 +201,15 @@ do_add( Operation *op, SlapReply *rs ) } 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; } } @@ -329,11 +333,17 @@ fe_op_add( Operation *op, SlapReply *rs ) 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 { diff --git a/servers/slapd/backend.c b/servers/slapd/backend.c index b36b65c3d1..fb92cf6f7f 100644 --- a/servers/slapd/backend.c +++ b/servers/slapd/backend.c @@ -585,6 +585,7 @@ backend_db_init( } be->bd_info = bi; + be->bd_orig = be; be->be_def_limit = frontendDB->be_def_limit; be->be_dfltaccess = frontendDB->be_dfltaccess; @@ -1349,8 +1350,17 @@ fe_acl_group( 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 || @@ -1556,17 +1566,26 @@ backend_group( 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; } @@ -1586,8 +1605,17 @@ 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; + else + op->o_bd = select_backend( edn, 0 ); if ( target && dn_match( &target->e_nname, edn ) ) { e = target; @@ -1706,13 +1734,22 @@ backend_attribute( 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; } @@ -1738,7 +1775,12 @@ backend_access( 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; @@ -1831,6 +1873,13 @@ fe_aux_operational( { 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 */ ; @@ -1856,19 +1905,19 @@ 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 */ + /* 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; } @@ -1877,6 +1926,14 @@ int backend_operational( Operation *op, SlapReply *rs ) { 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 */ @@ -1884,6 +1941,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; } diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index 2a086aa560..7aa16a3b44 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -1707,6 +1707,7 @@ struct ConfigOCs; /* config.h */ 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_ */ @@ -2466,6 +2467,20 @@ typedef union OpRequest { 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; @@ -2657,7 +2672,9 @@ struct Operation { 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 */ }; diff --git a/servers/slapd/slapi/slapi_ops.c b/servers/slapd/slapi/slapi_ops.c index 9080f174e5..e7aab5d8d3 100644 --- a/servers/slapd/slapi/slapi_ops.c +++ b/servers/slapd/slapi/slapi_ops.c @@ -419,6 +419,8 @@ slapi_add_internal_pb( Slapi_PBlock *pb ) { SlapReply *rs; Slapi_Entry *entry_orig = NULL; + OpExtraDB oex; + int rc; if ( pb == NULL ) { return -1; @@ -478,16 +480,20 @@ slapi_add_internal_pb( Slapi_PBlock *pb ) 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; } } -- GitLab