[SCM] Samba Shared Repository - branch master updated

Andreas Schneider asn at samba.org
Wed Jan 15 13:31:05 UTC 2020


The branch, master has been updated
       via  6b8a6838849 tests: Test samba-tool user setprimarygroup command
       via  fd1c905ec3b tests: Test samba-tool user getgroups command
       via  d73a9d1a8d8 selftest: create working directory for blackbox test
       via  a77f758df11 samba-tool: implement user getgroups command
       via  8403527bbd1 samba-tool: implement user setprimary group command (set primaryGroupID)
      from  d512b27563b clitar: use modern DBG macros

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


- Log -----------------------------------------------------------------
commit 6b8a683884950603a690a2e7e3b267c21e458d6b
Author: Björn Baumbach <bb at sernet.de>
Date:   Tue Jan 14 15:19:40 2020 +0100

    tests: Test samba-tool user setprimarygroup command
    
    Signed-off-by: Björn Baumbach <bb at sernet.de>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    
    Autobuild-User(master): Andreas Schneider <asn at cryptomilk.org>
    Autobuild-Date(master): Wed Jan 15 13:30:53 UTC 2020 on sn-devel-184

commit fd1c905ec3b21f7fcc61f9bc827a56e3a3038381
Author: Björn Baumbach <bb at sernet.de>
Date:   Tue Jan 14 15:10:09 2020 +0100

    tests: Test samba-tool user getgroups command
    
    Signed-off-by: Björn Baumbach <bb at sernet.de>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit d73a9d1a8d81bf7d7bc9aeab5198931b2a7fb582
Author: Björn Baumbach <bb at sernet.de>
Date:   Wed Dec 18 11:56:03 2019 +0100

    selftest: create working directory for blackbox test
    
    Required to run test separately.
    
    Signed-off-by: Björn Baumbach <bb at sernet.de>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit a77f758df117638ea22b7589323b71d5f5261bd9
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed May 16 13:00:16 2018 +0200

    samba-tool: implement user getgroups command
    
    samba-tool user getgroups command to list a users group memberships.
    
    Pair-programmed-with: Björn Baumbach <bb at sernet.de>
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Signed-off-by: Björn Baumbach <bb at sernet.de>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit 8403527bbd132ee639fdd3926bf55d15bd8dea56
Author: Björn Baumbach <bb at sernet.de>
Date:   Wed May 16 10:19:16 2018 +0200

    samba-tool: implement user setprimary group command (set primaryGroupID)
    
    Introduce an option to set the primaryGroupID attribute of a user account.
    
    Pair-programmed-with: Stefan Metzmacher <metze at samba.org>
    
    Signed-off-by: Björn Baumbach <bb at sernet.de>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

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

Summary of changes:
 docs-xml/manpages/samba-tool.8.xml    |  10 ++
 python/samba/netcmd/user.py           | 189 ++++++++++++++++++++++++++++++++++
 source4/setup/tests/blackbox_group.sh |  42 ++++++++
 3 files changed, 241 insertions(+)


Changeset truncated at 500 lines:

diff --git a/docs-xml/manpages/samba-tool.8.xml b/docs-xml/manpages/samba-tool.8.xml
index 9664bb9cd56..ef55d72e714 100644
--- a/docs-xml/manpages/samba-tool.8.xml
+++ b/docs-xml/manpages/samba-tool.8.xml
@@ -1192,6 +1192,16 @@
 	<para>List all users.</para>
 </refsect3>
 
+<refsect3>
+	<title>user setprimarygroup <replaceable>username</replaceable> <replaceable>primarygroupname</replaceable></title>
+	<para>Set the primary group a user account.</para>
+</refsect3>
+
+<refsect3>
+	<title>user getgroups <replaceable>username</replaceable></title>
+	<para>Get the direct group memberships of a user account.</para>
+</refsect3>
+
 <refsect3>
 	<title>user show <replaceable>username</replaceable> [options]</title>
 	<para>Display a user AD object.</para>
diff --git a/python/samba/netcmd/user.py b/python/samba/netcmd/user.py
index 86a7a45b24e..c66fd98139c 100644
--- a/python/samba/netcmd/user.py
+++ b/python/samba/netcmd/user.py
@@ -736,6 +736,193 @@ class cmd_user_password(Command):
         self.outf.write("Changed password OK\n")
 
 
