[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Thu Oct 18 01:52:02 MDT 2012


The branch, master has been updated
       via  64886e3 Warn when setting UID/GID without idmap_ldb:use rfc2307 = Yes
       via  071047e Tests for 'samba-tool user create' with RFC2307 attributes
       via  bfdaaf2 Set RFC2307 attributes in samba-tool create
       via  9eb022c provision: No longer use the wheel group in new AD Domains
      from  b557f34 s3:smbd: fix brace placements in validate_my_share_entries() for readability

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


- Log -----------------------------------------------------------------
commit 64886e312fe76145c2c4bc900b794274594368aa
Author: Alexander Wuerstlein <arw at arw.name>
Date:   Sun Sep 30 04:32:01 2012 +0200

    Warn when setting UID/GID without idmap_ldb:use rfc2307 = Yes
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    
    Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
    Autobuild-Date(master): Thu Oct 18 09:51:35 CEST 2012 on sn-devel-104

commit 071047e8953f36a4c71c30d9540323578a4204f2
Author: Alexander Wuerstlein <arw at arw.name>
Date:   Sun Sep 30 04:32:00 2012 +0200

    Tests for 'samba-tool user create' with RFC2307 attributes
    
    Check if attributes are correctly set and read from SamDB
    Test automatic creation of attributes from getpwent (NSS)
    Check if overriding NSS attributes works
    
    getpwent will be skipped if the current UID of the user running the
    tests has no passwd entry (getpwuid(geteuid())).
    
    If a user with the name of the current UID already exists in the
    directory, the getpwent test will fail. If that should happen, the
    test would need to be updated to use a nonexistent UID that is
    visible to the Python 'pwd' module.
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>

commit bfdaaf2327441c0cf909a70f9b3ca781caadbddc
Author: Alexander Wuerstlein <arw at arw.name>
Date:   Sun Sep 30 04:31:59 2012 +0200

    Set RFC2307 attributes in samba-tool create
    
    Optionally set RFC2307 (NIS Schema) attributes in samba-tool create.
    Mainly needed for UID mapping to be usable.
    Not all attributes are set-able, only harmless and non-overlapping
    ones (uid, uidNumber, gidNumber, loginShell, gecos). Description and
    homeDirectory should already be set, userPassword seems problematic.
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>

commit 9eb022c8c65663425e60a10a12c2ec52c3017a59
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue Oct 16 13:08:22 2012 +1100

    provision: No longer use the wheel group in new AD Domains
    
    The issue here is that if we set S-1-5-32-544 (administrators) to a
    GID only, then users cannot force a mandetory profile to be owned by
    administrators (which is a requirement).
    
    There is no particularly useful reason for us to enforce this matching
    a system group.
    
    Andrew Bartlett

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

Summary of changes:
 source4/scripting/bin/samba_upgradedns             |    2 +-
 source4/scripting/python/samba/netcmd/domain.py    |    5 +-
 source4/scripting/python/samba/netcmd/user.py      |   39 +++++-
 .../scripting/python/samba/provision/__init__.py   |   39 +++---
 source4/scripting/python/samba/samdb.py            |   26 ++++-
 source4/scripting/python/samba/tests/posixacl.py   |    8 +-
 .../python/samba/tests/samba_tool/base.py          |    6 +
 .../python/samba/tests/samba_tool/user.py          |  141 ++++++++++++++++++-
 source4/scripting/python/samba/upgrade.py          |    2 +-
 source4/scripting/python/samba/upgradehelpers.py   |    4 +-
 10 files changed, 230 insertions(+), 42 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/scripting/bin/samba_upgradedns b/source4/scripting/bin/samba_upgradedns
index 8304134..ba597cf 100755
--- a/source4/scripting/bin/samba_upgradedns
+++ b/source4/scripting/bin/samba_upgradedns
@@ -91,7 +91,7 @@ def fix_names(pnames):
     names.domaindn = pnames.domaindn[0]
     names.configdn = pnames.configdn[0]
     names.schemadn = pnames.schemadn[0]
-    names.wheel_gid = pnames.wheel_gid[0]
+    names.root_gid = pnames.root_gid
     names.serverdn = str(pnames.serverdn)
     return names
 
diff --git a/source4/scripting/python/samba/netcmd/domain.py b/source4/scripting/python/samba/netcmd/domain.py
index 6e3f35a..4ba305c 100644
--- a/source4/scripting/python/samba/netcmd/domain.py
+++ b/source4/scripting/python/samba/netcmd/domain.py
@@ -186,8 +186,6 @@ class cmd_domain_provision(Command):
                 help="choose 'root' unix username"),
          Option("--nobody", type="string", metavar="USERNAME",
                 help="choose 'nobody' user"),
