[SCM] Samba Shared Repository - branch master updated

Andreas Schneider asn at samba.org
Thu Oct 17 12:22:04 UTC 2019


The branch, master has been updated
       via  68155811aba samba-tool: Add facility to add rfc2307 attributes to an already created user or group
      from  aacbd383b9e samba-tool: Update 'samba-tool gpo list <>' description

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


- Log -----------------------------------------------------------------
commit 68155811aba10a498cc07bf8a1c6f3a092e6147c
Author: Rowland Penny <rowland at devstation.samdom.example.com>
Date:   Tue Jul 2 13:41:34 2019 +0100

    samba-tool: Add facility to add rfc2307 attributes to an already created user or group
    
    Signed-off-by: Rowland Penny <rpenny at samba.org>
    Reviewed-by: David Mulder <dmulder at suse.com>
    Reviewed-by: Andrew Bartlet <abartlet at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    
    Autobuild-User(master): Andreas Schneider <asn at cryptomilk.org>
    Autobuild-Date(master): Thu Oct 17 12:21:55 UTC 2019 on sn-devel-184

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

Summary of changes:
 python/samba/netcmd/group.py           |  96 ++++++++++++++
 python/samba/netcmd/user.py            | 224 +++++++++++++++++++++++++++++++++
 python/samba/tests/samba_tool/group.py | 102 ++++++++++++++-
 python/samba/tests/samba_tool/user.py  |  58 ++++++++-
 4 files changed, 473 insertions(+), 7 deletions(-)


Changeset truncated at 500 lines:

diff --git a/python/samba/netcmd/group.py b/python/samba/netcmd/group.py
index 536c1cba613..4798b773ddf 100644
--- a/python/samba/netcmd/group.py
+++ b/python/samba/netcmd/group.py
@@ -804,6 +804,101 @@ class cmd_group_edit(Command):
         self.outf.write("Modified group '%s' successfully\n" % groupname)
 
 
+class cmd_group_add_unix_attrs(Command):
+    """Add RFC2307 attributes to a group.
+
+This command adds Unix attributes to a group account in the Active
+Directory domain.
+The groupname specified on the command is the sAMaccountName.
+
+Unix (RFC2307) attributes will be added to the group account.
+
+Add 'idmap_ldb:use rfc2307 = Yes' to smb.conf to use these attributes for
+UID/GID mapping.
+
+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 group addunixattrs Group1 10000
+
+Example1 shows how to add RFC2307 attributes to a domain enabled group
+account.
+
+The groups Unix ID will be set to '10000', provided this ID isn't already
+in use.
+
+"""
+    synopsis = "%prog <groupname> <gidnumber> [options]"
+
+    takes_options = [
+        Option("-H", "--URL", help="LDB URL for database or target server",
+               type=str, metavar="URL", dest="H"),
+    ]
+
+    takes_args = ["groupname", "gidnumber"]
+
+    takes_optiongroups = {
+        "sambaopts": options.SambaOptions,
+        "credopts": options.CredentialsOptions,
+        "versionopts": options.VersionOptions,
+        }
+
+    def run(self, groupname, gidnumber, 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)
+
+        domaindn = samdb.domain_dn()
+
+        # Check group exists and doesn't have a gidNumber
+        filter = "(samaccountname={})".format(ldb.binary_encode(groupname))
+        res = samdb.search(domaindn,
+                           scope=ldb.SCOPE_SUBTREE,
+                           expression=filter)
+        if (len(res) == 0):
+            raise CommandError("Unable to find group '{}'".format(groupname))
+
+        group_dn = res[0].dn
+
+        if "gidNumber" in res[0]:
+            raise CommandError("Group {} is a Unix group.".format(groupname))
+
+        # Check if supplied gidnumber isn't already being used
+        filter = "(&(objectClass=group)(gidNumber={}))".format(gidnumber)
+        res = samdb.search(domaindn,
+                           scope=ldb.SCOPE_SUBTREE,
+                           expression=filter)
+        if (len(res) != 0):
+            raise CommandError('gidNumber {} already used.'.format(gidnumber))
+
+        if not lp.get("idmap_ldb:use rfc2307"):
+            self.outf.write("You are setting a Unix/RFC2307 GID. "
+                            "You may want to set 'idmap_ldb:use rfc2307 = Yes'"
+                            " in smb.conf to use the attributes for "
+                            "XID/SID-mapping.\n")
+
+        group_mod = """
+dn: {0}
+changetype: modify
+add: gidNumber
+gidNumber: {1}
+""".format(group_dn, gidnumber)
+
+        try:
+            samdb.modify_ldif(group_mod)
+        except ldb.LdbError as e:
+            raise CommandError("Failed to modify group '{0}': {1}"
+                               .format(groupname, e))
+
+        self.outf.write("Modified Group '{}' successfully\n".format(groupname))
+
+
 class cmd_group(SuperCommand):
     """Group management."""
 
