]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
samba-tool: Optionally hide disabled/expired accounts in "user list"
authorBjörn Baumbach <bb@sernet.de>
Wed, 23 Dec 2020 12:00:34 +0000 (13:00 +0100)
committerVolker Lendecke <vl@samba.org>
Fri, 15 Jan 2021 15:24:37 +0000 (15:24 +0000)
  --hide-expired        Do not list expired user accounts
  --hide-disabled       Do not list disabled user accounts

Signed-off-by: Björn Baumbach <bb@sernet.de>
Reviewed-by: Volker Lendecke <vl@samba.org>
docs-xml/manpages/samba-tool.8.xml
python/samba/netcmd/user.py
python/samba/samdb.py
python/samba/tests/samba_tool/user.py

index de3a9e3ac26352d061aa4cf7d96cd2acd0047be7..5ab8cd916182a0a35a25d7f07823ee4dc7387698 100644 (file)
        listed.
        </para></listitem>
        </varlistentry>
+       <varlistentry>
+       <term>--hide-expired</term>
+       <listitem><para>
+       Do not list expired user accounts.
+       </para></listitem>
+       </varlistentry>
+       <varlistentry>
+       <term>--hide-disabled</term>
+       <listitem><para>
+       Do not list disabled user accounts.
+       </para></listitem>
+       </varlistentry>
        </variablelist>
 </refsect3>
 
index 7e8204462d1d27d98715c90f5537c1aaefaada36..bbfa7e989dd2fd7088e2d7db15d52067ee9e465c 100644 (file)
@@ -466,6 +466,14 @@ class cmd_user_list(Command):
     takes_options = [
         Option("-H", "--URL", help="LDB URL for database or target server", type=str,
                metavar="URL", dest="H"),
+        Option("--hide-expired",
+               help="Do not list expired user accounts",
+               default=False,
+               action='store_true'),
+        Option("--hide-disabled",
+               default=False,
+               action='store_true',
+               help="Do not list disabled user accounts"),
         Option("-b", "--base-dn",
                help="Specify base DN to use",
                type=str),
@@ -486,6 +494,8 @@ class cmd_user_list(Command):
             credopts=None,
             versionopts=None,
             H=None,
+            hide_expired=False,
+            hide_disabled=False,
             base_dn=None,
             full_dn=False):
         lp = sambaopts.get_loadparm()
@@ -498,10 +508,26 @@ class cmd_user_list(Command):
         if base_dn:
             search_dn = samdb.normalize_dn_in_domain(base_dn)
 
+        filter_expires = ""
+        if hide_expired is True:
+            current_nttime = samdb.get_nttime()
+            filter_expires = "(|(accountExpires=0)(accountExpires>=%u))" % (
+                current_nttime)
+
+        filter_disabled = ""
+        if hide_disabled is True:
+            filter_disabled = "(!(userAccountControl:%s:=%u))" % (
+                ldb.OID_COMPARATOR_AND, dsdb.UF_ACCOUNTDISABLE)
+
+        filter = "(&(objectClass=user)(userAccountControl:%s:=%u)%s%s)" % (
+            ldb.OID_COMPARATOR_AND,
+            dsdb.UF_NORMAL_ACCOUNT,
+            filter_disabled,
+            filter_expires)
+
         res = samdb.search(search_dn,
                            scope=ldb.SCOPE_SUBTREE,
-                           expression=("(&(objectClass=user)(userAccountControl:%s:=%u))"
-                                       % (ldb.OID_COMPARATOR_AND, dsdb.UF_NORMAL_ACCOUNT)),
+                           expression=filter,
                            attrs=["samaccountname"])
         if (len(res) == 0):
             return
index a0a7dbf1c509ada46102ded63c92c0926be6c4ac..f95709ab7c844a2b1cba09887ffb931e93ab8f28 100644 (file)
@@ -984,6 +984,21 @@ accountExpires: %u
         """Get the NTDS objectGUID"""
         return dsdb._samdb_ntds_objectGUID(self)
 
+    def get_timestr(self):
+        """Get the current time as generalized time string"""
+        res = self.search(base="",
+                          scope=ldb.SCOPE_BASE,
+                          attrs=["currentTime"])
+        return str(res[0]["currentTime"][0])
+
+    def get_time(self):
+        """Get the current time as UNIX time"""
+        return ldb.string_to_time(self.get_timestr())
+
+    def get_nttime(self):
+        """Get the current time as NT time"""
+        return samba.unix2nttime(self.get_time())
+
     def server_site_name(self):
         """Get the server site name"""
         return dsdb._samdb_server_site_name(self)
index 07eb09b24d5aa4a663e5be4f352ff03641e1b239..3d3ea0681f8f01763cecc6282154e56fc3f5b7b0 100644 (file)
@@ -433,6 +433,76 @@ class UserCmdTestCase(SambaToolCmdTest):
             found = self.assertMatch(out, name,
                                      "user '%s' not found" % name)
 
+    def test_list_hide_expired(self):
+        expire_username = "expireUser"
+        expire_user = self._randomUser({"name": expire_username})
+        self._create_user(expire_user)
+
+        (result, out, err) = self.runsubcmd(
+            "user",
+            "list",
+            "--hide-expired",
+            "-H",
+            "ldap://%s" % os.environ["DC_SERVER"],
+            "-U%s%%%s" % (os.environ["DC_USERNAME"],
+                          os.environ["DC_PASSWORD"]))
+        self.assertCmdSuccess(result, out, err, "Error running list")
+        self.assertTrue(expire_username in out,
+                        "user '%s' not found" % expire_username)
+
+        # user will be expired one second ago
+        self.samdb.setexpiry(
+            "(sAMAccountname=%s)" % expire_username,
+            -1,
+            False)
+
+        (result, out, err) = self.runsubcmd(
+            "user",
+            "list",
+            "--hide-expired",
+            "-H",
+            "ldap://%s" % os.environ["DC_SERVER"],
+            "-U%s%%%s" % (os.environ["DC_USERNAME"],
+                          os.environ["DC_PASSWORD"]))
+        self.assertCmdSuccess(result, out, err, "Error running list")
+        self.assertFalse(expire_username in out,
+                         "user '%s' found" % expire_username)
+
+        self.samdb.deleteuser(expire_username)
+
+    def test_list_hide_disabled(self):
+        disable_username = "disableUser"
+        disable_user = self._randomUser({"name": disable_username})
+        self._create_user(disable_user)
+
+        (result, out, err) = self.runsubcmd(
+            "user",
+            "list",
+            "--hide-disabled",
+            "-H",
+            "ldap://%s" % os.environ["DC_SERVER"],
+            "-U%s%%%s" % (os.environ["DC_USERNAME"],
+                          os.environ["DC_PASSWORD"]))
+        self.assertCmdSuccess(result, out, err, "Error running list")
+        self.assertTrue(disable_username in out,
+                        "user '%s' not found" % disable_username)
+
+        self.samdb.disable_account("(sAMAccountname=%s)" % disable_username)
+
+        (result, out, err) = self.runsubcmd(
+            "user",
+            "list",
+            "--hide-disabled",
+            "-H",
+            "ldap://%s" % os.environ["DC_SERVER"],
+            "-U%s%%%s" % (os.environ["DC_USERNAME"],
+                          os.environ["DC_PASSWORD"]))
+        self.assertCmdSuccess(result, out, err, "Error running list")
+        self.assertFalse(disable_username in out,
+                         "user '%s' found" % disable_username)
+
+        self.samdb.deleteuser(disable_username)
+
     def test_show(self):
         for user in self.users:
             (result, out, err) = self.runsubcmd(