py:dcerpc/raw_testcase: add pfc_flags_2nd and use_auth3 options to do_generic_bind()
[samba.git] / python / samba / tests / dcerpc / raw_testcase.py
1 # Unix SMB/CIFS implementation.
2 # Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007-2010
3 # Copyright (C) Stefan Metzmacher 2014,2015
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
19 import sys
20 import socket
21 import samba.dcerpc.dcerpc as dcerpc
22 import samba.dcerpc.base
23 import samba.dcerpc.epmapper
24 import samba.dcerpc.security as security
25 import samba.tests
26 from samba import gensec
27 from samba.credentials import Credentials
28 from samba.tests import TestCase
29 from samba.ndr import ndr_pack, ndr_unpack, ndr_unpack_out
30 from samba.compat import text_type
31 from samba.ntstatus import (
32     NT_STATUS_CONNECTION_DISCONNECTED,
33     NT_STATUS_PIPE_DISCONNECTED,
34     NT_STATUS_IO_TIMEOUT
35 )
36 from samba import NTSTATUSError
37 from samba.samba3 import param as s3param
38 from samba.samba3 import libsmb_samba_internal as libsmb
39
40 class smb_pipe_socket(object):
41
42     def __init__(self, target_hostname, pipename, creds, impersonation_level, lp):
43         lp3 = s3param.get_context()
44         lp3.load(lp.configfile)
45         self.smbconn = libsmb.Conn(target_hostname, 'IPC$', lp3,
46                                    creds=creds, sign=True)
47         self.smbfid = self.smbconn.create(pipename,
48                                           DesiredAccess=0x12019f,
49                                           ShareAccess=0x7,
50                                           CreateDisposition=1,
51                                           CreateOptions=0x400040,
52                                           ImpersonationLevel=impersonation_level)
53         return
54
55     def close(self):
56         self.smbconn.close(self.smbfid)
57         del self.smbconn
58
59     def settimeout(self, timeo):
60         # The socket module we simulate there
61         # specifies the timeo as seconds as float.
62         msecs = int(timeo * 1000)
63         assert msecs >= 0
64         self.smbconn.settimeout(msecs)
65         return
66
67     def send(self, buf, flags=0):
68         return self.smbconn.write(self.smbfid, buffer=buf, offset=0, mode=8)
69
70     def recv(self, len, flags=0):
71         try:
72             return self.smbconn.read(self.smbfid, offset=0, size=len)
73         except NTSTATUSError as e:
74             if e.args[0] == NT_STATUS_CONNECTION_DISCONNECTED:
75                 return b'\0' * 0
76             if e.args[0] == NT_STATUS_PIPE_DISCONNECTED:
77                 return b'\0' * 0
78             if e.args[0] == NT_STATUS_IO_TIMEOUT:
79                 raise socket.timeout(str(e))
80             raise e
81
82 class RawDCERPCTest(TestCase):
83     """A raw DCE/RPC Test case."""
84
85     def _disconnect(self, reason):
86         if self.s is None:
87             return
88         self.s.close()
89         self.s = None
90         if self.do_hexdump:
91             sys.stderr.write("disconnect[%s]\n" % reason)
92
93     def _connect_tcp(self):
94         tcp_port = int(self.primary_address)
95         try:
96             self.a = socket.getaddrinfo(self.host, tcp_port, socket.AF_UNSPEC,
97                                         socket.SOCK_STREAM, socket.SOL_TCP,
98                                         0)
99             self.s = socket.socket(self.a[0][0], self.a[0][1], self.a[0][2])
100             self.s.settimeout(10)
101             self.s.connect(self.a[0][4])
102         except socket.error as e:
103             self.s.close()
104             raise
105         except IOError as e:
106             self.s.close()
107             raise
108         except Exception as e:
109             raise
110         finally:
111             pass
112         self.max_xmit_frag = 5840
113         self.max_recv_frag = 5840
114         if self.secondary_address is None:
115             self.secondary_address = self.primary_address
116         # compat for older tests
117         self.tcp_port = tcp_port
118
119     def _connect_smb(self):
120         a = self.primary_address.split('\\')
121         self.assertEquals(len(a), 3)
122         self.assertEquals(a[0], "")
123         self.assertEquals(a[1], "pipe")
124         pipename = a[2]
125         self.s = smb_pipe_socket(self.target_hostname,
126                                  pipename,
127                                  self.transport_creds,
128                                  self.transport_impersonation,
129                                  self.lp_ctx)
130         self.max_xmit_frag = 4280
131         self.max_recv_frag = 4280
132         if self.secondary_address is None:
133             self.secondary_address = self.primary_address
134
135     def connect(self):
136         self.assertNotConnected()
137         if self.primary_address.startswith("\\pipe\\"):
138             self._connect_smb()
139         else:
140             self._connect_tcp()
141         if self.secondary_address is None:
142             self.secondary_address = self.primary_address
143         return
144
145     def setUp(self):
146         super(RawDCERPCTest, self).setUp()
147         self.do_ndr_print = False
148         self.do_hexdump = False
149
150         self.ignore_random_pad = samba.tests.env_get_var_value('IGNORE_RANDOM_PAD',
151                                                                allow_missing=True)
152         self.host = samba.tests.env_get_var_value('SERVER')
153         self.target_hostname = samba.tests.env_get_var_value('TARGET_HOSTNAME', allow_missing=True)
154         if self.target_hostname is None:
155             self.target_hostname = self.host
156         self.primary_address = "135"
157         self.secondary_address = None
158         self.transport_creds = self.get_anon_creds()
159         self.transport_impersonation = 0x2
160
161         self.settings = {}
162         self.settings["lp_ctx"] = self.lp_ctx = samba.tests.env_loadparm()
163         self.settings["target_hostname"] = self.target_hostname
164
165         self.s = None
166         self.connect()
167
168     def tearDown(self):
169         self._disconnect("tearDown")
170         super(TestCase, self).tearDown()
171
172     def noop(self):
173         return
174
175     def reconnect_smb_pipe(self, primary_address, secondary_address=None,
176                            transport_creds=None, transport_impersonation=None):
177         self._disconnect("reconnect_smb_pipe")
178         self.assertIsNotNone(primary_address)
179         self.primary_address = primary_address
180         if secondary_address is not None:
181             self.secondary_address = secondary_address
182         else:
183             self.secondary_address = None
184
185         if transport_creds is not None:
186             self.transport_creds = transport_creds
187
188         if transport_impersonation is not None:
189             self.transport_impersonation = transport_impersonation
190
191         self.connect()
192         return
193
194     def second_connection(self, primary_address=None, secondary_address=None,
195                           transport_creds=None, transport_impersonation=None):
196         c = RawDCERPCTest(methodName='noop')
197         c.do_ndr_print = self.do_ndr_print
198         c.do_hexdump = self.do_hexdump
199         c.ignore_random_pad = self.ignore_random_pad
200
201         c.host = self.host
202         c.target_hostname = self.target_hostname
203         if primary_address is not None:
204             c.primary_address = primary_address
205             if secondary_address is not None:
206                 c.secondary_address = secondary_address
207             else:
208                 c.secondary_address = None
209         else:
210             self.assertIsNone(secondary_address)
211             c.primary_address = self.primary_address
212             c.secondary_address = self.secondary_address
213
214         if transport_creds is not None:
215             c.transport_creds = transport_creds
216         else:
217             c.transport_creds = self.transport_creds
218
219         if transport_impersonation is not None:
220             c.transport_impersonation = transport_impersonation
221         else:
222             c.transport_impersonation = self.transport_impersonation
223
224         c.lp_ctx = self.lp_ctx
225         c.settings = self.settings
226
227         c.s = None
228         c.connect()
229         return c
230
231     def get_user_creds(self):
232         c = Credentials()
233         c.guess()
234         domain = samba.tests.env_get_var_value('DOMAIN')
235         realm = samba.tests.env_get_var_value('REALM')
236         username = samba.tests.env_get_var_value('USERNAME')
237         password = samba.tests.env_get_var_value('PASSWORD')
238         c.set_domain(domain)
239         c.set_realm(realm)
240         c.set_username(username)
241         c.set_password(password)
242         return c
243
244     def get_anon_creds(self):
245         c = Credentials()
246         c.set_anonymous()
247         return c
248
249     def get_auth_context_creds(self, creds, auth_type, auth_level,
250                                auth_context_id,
251                                g_auth_level=None,
252                                hdr_signing=False):
253
254         if g_auth_level is None:
255             g_auth_level = auth_level
256
257         g = gensec.Security.start_client(self.settings)
258         g.set_credentials(creds)
259         g.want_feature(gensec.FEATURE_DCE_STYLE)
260         g.start_mech_by_authtype(auth_type, g_auth_level)
261
262         if auth_type == dcerpc.DCERPC_AUTH_TYPE_KRB5:
263             expect_3legs = True
264         elif auth_type == dcerpc.DCERPC_AUTH_TYPE_NTLMSSP:
265             expect_3legs = True
266         else:
267             expect_3legs = False
268
269         auth_context = {}
270         auth_context["auth_type"] = auth_type
271         auth_context["auth_level"] = auth_level
272         auth_context["auth_context_id"] = auth_context_id
273         auth_context["g_auth_level"] = g_auth_level
274         auth_context["gensec"] = g
275         auth_context["hdr_signing"] = hdr_signing
276         auth_context["expect_3legs"] = expect_3legs
277
278         return auth_context
279
280     def do_generic_bind(self, ctx, auth_context=None,
281                         pfc_flags=samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST |
282                         samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST,
283                         assoc_group_id=0, call_id=0,
284                         nak_reason=None, alter_fault=None,
285                         start_with_alter=False,
286                         pfc_flags_2nd=samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST |
287                         samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST,
288                         use_auth3=False):
289         ctx_list = [ctx]
290
291         if auth_context is not None:
292             if auth_context['hdr_signing']:
293                 pfc_flags |= dcerpc.DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN
294
295             expect_3legs = auth_context["expect_3legs"]
296
297             from_server = b""
298             (finished, to_server) = auth_context["gensec"].update(from_server)
299             self.assertFalse(finished)
300
301             auth_info = self.generate_auth(auth_type=auth_context["auth_type"],
302                                            auth_level=auth_context["auth_level"],
303                                            auth_context_id=auth_context["auth_context_id"],
304                                            auth_blob=to_server)
305         else:
306             auth_info = b""
307
308         if start_with_alter:
309             req = self.generate_alter(call_id=call_id,
310                                       pfc_flags=pfc_flags,
311                                       ctx_list=ctx_list,
312                                       assoc_group_id=0xffffffff - assoc_group_id,
313                                       auth_info=auth_info)
314             self.send_pdu(req)
315             rep = self.recv_pdu()
316             if alter_fault is not None:
317                 self.verify_pdu(rep, samba.dcerpc.dcerpc.DCERPC_PKT_FAULT, req.call_id,
318                                 pfc_flags=req.pfc_flags |
319                                 samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
320                                 auth_length=0)
321                 self.assertNotEquals(rep.u.alloc_hint, 0)
322                 self.assertEquals(rep.u.context_id, 0)
323                 self.assertEquals(rep.u.cancel_count, 0)
324                 self.assertEquals(rep.u.flags, 0)
325                 self.assertEquals(rep.u.status, alter_fault)
326                 self.assertEquals(rep.u.reserved, 0)
327                 self.assertEquals(len(rep.u.error_and_verifier), 0)
328                 return None
329             self.verify_pdu(rep, samba.dcerpc.dcerpc.DCERPC_PKT_ALTER_RESP, req.call_id,
330                             pfc_flags=req.pfc_flags)
331             self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag)
332             self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag)
333             self.assertEquals(rep.u.assoc_group_id, assoc_group_id)
334             self.assertEquals(rep.u.secondary_address_size, 0)
335             self.assertEquals(rep.u.secondary_address, '')
336             self.assertPadding(rep.u._pad1, 2)
337         else:
338             req = self.generate_bind(call_id=call_id,
339                                      pfc_flags=pfc_flags,
340                                      ctx_list=ctx_list,
341                                      assoc_group_id=assoc_group_id,
342                                      auth_info=auth_info)
343             self.send_pdu(req)
344             rep = self.recv_pdu()
345             if nak_reason is not None:
346                 self.verify_pdu(rep, samba.dcerpc.dcerpc.DCERPC_PKT_BIND_NAK, req.call_id,
347                                 auth_length=0)
348                 self.assertEquals(rep.u.reject_reason, nak_reason)
349                 self.assertEquals(rep.u.num_versions, 1)
350                 self.assertEquals(rep.u.versions[0].rpc_vers, req.rpc_vers)
351                 self.assertEquals(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor)
352                 self.assertPadding(rep.u._pad, 3)
353                 return
354             self.verify_pdu(rep, samba.dcerpc.dcerpc.DCERPC_PKT_BIND_ACK, req.call_id,
355                             pfc_flags=pfc_flags)
356             self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag)
357             self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag)
358             if assoc_group_id != 0:
359                 self.assertEquals(rep.u.assoc_group_id, assoc_group_id)
360             else:
361                 self.assertNotEquals(rep.u.assoc_group_id, 0)
362                 assoc_group_id = rep.u.assoc_group_id
363             sda_str = self.secondary_address
364             sda_len = len(sda_str) + 1
365             mod_len = (2 + sda_len) % 4
366             if mod_len != 0:
367                 sda_pad = 4 - mod_len
368             else:
369                 sda_pad = 0
370             self.assertEquals(rep.u.secondary_address_size, sda_len)
371             self.assertEquals(rep.u.secondary_address, sda_str)
372             self.assertPadding(rep.u._pad1, sda_pad)
373
374         self.assertEquals(rep.u.num_results, 1)
375         self.assertEquals(rep.u.ctx_list[0].result,
376                           samba.dcerpc.dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE)
377         self.assertEquals(rep.u.ctx_list[0].reason,
378                           samba.dcerpc.dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
379         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ctx.transfer_syntaxes[0])
380         ack = rep
381         if auth_context is None:
382             self.assertEquals(rep.auth_length, 0)
383             self.assertEquals(len(rep.u.auth_info), 0)
384             return ack
385         self.assertNotEquals(rep.auth_length, 0)
386         self.assertGreater(len(rep.u.auth_info), samba.dcerpc.dcerpc.DCERPC_AUTH_TRAILER_LENGTH)
387         self.assertEquals(rep.auth_length, len(rep.u.auth_info) - samba.dcerpc.dcerpc.DCERPC_AUTH_TRAILER_LENGTH)
388
389         a = self.parse_auth(rep.u.auth_info, auth_context=auth_context)
390
391         from_server = a.credentials
392         (finished, to_server) = auth_context["gensec"].update(from_server)
393         if expect_3legs:
394             self.assertTrue(finished)
395             if auth_context['hdr_signing']:
396                 auth_context["gensec"].want_feature(gensec.FEATURE_SIGN_PKT_HEADER)
397         else:
398             self.assertFalse(use_auth3)
399             self.assertFalse(finished)
400
401         auth_info = self.generate_auth(auth_type=auth_context["auth_type"],
402                                        auth_level=auth_context["auth_level"],
403                                        auth_context_id=auth_context["auth_context_id"],
404                                        auth_blob=to_server)
405         if use_auth3:
406             req = self.generate_auth3(call_id=call_id,
407                                       pfc_flags=pfc_flags_2nd,
408                                       auth_info=auth_info)
409             self.send_pdu(req)
410             rep = self.recv_pdu(timeout=0.01)
411             self.assertIsNone(rep)
412             self.assertIsConnected()
413             return ack
414         req = self.generate_alter(call_id=call_id,
415                                   ctx_list=ctx_list,
416                                   pfc_flags=pfc_flags_2nd,
417                                   assoc_group_id=0xffffffff - assoc_group_id,
418                                   auth_info=auth_info)
419         self.send_pdu(req)
420         rep = self.recv_pdu()
421         if alter_fault is not None:
422             self.verify_pdu(rep, samba.dcerpc.dcerpc.DCERPC_PKT_FAULT, req.call_id,
423                             pfc_flags=req.pfc_flags |
424                             samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
425                             auth_length=0)
426             self.assertNotEquals(rep.u.alloc_hint, 0)
427             self.assertEquals(rep.u.context_id, 0)
428             self.assertEquals(rep.u.cancel_count, 0)
429             self.assertEquals(rep.u.flags, 0)
430             self.assertEquals(rep.u.status, alter_fault)
431             self.assertEquals(rep.u.reserved, 0)
432             self.assertEquals(len(rep.u.error_and_verifier), 0)
433             return None
434         self.verify_pdu(rep, samba.dcerpc.dcerpc.DCERPC_PKT_ALTER_RESP, req.call_id,
435                         pfc_flags=req.pfc_flags)
436         self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag)
437         self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag)
438         self.assertEquals(rep.u.assoc_group_id, assoc_group_id)
439         self.assertEquals(rep.u.secondary_address_size, 0)
440         self.assertEquals(rep.u.secondary_address, '')
441         self.assertPadding(rep.u._pad1, 2)
442         self.assertEquals(rep.u.num_results, 1)
443         self.assertEquals(rep.u.ctx_list[0].result,
444                           samba.dcerpc.dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE)
445         self.assertEquals(rep.u.ctx_list[0].reason,
446                           samba.dcerpc.dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
447         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ctx.transfer_syntaxes[0])
448         if finished:
449             self.assertEquals(rep.auth_length, 0)
450         else:
451             self.assertNotEquals(rep.auth_length, 0)
452         self.assertGreaterEqual(len(rep.u.auth_info), samba.dcerpc.dcerpc.DCERPC_AUTH_TRAILER_LENGTH)
453         self.assertEquals(rep.auth_length, len(rep.u.auth_info) - samba.dcerpc.dcerpc.DCERPC_AUTH_TRAILER_LENGTH)
454
455         a = self.parse_auth(rep.u.auth_info, auth_context=auth_context)
456
457         if finished:
458             return ack
459
460         from_server = a.credentials
461         (finished, to_server) = auth_context["gensec"].update(from_server)
462         self.assertTrue(finished)
463         if auth_context['hdr_signing']:
464             auth_context["gensec"].want_feature(gensec.FEATURE_SIGN_PKT_HEADER)
465
466         return ack
467
468     def prepare_presentation(self, abstract, transfer, object=None,
469                              context_id=0xffff, epmap=False, auth_context=None,
470                              pfc_flags=samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST |
471                              samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST,
472                              assoc_group_id=0,
473                              return_ack=False):
474         if epmap:
475             self.epmap_reconnect(abstract, transfer=transfer, object=object)
476
477         tsf1_list = [transfer]
478         ctx = samba.dcerpc.dcerpc.ctx_list()
479         ctx.context_id = context_id
480         ctx.num_transfer_syntaxes = len(tsf1_list)
481         ctx.abstract_syntax = abstract
482         ctx.transfer_syntaxes = tsf1_list
483
484         ack = self.do_generic_bind(ctx=ctx,
485                                    auth_context=auth_context,
486                                    pfc_flags=pfc_flags,
487                                    assoc_group_id=assoc_group_id)
488         if ack is None:
489             ctx = None
490
491         if return_ack:
492             return (ctx, ack)
493         return ctx
494
495     def do_single_request(self, call_id, ctx, io,
496                           auth_context=None,
497                           object=None,
498                           bigendian=False, ndr64=False,
499                           allow_remaining=False,
500                           send_req=True,
501                           recv_rep=True,
502                           fault_pfc_flags=(
503                               samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST |
504                               samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST),
505                           fault_status=None,
506                           fault_context_id=None,
507                           timeout=None,
508                           ndr_print=None,
509                           hexdump=None):
510
511         if fault_context_id is None:
512             fault_context_id = ctx.context_id
513
514         if ndr_print is None:
515             ndr_print = self.do_ndr_print
516         if hexdump is None:
517             hexdump = self.do_hexdump
518
519         if send_req:
520             if ndr_print:
521                 sys.stderr.write("in: %s" % samba.ndr.ndr_print_in(io))
522             stub_in = samba.ndr.ndr_pack_in(io, bigendian=bigendian, ndr64=ndr64)
523             if hexdump:
524                 sys.stderr.write("stub_in: %d\n%s" % (len(stub_in), self.hexdump(stub_in)))
525
526         pfc_flags = samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST
527         pfc_flags |= samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST
528         if object is not None:
529             pfc_flags |= samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_OBJECT_UUID
530
531         req = self.generate_request_auth(call_id=call_id,
532                                          context_id=ctx.context_id,
533                                          pfc_flags=pfc_flags,
534                                          object=object,
535                                          opnum=io.opnum(),
536                                          stub=stub_in,
537                                          auth_context=auth_context)
538         if send_req:
539             self.send_pdu(req, ndr_print=ndr_print, hexdump=hexdump)
540         if recv_rep:
541             (rep, rep_blob) = self.recv_pdu_raw(timeout=timeout,
542                                                 ndr_print=ndr_print,
543                                                 hexdump=hexdump)
544             if fault_status:
545                 self.verify_pdu(rep, samba.dcerpc.dcerpc.DCERPC_PKT_FAULT, req.call_id,
546                                 pfc_flags=fault_pfc_flags, auth_length=0)
547                 self.assertNotEquals(rep.u.alloc_hint, 0)
548                 self.assertEquals(rep.u.context_id, fault_context_id)
549                 self.assertEquals(rep.u.cancel_count, 0)
550                 self.assertEquals(rep.u.flags, 0)
551                 self.assertEquals(rep.u.status, fault_status)
552                 self.assertEquals(rep.u.reserved, 0)
553                 self.assertEquals(len(rep.u.error_and_verifier), 0)
554                 return
555
556             expected_auth_length = 0
557             if auth_context is not None and \
558                auth_context["auth_level"] >= dcerpc.DCERPC_AUTH_LEVEL_PACKET:
559                 expected_auth_length = req.auth_length
560
561             self.verify_pdu(rep, samba.dcerpc.dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
562                             auth_length=expected_auth_length)
563             self.assertNotEquals(rep.u.alloc_hint, 0)
564             self.assertEquals(rep.u.context_id, req.u.context_id & 0xff)
565             self.assertEquals(rep.u.cancel_count, 0)
566             self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
567             stub_out = self.check_response_auth(rep, rep_blob, auth_context)
568             self.assertEqual(len(stub_out), rep.u.alloc_hint)
569
570             if hexdump:
571                 sys.stderr.write("stub_out: %d\n%s" % (len(stub_out), self.hexdump(stub_out)))
572             ndr_unpack_out(io, stub_out, bigendian=bigendian, ndr64=ndr64,
573                            allow_remaining=allow_remaining)
574             if ndr_print:
575                 sys.stderr.write("out: %s" % samba.ndr.ndr_print_out(io))
576
577     def epmap_reconnect(self, abstract, transfer=None, object=None):
578         ndr32 = samba.dcerpc.base.transfer_syntax_ndr()
579
580         if transfer is None:
581             transfer = ndr32
582
583         if object is None:
584             object = samba.dcerpc.misc.GUID()
585
586         ctx = self.prepare_presentation(samba.dcerpc.epmapper.abstract_syntax(),
587                                         transfer, context_id=0)
588
589         data1 = ndr_pack(abstract)
590         lhs1 = samba.dcerpc.epmapper.epm_lhs()
591         lhs1.protocol = samba.dcerpc.epmapper.EPM_PROTOCOL_UUID
592         lhs1.lhs_data = data1[:18]
593         rhs1 = samba.dcerpc.epmapper.epm_rhs_uuid()
594         rhs1.unknown = data1[18:]
595         floor1 = samba.dcerpc.epmapper.epm_floor()
596         floor1.lhs = lhs1
597         floor1.rhs = rhs1
598         data2 = ndr_pack(transfer)
599         lhs2 = samba.dcerpc.epmapper.epm_lhs()
600         lhs2.protocol = samba.dcerpc.epmapper.EPM_PROTOCOL_UUID
601         lhs2.lhs_data = data2[:18]
602         rhs2 = samba.dcerpc.epmapper.epm_rhs_uuid()
603         rhs2.unknown = data1[18:]
604         floor2 = samba.dcerpc.epmapper.epm_floor()
605         floor2.lhs = lhs2
606         floor2.rhs = rhs2
607         lhs3 = samba.dcerpc.epmapper.epm_lhs()
608         lhs3.protocol = samba.dcerpc.epmapper.EPM_PROTOCOL_NCACN
609         lhs3.lhs_data = b""
610         floor3 = samba.dcerpc.epmapper.epm_floor()
611         floor3.lhs = lhs3
612         floor3.rhs.minor_version = 0
613         lhs4 = samba.dcerpc.epmapper.epm_lhs()
614         lhs4.protocol = samba.dcerpc.epmapper.EPM_PROTOCOL_TCP
615         lhs4.lhs_data = b""
616         floor4 = samba.dcerpc.epmapper.epm_floor()
617         floor4.lhs = lhs4
618         floor4.rhs.port = int(self.primary_address)
619         lhs5 = samba.dcerpc.epmapper.epm_lhs()
620         lhs5.protocol = samba.dcerpc.epmapper.EPM_PROTOCOL_IP
621         lhs5.lhs_data = b""
622         floor5 = samba.dcerpc.epmapper.epm_floor()
623         floor5.lhs = lhs5
624         floor5.rhs.ipaddr = "0.0.0.0"
625
626         floors = [floor1, floor2, floor3, floor4, floor5]
627         req_tower = samba.dcerpc.epmapper.epm_tower()
628         req_tower.num_floors = len(floors)
629         req_tower.floors = floors
630         req_twr = samba.dcerpc.epmapper.epm_twr_t()
631         req_twr.tower = req_tower
632
633         epm_map = samba.dcerpc.epmapper.epm_Map()
634         epm_map.in_object = object
635         epm_map.in_map_tower = req_twr
636         epm_map.in_entry_handle = samba.dcerpc.misc.policy_handle()
637         epm_map.in_max_towers = 4
638
639         self.do_single_request(call_id=2, ctx=ctx, io=epm_map)
640
641         self.assertGreaterEqual(epm_map.out_num_towers, 1)
642         rep_twr = epm_map.out_towers[0].twr
643         self.assertIsNotNone(rep_twr)
644         self.assertEqual(rep_twr.tower_length, 75)
645         self.assertEqual(rep_twr.tower.num_floors, 5)
646         self.assertEqual(len(rep_twr.tower.floors), 5)
647         self.assertEqual(rep_twr.tower.floors[3].lhs.protocol,
648                          samba.dcerpc.epmapper.EPM_PROTOCOL_TCP)
649         self.assertEqual(rep_twr.tower.floors[3].lhs.protocol,
650                          samba.dcerpc.epmapper.EPM_PROTOCOL_TCP)
651
652         # reconnect to the given port
653         self._disconnect("epmap_reconnect")
654         self.primary_address = "%d" % rep_twr.tower.floors[3].rhs.port
655         self.secondary_address = None
656         self.connect()
657
658     def send_pdu(self, req, ndr_print=None, hexdump=None):
659         if ndr_print is None:
660             ndr_print = self.do_ndr_print
661         if hexdump is None:
662             hexdump = self.do_hexdump
663         try:
664             req_pdu = ndr_pack(req)
665             if ndr_print:
666                 sys.stderr.write("send_pdu: %s" % samba.ndr.ndr_print(req))
667             if hexdump:
668                 sys.stderr.write("send_pdu: %d\n%s" % (len(req_pdu), self.hexdump(req_pdu)))
669             while True:
670                 sent = self.s.send(req_pdu, 0)
671                 if sent == len(req_pdu):
672                     break
673                 req_pdu = req_pdu[sent:]
674         except socket.error as e:
675             self._disconnect("send_pdu: %s" % e)
676             raise
677         except IOError as e:
678             self._disconnect("send_pdu: %s" % e)
679             raise
680         except NTSTATUSError as e:
681             self._disconnect("send_pdu: %s" % e)
682             raise
683         finally:
684             pass
685
686     def recv_raw(self, hexdump=None, timeout=None):
687         rep_pdu = None
688         if hexdump is None:
689             hexdump = self.do_hexdump
690         try:
691             if timeout is not None:
692                 self.s.settimeout(timeout)
693             rep_pdu = self.s.recv(0xffff, 0)
694             self.s.settimeout(10)
695             if len(rep_pdu) == 0:
696                 self._disconnect("recv_raw: EOF")
697                 return None
698             if hexdump:
699                 sys.stderr.write("recv_raw: %d\n%s" % (len(rep_pdu), self.hexdump(rep_pdu)))
700         except socket.timeout as e:
701             self.s.settimeout(10)
702             sys.stderr.write("recv_raw: TIMEOUT\n")
703             pass
704         except socket.error as e:
705             self._disconnect("recv_raw: %s" % e)
706             raise
707         except IOError as e:
708             self._disconnect("recv_raw: %s" % e)
709             raise
710         finally:
711             pass
712         return rep_pdu
713
714     def recv_pdu_raw(self, ndr_print=None, hexdump=None, timeout=None):
715         rep_pdu = None
716         rep = None
717         if ndr_print is None:
718             ndr_print = self.do_ndr_print
719         if hexdump is None:
720             hexdump = self.do_hexdump
721         try:
722             rep_pdu = self.recv_raw(hexdump=hexdump, timeout=timeout)
723             if rep_pdu is None:
724                 return (None, None)
725             rep = ndr_unpack(samba.dcerpc.dcerpc.ncacn_packet, rep_pdu, allow_remaining=True)
726             if ndr_print:
727                 sys.stderr.write("recv_pdu: %s" % samba.ndr.ndr_print(rep))
728             self.assertEqual(rep.frag_length, len(rep_pdu))
729         finally:
730             pass
731         return (rep, rep_pdu)
732
733     def recv_pdu(self, ndr_print=None, hexdump=None, timeout=None):
734         (rep, rep_pdu) = self.recv_pdu_raw(ndr_print=ndr_print,
735                                            hexdump=hexdump,
736                                            timeout=timeout)
737         return rep
738
739     def generate_auth(self,
740                       auth_type=None,
741                       auth_level=None,
742                       auth_pad_length=0,
743                       auth_context_id=None,
744                       auth_blob=None,
745                       ndr_print=None, hexdump=None):
746         if ndr_print is None:
747             ndr_print = self.do_ndr_print
748         if hexdump is None:
749             hexdump = self.do_hexdump
750
751         if auth_type is not None:
752             a = samba.dcerpc.dcerpc.auth()
753             a.auth_type = auth_type
754             a.auth_level = auth_level
755             a.auth_pad_length = auth_pad_length
756             a.auth_context_id = auth_context_id
757             a.credentials = auth_blob
758
759             ai = ndr_pack(a)
760             if ndr_print:
761                 sys.stderr.write("generate_auth: %s" % samba.ndr.ndr_print(a))
762             if hexdump:
763                 sys.stderr.write("generate_auth: %d\n%s" % (len(ai), self.hexdump(ai)))
764         else:
765             ai = b""
766
767         return ai
768
769     def parse_auth(self, auth_info, ndr_print=None, hexdump=None,
770                    auth_context=None, stub_len=0):
771         if ndr_print is None:
772             ndr_print = self.do_ndr_print
773         if hexdump is None:
774             hexdump = self.do_hexdump
775
776         if (len(auth_info) <= samba.dcerpc.dcerpc.DCERPC_AUTH_TRAILER_LENGTH):
777             return None
778
779         if hexdump:
780             sys.stderr.write("parse_auth: %d\n%s" % (len(auth_info), self.hexdump(auth_info)))
781         a = ndr_unpack(samba.dcerpc.dcerpc.auth, auth_info, allow_remaining=True)
782         if ndr_print:
783             sys.stderr.write("parse_auth: %s" % samba.ndr.ndr_print(a))
784
785         if auth_context is not None:
786             self.assertEquals(a.auth_type, auth_context["auth_type"])
787             self.assertEquals(a.auth_level, auth_context["auth_level"])
788             self.assertEquals(a.auth_reserved, 0)
789             self.assertEquals(a.auth_context_id, auth_context["auth_context_id"])
790
791             self.assertLessEqual(a.auth_pad_length, dcerpc.DCERPC_AUTH_PAD_ALIGNMENT)
792             self.assertLessEqual(a.auth_pad_length, stub_len)
793
794         return a
795
796     def check_response_auth(self, rep, rep_blob, auth_context=None,
797                             auth_pad_length=None):
798
799         if auth_context is None:
800             self.assertEquals(rep.auth_length, 0)
801             return rep.u.stub_and_verifier
802
803         if auth_context["auth_level"] == dcerpc.DCERPC_AUTH_LEVEL_CONNECT:
804             self.assertEquals(rep.auth_length, 0)
805             return rep.u.stub_and_verifier
806
807         self.assertGreater(rep.auth_length, 0)
808
809         ofs_stub = dcerpc.DCERPC_REQUEST_LENGTH
810         ofs_sig = rep.frag_length - rep.auth_length
811         ofs_trailer = ofs_sig - dcerpc.DCERPC_AUTH_TRAILER_LENGTH
812         rep_data = rep_blob[ofs_stub:ofs_trailer]
813         rep_whole = rep_blob[0:ofs_sig]
814         rep_sig = rep_blob[ofs_sig:]
815         rep_auth_info_blob = rep_blob[ofs_trailer:]
816
817         rep_auth_info = self.parse_auth(rep_auth_info_blob,
818                                         auth_context=auth_context,
819                                         stub_len=len(rep_data))
820         if auth_pad_length is not None:
821             self.assertEquals(rep_auth_info.auth_pad_length, auth_pad_length)
822         self.assertEquals(rep_auth_info.credentials, rep_sig)
823
824         if auth_context["auth_level"] >= dcerpc.DCERPC_AUTH_LEVEL_PRIVACY:
825             # TODO: not yet supported here
826             self.assertTrue(False)
827         elif auth_context["auth_level"] >= dcerpc.DCERPC_AUTH_LEVEL_PACKET:
828             auth_context["gensec"].check_packet(rep_data, rep_whole, rep_sig)
829
830         stub_out = rep_data[0:len(rep_data)-rep_auth_info.auth_pad_length]
831
832         return stub_out
833
834     def generate_pdu(self, ptype, call_id, payload,
835                      rpc_vers=5,
836                      rpc_vers_minor=0,
837                      pfc_flags=(samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST |
838                                 samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST),
839                      drep=[samba.dcerpc.dcerpc.DCERPC_DREP_LE, 0, 0, 0],
840                      ndr_print=None, hexdump=None):
841
842         if getattr(payload, 'auth_info', None):
843             ai = payload.auth_info
844         else:
845             ai = b""
846
847         p = samba.dcerpc.dcerpc.ncacn_packet()
848         p.rpc_vers = rpc_vers
849         p.rpc_vers_minor = rpc_vers_minor
850         p.ptype = ptype
851         p.pfc_flags = pfc_flags
852         p.drep = drep
853         p.frag_length = 0
854         if len(ai) > samba.dcerpc.dcerpc.DCERPC_AUTH_TRAILER_LENGTH:
855             p.auth_length = len(ai) - samba.dcerpc.dcerpc.DCERPC_AUTH_TRAILER_LENGTH
856         else:
857             p.auth_length = 0
858         p.call_id = call_id
859         p.u = payload
860
861         pdu = ndr_pack(p)
862         p.frag_length = len(pdu)
863
864         return p
865
866     def generate_request_auth(self, call_id,
867                               pfc_flags=(dcerpc.DCERPC_PFC_FLAG_FIRST |
868                                          dcerpc.DCERPC_PFC_FLAG_LAST),
869                               alloc_hint=None,
870                               context_id=None,
871                               opnum=None,
872                               object=None,
873                               stub=None,
874                               auth_context=None,
875                               ndr_print=None, hexdump=None):
876
877         if stub is None:
878             stub = b""
879
880         sig_size = 0
881         if auth_context is not None:
882             mod_len = len(stub) % dcerpc.DCERPC_AUTH_PAD_ALIGNMENT
883             auth_pad_length = 0
884             if mod_len > 0:
885                 auth_pad_length = dcerpc.DCERPC_AUTH_PAD_ALIGNMENT - mod_len
886             stub += b'\x00' * auth_pad_length
887
888             if auth_context["g_auth_level"] >= samba.dcerpc.dcerpc.DCERPC_AUTH_LEVEL_PACKET:
889                 sig_size = auth_context["gensec"].sig_size(len(stub))
890             else:
891                 sig_size = 16
892
893             zero_sig = b"\x00" * sig_size
894             auth_info = self.generate_auth(auth_type=auth_context["auth_type"],
895                                            auth_level=auth_context["auth_level"],
896                                            auth_pad_length=auth_pad_length,
897                                            auth_context_id=auth_context["auth_context_id"],
898                                            auth_blob=zero_sig)
899         else:
900             auth_info = b""
901
902         req = self.generate_request(call_id=call_id,
903                                     pfc_flags=pfc_flags,
904                                     alloc_hint=alloc_hint,
905                                     context_id=context_id,
906                                     opnum=opnum,
907                                     object=object,
908                                     stub=stub,
909                                     auth_info=auth_info,
910                                     ndr_print=ndr_print,
911                                     hexdump=hexdump)
912         if auth_context is None:
913             return req
914
915         req_blob = samba.ndr.ndr_pack(req)
916         ofs_stub = dcerpc.DCERPC_REQUEST_LENGTH
917         ofs_sig = len(req_blob) - req.auth_length
918         ofs_trailer = ofs_sig - dcerpc.DCERPC_AUTH_TRAILER_LENGTH
919         req_data = req_blob[ofs_stub:ofs_trailer]
920         req_whole = req_blob[0:ofs_sig]
921
922         if auth_context["auth_level"] >= dcerpc.DCERPC_AUTH_LEVEL_PRIVACY:
923             # TODO: not yet supported here
924             self.assertTrue(False)
925         elif auth_context["auth_level"] >= dcerpc.DCERPC_AUTH_LEVEL_PACKET:
926             req_sig = auth_context["gensec"].sign_packet(req_data, req_whole)
927         elif auth_context["auth_level"] >= dcerpc.DCERPC_AUTH_LEVEL_CONNECT:
928             self.assertEquals(auth_context["auth_type"],
929                               dcerpc.DCERPC_AUTH_TYPE_NTLMSSP)
930             req_sig = b"\x01" +b"\x00" *15
931         else:
932             return req
933         self.assertEquals(len(req_sig), req.auth_length)
934         self.assertEquals(len(req_sig), sig_size)
935
936         stub_sig_ofs = len(req.u.stub_and_verifier) - sig_size
937         stub = req.u.stub_and_verifier[0:stub_sig_ofs] + req_sig
938         req.u.stub_and_verifier = stub
939
940         return req
941
942     def verify_pdu(self, p, ptype, call_id,
943                    rpc_vers=5,
944                    rpc_vers_minor=0,
945                    pfc_flags=(samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST |
946                               samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST),
947                    drep=[samba.dcerpc.dcerpc.DCERPC_DREP_LE, 0, 0, 0],
948                    auth_length=None):
949
950         self.assertIsNotNone(p, "No valid pdu")
951
952         if getattr(p.u, 'auth_info', None):
953             ai = p.u.auth_info
954         else:
955             ai = b""
956
957         self.assertEqual(p.rpc_vers, rpc_vers)
958         self.assertEqual(p.rpc_vers_minor, rpc_vers_minor)
959         self.assertEqual(p.ptype, ptype)
960         self.assertEqual(p.pfc_flags, pfc_flags)
961         self.assertEqual(p.drep, drep)
962         self.assertGreaterEqual(p.frag_length,
963                                 samba.dcerpc.dcerpc.DCERPC_NCACN_PAYLOAD_OFFSET)
964         if len(ai) > samba.dcerpc.dcerpc.DCERPC_AUTH_TRAILER_LENGTH:
965             self.assertEqual(p.auth_length,
966                              len(ai) - samba.dcerpc.dcerpc.DCERPC_AUTH_TRAILER_LENGTH)
967         elif auth_length is not None:
968             self.assertEqual(p.auth_length, auth_length)
969         else:
970             self.assertEqual(p.auth_length, 0)
971         self.assertEqual(p.call_id, call_id)
972
973         return
974
975     def generate_bind(self, call_id,
976                       pfc_flags=(samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST |
977                                  samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST),
978                       max_xmit_frag=None,
979                       max_recv_frag=None,
980                       assoc_group_id=0,
981                       ctx_list=[],
982                       auth_info=b"",
983                       ndr_print=None, hexdump=None):
984
985         if max_xmit_frag is None:
986             max_xmit_frag=self.max_xmit_frag
987         if max_recv_frag is None:
988             max_recv_frag=self.max_recv_frag
989
990         b = samba.dcerpc.dcerpc.bind()
991         b.max_xmit_frag = max_xmit_frag
992         b.max_recv_frag = max_recv_frag
993         b.assoc_group_id = assoc_group_id
994         b.num_contexts = len(ctx_list)
995         b.ctx_list = ctx_list
996         b.auth_info = auth_info
997
998         p = self.generate_pdu(ptype=samba.dcerpc.dcerpc.DCERPC_PKT_BIND,
999                               pfc_flags=pfc_flags,
1000                               call_id=call_id,
1001                               payload=b,
1002                               ndr_print=ndr_print, hexdump=hexdump)
1003
1004         return p
1005
1006     def generate_alter(self, call_id,
1007                        pfc_flags=(samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST |
1008                                   samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST),
1009                        max_xmit_frag=None,
1010                        max_recv_frag=None,
1011                        assoc_group_id=0,
1012                        ctx_list=[],
1013                        auth_info=b"",
1014                        ndr_print=None, hexdump=None):
1015
1016         if max_xmit_frag is None:
1017             max_xmit_frag=self.max_xmit_frag
1018         if max_recv_frag is None:
1019             max_recv_frag=self.max_recv_frag
1020
1021         a = samba.dcerpc.dcerpc.bind()
1022         a.max_xmit_frag = max_xmit_frag
1023         a.max_recv_frag = max_recv_frag
1024         a.assoc_group_id = assoc_group_id
1025         a.num_contexts = len(ctx_list)
1026         a.ctx_list = ctx_list
1027         a.auth_info = auth_info
1028
1029         p = self.generate_pdu(ptype=samba.dcerpc.dcerpc.DCERPC_PKT_ALTER,
1030                               pfc_flags=pfc_flags,
1031                               call_id=call_id,
1032                               payload=a,
1033                               ndr_print=ndr_print, hexdump=hexdump)
1034
1035         return p
1036
1037     def generate_auth3(self, call_id,
1038                        pfc_flags=(samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST |
1039                                   samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST),
1040                        auth_info=b"",
1041                        ndr_print=None, hexdump=None):
1042
1043         a = samba.dcerpc.dcerpc.auth3()
1044         a.auth_info = auth_info
1045
1046         p = self.generate_pdu(ptype=samba.dcerpc.dcerpc.DCERPC_PKT_AUTH3,
1047                               pfc_flags=pfc_flags,
1048                               call_id=call_id,
1049                               payload=a,
1050                               ndr_print=ndr_print, hexdump=hexdump)
1051
1052         return p
1053
1054     def generate_request(self, call_id,
1055                          pfc_flags=(samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST |
1056                                     samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST),
1057                          alloc_hint=None,
1058                          context_id=None,
1059                          opnum=None,
1060                          object=None,
1061                          stub=None,
1062                          auth_info=b"",
1063                          ndr_print=None, hexdump=None):
1064
1065         if alloc_hint is None:
1066             alloc_hint = len(stub)
1067
1068         r = samba.dcerpc.dcerpc.request()
1069         r.alloc_hint = alloc_hint
1070         r.context_id = context_id
1071         r.opnum = opnum
1072         if object is not None:
1073             r.object = object
1074         r.stub_and_verifier = stub + auth_info
1075
1076         p = self.generate_pdu(ptype=samba.dcerpc.dcerpc.DCERPC_PKT_REQUEST,
1077                               pfc_flags=pfc_flags,
1078                               call_id=call_id,
1079                               payload=r,
1080                               ndr_print=ndr_print, hexdump=hexdump)
1081
1082         if len(auth_info) > samba.dcerpc.dcerpc.DCERPC_AUTH_TRAILER_LENGTH:
1083             p.auth_length = len(auth_info) - samba.dcerpc.dcerpc.DCERPC_AUTH_TRAILER_LENGTH
1084
1085         return p
1086
1087     def generate_co_cancel(self, call_id,
1088                            pfc_flags=(samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST |
1089                                       samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST),
1090                            auth_info=b"",
1091                            ndr_print=None, hexdump=None):
1092
1093         c = samba.dcerpc.dcerpc.co_cancel()
1094         c.auth_info = auth_info
1095
1096         p = self.generate_pdu(ptype=samba.dcerpc.dcerpc.DCERPC_PKT_CO_CANCEL,
1097                               pfc_flags=pfc_flags,
1098                               call_id=call_id,
1099                               payload=c,
1100                               ndr_print=ndr_print, hexdump=hexdump)
1101
1102         return p
1103
1104     def generate_orphaned(self, call_id,
1105                           pfc_flags=(samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST |
1106                                      samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST),
1107                           auth_info=b"",
1108                           ndr_print=None, hexdump=None):
1109
1110         o = samba.dcerpc.dcerpc.orphaned()
1111         o.auth_info = auth_info
1112
1113         p = self.generate_pdu(ptype=samba.dcerpc.dcerpc.DCERPC_PKT_ORPHANED,
1114                               pfc_flags=pfc_flags,
1115                               call_id=call_id,
1116                               payload=o,
1117                               ndr_print=ndr_print, hexdump=hexdump)
1118
1119         return p
1120
1121     def generate_shutdown(self, call_id,
1122                           pfc_flags=(samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST |
1123                                      samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST),
1124                           ndr_print=None, hexdump=None):
1125
1126         s = samba.dcerpc.dcerpc.shutdown()
1127
1128         p = self.generate_pdu(ptype=samba.dcerpc.dcerpc.DCERPC_PKT_SHUTDOWN,
1129                               pfc_flags=pfc_flags,
1130                               call_id=call_id,
1131                               payload=s,
1132                               ndr_print=ndr_print, hexdump=hexdump)
1133
1134         return p
1135
1136     def assertIsConnected(self):
1137         self.assertIsNotNone(self.s, msg="Not connected")
1138         return
1139
1140     def assertNotConnected(self):
1141         self.assertIsNone(self.s, msg="Is connected")
1142         return
1143
1144     def assertNDRSyntaxEquals(self, s1, s2):
1145         self.assertEqual(s1.uuid, s2.uuid)
1146         self.assertEqual(s1.if_version, s2.if_version)
1147         return
1148
1149     def assertPadding(self, pad, length):
1150         self.assertEquals(len(pad), length)
1151         #
1152         # sometimes windows sends random bytes
1153         #
1154         # we have IGNORE_RANDOM_PAD=1 to
1155         # disable the check
1156         #
1157         if self.ignore_random_pad:
1158             return
1159         zero_pad = b'\0' * length
1160         self.assertEquals(pad, zero_pad)