summaryrefslogtreecommitdiff
path: root/python/samba
diff options
context:
space:
mode:
authorBjörn Baumbach <bb@sernet.de>2020-12-23 15:51:12 +0100
committerVolker Lendecke <vl@samba.org>2021-01-15 16:34:11 +0000
commite84f8bdff584ae2d020e42bbd8b15444f097acd2 (patch)
tree6da34812ec9fbb3a9a847d817e53c9ed767f797a /python/samba
parent7dad13cc86fa603d1ae9c2b00c26686a5f652dc2 (diff)
downloadsamba-e84f8bdff584ae2d020e42bbd8b15444f097acd2.tar.gz
samba-tool: Optionally hide disabled/expired accounts in "group listmembers"
--hide-expired Do not list expired group members --hide-disabled Do not list disabled group members Signed-off-by: Björn Baumbach <bb@sernet.de> Reviewed-by: Volker Lendecke <vl@samba.org> Autobuild-User(master): Volker Lendecke <vl@samba.org> Autobuild-Date(master): Fri Jan 15 16:34:11 UTC 2021 on sn-devel-184
Diffstat (limited to 'python/samba')
-rw-r--r--python/samba/netcmd/group.py29
-rw-r--r--python/samba/tests/samba_tool/group.py109
2 files changed, 135 insertions, 3 deletions
diff --git a/python/samba/netcmd/group.py b/python/samba/netcmd/group.py
index b5c86d33019..a958db2c42c 100644
--- a/python/samba/netcmd/group.py
+++ b/python/samba/netcmd/group.py
@@ -33,6 +33,7 @@ from samba.dsdb import (
GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP,
GTYPE_DISTRIBUTION_GLOBAL_GROUP,
GTYPE_DISTRIBUTION_UNIVERSAL_GROUP,
+ UF_ACCOUNTDISABLE,
)
from collections import defaultdict
from subprocess import check_call, CalledProcessError
@@ -488,6 +489,14 @@ samba-tool group listmembers \"Domain Users\" -H ldap://samba.samdom.example.com
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 group members",
+ default=False,
+ action='store_true'),
+ Option("--hide-disabled",
+ default=False,
+ action='store_true',
+ help="Do not list disabled group members"),
Option("--full-dn", dest="full_dn",
default=False,
action='store_true',
@@ -508,6 +517,8 @@ samba-tool group listmembers \"Domain Users\" -H ldap://samba.samdom.example.com
sambaopts=None,
versionopts=None,
H=None,
+ hide_expired=False,
+ hide_disabled=False,
full_dn=False):
lp = sambaopts.get_loadparm()
creds = credopts.get_credentials(lp, fallback_machine=True)
@@ -530,10 +541,22 @@ samba-tool group listmembers \"Domain Users\" -H ldap://samba.samdom.example.com
(group_dom_sid, rid) = group_sid.split()
group_sid_dn = "<SID=%s>" % (group_sid)
- search_filter = ("(|(primaryGroupID=%s)(memberOf=%s))" %
- (rid, group_sid_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, UF_ACCOUNTDISABLE)
+
+ filter = "(&(|(primaryGroupID=%s)(memberOf=%s))%s%s)" % (
+ rid, group_sid_dn, filter_disabled, filter_expires)
+
res = samdb.search(samdb.domain_dn(), scope=ldb.SCOPE_SUBTREE,
- expression=(search_filter),
+ expression=filter,
attrs=["samAccountName", "cn"])
if (len(res) == 0):
diff --git a/python/samba/tests/samba_tool/group.py b/python/samba/tests/samba_tool/group.py
index 3d714f206f3..2542411d74a 100644
--- a/python/samba/tests/samba_tool/group.py
+++ b/python/samba/tests/samba_tool/group.py
@@ -239,6 +239,79 @@ class GroupCmdTestCase(SambaToolCmdTest):
name = str(groupobj.get("samAccountName", idx=0))
found = self.assertMatch(out, name, "group '%s' not found" % name)
+ def test_listmembers_hide_expired(self):
+ expire_username = "expireUser"
+ expire_user = self._random_user({"name": expire_username})
+ self._create_user(expire_user)
+
+ (result, out, err) = self.runsubcmd(
+ "group",
+ "listmembers",
+ "Domain Users",
+ "--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 listmembers")
+ 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(
+ "group",
+ "listmembers",
+ "Domain Users",
+ "--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 listmembers")
+ self.assertFalse(expire_username in out,
+ "user '%s' not found" % expire_username)
+
+ self.samdb.deleteuser(expire_username)
+
+ def test_listmembers_hide_disabled(self):
+ disable_username = "disableUser"
+ disable_user = self._random_user({"name": disable_username})
+ self._create_user(disable_user)
+
+ (result, out, err) = self.runsubcmd(
+ "group",
+ "listmembers",
+ "Domain Users",
+ "--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 listmembers")
+ 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(
+ "group",
+ "listmembers",
+ "Domain Users",
+ "--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 listmembers")
+ self.assertFalse(disable_username in out,
+ "user '%s' not found" % disable_username)
+
+ self.samdb.deleteuser(disable_username)
def test_listmembers_full_dn(self):
(result, out, err) = self.runsubcmd("group", "listmembers", "Domain Users",
@@ -502,3 +575,39 @@ template """
total_groups = len(grouplist)
self.assertTrue("Total groups: {0}".format(total_groups) in out,
"Total groups not reported correctly")
+
+ def _random_user(self, base={}):
+ '''
+ create a user with random attribute values, you can specify
+ base attributes
+ '''
+ user = {
+ "name": self.randomName(),
+ "password": self.random_password(16),
+ "surname": self.randomName(),
+ "given-name": self.randomName(),
+ "job-title": self.randomName(),
+ "department": self.randomName(),
+ "company": self.randomName(),
+ "description": self.randomName(count=100),
+ "createUserFn": self._create_user,
+ }
+ user.update(base)
+ return user
+
+ def _create_user(self, user):
+ return self.runsubcmd(
+ "user",
+ "add",
+ user["name"],
+ user["password"],
+ "--surname=%s" % user["surname"],
+ "--given-name=%s" % user["given-name"],
+ "--job-title=%s" % user["job-title"],
+ "--department=%s" % user["department"],
+ "--description=%s" % user["description"],
+ "--company=%s" % user["company"],
+ "-H",
+ "ldap://%s" % os.environ["DC_SERVER"],
+ "-U%s%%%s" % (os.environ["DC_USERNAME"],
+ os.environ["DC_PASSWORD"]))