diff options
author | Jelmer Vernooij <jelmer@samba.org> | 2007-12-27 23:31:59 -0600 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2007-12-27 17:36:06 -0600 |
commit | 8ad2a035e35284f50ed2650bb202f050416de248 (patch) | |
tree | 118cc59f67af69f090e0e806d2e2786969709a32 | |
parent | 18f9eaca071d031eb90185a1dec42d2f998d0b2c (diff) | |
download | samba-8ad2a035e35284f50ed2650bb202f050416de248.tar.gz samba-8ad2a035e35284f50ed2650bb202f050416de248.tar.bz2 samba-8ad2a035e35284f50ed2650bb202f050416de248.zip |
r26616: Support parsing of user data in SAmba 3 tdbsam.
(This used to be commit 2f33e0451d6699fed8bc9abfa2f331317502b358)
-rw-r--r-- | source4/scripting/python/samba/getopt.py | 2 | ||||
-rw-r--r-- | source4/scripting/python/samba/samba3.py | 139 | ||||
-rw-r--r-- | source4/scripting/python/samba/tests/samba3.py | 32 | ||||
-rw-r--r-- | source4/scripting/python/samba/upgrade.py | 53 |
4 files changed, 111 insertions, 115 deletions
diff --git a/source4/scripting/python/samba/getopt.py b/source4/scripting/python/samba/getopt.py index 3335c55bc6..014dd336d8 100644 --- a/source4/scripting/python/samba/getopt.py +++ b/source4/scripting/python/samba/getopt.py @@ -23,7 +23,7 @@ from credentials import Credentials class SambaOptions(optparse.OptionGroup): def __init__(self, parser): optparse.OptionGroup.__init__(self, parser, "Samba Common Options") - self.add_option("--configfile", type="string", metavar="FILE", + self.add_option("-s", "--configfile", type="string", metavar="FILE", help="Configuration file") diff --git a/source4/scripting/python/samba/samba3.py b/source4/scripting/python/samba/samba3.py index c9153d85cf..27656900ad 100644 --- a/source4/scripting/python/samba/samba3.py +++ b/source4/scripting/python/samba/samba3.py @@ -324,7 +324,8 @@ class SAMUser: 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): + 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 @@ -351,37 +352,16 @@ class SAMUser: 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.username == other.username and - self.uid == other.uid and - self.lm_password == other.lm_password and - self.nt_password == other.nt_password and - self.acct_ctrl == other.acct_ctrl and - self.pass_last_set_time == other.pass_last_set_time and - self.nt_username == other.nt_username and - self.fullname == other.fullname and - self.logon_time == other.logon_time and - self.logoff_time == other.logoff_time and - self.acct_desc == other.acct_desc and - self.group_rid == other.group_rid and - self.bad_password_count == other.bad_password_count and - self.logon_count == other.logon_count and - self.domain == other.domain and - self.dir_drive == other.dir_drive and - self.munged_dial == other.munged_dial and - self.homedir == other.homedir and - self.logon_script == other.logon_script and - self.profile_path == other.profile_path and - self.workstations == other.workstations and - self.kickoff_time == other.kickoff_time and - self.bad_password_time == other.bad_password_time and - self.pass_can_change_time == other.pass_can_change_time and - self.pass_must_change_time == other.pass_must_change_time and - self.user_rid == other.user_rid) - + return self.__dict__ == other.__dict__ class SmbpasswdFile: def __init__(self, file): @@ -451,7 +431,7 @@ class LdapSam: class TdbSam: def __init__(self, file): self.tdb = tdb.Tdb(file, flags=os.O_RDONLY) - self.version = self.tdb.fetch_uint32("INFO/version") or 0 + self.version = self.tdb.fetch_uint32("INFO/version\0") or 0 assert self.version in (0, 1, 2) def usernames(self): @@ -463,41 +443,82 @@ class TdbSam: def __getitem__(self, name): data = self.tdb["%s%s\0" % (TDBSAM_USER_PREFIX, name)] - import struct - (logon_time, logoff_time, kickoff_time, pass_last_set_time, pass_can_change_time, \ - pass_must_change_time) = struct.unpack("<llllll", data[:6*4]) user = SAMUser(name) - user.logon_time = logon_time + import struct + + 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 - user.pass_last_set_time = pass_last_set_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 -# &username_len, &sampass->username, /* B */ -# &domain_len, &sampass->domain, /* B */ -# &nt_username_len, &sampass->nt_username, /* B */ -# &fullname_len, &sampass->fullname, /* B */ -# &homedir_len, &sampass->homedir, /* B */ -# &dir_drive_len, &sampass->dir_drive, /* B */ -# &logon_script_len, &sampass->logon_script, /* B */ -# &profile_path_len, &sampass->profile_path, /* B */ -# &acct_desc_len, &sampass->acct_desc, /* B */ -# &workstations_len, &sampass->workstations, /* B */ -# &unknown_str_len, &sampass->unknown_str, /* B */ -# &munged_dial_len, &sampass->munged_dial, /* B */ -# &sampass->user_rid, /* d */ -# &sampass->group_rid, /* d */ -# &lm_pw_len, sampass->lm_pw.hash, /* B */ -# &nt_pw_len, sampass->nt_pw.hash, /* B */ -# &sampass->acct_ctrl, /* w */ -# &remove_me, /* remove on the next TDB_FORMAT upgarde */ /* d */ -# &sampass->logon_divs, /* w */ -# &sampass->hours_len, /* d */ -# &hourslen, &sampass->hours, /* B */ -# &sampass->bad_password_count, /* w */ -# &sampass->logon_count, /* w */ -# &sampass->unknown_6); /* d */ -# + (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 close(self): diff --git a/source4/scripting/python/samba/tests/samba3.py b/source4/scripting/python/samba/tests/samba3.py index 22b21ba1b4..175aa90497 100644 --- a/source4/scripting/python/samba/tests/samba3.py +++ b/source4/scripting/python/samba/tests/samba3.py @@ -107,9 +107,37 @@ class TdbSamTestCase(unittest.TestCase): self.assertEquals(3, len(list(self.samdb.usernames()))) def test_getuser(self): - return user = SAMUser("root") - self.assertEquals(user, self.samdb["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) class WinsDatabaseTestCase(unittest.TestCase): diff --git a/source4/scripting/python/samba/upgrade.py b/source4/scripting/python/samba/upgrade.py index 3ecfe872f9..abf1127c36 100644 --- a/source4/scripting/python/samba/upgrade.py +++ b/source4/scripting/python/samba/upgrade.py @@ -435,56 +435,3 @@ def import_registry(samba4_registry, samba3_regdb): key_handle.set_value(value_name, value_type, value_data) -def upgrade(subobj, samba3, message, paths, session_info, credentials): - ret = 0 - samdb = Ldb(paths.samdb, session_info=session_info, credentials=credentials) - - message("Writing configuration") - newconf = upgrade_smbconf(samba3.configuration,True) - newconf.save(paths.smbconf) - - message("Importing account policies") - samdb.modify_ldif(upgrade_sam_policy(samba3,subobj.BASEDN)) - regdb = Ldb(paths.hklm) - - regdb.modify(""" -dn: value=RefusePasswordChange,key=Parameters,key=Netlogon,key=Services,key=CurrentControlSet,key=System,HIVE=NONE -replace: type -type: 4 -replace: data -data: %d -""" % policy.refuse_machine_password_change) - - message("Importing users") - for account in samba3.samaccounts: - msg = "... " + account.username - ldif = upgrade_sam_account(samdb, accounts,subobj.BASEDN,subobj.DOMAINSID) - try: - samdb.add(ldif) - except LdbError, e: - # FIXME: Ignore 'Record exists' errors - msg += "... error: " + str(e) - ret += 1; - message(msg) - - message("Importing groups") - for mapping in samba3.groupmappings: - msg = "... " + mapping.nt_name - ldif = upgrade_sam_group(mapping, subobj.BASEDN) - if ldif is not None: - try: - samdb.add(ldif) - except LdbError, e: - # FIXME: Ignore 'Record exists' errors - msg += "... error: " + str(e) - ret += 1 - message(msg) - - message("Importing WINS data") - winsdb = Ldb(paths.winsdb) - ldb_erase(winsdb) - - ldif = upgrade_wins(samba3) - winsdb.add(ldif) - - |