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############################################################## 17import string 18 19def 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 54def 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 112def 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 132def 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) 145