|
|
232633 |
From d9e895e928c39ca66e272a61a431fa3bfc3d8f5c Mon Sep 17 00:00:00 2001
|
|
|
232633 |
From: Thierry Bordaz <tbordaz@redhat.com>
|
|
|
232633 |
Date: Fri, 13 Jul 2018 17:55:27 +0200
|
|
|
232633 |
Subject: [PATCH] Ticket 49789 - By default, do not manage unhashed password
|
|
|
232633 |
|
|
|
232633 |
Bug Description:
|
|
|
232633 |
By default, unhashed#user#password is recorded into changelog database.
|
|
|
232633 |
It is a specific use when some plugin need to know the clear text password on update.
|
|
|
232633 |
This should be disabled ('off') by default
|
|
|
232633 |
|
|
|
232633 |
Fix Description:
|
|
|
232633 |
Switch the default value from 'on' to 'off'
|
|
|
232633 |
|
|
|
232633 |
https://pagure.io/389-ds-base/issue/49789
|
|
|
232633 |
|
|
|
232633 |
Reviewed by: Viktor Ashirov, Simon Pichugi, Mark Reynolds
|
|
|
232633 |
|
|
|
232633 |
Platforms tested: F28
|
|
|
232633 |
|
|
|
232633 |
Flag Day: no
|
|
|
232633 |
|
|
|
232633 |
Doc impact: no
|
|
|
232633 |
---
|
|
|
232633 |
.../tests/suites/password/regression_test.py | 121 +++++++++++++++++-
|
|
|
232633 |
ldap/servers/slapd/slap.h | 4 +-
|
|
|
232633 |
2 files changed, 122 insertions(+), 3 deletions(-)
|
|
|
232633 |
|
|
|
232633 |
diff --git a/dirsrvtests/tests/suites/password/regression_test.py b/dirsrvtests/tests/suites/password/regression_test.py
|
|
|
232633 |
index b01b73e2e..c239799e4 100644
|
|
|
232633 |
--- a/dirsrvtests/tests/suites/password/regression_test.py
|
|
|
232633 |
+++ b/dirsrvtests/tests/suites/password/regression_test.py
|
|
|
232633 |
@@ -8,8 +8,11 @@
|
|
|
232633 |
import pytest
|
|
|
232633 |
import time
|
|
|
232633 |
from lib389._constants import PASSWORD, DN_DM, DEFAULT_SUFFIX
|
|
|
232633 |
+from lib389._constants import SUFFIX, PASSWORD, DN_DM, DN_CONFIG, PLUGIN_RETRO_CHANGELOG, DEFAULT_SUFFIX, DEFAULT_CHANGELOG_DB
|
|
|
232633 |
+from lib389 import Entry
|
|
|
232633 |
+from lib389.topologies import topology_m1 as topo_master
|
|
|
232633 |
from lib389.idm.user import UserAccounts
|
|
|
232633 |
-from lib389.utils import ldap, os, logging
|
|
|
232633 |
+from lib389.utils import ldap, os, logging, ensure_bytes
|
|
|
232633 |
from lib389.topologies import topology_st as topo
|
|
|
232633 |
from lib389.idm.organizationalunit import OrganizationalUnits
|
|
|
232633 |
|
|
|
232633 |
@@ -36,6 +39,23 @@ TEST_PASSWORDS += ['CNpwtest1ZZZZ', 'ZZZZZCNpwtest1',
|
|
|
232633 |
TEST_PASSWORDS2 = (
|
|
|
232633 |
'CN12pwtest31', 'SN3pwtest231', 'UID1pwtest123', 'MAIL2pwtest12@redhat.com', '2GN1pwtest123', 'People123')
|
|
|
232633 |
|
|
|
232633 |
+def _check_unhashed_userpw(inst, user_dn, is_present=False):
|
|
|
232633 |
+ """Check if unhashed#user#password attribute is present of not in the changelog"""
|
|
|
232633 |
+ unhashed_pwd_attribute = 'unhashed#user#password'
|
|
|
232633 |
+
|
|
|
232633 |
+ changelog_dbdir = os.path.join(os.path.dirname(inst.dbdir), DEFAULT_CHANGELOG_DB)
|
|
|
232633 |
+ for dbfile in os.listdir(changelog_dbdir):
|
|
|
232633 |
+ if dbfile.endswith('.db'):
|
|
|
232633 |
+ changelog_dbfile = os.path.join(changelog_dbdir, dbfile)
|
|
|
232633 |
+ log.info('Changelog dbfile file exist: {}'.format(changelog_dbfile))
|
|
|
232633 |
+ log.info('Running dbscan -f to check {} attr'.format(unhashed_pwd_attribute))
|
|
|
232633 |
+ dbscanOut = inst.dbscan(DEFAULT_CHANGELOG_DB, changelog_dbfile)
|
|
|
232633 |
+ for entry in dbscanOut.split(b'dbid: '):
|
|
|
232633 |
+ if ensure_bytes('operation: modify') in entry and ensure_bytes(user_dn) in entry and ensure_bytes('userPassword') in entry:
|
|
|
232633 |
+ if is_present:
|
|
|
232633 |
+ assert ensure_bytes(unhashed_pwd_attribute) in entry
|
|
|
232633 |
+ else:
|
|
|
232633 |
+ assert ensure_bytes(unhashed_pwd_attribute) not in entry
|
|
|
232633 |
|
|
|
232633 |
@pytest.fixture(scope="module")
|
|
|
232633 |
def passw_policy(topo, request):
|
|
|
232633 |
@@ -193,6 +213,105 @@ def test_global_vs_local(topo, passw_policy, create_user, user_pasw):
|
|
|
232633 |
# reset password
|
|
|
232633 |
create_user.set('userPassword', PASSWORD)
|
|
|
232633 |
|
|
|
232633 |
+@pytest.mark.ds49789
|
|
|
232633 |
+def test_unhashed_pw_switch(topo_master):
|
|
|
232633 |
+ """Check that nsslapd-unhashed-pw-switch works corrently
|
|
|
232633 |
+
|
|
|
232633 |
+ :id: e5aba180-d174-424d-92b0-14fe7bb0b92a
|
|
|
232633 |
+ :setup: Master Instance
|
|
|
232633 |
+ :steps:
|
|
|
232633 |
+ 1. A Master is created, enable retrocl (not used here)
|
|
|
232633 |
+ 2. create a set of users
|
|
|
232633 |
+ 3. update userpassword of user1 and check that unhashed#user#password is not logged (default)
|
|
|
232633 |
+ 4. udpate userpassword of user2 and check that unhashed#user#password is not logged ('nolog')
|
|
|
232633 |
+ 5. udpate userpassword of user3 and check that unhashed#user#password is logged ('on')
|
|
|
232633 |
+ :expectedresults:
|
|
|
232633 |
+ 1. Success
|
|
|
232633 |
+ 2. Success
|
|
|
232633 |
+ 3 Success (unhashed#user#password is not logged in the replication changelog)
|
|
|
232633 |
+ 4. Success (unhashed#user#password is not logged in the replication changelog)
|
|
|
232633 |
+ 5. Success (unhashed#user#password is logged in the replication changelog)
|
|
|
232633 |
+ """
|
|
|
232633 |
+ MAX_USERS = 10
|
|
|
232633 |
+ PEOPLE_DN = ("ou=people," + DEFAULT_SUFFIX)
|
|
|
232633 |
+
|
|
|
232633 |
+ inst = topo_master.ms["master1"]
|
|
|
232633 |
+ inst.modify_s("cn=Retro Changelog Plugin,cn=plugins,cn=config",
|
|
|
232633 |
+ [(ldap.MOD_REPLACE, 'nsslapd-changelogmaxage', b'2m'),
|
|
|
232633 |
+ (ldap.MOD_REPLACE, 'nsslapd-changelog-trim-interval', b"5s"),
|
|
|
232633 |
+ (ldap.MOD_REPLACE, 'nsslapd-logAccess', b'on')])
|
|
|
232633 |
+ inst.config.loglevel(vals=[256 + 4], service='access')
|
|
|
232633 |
+ inst.restart()
|
|
|
232633 |
+ # If you need any test suite initialization,
|
|
|
232633 |
+ # please, write additional fixture for that (including finalizer).
|
|
|
232633 |
+ # Topology for suites are predefined in lib389/topologies.py.
|
|
|
232633 |
+
|
|
|
232633 |
+ # enable dynamic plugins, memberof and retro cl plugin
|
|
|
232633 |
+ #
|
|
|
232633 |
+ log.info('Enable plugins...')
|
|
|
232633 |
+ try:
|
|
|
232633 |
+ inst.modify_s(DN_CONFIG,
|
|
|
232633 |
+ [(ldap.MOD_REPLACE,
|
|
|
232633 |
+ 'nsslapd-dynamic-plugins',
|
|
|
232633 |
+ b'on')])
|
|
|
232633 |
+ except ldap.LDAPError as e:
|
|
|
232633 |
+ ldap.error('Failed to enable dynamic plugins! ' + e.message['desc'])
|
|
|
232633 |
+ assert False
|
|
|
232633 |
+
|
|
|
232633 |
+ #topology_st.standalone.plugins.enable(name=PLUGIN_MEMBER_OF)
|
|
|
232633 |
+ inst.plugins.enable(name=PLUGIN_RETRO_CHANGELOG)
|
|
|
232633 |
+ #topology_st.standalone.modify_s("cn=changelog,cn=ldbm database,cn=plugins,cn=config", [(ldap.MOD_REPLACE, 'nsslapd-cachememsize', str(100000))])
|
|
|
232633 |
+ inst.restart()
|
|
|
232633 |
+
|
|
|
232633 |
+ log.info('create users and group...')
|
|
|
232633 |
+ for idx in range(1, MAX_USERS):
|
|
|
232633 |
+ try:
|
|
|
232633 |
+ USER_DN = ("uid=member%d,%s" % (idx, PEOPLE_DN))
|
|
|
232633 |
+ inst.add_s(Entry((USER_DN,
|
|
|
232633 |
+ {'objectclass': 'top extensibleObject'.split(),
|
|
|
232633 |
+ 'uid': 'member%d' % (idx)})))
|
|
|
232633 |
+ except ldap.LDAPError as e:
|
|
|
232633 |
+ log.fatal('Failed to add user (%s): error %s' % (USER_DN, e.message['desc']))
|
|
|
232633 |
+ assert False
|
|
|
232633 |
+
|
|
|
232633 |
+ # Check default is that unhashed#user#password is not logged
|
|
|
232633 |
+ user = "uid=member1,%s" % (PEOPLE_DN)
|
|
|
232633 |
+ inst.modify_s(user, [(ldap.MOD_REPLACE,
|
|
|
232633 |
+ 'userpassword',
|
|
|
232633 |
+ PASSWORD.encode())])
|
|
|
232633 |
+ inst.stop()
|
|
|
232633 |
+ _check_unhashed_userpw(inst, user, is_present=False)
|
|
|
232633 |
+
|
|
|
232633 |
+ # Check with nolog that unhashed#user#password is not logged
|
|
|
232633 |
+ inst.modify_s(DN_CONFIG,
|
|
|
232633 |
+ [(ldap.MOD_REPLACE,
|
|
|
232633 |
+ 'nsslapd-unhashed-pw-switch',
|
|
|
232633 |
+ b'nolog')])
|
|
|
232633 |
+ inst.restart()
|
|
|
232633 |
+ user = "uid=member2,%s" % (PEOPLE_DN)
|
|
|
232633 |
+ inst.modify_s(user, [(ldap.MOD_REPLACE,
|
|
|
232633 |
+ 'userpassword',
|
|
|
232633 |
+ PASSWORD.encode())])
|
|
|
232633 |
+ inst.stop()
|
|
|
232633 |
+ _check_unhashed_userpw(inst, user, is_present=False)
|
|
|
232633 |
+
|
|
|
232633 |
+ # Check with value 'on' that unhashed#user#password is logged
|
|
|
232633 |
+ inst.modify_s(DN_CONFIG,
|
|
|
232633 |
+ [(ldap.MOD_REPLACE,
|
|
|
232633 |
+ 'nsslapd-unhashed-pw-switch',
|
|
|
232633 |
+ b'on')])
|
|
|
232633 |
+ inst.restart()
|
|
|
232633 |
+ user = "uid=member3,%s" % (PEOPLE_DN)
|
|
|
232633 |
+ inst.modify_s(user, [(ldap.MOD_REPLACE,
|
|
|
232633 |
+ 'userpassword',
|
|
|
232633 |
+ PASSWORD.encode())])
|
|
|
232633 |
+ inst.stop()
|
|
|
232633 |
+ _check_unhashed_userpw(inst, user, is_present=True)
|
|
|
232633 |
+
|
|
|
232633 |
+ if DEBUGGING:
|
|
|
232633 |
+ # Add debugging steps(if any)...
|
|
|
232633 |
+ pass
|
|
|
232633 |
+
|
|
|
232633 |
|
|
|
232633 |
if __name__ == '__main__':
|
|
|
232633 |
# Run isolated
|
|
|
232633 |
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
|
|
|
232633 |
index b3ede6f7c..a1b68b7b6 100644
|
|
|
232633 |
--- a/ldap/servers/slapd/slap.h
|
|
|
232633 |
+++ b/ldap/servers/slapd/slap.h
|
|
|
232633 |
@@ -295,8 +295,8 @@ typedef void (*VFPV)(); /* takes undefined arguments */
|
|
|
232633 |
#define SLAPD_DEFAULT_VALIDATE_CERT SLAPD_VALIDATE_CERT_WARN
|
|
|
232633 |
#define SLAPD_DEFAULT_VALIDATE_CERT_STR "warn"
|
|
|
232633 |
|
|
|
232633 |
-#define SLAPD_DEFAULT_UNHASHED_PW_SWITCH SLAPD_UNHASHED_PW_ON
|
|
|
232633 |
-#define SLAPD_DEFAULT_UNHASHED_PW_SWITCH_STR "on"
|
|
|
232633 |
+#define SLAPD_DEFAULT_UNHASHED_PW_SWITCH SLAPD_UNHASHED_PW_OFF
|
|
|
232633 |
+#define SLAPD_DEFAULT_UNHASHED_PW_SWITCH_STR "off"
|
|
|
232633 |
|
|
|
232633 |
#define SLAPD_DEFAULT_LDAPI_SEARCH_BASE "dc=example,dc=com"
|
|
|
232633 |
#define SLAPD_DEFAULT_LDAPI_AUTO_DN "cn=peercred,cn=external,cn=auth"
|
|
|
232633 |
--
|
|
|
232633 |
2.21.0
|
|
|
232633 |
|