Blame SOURCES/0047-Ticket-49524-Password-policy-minimum-token-length-fa.patch

b045b9
From a85f64d2c4fa2718748a205d4ae0ebab47513199 Mon Sep 17 00:00:00 2001
b045b9
From: Mark Reynolds <mreynolds@redhat.com>
b045b9
Date: Mon, 8 Jan 2018 11:34:02 -0500
b045b9
Subject: [PATCH] Ticket 49524 - Password policy: minimum token length fails 
b045b9
 when the token length is equal to attribute length
b045b9
b045b9
Bug Description:  The token checking breaks when the password is the
b045b9
                  exact value of the entry attribute.
b045b9
b045b9
Fix Description:  Remove the "equal" part of the string comparisons.
b045b9
b045b9
https://pagure.io/389-ds-base/issue/49524
b045b9
b045b9
Reviewed by: firstyear & spichugi(Thanks!!)
b045b9
b045b9
(cherry picked from commit 790be09fc434d394239bf2486d01f212b36cf0e3)
b045b9
---
b045b9
 .../tests/suites/password/pwdPolicy_token_test.py  | 75 ++++++++++++++++++++++
b045b9
 ldap/servers/slapd/pw.c                            |  2 +-
b045b9
 ldap/servers/slapd/utf8.c                          |  2 +-
b045b9
 3 files changed, 77 insertions(+), 2 deletions(-)
b045b9
 create mode 100644 dirsrvtests/tests/suites/password/pwdPolicy_token_test.py
b045b9
b045b9
diff --git a/dirsrvtests/tests/suites/password/pwdPolicy_token_test.py b/dirsrvtests/tests/suites/password/pwdPolicy_token_test.py
b045b9
new file mode 100644
b045b9
index 000000000..7a4de9c85
b045b9
--- /dev/null
b045b9
+++ b/dirsrvtests/tests/suites/password/pwdPolicy_token_test.py
b045b9
@@ -0,0 +1,75 @@
b045b9
+import logging
b045b9
+import pytest
b045b9
+import os
b045b9
+import time
b045b9
+import ldap
b045b9
+from lib389._constants import *
b045b9
+from lib389.idm.user import UserAccounts
b045b9
+from lib389.topologies import topology_st as topo
b045b9
+
b045b9
+DEBUGGING = os.getenv("DEBUGGING", default=False)
b045b9
+if DEBUGGING:
b045b9
+    logging.getLogger(__name__).setLevel(logging.DEBUG)
b045b9
+else:
b045b9
+    logging.getLogger(__name__).setLevel(logging.INFO)
b045b9
+log = logging.getLogger(__name__)
b045b9
+
b045b9
+USER_DN = 'uid=Test_user1,ou=People,dc=example,dc=com'
b045b9
+TOKEN = 'test_user1'
b045b9
+
b045b9
+user_properties = {
b045b9
+    'uid': 'Test_user1',
b045b9
+    'cn': 'test_user1',
b045b9
+    'sn': 'test_user1',
b045b9
+    'uidNumber': '1001',
b045b9
+    'gidNumber': '2001',
b045b9
+    'userpassword': PASSWORD,
b045b9
+    'description': 'userdesc',
b045b9
+    'homeDirectory': '/home/{}'.format('test_user')}
b045b9
+
b045b9
+
b045b9
+def pwd_setup(topo):
b045b9
+    topo.standalone.config.replace_many(('passwordCheckSyntax', 'on'),
b045b9
+                                        ('passwordMinLength', '4'),
b045b9
+                                        ('passwordMinCategories', '1'))
b045b9
+    users = UserAccounts(topo.standalone, DEFAULT_SUFFIX)
b045b9
+    return users.create(properties=user_properties)
b045b9
+
b045b9
+
b045b9
+def test_token_lengths(topo):
b045b9
+    """Test that password token length is enforced for various lengths including
b045b9
+    the same length as the attribute being checked by the policy.
b045b9
+
b045b9
+    :id: dae9d916-2a03-4707-b454-9e901d295b13
b045b9
+    :setup: Standalone instance
b045b9
+    :steps:
b045b9
+        1. Test token length rejects password of the same length as rdn value
b045b9
+    :expectedresults:
b045b9
+        1. Passwords are rejected
b045b9
+    """
b045b9
+    user = pwd_setup(topo)
b045b9
+    for length in ['4', '6', '10']:
b045b9
+        topo.standalone.simple_bind_s(DN_DM, PASSWORD)
b045b9
+        topo.standalone.config.set('passwordMinTokenLength', length)
b045b9
+        topo.standalone.simple_bind_s(USER_DN, PASSWORD)
b045b9
+        time.sleep(1)
b045b9
+
b045b9
+        try:
b045b9
+            passwd = TOKEN[:int(length)]
b045b9
+            log.info("Testing password len {} token ({})".format(length, passwd))
b045b9
+            user.replace('userpassword', passwd)
b045b9
+            log.fatal('Password incorrectly allowed!')
b045b9
+            assert False
b045b9
+        except ldap.CONSTRAINT_VIOLATION as e:
b045b9
+            log.info('Password correctly rejected: ' + str(e))
b045b9
+        except ldap.LDAPError as e:
b045b9
+            log.fatal('Unexpected failure ' + str(e))
b045b9
+            assert False
b045b9
+
b045b9
+
b045b9
+if __name__ == '__main__':
b045b9
+    # Run isolated
b045b9
+    # -s for DEBUG mode
b045b9
+    CURRENT_FILE = os.path.realpath(__file__)
b045b9
+    pytest.main("-s %s" % CURRENT_FILE)
b045b9
+
b045b9
diff --git a/ldap/servers/slapd/pw.c b/ldap/servers/slapd/pw.c
b045b9
index e625962e8..0cf795b41 100644
b045b9
--- a/ldap/servers/slapd/pw.c
b045b9
+++ b/ldap/servers/slapd/pw.c
b045b9
@@ -1465,7 +1465,7 @@ check_trivial_words(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Value **vals, char *
b045b9
             sp = slapi_ch_strdup(slapi_value_get_string(valp));
b045b9
             ep = sp + strlen(sp);
b045b9
             ep = ldap_utf8prevn(sp, ep, toklen);
b045b9
-            if (!ep || (sp >= ep)) {
b045b9
+            if (!ep || (sp > ep)) {
b045b9
                 slapi_ch_free_string(&sp);
b045b9
                 continue;
b045b9
             }
b045b9
diff --git a/ldap/servers/slapd/utf8.c b/ldap/servers/slapd/utf8.c
b045b9
index b0667c636..4538625b3 100644
b045b9
--- a/ldap/servers/slapd/utf8.c
b045b9
+++ b/ldap/servers/slapd/utf8.c
b045b9
@@ -152,7 +152,7 @@ ldap_utf8prevn(char *s, char *from, int n)
b045b9
     }
b045b9
     for (; n > 0; --n) {
b045b9
         prev = ldap_utf8prev(prev);
b045b9
-        if ((prev <= s) && (n > 0)) {
b045b9
+        if ((n > 0) && (prev < s)) {
b045b9
             return NULL;
b045b9
         }
b045b9
     }
b045b9
-- 
b045b9
2.13.6
b045b9