From 5d3121902f11e84c29edf1d0e70b33ed34bcdf4d Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Mon, 28 Aug 2006 12:44:39 +0000 Subject: [PATCH] Add single-password constraint; NOTE from ppolicy.c: /* 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 */ --- servers/slapd/overlays/ppolicy.c | 39 +++++++++++++++-- tests/scripts/test022-ppolicy | 75 +++++++++++++++++++++++++++----- 2 files changed, 99 insertions(+), 15 deletions(-) diff --git a/servers/slapd/overlays/ppolicy.c b/servers/slapd/overlays/ppolicy.c index c68c0e9a8b..03452d7288 100644 --- a/servers/slapd/overlays/ppolicy.c +++ b/servers/slapd/overlays/ppolicy.c @@ -248,8 +248,6 @@ ppolicy_cf_default( ConfigArgs *c ) { 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 ); @@ -1200,6 +1198,14 @@ ppolicy_add( 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 @@ -1443,18 +1449,43 @@ ppolicy_modify( Operation *op, SlapReply *rs ) 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 */ diff --git a/tests/scripts/test022-ppolicy b/tests/scripts/test022-ppolicy index de6b9fb8c8..a7ccc295a6 100755 --- a/tests/scripts/test022-ppolicy +++ b/tests/scripts/test022-ppolicy @@ -55,10 +55,12 @@ if test $RC != 0 ; then 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)!" @@ -135,7 +137,7 @@ if test $RC != 0 ; then 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 @@ -193,7 +195,7 @@ if test $RC != 0 ; then 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 @@ -213,7 +215,7 @@ fi 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 @@ -249,7 +251,7 @@ fi 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 @@ -276,7 +278,7 @@ echo "Testing Safe 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)!" @@ -288,7 +290,7 @@ sleep 2 $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)!" @@ -300,14 +302,15 @@ echo "Testing length requirement..." $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 @@ -317,7 +320,7 @@ fi 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 @@ -328,18 +331,68 @@ userPassword: {MD5}xxxxxx 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" -- 2.39.5