svn commit: samba r26590 - in branches/SAMBA_4_0: . source/scripting/python/samba source/scripting/python/samba/tests

jelmer at samba.org jelmer at samba.org
Mon Dec 24 14:16:42 GMT 2007


Author: jelmer
Date: 2007-12-24 14:16:40 +0000 (Mon, 24 Dec 2007)
New Revision: 26590

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=26590

Log:
Parsing routines for the smbpasswd file and idmap database.

Modified:
   branches/SAMBA_4_0/
   branches/SAMBA_4_0/source/scripting/python/samba/samba3.py
   branches/SAMBA_4_0/source/scripting/python/samba/tests/samba3.py


Changeset:

Property changes on: branches/SAMBA_4_0
___________________________________________________________________
Name: bzr:revision-info
...skipped...
Name: bzr:revision-id:v3-trunk0
...skipped...

Modified: branches/SAMBA_4_0/source/scripting/python/samba/samba3.py
===================================================================
--- branches/SAMBA_4_0/source/scripting/python/samba/samba3.py	2007-12-24 13:06:57 UTC (rev 26589)
+++ branches/SAMBA_4_0/source/scripting/python/samba/samba3.py	2007-12-24 14:16:40 UTC (rev 26590)
@@ -108,17 +108,48 @@
 
 
 # High water mark keys
-HWM_GROUP = "GROUP HWM"
-HWM_USER = "USER HWM"
+IDMAP_HWM_GROUP = "GROUP HWM\0"
+IDMAP_HWM_USER = "USER HWM\0"
 
+IDMAP_GROUP_PREFIX = "GID "
+IDMAP_USER_PREFIX = "UID "
+
 # idmap version determines auto-conversion
-IDMAP_VERSION = 2
+IDMAP_VERSION_V2 = 2
 
 class IdmapDatabase:
     def __init__(self, file):
         self.tdb = tdb.Tdb(file, flags=os.O_RDONLY)
-        assert self.tdb.fetch_int32("IDMAP_VERSION") == IDMAP_VERSION
+        assert self.tdb.fetch_int32("IDMAP_VERSION\0") == IDMAP_VERSION_V2
 
+    def uids(self):
+        for k in self.tdb.keys():
+            if k.startswith(IDMAP_USER_PREFIX):
+                yield int(k[len(IDMAP_USER_PREFIX):].rstrip("\0"))
+
+    def gids(self):
+        for k in self.tdb.keys():
+            if k.startswith(IDMAP_GROUP_PREFIX):
+                yield int(k[len(IDMAP_GROUP_PREFIX):].rstrip("\0"))
+
+    def get_user_sid(self, uid):
+        data = self.tdb.get("%s%d\0" % (IDMAP_USER_PREFIX, uid))
+        if data is None:
+            return data
+        return data.rstrip("\0")
+
+    def get_group_sid(self, gid):
+        data = self.tdb.get("%s%d\0" % (IDMAP_GROUP_PREFIX, gid))
+        if data is None:
+            return data
+        return data.rstrip("\0")
+
+    def get_user_hwm(self):
+        return self.tdb.fetch_uint32(IDMAP_HWM_USER)
+
+    def get_group_hwm(self):
+        return self.tdb.fetch_uint32(IDMAP_HWM_GROUP)
+
     def close(self):
         self.tdb.close()
 
@@ -181,6 +212,7 @@
     def get_secdesc(self, name):
         secdesc = self.tdb.get("SECDESC/%s" % name)
         # FIXME: Run ndr_pull_security_descriptor
+        return secdesc
 
     def close(self):
         self.tdb.close()
@@ -220,11 +252,65 @@
         ' ': 0
         }
 
+def decode_acb(text):
+    assert not "[" in text and not "]" in text
+    ret = 0
+    for x in text:
+        ret |= acb_info_mapping[x]
+    return ret
 
-class Smbpasswd:
+
+class SmbpasswdFile:
     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] = (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 close(self): # For consistency
         pass
 
+
 TDBSAM_FORMAT_STRING_V0 = "ddddddBBBBBBBBBBBBddBBwdwdBwwd"
 TDBSAM_FORMAT_STRING_V1 = "dddddddBBBBBBBBBBBBddBBwdwdBwwd"
 TDBSAM_FORMAT_STRING_V2 = "dddddddBBBBBBBBBBBBddBBBwwdBwwd"

Modified: branches/SAMBA_4_0/source/scripting/python/samba/tests/samba3.py
===================================================================
--- branches/SAMBA_4_0/source/scripting/python/samba/tests/samba3.py	2007-12-24 13:06:57 UTC (rev 26589)
+++ branches/SAMBA_4_0/source/scripting/python/samba/tests/samba3.py	2007-12-24 14:16:40 UTC (rev 26590)
@@ -19,7 +19,7 @@
 
 import unittest
 from samba.samba3 import (GroupMappingDatabase, Registry, PolicyDatabase, SecretsDatabase, TdbSam,
-                          WinsDatabase)
+                          WinsDatabase, SmbpasswdFile, ACB_NORMAL, IdmapDatabase)
 import os
 
 DATADIR=os.path.join(os.path.dirname(__file__), "../../../../../testdata/samba3")
@@ -109,6 +109,51 @@
     def tearDown(self):
         self.winsdb.close()
 
-# FIXME: smbpasswd
-# FIXME: idmapdb
-# FIXME: Shares
+class SmbpasswdTestCase(unittest.TestCase):
+    def setUp(self):
+        self.samdb = SmbpasswdFile(os.path.join(DATADIR, "smbpasswd"))
+
+    def test_length(self):
+        self.assertEquals(3, len(self.samdb))
+
+    def test_get_user(self):
+        self.assertEquals((0, "552902031BEDE9EFAAD3B435B51404EE", "878D8014606CDA29677A44EFA1353FC7", ACB_NORMAL, int(1125418267)), self.samdb["rootpw"])
+
+    def tearDown(self):
+        self.samdb.close()
+
+
+class IdmapDbTestCase(unittest.TestCase):
+    def setUp(self):
+        self.idmapdb = IdmapDatabase(os.path.join(DATADIR, "winbindd_idmap.tdb"))
+
+    def test_user_hwm(self):
+        self.assertEquals(10000, self.idmapdb.get_user_hwm())
+
+    def test_group_hwm(self):
+        self.assertEquals(10002, self.idmapdb.get_group_hwm())
+
+    def test_uids(self):
+        self.assertEquals(1, len(list(self.idmapdb.uids())))
+
+    def test_gids(self):
+        self.assertEquals(3, len(list(self.idmapdb.gids())))
+
+    def test_get_user_sid(self):
+        self.assertEquals("S-1-5-21-58189338-3053988021-627566699-501", self.idmapdb.get_user_sid(65534))
+
+    def test_get_group_sid(self):
+        self.assertEquals("S-1-5-21-2447931902-1787058256-3961074038-3007", self.idmapdb.get_group_sid(10001))
+
+    def tearDown(self):
+        self.idmapdb.close()
+
+
+class ShareInfoTestCase(unittest.TestCase):
+    def setUp(self):
+        self.shareinfodb = ShareInfoDatabase(os.path.join(DATADIR, "share_info.tdb"))
+
+    # FIXME: needs proper data so it can be tested
+
+    def tearDown(self):
+        self.shareinfodb.close()



More information about the samba-cvs mailing list