ITS#8184 avoid redundant mod ops

If multiple ppolicy overlays are present on a glued tree, they all
attempt to update the policy operational attributes in response to
password-related activities. The redundant mod ops will cause the
entire op to fail. Check for these ops before inserting new ones.
This commit is contained in:
Howard Chu 2015-07-09 19:11:22 +01:00
parent eb25ece469
commit 624c1fac8b

View file

@ -1565,6 +1565,8 @@ ppolicy_modify( Operation *op, SlapReply *rs )
LDAPControl *ctrl = NULL; LDAPControl *ctrl = NULL;
LDAPControl **oldctrls = NULL; LDAPControl **oldctrls = NULL;
int is_pwdexop = 0; int is_pwdexop = 0;
int got_del_grace = 0, got_del_lock = 0, got_pw = 0, got_del_fail = 0;
int got_changed = 0, got_history = 0;
op->o_bd->bd_info = (BackendInfo *)on->on_info; op->o_bd->bd_info = (BackendInfo *)on->on_info;
rc = be_entry_get_rw( op, &op->o_req_ndn, NULL, NULL, 0, &e ); rc = be_entry_get_rw( op, &op->o_req_ndn, NULL, NULL, 0, &e );
@ -1577,7 +1579,6 @@ ppolicy_modify( Operation *op, SlapReply *rs )
*/ */
if ( be_shadow_update( op )) { if ( be_shadow_update( op )) {
Modifications **prev; Modifications **prev;
int got_del_grace = 0, got_del_lock = 0, got_pw = 0, got_del_fail = 0;
Attribute *a_grace, *a_lock, *a_fail; Attribute *a_grace, *a_lock, *a_fail;
a_grace = attr_find( e->e_attrs, ad_pwdGraceUseTime ); a_grace = attr_find( e->e_attrs, ad_pwdGraceUseTime );
@ -1596,19 +1597,25 @@ ppolicy_modify( Operation *op, SlapReply *rs )
int drop = 0; int drop = 0;
if ( ml->sml_desc == ad_pwdGraceUseTime ) { if ( ml->sml_desc == ad_pwdGraceUseTime ) {
got_del_grace = 1; if ( !a_grace || got_del_grace ) {
if ( !a_grace )
drop = 1; drop = 1;
} else {
got_del_grace = 1;
}
} else } else
if ( ml->sml_desc == ad_pwdAccountLockedTime ) { if ( ml->sml_desc == ad_pwdAccountLockedTime ) {
got_del_lock = 1; if ( !a_lock || got_del_lock ) {
if ( !a_lock )
drop = 1; drop = 1;
} else {
got_del_lock = 1;
}
} else } else
if ( ml->sml_desc == ad_pwdFailureTime ) { if ( ml->sml_desc == ad_pwdFailureTime ) {
got_del_fail = 1; if ( !a_fail || got_del_fail ) {
if ( !a_fail )
drop = 1; drop = 1;
} else {
got_del_fail = 1;
}
} }
if ( drop ) { if ( drop ) {
*prev = ml->sml_next; *prev = ml->sml_next;
@ -1760,6 +1767,20 @@ ppolicy_modify( Operation *op, SlapReply *rs )
(ml->sml_op == LDAP_MOD_REPLACE)) (ml->sml_op == LDAP_MOD_REPLACE))
zapReset = 0; zapReset = 0;
} }
if ( ml->sml_op == LDAP_MOD_DELETE ) {
if ( ml->sml_desc == ad_pwdGraceUseTime ) {
got_del_grace = 1;
} else if ( ml->sml_desc == ad_pwdAccountLockedTime ) {
got_del_lock = 1;
} else if ( ml->sml_desc == ad_pwdFailureTime ) {
got_del_fail = 1;
}
}
if ( ml->sml_desc == ad_pwdChangedTime ) {
got_changed = 1;
} else if (ml->sml_desc == ad_pwdHistory ) {
got_history = 1;
}
} }
if (!BER_BVISEMPTY( &pwcons[op->o_conn->c_conn_idx].dn ) && !mod_pw_only ) { if (!BER_BVISEMPTY( &pwcons[op->o_conn->c_conn_idx].dn ) && !mod_pw_only ) {
@ -1996,6 +2017,7 @@ do_modify:
* up to date. * up to date.
*/ */
if (!got_changed) {
timestamp.bv_val = timebuf; timestamp.bv_val = timebuf;
timestamp.bv_len = sizeof(timebuf); timestamp.bv_len = sizeof(timebuf);
slap_timestamp( &now, &timestamp ); slap_timestamp( &now, &timestamp );
@ -2020,8 +2042,9 @@ do_modify:
modtail->sml_next = mods; modtail->sml_next = mods;
modtail = mods; modtail = mods;
} }
}
if (attr_find(e->e_attrs, ad_pwdGraceUseTime )) { if (!got_del_grace && attr_find(e->e_attrs, ad_pwdGraceUseTime )) {
mods = (Modifications *) ch_calloc( sizeof( Modifications ), 1 ); mods = (Modifications *) ch_calloc( sizeof( Modifications ), 1 );
mods->sml_op = LDAP_MOD_DELETE; mods->sml_op = LDAP_MOD_DELETE;
mods->sml_desc = ad_pwdGraceUseTime; mods->sml_desc = ad_pwdGraceUseTime;
@ -2031,7 +2054,7 @@ do_modify:
modtail = mods; modtail = mods;
} }
if (attr_find(e->e_attrs, ad_pwdAccountLockedTime )) { if (!got_del_lock && attr_find(e->e_attrs, ad_pwdAccountLockedTime )) {
mods = (Modifications *) ch_calloc( sizeof( Modifications ), 1 ); mods = (Modifications *) ch_calloc( sizeof( Modifications ), 1 );
mods->sml_op = LDAP_MOD_DELETE; mods->sml_op = LDAP_MOD_DELETE;
mods->sml_desc = ad_pwdAccountLockedTime; mods->sml_desc = ad_pwdAccountLockedTime;
@ -2041,7 +2064,7 @@ do_modify:
modtail = mods; modtail = mods;
} }
if (attr_find(e->e_attrs, ad_pwdFailureTime )) { if (!got_del_fail && attr_find(e->e_attrs, ad_pwdFailureTime )) {
mods = (Modifications *) ch_calloc( sizeof( Modifications ), 1 ); mods = (Modifications *) ch_calloc( sizeof( Modifications ), 1 );
mods->sml_op = LDAP_MOD_DELETE; mods->sml_op = LDAP_MOD_DELETE;
mods->sml_desc = ad_pwdFailureTime; mods->sml_desc = ad_pwdFailureTime;
@ -2062,7 +2085,7 @@ do_modify:
modtail = mods; modtail = mods;
} }
if (pp.pwdInHistory > 0) { if (!got_history && pp.pwdInHistory > 0) {
if (hsize >= pp.pwdInHistory) { if (hsize >= pp.pwdInHistory) {
/* /*
* We use the >= operator, since we are going to add * We use the >= operator, since we are going to add