-         Option("--wheel", type="string", metavar="GROUPNAME",
-                help="choose 'wheel' privileged group"),
          Option("--users", type="string", metavar="GROUPNAME",
                 help="choose 'users' group"),
          Option("--quiet", help="Be quiet", action="store_true"),
@@ -237,7 +235,6 @@ class cmd_domain_provision(Command):
             ldapadminpass=None,
             root=None,
             nobody=None,
-            wheel=None,
             users=None,
             quiet=None,
             blank=None,
@@ -393,7 +390,7 @@ class cmd_domain_provision(Command):
                   krbtgtpass=krbtgtpass, machinepass=machinepass,
                   dns_backend=dns_backend, dns_forwarder=dns_forwarder,
                   dnspass=dnspass, root=root, nobody=nobody,
-                  wheel=wheel, users=users,
+                  users=users,
                   serverrole=server_role, dom_for_fun_level=dom_for_fun_level,
                   backend_type=ldap_backend_type,
                   ldapadminpass=ldapadminpass, ol_mmr_urls=ol_mmr_urls,
diff --git a/source4/scripting/python/samba/netcmd/user.py b/source4/scripting/python/samba/netcmd/user.py
index 619fe30..9bb232b 100644
--- a/source4/scripting/python/samba/netcmd/user.py
+++ b/source4/scripting/python/samba/netcmd/user.py
@@ -19,6 +19,7 @@
 
 import samba.getopt as options
 import ldb
+import pwd
 from getpass import getpass
 from samba.auth import system_session
 from samba.samdb import SamDB
@@ -46,6 +47,8 @@ User accounts may represent physical entities, such as people or may be used as
 
 A user account enables a user to logon to a computer and domain with an identity that can be authenticated.  To maximize security, each user should have their own unique user account and password.  A user's access to domain resources is based on permissions assigned to the user account.
 
+Unix (RFC2307) attributes may be added to the user account. Attributes taken from NSS are obtained on the local machine. Explicitly given values override values obtained from NSS. Configure 'idmap_ldb:use rfc2307 = Yes' 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:
@@ -63,6 +66,11 @@ samba-tool user add User3 passw3rd --userou=OrgUnit
 
 Example3 shows how to create a new user in the OrgUnit organizational unit.
 
