[PATCH] Extension to the samba-tool group subcommand functionality to allow listing of the members of an AD group
Lukasz Zalewski
lukas at eecs.qmul.ac.uk
Tue May 1 14:38:30 MDT 2012
Hi all,
Please find attached patch that extends samba-tool group sub-command
functionality to allow listing of group members (akin to Members tab in
AD users and Computers).
Regards
L
-------------- next part --------------
>From afa1d22c83bb5dd49de6b70cf7b6109a8a669b6a Mon Sep 17 00:00:00 2001
From: Lukasz Zalewski <lukas at eecs.qmul.ac.uk>
Date: Tue, 1 May 2012 21:17:33 +0100
Subject: [PATCH] Extension to the samba-tool group subcommand functionality to allow listing of the members of an AD group
---
source4/scripting/python/samba/netcmd/group.py | 66 ++++++++++++++++++++
.../python/samba/tests/samba_tool/group.py | 19 ++++++
source4/setup/tests/blackbox_group.sh | 6 ++
3 files changed, 91 insertions(+), 0 deletions(-)
diff --git a/source4/scripting/python/samba/netcmd/group.py b/source4/scripting/python/samba/netcmd/group.py
index 004307b..5cd9ba8 100644
--- a/source4/scripting/python/samba/netcmd/group.py
+++ b/source4/scripting/python/samba/netcmd/group.py
@@ -20,6 +20,8 @@
import samba.getopt as options
from samba.netcmd import Command, SuperCommand, CommandError, Option
import ldb
+from samba.ndr import ndr_unpack
+from samba.dcerpc import security
from getpass import getpass
from samba.auth import system_session
@@ -260,6 +262,7 @@ Example2 shows how to remove a single user account, User2, from the supergroup A
raise CommandError('Failed to remove members "%s" from group "%s"' % (listofmembers, groupname), e)
self.outf.write("Removed members from group %s\n" % groupname)
+
class cmd_group_list(Command):
"""List all groups"""
@@ -293,6 +296,68 @@ class cmd_group_list(Command):
for msg in res:
self.outf.write("%s\n" % msg.get("samaccountname", idx=0))
+
+class cmd_group_list_members(Command):
+ """List all members of an AD group
+
+This command lists members from an existing Active Directory group. The command accepts one group name.
+
+Example1:
+samba-tool group listmembers \"Domain Users\" -H ldap://samba.samdom.example.com -Uadministrator%passw0rd
+"""
+
+ synopsis = "%prog <groupname> [options]"
+
+ takes_options = [
+ Option("-H", "--URL", help="LDB URL for database or target server", type=str,
+ metavar="URL", dest="H"),
+ ]
+
+ takes_optiongroups = {
+ "sambaopts": options.SambaOptions,
+ "credopts": options.CredentialsOptions,
+ "versionopts": options.VersionOptions,
+ }
+
+ takes_args = ["groupname"]
+
+ def run(self, groupname, credopts=None, sambaopts=None, versionopts=None, H=None):
+ lp = sambaopts.get_loadparm()
+ creds = credopts.get_credentials(lp, fallback_machine=True)
+
+ try:
+ samdb = SamDB(url=H, session_info=system_session(),
+ credentials=creds, lp=lp)
+
+ search_filter = "(&(objectClass=group)(samaccountname=%s))" % groupname
+ res = samdb.search(samdb.domain_dn(), scope=ldb.SCOPE_SUBTREE,
+ expression=(search_filter),
+ attrs=["objectSid"])
+
+ if (len(res) != 1):
+ return
+
+ group_dn = res[0].get('dn', idx=0)
+ object_sid = res[0].get('objectSid', idx=0)
+
+ object_sid = ndr_unpack(security.dom_sid, object_sid)
+ (group_dom_sid, rid) = object_sid.split()
+
+ search_filter = "(|(primaryGroupID=%s)(memberOf=%s))" % (rid, group_dn)
+ res = samdb.search(samdb.domain_dn(), scope=ldb.SCOPE_SUBTREE,
+ expression=(search_filter),
+ attrs=["cn"])
+
+ if (len(res) == 0):
+ return
+
+ for msg in res:
+ self.outf.write("%s\n" % msg.get("cn", idx=0))
+
+ except Exception, e:
+ raise CommandError('Failed to list members of "%s" group ' % groupname, e)
+
+
class cmd_group(SuperCommand):
"""Group management"""
@@ -302,3 +367,4 @@ class cmd_group(SuperCommand):
subcommands["addmembers"] = cmd_group_add_members()
subcommands["removemembers"] = cmd_group_remove_members()
subcommands["list"] = cmd_group_list()
+ subcommands["listmembers"] = cmd_group_list_members()
diff --git a/source4/scripting/python/samba/tests/samba_tool/group.py b/source4/scripting/python/samba/tests/samba_tool/group.py
index be10716..b7f7517 100644
--- a/source4/scripting/python/samba/tests/samba_tool/group.py
+++ b/source4/scripting/python/samba/tests/samba_tool/group.py
@@ -118,6 +118,25 @@ class GroupCmdTestCase(SambaToolCmdTest):
found = self.assertMatch(out, name,
"group '%s' not found" % name)
+ def test_listmembers(self):
+ (result, out, err) = self.runsubcmd("group", "listmembers", "Domain Users",
+ "-H", "ldap://%s" % os.environ["DC_SERVER"],
+ "-U%s%%%s" % (os.environ["DC_USERNAME"],
+ os.environ["DC_PASSWORD"]))
+ self.assertCmdSuccess(result, "Error running listmembers")
+
+ search_filter = "(|(primaryGroupID=513)(memberOf=CN=Domain Users,CN=Users,%s))" % self.samdb.domain_dn()
+
+ grouplist = self.samdb.search(base=self.samdb.domain_dn(),
+ scope=ldb.SCOPE_SUBTREE,
+ expression=search_filter,
+ attrs=["cn"])
+
+ self.assertTrue(len(grouplist) > 0, "no groups found in samdb")
+
+ for groupobj in grouplist:
+ name = groupobj.get("cn", idx=0)
+ found = self.assertMatch(out, name, "group '%s' not found" % name)
def _randomGroup(self, base={}):
"""create a group with random attribute values, you can specify base attributes"""
diff --git a/source4/setup/tests/blackbox_group.sh b/source4/setup/tests/blackbox_group.sh
index 08b8e5b..aaddeeb 100755
--- a/source4/setup/tests/blackbox_group.sh
+++ b/source4/setup/tests/blackbox_group.sh
@@ -71,4 +71,10 @@ testit "group delete" $samba_tool group delete $CONFIG ddg
testit "group delete" $samba_tool group delete $CONFIG gdg
testit "group delete" $samba_tool group delete $CONFIG udg
+#test listing of all groups
+testit "group list" $samba_tool group list $CONFIG
+
+#test listing of members of a particular group
+testit "group listmembers" $samba_tool group listmembers $CONFIG Users
+
exit $failed
--
1.7.1
More information about the samba-technical
mailing list