X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=contrib%2Fslapd-modules%2Fautogroup%2Fautogroup.c;h=4d7d3b0aa70674c586536d509d57e49203aff230;hb=1df85d3427c287086df4ef41ef0edb1fa7e5bcec;hp=06e140789f1ac65558c2c91282122fea3153cec3;hpb=b107cffb871a5b1925590e4122e0fadd079ff829;p=openldap diff --git a/contrib/slapd-modules/autogroup/autogroup.c b/contrib/slapd-modules/autogroup/autogroup.c index 06e140789f..4d7d3b0aa7 100644 --- a/contrib/slapd-modules/autogroup/autogroup.c +++ b/contrib/slapd-modules/autogroup/autogroup.c @@ -2,7 +2,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 2007-2013 The OpenLDAP Foundation. + * Copyright 2007-2017 The OpenLDAP Foundation. * Portions Copyright 2007 Michał Szulczyński. * Portions Copyright 2009 Howard Chu. * All rights reserved. @@ -38,6 +38,8 @@ #define SLAPD_MEMBEROF_ATTR "memberOf" #endif +static slap_overinst autogroup; + /* Filter represents the memberURL of a group. */ typedef struct autogroup_filter_t { struct berval agf_dn; /* The base DN in memberURL */ @@ -111,6 +113,8 @@ autogroup_add_member_to_group( Operation *op, BerValue *dn, BerValue *ndn, autog BerValue *vals, *nvals; slap_callback cb = { NULL, slap_null_cb, NULL, NULL }; Operation o = *op; + unsigned long opid = op->o_opid; + OpExtra oex; assert( dn != NULL ); assert( ndn != NULL ); @@ -133,20 +137,31 @@ autogroup_add_member_to_group( Operation *op, BerValue *dn, BerValue *ndn, autog modlist->sml_flags = SLAP_MOD_INTERNAL; modlist->sml_next = NULL; + o.o_opid = 0; /* shared with op, saved above */ o.o_tag = LDAP_REQ_MODIFY; o.o_callback = &cb; o.orm_modlist = modlist; + o.o_dn = op->o_bd->be_rootdn; + o.o_ndn = op->o_bd->be_rootndn; o.o_req_dn = age->age_dn; o.o_req_ndn = age->age_ndn; o.o_permissive_modify = 1; + o.o_dont_replicate = 1; + o.orm_no_opattrs = 1; o.o_managedsait = SLAP_CONTROL_CRITICAL; o.o_relax = SLAP_CONTROL_CRITICAL; + oex.oe_key = (void *)&autogroup; + LDAP_SLIST_INSERT_HEAD( &o.o_extra, &oex, oe_next ); + o.o_bd->bd_info = (BackendInfo *)on->on_info; (void)op->o_bd->be_modify( &o, &sreply ); o.o_bd->bd_info = (BackendInfo *)on; + LDAP_SLIST_REMOVE( &o.o_extra, &oex, OpExtra, oe_next ); + slap_mods_free( modlist, 1 ); + op->o_opid = opid; return sreply.sr_err; } @@ -156,24 +171,18 @@ autogroup_add_member_to_group( Operation *op, BerValue *dn, BerValue *ndn, autog ** age - the group to which the values will be added */ static int -autogroup_add_member_values_to_group( Operation *op, Entry *e, autogroup_entry_t *age, AttributeDescription *attrdesc ) +autogroup_add_member_values_to_group( Operation *op, struct berval *dn, autogroup_entry_t *age, Attribute *attr ) { slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; Modifications modlist; SlapReply sreply = {REP_RESULT}; - Attribute *attr; slap_callback cb = { NULL, slap_null_cb, NULL, NULL }; Operation o = *op; + unsigned long opid = op->o_opid; + OpExtra oex; - assert( e != NULL ); Debug(LDAP_DEBUG_TRACE, "==> autogroup_add_member_values_to_group adding <%s> to <%s>\n", - e->e_name.bv_val, age->age_dn.bv_val, 0); - - attr = attrs_find( e->e_attrs, attrdesc ); - if (!attr) { - // Nothing to add - return LDAP_SUCCESS; - } + dn->bv_val, age->age_dn.bv_val, 0); modlist.sml_op = LDAP_MOD_ADD; modlist.sml_desc = age->age_def->agd_member_ad; @@ -184,18 +193,28 @@ autogroup_add_member_values_to_group( Operation *op, Entry *e, autogroup_entry_t modlist.sml_flags = SLAP_MOD_INTERNAL; modlist.sml_next = NULL; + o.o_opid = 0; o.o_tag = LDAP_REQ_MODIFY; o.o_callback = &cb; o.orm_modlist = &modlist; + o.o_dn = op->o_bd->be_rootdn; + o.o_ndn = op->o_bd->be_rootndn; o.o_req_dn = age->age_dn; o.o_req_ndn = age->age_ndn; o.o_permissive_modify = 1; + o.o_dont_replicate = 1; + o.orm_no_opattrs = 1; o.o_managedsait = SLAP_CONTROL_CRITICAL; o.o_relax = SLAP_CONTROL_CRITICAL; + oex.oe_key = (void *)&autogroup; + LDAP_SLIST_INSERT_HEAD( &o.o_extra, &oex, oe_next ); + o.o_bd->bd_info = (BackendInfo *)on->on_info; (void)op->o_bd->be_modify( &o, &sreply ); o.o_bd->bd_info = (BackendInfo *)on; + op->o_opid = opid; + LDAP_SLIST_REMOVE( &o.o_extra, &oex, OpExtra, oe_next ); return sreply.sr_err; } @@ -214,6 +233,8 @@ autogroup_delete_member_from_group( Operation *op, BerValue *dn, BerValue *ndn, BerValue *vals, *nvals; slap_callback cb = { NULL, slap_null_cb, NULL, NULL }; Operation o = *op; + unsigned long opid = op->o_opid; + OpExtra oex; if ( dn == NULL || ndn == NULL ) { Debug(LDAP_DEBUG_TRACE, "==> autogroup_delete_member_from_group removing all members from <%s>\n", @@ -245,21 +266,32 @@ autogroup_delete_member_from_group( Operation *op, BerValue *dn, BerValue *ndn, modlist->sml_flags = SLAP_MOD_INTERNAL; modlist->sml_next = NULL; + o.o_opid = 0; o.o_callback = &cb; o.o_tag = LDAP_REQ_MODIFY; o.orm_modlist = modlist; + o.o_dn = op->o_bd->be_rootdn; + o.o_ndn = op->o_bd->be_rootndn; o.o_req_dn = age->age_dn; o.o_req_ndn = age->age_ndn; o.o_relax = SLAP_CONTROL_CRITICAL; o.o_managedsait = SLAP_CONTROL_CRITICAL; o.o_permissive_modify = 1; + o.o_dont_replicate = 1; + o.orm_no_opattrs = 1; + + oex.oe_key = (void *)&autogroup; + LDAP_SLIST_INSERT_HEAD( &o.o_extra, &oex, oe_next ); o.o_bd->bd_info = (BackendInfo *)on->on_info; (void)op->o_bd->be_modify( &o, &sreply ); o.o_bd->bd_info = (BackendInfo *)on; + LDAP_SLIST_REMOVE( &o.o_extra, &oex, OpExtra, oe_next ); + slap_mods_free( modlist, 1 ); + op->o_opid = opid; return sreply.sr_err; } @@ -268,24 +300,18 @@ autogroup_delete_member_from_group( Operation *op, BerValue *dn, BerValue *ndn, ** age - the group from which the values will be deleted */ static int -autogroup_delete_member_values_from_group( Operation *op, Entry *e, autogroup_entry_t *age, AttributeDescription *attrdesc ) +autogroup_delete_member_values_from_group( Operation *op, struct berval *dn, autogroup_entry_t *age, Attribute *attr ) { slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; Modifications modlist; SlapReply sreply = {REP_RESULT}; - Attribute *attr; slap_callback cb = { NULL, slap_null_cb, NULL, NULL }; Operation o = *op; + unsigned long opid = op->o_opid; + OpExtra oex; - assert( e != NULL ); Debug(LDAP_DEBUG_TRACE, "==> autogroup_delete_member_values_from_group removing <%s> from <%s>\n", - e->e_name.bv_val, age->age_dn.bv_val, 0); - - attr = attrs_find( e->e_attrs, attrdesc ); - if (!attr) { - // Nothing to add - return LDAP_SUCCESS; - } + dn->bv_val, age->age_dn.bv_val, 0); modlist.sml_op = LDAP_MOD_DELETE; modlist.sml_desc = age->age_def->agd_member_ad; @@ -296,18 +322,29 @@ autogroup_delete_member_values_from_group( Operation *op, Entry *e, autogroup_en modlist.sml_flags = SLAP_MOD_INTERNAL; modlist.sml_next = NULL; + o.o_opid = 0; o.o_tag = LDAP_REQ_MODIFY; o.o_callback = &cb; o.orm_modlist = &modlist; + o.o_dn = op->o_bd->be_rootdn; + o.o_ndn = op->o_bd->be_rootndn; o.o_req_dn = age->age_dn; o.o_req_ndn = age->age_ndn; o.o_permissive_modify = 1; + o.o_dont_replicate = 1; + o.orm_no_opattrs = 1; o.o_managedsait = SLAP_CONTROL_CRITICAL; o.o_relax = SLAP_CONTROL_CRITICAL; + oex.oe_key = (void *)&autogroup; + LDAP_SLIST_INSERT_HEAD( &o.o_extra, &oex, oe_next ); + o.o_bd->bd_info = (BackendInfo *)on->on_info; (void)op->o_bd->be_modify( &o, &sreply ); o.o_bd->bd_info = (BackendInfo *)on; + op->o_opid = opid; + + LDAP_SLIST_REMOVE( &o.o_extra, &oex, OpExtra, oe_next ); return sreply.sr_err; } @@ -331,6 +368,7 @@ autogroup_member_search_cb( Operation *op, SlapReply *rs ) const char *text = NULL; char textbuf[1024]; struct berval *vals, *nvals; + struct berval lvals[ 2 ], lnvals[ 2 ]; int numvals; Debug(LDAP_DEBUG_TRACE, "==> autogroup_member_search_cb <%s>\n", @@ -347,7 +385,6 @@ autogroup_member_search_cb( Operation *op, SlapReply *rs ) return 0; } } else { - struct berval lvals[ 2 ], lnvals[ 2 ]; lvals[ 0 ] = rs->sr_entry->e_name; BER_BVZERO( &lvals[ 1 ] ); lnvals[ 0 ] = rs->sr_entry->e_nname; @@ -387,6 +424,7 @@ autogroup_member_search_modify_cb( Operation *op, SlapReply *rs ) autogroup_filter_t *agf = agg->agg_filter; Modifications *modlist; struct berval *vals, *nvals; + struct berval lvals[ 2 ], lnvals[ 2 ]; int numvals; Debug(LDAP_DEBUG_TRACE, "==> autogroup_member_search_modify_cb <%s>\n", @@ -403,7 +441,6 @@ autogroup_member_search_modify_cb( Operation *op, SlapReply *rs ) return 0; } } else { - struct berval lvals[ 2 ], lnvals[ 2 ]; lvals[ 0 ] = rs->sr_entry->e_name; BER_BVZERO( &lvals[ 1 ] ); lnvals[ 0 ] = rs->sr_entry->e_nname; @@ -460,6 +497,7 @@ autogroup_add_members_from_filter( Operation *op, Entry *e, autogroup_entry_t *a slap_callback cb = { 0 }; slap_callback null_cb = { NULL, slap_null_cb, NULL, NULL }; autogroup_ga_t agg; + OpExtra oex; Debug(LDAP_DEBUG_TRACE, "==> autogroup_add_members_from_filter <%s>\n", age->age_dn.bv_val, 0, 0); @@ -467,6 +505,8 @@ autogroup_add_members_from_filter( Operation *op, Entry *e, autogroup_entry_t *a o.ors_attrsonly = 0; o.o_tag = LDAP_REQ_SEARCH; + o.o_dn = op->o_bd->be_rootdn; + o.o_ndn = op->o_bd->be_rootndn; o.o_req_dn = agf->agf_dn; o.o_req_ndn = agf->agf_ndn; @@ -479,6 +519,7 @@ autogroup_add_members_from_filter( Operation *op, Entry *e, autogroup_entry_t *a o.ors_tlimit = SLAP_NO_LIMIT; o.ors_slimit = SLAP_NO_LIMIT; o.ors_attrs = agf->agf_anlist ? agf->agf_anlist : slap_anlist_no_attrs; + o.o_do_not_cache = 1; agg.agg_group = age; agg.agg_filter = agf; @@ -503,23 +544,36 @@ autogroup_add_members_from_filter( Operation *op, Entry *e, autogroup_entry_t *a o.o_bd->bd_info = (BackendInfo *)on; if ( modify == 1 && agg.agg_mod ) { + unsigned long opid = op->o_opid; + rs_reinit( &rs, REP_RESULT ); o = *op; + o.o_opid = 0; o.o_callback = &null_cb; o.o_tag = LDAP_REQ_MODIFY; o.orm_modlist = agg.agg_mod; + o.o_dn = op->o_bd->be_rootdn; + o.o_ndn = op->o_bd->be_rootndn; o.o_req_dn = age->age_dn; o.o_req_ndn = age->age_ndn; o.o_relax = SLAP_CONTROL_CRITICAL; o.o_managedsait = SLAP_CONTROL_NONCRITICAL; o.o_permissive_modify = 1; + o.o_dont_replicate = 1; + o.orm_no_opattrs = 1; + + oex.oe_key = (void *)&autogroup; + LDAP_SLIST_INSERT_HEAD( &o.o_extra, &oex, oe_next ); o.o_bd->bd_info = (BackendInfo *)on->on_info; (void)op->o_bd->be_modify( &o, &rs ); o.o_bd->bd_info = (BackendInfo *)on; + LDAP_SLIST_REMOVE( &o.o_extra, &oex, OpExtra, oe_next ); + slap_mods_free(agg.agg_mod, 1); + op->o_opid = opid; } return 0; @@ -620,7 +674,11 @@ autogroup_add_group( Operation *op, autogroup_info_t *agi, autogroup_def_t *agd, if ( lud->lud_filter != NULL ) { ber_str2bv( lud->lud_filter, 0, 1, &agf->agf_filterstr); agf->agf_filter = str2filter( lud->lud_filter ); - } + } else { + Debug( LDAP_DEBUG_TRACE, "autogroup_add_group: URL filter is missing <%s>\n", bv->bv_val,0,0); + /* FIXME: error? */ + goto cleanup; + } if ( lud->lud_attrs != NULL ) { int i; @@ -633,26 +691,33 @@ autogroup_add_group( Operation *op, autogroup_info_t *agi, autogroup_def_t *agd, Debug( LDAP_DEBUG_ANY, "autogroup_add_group: too many attributes specified in url <%s>\n", bv->bv_val, 0, 0); /* FIXME: error? */ + filter_free( agf->agf_filter ); + ch_free( agf->agf_filterstr.bv_val ); + ch_free( agf->agf_dn.bv_val ); + ch_free( agf->agf_ndn.bv_val ); ldap_free_urldesc( lud ); - ch_free( agf ); + ch_free( agf ); continue; } - + agf->agf_anlist = str2anlist( NULL, lud->lud_attrs[0], "," ); if ( agf->agf_anlist == NULL ) { Debug( LDAP_DEBUG_ANY, "autogroup_add_group: unable to find AttributeDescription \"%s\".\n", - lud->lud_attrs[0], 0, 0 ); + lud->lud_attrs[0], 0, 0 ); /* FIXME: error? */ + filter_free( agf->agf_filter ); + ch_free( agf->agf_filterstr.bv_val ); + ch_free( agf->agf_dn.bv_val ); + ch_free( agf->agf_ndn.bv_val ); ldap_free_urldesc( lud ); - ch_free( agf ); + ch_free( agf ); continue; } } agf->agf_next = NULL; - if( (*agep)->age_filter == NULL ) { (*agep)->age_filter = agf; } @@ -677,6 +742,8 @@ autogroup_add_group( Operation *op, autogroup_info_t *agi, autogroup_def_t *agd, cleanup:; + ch_free( agf->agf_ndn.bv_val ); + ch_free( agf->agf_dn.bv_val ); ldap_free_urldesc( lud ); ch_free( agf ); } @@ -709,6 +776,76 @@ autogroup_group_add_cb( Operation *op, SlapReply *rs ) return 0; } +typedef struct ag_addinfo { + slap_overinst *on; + Entry *e; + autogroup_def_t *agd; +} ag_addinfo; + +static int +autogroup_add_entry_cb( Operation *op, SlapReply *rs ) +{ + slap_callback *sc = op->o_callback; + ag_addinfo *aa = sc->sc_private; + slap_overinst *on = aa->on; + autogroup_info_t *agi = (autogroup_info_t *)on->on_bi.bi_private; + BackendInfo *bi = op->o_bd->bd_info; + + if ( rs->sr_err != LDAP_SUCCESS ) + goto done; + + op->o_bd->bd_info = (BackendInfo *)on; + ldap_pvt_thread_mutex_lock( &agi->agi_mutex ); + if ( aa->agd ) { + autogroup_add_group( op, agi, aa->agd, aa->e, NULL, 1 , 0); + } else { + autogroup_entry_t *age; + autogroup_filter_t *agf; + struct berval odn, ondn; + int rc; + + /* must use rootdn when calling test_filter */ + odn = op->o_dn; + ondn = op->o_ndn; + op->o_dn = op->o_bd->be_rootdn; + op->o_ndn = op->o_bd->be_rootndn; + + for ( age = agi->agi_entry; age ; age = age->age_next ) { + ldap_pvt_thread_mutex_lock( &age->age_mutex ); + + /* Check if any of the filters are the suffix to the entry DN. + If yes, we can test that filter against the entry. */ + + for ( agf = age->age_filter; agf ; agf = agf->agf_next ) { + if ( dnIsSuffix( &op->o_req_ndn, &agf->agf_ndn ) ) { + rc = test_filter( op, aa->e, agf->agf_filter ); + if ( rc == LDAP_COMPARE_TRUE ) { + if ( agf->agf_anlist ) { + Attribute *a = attr_find( aa->e->e_attrs, agf->agf_anlist[0].an_desc ); + if ( a ) + autogroup_add_member_values_to_group( op, &op->o_req_dn, age, a ); + } else { + autogroup_add_member_to_group( op, &aa->e->e_name, &aa->e->e_nname, age ); + } + break; + } + } + } + ldap_pvt_thread_mutex_unlock( &age->age_mutex ); + } + op->o_dn = odn; + op->o_ndn = ondn; + } + ldap_pvt_thread_mutex_unlock( &agi->agi_mutex ); + + op->o_bd->bd_info = bi; + +done: + op->o_callback = sc->sc_next; + op->o_tmpfree( sc, op->o_tmpmemctx ); + + return SLAP_CB_CONTINUE; +} /* ** When adding a group, we first strip any existing members, @@ -720,14 +857,20 @@ autogroup_add_entry( Operation *op, SlapReply *rs) slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; autogroup_info_t *agi = (autogroup_info_t *)on->on_bi.bi_private; autogroup_def_t *agd = agi->agi_def; - autogroup_entry_t *age; - autogroup_filter_t *agf; - int rc = 0; + slap_callback *sc = NULL; + ag_addinfo *aa = NULL; Debug( LDAP_DEBUG_TRACE, "==> autogroup_add_entry <%s>\n", op->ora_e->e_name.bv_val, 0, 0); - ldap_pvt_thread_mutex_lock( &agi->agi_mutex ); + sc = op->o_tmpcalloc( sizeof(slap_callback) + sizeof(ag_addinfo), 1, op->o_tmpmemctx ); + sc->sc_private = (sc+1); + sc->sc_response = autogroup_add_entry_cb; + aa = sc->sc_private; + aa->on = on; + aa->e = op->ora_e; + sc->sc_next = op->o_callback; + op->o_callback = sc; /* Check if it's a group. */ for ( ; agd ; agd = agd->agd_next ) { @@ -745,37 +888,12 @@ autogroup_add_entry( Operation *op, SlapReply *rs) /* We don't want any member attributes added by the user. */ modify_delete_values( op->ora_e, &mod, /* permissive */ 1, &text, textbuf, sizeof( textbuf ) ); - autogroup_add_group( op, agi, agd, op->ora_e, NULL, 1 , 0); - ldap_pvt_thread_mutex_unlock( &agi->agi_mutex ); - return SLAP_CB_CONTINUE; - } - } - - - for ( age = agi->agi_entry; age ; age = age->age_next ) { - ldap_pvt_thread_mutex_lock( &age->age_mutex ); - - /* Check if any of the filters are the suffix to the entry DN. - If yes, we can test that filter against the entry. */ + aa->agd = agd; - for ( agf = age->age_filter; agf ; agf = agf->agf_next ) { - if ( dnIsSuffix( &op->o_req_ndn, &agf->agf_ndn ) ) { - rc = test_filter( op, op->ora_e, agf->agf_filter ); - if ( rc == LDAP_COMPARE_TRUE ) { - if ( agf->agf_anlist ) { - autogroup_add_member_values_to_group( op, op->ora_e, age, agf->agf_anlist[0].an_desc ); - } else { - autogroup_add_member_to_group( op, &op->ora_e->e_name, &op->ora_e->e_nname, age ); - } - break; - } - } + break; } - ldap_pvt_thread_mutex_unlock( &age->age_mutex ); } - ldap_pvt_thread_mutex_unlock( &agi->agi_mutex ); - return SLAP_CB_CONTINUE; } @@ -846,6 +964,13 @@ autogroup_delete_entry( Operation *op, SlapReply *rs) autogroup_filter_t *agf; Entry *e; int matched_group = 0, rc = 0; + struct berval odn, ondn; + OpExtra *oex; + + LDAP_SLIST_FOREACH( oex, &op->o_extra, oe_next ) { + if ( oex->oe_key == (void *)&autogroup ) + return SLAP_CB_CONTINUE; + } Debug( LDAP_DEBUG_TRACE, "==> autogroup_delete_entry <%s>\n", op->o_req_dn.bv_val, 0, 0); @@ -889,6 +1014,11 @@ autogroup_delete_entry( Operation *op, SlapReply *rs) /* Check if the entry matches any of the groups. If yes, we can delete the entry from that group. */ + odn = op->o_dn; + ondn = op->o_ndn; + op->o_dn = op->o_bd->be_rootdn; + op->o_ndn = op->o_bd->be_rootndn; + for ( age = agi->agi_entry ; age ; age = age->age_next ) { ldap_pvt_thread_mutex_lock( &age->age_mutex ); @@ -912,6 +1042,8 @@ autogroup_delete_entry( Operation *op, SlapReply *rs) } ldap_pvt_thread_mutex_unlock( &age->age_mutex ); } + op->o_dn = odn; + op->o_ndn = ondn; overlay_entry_release_ov( op, e, 0, on ); ldap_pvt_thread_mutex_unlock( &agi->agi_mutex ); @@ -929,12 +1061,18 @@ autogroup_response( Operation *op, SlapReply *rs ) autogroup_filter_t *agf; BerValue new_dn, new_ndn, pdn; Entry *e, *group; - Attribute *a, *ea; + Attribute *a, *ea, *attrs; int is_olddn, is_newdn, is_value_refresh, dn_equal; + OpExtra *oex; + + LDAP_SLIST_FOREACH( oex, &op->o_extra, oe_next ) { + if ( oex->oe_key == (void *)&autogroup ) + break; + } /* Handle all cases where a refresh of the group is needed */ if ( op->o_tag == LDAP_REQ_DELETE || op->o_tag == LDAP_REQ_MODIFY ) { - if ( rs->sr_type == REP_RESULT && rs->sr_err == LDAP_SUCCESS && !get_manageDSAit( op ) ) { + if ( rs->sr_type == REP_RESULT && rs->sr_err == LDAP_SUCCESS && !oex ) { ldap_pvt_thread_mutex_lock( &agi->agi_mutex ); @@ -957,7 +1095,7 @@ autogroup_response( Operation *op, SlapReply *rs ) ldap_pvt_thread_mutex_unlock( &agi->agi_mutex ); } } else if ( op->o_tag == LDAP_REQ_MODRDN ) { - if ( rs->sr_type == REP_RESULT && rs->sr_err == LDAP_SUCCESS && !get_manageDSAit( op )) { + if ( rs->sr_type == REP_RESULT && rs->sr_err == LDAP_SUCCESS && !oex ) { Debug( LDAP_DEBUG_TRACE, "==> autogroup_response MODRDN from <%s>\n", op->o_req_dn.bv_val, 0, 0); @@ -1038,16 +1176,17 @@ autogroup_response( Operation *op, SlapReply *rs ) and add it's DN to the group. If 1 is true, and 2 is false, we delete the entry's DN from the group. */ + attrs = attrs_dup( e->e_attrs ); + overlay_entry_release_ov( op, e, 0, on ); for ( age = agi->agi_entry ; age ; age = age->age_next ) { is_olddn = 0; is_newdn = 0; is_value_refresh = 0; - ldap_pvt_thread_mutex_lock( &age->age_mutex ); if ( age->age_filter && age->age_filter->agf_anlist ) { - ea = attrs_find( e->e_attrs, age->age_filter->agf_anlist[0].an_desc ); + ea = attrs_find( attrs, age->age_filter->agf_anlist[0].an_desc ); } else { ea = NULL; @@ -1067,7 +1206,7 @@ autogroup_response( Operation *op, SlapReply *rs ) op->o_tmpfree( new_dn.bv_val, op->o_tmpmemctx ); op->o_tmpfree( new_ndn.bv_val, op->o_tmpmemctx ); - overlay_entry_release_ov( op, e, 0, on ); + attrs_free( attrs ); ldap_pvt_thread_mutex_unlock( &age->age_mutex ); ldap_pvt_thread_mutex_unlock( &agi->agi_mutex ); return SLAP_CB_CONTINUE; @@ -1113,20 +1252,32 @@ autogroup_response( Operation *op, SlapReply *rs ) } if ( is_olddn == 1 && is_newdn == 0 ) { if ( ea ) - autogroup_delete_member_values_from_group( op, e, age, age->age_filter->agf_anlist[0].an_desc ); + autogroup_delete_member_values_from_group( op, &new_dn, age, ea ); else autogroup_delete_member_from_group( op, &op->o_req_dn, &op->o_req_ndn, age ); } else if ( is_olddn == 0 && is_newdn == 1 ) { + Entry etmp; + struct berval odn, ondn; + etmp.e_name = op->o_req_dn; + etmp.e_nname = op->o_req_ndn; + etmp.e_attrs = attrs; + odn = op->o_dn; + ondn = op->o_ndn; + op->o_dn = op->o_bd->be_rootdn; + op->o_ndn = op->o_bd->be_rootndn; + for ( agf = age->age_filter; agf; agf = agf->agf_next ) { - if ( test_filter( op, e, agf->agf_filter ) == LDAP_COMPARE_TRUE ) { - if ( ea ) - autogroup_add_member_values_to_group( op, e, age, age->age_filter->agf_anlist[0].an_desc ); - else + if ( test_filter( op, &etmp, agf->agf_filter ) == LDAP_COMPARE_TRUE ) { + if ( ea ) { + autogroup_add_member_values_to_group( op, &new_dn, age, ea ); + } else autogroup_add_member_to_group( op, &new_dn, &new_ndn, age ); break; } } + op->o_dn = odn; + op->o_ndn = ondn; } else if ( is_olddn == 1 && is_newdn == 1 && dn_equal != 0 ) { if ( ea ) { @@ -1149,14 +1300,16 @@ autogroup_response( Operation *op, SlapReply *rs ) op->o_tmpfree( new_dn.bv_val, op->o_tmpmemctx ); op->o_tmpfree( new_ndn.bv_val, op->o_tmpmemctx ); - overlay_entry_release_ov( op, e, 0, on ); + attrs_free( attrs ); ldap_pvt_thread_mutex_unlock( &agi->agi_mutex ); } } if ( op->o_tag == LDAP_REQ_MODIFY ) { - if ( rs->sr_type == REP_RESULT && rs->sr_err == LDAP_SUCCESS && !get_manageDSAit( op ) ) { + if ( rs->sr_type == REP_RESULT && rs->sr_err == LDAP_SUCCESS && !oex ) { + Entry etmp; + struct berval odn, ondn; Debug( LDAP_DEBUG_TRACE, "==> autogroup_response MODIFY <%s>\n", op->o_req_dn.bv_val, 0, 0); ldap_pvt_thread_mutex_lock( &agi->agi_mutex ); @@ -1212,7 +1365,6 @@ autogroup_response( Operation *op, SlapReply *rs ) autogroup_add_group( op, agi, group_agd, NULL, &op->o_req_ndn, 1, 1); - overlay_entry_release_ov( op, e, 0, on ); ldap_pvt_thread_mutex_unlock( &agi->agi_mutex ); return SLAP_CB_CONTINUE; } @@ -1231,7 +1383,7 @@ autogroup_response( Operation *op, SlapReply *rs ) } } - /* When modifing any of the attributes of an entry, we must + /* When modifying any of the attributes of an entry, we must check if the entry is in any of our groups, and if the modified entry maches any of the filters of that group. @@ -1240,15 +1392,24 @@ autogroup_response( Operation *op, SlapReply *rs ) If the entry doesn't exist in a group, but matches a filter, we add it to that group. */ + attrs = attrs_dup( e->e_attrs ); + overlay_entry_release_ov( op, e, 0, on ); + etmp.e_name = op->o_req_dn; + etmp.e_nname = op->o_req_ndn; + etmp.e_attrs = attrs; + odn = op->o_dn; + ondn = op->o_ndn; + op->o_dn = op->o_bd->be_rootdn; + op->o_ndn = op->o_bd->be_rootndn; + for ( age = agi->agi_entry ; age ; age = age->age_next ) { is_olddn = 0; is_newdn = 0; - ldap_pvt_thread_mutex_lock( &age->age_mutex ); if ( age->age_filter && age->age_filter->agf_anlist ) { - ea = attrs_find( e->e_attrs, age->age_filter->agf_anlist[0].an_desc ); + ea = attrs_find( attrs, age->age_filter->agf_anlist[0].an_desc ); } else { ea = NULL; @@ -1259,9 +1420,11 @@ autogroup_response( Operation *op, SlapReply *rs ) Debug( LDAP_DEBUG_TRACE, "autogroup_response MODIFY cannot get entry for <%s>\n", age->age_dn.bv_val, 0, 0); - overlay_entry_release_ov( op, e, 0, on ); + attrs_free( attrs ); ldap_pvt_thread_mutex_unlock( &age->age_mutex ); ldap_pvt_thread_mutex_unlock( &agi->agi_mutex ); + op->o_dn = odn; + op->o_ndn = ondn; return SLAP_CB_CONTINUE; } @@ -1282,7 +1445,7 @@ autogroup_response( Operation *op, SlapReply *rs ) for ( agf = age->age_filter ; agf ; agf = agf->agf_next ) { if ( dnIsSuffix( &op->o_req_ndn, &agf->agf_ndn ) ) { - if ( test_filter( op, e, agf->agf_filter ) == LDAP_COMPARE_TRUE ) { + if ( test_filter( op, &etmp, agf->agf_filter ) == LDAP_COMPARE_TRUE ) { is_newdn = 1; break; } @@ -1291,13 +1454,13 @@ autogroup_response( Operation *op, SlapReply *rs ) if ( is_olddn == 1 && is_newdn == 0 ) { if(ea) - autogroup_delete_member_values_from_group( op, e, age, age->age_filter->agf_anlist[0].an_desc ); + autogroup_delete_member_values_from_group( op, &op->o_req_dn, age, ea ); else autogroup_delete_member_from_group( op, &op->o_req_dn, &op->o_req_ndn, age ); } else if ( is_olddn == 0 && is_newdn == 1 ) { if(ea) - autogroup_add_member_values_to_group( op, e, age, age->age_filter->agf_anlist[0].an_desc ); + autogroup_add_member_values_to_group( op, &op->o_req_dn, age, ea ); else autogroup_add_member_to_group( op, &op->o_req_dn, &op->o_req_ndn, age ); } @@ -1305,7 +1468,9 @@ autogroup_response( Operation *op, SlapReply *rs ) ldap_pvt_thread_mutex_unlock( &age->age_mutex ); } - overlay_entry_release_ov( op, e, 0, on ); + op->o_dn = odn; + op->o_ndn = ondn; + attrs_free( attrs ); ldap_pvt_thread_mutex_unlock( &agi->agi_mutex ); } @@ -1355,9 +1520,12 @@ autogroup_modify_entry( Operation *op, SlapReply *rs) autogroup_entry_t *age; Entry *e; Attribute *a; + struct berval odn, ondn; + OpExtra *oex; - if ( get_manageDSAit( op ) ) { - return SLAP_CB_CONTINUE; + LDAP_SLIST_FOREACH( oex, &op->o_extra, oe_next ) { + if ( oex->oe_key == (void *)&autogroup ) + return SLAP_CB_CONTINUE; } Debug( LDAP_DEBUG_TRACE, "==> autogroup_modify_entry <%s>\n", op->o_req_dn.bv_val, 0, 0); @@ -1370,6 +1538,11 @@ autogroup_modify_entry( Operation *op, SlapReply *rs) return SLAP_CB_CONTINUE; } + odn = op->o_dn; + ondn = op->o_ndn; + op->o_dn = op->o_bd->be_rootdn; + op->o_ndn = op->o_bd->be_rootndn; + /* Must refresh groups if a matching member value is modified OR filter contains memberOf=DN */ for ( age = agi->agi_entry; age ; age = age->age_next ) { autogroup_filter_t *agf; @@ -1393,6 +1566,8 @@ autogroup_modify_entry( Operation *op, SlapReply *rs) } } } + op->o_dn = odn; + op->o_ndn = ondn; a = attrs_find( e->e_attrs, slap_schema.si_ad_objectClass ); @@ -1433,9 +1608,8 @@ autogroup_modify_entry( Operation *op, SlapReply *rs) } } - overlay_entry_release_ov( op, e, 0, on ); - ldap_pvt_thread_mutex_unlock( &agi->agi_mutex ); - return SLAP_CB_CONTINUE; + /* an entry may only have one dynamic group class */ + break; } } @@ -1454,9 +1628,12 @@ autogroup_modrdn_entry( Operation *op, SlapReply *rs) autogroup_info_t *agi = (autogroup_info_t *)on->on_bi.bi_private; autogroup_entry_t *age; Entry *e; + struct berval odn, ondn; + OpExtra *oex; - if ( get_manageDSAit( op ) ) { - return SLAP_CB_CONTINUE; + LDAP_SLIST_FOREACH( oex, &op->o_extra, oe_next ) { + if ( oex->oe_key == (void *)&autogroup ) + return SLAP_CB_CONTINUE; } Debug( LDAP_DEBUG_TRACE, "==> autogroup_modrdn_entry <%s>\n", op->o_req_dn.bv_val, 0, 0); @@ -1469,6 +1646,11 @@ autogroup_modrdn_entry( Operation *op, SlapReply *rs) return SLAP_CB_CONTINUE; } + odn = op->o_dn; + ondn = op->o_ndn; + op->o_dn = op->o_bd->be_rootdn; + op->o_ndn = op->o_bd->be_rootndn; + /* Must check if a dn is modified */ for ( age = agi->agi_entry; age ; age = age->age_next ) { autogroup_filter_t *agf; @@ -1483,6 +1665,8 @@ autogroup_modrdn_entry( Operation *op, SlapReply *rs) } } } + op->o_dn = odn; + op->o_ndn = ondn; overlay_entry_release_ov( op, e, 0, on ); ldap_pvt_thread_mutex_unlock( &agi->agi_mutex ); @@ -1528,7 +1712,7 @@ static ConfigDriver ag_cfgen; static ConfigTable agcfg[] = { { "autogroup-attrset", "group-oc> , , ' " "EQUALITY caseIgnoreMatch " @@ -1904,6 +2088,7 @@ autogroup_db_open( op->ors_tlimit = SLAP_NO_LIMIT; op->ors_slimit = SLAP_NO_LIMIT; op->ors_attrs = slap_anlist_no_attrs; + op->o_do_not_cache = 1; op->o_bd = be; op->o_bd->bd_info = (BackendInfo *)on->on_info; @@ -2014,8 +2199,6 @@ autogroup_db_destroy( return 0; } -static slap_overinst autogroup = { { NULL } }; - static int autogroup_initialize(void)