ctdb/docs: Include ceph rados namespace support in man page
[samba.git] / python / samba / emulate / traffic_packets.py
1 # Dispatch for various request types.
2 #
3 # Copyright (C) Catalyst IT Ltd. 2017
4 #
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 #
18 import os
19 import ctypes
20 import random
21
22 from samba.net import Net
23 from samba.dcerpc import security, drsuapi, nbt, lsa, netlogon, ntlmssp
24 from samba.dcerpc.netlogon import netr_WorkstationInformation
25 from samba.dcerpc.security import dom_sid
26 from samba.netbios import Node
27 from samba.ndr import ndr_pack
28 from samba.credentials import (
29     CLI_CRED_NTLMv2_AUTH,
30     MUST_USE_KERBEROS,
31     DONT_USE_KERBEROS
32 )
33 from samba import NTSTATUSError
34 from samba.ntstatus import (
35     NT_STATUS_OBJECT_NAME_NOT_FOUND,
36     NT_STATUS_NO_SUCH_DOMAIN
37 )
38 import samba
39 import dns.resolver
40 from ldb import SCOPE_BASE
41
42 def uint32(v):
43     return ctypes.c_uint32(v).value
44
45
46 def check_runtime_error(runtime, val):
47     if runtime is None:
48         return False
49
50     err32 = uint32(runtime.args[0])
51     if err32 == val:
52         return True
53
54     return False
55
56
57 name_formats = [
58     drsuapi.DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
59     drsuapi.DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
60     drsuapi.DRSUAPI_DS_NAME_FORMAT_DISPLAY,
61     drsuapi.DRSUAPI_DS_NAME_FORMAT_GUID,
62     drsuapi.DRSUAPI_DS_NAME_FORMAT_CANONICAL,
63     drsuapi.DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
64     drsuapi.DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX,
65     drsuapi.DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
66     drsuapi.DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
67     drsuapi.DRSUAPI_DS_NAME_FORMAT_DNS_DOMAIN,
68     drsuapi.DRSUAPI_DS_NAME_FORMAT_UPN_AND_ALTSECID,
69     drsuapi.DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT_NAME_SANS_DOMAIN_EX,
70     drsuapi.DRSUAPI_DS_NAME_FORMAT_LIST_GLOBAL_CATALOG_SERVERS,
71     drsuapi.DRSUAPI_DS_NAME_FORMAT_UPN_FOR_LOGON,
72     drsuapi.DRSUAPI_DS_NAME_FORMAT_LIST_SERVERS_WITH_DCS_IN_SITE,
73     drsuapi.DRSUAPI_DS_NAME_FORMAT_STRING_SID_NAME,
74     drsuapi.DRSUAPI_DS_NAME_FORMAT_ALT_SECURITY_IDENTITIES_NAME,
75     drsuapi.DRSUAPI_DS_NAME_FORMAT_LIST_NCS,
76     drsuapi.DRSUAPI_DS_NAME_FORMAT_LIST_DOMAINS,
77     drsuapi.DRSUAPI_DS_NAME_FORMAT_MAP_SCHEMA_GUID,
78     drsuapi.DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT_NAME_SANS_DOMAIN,
79     drsuapi.DRSUAPI_DS_NAME_FORMAT_LIST_ROLES,
80     drsuapi.DRSUAPI_DS_NAME_FORMAT_LIST_INFO_FOR_SERVER,
81     drsuapi.DRSUAPI_DS_NAME_FORMAT_LIST_SERVERS_FOR_DOMAIN_IN_SITE,
82     drsuapi.DRSUAPI_DS_NAME_FORMAT_LIST_DOMAINS_IN_SITE,
83     drsuapi.DRSUAPI_DS_NAME_FORMAT_LIST_SERVERS_IN_SITE,
84     drsuapi.DRSUAPI_DS_NAME_FORMAT_LIST_SITES,
85 ]
86
87
88 def warning(message):
89     print("\033[37;41;1m" "Warning: %s" "\033[00m" % (message))
90
91 ###############################################################################
92 #
93 # Packet generation functions:
94 #
95 # All the packet generation functions have the following form:
96 #  packet_${protocol}_${opcode}(packet, conversation, context)
97 #
98 #  The functions return true, if statistics should be collected for the packet
99 #                      false, the packet has been ignored.
100 #
101 # Where:
102 #   protocol is the protocol, i.e. cldap, dcerpc, ...
103 #   opcode   is the protocol op code i.e. type of the packet to be
104 #            generated.
105 #
106 #   packet contains data about the captured/generated packet
107 #          provides any extra data needed to generate the packet
108 #
109 #   conversation Details of the current client/server interaction
110 #
111 #   context state data for the current interaction
112 #
113 #
114 #
115 # The following protocols are not currently handled:
116 #     smb
117 #     smb2
118 #     browser
119 #     smb_netlogon
120 #
121 # The following drsuapi replication packets are currently ignored:
122 #     DsReplicaSync
123 #     DsGetNCChanges
124 #     DsReplicaUpdateRefs
125
126
127 # Packet generators that do NOTHING are assigned to the null_packet
128 # function which allows the conversation generators to notice this and
129 # avoid a whole lot of pointless work.
130 def null_packet(packet, conversation, context):
131     return False
132
133
134 def packet_cldap_3(packet, conversation, context):
135     # searchRequest
136     net = Net(creds=context.creds, lp=context.lp)
137     net.finddc(domain=context.lp.get('realm'),
138                flags=(nbt.NBT_SERVER_LDAP |
139                       nbt.NBT_SERVER_DS |
140                       nbt.NBT_SERVER_WRITABLE))
141     return True
142
143
144 packet_cldap_5 = null_packet
145 # searchResDone
146
147 packet_dcerpc_0  = null_packet
148 # Request
149 # Can be ignored, it's the continuation of an existing conversation
150
151 packet_dcerpc_2 = null_packet
152 # Request
153 # Server response, so should be ignored
154
155 packet_dcerpc_3 = null_packet
156
157 packet_dcerpc_11 = null_packet
158 # Bind
159 # creation of the rpc dcerpc connection is managed by the higher level
160 # protocol drivers. So we ignore it when generating traffic
161
162
163 packet_dcerpc_12 = null_packet
164 # Bind_ack
165 # Server response, so should be ignored
166
167
168 packet_dcerpc_13 = null_packet
169 # Bind_nak
170 # Server response, so should be ignored
171
172
173 packet_dcerpc_14 = null_packet
174 # Alter_context
175 # Generated as part of the connect process
176
177
178 def packet_dcerpc_15(packet, conversation, context):
179     # Alter_context_resp
180     # This means it was GSSAPI/krb5 (probably)
181     # Check the kerberos_state and issue a diagnostic if kerberos not enabled
182     if context.user_creds.get_kerberos_state() == DONT_USE_KERBEROS:
183         warning("Kerberos disabled but have dcerpc Alter_context_resp "
184                 "indicating Kerberos was used")
185     return False
186
187
188 def packet_dcerpc_16(packet, conversation, context):
189     # AUTH3
190     # This means it was NTLMSSP
191     # Check the kerberos_state and issue a diagnostic if kerberos enabled
192     if context.user_creds.get_kerberos_state() == MUST_USE_KERBEROS:
193         warning("Kerberos enabled but have dcerpc AUTH3 "
194                 "indicating NTLMSSP was used")
195     return False
196
197
198 def packet_dns_0(packet, conversation, context):
199     # query
200     name, rtype = context.guess_a_dns_lookup()
201     dns.resolver.query(name, rtype)
202     return True
203
204
205 packet_dns_1 = null_packet
206 # response
207 # Server response, so should be ignored
208
209
210 def packet_drsuapi_0(packet, conversation, context):
211     # DsBind
212     context.get_drsuapi_connection_pair(True)
213     return True
214
215
216 NAME_FORMATS = [getattr(drsuapi, _x) for _x in dir(drsuapi)
217                 if 'NAME_FORMAT' in _x]
218
219
220 def packet_drsuapi_12(packet, conversation, context):
221     # DsCrackNames
222     drs, handle = context.get_drsuapi_connection_pair()
223
224     names = drsuapi.DsNameString()
225     names.str = context.server
226
227     req = drsuapi.DsNameRequest1()
228     req.format_flags = 0
229     req.format_offered = 7
230     req.format_desired = random.choice(name_formats)
231     req.codepage = 1252
232     req.language = 1033  # German, I think
233     req.format_flags = 0
234     req.count = 1
235     req.names = [names]
236
237     (result, ctr) = drs.DsCrackNames(handle, 1, req)
238     return True
239
240
241 def packet_drsuapi_13(packet, conversation, context):
242     # DsWriteAccountSpn
243     req = drsuapi.DsWriteAccountSpnRequest1()
244     req.operation = drsuapi.DRSUAPI_DS_SPN_OPERATION_REPLACE
245     req.unknown1 = 0  # Unused, must be 0
246     req.object_dn = context.user_dn
247     req.count = 1  # only 1 name
248     spn_name = drsuapi.DsNameString()
249     spn_name.str = 'foo/{}'.format(context.username)
250     req.spn_names = [spn_name]
251     (drs, handle) = context.get_drsuapi_connection_pair()
252     (level, res) = drs.DsWriteAccountSpn(handle, 1, req)
253     return True
254
255
256 def packet_drsuapi_1(packet, conversation, context):
257     # DsUnbind
258     (drs, handle) = context.get_drsuapi_connection_pair()
259     drs.DsUnbind(handle)
260     del context.drsuapi_connections[-1]
261     return True
262
263
264 packet_drsuapi_2 = null_packet
265 # DsReplicaSync
266 # This is between DCs, triggered on a DB change
267 # Ignoring for now
268
269
270 packet_drsuapi_3 = null_packet
271 # DsGetNCChanges
272 # This is between DCs, trigger with DB operation,
273 # or DsReplicaSync between DCs.
274 # Ignoring for now
275
276
277 packet_drsuapi_4 = null_packet
278 # DsReplicaUpdateRefs
279 # Ignoring for now
280
281
282 packet_epm_3 = null_packet
283 # Map
284 # Will be generated by higher level protocol calls
285
286
287 def packet_kerberos_(packet, conversation, context):
288     # Use the presence of kerberos packets as a hint to enable kerberos
289     # for the rest of the conversation.
290     # i.e. kerberos packets are not explicitly generated.
291     context.user_creds.set_kerberos_state(MUST_USE_KERBEROS)
292     context.user_creds_bad.set_kerberos_state(MUST_USE_KERBEROS)
293     context.machine_creds.set_kerberos_state(MUST_USE_KERBEROS)
294     context.machine_creds_bad.set_kerberos_state(MUST_USE_KERBEROS)
295     context.creds.set_kerberos_state(MUST_USE_KERBEROS)
296     return False
297
298
299 packet_ldap_ = null_packet
300 # Unknown
301 # The ldap payload was probably encrypted so just ignore it.
302
303
304 def packet_ldap_0(packet, conversation, context):
305     # bindRequest
306     if packet.extra[5] == "simple":
307         # Perform a simple bind.
308         context.get_ldap_connection(new=True, simple=True)
309     else:
310         # Perform a sasl bind.
311         context.get_ldap_connection(new=True, simple=False)
312     return True
313
314
315 packet_ldap_1 = null_packet
316 # bindResponse
317 # Server response ignored for traffic generation
318
319
320 def packet_ldap_2(packet, conversation, context):
321     # unbindRequest
322     # pop the last one off -- most likely we're in a bind/unbind ping.
323     del context.ldap_connections[-1:]
324     return False
325
326
327 def packet_ldap_3(packet, conversation, context):
328     # searchRequest
329
330     (scope, dn_sig, filter, attrs, extra, desc, oid) = packet.extra
331     if not scope:
332         scope = SCOPE_BASE
333
334     samdb = context.get_ldap_connection()
335     dn = context.get_matching_dn(dn_sig)
336
337     # try to guess the search expression (don't bother for base searches, as
338     # they're only looking up a single object)
339     if (filter is None or filter == '') and scope != SCOPE_BASE:
340         filter = context.guess_search_filter(attrs, dn_sig, dn)
341
342     samdb.search(dn,
343                  expression=filter,
344                  scope=int(scope),
345                  attrs=attrs.split(','),
346                  controls=["paged_results:1:1000"])
347     return True
348
349
350 packet_ldap_4 = null_packet
351 # searchResEntry
352 # Server response ignored for traffic generation
353
354
355 packet_ldap_5 = null_packet
356 # Server response ignored for traffic generation
357
358 packet_ldap_6 = null_packet
359
360 packet_ldap_7 = null_packet
361
362 packet_ldap_8 = null_packet
363
364 packet_ldap_9 = null_packet
365
366 packet_ldap_16 = null_packet
367
368 packet_lsarpc_0 = null_packet
369 # lsarClose
370
371 packet_lsarpc_1 = null_packet
372 # lsarDelete
373
374 packet_lsarpc_2 = null_packet
375 # lsarEnumeratePrivileges
376
377 packet_lsarpc_3 = null_packet
378 # LsarQuerySecurityObject
379
380 packet_lsarpc_4 = null_packet
381 # LsarSetSecurityObject
382
383 packet_lsarpc_5 = null_packet
384 # LsarChangePassword
385
386 packet_lsarpc_6 = null_packet
387 # lsa_OpenPolicy
388 # We ignore this, but take it as a hint that the lsarpc handle should
389 # be over a named pipe.
390 #
391
392
393 def packet_lsarpc_14(packet, conversation, context):
394     # lsa_LookupNames
395     c = context.get_lsarpc_named_pipe_connection()
396
397     objectAttr = lsa.ObjectAttribute()
398     pol_handle = c.OpenPolicy2(u'', objectAttr,
399                                security.SEC_FLAG_MAXIMUM_ALLOWED)
400
401     sids  = lsa.TransSidArray()
402     names = [lsa.String("This Organization"),
403              lsa.String("Digest Authentication")]
404     level = lsa.LSA_LOOKUP_NAMES_ALL
405     count = 0
406     c.LookupNames(pol_handle, names, sids, level, count)
407     return True
408
409
410 def packet_lsarpc_15(packet, conversation, context):
411     # lsa_LookupSids
412     c = context.get_lsarpc_named_pipe_connection()
413
414     objectAttr = lsa.ObjectAttribute()
415     pol_handle = c.OpenPolicy2(u'', objectAttr,
416                                security.SEC_FLAG_MAXIMUM_ALLOWED)
417
418     sids = lsa.SidArray()
419     sid = lsa.SidPtr()
420
421     x = dom_sid("S-1-5-7")
422     sid.sid = x
423     sids.sids = [sid]
424     sids.num_sids = 1
425     names = lsa.TransNameArray()
426     level = lsa.LSA_LOOKUP_NAMES_ALL
427     count = 0
428
429     c.LookupSids(pol_handle, sids, names, level, count)
430     return True
431
432
433 def packet_lsarpc_39(packet, conversation, context):
434     # lsa_QueryTrustedDomainInfoBySid
435     # Samba does not support trusted domains, so this call is expected to fail
436     #
437     c = context.get_lsarpc_named_pipe_connection()
438
439     objectAttr = lsa.ObjectAttribute()
440
441     pol_handle = c.OpenPolicy2(u'', objectAttr,
442                                security.SEC_FLAG_MAXIMUM_ALLOWED)
443
444     domsid = security.dom_sid(context.domain_sid)
445     level = 1
446     try:
447         c.QueryTrustedDomainInfoBySid(pol_handle, domsid, level)
448     except NTSTATUSError as error:
449         # Object Not found is the expected result from samba,
450         # while No Such Domain is the expected result from windows,
451         # anything else is a failure.
452         if not check_runtime_error(error, NT_STATUS_OBJECT_NAME_NOT_FOUND) \
453                 and not check_runtime_error(error, NT_STATUS_NO_SUCH_DOMAIN):
454             raise
455     return True
456
457
458 packet_lsarpc_40 = null_packet
459 # lsa_SetTrustedDomainInfo
460 # Not currently supported
461
462
463 packet_lsarpc_43 = null_packet
464 # LsaStorePrivateData
465
466
467 packet_lsarpc_44 = null_packet
468 # LsaRetrievePrivateData
469
470
471 packet_lsarpc_68 = null_packet
472 # LsarLookupNames3
473
474
475 def packet_lsarpc_76(packet, conversation, context):
476     # lsa_LookupSids3
477     c = context.get_lsarpc_connection()
478     sids = lsa.SidArray()
479     sid = lsa.SidPtr()
480     # Need a set
481     x = dom_sid("S-1-5-7")
482     sid.sid = x
483     sids.sids = [sid]
484     sids.num_sids = 1
485     names = lsa.TransNameArray2()
486     level = lsa.LSA_LOOKUP_NAMES_ALL
487     count = 0
488     lookup_options = lsa.LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES
489     client_revision = lsa.LSA_CLIENT_REVISION_2
490     c.LookupSids3(sids, names, level, count, lookup_options, client_revision)
491     return True
492
493
494 def packet_lsarpc_77(packet, conversation, context):
495     # lsa_LookupNames4
496     c = context.get_lsarpc_connection()
497     sids  = lsa.TransSidArray3()
498     names = [lsa.String("This Organization"),
499              lsa.String("Digest Authentication")]
500     level = lsa.LSA_LOOKUP_NAMES_ALL
501     count = 0
502     lookup_options = lsa.LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES
503     client_revision = lsa.LSA_CLIENT_REVISION_2
504     c.LookupNames4(names, sids, level, count, lookup_options, client_revision)
505     return True
506
507
508 def packet_nbns_0(packet, conversation, context):
509     # query
510     n = Node()
511     try:
512         n.query_name("ANAME", context.server, timeout=4, broadcast=False)
513     except:
514         pass
515     return True
516
517
518 packet_nbns_1 = null_packet
519 # response
520 # Server response, not generated by the client
521
522
523 packet_rpc_netlogon_0 = null_packet
524
525 packet_rpc_netlogon_1 = null_packet
526
527 packet_rpc_netlogon_4 = null_packet
528 # NetrServerReqChallenge
529 # generated by higher level protocol drivers
530 # ignored for traffic generation
531
532 packet_rpc_netlogon_14 = null_packet
533
534 packet_rpc_netlogon_15 = null_packet
535
536 packet_rpc_netlogon_21 = null_packet
537 # NetrLogonDummyRoutine1
538 # Used to determine security settings. Triggered from schannel setup
539 # So no need for an explicit generator
540
541
542 packet_rpc_netlogon_26 = null_packet
543 # NetrServerAuthenticate3
544 # Triggered from schannel set up, no need for an explicit generator
545
546
547 def packet_rpc_netlogon_29(packet, conversation, context):
548     # NetrLogonGetDomainInfo [531]
549     c = context.get_netlogon_connection()
550     (auth, succ) = context.get_authenticator()
551     query = netr_WorkstationInformation()
552
553     c.netr_LogonGetDomainInfo(context.server,
554                               context.netbios_name,
555                               auth,
556                               succ,
557                               2,      # TODO are there other values?
558                               query)
559     return True
560
561
562 def packet_rpc_netlogon_30(packet, conversation, context):
563     # NetrServerPasswordSet2
564     c = context.get_netlogon_connection()
565     (auth, succ) = context.get_authenticator()
566     DATA_LEN = 512
567     # Set the new password to the existing password, this generates the same
568     # work load as a new value, and leaves the account password intact for
569     # subsequent runs
570     newpass = context.machine_creds.get_password().encode('utf-16-le')
571     pwd_len = len(newpass)
572     filler  = list(os.urandom(DATA_LEN - pwd_len))
573     pwd = netlogon.netr_CryptPassword()
574     pwd.length = pwd_len
575     pwd.data = filler + list(newpass)
576     context.machine_creds.encrypt_netr_crypt_password(pwd)
577     c.netr_ServerPasswordSet2(context.server,
578                               # must ends with $, so use get_username instead
579                               # of get_workstation here
580                               context.machine_creds.get_username(),
581                               context.machine_creds.get_secure_channel_type(),
582                               context.netbios_name,
583                               auth,
584                               pwd)
585     return True
586
587
588 packet_rpc_netlogon_34 = null_packet
589
590
591 def packet_rpc_netlogon_39(packet, conversation, context):
592     # NetrLogonSamLogonEx [4331]
593     def connect(creds):
594         c = context.get_netlogon_connection()
595
596         # Disable Kerberos in cli creds to extract NTLM response
597         old_state = creds.get_kerberos_state()
598         creds.set_kerberos_state(DONT_USE_KERBEROS)
599
600         logon = samlogon_logon_info(context.domain,
601                                     context.netbios_name,
602                                     creds)
603         logon_level = netlogon.NetlogonNetworkTransitiveInformation
604         validation_level = netlogon.NetlogonValidationSamInfo4
605         netr_flags = 0
606         c.netr_LogonSamLogonEx(context.server,
607                                context.machine_creds.get_workstation(),
608                                logon_level,
609                                logon,
610                                validation_level,
611                                netr_flags)
612
613         creds.set_kerberos_state(old_state)
614
615     context.last_samlogon_bad =\
616         context.with_random_bad_credentials(connect,
617                                             context.user_creds,
618                                             context.user_creds_bad,
619                                             context.last_samlogon_bad)
620     return True
621
622
623 def samlogon_target(domain_name, computer_name):
624     target_info = ntlmssp.AV_PAIR_LIST()
625     target_info.count = 3
626     computername = ntlmssp.AV_PAIR()
627     computername.AvId = ntlmssp.MsvAvNbComputerName
628     computername.Value = computer_name
629
630     domainname = ntlmssp.AV_PAIR()
631     domainname.AvId = ntlmssp.MsvAvNbDomainName
632     domainname.Value = domain_name
633
634     eol = ntlmssp.AV_PAIR()
635     eol.AvId = ntlmssp.MsvAvEOL
636     target_info.pair = [domainname, computername, eol]
637
638     return ndr_pack(target_info)
639
640
641 def samlogon_logon_info(domain_name, computer_name, creds):
642
643     target_info_blob = samlogon_target(domain_name, computer_name)
644
645     challenge = b"abcdefgh"
646     # User account under test
647     response = creds.get_ntlm_response(flags=CLI_CRED_NTLMv2_AUTH,
648                                        challenge=challenge,
649                                        target_info=target_info_blob)
650
651     logon = netlogon.netr_NetworkInfo()
652
653     logon.challenge     = list(challenge)
654     logon.nt            = netlogon.netr_ChallengeResponse()
655     logon.nt.length     = len(response["nt_response"])
656     logon.nt.data       = list(response["nt_response"])
657
658     logon.identity_info = netlogon.netr_IdentityInfo()
659
660     (username, domain)  = creds.get_ntlm_username_domain()
661     logon.identity_info.domain_name.string  = domain
662     logon.identity_info.account_name.string = username
663     logon.identity_info.workstation.string  = creds.get_workstation()
664
665     return logon
666
667
668 def packet_rpc_netlogon_40(packet, conversation, context):
669     # DsrEnumerateDomainTrusts
670     c = context.get_netlogon_connection()
671     c.netr_DsrEnumerateDomainTrusts(
672         context.server,
673         netlogon.NETR_TRUST_FLAG_IN_FOREST |
674         netlogon.NETR_TRUST_FLAG_OUTBOUND  |
675         netlogon.NETR_TRUST_FLAG_INBOUND)
676     return True
677
678
679 def packet_rpc_netlogon_45(packet, conversation, context):
680     # NetrLogonSamLogonWithFlags [7]
681     def connect(creds):
682         c = context.get_netlogon_connection()
683         (auth, succ) = context.get_authenticator()
684
685         # Disable Kerberos in cli creds to extract NTLM response
686         old_state = creds.get_kerberos_state()
687         creds.set_kerberos_state(DONT_USE_KERBEROS)
688
689         logon = samlogon_logon_info(context.domain,
690                                     context.netbios_name,
691                                     creds)
692         logon_level = netlogon.NetlogonNetworkTransitiveInformation
693         validation_level = netlogon.NetlogonValidationSamInfo4
694         netr_flags = 0
695         c.netr_LogonSamLogonWithFlags(context.server,
696                                       context.machine_creds.get_workstation(),
697                                       auth,
698                                       succ,
699                                       logon_level,
700                                       logon,
701                                       validation_level,
702                                       netr_flags)
703
704         creds.set_kerberos_state(old_state)
705
706     context.last_samlogon_bad =\
707         context.with_random_bad_credentials(connect,
708                                             context.user_creds,
709                                             context.user_creds_bad,
710                                             context.last_samlogon_bad)
711     return True
712
713
714 def packet_samr_0(packet, conversation, context):
715     # Open
716     c = context.get_samr_context()
717     c.get_handle()
718     return True
719
720
721 def packet_samr_1(packet, conversation, context):
722     # Close
723     c = context.get_samr_context()
724     s = c.get_connection()
725     # close the last opened handle, may not always be accurate
726     # but will do for load simulation
727     if c.user_handle is not None:
728         s.Close(c.user_handle)
729         c.user_handle = None
730     elif c.group_handle is not None:
731         s.Close(c.group_handle)
732         c.group_handle = None
733     elif c.domain_handle is not None:
734         s.Close(c.domain_handle)
735         c.domain_handle = None
736         c.rids          = None
737     elif c.handle is not None:
738         s.Close(c.handle)
739         c.handle     = None
740         c.domain_sid = None
741     return True
742
743
744 def packet_samr_3(packet, conversation, context):
745     # QuerySecurity
746     c = context.get_samr_context()
747     s = c.get_connection()
748     if c.user_handle is None:
749         packet_samr_34(packet, conversation, context)
750     s.QuerySecurity(c.user_handle, 1)
751     return True
752
753
754 def packet_samr_5(packet, conversation, context):
755     # LookupDomain
756     c = context.get_samr_context()
757     s = c.get_connection()
758     h = c.get_handle()
759     d = lsa.String()
760     d.string = context.domain
761     c.domain_sid = s.LookupDomain(h, d)
762     return True
763
764
765 def packet_samr_6(packet, conversation, context):
766     # EnumDomains
767     c = context.get_samr_context()
768     s = c.get_connection()
769     h = c.get_handle()
770     s.EnumDomains(h, 0, 0)
771     return True
772
773
774 def packet_samr_7(packet, conversation, context):
775     # OpenDomain
776     c = context.get_samr_context()
777     s = c.get_connection()
778     h = c.get_handle()
779     if c.domain_sid is None:
780         packet_samr_5(packet, conversation, context)
781
782     c.domain_handle = s.OpenDomain(h,
783                                    security.SEC_FLAG_MAXIMUM_ALLOWED,
784                                    c.domain_sid)
785     return True
786
787
788 SAMR_QUERY_DOMAIN_INFO_LEVELS = [8, 12]
789
790
791 def packet_samr_8(packet, conversation, context):
792     # QueryDomainInfo [228]
793     c = context.get_samr_context()
794     s = c.get_connection()
795     if c.domain_handle is None:
796         packet_samr_7(packet, conversation, context)
797     level = random.choice(SAMR_QUERY_DOMAIN_INFO_LEVELS)
798     s.QueryDomainInfo(c.domain_handle, level)
799     return True
800
801
802 packet_samr_14 = null_packet
803 # CreateDomainAlias
804 # Ignore these for now.
805
806
807 def packet_samr_15(packet, conversation, context):
808     # EnumDomainAliases
809     c = context.get_samr_context()
810     s = c.get_connection()
811     if c.domain_handle is None:
812         packet_samr_7(packet, conversation, context)
813
814     s.EnumDomainAliases(c.domain_handle, 100, 0)
815     return True
816
817
818 def packet_samr_16(packet, conversation, context):
819     # GetAliasMembership
820     c = context.get_samr_context()
821     s = c.get_connection()
822     if c.domain_handle is None:
823         packet_samr_7(packet, conversation, context)
824
825     sids = lsa.SidArray()
826     sid  = lsa.SidPtr()
827     sid.sid = c.domain_sid
828     sids.sids = [sid]
829     s.GetAliasMembership(c.domain_handle, sids)
830     return True
831
832
833 def packet_samr_17(packet, conversation, context):
834     # LookupNames
835     c = context.get_samr_context()
836     s = c.get_connection()
837     if c.domain_handle is None:
838         packet_samr_7(packet, conversation, context)
839
840     name = lsa.String(context.username)
841     c.rids = s.LookupNames(c.domain_handle, [name])
842     return True
843
844
845 def packet_samr_18(packet, conversation, context):
846     # LookupRids
847     c = context.get_samr_context()
848     s = c.get_connection()
849     if c.rids is None:
850         packet_samr_17(packet, conversation, context)
851     rids = []
852     for r in c.rids:
853         for i in r.ids:
854             rids.append(i)
855     s.LookupRids(c.domain_handle, rids)
856     return True
857
858
859 def packet_samr_19(packet, conversation, context):
860     # OpenGroup
861     c = context.get_samr_context()
862     s = c.get_connection()
863     if c.domain_handle is None:
864         packet_samr_7(packet, conversation, context)
865
866     rid = 0x202  # Users I think.
867     c.group_handle = s.OpenGroup(c.domain_handle,
868                                  security.SEC_FLAG_MAXIMUM_ALLOWED,
869                                  rid)
870     return True
871
872
873 def packet_samr_25(packet, conversation, context):
874     # QueryGroupMember
875     c = context.get_samr_context()
876     s = c.get_connection()
877     if c.group_handle is None:
878         packet_samr_19(packet, conversation, context)
879     s.QueryGroupMember(c.group_handle)
880     return True
881
882
883 def packet_samr_34(packet, conversation, context):
884     # OpenUser
885     c = context.get_samr_context()
886     s = c.get_connection()
887     if c.rids is None:
888         packet_samr_17(packet, conversation, context)
889     c.user_handle = s.OpenUser(c.domain_handle,
890                                security.SEC_FLAG_MAXIMUM_ALLOWED,
891                                c.rids[0].ids[0])
892     return True
893
894
895 def packet_samr_36(packet, conversation, context):
896     # QueryUserInfo
897     c = context.get_samr_context()
898     s = c.get_connection()
899     if c.user_handle is None:
900         packet_samr_34(packet, conversation, context)
901     level = 1
902     s.QueryUserInfo(c.user_handle, level)
903     return True
904
905
906 packet_samr_37 = null_packet
907
908
909 def packet_samr_39(packet, conversation, context):
910     # GetGroupsForUser
911     c = context.get_samr_context()
912     s = c.get_connection()
913     if c.user_handle is None:
914         packet_samr_34(packet, conversation, context)
915     s.GetGroupsForUser(c.user_handle)
916     return True
917
918
919 packet_samr_40 = null_packet
920
921 packet_samr_44 = null_packet
922
923
924 def packet_samr_57(packet, conversation, context):
925     # Connect2
926     c = context.get_samr_context()
927     c.get_handle()
928     return True
929
930
931 def packet_samr_64(packet, conversation, context):
932     # Connect5
933     c = context.get_samr_context()
934     c.get_handle()
935     return True
936
937
938 packet_samr_68 = null_packet
939
940
941 def packet_srvsvc_16(packet, conversation, context):
942     # NetShareGetInfo
943     s = context.get_srvsvc_connection()
944     server_unc = "\\\\" + context.server
945     share_name = "IPC$"
946     level = 1
947     s.NetShareGetInfo(server_unc, share_name, level)
948     return True
949
950
951 def packet_srvsvc_21(packet, conversation, context):
952     """NetSrvGetInfo
953
954     FIXME: Level changed from 102 to 101 here, to bypass Windows error.
955
956     Level 102 will cause WERR_ACCESS_DENIED error against Windows, because:
957
958         > If the level is 102 or 502, the Windows implementation checks whether
959         > the caller is a member of one of the groups previously mentioned or
960         > is a member of the Power Users local group.
961
962     It passed against Samba since this check is not implemented by Samba yet.
963
964     refer to:
965
966         https://msdn.microsoft.com/en-us/library/cc247297.aspx#Appendix_A_80
967
968     """
969     srvsvc = context.get_srvsvc_connection()
970     server_unc = "\\\\" + context.server
971     level = 101
972     srvsvc.NetSrvGetInfo(server_unc, level)
973     return True