[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