allow controls deletion to be deferred; pass response controls back to frontend in extops (ITS#5711)

This commit is contained in:
Pierangelo Masarati 2008-09-27 10:06:43 +00:00
parent 9f808bd4b6
commit a0e3e68a02
4 changed files with 59 additions and 28 deletions

View File

@ -362,20 +362,14 @@ account_locked( Operation *op, Entry *e,
static const char ppolicy_ctrl_oid[] = LDAP_CONTROL_PASSWORDPOLICYRESPONSE;
static LDAPControl *
create_passcontrol( int exptime, int grace, LDAPPasswordPolicyError err )
create_passcontrol( Operation *op, int exptime, int grace, LDAPPasswordPolicyError err )
{
char berbuf[LBER_ELEMENT_SIZEOF], bb2[LBER_ELEMENT_SIZEOF];
BerElement *ber = (BerElement *)berbuf, *b2 = (BerElement *)bb2;
LDAPControl *c;
LDAPControl c = { 0 }, *cp;
struct berval bv;
c = ch_calloc( sizeof( LDAPControl ), 1 );
if ( c == NULL ) {
return NULL;
}
c->ldctl_oid = (char *)ppolicy_ctrl_oid;
c->ldctl_iscritical = 0;
BER_BVZERO( &c->ldctl_value );
BER_BVZERO( &c.ldctl_value );
ber_init2( ber, NULL, LBER_USE_DER );
ber_printf( ber, "{" /*}*/ );
@ -401,12 +395,19 @@ create_passcontrol( int exptime, int grace, LDAPPasswordPolicyError err )
}
ber_printf( ber, /*{*/ "N}" );
if (ber_flatten2( ber, &(c->ldctl_value), 1 ) == LBER_DEFAULT) {
ch_free(c);
c = NULL;
if (ber_flatten2( ber, &(c.ldctl_value), 1 ) == LBER_DEFAULT) {
return NULL;
}
(void)ber_free_buf(ber);
return c;
cp = op->o_tmpalloc( sizeof( LDAPControl ) + c.ldctl_value.bv_len, op->o_tmpmemctx );
cp->ldctl_oid = (char *)ppolicy_ctrl_oid;
cp->ldctl_iscritical = 0;
cp->ldctl_value.bv_val = (char *)&cp[1];
cp->ldctl_value.bv_len = c.ldctl_value.bv_len;
AC_MEMCPY( cp->ldctl_value.bv_val, c.ldctl_value.bv_val, c.ldctl_value.bv_len );
ber_memfree( c.ldctl_value.bv_val );
return cp;
}
static LDAPControl **
@ -1138,7 +1139,7 @@ locked:
if ( ppb->pErr == PP_accountLocked && !pi->use_lockout ) {
ppb->pErr = PP_noError;
}
ctrl = create_passcontrol( warn, ngut, ppb->pErr );
ctrl = create_passcontrol( op, warn, ngut, ppb->pErr );
ppb->oldctrls = add_passcontrol( op, rs, ctrl );
op->o_callback->sc_cleanup = ppolicy_ctrls_cleanup;
}
@ -1251,7 +1252,7 @@ ppolicy_restrict(
"connection restricted to password changing only\n", 0, 0, 0);
if ( send_ctrl ) {
LDAPControl *ctrl = NULL;
ctrl = create_passcontrol( -1, -1, PP_changeAfterReset );
ctrl = create_passcontrol( op, -1, -1, PP_changeAfterReset );
oldctrls = add_passcontrol( op, rs, ctrl );
}
op->o_bd->bd_info = (BackendInfo *)on->on_info;
@ -1317,7 +1318,7 @@ ppolicy_add(
op->o_bd->bd_info = (BackendInfo *)on->on_info;
if ( send_ctrl ) {
LDAPControl *ctrl = NULL;
ctrl = create_passcontrol( -1, -1, pErr );
ctrl = create_passcontrol( op, -1, -1, pErr );
oldctrls = add_passcontrol( op, rs, ctrl );
}
send_ldap_error( op, rs, rc, "Password fails quality checking policy" );
@ -1406,7 +1407,9 @@ ppolicy_modify( Operation *op, SlapReply *rs )
struct berval newpw = BER_BVNULL, oldpw = BER_BVNULL,
*bv, cr[2];
LDAPPasswordPolicyError pErr = PP_noError;
LDAPControl *ctrl = NULL;
LDAPControl **oldctrls = NULL;
int is_pwdexop = 0;
op->o_bd->bd_info = (BackendInfo *)on->on_info;
rc = be_entry_get_rw( op, &op->o_req_ndn, NULL, NULL, 0, &e );
@ -1526,6 +1529,7 @@ ppolicy_modify( Operation *op, SlapReply *rs )
req_pwdexop_s *qpw = sc->sc_private;
newpw = qpw->rs_new;
oldpw = qpw->rs_old;
is_pwdexop = 1;
break;
}
}
@ -2010,14 +2014,21 @@ return_results:
op->o_bd->bd_info = (BackendInfo *)on->on_info;
be_entry_release_r( op, e );
if ( send_ctrl ) {
LDAPControl *ctrl = NULL;
ctrl = create_passcontrol( -1, -1, pErr );
ctrl = create_passcontrol( op, -1, -1, pErr );
oldctrls = add_passcontrol( op, rs, ctrl );
}
send_ldap_result( op, rs );
if ( send_ctrl ) {
ctrls_cleanup( op, rs, oldctrls );
if ( is_pwdexop ) {
if ( rs->sr_flags & REP_CTRLS_MUSTBEFREED ) {
slap_free_ctrls( op, oldctrls );
}
oldctrls = NULL;
rs->sr_flags |= REP_CTRLS_MUSTBEFREED;
} else {
ctrls_cleanup( op, rs, oldctrls );
}
}
return rs->sr_err;
}

View File

@ -538,6 +538,14 @@ clean2:;
}
}
if ( rs->sr_flags & REP_CTRLS_MUSTBEFREED ) {
rs->sr_flags ^= REP_CTRLS_MUSTBEFREED; /* paranoia */
if ( rs->sr_ctrls ) {
slap_free_ctrls( op, rs->sr_ctrls );
rs->sr_ctrls = NULL;
}
}
return rc;
}

View File

@ -2059,6 +2059,9 @@ struct SlapReply {
#define REP_REF_MUSTBEFREED 0x0020U
#define REP_REF_MASK (REP_REF_MUSTBEFREED)
#define REP_CTRLS_MUSTBEFREED 0x0040U
#define REP_CTRLS_MASK (REP_CTRLS_MUSTBEFREED)
#define REP_NO_ENTRYDN 0x1000U
#define REP_NO_SUBSCHEMA 0x2000U
#define REP_NO_OPERATIONALS (REP_NO_ENTRYDN|REP_NO_SUBSCHEMA)

View File

@ -142,7 +142,7 @@ $LDAPMODIFY -v -D "$USER" -h $LOCALHOST -p $PORT1 -w $PASS >> \
dn: uid=nd, ou=People, dc=example, dc=com
changetype: modify
delete: userpassword
userpassword: testpassword
userpassword: $PASS
-
replace: userpassword
userpassword: 20urgle12-1
@ -220,7 +220,7 @@ $LDAPMODIFY -v -D "$MANAGERDN" -h $LOCALHOST -p $PORT1 -w $PASSWD >> \
dn: uid=nd, ou=People, dc=example, dc=com
changetype: modify
replace: userPassword
userPassword: testpassword
userPassword: $PASS
-
replace: pwdReset
pwdReset: TRUE
@ -288,8 +288,11 @@ fi
sleep 2
OLDPASS=$PASS
PASS=successexpect
$LDAPPASSWD -h $LOCALHOST -p $PORT1 \
-w $PASS -s failexpect -a $PASS \
-w $OLDPASS -s $PASS -a $OLDPASS \
-D "$USER" >> $TESTOUT 2>&1
RC=$?
if test $RC != 0 ; then
@ -299,10 +302,10 @@ if test $RC != 0 ; then
fi
echo "Testing length requirement..."
# check control in response (ITS#5711)
$LDAPPASSWD -h $LOCALHOST -p $PORT1 \
-w failexpect -a failexpect -s spw \
-D "$USER" > ${TESTOUT}.2 2>&1
-w $PASS -a $PASS -s 2shr \
-D "$USER" -e ppolicy > ${TESTOUT}.2 2>&1
RC=$?
cat ${TESTOUT}.2 >> $TESTOUT
if test $RC = 0 ; then
@ -316,15 +319,21 @@ if test $COUNT != 1 ; then
test $KILLSERVERS != no && kill -HUP $KILLPIDS
exit 1
fi
COUNT=`grep "Password is too short for policy" ${TESTOUT}.2 | wc -l`
if test $COUNT != 1 ; then
echo "Control not returned in response"
test $KILLSERVERS != no && kill -HUP $KILLPIDS
exit 1
fi
echo "Testing hashed length requirement..."
$LDAPMODIFY -h $LOCALHOST -p $PORT1 -D "$USER" -w failexpect > \
$LDAPMODIFY -h $LOCALHOST -p $PORT1 -D "$USER" -w $PASS > \
${TESTOUT}.2 2>&1 << EOMODS
dn: $USER
changetype: modify
delete: userPassword
userPassword: failexpect
userPassword: $PASS
-
add: userPassword
userPassword: {MD5}xxxxxx