@@ -818,3 +913,4 @@ class cmd_group(SuperCommand):
     subcommands["move"] = cmd_group_move()
     subcommands["show"] = cmd_group_show()
     subcommands["stats"] = cmd_group_stats()
+    subcommands["addunixattrs"] = cmd_group_add_unix_attrs()
diff --git a/python/samba/netcmd/user.py b/python/samba/netcmd/user.py
index 6730ab718de..affbbf067c1 100644
--- a/python/samba/netcmd/user.py
+++ b/python/samba/netcmd/user.py
@@ -2603,6 +2603,229 @@ class cmd_user_move(Command):
                         (username, full_new_parent_dn))
 
 
+class cmd_user_add_unix_attrs(Command):
+    """Add RFC2307 attributes to a user.
+
+This command adds Unix attributes to a user account in the Active
+Directory domain.
+
+The username specified on the command is the sAMaccountName.
+
+You must supply a unique uidNumber.
+
+Unix (RFC2307) attributes will be added to the user account.
+
+If you supply a gidNumber with '--gid-number', this will be used for the
+users Unix 'gidNumber' attribute.
+
+If '--gid-number' is not supplied, the users Unix gidNumber will be set to the
+one found in 'Domain Users', this means Domain Users must have a gidNumber
+attribute.
+
+if '--unix-home' is not supplied, the users Unix home directory will be
+set to /home/DOMAIN/username
+
+if '--login-shell' is not supplied, the users Unix login shell will be
+set to '/bin/sh'
+
+if ---gecos' is not supplied, the users Unix gecos field will be set to the
+users 'CN'
+
+Add 'idmap_ldb:use rfc2307 = Yes' to the smb.conf on DCs, to use these
+attributes for UID/GID mapping.
+
+The command may be run from the root userid or another authorised userid.
+The -H or --URL= option can be used to execute the command against a
+remote server.
+
+Example1:
+samba-tool user addunixattrs User1 10001
+
+Example1 shows how to add RFC2307 attributes to a domain enabled user
+account, Domain Users will be set as the users gidNumber.
+
+The users Unix ID will be set to '10001', provided this ID isn't already
+in use.
+
+Example2:
+samba-tool user addunixattrs User2 10002 --gid-number=10001 \
+--unix-home=/home/User2
+
+Example2 shows how to add RFC2307 attributes to a domain enabled user
+account.
+
+The users Unix ID will be set to '10002', provided this ID isn't already
+in use.
+
+The users gidNumber attribute will be set to '10001'
+
+The users Unix home directory will be set to '/home/user2'
+
+Example3:
+samba-tool user addunixattrs User3 10003 --gid-number=10001 \
+--login-shell=/bin/false --gecos='User3 test'
+
+Example3 shows how to add RFC2307 attributes to a domain enabled user
+account.
+
+The users Unix ID will be set to '10003', provided this ID isn't already
+in use.
+
+The users gidNumber attribute will be set to '10001'
+
+The users Unix login shell will be set to '/bin/false'
+
+The users gecos field will be set to 'User3 test'
+
+Example4:
+samba-tool user addunixattrs User4 10004 --gid-number=10001 \
+--unix-home=/home/User4 --login-shell=/bin/bash --gecos='User4 test'
+
+Example4 shows how to add RFC2307 attributes to a domain enabled user
+account.
+
+The users Unix ID will be set to '10004', provided this ID isn't already
+in use.
+
+The users gidNumber attribute will be set to '10001'
+
+The users Unix home directory will be set to '/home/User4'
+
+The users Unix login shell will be set to '/bin/bash'
+
+The users gecos field will be set to 'User4 test'
+
+"""
+
+    synopsis = "%prog <username> <uid-number> [options]"
+
+    takes_options = [
+        Option("-H", "--URL", help="LDB URL for database or target server",
+               type=str, metavar="URL", dest="H"),
+        Option("--gid-number", help="User's Unix/RFC2307 GID", type=str),
+        Option("--unix-home", help="User's Unix/RFC2307 home directory",
+               type=str),
+        Option("--login-shell", help="User's Unix/RFC2307 login shell",
+               type=str),
+        Option("--gecos", help="User's Unix/RFC2307 GECOS field", type=str),
+        Option("--uid", help="User's Unix/RFC2307 username", type=str),
+    ]
+
+    takes_args = ["username", "uid-number"]
+
+    takes_optiongroups = {
+        "sambaopts": options.SambaOptions,
+        "credopts": options.CredentialsOptions,
+        "versionopts": options.VersionOptions,
+        }
+
+    def run(self, username, uid_number, credopts=None, sambaopts=None,
+            versionopts=None, H=None, gid_number=None, unix_home=None,
+            login_shell=None, gecos=None, uid=None):
+
+        lp = sambaopts.get_loadparm()
+        creds = credopts.get_credentials(lp)
+
+        samdb = SamDB(url=H, session_info=system_session(),
+                      credentials=creds, lp=lp)
+
+        domaindn = samdb.domain_dn()
+
+        # Check that uidNumber supplied isn't already in use
+        filter = ("(&(objectClass=person)(uidNumber={}))"
+                  .format(uid_number))
+        res = samdb.search(domaindn,
+                           scope=ldb.SCOPE_SUBTREE,
+                           expression=filter)
+        if (len(res) != 0):
+            raise CommandError("uidNumber {} is already being used."
+                               .format(uid_number))
+
+        # Check user exists and doesn't have a uidNumber
+        filter = "(samaccountname={})".format(ldb.binary_encode(username))
+        res = samdb.search(domaindn,
+                           scope=ldb.SCOPE_SUBTREE,
+                           expression=filter)
+        if (len(res) == 0):
+            raise CommandError("Unable to find user '{}'".format(username))
+
+        user_dn = res[0].dn
+
+        if "uidNumber" in res[0]:
+            raise CommandError("User {} is already a Unix user."
+                               .format(username))
+
+        if gecos is None:
+            gecos = res[0]["cn"][0]
+
+        if uid is None:
+            uid = res[0]["cn"][0]
+
+        if gid_number is None:
+            search_filter = ("(samaccountname={})"
+                              .format(ldb.binary_encode('Domain Users')))
+            try:
+                res = samdb.search(domaindn,
+                                   scope=ldb.SCOPE_SUBTREE,
+                                   expression=search_filter)
+                for msg in res:
+                    gid_number=msg.get('gidNumber')
+            except IndexError:
+                raise CommandError('Domain Users does not have a'
+                                   ' gidNumber attribute')
+
+        if login_shell is None:
+            login_shell = "/bin/sh"
+
+        if unix_home is None:
+            # obtain nETBIOS Domain Name
+            filter = "(&(objectClass=crossRef)(nETBIOSName=*))"
+            searchdn = ("CN=Partitions,CN=Configuration," + domaindn)
+            try:
+                res = samdb.search(searchdn,
+                                   scope=ldb.SCOPE_SUBTREE,
+                                   expression=filter)
+                unix_domain = res[0]["nETBIOSName"][0]
+            except IndexError:
+                raise CommandError('Unable to find Unix domain')
+
+            unix_home = "/home/{0}/{1}".format(unix_domain, username)
+
+        if not lp.get("idmap_ldb:use rfc2307"):
+            self.outf.write("You are setting a Unix/RFC2307 UID & GID. "
+                            "You may want to set 'idmap_ldb:use rfc2307 = Yes'"
+                            " in smb.conf to use the attributes for "
+                            "XID/SID-mapping.\n")
+
+        user_mod = """
+dn: {0}
+changetype: modify
+add: uidNumber
+uidNumber: {1}
+add: gidnumber
+gidNumber: {2}
+add: gecos
+gecos: {3}
+add: uid
+uid: {4}
+add: loginshell
+loginShell: {5}
+add: unixHomeDirectory
+unixHomeDirectory: {6}
+""".format(user_dn, uid_number, gid_number, gecos, uid, login_shell, unix_home)
+
+        samdb.transaction_start()
+        try:
+            samdb.modify_ldif(user_mod)
+        except ldb.LdbError as e:
+            raise CommandError("Failed to modify user '{0}': {1}"
+                               .format(username, e))
+        else:
+            samdb.transaction_commit()
+            self.outf.write("Modified User '{}' successfully\n"
+                            .format(username))
+
+
 class cmd_user(SuperCommand):
     """User management."""
 
