Blame SOURCES/0035-Ticket-48956-ns-accountstatus.pl-showing-activated-u.patch

7c7f29
From 3d1a6717b4b8c11dda68dd3d1a923acb2e6c5eeb Mon Sep 17 00:00:00 2001
7c7f29
From: Thierry Bordaz <tbordaz@redhat.com>
7c7f29
Date: Wed, 17 Aug 2016 16:46:47 +0200
7c7f29
Subject: [PATCH 35/35] Ticket 48956 ns-accountstatus.pl showing "activated"
7c7f29
 user even if it is inactivated
7c7f29
7c7f29
Bug Description:
7c7f29
    If the account policy DN is long (suffix is long), it is fold on several lines.
7c7f29
    So when looking for it, the base DN is invalid and fail to retrieve it and the limit value.
7c7f29
7c7f29
Fix Description:
7c7f29
    Change the DSutil search to be in no fold
7c7f29
7c7f29
https://fedorahosted.org/389/ticket/48956
7c7f29
7c7f29
Reviewed by: Noriko Hosoi (Thanks Noriko)
7c7f29
7c7f29
Platforms tested: F23
7c7f29
7c7f29
Flag Day: no
7c7f29
7c7f29
Doc impact: no
7c7f29
7c7f29
(cherry picked from commit 3cce9f9188a38e1a5043c9659ecbc5955ddb0242)
7c7f29
---
7c7f29
 dirsrvtests/tests/tickets/ticket48956_test.py | 167 ++++++++++++++++++++++++++
7c7f29
 ldap/admin/src/scripts/DSUtil.pm.in           |  34 +++---
7c7f29
 2 files changed, 185 insertions(+), 16 deletions(-)
7c7f29
 create mode 100644 dirsrvtests/tests/tickets/ticket48956_test.py