+Example4:
+samba-tool user create User4 passw4rd --rfc2307-from-nss --gecos 'some text'
+
+Example4 shows how to create a new user with Unix UID, GID and login-shell set from the local NSS and GECOS set to 'some text'.
+
 """
     synopsis = "%prog <username> [<password>] [options]"
 
@@ -96,6 +104,14 @@ Example3 shows how to create a new user in the OrgUnit organizational unit.
         Option("--internet-address", help="User's home page", type=str),
         Option("--telephone-number", help="User's phone number", type=str),
         Option("--physical-delivery-office", help="User's office location", type=str),
+        Option("--rfc2307-from-nss",
+                help="Copy Unix user attributes from NSS (will be overridden by explicit UID/GID/GECOS/shell)",
+                action="store_true"),
+        Option("--uid", help="User's Unix/RFC2307 username", type=str),
+        Option("--uid-number", help="User's Unix/RFC2307 numeric UID", type=int),
+        Option("--gid-number", help="User's Unix/RFC2307 primary GID number", type=int),
+        Option("--gecos", help="User's Unix/RFC2307 GECOS field", type=str),
+        Option("--login-shell", help="User's Unix/RFC2307 login shell", type=str),
     ]
 
     takes_args = ["username", "password?"]
@@ -113,7 +129,8 @@ Example3 shows how to create a new user in the OrgUnit organizational unit.
             script_path=None, home_drive=None, home_directory=None,
             job_title=None, department=None, company=None, description=None,
             mail_address=None, internet_address=None, telephone_number=None,
-            physical_delivery_office=None):
+            physical_delivery_office=None, rfc2307_from_nss=False,
+            uid=None, uid_number=None, gid_number=None, gecos=None, login_shell=None):
 
         if random_password:
             password = generate_random_password(128, 255)
@@ -127,9 +144,26 @@ Example3 shows how to create a new user in the OrgUnit organizational unit.
                 password = None
                 self.outf.write("Sorry, passwords do not match.\n")
 
+        if rfc2307_from_nss:
+                pwent = pwd.getpwnam(username)
+                if uid is None:
+                    uid = username
+                if uid_number is None:
+                    uid_number = pwent[2]
+                if gid_number is None:
+                    gid_number = pwent[3]
+                if gecos is None:
+                    gecos = pwent[4]
+                if login_shell is None:
+                    login_shell = pwent[6]
+
         lp = sambaopts.get_loadparm()
         creds = credopts.get_credentials(lp)
 
+        if uid_number or gid_number:
+            if not lp.get("idmap_ldb:use rfc2307"):
+                self.outf.write("You are setting a Unix/RFC2307 UID or GID. You may want to set 'idmap_ldb:use rfc2307 = Yes' to use those attributes for XID/SID-mapping.\n")
+
         try:
             samdb = SamDB(url=H, session_info=system_session(),
                           credentials=creds, lp=lp)
@@ -138,7 +172,8 @@ Example3 shows how to create a new user in the OrgUnit organizational unit.
                           profilepath=profile_path, homedrive=home_drive, scriptpath=script_path, homedirectory=home_directory,
                           jobtitle=job_title, department=department, company=company, description=description,
                           mailaddress=mail_address, internetaddress=internet_address,
-                          telephonenumber=telephone_number, physicaldeliveryoffice=physical_delivery_office)
+                          telephonenumber=telephone_number, physicaldeliveryoffice=physical_delivery_office,
+                          uid=uid, uidnumber=uid_number, gidnumber=gid_number, gecos=gecos, loginshell=login_shell)
         except Exception, e:
             raise CommandError("Failed to add user '%s': " % username, e)
 
diff --git a/source4/scripting/python/samba/provision/__init__.py b/source4/scripting/python/samba/provision/__init__.py
index d440b9f..f6c11b5 100644
--- a/source4/scripting/python/samba/provision/__init__.py
+++ b/source4/scripting/python/samba/provision/__init__.py
@@ -240,12 +240,16 @@ def find_provision_key_parameters(samdb, secretsdb, idmapdb, paths, smbconf,
         names.policyid_dc = str(res8[0]["cn"]).replace("{","").replace("}","")
     else:
         names.policyid_dc = None
-    res9 = idmapdb.search(expression="(cn=%s)" %
-                            (security.SID_BUILTIN_ADMINISTRATORS),
-                            attrs=["xidNumber"])
+
+    res9 = idmapdb.search(expression="(cn=%s-%s)" %
+                          (str(names.domainsid), security.DOMAIN_RID_ADMINISTRATOR),
+                          attrs=["xidNumber", "type"])
     if len(res9) != 1:
-        raise ProvisioningError("Unable to find uid/gid for Domain Admins rid")
-    names.wheel_gid = res9[0]["xidNumber"]
+        raise ProvisioningError("Unable to find uid/gid for Domain Admins rid (%s-%s" % (str(names.domainsid), security.DOMAIN_RID_ADMINISTRATOR))
+    if res9[0]["type"][0] == "ID_TYPE_BOTH":
+        names.root_gid = res9[0]["xidNumber"][0]
+    else:
+        names.root_gid = pwd.getpwuid(int(res9[0]["xidNumber"][0])).pw_gid
     return names
 
 
@@ -683,7 +687,7 @@ def make_smbconf(smbconf, hostname, domain, realm, targetdir,
 
 
 def setup_name_mappings(idmap, sid, root_uid, nobody_uid,
-                        users_gid, wheel_gid):
+                        users_gid, root_gid):
     """setup reasonable name mappings for sam names to unix names.
 
     :param samdb: SamDB object.