+class cmd_user_getgroups(Command):
+    """Get the direct group memberships of a user account.
+
+The username specified on the command is the sAMAccountName."""
+    synopsis = "%prog <username> [options]"
+
+    takes_optiongroups = {
+        "sambaopts": options.SambaOptions,
+        "versionopts": options.VersionOptions,
+        "credopts": options.CredentialsOptions,
+    }
+
+    takes_options = [
+        Option("-H", "--URL", help="LDB URL for database or target server",
+               type=str, metavar="URL", dest="H"),
+        ]
+
+    takes_args = ["username"]
+
+    def run(self, username, credopts=None, sambaopts=None,
+            versionopts=None, H=None):
+
+        lp = sambaopts.get_loadparm()
+        creds = credopts.get_credentials(lp)
+
+        samdb = SamDB(url=H, session_info=system_session(),
+                      credentials=creds, lp=lp)
+
+        filter = ("(&(sAMAccountName=%s)(objectClass=user))" %
+                  ldb.binary_encode(username))
+        try:
+            res = samdb.search(base=samdb.domain_dn(),
+                               expression=filter,
+                               scope=ldb.SCOPE_SUBTREE,
+                               attrs=["objectSid",
+                                      "memberOf",
+                                      "primaryGroupID"])
+            user_sid_binary = res[0].get('objectSid', idx=0)
+            user_sid = ndr_unpack(security.dom_sid, user_sid_binary)
+            (user_dom_sid, user_rid) = user_sid.split()
+            user_sid_dn = "<SID=%s>" % user_sid
+            user_pgid = int(res[0].get('primaryGroupID', idx=0))
+            user_groups = res[0].get('memberOf')
+            if user_groups is None:
+                user_groups = []
+        except IndexError:
+            raise CommandError("Unable to find user '%s'" % (username))
+
+        primarygroup_sid_dn = "<SID=%s-%u>" % (user_dom_sid, user_pgid)
+
+        filter = "(objectClass=group)"
+        try:
+            res = samdb.search(base=primarygroup_sid_dn,
+                               expression=filter,
+                               scope=ldb.SCOPE_BASE,
+                               attrs=['sAMAccountName'])
+            primary_group_dn = str(res[0].dn)
+            primary_group_name = res[0].get('sAMAccountName')
+        except IndexError:
+            raise CommandError("Unable to find primary group '%s'" % (primarygroup_sid_dn))
+
+        group_names = []
+        for gdn in user_groups:
+            try:
+                res = samdb.search(base=gdn,
+                                   expression=filter,
+                                   scope=ldb.SCOPE_BASE,
+                                   attrs=['sAMAccountName'])
+                group_names.extend(res[0].get('sAMAccountName'))
+            except IndexError:
+                raise CommandError("Unable to find group '%s'" % (gdn))
+
+        self.outf.write("%s\n" % primary_group_name)
+        for group_name in group_names:
+            self.outf.write("%s\n" % group_name)
+
+
+class cmd_user_setprimarygroup(Command):
+    """Set the primary group a user account.
+
+This command sets the primary group a user account. The username specified on
+the command is the sAMAccountName. The primarygroupname is the sAMAccountName
+of the new primary group. The user must be a member of the group.
+
+The command may be run from the root userid or another authorized userid. The
+-H or --URL= option can be used to execute the command against a remote server.
+
+Example1:
+samba-tool user setprimarygroup TestUser1 newPrimaryGroup --URL=ldap://samba.samdom.example.com -Uadministrator%passw1rd
+
+Example1 shows how to set the primary group for TestUser1 on a remote LDAP
+server. The --URL parameter is used to specify the remote target server.  The
+-U option is used to pass the username and password of a user that exists on
+the remote server and is authorized to update the server.
+"""
+    synopsis = "%prog <username> <primarygroupname> [options]"
+
+    takes_optiongroups = {
+        "sambaopts": options.SambaOptions,
+        "versionopts": options.VersionOptions,
+        "credopts": options.CredentialsOptions,
+    }
+
+    takes_options = [
+        Option("-H", "--URL", help="LDB URL for database or target server", type=str,
+               metavar="URL", dest="H"),
+        ]
+
+    takes_args = ["username", "primarygroupname"]
+
+    def run(self, username, primarygroupname, credopts=None, sambaopts=None,
+            versionopts=None, H=None):
+
+        lp = sambaopts.get_loadparm()
+        creds = credopts.get_credentials(lp)
+
+        samdb = SamDB(url=H, session_info=system_session(),
+                      credentials=creds, lp=lp)
+
+        filter = ("(&(sAMAccountName=%s)(objectClass=user))" %
+                  ldb.binary_encode(username))
+        try:
+            res = samdb.search(base=samdb.domain_dn(),
+                               expression=filter,
+                               scope=ldb.SCOPE_SUBTREE,
+                               controls=["extended_dn:1:1"],
+                               attrs=["objectSid",
+                                      "memberOf",
+                                      "primaryGroupID"])
+            user_sid_binary = res[0].get('objectSid', idx=0)
+            user_sid = ndr_unpack(security.dom_sid, user_sid_binary)
+            (user_dom_sid, user_rid) = user_sid.split()
+            user_sid_dn = "<SID=%s>" % user_sid
+            user_pgid = int(res[0].get('primaryGroupID', idx=0))
+            user_groups = res[0].get('memberOf')
+            if user_groups is None:
+                user_groups = []
+        except IndexError:
+            raise CommandError("Unable to find user '%s'" % (username))
+
+        user_group_sids = []
+        for user_group in user_groups:
+            user_group_dn = ldb.Dn(samdb, str(user_group))
+            user_group_binary_sid = user_group_dn.get_extended_component("SID")
+            user_group_sid = ndr_unpack(security.dom_sid, user_group_binary_sid)
+            user_group_sids.append(user_group_sid)
+
+        filter = ("(&(sAMAccountName=%s)(objectClass=group))" %
+                  ldb.binary_encode(primarygroupname))
+        try:
+            res = samdb.search(base=samdb.domain_dn(),
+                               expression=filter,
+                               scope=ldb.SCOPE_SUBTREE,
+                               attrs=["objectSid"])
+            group_sid_binary = res[0].get('objectSid', idx=0)
+        except IndexError:
+            raise CommandError("Unable to find group '%s'" % (primarygroupname))
+
+        primarygroup_sid = ndr_unpack(security.dom_sid, group_sid_binary)
+        (primarygroup_dom_sid, primarygroup_rid) = primarygroup_sid.split()
+
+        if user_dom_sid != primarygroup_dom_sid:
+            raise CommandError("Group '%s' does not belong to the user's "
+                               "domain" % primarygroupname)
+
+        if primarygroup_rid != user_pgid and primarygroup_sid not in user_group_sids:
+            raise CommandError("User '%s' is not member of group '%s'" %
+                               (username, primarygroupname))
+
+        setprimarygroup_ldif = """
+dn: %s
+changetype: modify
+delete: primaryGroupID
+primaryGroupID: %u
+add: primaryGroupID
+primaryGroupID: %u
+""" % (user_sid_dn, user_pgid, primarygroup_rid)
+
+        try:
+            samdb.modify_ldif(setprimarygroup_ldif)
+        except Exception as msg:
+            raise CommandError("Failed to set primary group '%s' "
+                               "for user '%s': %s" %
+                               (primarygroupname, username, msg))
+        self.outf.write("Changed primary group to '%s'\n" % primarygroupname)
+
+
 class cmd_user_setpassword(Command):
     """Set or reset the password of a user account.
 
@@ -2894,6 +3081,8 @@ class cmd_user(SuperCommand):
     subcommands["list"] = cmd_user_list()
     subcommands["setexpiry"] = cmd_user_setexpiry()
     subcommands["password"] = cmd_user_password()
+    subcommands["getgroups"] = cmd_user_getgroups()
+    subcommands["setprimarygroup"] = cmd_user_setprimarygroup()
     subcommands["setpassword"] = cmd_user_setpassword()
     subcommands["getpassword"] = cmd_user_getpassword()
     subcommands["syncpasswords"] = cmd_user_syncpasswords()
diff --git a/source4/setup/tests/blackbox_group.sh b/source4/setup/tests/blackbox_group.sh
index 4adfa0c7f4f..e4a587fbba1 100755
--- a/source4/setup/tests/blackbox_group.sh
+++ b/source4/setup/tests/blackbox_group.sh
@@ -14,6 +14,7 @@ shift 1
 
 
 rm -rf $PREFIX/simple-dc
+mkdir -p $PREFIX
 testit "simple-dc" $PYTHON $BINDIR/samba-tool domain provision --server-role="dc" --domain=FOO --realm=foo.example.com --domain-sid=S-1-5-21-4177067393-1453636373-93818738 --targetdir=$PREFIX/simple-dc --use-ntvfs
 samba_tool="./bin/samba-tool"
 
@@ -23,6 +24,15 @@ CONFIG="--configfile=$PREFIX/simple-dc/etc/smb.conf"
 testit "user add" $PYTHON $samba_tool user create $CONFIG --given-name="User" --surname="Tester" --initial="UT" testuser testp at ssw0Rd
 testit "user add" $PYTHON $samba_tool user create $CONFIG --given-name="User1" --surname="Tester" --initial="UT" testuser1 testp at ssw0Rd
 
+# test samba-tool user getgroups command
+user_getgroups_primary_only() {
+	res=$($PYTHON $samba_tool user getgroups $CONFIG testuser)
+
+	primary_group=$(echo $res)
+	echo $primary_group | grep -q "^Domain Users$" || return 1
+}
+testit "user getgroups primary only" user_getgroups_primary_only
+
 #test creation of six different groups
 testit "group add" $PYTHON $samba_tool group add $CONFIG --group-scope='Domain' --group-type='Security' --description='DomainSecurityGroup' --mail-address='dsg at samba.org' --notes='Notes' dsg
 testit "group add" $PYTHON $samba_tool group add $CONFIG --group-scope='Global' --group-type='Security' --description='GlobalSecurityGroup' --mail-address='gsg at samba.org' --notes='Notes' gsg
@@ -39,6 +49,38 @@ testit "group addmembers" $PYTHON $samba_tool group addmembers $CONFIG ddg testu
 testit "group addmembers" $PYTHON $samba_tool group addmembers $CONFIG gdg testuser,testuser1
 testit "group addmembers" $PYTHON $samba_tool group addmembers $CONFIG udg testuser,testuser1
 
+# test samba-tool user getgroups command
+user_getgroups() {
+	groups="dsg gsg usg ddg gdg udg"
+
+	res=$($PYTHON $samba_tool user getgroups $CONFIG testuser)
+	for g in $groups ; do
+		echo "$res" | grep -q "^${g}$" || return 1
+	done
+
+	# the users primary group is expected in the first line
+	primary_group=$(echo "$res" | head -1)
+	echo $primary_group | grep -q "^Domain Users$" || return 1
+}
+testit "user getgroups" user_getgroups
+
+# test settings a users primary group
+user_getgroups_primary_first() {
+	expected_primary_group=$1
+	res=$($PYTHON $samba_tool user getgroups $CONFIG testuser)
+
+	# the users primary group is expected in the first line
+	primary_group=$(echo "$res" | head -1)
+	echo $primary_group | grep -q "^${expected_primary_group}$" || return 1
+}
+testit "user setprimarygroup" $PYTHON $samba_tool user setprimarygroup $CONFIG testuser dsg
+testit "user getgroups primary first" user_getgroups_primary_first dsg
+testit "user setprimarygroup" $PYTHON $samba_tool user setprimarygroup $CONFIG testuser gsg
+testit "user getgroups primary first" user_getgroups_primary_first gsg
+
+# reset group (without testit, because I do not know how to quote the groupname)
+$PYTHON $samba_tool user setprimarygroup $CONFIG testuser 'Domain Users'
+
 #test removing test users from all groups by their username
 testit "group removemembers" $PYTHON $samba_tool group removemembers $CONFIG dsg testuser,testuser1
 testit "group removemembers" $PYTHON $samba_tool group removemembers $CONFIG gsg testuser,testuser1


-- 
Samba Shared Repository



More information about the samba-cvs mailing list