summaryrefslogtreecommitdiffstats
path: root/source4/scripting/python/samba/samba3.py
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2007-12-27 03:09:49 -0600
committerStefan Metzmacher <metze@samba.org>2007-12-26 21:18:02 -0600
commit222262b54e74a01a66b3cbbea5502d4ce488905d (patch)
treed51f4307a93ae04cdd762d969db8b4a114ca365f /source4/scripting/python/samba/samba3.py
parentc4d3666ac2821518be57ca89d963f77bbddaedf4 (diff)
downloadsamba-222262b54e74a01a66b3cbbea5502d4ce488905d.tar.gz
samba-222262b54e74a01a66b3cbbea5502d4ce488905d.tar.xz
samba-222262b54e74a01a66b3cbbea5502d4ce488905d.zip
r26608: More improvements to the upgrade code.
(This used to be commit 7ea06d91f602f770f55a1171174f11b922fed8e7)
Diffstat (limited to 'source4/scripting/python/samba/samba3.py')
-rw-r--r--source4/scripting/python/samba/samba3.py165
1 files changed, 146 insertions, 19 deletions
diff --git a/source4/scripting/python/samba/samba3.py b/source4/scripting/python/samba/samba3.py
index df94f3503c1..c9153d85cf4 100644
--- a/source4/scripting/python/samba/samba3.py
+++ b/source4/scripting/python/samba/samba3.py
@@ -118,6 +118,15 @@ class GroupMappingDatabase:
if k.startswith(GROUP_PREFIX):
yield k[len(GROUP_PREFIX):].rstrip("\0")
+ def get_group(self, sid):
+ data = self.tdb.get("%s%s\0" % (GROUP_PREFIX, sid))
+ if data is None:
+ return data
+ import struct
+ (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):
for k in self.tdb.keys():
if k.startswith(MEMBEROF_PREFIX):
@@ -288,15 +297,15 @@ 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.
+ '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
}
@@ -308,6 +317,72 @@ def decode_acb(text):
return ret
+class SAMUser:
+ 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):
+ 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
+
+ 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)
+
+
class SmbpasswdFile:
def __init__(self, file):
self.users = {}
@@ -345,7 +420,7 @@ class SmbpasswdFile:
acct_ctrl &= ~ACB_NORMAL
acct_ctrl |= ACB_WSTRUST
- self.users[username] = (uid, lm_password, nt_password, acct_ctrl, last_change_time)
+ self.users[username] = SAMUser(username, uid, lm_password, nt_password, acct_ctrl, last_change_time)
f.close()
@@ -368,6 +443,11 @@ TDBSAM_FORMAT_STRING_V2 = "dddddddBBBBBBBBBBBBddBBBwwdBwwd"
TDBSAM_USER_PREFIX = "USER_"
+class LdapSam:
+ def __init__(self, url):
+ self.ldap_url = ldap_url
+
+
class TdbSam:
def __init__(self, file):
self.tdb = tdb.Tdb(file, flags=os.O_RDONLY)
@@ -380,6 +460,45 @@ class TdbSam:
yield k[len(TDBSAM_USER_PREFIX):].rstrip("\0")
__iter__ = usernames
+
+ 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
+ user.logoff_time = logoff_time
+ user.kickoff_time = kickoff_time
+ 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 */
+#
+ return user
def close(self):
self.tdb.close()
@@ -423,7 +542,7 @@ class WinsDatabase:
while "." in entries[i]:
ips.append(entries[i])
i+=1
- nb_flags = entries[i]
+ nb_flags = int(entries[i][:-1], 16)
assert not name in self.entries, "Name %s exists twice" % name
self.entries[name] = (ttl, ips, nb_flags)
f.close()
@@ -437,6 +556,9 @@ class WinsDatabase:
def __iter__(self):
return iter(self.entries)
+ def items(self):
+ return self.entries.items()
+
def close(self): # for consistency
pass
@@ -459,14 +581,19 @@ class Samba3:
def get_sam_db(self):
lp = self.get_conf()
backends = str(lp.get("passdb backend")).split(" ")
- if backends[0].startswith("smbpasswd"):
- if ":" in backends[0]:
- return SmbpasswdFile(self.libdir_path(backends[0][len("smbpasswd:"):]))
- return SmbpasswdFile(self.libdir_path("smbpasswd"))
- elif backends[0].startswith("tdbsam"):
- if ":" in backends[0]:
- return TdbSam(self.libdir_path(backends[0][len("tdbsam:"):]))
- return TdbSam(self.libdir_path("passdb.tdb"))
+ 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])