@@ -2621,3 +2844,4 @@ class cmd_user(SuperCommand):
     subcommands["edit"] = cmd_user_edit()
     subcommands["show"] = cmd_user_show()
     subcommands["move"] = cmd_user_move()
+    subcommands["addunixattrs"] = cmd_user_add_unix_attrs()
diff --git a/python/samba/tests/samba_tool/group.py b/python/samba/tests/samba_tool/group.py
index e521c720b77..215219c3918 100644
--- a/python/samba/tests/samba_tool/group.py
+++ b/python/samba/tests/samba_tool/group.py
@@ -39,14 +39,29 @@ class GroupCmdTestCase(SambaToolCmdTest):
         self.groups.append(self._randomGroup({"name": "testgroup2"}))
         self.groups.append(self._randomGroup({"name": "testgroup3"}))
         self.groups.append(self._randomGroup({"name": "testgroup4"}))
-
-        # setup the 4 groups and ensure they are correct
+        self.groups.append(self._randomPosixGroup({"name": "posixgroup1"}))
+        self.groups.append(self._randomPosixGroup({"name": "posixgroup2"}))
+        self.groups.append(self._randomPosixGroup({"name": "posixgroup3"}))
+        self.groups.append(self._randomPosixGroup({"name": "posixgroup4"}))
+        self.groups.append(self._randomUnixGroup({"name": "unixgroup1"}))
+        self.groups.append(self._randomUnixGroup({"name": "unixgroup2"}))
+        self.groups.append(self._randomUnixGroup({"name": "unixgroup3"}))
+        self.groups.append(self._randomUnixGroup({"name": "unixgroup4"}))
+
+        # setup the 12 groups and ensure they are correct
         for group in self.groups:
