74ca47
From 5854fc41c6620567f0356e382baec4eda1e645b2 Mon Sep 17 00:00:00 2001
74ca47
From: Mark Reynolds <mreynolds@redhat.com>
74ca47
Date: Wed, 5 Apr 2017 11:05:28 -0400
74ca47
Subject: [PATCH] Issue 49210 - Fix regression when checking is password min 
74ca47
 age should be checked
74ca47
74ca47
Bug Description:  If a plugin makes an internal modification of userpassword
74ca47
                  the connection structure in the pblock is null, and it was
74ca47
                  being dereferenced.
74ca47
74ca47
Fix Description:  These internal operations do not need to have the password
74ca47
                  policy checks done.  They are intended to be unrestricted.
74ca47
                  So we only need to check password policy on client connections.
74ca47
                  The fix frist hecks if the connection structy is present,
74ca47
                  only then it continues.
74ca47
74ca47
                  Revised test script to include the tool: ldappasswd
74ca47
74ca47
https://pagure.io/389-ds-base/issue/49210
74ca47
74ca47
Reviewed by: firstyear(Thanks!)
74ca47
---
74ca47
 dirsrvtests/tests/tickets/ticket49039_test.py | 62 +++++++++++++++++++++++++++
74ca47
 ldap/servers/slapd/modify.c                   |  2 +-
74ca47
 2 files changed, 63 insertions(+), 1 deletion(-)
74ca47
74ca47
diff --git a/dirsrvtests/tests/tickets/ticket49039_test.py b/dirsrvtests/tests/tickets/ticket49039_test.py
74ca47
index e6d4c03..f0b224c 100644
74ca47
--- a/dirsrvtests/tests/tickets/ticket49039_test.py
74ca47
+++ b/dirsrvtests/tests/tickets/ticket49039_test.py
74ca47
@@ -2,6 +2,7 @@ import time
74ca47
 import ldap
74ca47
 import logging
74ca47
 import pytest
74ca47
+import os
74ca47
 from lib389 import Entry
74ca47
 from lib389._constants import *
74ca47
 from lib389.properties import *
74ca47
@@ -9,6 +10,7 @@ from lib389.tasks import *
74ca47
 from lib389.utils import *
74ca47
 from lib389.topologies import topology_st as topo
74ca47
 
74ca47
+
74ca47
 DEBUGGING = os.getenv("DEBUGGING", default=False)
74ca47
 if DEBUGGING:
74ca47
     logging.getLogger(__name__).setLevel(logging.DEBUG)
74ca47
@@ -19,11 +21,39 @@ log = logging.getLogger(__name__)
74ca47
 USER_DN = 'uid=user,dc=example,dc=com'
74ca47
 
74ca47
 
74ca47
+def ssl_init(topo):
74ca47
+    """ Setup TLS
74ca47
+    """
74ca47
+    topo.standalone.stop()
74ca47
+    # Prepare SSL but don't enable it.
74ca47
+    for f in ('key3.db', 'cert8.db', 'key4.db', 'cert9.db', 'secmod.db', 'pkcs11.txt'):
74ca47
+        try:
74ca47
+            os.remove("%s/%s" % (topo.standalone.confdir, f))
74ca47
+        except:
74ca47
+            pass
74ca47
+    assert(topo.standalone.nss_ssl.reinit() is True)
74ca47
+    assert(topo.standalone.nss_ssl.create_rsa_ca() is True)
74ca47
+    assert(topo.standalone.nss_ssl.create_rsa_key_and_cert() is True)
74ca47
+    # Start again
74ca47
+    topo.standalone.start()
74ca47
+    topo.standalone.rsa.create()
74ca47
+    topo.standalone.config.set('nsslapd-ssl-check-hostname', 'off')
74ca47
+    topo.standalone.config.set('nsslapd-secureport', '%s' %
74ca47
+                               SECUREPORT_STANDALONE1)
74ca47
+    topo.standalone.config.set('nsslapd-security', 'on')
74ca47
+    topo.standalone.restart()
74ca47
+
74ca47
+    log.info("SSL setup complete\n")
74ca47
+
74ca47
+
74ca47
 def test_ticket49039(topo):
74ca47
     """Test "password must change" verses "password min age".  Min age should not
74ca47
     block password update if the password was reset.
74ca47
     """
74ca47
 
74ca47
+    # Setup SSL (for ldappasswd test)
74ca47
+    ssl_init(topo)
74ca47
+
74ca47
     # Configure password policy
74ca47
     try:
74ca47
         topo.standalone.modify_s("cn=config", [(ldap.MOD_REPLACE, 'nsslapd-pwpolicy-local', 'on'),
74ca47
@@ -68,6 +98,38 @@ def test_ticket49039(topo):
74ca47
         log.fatal('Failed to change password: error ' + e.message['desc'])
74ca47
         assert False
74ca47
 
74ca47
+    ###################################
74ca47
+    # Make sure ldappasswd also works
74ca47
+    ###################################
74ca47
+
74ca47
+    # Reset password as RootDN
74ca47
+    try:
74ca47
+        topo.standalone.simple_bind_s(DN_DM, PASSWORD)
74ca47
+    except ldap.LDAPError as e:
74ca47
+        log.fatal('Failed to bind as rootdn: error ' + e.message['desc'])
74ca47
+        assert False
74ca47
+
74ca47
+    try:
74ca47
+        topo.standalone.modify_s(USER_DN, [(ldap.MOD_REPLACE, 'userpassword', PASSWORD)])
74ca47
+    except ldap.LDAPError as e:
74ca47
+        log.fatal('Failed to bind: error ' + e.message['desc'])
74ca47
+        assert False
74ca47
+
74ca47
+    time.sleep(1)
74ca47
+
74ca47
+    # Run ldappasswd as the User.
74ca47
+    cmd = ('LDAPTLS_REQCERT=never LDAPTLS_CACERTDIR=' + topo.standalone.get_cert_dir() +
74ca47
+           ' ldappasswd' + ' -h ' + topo.standalone.host + ' -Z -p 38901 -D ' + USER_DN +
74ca47
+           ' -w password -a password -s password2 ' + USER_DN)
74ca47
+    os.system(cmd)
74ca47
+    time.sleep(1)
74ca47
+
74ca47
+    try:
74ca47
+        topo.standalone.simple_bind_s(USER_DN, "password2")
74ca47
+    except ldap.LDAPError as e:
74ca47
+        log.fatal('Failed to bind: error ' + e.message['desc'])
74ca47
+        assert False
74ca47
+
74ca47
     log.info('Test Passed')
74ca47
 
74ca47
 
74ca47
diff --git a/ldap/servers/slapd/modify.c b/ldap/servers/slapd/modify.c
74ca47
index 32defae..e23fe67 100644
74ca47
--- a/ldap/servers/slapd/modify.c
74ca47
+++ b/ldap/servers/slapd/modify.c
74ca47
@@ -1326,7 +1326,7 @@ static int op_shared_allow_pw_change (Slapi_PBlock *pb, LDAPMod *mod, char **old
74ca47
 	       
74ca47
 	/* check if password is within password minimum age;
74ca47
 	   error result is sent directly from check_pw_minage */	
74ca47
-	if (!pb->pb_conn->c_needpw &&
74ca47
+	if (pb->pb_conn && !pb->pb_conn->c_needpw &&
74ca47
 	    check_pw_minage(pb, &sdn, mod->mod_bvalues) == 1)
74ca47
 	{
74ca47
 		if (operation_is_flag_set(operation,OP_FLAG_ACTION_LOG_ACCESS))
74ca47
-- 
74ca47
2.9.3
74ca47