diff options
Diffstat (limited to 'source4/scripting/swig/samr.py')
-rw-r--r-- | source4/scripting/swig/samr.py | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/source4/scripting/swig/samr.py b/source4/scripting/swig/samr.py new file mode 100644 index 0000000000..5fd87da3ad --- /dev/null +++ b/source4/scripting/swig/samr.py @@ -0,0 +1,165 @@ +import dcerpc + +def sid_to_string(sid): + """Convert a Python dictionary SID to a string SID.""" + + result = 'S-%d' % sid['sid_rev_num'] + + ia = sid['id_auth'] + + result = result + '-%u' % (ia[5] + (ia[4] << 8) + (ia[3] << 16) + \ + (ia[2] << 24)) + + for i in range(0, sid['num_auths']): + result = result + '-%u' % sid['sub_auths'][i] + + return result + +def string_to_sid(string): + """Convert a string SID to a Python dictionary SID. Throws a + ValueError if the SID string was badly formed.""" + + if string[0] != 'S': + raise ValueError('Bad SID format') + + string = string[1:] + + import re + + match = re.match('-\d+', string) + + if not match: + raise ValueError('Bad SID format') + + try: + sid_rev_num = int(string[match.start()+1:match.end()]) + except ValueError: + raise ValueError('Bad SID format') + + string = string[match.end():] + + match = re.match('-\d+', string) + + if not match: + raise ValueError('Bad SID format') + + try: + ia = int(string[match.start()+1:match.end()]) + except ValueError: + raise ValueError('Bad SID format') + + string = string[match.end():] + + id_auth = [0, 0, (ia >> 24) & 0xff, (ia >> 16) & 0xff, + (ia >> 8) & 0xff, ia & 0xff] + + num_auths = 0 + sub_auths = [] + + while len(string): + + match = re.match('-\d+', string) + + if not match: + raise ValueError('Bad SID format') + + try: + sa = int(string[match.start() + 1 : match.end()]) + except ValueError: + raise ValueError('Bad SID format') + + num_auths = num_auths + 1 + sub_auths.append(int(sa)) + + string = string[match.end():] + + print map(type, sub_auths) + + return {'sid_rev_num': sid_rev_num, 'id_auth': id_auth, + 'num_auths': num_auths, 'sub_auths': sub_auths} + +class SamrHandle: + + def __init__(self, pipe, handle): + + self.pipe = pipe + self.handle = handle + + def __del__(self): + + r = {} + r['handle'] = self.handle + + dcerpc.samr_Close(self.pipe, r) + +class ConnectHandle(SamrHandle): + + def EnumDomains(self): + + r = {} + r['connect_handle'] = self.handle + r['resume_handle'] = 0 + r['buf_size'] = -1 + + domains = [] + + while 1: + + result = dcerpc.samr_EnumDomains(self.pipe, r) + + domains = domains + result['sam']['entries'] + + if result['result'] == dcerpc.STATUS_MORE_ENTRIES: + r['resume_handle'] = result['resume_handle'] + continue + + break + + return map(lambda x: x['name']['name'], domains) + + def LookupDomain(self, domain_name): + + r = {} + r['connect_handle'] = self.handle + r['domain'] = {} + r['domain']['name_len'] = 0 + r['domain']['name_size'] = 0 + r['domain']['name'] = domain_name + + result = dcerpc.samr_LookupDomain(self.pipe, r) + + return sid_to_string(result['sid']) + + def OpenDomain(self, domain_sid, access_mask = 0x02000000): + + r = {} + r['connect_handle'] = self.handle + r['access_mask'] = access_mask + r['sid'] = string_to_sid(domain_sid) + + result = dcerpc.samr_OpenDomain(self.pipe, r) + + return DomainHandle(pipe, result['domain_handle']) + +class DomainHandle(SamrHandle): + + def QueryDomainInfo(self, level = 2): + + r = {} + r['domain_handle'] = self.domain_handle + r['level'] = level + + result = dcerpc.samr_QueryDomainInfo(pipe, r) + + return result + +def Connect(pipe, system_name = None, access_mask = 0x02000000): + """Connect to the SAMR pipe.""" + + r = {} + r['system_name'] = system_name + r['access_mask'] = access_mask + + result = dcerpc.samr_Connect2(pipe, r) + + return ConnectHandle(pipe, result['connect_handle']) |