3 def sid_to_string(sid):
4 """Convert a Python dictionary SID to a string SID."""
6 result = 'S-%d' % sid.sid_rev_num
8 result = result + '-%u' % \
9 (dcerpc.uint8_array_getitem(sid.id_auth, 5) +
10 (dcerpc.uint8_array_getitem(sid.id_auth, 4) << 8) +
11 (dcerpc.uint8_array_getitem(sid.id_auth, 3) << 16) +
12 (dcerpc.uint8_array_getitem(sid.id_auth, 2) << 24))
14 for i in range(0, sid.num_auths):
15 result = result + '-%u' % \
16 dcerpc.uint32_array_getitem(sid.sub_auths, i)
21 def string_to_sid(string):
22 """Convert a string SID to a Python dictionary SID. Throws a
23 ValueError if the SID string was badly formed."""
26 raise ValueError('Bad SID format')
32 match = re.match('-\d+', string)
35 raise ValueError('Bad SID format')
38 sid_rev_num = int(string[match.start()+1:match.end()])
40 raise ValueError('Bad SID format')
42 string = string[match.end():]
44 match = re.match('-\d+', string)
47 raise ValueError('Bad SID format')
50 ia = int(string[match.start()+1:match.end()])
52 raise ValueError('Bad SID format')
54 string = string[match.end():]
56 id_auth = [0, 0, (ia >> 24) & 0xff, (ia >> 16) & 0xff,
57 (ia >> 8) & 0xff, ia & 0xff]
64 match = re.match('-\d+', string)
67 raise ValueError('Bad SID format')
70 sa = int(string[match.start() + 1 : match.end()])
72 raise ValueError('Bad SID format')
74 num_auths = num_auths + 1
75 sub_auths.append(int(sa))
77 string = string[match.end():]
79 sid = dcerpc.dom_sid()
80 sid.sid_rev_num = sid_rev_num
81 sid.id_auth = dcerpc.new_uint8_array(6)
83 dcerpc.uint8_array_setitem(sid.id_auth, i, id_auth[i])
84 sid.num_auths = num_auths
85 sid.sub_auths = dcerpc.new_uint32_array(num_auths)
86 for i in range(num_auths):
87 dcerpc.uint32_array_setitem(sid.sub_auths, i, sub_auths[i])
92 def call_fn(fn, pipe, args):
93 """Wrap up a RPC call and throw an exception is an error was returned."""
95 result = fn(pipe, args);
97 if result & 0xc0000000L:
98 raise dcerpc.NTSTATUS(result, dcerpc.nt_errstr(result));
105 def __init__(self, pipe, handle):
112 if self.handle is not None:
117 r = dcerpc.samr_Close()
118 r.data_in.handle = self.handle
120 call_fn(dcerpc.dcerpc_samr_Close, self.pipe, r)
124 def QuerySecurity(self, sec_info = 7):
126 r = dcerpc.samr_QuerySecurity()
127 r.data_in.handle = self.handle
128 r.data_in.sec_info = sec_info
130 call_fn(dcerpc.dcerpc_samr_QuerySecurity, self.pipe, r)
132 return r.data_out.sdbuf
134 def SetSecurity(self, sdbuf, sec_info = 7):
136 r = dcerpc.samr_SetSecurity()
137 r.data_in.handle = self.handle
138 r.data_in.sec_info = sec_info
139 r.data_in.sdbuf = sdbuf
141 call_fn(dcerpc.dcerpc_samr_SetSecurity, self.pipe, r)
144 class ConnectHandle(SamrHandle):
146 def EnumDomains(self):
148 r = dcerpc.samr_EnumDomains()
149 r.data_in.connect_handle = self.handle
150 r.data_in.resume_handle = 0
151 r.data_in.buf_size = -1
157 call_fn(dcerpc.dcerpc_samr_EnumDomains, self.pipe, r)
159 for i in range(r.data_out.sam.count):
160 domains.append(dcerpc.samr_SamEntry_array_getitem(
161 r.data_out.sam.entries, i).name.string)
163 # TODO: Handle more entries here
169 def LookupDomain(self, domain_name):
171 r = dcerpc.samr_LookupDomain()
172 r.data_in.connect_handle = self.handle
173 r.data_in.domain_name = dcerpc.samr_String()
174 r.data_in.domain_name.string = domain_name
176 call_fn(dcerpc.dcerpc_samr_LookupDomain, self.pipe, r)
178 return sid_to_string(r.data_out.sid);
180 def OpenDomain(self, domain_sid, access_mask = 0x02000000):
182 r = dcerpc.samr_OpenDomain()
183 r.data_in.connect_handle = self.handle
184 r.data_in.access_mask = access_mask
185 r.data_in.sid = string_to_sid(domain_sid)
187 call_fn(dcerpc.dcerpc_samr_OpenDomain, self.pipe, r)
189 return DomainHandle(self.pipe, r.data_out.domain_handle)
193 r = dcerpc.samr_Shutdown()
194 r.data_in.connect_handle = self.handle
196 call_fn(dcerpc.dcerpc_samr_Shutdown, self.pipe, r)
198 def GetDomPwInfo(self, system_name):
200 r = dcerpc.samr_GetDomPwInfo()
201 r.data_in.domain_name = dcerpc.samr_String()
202 r.data_in.domain_name.string = system_name
204 call_fn(dcerpc.dcerpc_samr_GetDomPwInfo, self.pipe, r)
206 return r.data_out.info
209 class DomainHandle(SamrHandle):
211 def QueryDomainInfo(self, level = 2):
213 r = dcerpc.samr_QueryDomainInfo()
214 r.data_in.domain_handle = self.handle
215 r.data_in.level = level
217 call_fn(dcerpc.dcerpc_samr_QueryDomainInfo, self.pipe, r)
219 return getattr(r.data_out.info, 'info%d' % level)
221 def QueryDomainInfo2(self, level = 2):
223 r = dcerpc.samr_QueryDomainInfo2()
224 r.data_in.domain_handle = self.handle
225 r.data_in.level = level
227 call_fn(dcerpc.dcerpc_samr_QueryDomainInfo2, self.pipe, r)
229 return getattr(r.data_out.info, 'info%d' % level)
231 def EnumDomainGroups(self):
233 r = dcerpc.samr_EnumDomainGroups()
234 r.data_in.domain_handle = self.handle
235 r.data_in.resume_handle = 0
236 r.data_in.max_size = 1000
238 call_fn(dcerpc.dcerpc_samr_EnumDomainGroups, self.pipe, r)
242 if r.data_out.sam.entries:
243 for i in range(r.data_out.sam.count):
244 groups.append(dcerpc.samr_SamEntry_array_getitem(
245 r.data_out.sam.entries, i).name.string)
249 def EnumDomainAliases(self):
251 r = dcerpc.samr_EnumDomainAliases()
252 r.data_in.domain_handle = self.handle
253 r.data_in.resume_handle = 0
254 # acct_flags in SamrEnumerateAliasesInDomain has probably
255 # no meaning so use 0xffffffff like W2K
256 r.data_in.acct_flags = 0xffffffffL
258 call_fn(dcerpc.dcerpc_samr_EnumDomainAliases, self.pipe, r)
262 if r.data_out.sam.entries:
263 for i in range(r.data_out.sam.count):
264 aliases.append(dcerpc.samr_SamEntry_array_getitem(
265 r.data_out.sam.entries, i).name.string)
269 def EnumDomainUsers(self, user_account_flags = 16):
271 r = dcerpc.samr_EnumDomainUsers()
272 r.data_in.domain_handle = self.handle
273 r.data_in.resume_handle = 0
274 r.data_in.acct_flags = user_account_flags
275 r.data_in.max_size = 1000
277 call_fn(dcerpc.dcerpc_samr_EnumDomainUsers, self.pipe, r)
281 if r.data_out.sam.entries:
282 for i in range(r.data_out.sam.count):
283 users.append(dcerpc.samr_SamEntry_array_getitem(
284 r.data_out.sam.entries, i).name.string)
288 def CreateUser(self, account_name, access_mask = 0x02000000):
290 r = dcerpc.samr_CreateUser()
291 r.data_in.domain_handle = self.handle
292 r.data_in.account_name = dcerpc.samr_String()
293 r.data_in.account_name.string = account_name
294 r.data_in.access_mask = access_mask
296 call_fn(dcerpc.dcerpc_samr_CreateUser, self.pipe, r)
298 return (r.data_out.user_handle,
299 dcerpc.uint32_array_getitem(r.data_out.rid, 0))
301 def CreateUser2(self, account_name, acct_flags = 0x00000010,
302 access_mask = 0x02000000):
304 r = dcerpc.samr_CreateUser2()
305 r.data_in.domain_handle = self.handle
306 r.data_in.account_name = dcerpc.samr_String()
307 r.data_in.account_name.string = account_name
308 r.data_in.acct_flags = acct_flags
309 r.data_in.access_mask = access_mask
311 call_fn(dcerpc.dcerpc_samr_CreateUser2, self.pipe, r)
313 return (r.data_out.user_handle,
314 dcerpc.uint32_array_getitem(r.data_out.access_granted, 0),
315 dcerpc.uint32_array_getitem(r.data_out.rid, 0))
317 def OpenUser(self, rid, access_mask = 0x02000000):
319 r = dcerpc.samr_OpenUser()
320 r.data_in.domain_handle = self.handle
321 r.data_in.access_mask = access_mask
324 call_fn(dcerpc.dcerpc_samr_OpenUser, self.pipe, r)
326 return UserHandle(self.pipe, r.data_out.user_handle)
328 def OpenGroup(self, rid, access_mask = 0x02000000):
330 r = dcerpc.samr_OpenGroup()
331 r.data_in.domain_handle = self.handle
332 r.data_in.access_mask = access_mask
335 call_fn(dcerpc.dcerpc_samr_OpenGroup, self.pipe, r)
337 return GroupHandle(pipe, r.data_out.group_handle)
339 def OpenAlias(self, rid, access_mask = 0x02000000):
341 r = dcerpc.samr_OpenAlias()
342 r.data_in.domain_handle = self.handle
343 r.data_in.access_mask = access_mask
346 call_fn(dcerpc.dcerpc_samr_OpenAlias, self.pipe, r)
348 return AliasHandle(self.pipe, r.data_out.alias_handle)
350 def CreateDomAlias(self, alias_name, access_mask = 0x02000000):
352 r = dcerpc.samr_CreateDomAlias()
353 r.data_in.domain_handle = self.handle
354 r.data_in.alias_name = dcerpc.samr_String()
355 r.data_in.alias_name.string = alias_name
356 r.data_in.access_mask = access_mask
358 call_fn(dcerpc.dcerpc_samr_CreateDomAlias, self.pipe, r)
360 return (AliasHandle(self.pipe, r.data_out.alias_handle),
363 def RidToSid(self, rid):
365 r = dcerpc.samr_RidToSid()
366 r.data_in.domain_handle = self.handle
368 call_fn(dcerpc.dcerpc_samr_RidToSid, self.pipe, r)
370 return sid_to_string(r.data_out.sid)
372 def RemoveMemberFromForeignDomain(self, sid):
374 r = dcerpc.samr_RemoveMemberFromForeignDomain()
375 r.data_in.domain_handle = self.handle
378 call_fn(dcerpc.dcerpc_samr_RemoveMemberFromForeignDomain, self.pipe, r)
380 def LookupNames(self, names):
382 r = dcerpc.samr_LookupNames()
383 r.data_in.domain_handle = self.handle
384 r.data_in.num_names = len(names)
385 r.data_in.names = dcerpc.new_samr_String_array(len(names))
387 for i in range(len(names)):
388 s = dcerpc.samr_String()
390 dcerpc.samr_String_array_setitem(r.data_in.names, i, s)
392 call_fn(dcerpc.dcerpc_samr_LookupNames, self.pipe, r)
394 return ([dcerpc.uint32_array_getitem(r.data_out.rids.ids, i) for i in range(r.data_out.rids.count)],
395 [dcerpc.uint32_array_getitem(r.data_out.types.ids, i) for i in range(r.data_out.types.count)])
397 def CreateDomainGroup(self, domain_name, access_mask = 0x02000000):
399 r = dcerpc.samr_CreateDomainGroup()
400 r.data_in.domain_handle = self.handle
401 r.data_in.name = dcerpc.samr_String()
402 r.data_in.name.string = domain_name
403 r.data_in.access_mask = access_mask
405 call_fn(dcerpc.dcerpc_samr_CreateDomainGroup, self.pipe, r)
407 def GetAliasMembership(self, sids):
409 r = dcerpc.samr_GetAliasMembership()
410 r.data_in.domain_handle = self.handle
411 r.data_in.sids = dcerpc.lsa_SidArray()
412 r.data_in.sids.num_sids = len(sids)
413 r.data_in.sids.sids = dcerpc.new_lsa_SidPtr_array(len(sids))
415 for i in range(len(sids)):
416 s = dcerpc.lsa_SidPtr()
417 s.sid = string_to_sid(sids[i])
418 dcerpc.lsa_SidPtr_array_setitem(r.data_in.sids.sids, i, s)
420 call_fn(dcerpc.dcerpc_samr_GetAliasMembership, self.pipe, r)
422 return [r.ids[x] x in range(r.count)]
424 class UserHandle(SamrHandle):
426 def DeleteUser(self):
428 r = dcerpc.samr_DeleteUser()
429 r.data_in.user_handle = self.handle
431 call_fn(dcerpc.dcerpc_samr_DeleteUser, self.pipe, r)
436 class GroupHandle(SamrHandle):
440 class AliasHandle(SamrHandle):
442 def DeleteDomAlias(self):
444 r = dcerpc.samr_DeleteDomAlias()
445 r.data_in.alias_handle = self.handle
447 call_fn(dcerpc.dcerpc_samr_DeleteDomAlias, self.pipe, r)
451 def QueryAliasInfo(self, level = 1):
453 r = dcerpc.samr_QueryAliasInfo()
454 r.data_in.alias_handle = self.handle
455 r.data_in.level = level
457 call_fn(dcerpc.dcerpc_samr_QueryAliasInfo, self.pipe, r)
459 return r.data_out.info
461 def SetAliasInfo(self, level, info):
463 r = dcerpc.samr_SetAliasInfo()
464 r.data_in.alias_handle = self.handle
465 r.data_in.level = level
466 r.data_in.info = info
468 call_fn(dcerpc.dcerpc_samr_SetAliasInfo, self.pipe, r)
470 def AddAliasMember(self, sid):
472 r = dcerpc.samr_AddAliasMember()
473 r.data_in.alias_handle = self.handle
474 r.data_in.sid = string_to_sid(sid)
476 call_fn(dcerpc.dcerpc_samr_AddAliasMember, self.pipe, r)
478 def AddMultipleMembersToAlias(self, sids):
480 r = dcerpc.samr_AddMultipleMembersToAlias()
481 r.data_in.alias_handle = self.handle
482 r.data_in.sids = dcerpc.lsa_SidArray()
483 r.data_in.sids.num_sids = len(sids)
484 r.data_in.sids.sids = dcerpc.new_lsa_SidPtr_array(len(sids))
486 for i in range(len(sids)):
487 s = dcerpc.lsa_SidPtr()
488 s.sid = string_to_sid(sids[i])
489 dcerpc.lsa_SidPtr_array_setitem(r.data_in.sids.sids, i, s)
491 call_fn(dcerpc.dcerpc_samr_AddMultipleMembersToAlias, self.pipe, r)
493 def Connect(pipe, access_mask = 0x02000000):
495 r = dcerpc.samr_Connect()
496 r.data_in.system_name = dcerpc.new_uint16_array(1)
497 dcerpc.uint16_array_setitem(r.data_in.system_name, 0, ord('\\'))
498 r.data_in.access_mask = access_mask
500 call_fn(dcerpc.dcerpc_samr_Connect, pipe, r)
502 return ConnectHandle(pipe, r.data_out.connect_handle)
505 def Connect2(pipe, system_name = '', access_mask = 0x02000000):
506 """Connect to the SAMR pipe."""
508 r = dcerpc.samr_Connect2()
509 r.data_in.system_name = system_name
510 r.data_in.access_mask = access_mask
512 call_fn(dcerpc.dcerpc_samr_Connect2, pipe, r)
514 return ConnectHandle(pipe, r.data_out.connect_handle)
517 def Connect3(pipe, system_name = '', access_mask = 0x02000000):
519 r = dcerpc.samr_Connect3()
520 r.data_in.system_name = system_name
521 r.data_in.unknown = 0
522 r.data_in.access_mask = access_mask
524 call_fn(dcerpc.dcerpc_samr_Connect3, pipe, r)
526 return ConnectHandle(pipe, r.data_out.connect_handle)
529 def Connect4(pipe, system_name = '', access_mask = 0x02000000):
531 r = dcerpc.samr_Connect4()
532 r.data_in.system_name = system_name
533 r.data_in.unknown = 0
534 r.data_in.access_mask = access_mask
536 call_fn(dcerpc.dcerpc_samr_Connect4, pipe, r)
538 return ConnectHandle(pipe, r.data_out.connect_handle)
541 def Connect5(pipe, system_name = '', access_mask = 0x02000000):
543 r = dcerpc.samr_Connect5()
544 r.data_in.system_name = system_name
545 r.data_in.access_mask = access_mask
547 r.data_in.info = dcerpc.new_samr_ConnectInfo_array(1)
548 r.data_in.info.unknown1 = 0
549 r.data_in.info.unknown2 = 0
551 call_fn(dcerpc.dcerpc_samr_Connect5, pipe, r)
553 return ConnectHandle(pipe, r.data_out.connect_handle)
561 # SetMemberAttributesofGroup
570 # GetDisplayEnumerationIndex
571 # TestPrivateFunctionsDomain
572 # TestPrivateFunctionsUser
574 # RemoveMemberFromForeignDomain
578 # GetDisplayEnumerationIndex2
580 # RemoveMultipleMembersFromAlias
581 # OemChangePasswordUser2
582 # ChangePasswordUser2
584 # SetBootKeyInformation
585 # GetBootKeyInformation
586 # ChangePasswordUser3