-            (result, out, err) = self._create_group(group)
+            (result, out, err) = group["createGroupFn"](group)
 
             self.assertCmdSuccess(result, out, err)
             self.assertEquals(err, "", "There shouldn't be any error message")
-            self.assertIn("Added group %s" % group["name"], out)
+
+            if 'unix' in group["name"]:
+                self.assertIn("Modified Group '%s' successfully"
+                              % group["name"], out)
+            else:
+                self.assertIn("Added group %s" % group["name"], out)
+
+            group["checkGroupFn"](group)
 
             found = self._find_group(group["name"])
 
@@ -221,14 +236,72 @@ class GroupCmdTestCase(SambaToolCmdTest):
         self.assertIn("dn: CN=Domain Users,CN=Users,DC=samba,DC=example,DC=com", out)
 
     def _randomGroup(self, base={}):
-        """create a group with random attribute values, you can specify base attributes"""
+        """create a group with random attribute values, you can specify base
+ attributes"""
         group = {
             "name": self.randomName(),
             "description": self.randomName(count=100),
+            "createGroupFn": self._create_group,
+            "checkGroupFn": self._check_group,
+        }
+        group.update(base)
+        return group
+
+    def _randomPosixGroup(self, base={}):
+        """create a group with random attribute values and additional RFC2307
+        attributes, you can specify base attributes"""
+        group = self._randomGroup({})
+        group.update(base)
+        posixAttributes = {
+            "unixdomain": self.randomName(),
+            "gidNumber": self.randomXid(),
+            "createGroupFn": self._create_posix_group,
+            "checkGroupFn": self._check_posix_group,
+        }
+        group.update(posixAttributes)
+        group.update(base)
+        return group
+
+    def _randomUnixGroup(self, base={}):
+        """create a group with random attribute values and additional RFC2307
+        attributes, you can specify base attributes"""
+        group = self._randomGroup({})
+        group.update(base)
+        posixAttributes = {
+            "gidNumber": self.randomXid(),
+            "createGroupFn": self._create_unix_group,
+            "checkGroupFn": self._check_unix_group,
         }