@@ -693,10 +697,9 @@ def setup_name_mappings(idmap, sid, root_uid, nobody_uid,
     :param root_uid: uid of the UNIX root user.
     :param nobody_uid: uid of the UNIX nobody user.
     :param users_gid: gid of the UNIX users group.
-    :param wheel_gid: gid of the UNIX wheel group.
+    :param root_gid: gid of the UNIX root group.
     """
     idmap.setup_name_mapping("S-1-5-7", idmap.TYPE_UID, nobody_uid)
-    idmap.setup_name_mapping("S-1-5-32-544", idmap.TYPE_GID, wheel_gid)
 
     idmap.setup_name_mapping(sid + "-500", idmap.TYPE_UID, root_uid)
     idmap.setup_name_mapping(sid + "-513", idmap.TYPE_GID, users_gid)
@@ -1640,7 +1643,7 @@ def provision_fill(samdb, secrets_ldb, logger, names, paths,
                            policyguid_dc)
         if not skip_sysvolacl:
             setsysvolacl(samdb, paths.netlogon, paths.sysvol, paths.root_uid,
-                         paths.wheel_gid, domainsid, names.dnsdomain,
+                         paths.root_gid, domainsid, names.dnsdomain,
                          names.domaindn, lp, use_ntvfs)
         else:
             logger.info("Setting acl on sysvol skipped")
@@ -1772,7 +1775,7 @@ def provision(logger, session_info, credentials, smbconf=None,
         krbtgtpass=None, domainguid=None, policyguid=None, policyguid_dc=None,
         dns_backend=None, dns_forwarder=None, dnspass=None,
         invocationid=None, machinepass=None, ntdsguid=None,
-        root=None, nobody=None, users=None, wheel=None, backup=None, aci=None,
+        root=None, nobody=None, users=None, backup=None, aci=None,
         serverrole=None, dom_for_fun_level=None, backend_type=None,
         sitename=None, ol_mmr_urls=None, ol_olc=None, slapd_path="/bin/false",
         useeadb=False, am_rodc=False, lp=None, use_ntvfs=False,
@@ -1802,10 +1805,8 @@ def provision(logger, session_info, credentials, smbconf=None,
     root_uid = findnss_uid([root or "root"])
     nobody_uid = findnss_uid([nobody or "nobody"])
     users_gid = findnss_gid([users or "users", 'users', 'other', 'staff'])
-    if wheel is None:
-        wheel_gid = findnss_gid(["wheel", "adm"])
-    else:
-        wheel_gid = findnss_gid([wheel])
+    root_gid = pwd.getpwuid(root_uid).pw_gid
+
     try:
         bind_gid = findnss_gid(["bind", "named"])
     except KeyError:
@@ -1868,7 +1869,7 @@ def provision(logger, session_info, credentials, smbconf=None,
 
     paths.bind_gid = bind_gid
     paths.root_uid = root_uid;
-    paths.wheel_gid = wheel_gid
+    paths.root_gid = root_gid
 
     if hostip is None:
         logger.info("Looking up IPv4 addresses")
@@ -1919,7 +1920,7 @@ def provision(logger, session_info, credentials, smbconf=None,
         file = tempfile.NamedTemporaryFile(dir=os.path.abspath(paths.sysvol))
         try:
             try:
-                smbd.set_simple_acl(file.name, 0755, wheel_gid)
+                smbd.set_simple_acl(file.name, 0755, root_gid)
             except Exception:
                 if not smbd.have_posix_acls():
                     # This clue is only strictly correct for RPM and
@@ -1929,7 +1930,7 @@ def provision(logger, session_info, credentials, smbconf=None,
 
                 raise ProvisioningError("Your filesystem or build does not support posix ACLs, which s3fs requires.  Try the mounting the filesystem with the 'acl' option.")
             try:
-                smbd.chown(file.name, root_uid, wheel_gid)
+                smbd.chown(file.name, root_uid, root_gid)
             except Exception:
                 raise ProvisioningError("Unable to chown a file on your filesystem.  You may not be running provision as root.")
         finally:
@@ -1993,7 +1994,7 @@ def provision(logger, session_info, credentials, smbconf=None,
 
         setup_name_mappings(idmap, sid=str(domainsid),
                             root_uid=root_uid, nobody_uid=nobody_uid,
-                            users_gid=users_gid, wheel_gid=wheel_gid)
+                            users_gid=users_gid, root_gid=root_gid)
 
         logger.info("Setting up SAM db")
         samdb = setup_samdb(paths.samdb, session_info,
@@ -2093,7 +2094,7 @@ def provision_become_dc(smbconf=None, targetdir=None,
         serverdn=None, domain=None, hostname=None, domainsid=None,
         adminpass=None, krbtgtpass=None, domainguid=None, policyguid=None,
         policyguid_dc=None, invocationid=None, machinepass=None, dnspass=None,
-        dns_backend=None, root=None, nobody=None, users=None, wheel=None,
+        dns_backend=None, root=None, nobody=None, users=None,
         backup=None, serverrole=None, ldap_backend=None,
         ldap_backend_type=None, sitename=None, debuglevel=1, use_ntvfs=False):
 
diff --git a/source4/scripting/python/samba/samdb.py b/source4/scripting/python/samba/samdb.py
index d83e0a6..0eb5a13 100644
--- a/source4/scripting/python/samba/samdb.py
+++ b/source4/scripting/python/samba/samdb.py
@@ -290,7 +290,8 @@ member: %s
             homedirectory=None, jobtitle=None, department=None, company=None,
             description=None, mailaddress=None, internetaddress=None,
             telephonenumber=None, physicaldeliveryoffice=None, sd=None,
-            setpassword=True):
+            setpassword=True, uidnumber=None, gidnumber=None, gecos=None,
+            loginshell=None, uid=None):
         """Adds a new user with additional parameters
 
         :param username: Name of the new user
@@ -316,6 +317,11 @@ member: %s
         :param physicaldeliveryoffice: Office location of the new user
         :param sd: security descriptor of the object
         :param setpassword: optionally disable password reset
+        :param uidnumber: RFC2307 Unix numeric UID of the new user
+        :param gidnumber: RFC2307 Unix primary GID of the new user
+        :param gecos: RFC2307 Unix GECOS field of the new user
+        :param loginshell: RFC2307 Unix login shell of the new user
+        :param uid: RFC2307 Unix username of the new user
         """
 
         displayname = ""
@@ -395,9 +401,27 @@ member: %s
         if sd is not None:
             ldbmessage["nTSecurityDescriptor"] = ndr_pack(sd)
 
+        ldbmessage2 = None
+        if any(map(lambda b: b is not None, (uid, uidnumber, gidnumber, gecos, loginshell))):
+            ldbmessage2 = ldb.Message()
+            ldbmessage2.dn = ldb.Dn(self, user_dn)
+            ldbmessage2["objectClass"] = ldb.MessageElement('posixAccount', ldb.FLAG_MOD_ADD, 'objectClass')
+            if uid is not None:
+                ldbmessage2["uid"] = ldb.MessageElement(str(uid), ldb.FLAG_MOD_REPLACE, 'uid')
+            if uidnumber is not None:
+                ldbmessage2["uidNumber"] = ldb.MessageElement(str(uidnumber), ldb.FLAG_MOD_REPLACE, 'uidNumber')
+            if gidnumber is not None:
+                ldbmessage2["gidNumber"] = ldb.MessageElement(str(gidnumber), ldb.FLAG_MOD_REPLACE, 'gidNumber')
+            if gecos is not None:
+                ldbmessage2["gecos"] = ldb.MessageElement(str(gecos), ldb.FLAG_MOD_REPLACE, 'gecos')
+            if loginshell is not None:
+                ldbmessage2["loginShell"] = ldb.MessageElement(str(loginshell), ldb.FLAG_MOD_REPLACE, 'loginShell')
+
         self.transaction_start()
         try:
             self.add(ldbmessage)
+            if ldbmessage2:
+                self.modify(ldbmessage2)
 
             # Sets the password for it
             if setpassword:
diff --git a/source4/scripting/python/samba/tests/posixacl.py b/source4/scripting/python/samba/tests/posixacl.py
index 066cc97..78a07f7 100644
--- a/source4/scripting/python/samba/tests/posixacl.py
+++ b/source4/scripting/python/samba/tests/posixacl.py
@@ -147,7 +147,7 @@ class PosixAclMappingTests(TestCase):
         (LA_uid,LA_type) = s4_passdb.sid_to_id(LA_sid)
         self.assertEquals(LA_type, idmap.ID_TYPE_UID)
         (BA_gid,BA_type) = s4_passdb.sid_to_id(BA_sid)
-        self.assertEquals(BA_type, idmap.ID_TYPE_GID)
+        self.assertEquals(BA_type, idmap.ID_TYPE_BOTH)
         (SO_gid,SO_type) = s4_passdb.sid_to_id(SO_sid)
         self.assertEquals(SO_type, idmap.ID_TYPE_BOTH)
         (SY_gid,SY_type) = s4_passdb.sid_to_id(SY_sid)
@@ -194,7 +194,7 @@ class PosixAclMappingTests(TestCase):
 # user::rwx
 # user:root:rwx (selftest user actually)
 # group::rwx
-# group:wheel:rwx
+# group:Local Admins:rwx
 # group:3000000:r-x
 # group:3000001:rwx
 # group:3000002:r-x
@@ -274,7 +274,7 @@ class PosixAclMappingTests(TestCase):
         (LA_uid,LA_type) = s4_passdb.sid_to_id(LA_sid)
         self.assertEquals(LA_type, idmap.ID_TYPE_UID)
         (BA_gid,BA_type) = s4_passdb.sid_to_id(BA_sid)
-        self.assertEquals(BA_type, idmap.ID_TYPE_GID)
+        self.assertEquals(BA_type, idmap.ID_TYPE_BOTH)
         (SO_gid,SO_type) = s4_passdb.sid_to_id(SO_sid)
         self.assertEquals(SO_type, idmap.ID_TYPE_BOTH)
         (SY_gid,SY_type) = s4_passdb.sid_to_id(SY_sid)
@@ -327,7 +327,7 @@ class PosixAclMappingTests(TestCase):
 # user::rwx
 # user:root:rwx (selftest user actually)
 # group::rwx
-# group:wheel:rwx
+# group:Local Admins:rwx
 # group:3000000:r-x
 # group:3000001:rwx
 # group:3000002:r-x
diff --git a/source4/scripting/python/samba/tests/samba_tool/base.py b/source4/scripting/python/samba/tests/samba_tool/base.py
index 489d6b5..26ce459 100644
--- a/source4/scripting/python/samba/tests/samba_tool/base.py
+++ b/source4/scripting/python/samba/tests/samba_tool/base.py
@@ -103,6 +103,12 @@ class SambaToolCmdTest(samba.tests.TestCase):
         name += ''.join(random.choice(string.ascii_uppercase + string.ascii_lowercase+ string.digits) for x in range(count - 3))
         return name
 
+    def randomXid(self):
+        # pick some hopefully unused, high UID/GID range to avoid interference
+        # from the system the test runs on
+        xid = random.randint(4711000, 4799000)
+        return xid
+
     def assertWithin(self, val1, val2, delta, msg=""):
         """Assert that val1 is within delta of val2, useful for time computations"""
         self.assertTrue(((val1 + delta) > val2) and ((val1 - delta) < val2), msg)
diff --git a/source4/scripting/python/samba/tests/samba_tool/user.py b/source4/scripting/python/samba/tests/samba_tool/user.py
index 1466b2f..ab95514 100644
--- a/source4/scripting/python/samba/tests/samba_tool/user.py
+++ b/source4/scripting/python/samba/tests/samba_tool/user.py
@@ -38,22 +38,21 @@ class UserCmdTestCase(SambaToolCmdTest):
         self.users.append(self._randomUser({"name": "sambatool2", "company": "comp1"}))
         self.users.append(self._randomUser({"name": "sambatool3", "company": "comp2"}))
         self.users.append(self._randomUser({"name": "sambatool4", "company": "comp2"}))
+        self.users.append(self._randomPosixUser({"name": "posixuser1"}))
+        self.users.append(self._randomPosixUser({"name": "posixuser2"}))
+        self.users.append(self._randomPosixUser({"name": "posixuser3"}))
+        self.users.append(self._randomPosixUser({"name": "posixuser4"}))
 
-        # setup the 4 users and ensure they are correct
+        # setup the 8 users and ensure they are correct
         for user in self.users:
-            (result, out, err) = self._create_user(user)
+            (result, out, err) = user["createUserFn"](user)
 
             self.assertCmdSuccess(result)
             self.assertEquals(err,"","Shouldn't be any error messages")
             self.assertIn("User '%s' created successfully" % user["name"], out)
 
-            found = self._find_user(user["name"])
+            user["checkUserFn"](user)
 
-            self.assertEquals("%s" % found.get("name"), "%(given-name)s %(surname)s" % user)
-            self.assertEquals("%s" % found.get("title"), user["job-title"])
-            self.assertEquals("%s" % found.get("company"), user["company"])
-            self.assertEquals("%s" % found.get("description"), user["description"])
-            self.assertEquals("%s" % found.get("department"), user["department"])
 
     def tearDown(self):
         super(UserCmdTestCase, self).tearDown()
@@ -198,7 +197,76 @@ class UserCmdTestCase(SambaToolCmdTest):
             name = userobj.get("samaccountname", idx=0)
             found = self.assertMatch(out, name,
                                      "user '%s' not found" % name)
+    def test_getpwent(self):
+        try:
+            import pwd
+        except ImportError:
+            self.skipTest("Skipping getpwent test, no 'pwd' module available")
+            return
+
+        # get the current user's data for the test
+        uid = os.geteuid()
+        try:
+            u = pwd.getpwuid(uid)
+        except KeyError:
+            self.skipTest("Skipping getpwent test, current EUID not found in NSS")
+            return
+
+        user = self._randomPosixUser({
+                        "name": u[0],
+                        "uid": u[0],
+                        "uidNumber": u[2],
+                        "gidNumber": u[3],
+                        "gecos": u[4],
+                        "loginShell": u[6],
+                        })
+        # check if --rfc2307-from-nss sets the same values as we got from pwd.getpwuid()
+        (result, out, err) = self.runsubcmd("user", "add", user["name"], user["password"],
+                                                "--surname=%s" % user["surname"],
+                                                "--given-name=%s" % user["given-name"],
+                                                "--job-title=%s" % user["job-title"],
+                                                "--department=%s" % user["department"],
+                                                "--description=%s" % user["description"],
+                                                "--company=%s" % user["company"],
+                                                "--rfc2307-from-nss",
+                                                "-H", "ldap://%s" % os.environ["DC_SERVER"],
+                                                "-U%s%%%s" % (os.environ["DC_USERNAME"], os.environ["DC_PASSWORD"]))
+
+        self.assertCmdSuccess(result)
+        self.assertEquals(err,"","Shouldn't be any error messages")
+        self.assertIn("User '%s' created successfully" % user["name"], out)
+
+        self._check_posix_user(user)
+        self.runsubcmd("user", "delete", user["name"])
+
+        # Check if overriding the attributes from NSS with explicit values works
+        #
+        # get a user with all random posix attributes
+        user = self._randomPosixUser({"name": u[0]})
+        # create a user with posix attributes from nss but override all of them with the
+        # random ones just obtained
+        (result, out, err) = self.runsubcmd("user", "add", user["name"], user["password"],
+                                                "--surname=%s" % user["surname"],
+                                                "--given-name=%s" % user["given-name"],
+                                                "--job-title=%s" % user["job-title"],
+                                                "--department=%s" % user["department"],
+                                                "--description=%s" % user["description"],
+                                                "--company=%s" % user["company"],
+                                                "--rfc2307-from-nss",
+                                                "--gecos=%s" % user["gecos"],
+                                                "--login-shell=%s" % user["loginShell"],
+                                                "--uid=%s" % user["uid"],
+                                                "--uid-number=%s" % user["uidNumber"],
+                                                "--gid-number=%s" % user["gidNumber"],
+                                                "-H", "ldap://%s" % os.environ["DC_SERVER"],
+                                                "-U%s%%%s" % (os.environ["DC_USERNAME"], os.environ["DC_PASSWORD"]))
+
+        self.assertCmdSuccess(result)
+        self.assertEquals(err,"","Shouldn't be any error messages")
+        self.assertIn("User '%s' created successfully" % user["name"], out)
 
+        self._check_posix_user(user)
+        self.runsubcmd("user", "delete", user["name"])
 
     def _randomUser(self, base={}):
         """create a user with random attribute values, you can specify base attributes"""
@@ -211,10 +279,51 @@ class UserCmdTestCase(SambaToolCmdTest):
             "department": self.randomName(),
             "company": self.randomName(),
             "description": self.randomName(count=100),
+            "createUserFn": self._create_user,
+            "checkUserFn": self._check_user,
             }
         user.update(base)
         return user
 
+    def _randomPosixUser(self, base={}):
+        """create a user with random attribute values and additional RFC2307
+        attributes, you can specify base attributes"""
+        user = self._randomUser({})
+        user.update(base)
+        posixAttributes = {
+            "uid": self.randomName(),


-- 
Samba Shared Repository


More information about the samba-cvs mailing list