struct berval agf_filterstr;
Filter *agf_filter;
int agf_scope;
+ AttributeName *agf_anlist;
struct autogroup_filter_t *agf_next;
} autogroup_filter_t;
autogroup_filter_t *age_filter; /* List of filters made from memberURLs */
autogroup_def_t *age_def; /* Attribute definition */
ldap_pvt_thread_mutex_t age_mutex;
+ int age_mustrefresh; /* Defined in request to refresh in response */
+ int age_modrdn_olddnmodified; /* Defined in request to refresh in response */
struct autogroup_entry_t *age_next;
} autogroup_entry_t;
/* Used for adding members, found when searching, to a group. */
typedef struct autogroup_ga_t {
autogroup_entry_t *agg_group; /* The group to which the members will be added. */
+ autogroup_filter_t *agg_filter; /* Current filter */
Entry *agg_entry; /* Used in autogroup_member_search_cb to modify
this entry with the search results. */
autogroup_add_member_to_group( Operation *op, BerValue *dn, BerValue *ndn, autogroup_entry_t *age )
{
slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
- Modifications modlist;
+ Modifications *modlist = (Modifications *)ch_calloc( 1, sizeof( Modifications ) );
SlapReply sreply = {REP_RESULT};
- BerValue vals[ 2 ], nvals[ 2 ];
+ BerValue *vals, *nvals;
slap_callback cb = { NULL, slap_null_cb, NULL, NULL };
Operation o = *op;
assert( dn != NULL );
assert( ndn != NULL );
- vals[ 0 ] = *dn;
+ vals = (BerValue *)ch_calloc( 2, sizeof( BerValue ) );
+ nvals = (BerValue *)ch_calloc( 2, sizeof( BerValue ) );
+ ber_dupbv( vals, dn );
BER_BVZERO( &vals[ 1 ] );
- nvals[ 0 ] = *ndn;
+ ber_dupbv( nvals, ndn );
BER_BVZERO( &nvals[ 1 ] );
+ modlist->sml_op = LDAP_MOD_ADD;
+ modlist->sml_desc = age->age_def->agd_member_ad;
+ modlist->sml_type = age->age_def->agd_member_ad->ad_cname;
+ modlist->sml_values = vals;
+ modlist->sml_nvalues = nvals;
+ modlist->sml_numvals = 1;
+ modlist->sml_flags = SLAP_MOD_INTERNAL;
+ modlist->sml_next = NULL;
+
+ o.o_tag = LDAP_REQ_MODIFY;
+ o.o_callback = &cb;
+ o.orm_modlist = modlist;
+ o.o_req_dn = age->age_dn;
+ o.o_req_ndn = age->age_ndn;
+ o.o_permissive_modify = 1;
+ o.o_managedsait = SLAP_CONTROL_CRITICAL;
+ o.o_relax = SLAP_CONTROL_CRITICAL;
+
+ o.o_bd->bd_info = (BackendInfo *)on->on_info;
+ (void)op->o_bd->be_modify( &o, &sreply );
+ o.o_bd->bd_info = (BackendInfo *)on;
+
+ slap_mods_free( modlist, 1 );
+
+ return sreply.sr_err;
+}
+
+/*
+** e - the entry where to get the attribute values
+** 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 )
+{
+ 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;
+
+ 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);
+
+ assert( e != NULL );
+
+ attr = attrs_find( e->e_attrs, attrdesc );
+ if (!attr) {
+ // Nothing to add
+ return LDAP_SUCCESS;
+ }
+
modlist.sml_op = LDAP_MOD_ADD;
modlist.sml_desc = age->age_def->agd_member_ad;
modlist.sml_type = age->age_def->agd_member_ad->ad_cname;
- modlist.sml_values = vals;
- modlist.sml_nvalues = nvals;
- modlist.sml_numvals = 1;
+ modlist.sml_values = attr->a_vals;
+ modlist.sml_nvalues = attr->a_nvals;
+ modlist.sml_numvals = attr->a_numvals;
modlist.sml_flags = SLAP_MOD_INTERNAL;
modlist.sml_next = NULL;
autogroup_delete_member_from_group( Operation *op, BerValue *dn, BerValue *ndn, autogroup_entry_t *age )
{
slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
- Modifications modlist;
+ Modifications *modlist = (Modifications *)ch_calloc( 1, sizeof( Modifications ) );
SlapReply sreply = {REP_RESULT};
- BerValue vals[ 2 ], nvals[ 2 ];
+ BerValue *vals, *nvals;
slap_callback cb = { NULL, slap_null_cb, NULL, NULL };
Operation o = *op;
Debug(LDAP_DEBUG_TRACE, "==> autogroup_delete_member_from_group removing all members from <%s>\n",
age->age_dn.bv_val, 0 ,0);
- modlist.sml_values = NULL;
- modlist.sml_nvalues = NULL;
- modlist.sml_numvals = 0;
+ modlist->sml_values = NULL;
+ modlist->sml_nvalues = NULL;
+ modlist->sml_numvals = 0;
} else {
Debug(LDAP_DEBUG_TRACE, "==> autogroup_delete_member_from_group removing <%s> from <%s>\n",
dn->bv_val, age->age_dn.bv_val, 0);
- vals[ 0 ] = *dn;
+ vals = (BerValue *)ch_calloc( 2, sizeof( BerValue ) );
+ nvals = (BerValue *)ch_calloc( 2, sizeof( BerValue ) );
+ ber_dupbv( vals, dn );
BER_BVZERO( &vals[ 1 ] );
- nvals[ 0 ] = *ndn;
+ ber_dupbv( nvals, ndn );
BER_BVZERO( &nvals[ 1 ] );
- modlist.sml_values = vals;
- modlist.sml_nvalues = nvals;
- modlist.sml_numvals = 1;
+ modlist->sml_values = vals;
+ modlist->sml_nvalues = nvals;
+ modlist->sml_numvals = 1;
}
- modlist.sml_op = LDAP_MOD_DELETE;
- modlist.sml_desc = age->age_def->agd_member_ad;
- modlist.sml_type = age->age_def->agd_member_ad->ad_cname;
- modlist.sml_flags = SLAP_MOD_INTERNAL;
- modlist.sml_next = NULL;
+ modlist->sml_op = LDAP_MOD_DELETE;
+ modlist->sml_desc = age->age_def->agd_member_ad;
+ modlist->sml_type = age->age_def->agd_member_ad->ad_cname;
+ modlist->sml_flags = SLAP_MOD_INTERNAL;
+ modlist->sml_next = NULL;
o.o_callback = &cb;
o.o_tag = LDAP_REQ_MODIFY;
- o.orm_modlist = &modlist;
+ o.orm_modlist = modlist;
o.o_req_dn = age->age_dn;
o.o_req_ndn = age->age_ndn;
o.o_relax = SLAP_CONTROL_CRITICAL;
(void)op->o_bd->be_modify( &o, &sreply );
o.o_bd->bd_info = (BackendInfo *)on;
+ slap_mods_free( modlist, 1 );
+
return sreply.sr_err;
}
if ( rs->sr_type == REP_SEARCH ) {
autogroup_ga_t *agg = (autogroup_ga_t *)op->o_callback->sc_private;
autogroup_entry_t *age = agg->agg_group;
+ autogroup_filter_t *agf = agg->agg_filter;
Modification mod;
const char *text = NULL;
char textbuf[1024];
- struct berval vals[ 2 ], nvals[ 2 ];
+ struct berval *vals, *nvals;
+ int numvals;
Debug(LDAP_DEBUG_TRACE, "==> autogroup_member_search_cb <%s>\n",
rs->sr_entry ? rs->sr_entry->e_name.bv_val : "UNKNOWN_DN", 0, 0);
- vals[ 0 ] = rs->sr_entry->e_name;
- BER_BVZERO( &vals[ 1 ] );
- nvals[ 0 ] = rs->sr_entry->e_nname;
- BER_BVZERO( &nvals[ 1 ] );
+ if ( agf->agf_anlist ) {
+ Attribute *attr = attrs_find( rs->sr_entry->e_attrs, agf->agf_anlist[0].an_desc );
+ if (attr) {
+ vals = attr->a_vals;
+ nvals = attr->a_nvals;
+ numvals = attr->a_numvals;
+ } else {
+ // Nothing to add
+ 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;
+ BER_BVZERO( &lnvals[ 1 ] );
+ vals = lvals;
+ nvals = lnvals;
+ numvals = 1;
+ }
mod.sm_op = LDAP_MOD_ADD;
mod.sm_desc = age->age_def->agd_member_ad;
mod.sm_type = age->age_def->agd_member_ad->ad_cname;
mod.sm_values = vals;
mod.sm_nvalues = nvals;
- mod.sm_numvals = 1;
+ mod.sm_numvals = numvals;
modify_add_values( agg->agg_entry, &mod, /* permissive */ 1, &text, textbuf, sizeof( textbuf ) );
}
if ( rs->sr_type == REP_SEARCH ) {
autogroup_ga_t *agg = (autogroup_ga_t *)op->o_callback->sc_private;
autogroup_entry_t *age = agg->agg_group;
+ autogroup_filter_t *agf = agg->agg_filter;
Modifications *modlist;
- struct berval vals[ 2 ], nvals[ 2 ];
+ struct berval *vals, *nvals;
+ int numvals;
Debug(LDAP_DEBUG_TRACE, "==> autogroup_member_search_modify_cb <%s>\n",
rs->sr_entry ? rs->sr_entry->e_name.bv_val : "UNKNOWN_DN", 0, 0);
- vals[ 0 ] = rs->sr_entry->e_name;
- BER_BVZERO( &vals[ 1 ] );
- nvals[ 0 ] = rs->sr_entry->e_nname;
- BER_BVZERO( &nvals[ 1 ] );
+ if ( agf->agf_anlist ) {
+ Attribute *attr = attrs_find( rs->sr_entry->e_attrs, agf->agf_anlist[0].an_desc );
+ if (attr) {
+ vals = attr->a_vals;
+ nvals = attr->a_nvals;
+ numvals = attr->a_numvals;
+ } else {
+ // Nothing to add
+ 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;
+ BER_BVZERO( &lnvals[ 1 ] );
+ vals = lvals;
+ nvals = lnvals;
+ numvals = 1;
+ }
- modlist = (Modifications *)ch_calloc( 1, sizeof( Modifications ) );
+ if ( numvals ) {
+ modlist = (Modifications *)ch_calloc( 1, sizeof( Modifications ) );
- modlist->sml_op = LDAP_MOD_ADD;
- modlist->sml_desc = age->age_def->agd_member_ad;
- modlist->sml_type = age->age_def->agd_member_ad->ad_cname;
+ modlist->sml_op = LDAP_MOD_ADD;
+ modlist->sml_desc = age->age_def->agd_member_ad;
+ modlist->sml_type = age->age_def->agd_member_ad->ad_cname;
- ber_bvarray_dup_x( &modlist->sml_values, vals, NULL );
- ber_bvarray_dup_x( &modlist->sml_nvalues, nvals, NULL );
- modlist->sml_numvals = 1;
+ ber_bvarray_dup_x( &modlist->sml_values, vals, NULL );
+ ber_bvarray_dup_x( &modlist->sml_nvalues, nvals, NULL );
+ modlist->sml_numvals = numvals;
- modlist->sml_flags = SLAP_MOD_INTERNAL;
- modlist->sml_next = NULL;
+ modlist->sml_flags = SLAP_MOD_INTERNAL;
+ modlist->sml_next = NULL;
- if ( agg->agg_mod == NULL ) {
- agg->agg_mod = modlist;
- agg->agg_mod_last = modlist;
- } else {
- agg->agg_mod_last->sml_next = modlist;
- agg->agg_mod_last = modlist;
+ if ( agg->agg_mod == NULL ) {
+ agg->agg_mod = modlist;
+ agg->agg_mod_last = modlist;
+ } else {
+ agg->agg_mod_last->sml_next = modlist;
+ agg->agg_mod_last = modlist;
+ }
}
}
o.ors_limit = NULL;
o.ors_tlimit = SLAP_NO_LIMIT;
o.ors_slimit = SLAP_NO_LIMIT;
- o.ors_attrs = slap_anlist_no_attrs;
+ o.ors_attrs = agf->agf_anlist ? agf->agf_anlist : slap_anlist_no_attrs;
agg.agg_group = age;
+ agg.agg_filter = agf;
agg.agg_mod = NULL;
agg.agg_mod_last = NULL;
agg.agg_entry = e;
op->o_bd->be_search( &o, &rs );
o.o_bd->bd_info = (BackendInfo *)on;
- if ( modify == 1 ) {
+ if ( modify == 1 && agg.agg_mod ) {
o = *op;
o.o_callback = &null_cb;
o.o_tag = LDAP_REQ_MODIFY;
ldap_pvt_thread_mutex_init( &(*agep)->age_mutex );
(*agep)->age_def = agd;
(*agep)->age_filter = NULL;
+ (*agep)->age_mustrefresh = 0;
+ (*agep)->age_modrdn_olddnmodified = 0;
ber_dupbv( &(*agep)->age_dn, &e->e_name );
ber_dupbv( &(*agep)->age_ndn, &e->e_nname );
agf->agf_filter = str2filter( lud->lud_filter );
}
+ if ( lud->lud_attrs != NULL ) {
+ int i;
+
+ for ( i=0 ; lud->lud_attrs[i]!=NULL ; i++) {
+ /* Just counting */;
+ }
+
+ if ( i > 1 ) {
+ Debug( LDAP_DEBUG_ANY, "autogroup_add_group: to much attributes specified in url <%s>\n",
+ bv->bv_val, 0, 0);
+ /* FIXME: error? */
+ ldap_free_urldesc( lud );
+ ch_free( agf );
+ }
+
+ 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 );
+ /* FIXME: error? */
+ ldap_free_urldesc( lud );
+ ch_free( agf );
+ continue;
+ }
+ }
+
agf->agf_next = NULL;
if ( dnIsSuffix( &op->o_req_ndn, &agf->agf_ndn ) ) {
rc = test_filter( op, op->ora_e, agf->agf_filter );
if ( rc == LDAP_COMPARE_TRUE ) {
- autogroup_add_member_to_group( op, &op->ora_e->e_name, &op->ora_e->e_nname, age );
+ 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;
}
}
ch_free( agf->agf_filterstr.bv_val );
ch_free( agf->agf_dn.bv_val );
ch_free( agf->agf_ndn.bv_val );
+ anlist_free( agf->agf_anlist, 1, NULL );
+ ch_free( agf );
}
ldap_pvt_thread_mutex_unlock( &age->age_mutex );
if ( dnIsSuffix( &op->o_req_ndn, &agf->agf_ndn ) ) {
rc = test_filter( op, e, agf->agf_filter );
if ( rc == LDAP_COMPARE_TRUE ) {
- autogroup_delete_member_from_group( op, &e->e_name, &e->e_nname, age );
+ /* If the attribute is retrieved from the entry, we don't know what to delete
+ ** So the group must be entirely refreshed
+ ** But the refresh can't be done now because the entry is not deleted
+ ** So the group is marked as mustrefresh
+ */
+ if ( agf->agf_anlist ) {
+ age->age_mustrefresh = 1;
+ } else {
+ autogroup_delete_member_from_group( op, &e->e_name, &e->e_nname, age );
+ }
break;
}
}
BerValue new_dn, new_ndn, pdn;
Entry *e, *group;
Attribute *a;
- int is_olddn, is_newdn, dn_equal;
+ int is_olddn, is_newdn, is_value_refresh, dn_equal;
+
+ /* 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 ) ) {
+
+ ldap_pvt_thread_mutex_lock( &agi->agi_mutex );
+
+ for ( age = agi->agi_entry ; age ; age = age->age_next ) {
+ /* Request detected that the group must be refreshed */
+
+ ldap_pvt_thread_mutex_lock( &age->age_mutex );
+
+ if ( age->age_mustrefresh ) {
+ autogroup_delete_member_from_group( op, NULL, NULL, age) ;
+
+ for ( agf = age->age_filter ; agf ; agf = agf->agf_next ) {
+ autogroup_add_members_from_filter( op, NULL, age, agf, 1 );
+ }
+ }
+ ldap_pvt_thread_mutex_unlock( &age->age_mutex );
+ }
+
+ ldap_pvt_thread_mutex_unlock( &agi->agi_mutex );
+ }
+ }
if ( op->o_tag == LDAP_REQ_MODRDN ) {
if ( rs->sr_type == REP_RESULT && rs->sr_err == LDAP_SUCCESS && !get_manageDSAit( op )) {
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 ( overlay_entry_get_ov( op, &age->age_ndn, NULL, NULL, 0, &group, on ) !=
- LDAP_SUCCESS || group == NULL ) {
- Debug( LDAP_DEBUG_TRACE, "autogroup_response MODRDN cannot get group entry <%s>\n", age->age_dn.bv_val, 0, 0);
+ if ( age->age_modrdn_olddnmodified ) {
+ /* Resquest already marked this group to be updated */
+ is_olddn = 1;
+ is_value_refresh = 1;
+ age->age_modrdn_olddnmodified = 0;
+ } else {
- op->o_tmpfree( new_dn.bv_val, op->o_tmpmemctx );
- op->o_tmpfree( new_ndn.bv_val, op->o_tmpmemctx );
+ if ( overlay_entry_get_ov( op, &age->age_ndn, NULL, NULL, 0, &group, on ) !=
+ LDAP_SUCCESS || group == NULL ) {
+ Debug( LDAP_DEBUG_TRACE, "autogroup_response MODRDN cannot get group entry <%s>\n", age->age_dn.bv_val, 0, 0);
- ldap_pvt_thread_mutex_unlock( &age->age_mutex );
- ldap_pvt_thread_mutex_unlock( &agi->agi_mutex );
- return SLAP_CB_CONTINUE;
- }
+ op->o_tmpfree( new_dn.bv_val, op->o_tmpmemctx );
+ op->o_tmpfree( new_ndn.bv_val, op->o_tmpmemctx );
- a = attrs_find( group->e_attrs, age->age_def->agd_member_ad );
+ ldap_pvt_thread_mutex_unlock( &age->age_mutex );
+ ldap_pvt_thread_mutex_unlock( &agi->agi_mutex );
+ return SLAP_CB_CONTINUE;
+ }
+
+ a = attrs_find( group->e_attrs, age->age_def->agd_member_ad );
+
+ if ( a != NULL ) {
+ if ( value_find_ex( age->age_def->agd_member_ad,
+ SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH |
+ SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH,
+ a->a_nvals, &op->o_req_ndn, op->o_tmpmemctx ) == 0 )
+ {
+ is_olddn = 1;
+ }
- if ( a != NULL ) {
- if ( value_find_ex( age->age_def->agd_member_ad,
- SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH |
- SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH,
- a->a_nvals, &op->o_req_ndn, op->o_tmpmemctx ) == 0 )
- {
- is_olddn = 1;
}
- }
+ overlay_entry_release_ov( op, group, 0, on );
- overlay_entry_release_ov( op, group, 0, on );
+ }
for ( agf = age->age_filter ; agf ; agf = agf->agf_next ) {
if ( dnIsSuffix( &new_ndn, &agf->agf_ndn ) ) {
+ /* TODO: should retest filter as it could imply conditions on the dn */
is_newdn = 1;
break;
}
}
+ if ( is_value_refresh ) {
+ if ( is_olddn != is_newdn ) {
+ /* group refresh */
+ autogroup_delete_member_from_group( op, NULL, NULL, age) ;
+
+ for ( agf = age->age_filter ; agf ; agf = agf->agf_next ) {
+ autogroup_add_members_from_filter( op, NULL, age, agf, 1 );
+ }
+ }
+ ldap_pvt_thread_mutex_unlock( &age->age_mutex );
+ continue;
+ }
if ( is_olddn == 1 && is_newdn == 0 ) {
autogroup_delete_member_from_group( op, &op->o_req_dn, &op->o_req_ndn, age );
} else
m = op->orm_modlist;
- for ( ; age ; age = age->age_next ) {
+ for ( age = agi->agi_entry ; age ; age = age->age_next ) {
ldap_pvt_thread_mutex_lock( &age->age_mutex );
dnMatch( &match, 0, NULL, NULL, &op->o_req_ndn, &age->age_ndn );
overlay_entry_release_ov( op, group, 0, on );
for ( agf = age->age_filter ; agf ; agf = agf->agf_next ) {
- if ( dnIsSuffix( &op->o_req_ndn, &agf->agf_ndn ) ) {
+ if ( !agf->agf_anlist && dnIsSuffix( &op->o_req_ndn, &agf->agf_ndn ) ) {
if ( test_filter( op, e, agf->agf_filter ) == LDAP_COMPARE_TRUE ) {
is_newdn = 1;
break;
return SLAP_CB_CONTINUE;
}
+ /* Must refresh groups if a matching member value is modified */
+ for ( ; age ; age = age->age_next ) {
+ autogroup_filter_t *agf;
+ for ( agf = age->age_filter ; agf ; agf = agf->agf_next ) {
+ if ( agf->agf_anlist ) {
+ Modifications *m;
+ for ( m = op->orm_modlist ; m ; m = m->sml_next ) {
+ if ( m->sml_desc == agf->agf_anlist[0].an_desc ) {
+ if ( dnIsSuffix( &op->o_req_ndn, &agf->agf_ndn ) ) {
+ int rc = test_filter( op, e, agf->agf_filter );
+ if ( rc == LDAP_COMPARE_TRUE ) {
+ age->age_mustrefresh = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
a = attrs_find( e->e_attrs, slap_schema.si_ad_objectClass );
if ( a == NULL ) {
m = op->orm_modlist;
- for ( ; age ; age = age->age_next ) {
+ for ( age = agi->agi_entry ; age ; age = age->age_next ) {
dnMatch( &match, 0, NULL, NULL, &op->o_req_ndn, &age->age_ndn );
if ( match == 0 ) {
return SLAP_CB_CONTINUE;
}
+/*
+** Detect if the olddn is part of a group and so if the group should be refreshed
+*/
+static int
+autogroup_modrdn_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_entry_t *age = agi->agi_entry;
+ Entry *e;
+
+ if ( get_manageDSAit( op ) ) {
+ return SLAP_CB_CONTINUE;
+ }
+
+ Debug( LDAP_DEBUG_TRACE, "==> autogroup_modrdn_entry <%s>\n", op->o_req_dn.bv_val, 0, 0);
+ ldap_pvt_thread_mutex_lock( &agi->agi_mutex );
+
+ if ( overlay_entry_get_ov( op, &op->o_req_ndn, NULL, NULL, 0, &e, on ) !=
+ LDAP_SUCCESS || e == NULL ) {
+ Debug( LDAP_DEBUG_TRACE, "autogroup_modrdn_entry cannot get entry for <%s>\n", op->o_req_dn.bv_val, 0, 0);
+ ldap_pvt_thread_mutex_unlock( &agi->agi_mutex );
+ return SLAP_CB_CONTINUE;
+ }
+
+ /* Must check if a dn is modified */
+ for ( ; age ; age = age->age_next ) {
+ autogroup_filter_t *agf;
+ for ( agf = age->age_filter ; agf ; agf = agf->agf_next ) {
+ if ( agf->agf_anlist ) {
+ if ( dnIsSuffix( &op->o_req_ndn, &agf->agf_ndn ) ) {
+ int rc = test_filter( op, e, agf->agf_filter );
+ if ( rc == LDAP_COMPARE_TRUE ) {
+ age->age_modrdn_olddnmodified = 1;
+ }
+ }
+ }
+ }
+ }
+
+ overlay_entry_release_ov( op, e, 0, on );
+ ldap_pvt_thread_mutex_unlock( &agi->agi_mutex );
+ return SLAP_CB_CONTINUE;
+}
+
/*
** Builds a filter for searching for the
** group entries, according to the objectClass.
ch_free( agf->agf_filterstr.bv_val );
ch_free( agf->agf_dn.bv_val );
ch_free( agf->agf_ndn.bv_val );
+ anlist_free( agf->agf_anlist, 1, NULL );
+ ch_free( agf );
}
ldap_pvt_thread_mutex_init( &age->age_mutex );
ch_free( agf->agf_filterstr.bv_val );
ch_free( agf->agf_dn.bv_val );
ch_free( agf->agf_ndn.bv_val );
+ anlist_free( agf->agf_anlist, 1, NULL );
+ ch_free( agf );
}
ldap_pvt_thread_mutex_destroy( &age->age_mutex );
ch_free( agf->agf_filterstr.bv_val );
ch_free( agf->agf_dn.bv_val );
ch_free( agf->agf_ndn.bv_val );
+ anlist_free( agf->agf_anlist, 1, NULL );
ch_free( agf );
}
autogroup.on_bi.bi_op_add = autogroup_add_entry;
autogroup.on_bi.bi_op_delete = autogroup_delete_entry;
autogroup.on_bi.bi_op_modify = autogroup_modify_entry;
+ autogroup.on_bi.bi_op_modrdn = autogroup_modrdn_entry;
autogroup.on_response = autogroup_response;