mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-03-07 14:18:15 +08:00
allow controls deletion to be deferred; pass response controls back to frontend in extops (ITS#5711)
This commit is contained in:
parent
9f808bd4b6
commit
a0e3e68a02
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user