[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Wed May 2 17:58:04 MDT 2012


The branch, master has been updated
       via  86b1dd8 s4-samba-tool: make new samba-tool group listmembers use samAccountName
       via  a0a8380 s4-s3upgrade: Force ldapsam:trusted = yes
       via  9cd664b Extension to the samba-tool group subcommand functionality to allow listing of the members of an AD group
       via  d2c8ebe s4-s3upgrade: Try harder to get group memberships on upgrade
       via  926c0a6 s3-pypassdb: add wrapper for enum_group_memberships
       via  0ef06dd s3-pypassdb: remove unused variable
      from  ac1e1af s4:torture:rpc: add a new test samba3.smb2-pipe-read-logoff

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 86b1dd845a595bd6f3a70176a155ee0187584a5e
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed May 2 16:44:27 2012 +1000

    s4-samba-tool: make new samba-tool group listmembers use samAccountName
    
    This is the unique username value.
    
    Andrew Bartlett
    
    Autobuild-User: Andrew Bartlett <abartlet at samba.org>
    Autobuild-Date: Thu May  3 01:57:41 CEST 2012 on sn-devel-104

commit a0a83802fbcb5e4d415315e4ea3a35db827785a3
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed May 2 16:05:25 2012 +1000

    s4-s3upgrade: Force ldapsam:trusted = yes
    
    While this setting is not the default in Samba3, any domain that is
    in a suitable condition to upgrade to Samba4 should already be in the
    layout that ldapsam:trusted uses.  It can be turned off by setting
    ldapsam:trusted=false in the smb.conf.
    
    Many upgrades to Samba4 happen on a different host to the old Samba3 domain
    and this avoids the need to configure nss_ldap only for the duration of
    the upgrade.
    
    Andrew Bartlett

commit 9cd664b2e9a01570d4beaf3dfc9e3f93b9370e63
Author: Lukasz Zalewski <lukas at eecs.qmul.ac.uk>
Date:   Tue May 1 21:17:33 2012 +0100

    Extension to the samba-tool group subcommand functionality to allow listing of the members of an AD group

commit d2c8ebe2c744d8ecd976328cd094267e82d18673
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed May 2 13:01:29 2012 +1000

    s4-s3upgrade: Try harder to get group memberships on upgrade
    
    This fixes an issue where some group types were not upgraded, as we
    did not upgrade alias memberships.
    
    It also uses enum_group_memberships() to try and find the memberships
    from the other direction, by asking which groups a user is a member
    of.  As Samba3 (and NT4) does not implement nested groups, this should
    be safe.
    
    Andrew Bartlett

commit 926c0a6a330f3b0f643d6384a15e90d2999bce26
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed May 2 12:57:27 2012 +1000

    s3-pypassdb: add wrapper for enum_group_memberships
    
    This will be used in samba3upgrade to try and get the group memberships by instead asking
    for the groups each user is in.  This reverse lookup may be more reliable, as this
    is used at login time.
    
    Andrew Bartlett

commit 0ef06dd0212c6504740a5e0333440a9be090c088
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed May 2 12:55:54 2012 +1000

    s3-pypassdb: remove unused variable

-----------------------------------------------------------------------

Summary of changes:
 source3/passdb/py_passdb.c                         |   60 +++++++++++++++++-
 source4/scripting/python/samba/netcmd/group.py     |   66 ++++++++++++++++++++
 .../python/samba/tests/samba_tool/group.py         |   19 ++++++
 source4/scripting/python/samba/upgrade.py          |   28 +++++++--
 source4/setup/tests/blackbox_group.sh              |    6 ++
 5 files changed, 171 insertions(+), 8 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/passdb/py_passdb.c b/source3/passdb/py_passdb.c
index 17ae476..194a7d4 100644
--- a/source3/passdb/py_passdb.c
+++ b/source3/passdb/py_passdb.c
@@ -196,8 +196,6 @@ static PyObject *py_samu_get_pass_must_change_time(PyObject *obj, void *closure)
 
 static int py_samu_set_pass_must_change_time(PyObject *obj, PyObject *value, void *closure)
 {
-	struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
-
 	PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
 
 	/* TODO: make this not a get/set or give a better exception */
@@ -1924,6 +1922,60 @@ static PyObject *py_pdb_enum_group_members(pytalloc_Object *self, PyObject *args
 }
 
 
+static PyObject *py_pdb_enum_group_memberships(pytalloc_Object *self, PyObject *args)
+{
+	NTSTATUS status;
+	struct pdb_methods *methods;
+	TALLOC_CTX *tframe;
+	int i;
+
+	struct samu *sam_acct;
+	PyObject *py_sam_acct;
+	PyObject *py_sid_list;
+	struct dom_sid *user_group_sids = NULL;
+	gid_t *user_group_ids = NULL;
+	uint32_t num_groups = 0;
+
+	if (!PyArg_ParseTuple(args, "O!:enum_group_memberships", &PySamu, &py_sam_acct)) {
+		return NULL;
+	}
+
+	methods = pytalloc_get_ptr(self);
+
+	if ((tframe = talloc_stackframe()) == NULL) {
+		PyErr_NoMemory();
+		return NULL;
+	}
+
+	sam_acct = pytalloc_get_ptr(py_sam_acct);
+
+	status = methods->enum_group_memberships(methods, tframe, sam_acct,
+						 &user_group_sids, &user_group_ids, &num_groups);
+	if (!NT_STATUS_IS_OK(status)) {
+		PyErr_Format(py_pdb_error, "Unable to enumerate group memberships, (%d,%s)",
+				NT_STATUS_V(status),
+				get_friendly_nt_error_msg(status));
+		talloc_free(tframe);
+		return NULL;
+	}
+
+	py_sid_list = PyList_New(0);
+	if (py_sid_list == NULL) {
+		PyErr_NoMemory();
+		talloc_free(tframe);
+		return NULL;
+	}
+
+	for(i=0; i<num_groups; i++) {
+		PyList_Append(py_sid_list, pytalloc_steal(dom_sid_Type, dom_sid_dup(NULL, &user_group_sids[i])));
+	}
+
+	talloc_free(tframe);
+
+	return py_sid_list;
+}
+
+
 static PyObject *py_pdb_add_groupmem(pytalloc_Object *self, PyObject *args)
 {
 	NTSTATUS status;
@@ -3412,7 +3464,9 @@ static PyMethodDef py_pdb_methods[] = {
 	{ "enum_group_members", (PyCFunction)py_pdb_enum_group_members, METH_VARARGS,
 		"enum_group_members(group_sid) -> List\n\n \
 		Return list of users (dom_sid object) in group." },
-	/* enum_group_memberships */
+	{ "enum_group_memberships", (PyCFunction)py_pdb_enum_group_memberships, METH_VARARGS,
+		"enum_group_memberships(samu object) -> List\n\n \
+		Return list of groups (dom_sid object) this user is part of." },
 	/* set_unix_primary_group */
 	{ "add_groupmem", (PyCFunction)py_pdb_add_groupmem, METH_VARARGS,
 		"add_groupmem(group_rid, member_rid) -> None\n\n \
diff --git a/source4/scripting/python/samba/netcmd/group.py b/source4/scripting/python/samba/netcmd/group.py
index 004307b..265170d 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=["samAccountName"])
+
+            if (len(res) == 0):
+                return
+
+            for msg in res:
+                self.outf.write("%s\n" % msg.get("samAccountName", 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..2c0c46e 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=["samAccountName"])
+
+        self.assertTrue(len(grouplist) > 0, "no groups found in samdb")
+
+        for groupobj in grouplist:
+            name = groupobj.get("samAccountName", 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/scripting/python/samba/upgrade.py b/source4/scripting/python/samba/upgrade.py
index 216ad41..7d69306 100644
--- a/source4/scripting/python/samba/upgrade.py
+++ b/source4/scripting/python/samba/upgrade.py
@@ -469,6 +469,9 @@ def upgrade_from_samba3(samba3, logger, targetdir, session_info=None, useeadb=Fa
     realm = samba3.lp.get("realm")
     netbiosname = samba3.lp.get("netbios name")
 
+    if samba3.lp.get("ldapsam:trusted") is None:
+        samba3.lp.set("ldapsam:trusted", "yes")
+
     # secrets db
     try:
         secrets_db = samba3.get_secrets_db()
@@ -536,6 +539,7 @@ def upgrade_from_samba3(samba3, logger, targetdir, session_info=None, useeadb=Fa
         if group.sid_name_use == lsa.SID_NAME_ALIAS:
             try:
                 members = s3db.enum_aliasmem(group.sid)
+                groupmembers[str(group.sid)] = members
             except passdb.error, e:
                 logger.warn("Ignoring group '%s' %s listed but then not found: %s",
                             group.nt_name, group.sid, e)
@@ -543,11 +547,11 @@ def upgrade_from_samba3(samba3, logger, targetdir, session_info=None, useeadb=Fa
         elif group.sid_name_use == lsa.SID_NAME_DOM_GRP:
             try:
                 members = s3db.enum_group_members(group.sid)
+                groupmembers[str(group.sid)] = members
             except passdb.error, e:
                 logger.warn("Ignoring group '%s' %s listed but then not found: %s",
                             group.nt_name, group.sid, e)
                 continue
-            groupmembers[group.nt_name] = members
         elif group.sid_name_use == lsa.SID_NAME_WKN_GRP:
             (group_dom_sid, rid) = group.sid.split()
             if (group_dom_sid != security.dom_sid(security.SID_BUILTIN)):
@@ -557,13 +561,14 @@ def upgrade_from_samba3(samba3, logger, targetdir, session_info=None, useeadb=Fa
             # A number of buggy databases mix up well known groups and aliases.
             try:
                 members = s3db.enum_aliasmem(group.sid)
+                groupmembers[str(group.sid)] = members
             except passdb.error, e:
                 logger.warn("Ignoring group '%s' %s listed but then not found: %s",
                             group.nt_name, group.sid, e)
                 continue
         else:
-            logger.warn("Ignoring group '%s' with sid_name_use=%d",
-                        group.nt_name, group.sid_name_use)
+            logger.warn("Ignoring group '%s' %s with sid_name_use=%d",
+                        group.nt_name, group.sid, group.sid_name_use)
             continue
 
     # Export users from old passdb backend
@@ -615,6 +620,19 @@ Please fix this account before attempting to upgrade again
         if username.lower() == 'administrator':
             admin_user = username
 
+        try:
+            group_memberships = s3db.enum_group_memberships(user);
+            for group in group_memberships:
+                if str(group) in groupmembers:
+                    if user.user_sid not in groupmembers[str(group)]:
+                        groupmembers[str(group)].append(user.user_sid)
+                else:
+                    groupmembers[str(group)] = [user.user_sid];
+        except passdb.error, e:
+            logger.warn("Ignoring group memberships of '%s' %s: %s",
+                        username, user.user_sid, e)
+
+
     logger.info("Next rid = %d", next_rid)
 
     # Check for same username/groupname
@@ -706,8 +724,8 @@ Please fix this account before attempting to upgrade again
 
     logger.info("Adding users to groups")
     for g in grouplist:
-        if g.nt_name in groupmembers:
-            add_users_to_group(result.samdb, g, groupmembers[g.nt_name], logger)
+        if str(g.sid) in groupmembers:
+            add_users_to_group(result.samdb, g, groupmembers[str(g.sid)], logger)
 
     # Set password for administrator
     if admin_user:
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


-- 
Samba Shared Repository


More information about the samba-cvs mailing list