summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
Diffstat (limited to 'source4')
-rw-r--r--source4/scripting/python/samba/samba3/__init__.py454
-rw-r--r--source4/scripting/python/samba/tests/samba3.py230
2 files changed, 117 insertions, 567 deletions
diff --git a/source4/scripting/python/samba/samba3/__init__.py b/source4/scripting/python/samba/samba3/__init__.py
index 385d9331ec..dd2f927aa4 100644
--- a/source4/scripting/python/samba/samba3/__init__.py
+++ b/source4/scripting/python/samba/samba3/__init__.py
@@ -26,6 +26,9 @@ import os
import struct
import tdb
+import passdb
+import param as s3param
+
def fetch_uint32(tdb, key):
try:
@@ -125,74 +128,6 @@ class Registry(TdbDatabase):
return ret
-class PolicyDatabase(TdbDatabase):
- """Samba 3 Account Policy database reader."""
- def __init__(self, file):
- """Open a policy database
-
- :param file: Path to the file to open.
- """
- super(PolicyDatabase, self).__init__(file)
- self.min_password_length = fetch_uint32(self.tdb, "min password length\x00")
- self.password_history = fetch_uint32(self.tdb, "password history\x00")
- self.user_must_logon_to_change_password = fetch_uint32(self.tdb, "user must logon to change pasword\x00")
- self.maximum_password_age = fetch_uint32(self.tdb, "maximum password age\x00")
- self.minimum_password_age = fetch_uint32(self.tdb, "minimum password age\x00")
- self.lockout_duration = fetch_uint32(self.tdb, "lockout duration\x00")
- self.reset_count_minutes = fetch_uint32(self.tdb, "reset count minutes\x00")
- self.bad_lockout_minutes = fetch_uint32(self.tdb, "bad lockout minutes\x00")
- self.disconnect_time = fetch_int32(self.tdb, "disconnect time\x00")
- self.refuse_machine_password_change = fetch_uint32(self.tdb, "refuse machine password change\x00")
-
- # FIXME: Read privileges as well
-
-
-GROUPDB_DATABASE_VERSION_V1 = 1 # native byte format.
-GROUPDB_DATABASE_VERSION_V2 = 2 # le format.
-
-GROUP_PREFIX = "UNIXGROUP/"
-
-# Alias memberships are stored reverse, as memberships. The performance
-# critical operation is to determine the aliases a SID is member of, not
-# listing alias members. So we store a list of alias SIDs a SID is member of
-# hanging of the member as key.
-MEMBEROF_PREFIX = "MEMBEROF/"
-
-class GroupMappingDatabase(TdbDatabase):
- """Samba 3 group mapping database reader."""
- def _check_version(self):
- assert fetch_int32(self.tdb, "INFO/version\x00") in (GROUPDB_DATABASE_VERSION_V1, GROUPDB_DATABASE_VERSION_V2)
-
- def groupsids(self):
- """Retrieve the SIDs for the groups in this database.
-
- :return: List with sids as strings.
- """
- for k in self.tdb.iterkeys():
- if k.startswith(GROUP_PREFIX):
- yield k[len(GROUP_PREFIX):].rstrip("\0")
-
- def get_group(self, sid):
- """Retrieve the group mapping information for a particular group.
-
- :param sid: SID of the group
- :return: None if the group can not be found, otherwise
- a tuple with gid, sid_name_use, the NT name and comment.
- """
- data = self.tdb.get("%s%s\0" % (GROUP_PREFIX, sid))
- if data is None:
- return data
- (gid, sid_name_use) = struct.unpack("<lL", data[0:8])
- (nt_name, comment, _) = data[8:].split("\0")
- return (gid, sid_name_use, nt_name, comment)
-
- def aliases(self):
- """Retrieve the aliases in this database."""
- for k in self.tdb.iterkeys():
- if k.startswith(MEMBEROF_PREFIX):
- yield k[len(MEMBEROF_PREFIX):].rstrip("\0")
-
-
# High water mark keys
IDMAP_HWM_GROUP = "GROUP HWM\0"
IDMAP_HWM_USER = "USER HWM\0"
@@ -229,6 +164,11 @@ class IdmapDatabase(TdbDatabase):
yield int(k[len(IDMAP_GROUP_PREFIX):].rstrip("\0"))
def get_sid(self, xid, id_type):
+ """Retrive SID associated with a particular id and type.
+
+ :param xid: UID or GID to retrive SID for.
+ :param id_type: Type of id specified - 'UID' or 'GID'
+ """
data = self.tdb.get("%s %s\0" % (id_type, str(xid)))
if data is None:
return data
@@ -354,266 +294,6 @@ class Shares(object):
return self.lp.__iter__()
-ACB_DISABLED = 0x00000001
-ACB_HOMDIRREQ = 0x00000002
-ACB_PWNOTREQ = 0x00000004
-ACB_TEMPDUP = 0x00000008
-ACB_NORMAL = 0x00000010
-ACB_MNS = 0x00000020
-ACB_DOMTRUST = 0x00000040
-ACB_WSTRUST = 0x00000080
-ACB_SVRTRUST = 0x00000100
-ACB_PWNOEXP = 0x00000200
-ACB_AUTOLOCK = 0x00000400
-ACB_ENC_TXT_PWD_ALLOWED = 0x00000800
-ACB_SMARTCARD_REQUIRED = 0x00001000
-ACB_TRUSTED_FOR_DELEGATION = 0x00002000
-ACB_NOT_DELEGATED = 0x00004000
-ACB_USE_DES_KEY_ONLY = 0x00008000
-ACB_DONT_REQUIRE_PREAUTH = 0x00010000
-ACB_PW_EXPIRED = 0x00020000
-ACB_NO_AUTH_DATA_REQD = 0x00080000
-
-acb_info_mapping = {
- 'N': ACB_PWNOTREQ, # 'N'o password.
- 'D': ACB_DISABLED, # 'D'isabled.
- 'H': ACB_HOMDIRREQ, # 'H'omedir required.
- 'T': ACB_TEMPDUP, # 'T'emp account.
- 'U': ACB_NORMAL, # 'U'ser account (normal).
- 'M': ACB_MNS, # 'M'NS logon user account. What is this ?
- 'W': ACB_WSTRUST, # 'W'orkstation account.
- 'S': ACB_SVRTRUST, # 'S'erver account.
- 'L': ACB_AUTOLOCK, # 'L'ocked account.
- 'X': ACB_PWNOEXP, # No 'X'piry on password
- 'I': ACB_DOMTRUST, # 'I'nterdomain trust account.
- ' ': 0
- }
-
-def decode_acb(text):
- """Decode a ACB field.
-
- :param text: ACB text
- :return: integer with flags set.
- """
- assert not "[" in text and not "]" in text
- ret = 0
- for x in text:
- ret |= acb_info_mapping[x]
- return ret
-
-
-class SAMUser(object):
- """Samba 3 SAM User.
-
- :note: Unknown or unset fields are set to None.
- """
- def __init__(self, name, uid=None, lm_password=None, nt_password=None, acct_ctrl=None,
- last_change_time=None, nt_username=None, fullname=None, logon_time=None, logoff_time=None,
- acct_desc=None, group_rid=None, bad_password_count=None, logon_count=None,
- domain=None, dir_drive=None, munged_dial=None, homedir=None, logon_script=None,
- profile_path=None, workstations=None, kickoff_time=None, bad_password_time=None,
- pass_last_set_time=None, pass_can_change_time=None, pass_must_change_time=None,
- user_rid=None, unknown_6=None, nt_password_history=None,
- unknown_str=None, hours=None, logon_divs=None):
- self.username = name
- self.uid = uid
- self.lm_password = lm_password
- self.nt_password = nt_password
- self.acct_ctrl = acct_ctrl
- self.pass_last_set_time = last_change_time
- self.nt_username = nt_username
- self.fullname = fullname
- self.logon_time = logon_time
- self.logoff_time = logoff_time
- self.acct_desc = acct_desc
- self.group_rid = group_rid
- self.bad_password_count = bad_password_count
- self.logon_count = logon_count
- self.domain = domain
- self.dir_drive = dir_drive
- self.munged_dial = munged_dial
- self.homedir = homedir
- self.logon_script = logon_script
- self.profile_path = profile_path
- self.workstations = workstations
- self.kickoff_time = kickoff_time
- self.bad_password_time = bad_password_time
- self.pass_can_change_time = pass_can_change_time
- self.pass_must_change_time = pass_must_change_time
- self.user_rid = user_rid
- self.unknown_6 = unknown_6
- self.nt_password_history = nt_password_history
- self.unknown_str = unknown_str
- self.hours = hours
- self.logon_divs = logon_divs
-
- def __eq__(self, other):
- if not isinstance(other, SAMUser):
- return False
- return self.__dict__ == other.__dict__
-
-
-class SmbpasswdFile(object):
- """Samba 3 smbpasswd file reader."""
- def __init__(self, file):
- self.users = {}
- f = open(file, 'r')
- for l in f.readlines():
- if len(l) == 0 or l[0] == "#":
- continue # Skip comments and blank lines
- parts = l.split(":")
- username = parts[0]
- uid = int(parts[1])
- acct_ctrl = 0
- last_change_time = None
- if parts[2] == "NO PASSWORD":
- acct_ctrl |= ACB_PWNOTREQ
- lm_password = None
- elif parts[2][0] in ("*", "X"):
- # No password set
- lm_password = None
- else:
- lm_password = parts[2]
-
- if parts[3][0] in ("*", "X"):
- # No password set
- nt_password = None
- else:
- nt_password = parts[3]
-
- if parts[4][0] == '[':
- assert "]" in parts[4]
- acct_ctrl |= decode_acb(parts[4][1:-1])
- if parts[5].startswith("LCT-"):
- last_change_time = int(parts[5][len("LCT-"):], 16)
- else: # old style file
- if username[-1] == "$":
- acct_ctrl &= ~ACB_NORMAL
- acct_ctrl |= ACB_WSTRUST
-
- self.users[username] = SAMUser(username, uid, lm_password, nt_password, acct_ctrl, last_change_time)
-
- f.close()
-
- def __len__(self):
- return len(self.users)
-
- def __getitem__(self, name):
- return self.users[name]
-
- def __iter__(self):
- return iter(self.users)
-
- def close(self): # For consistency
- pass
-
-
-TDBSAM_FORMAT_STRING_V0 = "ddddddBBBBBBBBBBBBddBBwdwdBwwd"
-TDBSAM_FORMAT_STRING_V1 = "dddddddBBBBBBBBBBBBddBBwdwdBwwd"
-TDBSAM_FORMAT_STRING_V2 = "dddddddBBBBBBBBBBBBddBBBwwdBwwd"
-TDBSAM_USER_PREFIX = "USER_"
-
-
-class LdapSam(object):
- """Samba 3 LDAP passdb backend reader."""
- def __init__(self, url):
- self.ldap_url = url
-
-
-class TdbSam(TdbDatabase):
- """Samba 3 TDB passdb backend reader."""
- def _check_version(self):
- self.version = fetch_uint32(self.tdb, "INFO/version\0") or 0
- assert self.version in (0, 1, 2)
-
- def usernames(self):
- """Iterate over the usernames in this Tdb database."""
- for k in self.tdb.iterkeys():
- if k.startswith(TDBSAM_USER_PREFIX):
- yield k[len(TDBSAM_USER_PREFIX):].rstrip("\0")
-
- __iter__ = usernames
-
- def __getitem__(self, name):
- data = self.tdb["%s%s\0" % (TDBSAM_USER_PREFIX, name)]
- user = SAMUser(name)
-
- def unpack_string(data):
- (length, ) = struct.unpack("<L", data[:4])
- data = data[4:]
- if length == 0:
- return (None, data)
- return (data[:length].rstrip("\0"), data[length:])
-
- def unpack_int32(data):
- (value, ) = struct.unpack("<l", data[:4])
- return (value, data[4:])
-
- def unpack_uint32(data):
- (value, ) = struct.unpack("<L", data[:4])
- return (value, data[4:])
-
- def unpack_uint16(data):
- (value, ) = struct.unpack("<H", data[:2])
- return (value, data[2:])
-
- (logon_time, data) = unpack_int32(data)
- (logoff_time, data) = unpack_int32(data)
- (kickoff_time, data) = unpack_int32(data)
-
- if self.version > 0:
- (bad_password_time, data) = unpack_int32(data)
- if bad_password_time != 0:
- user.bad_password_time = bad_password_time
- (pass_last_set_time, data) = unpack_int32(data)
- (pass_can_change_time, data) = unpack_int32(data)
- (pass_must_change_time, data) = unpack_int32(data)
-
- if logon_time != 0:
- user.logon_time = logon_time
- user.logoff_time = logoff_time
- user.kickoff_time = kickoff_time
- if pass_last_set_time != 0:
- user.pass_last_set_time = pass_last_set_time
- user.pass_can_change_time = pass_can_change_time
-
- (user.username, data) = unpack_string(data)
- (user.domain, data) = unpack_string(data)
- (user.nt_username, data) = unpack_string(data)
- (user.fullname, data) = unpack_string(data)
- (user.homedir, data) = unpack_string(data)
- (user.dir_drive, data) = unpack_string(data)
- (user.logon_script, data) = unpack_string(data)
- (user.profile_path, data) = unpack_string(data)
- (user.acct_desc, data) = unpack_string(data)
- (user.workstations, data) = unpack_string(data)
- (user.unknown_str, data) = unpack_string(data)
- (user.munged_dial, data) = unpack_string(data)
-
- (user.user_rid, data) = unpack_int32(data)
- (user.group_rid, data) = unpack_int32(data)
-
- (user.lm_password, data) = unpack_string(data)
- (user.nt_password, data) = unpack_string(data)
-
- if self.version > 1:
- (user.nt_password_history, data) = unpack_string(data)
-
- (user.acct_ctrl, data) = unpack_uint16(data)
- (_, data) = unpack_uint32(data) # remove_me field
- (user.logon_divs, data) = unpack_uint16(data)
- (hours, data) = unpack_string(data)
- user.hours = []
- for entry in hours:
- for i in range(8):
- user.hours.append(ord(entry) & (2 ** i) == (2 ** i))
- (user.bad_password_count, data) = unpack_uint16(data)
- (user.logon_count, data) = unpack_uint16(data)
- (user.unknown_6, data) = unpack_uint32(data)
- assert len(data) == 0
- return user
-
-
def shellsplit(text):
"""Very simple shell-like line splitting.
@@ -675,139 +355,51 @@ class WinsDatabase(object):
pass
-class ParamFile(object):
- """Simple smb.conf-compatible file parser
-
- Does not use a parameter table, unlike the "normal".
- """
-
- def __init__(self, sections=None):
- self._sections = sections or {}
-
- def _sanitize_name(self, name):
- return name.strip().lower().replace(" ","")
-
- def __repr__(self):
- return "ParamFile(%r)" % self._sections
-
- def read(self, filename):
- """Read a file.
-
- :param filename: Path to the file
- """
- section = None
- for i, l in enumerate(open(filename, 'r').xreadlines()):
- l = l.strip()
- if not l or l[0] == '#' or l[0] == ';':
- continue
- if l[0] == "[" and l[-1] == "]":
- section = self._sanitize_name(l[1:-1])
- self._sections.setdefault(section, {})
- elif "=" in l:
- (k, v) = l.split("=", 1)
- self._sections[section][self._sanitize_name(k)] = v
- else:
- raise Exception("Unable to parser line %d: %r" % (i+1,l))
-
- def get(self, param, section=None):
- """Return the value of a parameter.
-
- :param param: Parameter name
- :param section: Section name, defaults to "global"
- :return: parameter value as string if found, None otherwise.
- """
- if section is None:
- section = "global"
- section = self._sanitize_name(section)
- if not section in self._sections:
- return None
- param = self._sanitize_name(param)
- if not param in self._sections[section]:
- return None
- return self._sections[section][param].strip()
-
- def __getitem__(self, section):
- return self._sections[section]
-
- def get_section(self, section):
- return self._sections.get(section)
-
- def add_section(self, section):
- self._sections[self._sanitize_name(section)] = {}
-
- def set_string(self, name, value):
- self._sections["global"][name] = value
-
- def get_string(self, name):
- return self._sections["global"].get(name)
-
-
class Samba3(object):
"""Samba 3 configuration and state data reader."""
- def __init__(self, libdir, smbconfpath):
+ def __init__(self, smbconfpath, s3_lp_ctx=None):
"""Open the configuration and data for a Samba 3 installation.
- :param libdir: Library directory
:param smbconfpath: Path to the smb.conf file.
+ :param s3_lp_ctx: Samba3 Loadparm context
"""
self.smbconfpath = smbconfpath
- self.libdir = libdir
- self.lp = ParamFile()
- self.lp.read(self.smbconfpath)
- self.privatedir = self.lp.get("private dir") or libdir
+ if s3_lp_ctx:
+ self.lp = s3_lp_ctx
+ else:
+ self.lp = s3param.get_context()
+ self.lp.load(smbconfpath)
- def libdir_path(self, path):
+ def statedir_path(self, path):
if path[0] == "/" or path[0] == ".":
return path
- return os.path.join(self.libdir, path)
+ return os.path.join(self.lp.get("state directory"), path)
def privatedir_path(self, path):
if path[0] == "/" or path[0] == ".":
return path
- return os.path.join(self.privatedir, path)
+ return os.path.join(self.lp.get("private dir"), path)
def get_conf(self):
return self.lp
def get_sam_db(self):
- lp = self.get_conf()
- backends = (lp.get("passdb backend") or "").split(" ")
- if ":" in backends[0]:
- (name, location) = backends[0].split(":", 2)
- else:
- name = backends[0]
- location = None
- if name == "smbpasswd":
- return SmbpasswdFile(self.libdir_path(location or "smbpasswd"))
- elif name == "tdbsam":
- return TdbSam(self.libdir_path(location or "passdb.tdb"))
- elif name == "ldapsam":
- if location is not None:
- return LdapSam("ldap:%s" % location)
- return LdapSam(lp.get("ldap server"))
- else:
- raise NotImplementedError("unsupported passdb backend %s" % backends[0])
-
- def get_policy_db(self):
- return PolicyDatabase(self.libdir_path("account_policy.tdb"))
+ return passdb.PDB(self.lp.get('passdb backend'))
def get_registry(self):
- return Registry(self.libdir_path("registry.tdb"))
+ return Registry(self.statedir_path("registry.tdb"))
def get_secrets_db(self):
return SecretsDatabase(self.privatedir_path("secrets.tdb"))
def get_shareinfo_db(self):
- return ShareInfoDatabase(self.libdir_path("share_info.tdb"))
+ return ShareInfoDatabase(self.statedir_path("share_info.tdb"))
def get_idmap_db(self):
- return IdmapDatabase(self.libdir_path("winbindd_idmap.tdb"))
+ return IdmapDatabase(self.statedir_path("winbindd_idmap.tdb"))
def get_wins_db(self):
- return WinsDatabase(self.libdir_path("wins.dat"))
+ return WinsDatabase(self.statedir_path("wins.dat"))
def get_shares(self):
return Shares(self.get_conf(), self.get_shareinfo_db())
-
- def get_groupmapping_db(self):
- return GroupMappingDatabase(self.libdir_path("group_mapping.tdb"))
diff --git a/source4/scripting/python/samba/tests/samba3.py b/source4/scripting/python/samba/tests/samba3.py
index 3a4b851c75..03f1902142 100644
--- a/source4/scripting/python/samba/tests/samba3.py
+++ b/source4/scripting/python/samba/tests/samba3.py
@@ -19,11 +19,12 @@
"""Tests for samba.samba3."""
-from samba.samba3 import (GroupMappingDatabase, Registry, PolicyDatabase,
- SecretsDatabase, TdbSam)
-from samba.samba3 import (WinsDatabase, SmbpasswdFile, ACB_NORMAL,
- IdmapDatabase, SAMUser, ParamFile)
+from samba.samba3 import (Registry, SecretsDatabase)
+from samba.samba3 import (WinsDatabase, IdmapDatabase)
+from samba.samba3 import passdb
+from samba.samba3 import param as s3param
from samba.tests import TestCase
+from samba.dcerpc.security import dom_sid
import os
for p in [ "../../../../../testdata/samba3", "../../../../testdata/samba3" ]:
@@ -57,108 +58,111 @@ class RegistryTestCase(TestCase):
self.registry.values("HKLM/SYSTEM/CURRENTCONTROLSET/SERVICES/EVENTLOG"))
-class PolicyTestCase(TestCase):
+class PassdbTestCase(TestCase):
def setUp(self):
- super(PolicyTestCase, self).setUp()
- self.policy = PolicyDatabase(os.path.join(DATADIR, "account_policy.tdb"))
+ super (PassdbTestCase, self).setUp()
+ self.lp = s3param.get_context()
+ self.lp.load(os.path.join(DATADIR, "smb.conf"))
+ self.lp.set("private dir", DATADIR)
+ self.lp.set("state directory", DATADIR)
+ passdb.set_secrets_dir(DATADIR)
+ self.pdb = passdb.PDB("tdbsam")
- def test_policy(self):
- self.assertEquals(self.policy.min_password_length, 5)
- self.assertEquals(self.policy.minimum_password_age, 0)
- self.assertEquals(self.policy.maximum_password_age, 999999999)
- self.assertEquals(self.policy.refuse_machine_password_change, 0)
- self.assertEquals(self.policy.reset_count_minutes, 0)
- self.assertEquals(self.policy.disconnect_time, -1)
- self.assertEquals(self.policy.user_must_logon_to_change_password, None)
- self.assertEquals(self.policy.password_history, 0)
- self.assertEquals(self.policy.lockout_duration, 0)
- self.assertEquals(self.policy.bad_lockout_minutes, None)
+ def tearDown(self):
+ self.lp = []
+ self.pdb = []
+ super(PassdbTestCase, self).tearDown()
+ def test_param(self):
+ self.assertEquals("BEDWYR", self.lp.get("netbios name"))
+ self.assertEquals("SAMBA", self.lp.get("workgroup"))
+ self.assertEquals("USER", self.lp.get("security"))
-class GroupsTestCase(TestCase):
+ def test_policy(self):
+ policy = self.pdb.get_account_policy()
+ self.assertEquals(0, policy['bad lockout attempt'])
+ self.assertEquals(4294967295, policy['disconnect time'])
+ self.assertEquals(0, policy['lockout duration'])
+ self.assertEquals(999999999, policy['maximum password age'])
+ self.assertEquals(0, policy['minimum password age'])
+ self.assertEquals(5, policy['min password length'])
+ self.assertEquals(0, policy['password history'])
+ self.assertEquals(0, policy['refuse machine password change'])
+ self.assertEquals(0, policy['reset count minutes'])
+ self.assertEquals(0, policy['user must logon to change password'])
- def setUp(self):
- super(GroupsTestCase, self).setUp()
- self.groupdb = GroupMappingDatabase(os.path.join(DATADIR, "group_mapping.tdb"))
+ def test_get_sid(self):
+ domain_sid = passdb.get_global_sam_sid()
+ self.assertEquals(dom_sid("S-1-5-21-2470180966-3899876309-2637894779"), domain_sid)
- def tearDown(self):
- self.groupdb.close()
- super(GroupsTestCase, self).tearDown()
+ def test_usernames(self):
+ userlist = self.pdb.search_users(0)
+ self.assertEquals(3, len(userlist))
+
+ def test_getuser(self):
+ user = self.pdb.getsampwnam("root")
+
+ self.assertEquals(16, user.acct_ctrl)
+ self.assertEquals("", user.acct_desc)
+ self.assertEquals(0, user.bad_password_count)
+ self.assertEquals(0, user.bad_password_time)
+ self.assertEquals(0, user.code_page)
+ self.assertEquals(0, user.country_code)
+ self.assertEquals("", user.dir_drive)
+ self.assertEquals("BEDWYR", user.domain)
+ self.assertEquals("root", user.full_name)
+ self.assertEquals(dom_sid('S-1-5-21-2470180966-3899876309-2637894779-513'), user.group_sid)
+ self.assertEquals("\\\\BEDWYR\\root", user.home_dir)
+ self.assertEquals([-1 for i in range(21)], user.hours)
+ self.assertEquals(21, user.hours_len)
+ self.assertEquals(9223372036854775807, user.kickoff_time)
+ self.assertEquals(None, user.lanman_passwd)
+ self.assertEquals(9223372036854775807, user.logoff_time)
+ self.assertEquals(0, user.logon_count)
+ self.assertEquals(168, user.logon_divs)
+ self.assertEquals("", user.logon_script)
+ self.assertEquals(0, user.logon_time)
+ self.assertEquals("", user.munged_dial)
+ self.assertEquals('\x87\x8d\x80\x14`l\xda)gzD\xef\xa15?\xc7', user.nt_passwd)
+ self.assertEquals("", user.nt_username)
+ self.assertEquals(1125418267, user.pass_can_change_time)
+ self.assertEquals(1125418267, user.pass_last_set_time)
+ self.assertEquals(2125418266, user.pass_must_change_time)
+ self.assertEquals(None, user.plaintext_passwd)
+ self.assertEquals("\\\\BEDWYR\\root\\profile", user.profile_path)
+ self.assertEquals(None, user.pw_history)
+ self.assertEquals(dom_sid("S-1-5-21-2470180966-3899876309-2637894779-1000"), user.user_sid)
+ self.assertEquals("root", user.username)
+ self.assertEquals("", user.workstations)
def test_group_length(self):
- self.assertEquals(13, len(list(self.groupdb.groupsids())))
+ grouplist = self.pdb.enum_group_mapping()
+ self.assertEquals(13, len(grouplist))
def test_get_group(self):
- self.assertEquals((-1, 5L, 'Administrators', ''), self.groupdb.get_group("S-1-5-32-544"))
+ group = self.pdb.getgrsid(dom_sid("S-1-5-32-544"))
+ self.assertEquals("Administrators", group.nt_name)
+ self.assertEquals(4294967295, group.gid)
+ self.assertEquals(5, group.sid_name_use)
def test_groupsids(self):
- sids = list(self.groupdb.groupsids())
+ grouplist = self.pdb.enum_group_mapping()
+ sids = []
+ for g in grouplist:
+ sids.append(str(g.sid))
self.assertTrue("S-1-5-32-544" in sids)
+ self.assertTrue("S-1-5-32-545" in sids)
+ self.assertTrue("S-1-5-32-546" in sids)
+ self.assertTrue("S-1-5-32-548" in sids)
+ self.assertTrue("S-1-5-32-549" in sids)
+ self.assertTrue("S-1-5-32-550" in sids)
+ self.assertTrue("S-1-5-32-551" in sids)
def test_alias_length(self):
- self.assertEquals(0, len(list(self.groupdb.aliases())))
-
-
-class SecretsDbTestCase(TestCase):
-
- def setUp(self):
- super(SecretsDbTestCase, self).setUp()
- self.secretsdb = SecretsDatabase(os.path.join(DATADIR, "secrets.tdb"))
-
- def tearDown(self):
- self.secretsdb.close()
- super(SecretsDbTestCase, self).tearDown()
-
- def test_get_sid(self):
- self.assertTrue(self.secretsdb.get_sid("BEDWYR") is not None)
-
-
-class TdbSamTestCase(TestCase):
-
- def setUp(self):
- super(TdbSamTestCase, self).setUp()
- self.samdb = TdbSam(os.path.join(DATADIR, "passdb.tdb"))
-
- def tearDown(self):
- self.samdb.close()
- super(TdbSamTestCase, self).tearDown()
-
- def test_usernames(self):
- self.assertEquals(3, len(list(self.samdb.usernames())))
-
- def test_getuser(self):
- user = SAMUser("root")
- user.logoff_time = 2147483647
- user.kickoff_time = 2147483647
- user.pass_can_change_time = 1125418267
- user.username = "root"
- user.uid = None
- user.lm_password = 'U)\x02\x03\x1b\xed\xe9\xef\xaa\xd3\xb45\xb5\x14\x04\xee'
- user.nt_password = '\x87\x8d\x80\x14`l\xda)gzD\xef\xa15?\xc7'
- user.acct_ctrl = 16
- user.pass_last_set_time = 1125418267
- user.fullname = "root"
- user.nt_username = ""
- user.logoff_time = 2147483647
- user.acct_desc = ""
- user.group_rid = 1001
- user.logon_count = 0
- user.bad_password_count = 0
- user.domain = "BEDWYR"
- user.munged_dial = ""
- user.workstations = ""
- user.user_rid = 1000
- user.kickoff_time = 2147483647
- user.logoff_time = 2147483647
- user.unknown_6 = 1260L
- user.logon_divs = 0
- user.hours = [True for i in range(168)]
- other = self.samdb["root"]
- for name in other.__dict__:
- if other.__dict__[name] != user.__dict__[name]:
- print "%s: %r != %r" % (name, other.__dict__[name], user.__dict__[name])
- self.assertEquals(user, other)
+ aliaslist = self.pdb.search_aliases()
+ self.assertEquals(1, len(aliaslist))
+ self.assertEquals("Jelmers NT Group", aliaslist[0]['account_name'])
class WinsDatabaseTestCase(TestCase):
@@ -178,29 +182,6 @@ class WinsDatabaseTestCase(TestCase):
super(WinsDatabaseTestCase, self).tearDown()
-class SmbpasswdTestCase(TestCase):
-
- def setUp(self):
- super(SmbpasswdTestCase, self).setUp()
- self.samdb = SmbpasswdFile(os.path.join(DATADIR, "smbpasswd"))
-
- def test_length(self):
- self.assertEquals(3, len(self.samdb))
-
- def test_get_user(self):
- user = SAMUser("rootpw")
- user.lm_password = "552902031BEDE9EFAAD3B435B51404EE"
- user.nt_password = "878D8014606CDA29677A44EFA1353FC7"
- user.acct_ctrl = ACB_NORMAL
- user.pass_last_set_time = int(1125418267)
- user.uid = 0
- self.assertEquals(user, self.samdb["rootpw"])
-
- def tearDown(self):
- self.samdb.close()
- super(SmbpasswdTestCase, self).tearDown()
-
-
class IdmapDbTestCase(TestCase):
def setUp(self):
@@ -229,26 +210,3 @@ class IdmapDbTestCase(TestCase):
def tearDown(self):
self.idmapdb.close()
super(IdmapDbTestCase, self).tearDown()
-
-
-class ParamTestCase(TestCase):
-
- def test_init(self):
- file = ParamFile()
- self.assertTrue(file is not None)
-
- def test_add_section(self):
- file = ParamFile()
- file.add_section("global")
- self.assertTrue(file["global"] is not None)
-
- def test_set_param_string(self):
- file = ParamFile()
- file.add_section("global")
- file.set_string("data", "bar")
- self.assertEquals("bar", file.get_string("data"))
-
- def test_get_section(self):
- file = ParamFile()
- self.assertEquals(None, file.get_section("unknown"))
- self.assertRaises(KeyError, lambda: file["unknown"])