+        group.update(posixAttributes)
         group.update(base)
         return group
 
+    def _check_group(self, group):
+        """ check if a group from SamDB has the same attributes as
+ its template """
+        found = self._find_group(group["name"])
+
+        self.assertEquals("%s" % found.get("name"), group["name"])
+        self.assertEquals("%s" % found.get("description"), group["description"])
+
+    def _check_posix_group(self, group):
+        """ check if a posix_group from SamDB has the same attributes as
+ its template """
+        found = self._find_group(group["name"])
+
+        self.assertEquals("%s" % found.get("gidNumber"), "%s" %
+                          group["gidNumber"])
+        self._check_group(group)
+
+    def _check_unix_group(self, group):
+        """ check if a unix_group from SamDB has the same attributes as its
+template """
+        found = self._find_group(group["name"])
+
+        self.assertEquals("%s" % found.get("gidNumber"), "%s" %
+                          group["gidNumber"])
+        self._check_group(group)
+
     def _create_group(self, group):
         return self.runsubcmd("group", "add", group["name"],
                               "--description=%s" % group["description"],
@@ -236,6 +309,25 @@ class GroupCmdTestCase(SambaToolCmdTest):
                               "-U%s%%%s" % (os.environ["DC_USERNAME"],
                                             os.environ["DC_PASSWORD"]))
 
+    def _create_posix_group(self, group):
+        """ create a new group with RFC2307 attributes """
+        return self.runsubcmd("group", "add", group["name"],
+                              "--description=%s" % group["description"],
+                              "--nis-domain=%s" % group["unixdomain"],
+                              "--gid-number=%s" % group["gidNumber"],
+                              "-H", "ldap://%s" % os.environ["DC_SERVER"],
+                              "-U%s%%%s" % (os.environ["DC_USERNAME"],
+                              os.environ["DC_PASSWORD"]))
+
+    def _create_unix_group(self, group):
+        """ Add RFC2307 attributes to a group"""
+        self._create_group(group)
+        return self.runsubcmd("group", "addunixattrs", group["name"],
+                              "%s" % group["gidNumber"],
+                              "-H", "ldap://%s" % os.environ["DC_SERVER"],
+                              "-U%s%%%s" % (os.environ["DC_USERNAME"],
+                              os.environ["DC_PASSWORD"]))
+
     def _find_group(self, name):
         search_filter = ("(&(sAMAccountName=%s)(objectCategory=%s,%s))" %
                          (ldb.binary_encode(name),
diff --git a/python/samba/tests/samba_tool/user.py b/python/samba/tests/samba_tool/user.py
index 7ae80876b2a..4ebc9eb3bab 100644
--- a/python/samba/tests/samba_tool/user.py
+++ b/python/samba/tests/samba_tool/user.py
@@ -50,14 +50,23 @@ class UserCmdTestCase(SambaToolCmdTest):
         self.users.append(self._randomPosixUser({"name": "posixuser2"}))
         self.users.append(self._randomPosixUser({"name": "posixuser3"}))
         self.users.append(self._randomPosixUser({"name": "posixuser4"}))
+        self.users.append(self._randomUnixUser({"name": "unixuser1"}))
+        self.users.append(self._randomUnixUser({"name": "unixuser2"}))
+        self.users.append(self._randomUnixUser({"name": "unixuser3"}))
+        self.users.append(self._randomUnixUser({"name": "unixuser4"}))


-- 
Samba Shared Repository



More information about the samba-cvs mailing list