)
from samba.ndr import ndr_unpack
from samba.dcerpc import drsblobs
-from samba.compat import get_bytes
-from samba.compat import get_string
+from samba.common import get_bytes
+from samba.common import get_string
from samba.tests import env_loadparm
super(UserCmdTestCase, self).setUp()
self.samdb = self.getSamDB("-H", "ldap://%s" % os.environ["DC_SERVER"],
"-U%s%%%s" % (os.environ["DC_USERNAME"], os.environ["DC_PASSWORD"]))
+
+ # Modify the default template homedir
+ lp = self.get_loadparm()
+ self.template_homedir = lp.get('template homedir')
+ lp.set('template homedir', '/home/test/%D/%U')
+
self.users = []
self.users.append(self._randomUser({"name": "sambatool1", "company": "comp1"}))
self.users.append(self._randomUser({"name": "sambatool2", "company": "comp1"}))
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"}))
- # setup the 8 users and ensure they are correct
+ # setup the 12 users and ensure they are correct
for user in self.users:
(result, out, err) = user["createUserFn"](user)
self.assertCmdSuccess(result, out, err)
- self.assertEquals(err, "", "Shouldn't be any error messages")
- self.assertIn("User '%s' created successfully" % user["name"], out)
+ self.assertEqual(err, "", "Shouldn't be any error messages")
+ if 'unix' in user["name"]:
+ self.assertIn("Modified User '%s' successfully" % user["name"],
+ out)
+ else:
+ self.assertIn("User '%s' added successfully" % user["name"],
+ out)
user["checkUserFn"](user)
cachedb = lp.private_path("user-syncpasswords-cache.ldb")
if os.path.exists(cachedb):
os.remove(cachedb)
+ lp.set('template homedir', self.template_homedir)
def test_newuser(self):
# try to add all the users again, this should fail
"-U%s%%%s" % (os.environ["DC_USERNAME"], os.environ["DC_PASSWORD"]))
self.assertCmdSuccess(result, out, err)
- self.assertEquals(err, "", "Shouldn't be any error messages")
- self.assertIn("User '%s' created successfully" % user["name"], out)
+ self.assertEqual(err, "", "Shouldn't be any error messages")
+ self.assertIn("User '%s' added successfully" % user["name"], out)
found = self._find_user(user["name"])
- self.assertEquals("%s" % found.get("cn"), "%(name)s" % user)
- self.assertEquals("%s" % found.get("name"), "%(name)s" % user)
+ self.assertEqual("%s" % found.get("cn"), "%(name)s" % user)
+ self.assertEqual("%s" % found.get("name"), "%(name)s" % user)
def _verify_supplementalCredentials(self, ldif,
min_packages=3,
"-H", "ldap://%s" % os.environ["DC_SERVER"],
"-U%s%%%s" % (os.environ["DC_USERNAME"], os.environ["DC_PASSWORD"]))
self.assertCmdSuccess(result, out, err, "Ensure setpassword runs")
- self.assertEquals(err, "", "setpassword with url")
+ self.assertEqual(err, "", "setpassword with url")
self.assertMatch(out, "Changed password OK", "setpassword with url")
attributes = "sAMAccountName,unicodePwd,supplementalCredentials,virtualClearTextUTF8,virtualClearTextUTF16,virtualSSHA,virtualSambaGPG"
user["name"],
"--newpassword=%s" % newpasswd)
self.assertCmdSuccess(result, out, err, "Ensure setpassword runs")
- self.assertEquals(err, "", "setpassword without url")
+ self.assertEqual(err, "", "setpassword without url")
self.assertMatch(out, "Changed password OK", "setpassword without url")
(result, out, err) = self.runsubcmd("user", "syncpasswords", "--no-wait")
"-H", "ldap://%s" % os.environ["DC_SERVER"],
"-U%s%%%s" % (os.environ["DC_USERNAME"], os.environ["DC_PASSWORD"]))
self.assertCmdSuccess(result, out, err, "Ensure setpassword runs")
- self.assertEquals(err, "", "setpassword with forced change")
+ self.assertEqual(err, "", "setpassword with forced change")
self.assertMatch(out, "Changed password OK", "setpassword with forced change")
def test_setexpiry(self):
found = self.assertMatch(out, name,
"user '%s' not found" % name)
+
+ def test_list_base_dn(self):
+ base_dn = "CN=Users"
+ (result, out, err) = self.runsubcmd("user", "list", "-b", base_dn,
+ "-H", "ldap://%s" % os.environ["DC_SERVER"],
+ "-U%s%%%s" % (os.environ["DC_USERNAME"],
+ os.environ["DC_PASSWORD"]))
+ self.assertCmdSuccess(result, out, err, "Error running list")
+
+ search_filter = ("(&(objectClass=user)(userAccountControl:%s:=%u))" %
+ (ldb.OID_COMPARATOR_AND, dsdb.UF_NORMAL_ACCOUNT))
+
+ userlist = self.samdb.search(base=self.samdb.normalize_dn_in_domain(base_dn),
+ scope=ldb.SCOPE_SUBTREE,
+ expression=search_filter,
+ attrs=["samaccountname"])
+
+ self.assertTrue(len(userlist) > 0, "no users found in samdb")
+
+ for userobj in userlist:
+ name = str(userobj.get("samaccountname", idx=0))
+ found = self.assertMatch(out, name,
+ "user '%s' not found" % name)
+
+ def test_list_full_dn(self):
+ (result, out, err) = self.runsubcmd("user", "list", "--full-dn",
+ "-H", "ldap://%s" % os.environ["DC_SERVER"],
+ "-U%s%%%s" % (os.environ["DC_USERNAME"],
+ os.environ["DC_PASSWORD"]))
+ self.assertCmdSuccess(result, out, err, "Error running list")
+
+ search_filter = ("(&(objectClass=user)(userAccountControl:%s:=%u))" %
+ (ldb.OID_COMPARATOR_AND, dsdb.UF_NORMAL_ACCOUNT))
+
+ userlist = self.samdb.search(base=self.samdb.domain_dn(),
+ scope=ldb.SCOPE_SUBTREE,
+ expression=search_filter,
+ attrs=["dn"])
+
+ self.assertTrue(len(userlist) > 0, "no users found in samdb")
+
+ for userobj in userlist:
+ name = str(userobj.get("dn", idx=0))
+ found = self.assertMatch(out, name,
+ "user '%s' not found" % name)
+
def test_show(self):
for user in self.users:
(result, out, err) = self.runsubcmd(
def test_move(self):
full_ou_dn = str(self.samdb.normalize_dn_in_domain("OU=movetest"))
- (result, out, err) = self.runsubcmd("ou", "create", full_ou_dn)
+ (result, out, err) = self.runsubcmd("ou", "add", full_ou_dn)
self.assertCmdSuccess(result, out, err)
- self.assertEquals(err, "", "There shouldn't be any error message")
- self.assertIn('Created ou "%s"' % full_ou_dn, out)
+ self.assertEqual(err, "", "There shouldn't be any error message")
+ self.assertIn('Added ou "%s"' % full_ou_dn, out)
for user in self.users:
(result, out, err) = self.runsubcmd(
self.assertCmdSuccess(result, out, err,
"Failed to delete ou '%s'" % full_ou_dn)
+ def test_rename_surname_initials_givenname(self):
+ """rename the existing surname and given name and add missing
+ initials, then remove them, for all users"""
+ for user in self.users:
+ new_givenname = "new_given_name_of_" + user["name"]
+ new_initials = "A"
+ new_surname = "new_surname_of_" + user["name"]
+ found = self._find_user(user["name"])
+ old_cn = str(found.get("cn"))
+
+ # rename given name, initials and surname
+ (result, out, err) = self.runsubcmd("user", "rename", user["name"],
+ "--surname=%s" % new_surname,
+ "--initials=%s" % new_initials,
+ "--given-name=%s" % new_givenname)
+ self.assertCmdSuccess(result, out, err)
+ self.assertEqual(err, "", "Shouldn't be any error messages")
+ self.assertIn('successfully', out)
+
+ found = self._find_user(user["name"])
+ self.assertEqual("%s" % found.get("givenName"), new_givenname)
+ self.assertEqual("%s" % found.get("initials"), new_initials)
+ self.assertEqual("%s" % found.get("sn"), new_surname)
+ self.assertEqual("%s" % found.get("name"),
+ "%s %s. %s" % (new_givenname, new_initials, new_surname))
+ self.assertEqual("%s" % found.get("cn"),
+ "%s %s. %s" % (new_givenname, new_initials, new_surname))
+
+ # remove given name, initials and surname
+ (result, out, err) = self.runsubcmd("user", "rename", user["name"],
+ "--surname=",
+ "--initials=",
+ "--given-name=")
+ self.assertCmdSuccess(result, out, err)
+ self.assertEqual(err, "", "Shouldn't be any error messages")
+ self.assertIn('successfully', out)
+
+ found = self._find_user(user["name"])
+ self.assertEqual(found.get("givenName"), None)
+ self.assertEqual(found.get("initials"), None)
+ self.assertEqual(found.get("sn"), None)
+ self.assertEqual("%s" % found.get("cn"), user["name"])
+
+ # reset changes (initials are removed)
+ (result, out, err) = self.runsubcmd("user", "rename", user["name"],
+ "--surname=%(surname)s" % user,
+ "--given-name=%(given-name)s" % user)
+ self.assertCmdSuccess(result, out, err)
+
+ if old_cn:
+ (result, out, err) = self.runsubcmd("user", "rename", user["name"],
+ "--force-new-cn=%s" % old_cn)
+
+ def test_rename_cn_samaccountname(self):
+ """rename and try to remove the cn and the samaccount of all users"""
+ for user in self.users:
+ new_cn = "new_cn_of_" + user["name"]
+ new_samaccountname = "new_samaccount_of_" + user["name"]
+ new_surname = "new_surname_of_" + user["name"]
+
+ # rename cn
+ (result, out, err) = self.runsubcmd("user", "rename", user["name"],
+ "--samaccountname=%s"
+ % new_samaccountname,
+ "--force-new-cn=%s" % new_cn)
+ self.assertCmdSuccess(result, out, err)
+ self.assertEqual(err, "", "Shouldn't be any error messages")
+ self.assertIn('successfully', out)
+
+ found = self._find_user(new_samaccountname)
+ self.assertEqual("%s" % found.get("cn"), new_cn)
+ self.assertEqual("%s" % found.get("sAMAccountName"),
+ new_samaccountname)
+
+ # changing the surname has no effect to the cn
+ (result, out, err) = self.runsubcmd("user", "rename", new_samaccountname,
+ "--surname=%s" % new_surname)
+ self.assertCmdSuccess(result, out, err)
+
+ found = self._find_user(new_samaccountname)
+ self.assertEqual("%s" % found.get("cn"), new_cn)
+
+ # trying to remove cn (throws an error)
+ (result, out, err) = self.runsubcmd("user", "rename",
+ new_samaccountname,
+ "--force-new-cn=")
+ self.assertCmdFail(result)
+ self.assertIn('Failed to rename user', err)
+ self.assertIn("delete protected attribute", err)
+
+ # trying to remove the samccountname (throws an error)
+ (result, out, err) = self.runsubcmd("user", "rename",
+ new_samaccountname,
+ "--samaccountname=")
+ self.assertCmdFail(result)
+ self.assertIn('Failed to rename user', err)
+ self.assertIn('delete protected attribute', err)
+
+ # reset changes (cn must be the name)
+ (result, out, err) = self.runsubcmd("user", "rename", new_samaccountname,
+ "--samaccountname=%(name)s"
+ % user,
+ "--force-new-cn=%(name)s" % user)
+ self.assertCmdSuccess(result, out, err)
+
+ def test_rename_standard_cn(self):
+ """reset the cn of all users to the standard"""
+ for user in self.users:
+ new_cn = "new_cn_of_" + user["name"]
+ new_givenname = "new_given_name_of_" + user["name"]
+ new_initials = "A"
+ new_surname = "new_surname_of_" + user["name"]
+
+ # set different cn
+ (result, out, err) = self.runsubcmd("user", "rename", user["name"],
+ "--force-new-cn=%s" % new_cn)
+ self.assertCmdSuccess(result, out, err)
+
+ # remove given name, initials and surname
+ (result, out, err) = self.runsubcmd("user", "rename", user["name"],
+ "--surname=",
+ "--initials=",
+ "--given-name=")
+ self.assertCmdSuccess(result, out, err)
+
+ # reset the CN (no given name, initials or surname --> samaccountname)
+ (result, out, err) = self.runsubcmd("user", "rename", user["name"],
+ "--reset-cn")
+
+ self.assertCmdSuccess(result, out, err)
+ self.assertEqual(err, "", "Shouldn't be any error messages")
+ self.assertIn('successfully', out)
+
+ found = self._find_user(user["name"])
+ self.assertEqual("%s" % found.get("cn"), user["name"])
+
+ # set given name, initials and surname and set different cn
+ (result, out, err) = self.runsubcmd("user", "rename", user["name"],
+ "--force-new-cn=%s" % new_cn,
+ "--surname=%s" % new_surname,
+ "--initials=%s" % new_initials,
+ "--given-name=%s" % new_givenname)
+ self.assertCmdSuccess(result, out, err)
+
+ # reset the CN (given name, initials or surname are given --> given name)
+ (result, out, err) = self.runsubcmd("user", "rename", user["name"],
+ "--reset-cn")
+
+ self.assertCmdSuccess(result, out, err)
+ self.assertEqual(err, "", "Shouldn't be any error messages")
+ self.assertIn('successfully', out)
+
+ found = self._find_user(user["name"])
+ self.assertEqual("%s" % found.get("cn"),
+ "%s %s. %s" % (new_givenname, new_initials, new_surname))
+
+ # reset changes
+ (result, out, err) = self.runsubcmd("user", "rename", user["name"],
+ "--reset-cn",
+ "--initials=",
+ "--surname=%(surname)s" % user,
+ "--given-name=%(given-name)s" % user)
+ self.assertCmdSuccess(result, out, err)
+
+ def test_rename_mailaddress_displayname(self):
+ for user in self.users:
+ new_mail = "new_mailaddress_of_" + user["name"]
+ new_displayname = "new displayname of " + user["name"]
+
+ # change mail and displayname
+ (result, out, err) = self.runsubcmd("user", "rename", user["name"],
+ "--mail-address=%s"
+ % new_mail,
+ "--display-name=%s"
+ % new_displayname)
+ self.assertCmdSuccess(result, out, err)
+ self.assertEqual(err, "", "Shouldn't be any error messages")
+ self.assertIn('successfully', out)
+
+ found = self._find_user(user["name"])
+ self.assertEqual("%s" % found.get("mail"), new_mail)
+ self.assertEqual("%s" % found.get("displayName"), new_displayname)
+
+ # remove mail and displayname
+ (result, out, err) = self.runsubcmd("user", "rename", user["name"],
+ "--mail-address=",
+ "--display-name=")
+ self.assertCmdSuccess(result, out, err)
+ self.assertEqual(err, "", "Shouldn't be any error messages")
+ self.assertIn('successfully', out)
+
+ found = self._find_user(user["name"])
+ self.assertEqual(found.get("mail"), None)
+ self.assertEqual(found.get("displayName"), None)
+
+ def test_rename_upn(self):
+ """rename upn of all users"""
+ for user in self.users:
+ found = self._find_user(user["name"])
+ old_upn = "%s" % found.get("userPrincipalName")
+ valid_suffix = old_upn.split('@')[1] # samba.example.com
+
+ valid_new_upn = "new_%s@%s" % (user["name"], valid_suffix)
+ invalid_new_upn = "%s@invalid.suffix" + user["name"]
+
+ # trying to set invalid upn
+ (result, out, err) = self.runsubcmd("user", "rename", user["name"],
+ "--upn=%s"
+ % invalid_new_upn)
+ self.assertCmdFail(result)
+ self.assertIn('is not a valid upn', err)
+
+ # set valid upn
+ (result, out, err) = self.runsubcmd("user", "rename", user["name"],
+ "--upn=%s"
+ % valid_new_upn)
+ self.assertCmdSuccess(result, out, err)
+ self.assertEqual(err, "", "Shouldn't be any error messages")
+ self.assertIn('successfully', out)
+
+ found = self._find_user(user["name"])
+ self.assertEqual("%s" % found.get("userPrincipalName"), valid_new_upn)
+
+ # trying to remove upn
+ (result, out, err) = self.runsubcmd("user", "rename", user["name"],
+ "--upn=%s")
+ self.assertCmdFail(result)
+ self.assertIn('is not a valid upn', err)
+
+ # reset upn
+ (result, out, err) = self.runsubcmd("user", "rename", user["name"],
+ "--upn=%s" % old_upn)
+ self.assertCmdSuccess(result, out, err)
+
def test_getpwent(self):
try:
import pwd
"-U%s%%%s" % (os.environ["DC_USERNAME"], os.environ["DC_PASSWORD"]))
self.assertCmdSuccess(result, out, err)
- self.assertEquals(err, "", "Shouldn't be any error messages")
- self.assertIn("User '%s' created successfully" % user["name"], out)
+ self.assertEqual(err, "", "Shouldn't be any error messages")
+ self.assertIn("User '%s' added successfully" % user["name"], out)
self._check_posix_user(user)
self.runsubcmd("user", "delete", user["name"])
"-U%s%%%s" % (os.environ["DC_USERNAME"], os.environ["DC_PASSWORD"]))
self.assertCmdSuccess(result, out, err)
- self.assertEquals(err, "", "Shouldn't be any error messages")
- self.assertIn("User '%s' created successfully" % user["name"], out)
+ self.assertEqual(err, "", "Shouldn't be any error messages")
+ self.assertIn("User '%s' added successfully" % user["name"], out)
self._check_posix_user(user)
self.runsubcmd("user", "delete", user["name"])
user.update(base)
return user
+ def _randomUnixUser(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 = {
+ "uidNumber": self.randomXid(),
+ "gidNumber": self.randomXid(),
+ "uid": self.randomName(),
+ "loginShell": self.randomName(),
+ "gecos": self.randomName(),
+ "createUserFn": self._create_unix_user,
+ "checkUserFn": self._check_unix_user,
+ }
+ user.update(posixAttributes)
+ user.update(base)
+ return user
+
def _check_user(self, user):
""" check if a user from SamDB has the same attributes as its template """
found = self._find_user(user["name"])
- 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"])
+ self.assertEqual("%s" % found.get("name"), "%(given-name)s %(surname)s" % user)
+ self.assertEqual("%s" % found.get("title"), user["job-title"])
+ self.assertEqual("%s" % found.get("company"), user["company"])
+ self.assertEqual("%s" % found.get("description"), user["description"])
+ self.assertEqual("%s" % found.get("department"), user["department"])
def _check_posix_user(self, user):
""" check if a posix_user from SamDB has the same attributes as its template """
found = self._find_user(user["name"])
- self.assertEquals("%s" % found.get("loginShell"), user["loginShell"])
- self.assertEquals("%s" % found.get("gecos"), user["gecos"])
- self.assertEquals("%s" % found.get("uidNumber"), "%s" % user["uidNumber"])
- self.assertEquals("%s" % found.get("gidNumber"), "%s" % user["gidNumber"])
- self.assertEquals("%s" % found.get("uid"), user["uid"])
+ self.assertEqual("%s" % found.get("loginShell"), user["loginShell"])
+ self.assertEqual("%s" % found.get("gecos"), user["gecos"])
+ self.assertEqual("%s" % found.get("uidNumber"), "%s" % user["uidNumber"])
+ self.assertEqual("%s" % found.get("gidNumber"), "%s" % user["gidNumber"])
+ self.assertEqual("%s" % found.get("uid"), user["uid"])
+ self._check_user(user)
+
+ def _check_unix_user(self, user):
+ """ check if a unix_user from SamDB has the same attributes as its
+template """
+ found = self._find_user(user["name"])
+
+ self.assertEqual("%s" % found.get("loginShell"), user["loginShell"])
+ self.assertEqual("%s" % found.get("gecos"), user["gecos"])
+ self.assertEqual("%s" % found.get("uidNumber"), "%s" %
+ user["uidNumber"])
+ self.assertEqual("%s" % found.get("gidNumber"), "%s" %
+ user["gidNumber"])
+ self.assertEqual("%s" % found.get("uid"), user["uid"])
+ self.assertIn('/home/test/', "%s" % found.get("unixHomeDirectory"))
self._check_user(user)
def _create_user(self, user):
- return self.runsubcmd("user", "create", user["name"], user["password"],
+ return self.runsubcmd("user", "add", user["name"], user["password"],
"--surname=%s" % user["surname"],
"--given-name=%s" % user["given-name"],
"--job-title=%s" % user["job-title"],
"-H", "ldap://%s" % os.environ["DC_SERVER"],
"-U%s%%%s" % (os.environ["DC_USERNAME"], os.environ["DC_PASSWORD"]))
+ def _create_unix_user(self, user):
+ """ Add RFC2307 attributes to a user"""
+ self._create_user(user)
+ return self.runsubcmd("user", "addunixattrs", user["name"],
+ "%s" % user["uidNumber"],
+ "--gid-number=%s" % user["gidNumber"],
+ "--gecos=%s" % user["gecos"],
+ "--login-shell=%s" % user["loginShell"],
+ "--uid=%s" % user["uid"],
+ "-H", "ldap://%s" % os.environ["DC_SERVER"],
+ "-U%s%%%s" % (os.environ["DC_USERNAME"],
+ os.environ["DC_PASSWORD"]))
+
def _find_user(self, name):
search_filter = "(&(sAMAccountName=%s)(objectCategory=%s,%s))" % (ldb.binary_encode(name), "CN=Person,CN=Schema,CN=Configuration", self.samdb.domain_dn())
userlist = self.samdb.search(base=self.samdb.domain_dn(),
scope=ldb.SCOPE_SUBTREE,
- expression=search_filter, attrs=[])
+ expression=search_filter)
if userlist:
return userlist[0]
else: