{
slap_overinst *on = (slap_overinst *)c->bi;
pp_info *pi = (pp_info *)on->on_bi.bi_private;
- BackendDB *be = (BackendDB *)c->be;
- const char *text;
int rc = ARG_BAD_CONF;
assert ( c->type == PPOLICY_DEFAULT );
if ((pa = attr_find( op->oq_add.rs_e->e_attrs,
slap_schema.si_ad_userPassword )))
{
+ assert( pa->a_vals );
+ assert( !BER_BVISNULL( &pa->a_vals[ 0 ] ) );
+
+ if ( !BER_BVISNULL( &pa->a_vals[ 1 ] ) ) {
+ send_ldap_error( op, rs, LDAP_CONSTRAINT_VIOLATION, "Password policy only allows one password value" );
+ return rs->sr_err;
+ }
+
/*
* new entry contains a password - if we're not the root user
* then we need to check that the password fits in with the
pwmod = 1;
pwmop = ml->sml_op;
if ((deladd == 0) && (ml->sml_op == LDAP_MOD_DELETE) &&
- (ml->sml_values) && (ml->sml_values[0].bv_val != NULL)) {
+ (ml->sml_values) && !BER_BVISNULL( &ml->sml_values[0] ))
+ {
deladd = 1;
delmod = ml;
}
if ((deladd == 1) && ((ml->sml_op == LDAP_MOD_ADD) ||
- (ml->sml_op == LDAP_MOD_REPLACE)))
+ (ml->sml_op == LDAP_MOD_REPLACE)))
+ {
deladd = 2;
+ }
if ((ml->sml_op == LDAP_MOD_ADD) ||
(ml->sml_op == LDAP_MOD_REPLACE))
+ {
addmod = ml;
+
+ /* FIXME: there's no easy way to ensure
+ * that add does not cause multiple
+ * userPassword values; one way (that
+ * would be consistent with the single
+ * password constraint) would be to turn
+ * add into replace); another would be
+ * to disallow add.
+ *
+ * Let's check at least that a single value
+ * is being added
+ */
+ assert( addmod->sml_values != NULL );
+ assert( !BER_BVISNULL( &addmod->sml_values[ 0 ] ) );
+ if ( !BER_BVISNULL( &addmod->sml_values[ 1 ] ) ) {
+ rs->sr_err = LDAP_CONSTRAINT_VIOLATION;
+ rs->sr_text = "Password policy only allows one password value";
+ goto return_results;
+ }
+ }
+
} else if (! is_at_operational( ml->sml_desc->ad_type )) {
mod_pw_only = 0;
/* modifying something other than password */
exit $RC
fi
+echo /dev/null > $TESTOUT
+
echo "Using ldapadd to populate the database..."
# may need "-e relax" for draft 09, but not yet.
$LDAPADD -D "$MANAGERDN" -h $LOCALHOST -p $PORT1 -w $PASSWD < \
- $LDIFPPOLICY > $TESTOUT 2>&1
+ $LDIFPPOLICY >> $TESTOUT 2>&1
RC=$?
if test $RC != 0 ; then
echo "ldapadd failed ($RC)!"
fi
echo "Filling password history..."
-$LDAPMODIFY -v -D "$USER" -h $LOCALHOST -p $PORT1 -w $PASS > \
+$LDAPMODIFY -v -D "$USER" -h $LOCALHOST -p $PORT1 -w $PASS >> \
$TESTOUT 2>&1 << EOMODS
dn: uid=nd, ou=People, dc=example, dc=com
changetype: modify
exit $RC
fi
echo "Testing password history..."
-$LDAPMODIFY -v -D "$USER" -h $LOCALHOST -p $PORT1 -w 20urgle12-6 > \
+$LDAPMODIFY -v -D "$USER" -h $LOCALHOST -p $PORT1 -w 20urgle12-6 >> \
$TESTOUT 2>&1 << EOMODS
dn: uid=nd, ou=People, dc=example, dc=com
changetype: modify
echo "Testing forced reset..."
-$LDAPMODIFY -v -D "$MANAGERDN" -h $LOCALHOST -p $PORT1 -w $PASSWD > \
+$LDAPMODIFY -v -D "$MANAGERDN" -h $LOCALHOST -p $PORT1 -w $PASSWD >> \
$TESTOUT 2>&1 << EOMODS
dn: uid=nd, ou=People, dc=example, dc=com
changetype: modify
echo "Clearing forced reset..."
-$LDAPMODIFY -v -D "$MANAGERDN" -h $LOCALHOST -p $PORT1 -w $PASSWD > \
+$LDAPMODIFY -v -D "$MANAGERDN" -h $LOCALHOST -p $PORT1 -w $PASSWD >> \
$TESTOUT 2>&1 << EOMODS
dn: uid=nd, ou=People, dc=example, dc=com
changetype: modify
$LDAPPASSWD -h $LOCALHOST -p $PORT1 \
-w $PASS -s failexpect \
- -D "$USER" > $TESTOUT 2>&1
+ -D "$USER" >> $TESTOUT 2>&1
RC=$?
if test $RC = 0 ; then
echo "Safe modify test 1 failed ($RC)!"
$LDAPPASSWD -h $LOCALHOST -p $PORT1 \
-w $PASS -s failexpect -a $PASS \
- -D "$USER" > $TESTOUT 2>&1
+ -D "$USER" >> $TESTOUT 2>&1
RC=$?
if test $RC != 0 ; then
echo "Safe modify test 2 failed ($RC)!"
$LDAPPASSWD -h $LOCALHOST -p $PORT1 \
-w failexpect -a failexpect -s spw \
- -D "$USER" > $TESTOUT 2>&1
+ -D "$USER" > ${TESTOUT}.2 2>&1
RC=$?
+cat ${TESTOUT}.2 >> $TESTOUT
if test $RC = 0 ; then
echo "Length requirement test failed ($RC)!"
test $KILLSERVERS != no && kill -HUP $KILLPIDS
exit 1
fi
-COUNT=`grep "Password fails quality" $TESTOUT | wc -l`
+COUNT=`grep "Password fails quality" ${TESTOUT}.2 | wc -l`
if test $COUNT != 1 ; then
echo "Length requirement test failed"
test $KILLSERVERS != no && kill -HUP $KILLPIDS
echo "Testing hashed length requirement..."
$LDAPMODIFY -h $LOCALHOST -p $PORT1 -D "$USER" -w failexpect > \
- $TESTOUT 2>&1 << EOMODS
+ ${TESTOUT}.2 2>&1 << EOMODS
dn: $USER
changetype: modify
delete: userPassword
EOMODS
RC=$?
+cat ${TESTOUT}.2 >> $TESTOUT
if test $RC = 0 ; then
echo "Hashed length requirement test failed ($RC)!"
test $KILLSERVERS != no && kill -HUP $KILLPIDS
exit 1
fi
-COUNT=`grep "Password fails quality" $TESTOUT | wc -l`
+COUNT=`grep "Password fails quality" ${TESTOUT}.2 | wc -l`
if test $COUNT != 1 ; then
echo "Hashed length requirement test failed"
test $KILLSERVERS != no && kill -HUP $KILLPIDS
exit 1
fi
+echo "Testing multiple password add/modify checks..."
+
+$LDAPMODIFY -h $LOCALHOST -p $PORT1 -D "$MANAGERDN" -w $PASSWD >> \
+ $TESTOUT 2>&1 << EOMODS
+dn: cn=Add Should Fail, ou=People, dc=example, dc=com
+changetype: add
+objectClass: inetOrgPerson
+cn: Add Should Fail
+sn: Fail
+userPassword: firstpw
+userPassword: secondpw
+EOMODS
+RC=$?
+if test $RC = 0 ; then
+ echo "Multiple password add test failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit 1
+fi
+
+$LDAPMODIFY -h $LOCALHOST -p $PORT1 -D "$MANAGERDN" -w $PASSWD >> \
+ $TESTOUT 2>&1 << EOMODS
+dn: $USER
+changetype: modify
+add: userPassword
+userPassword: firstpw
+userPassword: secondpw
+EOMODS
+RC=$?
+if test $RC = 0 ; then
+ echo "Multiple password modify add test failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit 1
+fi
+
+$LDAPMODIFY -h $LOCALHOST -p $PORT1 -D "$MANAGERDN" -w $PASSWD >> \
+ $TESTOUT 2>&1 << EOMODS
+dn: $USER
+changetype: modify
+replace: userPassword
+userPassword: firstpw
+userPassword: secondpw
+EOMODS
+RC=$?
+if test $RC = 0 ; then
+ echo "Multiple password modify replace test failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit 1
+fi
+
test $KILLSERVERS != no && kill -HUP $KILLPIDS
echo ">>>>> Test succeeded"