7c7f29
7c7f29
diff --git a/dirsrvtests/tests/tickets/ticket48956_test.py b/dirsrvtests/tests/tickets/ticket48956_test.py
7c7f29
new file mode 100644
7c7f29
index 0000000..291dd4e
7c7f29
--- /dev/null
7c7f29
+++ b/dirsrvtests/tests/tickets/ticket48956_test.py
7c7f29
@@ -0,0 +1,167 @@
7c7f29
+import os
7c7f29
+import sys
7c7f29
+import time
7c7f29
+import ldap
7c7f29
+import logging
7c7f29
+import pytest
7c7f29
+import subprocess
7c7f29
+from lib389 import DirSrv, Entry, tools, tasks
7c7f29
+from lib389.tools import DirSrvTools
7c7f29
+from lib389._constants import *
7c7f29
+from lib389.properties import *
7c7f29
+from lib389.tasks import *
7c7f29
+from lib389.utils import *
7c7f29
+
7c7f29
+
7c7f29
+DEBUGGING = False
7c7f29
+
7c7f29
+RDN_LONG_SUFFIX = 'this'
7c7f29
+LONG_SUFFIX = "dc=%s,dc=is,dc=a,dc=very,dc=long,dc=suffix,dc=so,dc=long,dc=suffix,dc=extremely,dc=long,dc=suffix" % RDN_LONG_SUFFIX
7c7f29
+LONG_SUFFIX_BE = 'ticket48956'
7c7f29
+
7c7f29
+
7c7f29
+ACCT_POLICY_PLUGIN_DN = 'cn=%s,cn=plugins,cn=config' % PLUGIN_ACCT_POLICY
7c7f29
+ACCT_POLICY_CONFIG_DN = 'cn=config,%s' % ACCT_POLICY_PLUGIN_DN
7c7f29
+
7c7f29
+
7c7f29
+INACTIVITY_LIMIT = '9'
7c7f29
+SEARCHFILTER = '(objectclass=*)'
7c7f29
+
7c7f29
+TEST_USER = 'ticket48956user'
7c7f29
+TEST_USER_PW = '%s' % TEST_USER
7c7f29
+
7c7f29
+if DEBUGGING:
7c7f29
+    logging.getLogger(__name__).setLevel(logging.DEBUG)
7c7f29
+else:
7c7f29
+    logging.getLogger(__name__).setLevel(logging.INFO)
7c7f29
+log = logging.getLogger(__name__)
7c7f29
+
7c7f29
+
7c7f29
+class TopologyStandalone(object):
7c7f29
+    """The DS Topology Class"""
7c7f29
+    def __init__(self, standalone):
7c7f29
+        """Init"""
7c7f29
+        standalone.open()
7c7f29
+        self.standalone = standalone
7c7f29
+
7c7f29
+
7c7f29
+@pytest.fixture(scope="module")
7c7f29
+def topology(request):
7c7f29
+    """Create DS Deployment"""
7c7f29
+
7c7f29
+    # Creating standalone instance ...
7c7f29
+    if DEBUGGING:
7c7f29
+        standalone = DirSrv(verbose=True)
7c7f29
+    else:
7c7f29
+        standalone = DirSrv(verbose=False)
7c7f29
+    args_instance[SER_HOST] = HOST_STANDALONE
7c7f29
+    args_instance[SER_PORT] = PORT_STANDALONE
7c7f29
+    args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE
7c7f29
+    args_instance[SER_CREATION_SUFFIX] = DEFAULT_SUFFIX
7c7f29
+    args_standalone = args_instance.copy()
7c7f29
+    standalone.allocate(args_standalone)
7c7f29
+    instance_standalone = standalone.exists()
7c7f29
+    if instance_standalone:
7c7f29
+        standalone.delete()
7c7f29
+    standalone.create()
7c7f29
+    standalone.open()
7c7f29
+
7c7f29
+    def fin():
7c7f29
+        """If we are debugging just stop the instances, otherwise remove them
7c7f29
+        """
7c7f29
+        if DEBUGGING:
7c7f29
+            standalone.stop()
7c7f29
+        else:
7c7f29
+            standalone.delete()
7c7f29
+    request.addfinalizer(fin)
7c7f29
+
7c7f29
+    return TopologyStandalone(standalone)
7c7f29
+
7c7f29
+def _check_status(topology, user, expected):
7c7f29
+    nsaccountstatus = '%s/sbin/ns-accountstatus.pl' % topology.standalone.prefix
7c7f29
+    proc = subprocess.Popen([nsaccountstatus, '-Z', 'standalone', '-D', DN_DM, '-w', PASSWORD, '-p', str(topology.standalone.port), '-I', user], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
7c7f29
+
7c7f29
+    found = False
7c7f29
+    while True:
7c7f29
+        l = proc.stdout.readline()
7c7f29
+        log.info("output: %s" % l)
7c7f29
+        if l == "":
7c7f29
+            break
7c7f29
+        if expected in l:
7c7f29
+            found = True
7c7f29
+            break
7c7f29
+    return found
7c7f29
+
7c7f29
+def _check_inactivity(topology, mysuffix):
7c7f29
+    ACCT_POLICY_DN = 'cn=Account Inactivation Policy,%s' % mysuffix
7c7f29
+    log.info("\n######################### Adding Account Policy entry: %s ######################\n" % ACCT_POLICY_DN)
7c7f29
+    topology.standalone.add_s(Entry((ACCT_POLICY_DN, {'objectclass': "top ldapsubentry extensibleObject accountpolicy".split(),
7c7f29
+                                                      'accountInactivityLimit': INACTIVITY_LIMIT})))
7c7f29
+    TEST_USER_DN = 'uid=%s,%s' % (TEST_USER, mysuffix)
7c7f29
+    log.info("\n######################### Adding Test User entry: %s ######################\n" % TEST_USER_DN)
7c7f29
+    topology.standalone.add_s(Entry((TEST_USER_DN, {'objectclass': "top person organizationalPerson inetOrgPerson".split(),
7c7f29
+                                                    'cn': TEST_USER,
7c7f29
+                                                    'sn': TEST_USER,
7c7f29
+                                                    'givenname': TEST_USER,
7c7f29
+                                                    'userPassword': TEST_USER_PW,
7c7f29
+                                                    'acctPolicySubentry': ACCT_POLICY_DN})))
7c7f29
+
7c7f29
+    # Setting the lastLoginTime
7c7f29
+    try:
7c7f29
+        topology.standalone.simple_bind_s(TEST_USER_DN, TEST_USER_PW)
7c7f29
+    except ldap.CONSTRAINT_VIOLATION as e:
7c7f29
+        log.error('CONSTRAINT VIOLATION ' + e.message['desc'])
7c7f29
+    topology.standalone.simple_bind_s(DN_DM, PASSWORD)
7c7f29
+
7c7f29
+
7c7f29
+    assert(_check_status(topology, TEST_USER_DN, '- activated'))
7c7f29
+
7c7f29
+    time.sleep(int(INACTIVITY_LIMIT) + 5)
7c7f29
+    assert(_check_status(topology, TEST_USER_DN, '- inactivated (inactivity limit exceeded'))
7c7f29
+
7c7f29
+def test_ticket48956(topology):
7c7f29
+    """Write your testcase here...
7c7f29
+
7c7f29
+    Also, if you need any testcase initialization,
7c7f29
+    please, write additional fixture for that(include finalizer).
7c7f29
+
7c7f29
+    """
7c7f29
+
7c7f29
+    topology.standalone.modify_s(ACCT_POLICY_PLUGIN_DN, [(ldap.MOD_REPLACE, 'nsslapd-pluginarg0', ACCT_POLICY_CONFIG_DN)])
7c7f29
+
7c7f29
+    topology.standalone.modify_s(ACCT_POLICY_CONFIG_DN, [(ldap.MOD_REPLACE, 'alwaysrecordlogin', 'yes'),
7c7f29
+                                                         (ldap.MOD_REPLACE, 'stateattrname', 'lastLoginTime'),
7c7f29
+                                                         (ldap.MOD_REPLACE, 'altstateattrname', 'createTimestamp'),
7c7f29
+                                                         (ldap.MOD_REPLACE, 'specattrname', 'acctPolicySubentry'),
7c7f29
+                                                         (ldap.MOD_REPLACE, 'limitattrname', 'accountInactivityLimit')])
7c7f29
+
7c7f29
+    # Enable the plugins
7c7f29
+    topology.standalone.plugins.enable(name=PLUGIN_ACCT_POLICY)
7c7f29
+
7c7f29
+    topology.standalone.restart(timeout=10)
7c7f29
+
7c7f29
+    # Check inactivity on standard suffix (short)
7c7f29
+    _check_inactivity(topology, SUFFIX)
7c7f29
+
7c7f29
+    # Check inactivity on a long suffix
7c7f29
+    topology.standalone.backend.create(LONG_SUFFIX, {BACKEND_NAME: LONG_SUFFIX_BE})
7c7f29
+    topology.standalone.mappingtree.create(LONG_SUFFIX, bename=LONG_SUFFIX_BE)
7c7f29
+    topology.standalone.add_s(Entry((LONG_SUFFIX, {
7c7f29
+                                            'objectclass': "top domain".split(),
7c7f29
+                                            'dc': RDN_LONG_SUFFIX})))
7c7f29
+    _check_inactivity(topology, LONG_SUFFIX)
7c7f29
+
7c7f29
+
7c7f29
+    if DEBUGGING:
7c7f29
+        # Add debugging steps(if any)...
7c7f29
+        pass
7c7f29
+
7c7f29
+    log.info('Test PASSED')
7c7f29
+
7c7f29
+
7c7f29
+if __name__ == '__main__':
7c7f29
+    # Run isolated
7c7f29
+    # -s for DEBUG mode
7c7f29
+    CURRENT_FILE = os.path.realpath(__file__)
7c7f29
+    pytest.main("-s %s" % CURRENT_FILE)
7c7f29
+
7c7f29
diff --git a/ldap/admin/src/scripts/DSUtil.pm.in b/ldap/admin/src/scripts/DSUtil.pm.in
7c7f29
index f53f0c0..756d6ea 100644
7c7f29
--- a/ldap/admin/src/scripts/DSUtil.pm.in
7c7f29
+++ b/ldap/admin/src/scripts/DSUtil.pm.in
7c7f29
@@ -1201,8 +1201,10 @@ sub get_info {
7c7f29
     my $toollib = `ldapsearch -V 2>&1;;
7c7f29
     if ($toollib =~ /OpenLDAP/) { 
7c7f29
         $info{openldap} = "yes";
7c7f29
+        $info{nofold} = "-o ldif-wrap=no";
7c7f29
     } else {
7c7f29
         $info{openldap} = "no";
7c7f29
+        $info{nofold} = "-T";
7c7f29
     }
7c7f29
     
7c7f29
     #
7c7f29
@@ -1537,10 +1539,10 @@ sub ldapsrch {
7c7f29
             print "STARTTLS)\n";
7c7f29
         }
7c7f29
         if($info{openldap} eq "yes"){
7c7f29
-            $search = "ldapsearch -x -LLL -ZZ -p $info{port} -h $info{host} -D \"$info{rootdn}\" -w $myrootdnpw " .
7c7f29
+            $search = "ldapsearch -x -LLL -ZZ -p $info{port} -h $info{host} -D \"$info{rootdn}\" -w $myrootdnpw $info{nofold} " .
7c7f29
                       "$info{srch_args} -b \"$info{base}\" -s $info{scope} \"$info{filter}\" $info{attrs}";
7c7f29
         } else {
7c7f29
-            $search = "ldapsearch -ZZZ -P \"$info{certdir}\" -p $info{port} -h $info{host} -D \"$info{rootdn}\" " .
7c7f29
+            $search = "ldapsearch -ZZZ -P \"$info{certdir}\" -p $info{port} -h $info{host} -D \"$info{rootdn}\" $info{nofold} " .
7c7f29
                       "-w $myrootdnpw $info{srch_args} -b \"$info{base}\" -s $info{scope} \"$info{filter}\" $info{attrs}";
7c7f29
         }  
7c7f29
     } elsif (($info{security} eq "on" && $info{protocol} eq "") || ($info{security} eq "on" && $info{protocol} =~ m/LDAPS/i) ){ 
7c7f29
@@ -1551,10 +1553,10 @@ sub ldapsrch {
7c7f29
             print "LDAPS)\n";
7c7f29
         }
7c7f29
         if($info{openldap} eq "yes"){
7c7f29
-            $search = "ldapsearch -x -LLL -H \"ldaps://$info{host}:$info{secure_port}\" -D \"$info{rootdn}\" " .
7c7f29
+            $search = "ldapsearch -x -LLL -H \"ldaps://$info{host}:$info{secure_port}\" -D \"$info{rootdn}\" $info{nofold} " .
7c7f29
                       "-w $myrootdnpw $info{srch_args} -b \"$info{base}\" -s $info{scope} \"$info{filter}\" $info{attrs}";
7c7f29
         } else {
7c7f29
-            $search = "ldapsearch -Z -P \"$info{certdir}\" -p $info{secure_port} -h $info{host} -D \"$info{rootdn}\" " .
7c7f29
+            $search = "ldapsearch -Z -P \"$info{certdir}\" -p $info{secure_port} -h $info{host} -D \"$info{rootdn}\" $info{nofold} " .
7c7f29
                       "-w $myrootdnpw $info{srch_args} -b \"$info{base}\" -s $info{scope} \"$info{filter}\" $info{attrs}";
7c7f29
         } 
7c7f29
     } elsif (($info{openldap} eq "yes") && (($info{ldapi} eq "on" && $info{protocol} eq "") || ($info{ldapi} eq "on" && $info{protocol} =~ m/LDAPI/i)) ){  
7c7f29
@@ -1562,10 +1564,10 @@ sub ldapsrch {
7c7f29
         # LDAPI
7c7f29
         #
7c7f29
         if ($< == 0 && $info{autobind} eq "on"){
7c7f29
-            $search = "ldapsearch  -LLL -H \"$info{ldapiURL}\" -Y EXTERNAL " .
7c7f29
+            $search = "ldapsearch  -LLL -H \"$info{ldapiURL}\" -Y EXTERNAL $info{nofold} " .
7c7f29
                   "$info{srch_args} -b \"$info{base}\" -s $info{scope} \"$info{filter}\" $info{attrs} 2>/dev/null";
7c7f29
         } else {
7c7f29
-            $search = "ldapsearch -x -LLL -H \"$info{ldapiURL}\" -D \"$info{rootdn}\" -w $myrootdnpw " .
7c7f29
+            $search = "ldapsearch -x -LLL -H \"$info{ldapiURL}\" -D \"$info{rootdn}\" -w $myrootdnpw $info{nofold} " .
7c7f29
                   "$info{srch_args} -b \"$info{base}\" -s $info{scope} \"$info{filter}\" $info{attrs}";
7c7f29
         }
7c7f29
     } else {
7c7f29
@@ -1576,10 +1578,10 @@ sub ldapsrch {
7c7f29
             print "LDAP)\n";
7c7f29
         }
7c7f29
         if($info{openldap} eq "yes"){
7c7f29
-            $search = "ldapsearch -x -LLL -p $info{port} -h $info{host} -D \"$info{rootdn}\" -w $myrootdnpw " .
7c7f29
+            $search = "ldapsearch -x -LLL -p $info{port} -h $info{host} -D \"$info{rootdn}\" -w $myrootdnpw $info{nofold} " .
7c7f29
                   "$info{srch_args} -b \"$info{base}\" -s $info{scope} \"$info{filter}\" $info{attrs}";
7c7f29
         } else {
7c7f29
-            $search = "ldapsearch -p $info{port} -h $info{host} -D \"$info{rootdn}\" -w $myrootdnpw " .
7c7f29
+            $search = "ldapsearch -p $info{port} -h $info{host} -D \"$info{rootdn}\" -w $myrootdnpw $info{nofold} " .
7c7f29
                   "$info{srch_args} -b \"$info{base}\" -s $info{scope} \"$info{filter}\" $info{attrs}";
7c7f29
         }
7c7f29
     }
7c7f29
@@ -1611,9 +1613,9 @@ sub ldapsrch_ext {
7c7f29
             print "STARTTLS)\n";
7c7f29
         }
7c7f29
         if($info{openldap} eq "yes"){
7c7f29
-            return `ldapsearch -x -LLL -ZZ -p $info{port} -h $info{host} -D \"$info{rootdn}\" -w $myrootdnpw $info{srch_args} -b \"$info{base}\" -s $info{scope} \"$info{filter}\" $info{attrs} $info{redirect}`;
7c7f29
+            return `ldapsearch -x -LLL -ZZ -p $info{port} -h $info{host} -D \"$info{rootdn}\" -w $myrootdnpw $info{nofold} $info{srch_args} -b \"$info{base}\" -s $info{scope} \"$info{filter}\" $info{attrs} $info{redirect}`;
7c7f29
         } else {
7c7f29
-            return `ldapsearch -ZZZ -P $info{certdir} -p $info{port} -h $info{host} -D \"$info{rootdn}\" -w $myrootdnpw $info{srch_args} -b \"$info{base}\" -s $info{scope} \"$info{filter}\" $info{attrs} $info{redirect}`;
7c7f29
+            return `ldapsearch -ZZZ -P $info{certdir} -p $info{port} -h $info{host} -D \"$info{rootdn}\" -w $myrootdnpw $info{nofold} $info{srch_args} -b \"$info{base}\" -s $info{scope} \"$info{filter}\" $info{attrs} $info{redirect}`;
7c7f29
         }     
7c7f29
     } elsif (($info{security} eq "on" && $info{protocol} eq "") || ($info{security} eq "on" && $info{protocol} =~ m/LDAPS/i) ){ 
7c7f29
         # 
7c7f29
@@ -1623,18 +1625,18 @@ sub ldapsrch_ext {
7c7f29
             print "LDAPS)\n";
7c7f29
         }
7c7f29
         if($info{openldap} eq "yes"){
7c7f29
-            return `ldapsearch -x -LLL -H ldaps://$info{host}:$info{secure_port} -D \"$info{rootdn}\" -w $myrootdnpw $info{srch_args} -b \"$info{base}\" -s $info{scope} \"$info{filter}\" $info{attrs} $info{redirect}`;
7c7f29
+            return `ldapsearch -x -LLL -H ldaps://$info{host}:$info{secure_port} -D \"$info{rootdn}\" -w $myrootdnpw $info{nofold} $info{srch_args}  -b \"$info{base}\" -s $info{scope} \"$info{filter}\" $info{attrs} $info{redirect}`;
7c7f29
         } else {
7c7f29
-            return `ldapsearch -Z -P $info{certdir} -p $info{secure_port} -D \"$info{rootdn}\" -w $myrootdnpw $info{srch_args} -b \"$info{base}\" -s $info{scope} \"$info{filter}\" $info{attrs} $info{redirect}`;
7c7f29
+            return `ldapsearch -Z -P $info{certdir} -p $info{secure_port} -D \"$info{rootdn}\" -w $myrootdnpw $info{nofold} $info{srch_args} -b \"$info{base}\" -s $info{scope} \"$info{filter}\" $info{attrs} $info{redirect}`;
7c7f29
         }
7c7f29
     } elsif (($info{openldap} eq "yes") && (($info{ldapi} eq "on" && $info{protocol} eq "") || ($info{ldapi} eq "on" && $info{protocol} =~ m/LDAPI/i)) ){  
7c7f29
         # 
7c7f29
         # LDAPI
7c7f29
         #
7c7f29
         if ($< == 0 && $info{autobind} eq "on"){
7c7f29
-            return `ldapsearch -LLL -H \"$info{ldapiURL}\" -Y EXTERNAL $info{srch_args} -b \"$info{base}\" -s $info{scope} \"$info{filter}\" $info{attrs} $info{redirect} 2>/dev/null`;
7c7f29
+            return `ldapsearch -LLL -H \"$info{ldapiURL}\" -Y EXTERNAL $info{nofold} $info{srch_args} -b \"$info{base}\" -s $info{scope} \"$info{filter}\" $info{attrs} $info{redirect} 2>/dev/null`;
7c7f29
         } else {
7c7f29
-            return `ldapsearch -x -LLL -H \"$info{ldapiURL}\" -D \"$info{rootdn}\" -w $myrootdnpw $info{srch_args} -b \"$info{base}\" -s $info{scope} \"$info{filter}\" $info{attrs} $info{redirect}`;
7c7f29
+            return `ldapsearch -x -LLL -H \"$info{ldapiURL}\" -D \"$info{rootdn}\" -w $myrootdnpw $info{nofold} $info{srch_args} -b \"$info{base}\" -s $info{scope} \"$info{filter}\" $info{attrs} $info{redirect}`;
7c7f29
         }
7c7f29
     } else {
7c7f29
         # 
7c7f29
@@ -1644,9 +1646,9 @@ sub ldapsrch_ext {
7c7f29
             print "LDAP)\n";
7c7f29
         }
7c7f29
         if($info{openldap} eq "yes"){
7c7f29
-            return `ldapsearch -x -LLL -p $info{port} -h $info{host} -D \"$info{rootdn}\" -w $myrootdnpw $info{srch_args} -b \"$info{base}\" -s $info{scope} \"$info{filter}\" $info{attrs} $info{redirect}`;
7c7f29
+            return `ldapsearch -x -LLL -p $info{port} -h $info{host} -D \"$info{rootdn}\" -w $myrootdnpw $info{nofold} $info{srch_args} -b \"$info{base}\" -s $info{scope} \"$info{filter}\" $info{attrs} $info{redirect}`;
7c7f29
         } else {
7c7f29
-            return `ldapsearch -p $info{port} -h $info{host} -D \"$info{rootdn}\" -w $myrootdnpw $info{srch_args} -b \"$info{base}\" -s $info{scope} \"$info{filter}\" $info{attrs} $info{redirect}`;
7c7f29
+            return `ldapsearch -p $info{port} -h $info{host} -D \"$info{rootdn}\" -w $myrootdnpw $info{nofold} $info{srch_args} -b \"$info{base}\" -s $info{scope} \"$info{filter}\" $info{attrs} $info{redirect}`;
7c7f29
         }
7c7f29
     }
7c7f29
 }
7c7f29
-- 
7c7f29
2.4.11
7c7f29