From: Björn Baumbach Date: Wed, 23 Dec 2020 12:00:34 +0000 (+0100) Subject: samba-tool: Optionally hide disabled/expired accounts in "user list" X-Git-Tag: samba-4.14.0rc1~21 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7dad13cc86fa603d1ae9c2b00c26686a5f652dc2;p=thirdparty%2Fsamba.git samba-tool: Optionally hide disabled/expired accounts in "user list" --hide-expired Do not list expired user accounts --hide-disabled Do not list disabled user accounts Signed-off-by: Björn Baumbach Reviewed-by: Volker Lendecke --- diff --git a/docs-xml/manpages/samba-tool.8.xml b/docs-xml/manpages/samba-tool.8.xml index de3a9e3ac26..5ab8cd91618 100644 --- a/docs-xml/manpages/samba-tool.8.xml +++ b/docs-xml/manpages/samba-tool.8.xml @@ -1357,6 +1357,18 @@ listed. + + --hide-expired + + Do not list expired user accounts. + + + + --hide-disabled + + Do not list disabled user accounts. + + diff --git a/python/samba/netcmd/user.py b/python/samba/netcmd/user.py index 7e8204462d1..bbfa7e989dd 100644 --- a/python/samba/netcmd/user.py +++ b/python/samba/netcmd/user.py @@ -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 diff --git a/python/samba/samdb.py b/python/samba/samdb.py index a0a7dbf1c50..f95709ab7c8 100644 --- a/python/samba/samdb.py +++ b/python/samba/samdb.py @@ -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) diff --git a/python/samba/tests/samba_tool/user.py b/python/samba/tests/samba_tool/user.py index 07eb09b24d5..3d3ea0681f8 100644 --- a/python/samba/tests/samba_tool/user.py +++ b/python/samba/tests/samba_tool/user.py @@ -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(