1 | #!/usr/bin/python
|
---|
2 | #############################################################
|
---|
3 | # tdbutil
|
---|
4 | #
|
---|
5 | # Purpose:
|
---|
6 | # Contains functions that are used to pack and unpack data
|
---|
7 | # from Samba's tdb databases. Samba sometimes represents complex
|
---|
8 | # data structures as a single value in a database. These functions
|
---|
9 | # allow other python scripts to package data types into a single python
|
---|
10 | # string and unpackage them.
|
---|
11 | #
|
---|
12 | #
|
---|
13 | # XXXXX: This code is no longer used; it's just here for testing
|
---|
14 | # compatibility with the new (much faster) C implementation.
|
---|
15 | #
|
---|
16 | ##############################################################
|
---|
17 | import string
|
---|
18 |
|
---|
19 | def pack(format,list):
|
---|
20 | retstring = ''
|
---|
21 | listind = 0
|
---|
22 |
|
---|
23 | # Cycle through format entries
|
---|
24 | for type in format:
|
---|
25 | # Null Terminated String
|
---|
26 | if (type == 'f' or type == 'P'):
|
---|
27 | retstring = retstring + list[listind] + "\000"
|
---|
28 | # 4 Byte Number
|
---|
29 | if (type == 'd'):
|
---|
30 | retstring = retstring + PackNum(list[listind],4)
|
---|
31 | # 2 Byte Number
|
---|
32 | if (type == 'w'):
|
---|
33 | retstring = retstring + PackNum(list[listind],2)
|
---|
34 | # Pointer Value
|
---|
35 | if (type == 'p'):
|
---|
36 | if (list[listind]):
|
---|
37 | retstring = retstring + PackNum(1,4)
|
---|
38 | else:
|
---|
39 | retstring = retstring + PackNum(0,4)
|
---|
40 | # Buffer and Length
|
---|
41 | if (type == 'B'):
|
---|
42 | # length
|
---|
43 | length = list[listind]
|
---|
44 | retstring = retstring + PackNum(length,4)
|
---|
45 | length = int(length)
|
---|
46 | listind = listind + 1
|
---|
47 | # buffer
|
---|
48 | retstring = retstring + list[listind][:length]
|
---|
49 |
|
---|
50 | listind = listind + 1
|
---|
51 |
|
---|
52 | return retstring
|
---|
53 |
|
---|
54 | def unpack(format,buffer):
|
---|
55 | retlist = []
|
---|
56 | bufind = 0
|
---|
57 |
|
---|
58 | lasttype = ""
|
---|
59 | for type in format:
|
---|
60 | # Pointer Value
|
---|
61 | if (type == 'p'):
|
---|
62 | newvalue = UnpackNum(buffer[bufind:bufind+4])
|
---|
63 | bufind = bufind + 4
|
---|
64 | if (newvalue):
|
---|
65 | newvalue = 1L
|
---|
66 | else:
|
---|
67 | newvalue = 0L
|
---|
68 | retlist.append(newvalue)
|
---|
69 | # Previous character till end of data
|
---|
70 | elif (type == '$'):
|
---|
71 | if (lasttype == 'f'):
|
---|
72 | while (bufind < len(buffer)):
|
---|
73 | newstring = ''
|
---|
74 | while (buffer[bufind] != '\000'):
|
---|
75 | newstring = newstring + buffer[bufind]
|
---|
76 | bufind = bufind + 1
|
---|
77 | bufind = bufind + 1
|
---|
78 | retlist.append(newstring)
|
---|
79 | # Null Terminated String
|
---|
80 | elif (type == 'f' or type == 'P'):
|
---|
81 | newstring = ''
|
---|
82 | while (buffer[bufind] != '\000'):
|
---|
83 | newstring = newstring + buffer[bufind]
|
---|
84 | bufind = bufind + 1
|
---|
85 | bufind = bufind + 1
|
---|
86 | retlist.append(newstring)
|
---|
87 | # 4 Byte Number
|
---|
88 | elif (type == 'd'):
|
---|
89 | newvalue = UnpackNum(buffer[bufind:bufind+4])
|
---|
90 | bufind = bufind + 4
|
---|
91 | retlist.append(newvalue)
|
---|
92 | # 2 Byte Number
|
---|
93 | elif (type == 'w'):
|
---|
94 | newvalue = UnpackNum(buffer[bufind:bufind+2])
|
---|
95 | bufind = bufind + 2
|
---|
96 | retlist.append(newvalue)
|
---|
97 | # Length and Buffer
|
---|
98 | elif (type == 'B'):
|
---|
99 | # Length
|
---|
100 | length = UnpackNum(buffer[bufind:bufind+4])
|
---|
101 | bufind = bufind + 4
|
---|
102 | retlist.append(length)
|
---|
103 | length = int(length)
|
---|
104 | # Buffer
|
---|
105 | retlist.append(buffer[bufind:bufind+length])
|
---|
106 | bufind = bufind + length
|
---|
107 |
|
---|
108 | lasttype = type
|
---|
109 |
|
---|
110 | return ((retlist,buffer[bufind:]))
|
---|
111 |
|
---|
112 | def PackNum(myint,size):
|
---|
113 | retstring = ''
|
---|
114 | size = size * 2
|
---|
115 | hint = hex(myint)[2:]
|
---|
116 |
|
---|
117 | # Check for long notation
|
---|
118 | if (hint[-1:] == 'L'):
|
---|
119 | hint = hint[:-1]
|
---|
120 |
|
---|
121 | addon = size - len(hint)
|
---|
122 | for i in range(0,addon):
|
---|
123 | hint = '0' + hint
|
---|
124 |
|
---|
125 | while (size > 0):
|
---|
126 | val = string.atoi(hint[size-2:size],16)
|
---|
127 | retstring = retstring + chr(val)
|
---|
128 | size = size - 2
|
---|
129 |
|
---|
130 | return retstring
|
---|
131 |
|
---|
132 | def UnpackNum(buffer):
|
---|
133 | size = len(buffer)
|
---|
134 | mystring = ''
|
---|
135 |
|
---|
136 | for i in range(size-1,-1,-1):
|
---|
137 | val = hex(ord(buffer[i]))[2:]
|
---|
138 | if (len(val) == 1):
|
---|
139 | val = '0' + val
|
---|
140 | mystring = mystring + val
|
---|
141 | if (len(mystring) > 4):
|
---|
142 | return string.atol(mystring,16)
|
---|
143 | else:
|
---|
144 | return string.atoi(mystring,16)
|
---|