PEP8: fix E127: continuation line over-indented for visual indent
[samba.git] / python / samba / tests / dcerpc / raw_protocol.py
index ef660ea32b77a17c58bea83c83c6d904263bbea9..404dde0040ba95f844c84fc6c0fae2b7dcf10259 100755 (executable)
@@ -18,6 +18,7 @@
 
 import sys
 import os
+import time
 
 sys.path.insert(0, "bin/python")
 os.environ["PYTHONUNBUFFERED"] = "1"
@@ -29,9 +30,8 @@ import samba.dcerpc.epmapper
 import samba.dcerpc.mgmt
 import samba.dcerpc.netlogon
 import struct
-from samba.credentials import Credentials
 from samba import gensec
-from samba.tests import RawDCERPCTest
+from samba.tests.dcerpc.raw_testcase import RawDCERPCTest
 
 global_ndr_print = False
 global_hexdump = False
@@ -211,9 +211,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
                                         dcerpc.DCERPC_PFC_FLAG_FIRST |
                                         dcerpc.DCERPC_PFC_FLAG_LAST)
 
-    # TODO: doesn't announce DCERPC_PFC_FLAG_CONC_MPX
-    # by default
-    def _test_no_auth_request_bind_pfc_CONC_MPX(self):
+    def test_no_auth_request_bind_pfc_CONC_MPX(self):
         return self._test_no_auth_request_bind_pfc_flags(
                                         req_pfc_flags=0 |
                                         dcerpc.DCERPC_PFC_FLAG_CONC_MPX |
@@ -1442,7 +1440,75 @@ class TestDCERPC_BIND(RawDCERPCTest):
         self.assertIsNone(rep)
         self.assertNotConnected()
 
-    def _test_auth_none_level_bind(self, auth_level,
+    def test_no_auth_bind_time_keep_on_orphan_simple(self):
+        features = dcerpc.DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN
+        btf = base.bind_time_features_syntax(features)
+
+        zero_syntax = misc.ndr_syntax_id()
+
+        tsf1_list = [btf]
+        ctx1 = dcerpc.ctx_list()
+        ctx1.context_id = 1
+        ctx1.num_transfer_syntaxes = len(tsf1_list)
+        ctx1.abstract_syntax = zero_syntax
+        ctx1.transfer_syntaxes = tsf1_list
+
+        req = self.generate_bind(call_id=0, ctx_list=[ctx1])
+        self.send_pdu(req)
+        rep = self.recv_pdu()
+        self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id,
+                        auth_length=0)
+        self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag)
+        self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag)
+        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
+        self.assertEquals(rep.u.secondary_address_size, 4)
+        self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port)
+        self.assertEquals(len(rep.u._pad1), 2)
+        self.assertEquals(rep.u._pad1, '\0' * 2)
+        self.assertEquals(rep.u.num_results, 1)
+        self.assertEquals(rep.u.ctx_list[0].result,
+                dcerpc.DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK)
+        self.assertEquals(rep.u.ctx_list[0].reason, features)
+        self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, zero_syntax)
+        self.assertEquals(rep.u.auth_info, '\0' * 0)
+
+    def test_no_auth_bind_time_keep_on_orphan_ignore_additional(self):
+        features1 = dcerpc.DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN
+        btf1 = base.bind_time_features_syntax(features1)
+
+        features2 = dcerpc.DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING
+        btf2 = base.bind_time_features_syntax(features2)
+
+        zero_syntax = misc.ndr_syntax_id()
+        ndr64 = base.transfer_syntax_ndr64()
+
+        tsf1_list = [btf1,btf2,zero_syntax]
+        ctx1 = dcerpc.ctx_list()
+        ctx1.context_id = 1
+        ctx1.num_transfer_syntaxes = len(tsf1_list)
+        ctx1.abstract_syntax = ndr64
+        ctx1.transfer_syntaxes = tsf1_list
+
+        req = self.generate_bind(call_id=0, ctx_list=[ctx1])
+        self.send_pdu(req)
+        rep = self.recv_pdu()
+        self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id,
+                        auth_length=0)
+        self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag)
+        self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag)
+        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
+        self.assertEquals(rep.u.secondary_address_size, 4)
+        self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port)
+        self.assertEquals(len(rep.u._pad1), 2)
+        self.assertEquals(rep.u._pad1, '\0' * 2)
+        self.assertEquals(rep.u.num_results, 1)
+        self.assertEquals(rep.u.ctx_list[0].result,
+                dcerpc.DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK)
+        self.assertEquals(rep.u.ctx_list[0].reason, features1)
+        self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, zero_syntax)
+        self.assertEquals(rep.u.auth_info, '\0' * 0)
+
+    def _test_auth_type_level_bind_nak(self, auth_type, auth_level, creds=None,
                                    reason=dcerpc.DCERPC_BIND_NAK_REASON_INVALID_AUTH_TYPE):
         ndr32 = base.transfer_syntax_ndr()
 
@@ -1454,13 +1520,29 @@ class TestDCERPC_BIND(RawDCERPCTest):
         ctx1.transfer_syntaxes = tsf1_list
         ctx_list = [ctx1]
 
-        auth_type = dcerpc.DCERPC_AUTH_TYPE_NONE
         auth_context_id = 0
 
-        auth_info = self.generate_auth(auth_type=auth_type,
-                                       auth_level=auth_level,
-                                       auth_context_id=auth_context_id,
-                                       auth_blob="none")
+        if creds is not None:
+            # We always start with DCERPC_AUTH_LEVEL_INTEGRITY
+            auth_context = self.get_auth_context_creds(creds,
+                                auth_type=auth_type,
+                                auth_level=auth_level,
+                                auth_context_id=auth_context_id,
+                                g_auth_level=dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY)
+            from_server = ""
+            (finished, to_server) = auth_context["gensec"].update(from_server)
+            self.assertFalse(finished)
+
+            auth_info = self.generate_auth(auth_type=auth_context["auth_type"],
+                                           auth_level=auth_context["auth_level"],
+                                           auth_context_id=auth_context["auth_context_id"],
+                                           auth_blob=to_server)
+        else:
+            to_server = "none"
+            auth_info = self.generate_auth(auth_type=auth_type,
+                                           auth_level=auth_level,
+                                           auth_context_id=auth_context_id,
+                                           auth_blob=to_server)
 
         req = self.generate_bind(call_id=0,
                                  ctx_list=ctx_list,
@@ -1481,6 +1563,11 @@ class TestDCERPC_BIND(RawDCERPCTest):
         self.assertIsNone(rep)
         self.assertNotConnected()
 
+    def _test_auth_none_level_bind(self, auth_level,
+                                   reason=dcerpc.DCERPC_BIND_NAK_REASON_INVALID_AUTH_TYPE):
+        return self._test_auth_type_level_bind_nak(auth_type=dcerpc.DCERPC_AUTH_LEVEL_NONE,
+                                               auth_level=auth_level, reason=reason)
+
     def test_auth_none_none_bind(self):
         return self._test_auth_none_level_bind(dcerpc.DCERPC_AUTH_LEVEL_NONE,
                             reason=dcerpc.DCERPC_BIND_NAK_REASON_NOT_SPECIFIED)
@@ -1839,46 +1926,12 @@ class TestDCERPC_BIND(RawDCERPCTest):
 
     def _get_netlogon_ctx(self):
         abstract = samba.dcerpc.netlogon.abstract_syntax()
-        self.epmap_reconnect(abstract)
-
         ndr32 = base.transfer_syntax_ndr()
 
-        tsf1_list = [ndr32]
-        ctx = dcerpc.ctx_list()
-        ctx.context_id = 0
-        ctx.num_transfer_syntaxes = len(tsf1_list)
-        ctx.abstract_syntax = abstract
-        ctx.transfer_syntaxes = tsf1_list
-
-        req = self.generate_bind(call_id=0,
-                                 ctx_list=[ctx])
-        self.send_pdu(req)
-        rep = self.recv_pdu()
-        self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id,
-                        auth_length=0)
-        self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-        self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag)
-        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-        port_str = "%d" % self.tcp_port
-        port_len = len(port_str) + 1
-        mod_len = (2 + port_len) % 4
-        if mod_len != 0:
-            port_pad = 4 - mod_len
-        else:
-            port_pad = 0
-        self.assertEquals(rep.u.secondary_address_size, port_len)
-        self.assertEquals(rep.u.secondary_address, port_str)
-        self.assertEquals(len(rep.u._pad1), port_pad)
-        self.assertEquals(rep.u._pad1, '\0' * port_pad)
-        self.assertEquals(rep.u.num_results, 1)
-        self.assertEquals(rep.u.ctx_list[0].result,
-                dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE)
-        self.assertEquals(rep.u.ctx_list[0].reason,
-                dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
-        self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
-        self.assertEquals(rep.u.auth_info, '\0' * 0)
+        (ctx, ack) = self.prepare_presentation(abstract, ndr32, context_id=0,
+                                               epmap=True, return_ack=True)
 
-        server = '\\\\' + self.host
+        server = '\\\\' + self.target_hostname
         server_utf16 = unicode(server, 'utf-8').encode('utf-16-le')
         computer = 'UNKNOWNCOMPUTER'
         computer_utf16 = unicode(computer, 'utf-8').encode('utf-16-le')
@@ -1894,7 +1947,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
         real_stub += computer_utf16 + '\x00\x00'
         real_stub += '\x11\x22\x33\x44\x55\x66\x77\x88'
 
-        return (ctx, rep, real_stub)
+        return (ctx, ack, real_stub)
 
     def _test_fragmented_requests(self, remaining=None, alloc_hint=None,
                                   fault_first=None, fault_last=None):
@@ -1922,7 +1975,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
 
             # And now try a request without auth_info
             # netr_ServerReqChallenge()
-            req = self.generate_request(call_id = 2,
+            req = self.generate_request(call_id = 0x21234,
                                         pfc_flags=pfc_flags,
                                         context_id=ctx.context_id,
                                         opnum=4,
@@ -2043,7 +2096,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
             self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id,
                             auth_length=0)
             self.assertNotEquals(rep.u.alloc_hint, 0)
-            self.assertEquals(rep.u.context_id, req.u.context_id)
+            self.assertEquals(rep.u.context_id, 0)
             self.assertEquals(rep.u.cancel_count, 0)
             self.assertEquals(rep.u.flags, 0)
             self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR)
@@ -2127,7 +2180,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
         # netr_ServerReqChallenge with given flags
         req = self.generate_request(call_id = 2,
                                     pfc_flags=dcerpc.DCERPC_PFC_FLAG_FIRST |
-                                              dcerpc.DCERPC_PFC_FLAG_PENDING_CANCEL,
+                                    dcerpc.DCERPC_PFC_FLAG_PENDING_CANCEL,
                                     context_id=ctx.context_id,
                                     opnum=4,
                                     stub=real_stub)
@@ -2140,7 +2193,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
                         dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
                         auth_length=0)
         self.assertNotEquals(rep.u.alloc_hint, 0)
-        self.assertEquals(rep.u.context_id, req.u.context_id)
+        self.assertEquals(rep.u.context_id, 0)
         self.assertEquals(rep.u.cancel_count, 0)
         self.assertEquals(rep.u.flags, 0)
         self.assertEquals(rep.u.status, dcerpc.DCERPC_FAULT_NO_CALL_ACTIVE)
@@ -2265,98 +2318,55 @@ class TestDCERPC_BIND(RawDCERPCTest):
         self.assertEquals(rep.u.reserved, 0)
         self.assertEquals(len(rep.u.error_and_verifier), 0)
 
-    def test_spnego_connect_request(self):
+    def test_co_cancel_no_request(self):
         ndr32 = base.transfer_syntax_ndr()
+        abstract = samba.dcerpc.mgmt.abstract_syntax()
+        ctx = self.prepare_presentation(abstract, ndr32, context_id=0xff)
 
-        tsf1_list = [ndr32]
-        ctx1 = dcerpc.ctx_list()
-        ctx1.context_id = 1
-        ctx1.num_transfer_syntaxes = len(tsf1_list)
-        ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
-        ctx1.transfer_syntaxes = tsf1_list
-        ctx_list = [ctx1]
-
-        c = Credentials()
-        c.set_anonymous()
-        g = gensec.Security.start_client(self.settings)
-        g.set_credentials(c)
-        g.want_feature(gensec.FEATURE_DCE_STYLE)
-        auth_type = dcerpc.DCERPC_AUTH_TYPE_SPNEGO
-        auth_level = dcerpc.DCERPC_AUTH_LEVEL_CONNECT
-        auth_context_id = 2
-        g.start_mech_by_authtype(auth_type, auth_level)
-        from_server = ""
-        (finished, to_server) = g.update(from_server)
-        self.assertFalse(finished)
-
-        auth_info = self.generate_auth(auth_type=auth_type,
-                                       auth_level=auth_level,
-                                       auth_context_id=auth_context_id,
-                                       auth_blob=to_server)
-
-        req = self.generate_bind(call_id=0,
-                                 ctx_list=ctx_list,
-                                 auth_info=auth_info)
+        req = self.generate_co_cancel(call_id = 3)
+        self.send_pdu(req)
+        rep = self.recv_pdu(timeout=0.01)
+        self.assertIsNone(rep)
+        self.assertIsConnected()
 
+        # And now try a request
+        req = self.generate_request(call_id = 1,
+                                    context_id=ctx.context_id,
+                                    opnum=0,
+                                    stub="")
         self.send_pdu(req)
         rep = self.recv_pdu()
-        self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id)
-        self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-        self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag)
-        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-        self.assertEquals(rep.u.secondary_address_size, 4)
-        self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port)
-        self.assertEquals(len(rep.u._pad1), 2)
-        self.assertEquals(rep.u._pad1, '\0' * 2)
-        self.assertEquals(rep.u.num_results, 1)
-        self.assertEquals(rep.u.ctx_list[0].result,
-                dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE)
-        self.assertEquals(rep.u.ctx_list[0].reason,
-                dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
-        self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
-        self.assertNotEquals(len(rep.u.auth_info), 0)
-        a = self.parse_auth(rep.u.auth_info)
-
-        from_server = a.credentials
-        (finished, to_server) = g.update(from_server)
-        self.assertFalse(finished)
-
-        auth_info = self.generate_auth(auth_type=auth_type,
-                                       auth_level=auth_level,
-                                       auth_context_id=auth_context_id,
-                                       auth_blob=to_server)
+        self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
+                        auth_length=0)
+        self.assertNotEquals(rep.u.alloc_hint, 0)
+        self.assertEquals(rep.u.context_id, req.u.context_id)
+        self.assertEquals(rep.u.cancel_count, 0)
+        self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
 
-        req = self.generate_alter(call_id=0,
-                                  ctx_list=ctx_list,
-                                  assoc_group_id=rep.u.assoc_group_id,
-                                  auth_info=auth_info)
+    def test_co_cancel_request_after_first(self):
+        ndr32 = base.transfer_syntax_ndr()
+        abstract = samba.dcerpc.mgmt.abstract_syntax()
+        ctx = self.prepare_presentation(abstract, ndr32, context_id=0xff)
 
+        req = self.generate_request(call_id = 1,
+                                    pfc_flags=dcerpc.DCERPC_PFC_FLAG_FIRST,
+                                    context_id=ctx.context_id,
+                                    opnum=0,
+                                    stub="")
         self.send_pdu(req)
-        rep = self.recv_pdu()
-        self.verify_pdu(rep, dcerpc.DCERPC_PKT_ALTER_RESP, req.call_id)
-        self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-        self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag)
-        self.assertEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-        self.assertEquals(rep.u.secondary_address_size, 0)
-        self.assertEquals(len(rep.u._pad1), 2)
-        # Windows sends garbage
-        #self.assertEquals(rep.u._pad1, '\0' * 2)
-        self.assertEquals(rep.u.num_results, 1)
-        self.assertEquals(rep.u.ctx_list[0].result,
-                dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE)
-        self.assertEquals(rep.u.ctx_list[0].reason,
-                dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
-        self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
-        self.assertNotEquals(len(rep.u.auth_info), 0)
-        a = self.parse_auth(rep.u.auth_info)
+        rep = self.recv_pdu(timeout=0.01)
+        self.assertIsNone(rep)
+        self.assertIsConnected()
 
-        from_server = a.credentials
-        (finished, to_server) = g.update(from_server)
-        self.assertTrue(finished)
+        req = self.generate_co_cancel(call_id = 1)
+        self.send_pdu(req)
+        rep = self.recv_pdu(timeout=0.01)
+        self.assertIsNone(rep)
+        self.assertIsConnected()
 
-        # And now try a request without auth_info
-        req = self.generate_request(call_id = 2,
-                                    context_id=ctx1.context_id,
+        req = self.generate_request(call_id = 1,
+                                    pfc_flags=dcerpc.DCERPC_PFC_FLAG_LAST,
+                                    context_id=ctx.context_id,
                                     opnum=0,
                                     stub="")
         self.send_pdu(req)
@@ -2368,19 +2378,13 @@ class TestDCERPC_BIND(RawDCERPCTest):
         self.assertEquals(rep.u.cancel_count, 0)
         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
 
-        # Now a request with auth_info DCERPC_AUTH_LEVEL_CONNECT
-        auth_info = self.generate_auth(auth_type=auth_type,
-                                       auth_level=auth_level,
-                                       auth_context_id=auth_context_id,
-                                       auth_blob="\x01"+"\x00"*15)
-        req = self.generate_request(call_id = 3,
-                                    context_id=ctx1.context_id,
+        # And now try a request
+        req = self.generate_request(call_id = 2,
+                                    context_id=ctx.context_id,
                                     opnum=0,
-                                    stub="",
-                                    auth_info=auth_info)
+                                    stub="")
         self.send_pdu(req)
         rep = self.recv_pdu()
-        # We don't get an auth_info back
         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
                         auth_length=0)
         self.assertNotEquals(rep.u.alloc_hint, 0)
@@ -2388,28 +2392,368 @@ class TestDCERPC_BIND(RawDCERPCTest):
         self.assertEquals(rep.u.cancel_count, 0)
         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
 
-        # Now a request with auth_info DCERPC_AUTH_LEVEL_INTEGRITY
-        auth_info = self.generate_auth(auth_type=auth_type,
-                                       auth_level=dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY,
-                                       auth_context_id=auth_context_id,
-                                       auth_blob="\x01"+"\x00"*15)
-        req = self.generate_request(call_id = 4,
-                                    context_id=ctx1.context_id,
+    def test_orphaned_no_request(self):
+        ndr32 = base.transfer_syntax_ndr()
+        abstract = samba.dcerpc.mgmt.abstract_syntax()
+        ctx = self.prepare_presentation(abstract, ndr32)
+
+        req = self.generate_orphaned(call_id = 3)
+        self.send_pdu(req)
+        rep = self.recv_pdu(timeout=0.01)
+        self.assertIsNone(rep)
+        self.assertIsConnected()
+
+        # And now try a request
+        req = self.generate_request(call_id = 1,
+                                    context_id=ctx.context_id,
                                     opnum=0,
-                                    stub="",
-                                    auth_info=auth_info)
+                                    stub="")
         self.send_pdu(req)
         rep = self.recv_pdu()
-        # We get a fault back
-        self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id,
+        self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
                         auth_length=0)
         self.assertNotEquals(rep.u.alloc_hint, 0)
-        self.assertEquals(rep.u.context_id, req.u.context_id)
+        self.assertEquals(rep.u.context_id, req.u.context_id & 0xff)
         self.assertEquals(rep.u.cancel_count, 0)
-        self.assertEquals(rep.u.flags, 0)
-        self.assertEquals(rep.u.status, dcerpc.DCERPC_FAULT_ACCESS_DENIED)
-        self.assertEquals(rep.u.reserved, 0)
-        self.assertEquals(len(rep.u.error_and_verifier), 0)
+        self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
+
+    def test_orphaned_request_after_first_last(self):
+        ndr32 = base.transfer_syntax_ndr()
+        abstract = samba.dcerpc.mgmt.abstract_syntax()
+        ctx = self.prepare_presentation(abstract, ndr32)
+
+        req = self.generate_request(call_id = 1,
+                                    pfc_flags=dcerpc.DCERPC_PFC_FLAG_FIRST,
+                                    context_id=ctx.context_id,
+                                    opnum=0,
+                                    stub="")
+        self.send_pdu(req)
+        rep = self.recv_pdu(timeout=0.1)
+        self.assertIsNone(rep)
+        self.assertIsConnected()
+
+        req = self.generate_orphaned(call_id = 1)
+        self.send_pdu(req)
+        rep = self.recv_pdu(timeout=0.1)
+        self.assertIsNone(rep)
+        self.assertIsConnected()
+
+        req = self.generate_request(call_id = 1,
+                                    pfc_flags=dcerpc.DCERPC_PFC_FLAG_LAST,
+                                    context_id=ctx.context_id,
+                                    opnum=0,
+                                    stub="")
+        self.send_pdu(req)
+        rep = self.recv_pdu()
+        self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
+                        auth_length=0)
+        self.assertNotEquals(rep.u.alloc_hint, 0)
+        self.assertEquals(rep.u.context_id, req.u.context_id & 0xff)
+        self.assertEquals(rep.u.cancel_count, 0)
+        self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
+
+        # And now try a request
+        req = self.generate_request(call_id = 2,
+                                    context_id=ctx.context_id,
+                                    opnum=0,
+                                    stub="")
+        self.send_pdu(req)
+        rep = self.recv_pdu()
+        self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
+                        auth_length=0)
+        self.assertNotEquals(rep.u.alloc_hint, 0)
+        self.assertEquals(rep.u.context_id, req.u.context_id & 0xff)
+        self.assertEquals(rep.u.cancel_count, 0)
+        self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
+
+    def test_orphaned_request_after_first_mpx_last(self):
+        ndr32 = base.transfer_syntax_ndr()
+        abstract = samba.dcerpc.mgmt.abstract_syntax()
+
+        pfc_flags = samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST
+        pfc_flags |= samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST
+        pfc_flags |= samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_CONC_MPX
+        ctx = self.prepare_presentation(abstract, ndr32, pfc_flags=pfc_flags)
+
+        req = self.generate_request(call_id = 1,
+                                    pfc_flags=dcerpc.DCERPC_PFC_FLAG_FIRST,
+                                    context_id=ctx.context_id,
+                                    opnum=0,
+                                    stub="")
+        self.send_pdu(req)
+        rep = self.recv_pdu(timeout=0.1)
+        self.assertIsNone(rep)
+        self.assertIsConnected()
+
+        req = self.generate_orphaned(call_id = 1)
+        self.send_pdu(req)
+        rep = self.recv_pdu(timeout=0.1)
+        self.assertIsNone(rep)
+        self.assertIsConnected()
+
+        req = self.generate_request(call_id = 1,
+                                    pfc_flags=dcerpc.DCERPC_PFC_FLAG_LAST,
+                                    context_id=ctx.context_id,
+                                    opnum=0,
+                                    stub="")
+        self.send_pdu(req)
+        rep = self.recv_pdu()
+        self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
+                        auth_length=0)
+        self.assertNotEquals(rep.u.alloc_hint, 0)
+        self.assertEquals(rep.u.context_id, req.u.context_id & 0xff)
+        self.assertEquals(rep.u.cancel_count, 0)
+        self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
+
+        # And now try a request
+        req = self.generate_request(call_id = 2,
+                                    context_id=ctx.context_id,
+                                    opnum=0,
+                                    stub="")
+        self.send_pdu(req)
+        rep = self.recv_pdu()
+        self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
+                        auth_length=0)
+        self.assertNotEquals(rep.u.alloc_hint, 0)
+        self.assertEquals(rep.u.context_id, req.u.context_id & 0xff)
+        self.assertEquals(rep.u.cancel_count, 0)
+        self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
+
+    def test_orphaned_request_after_first_no_last(self):
+        ndr32 = base.transfer_syntax_ndr()
+        abstract = samba.dcerpc.mgmt.abstract_syntax()
+        ctx = self.prepare_presentation(abstract, ndr32)
+
+        req1 = self.generate_request(call_id = 1,
+                                    pfc_flags=dcerpc.DCERPC_PFC_FLAG_FIRST,
+                                    context_id=ctx.context_id,
+                                    opnum=0,
+                                    stub="")
+        self.send_pdu(req1)
+        rep = self.recv_pdu(timeout=0.1)
+        self.assertIsNone(rep)
+        self.assertIsConnected()
+
+        req = self.generate_orphaned(call_id = 1)
+        self.send_pdu(req)
+        rep = self.recv_pdu(timeout=0.1)
+        self.assertIsNone(rep)
+        self.assertIsConnected()
+
+        # And now try a new request
+        req2 = self.generate_request(call_id = 2,
+                                    context_id=ctx.context_id,
+                                    opnum=0,
+                                    stub="")
+        self.send_pdu(req2)
+        rep = self.recv_pdu()
+        self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req1.call_id,
+                        auth_length=0)
+        self.assertNotEquals(rep.u.alloc_hint, 0)
+        self.assertEquals(rep.u.context_id, req1.u.context_id)
+        self.assertEquals(rep.u.cancel_count, 0)
+        self.assertEquals(rep.u.flags, 0)
+        self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR)
+        self.assertEquals(rep.u.reserved, 0)
+        self.assertEquals(len(rep.u.error_and_verifier), 0)
+
+        # wait for a disconnect
+        rep = self.recv_pdu()
+        self.assertIsNone(rep)
+        self.assertNotConnected()
+
+    def test_orphaned_request_after_first_mpx_no_last(self):
+        ndr32 = base.transfer_syntax_ndr()
+        abstract = samba.dcerpc.mgmt.abstract_syntax()
+
+        pfc_flags = samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST
+        pfc_flags |= samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST
+        pfc_flags |= samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_CONC_MPX
+        ctx = self.prepare_presentation(abstract, ndr32,
+                                        pfc_flags=pfc_flags)
+
+        req1 = self.generate_request(call_id = 1,
+                                    pfc_flags=dcerpc.DCERPC_PFC_FLAG_FIRST,
+                                    context_id=ctx.context_id,
+                                    opnum=0,
+                                    stub="")
+        self.send_pdu(req1)
+        rep = self.recv_pdu(timeout=0.1)
+        self.assertIsNone(rep)
+        self.assertIsConnected()
+
+        req = self.generate_orphaned(call_id = 1)
+        self.send_pdu(req)
+        rep = self.recv_pdu(timeout=0.1)
+        self.assertIsNone(rep)
+        self.assertIsConnected()
+
+        # And now try a new request
+        req2 = self.generate_request(call_id = 2,
+                                    context_id=ctx.context_id-1,
+                                    opnum=0,
+                                    stub="")
+        self.send_pdu(req2)
+        rep = self.recv_pdu()
+        self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req2.call_id,
+                        auth_length=0)
+        self.assertNotEquals(rep.u.alloc_hint, 0)
+        self.assertEquals(rep.u.context_id, 0)
+        self.assertEquals(rep.u.cancel_count, 0)
+        self.assertEquals(rep.u.flags, 0)
+        self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR)
+        self.assertEquals(rep.u.reserved, 0)
+        self.assertEquals(len(rep.u.error_and_verifier), 0)
+
+        # wait for a disconnect
+        rep = self.recv_pdu()
+        self.assertIsNone(rep)
+        self.assertNotConnected()
+
+    def test_spnego_connect_request(self):
+        ndr32 = base.transfer_syntax_ndr()
+
+        tsf1_list = [ndr32]
+        ctx1 = dcerpc.ctx_list()
+        ctx1.context_id = 1
+        ctx1.num_transfer_syntaxes = len(tsf1_list)
+        ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
+        ctx1.transfer_syntaxes = tsf1_list
+        ctx_list = [ctx1]
+
+        c = self.get_anon_creds()
+        g = gensec.Security.start_client(self.settings)
+        g.set_credentials(c)
+        g.want_feature(gensec.FEATURE_DCE_STYLE)
+        auth_type = dcerpc.DCERPC_AUTH_TYPE_SPNEGO
+        auth_level = dcerpc.DCERPC_AUTH_LEVEL_CONNECT
+        auth_context_id = 2
+        g.start_mech_by_authtype(auth_type, auth_level)
+        from_server = ""
+        (finished, to_server) = g.update(from_server)
+        self.assertFalse(finished)
+
+        auth_info = self.generate_auth(auth_type=auth_type,
+                                       auth_level=auth_level,
+                                       auth_context_id=auth_context_id,
+                                       auth_blob=to_server)
+
+        req = self.generate_bind(call_id=0,
+                                 ctx_list=ctx_list,
+                                 auth_info=auth_info)
+
+        self.send_pdu(req)
+        rep = self.recv_pdu()
+        self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id)
+        self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag)
+        self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag)
+        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
+        self.assertEquals(rep.u.secondary_address_size, 4)
+        self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port)
+        self.assertEquals(len(rep.u._pad1), 2)
+        self.assertEquals(rep.u._pad1, '\0' * 2)
+        self.assertEquals(rep.u.num_results, 1)
+        self.assertEquals(rep.u.ctx_list[0].result,
+                dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE)
+        self.assertEquals(rep.u.ctx_list[0].reason,
+                dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
+        self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
+        self.assertNotEquals(len(rep.u.auth_info), 0)
+        a = self.parse_auth(rep.u.auth_info)
+
+        from_server = a.credentials
+        (finished, to_server) = g.update(from_server)
+        self.assertFalse(finished)
+
+        auth_info = self.generate_auth(auth_type=auth_type,
+                                       auth_level=auth_level,
+                                       auth_context_id=auth_context_id,
+                                       auth_blob=to_server)
+
+        req = self.generate_alter(call_id=0,
+                                  ctx_list=ctx_list,
+                                  assoc_group_id=rep.u.assoc_group_id,
+                                  auth_info=auth_info)
+
+        self.send_pdu(req)
+        rep = self.recv_pdu()
+        self.verify_pdu(rep, dcerpc.DCERPC_PKT_ALTER_RESP, req.call_id)
+        self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag)
+        self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag)
+        self.assertEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
+        self.assertEquals(rep.u.secondary_address_size, 0)
+        self.assertEquals(len(rep.u._pad1), 2)
+        # Windows sends garbage
+        #self.assertEquals(rep.u._pad1, '\0' * 2)
+        self.assertEquals(rep.u.num_results, 1)
+        self.assertEquals(rep.u.ctx_list[0].result,
+                dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE)
+        self.assertEquals(rep.u.ctx_list[0].reason,
+                dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
+        self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
+        self.assertNotEquals(len(rep.u.auth_info), 0)
+        a = self.parse_auth(rep.u.auth_info)
+
+        from_server = a.credentials
+        (finished, to_server) = g.update(from_server)
+        self.assertTrue(finished)
+
+        # And now try a request without auth_info
+        req = self.generate_request(call_id = 2,
+                                    context_id=ctx1.context_id,
+                                    opnum=0,
+                                    stub="")
+        self.send_pdu(req)
+        rep = self.recv_pdu()
+        self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
+                        auth_length=0)
+        self.assertNotEquals(rep.u.alloc_hint, 0)
+        self.assertEquals(rep.u.context_id, req.u.context_id & 0xff)
+        self.assertEquals(rep.u.cancel_count, 0)
+        self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
+
+        # Now a request with auth_info DCERPC_AUTH_LEVEL_CONNECT
+        auth_info = self.generate_auth(auth_type=auth_type,
+                                       auth_level=auth_level,
+                                       auth_context_id=auth_context_id,
+                                       auth_blob="\x01"+"\x00"*15)
+        req = self.generate_request(call_id = 3,
+                                    context_id=ctx1.context_id,
+                                    opnum=0,
+                                    stub="",
+                                    auth_info=auth_info)
+        self.send_pdu(req)
+        rep = self.recv_pdu()
+        # We don't get an auth_info back
+        self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
+                        auth_length=0)
+        self.assertNotEquals(rep.u.alloc_hint, 0)
+        self.assertEquals(rep.u.context_id, req.u.context_id & 0xff)
+        self.assertEquals(rep.u.cancel_count, 0)
+        self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
+
+        # Now a request with auth_info DCERPC_AUTH_LEVEL_INTEGRITY
+        auth_info = self.generate_auth(auth_type=auth_type,
+                                       auth_level=dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY,
+                                       auth_context_id=auth_context_id,
+                                       auth_blob="\x01"+"\x00"*15)
+        req = self.generate_request(call_id = 4,
+                                    context_id=ctx1.context_id,
+                                    opnum=0,
+                                    stub="",
+                                    auth_info=auth_info)
+        self.send_pdu(req)
+        rep = self.recv_pdu()
+        # We get a fault back
+        self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id,
+                        auth_length=0)
+        self.assertNotEquals(rep.u.alloc_hint, 0)
+        self.assertEquals(rep.u.context_id, req.u.context_id)
+        self.assertEquals(rep.u.cancel_count, 0)
+        self.assertEquals(rep.u.flags, 0)
+        self.assertEquals(rep.u.status, dcerpc.DCERPC_FAULT_ACCESS_DENIED)
+        self.assertEquals(rep.u.reserved, 0)
+        self.assertEquals(len(rep.u.error_and_verifier), 0)
 
         # wait for a disconnect
         rep = self.recv_pdu()
@@ -2427,8 +2771,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
         ctx1.transfer_syntaxes = tsf1_list
         ctx_list = [ctx1]
 
-        c = Credentials()
-        c.set_anonymous()
+        c = self.get_anon_creds()
         g = gensec.Security.start_client(self.settings)
         g.set_credentials(c)
         g.want_feature(gensec.FEATURE_DCE_STYLE)
@@ -2544,8 +2887,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
         ctx1.transfer_syntaxes = tsf1_list
         ctx_list = [ctx1]
 
-        c = Credentials()
-        c.set_anonymous()
+        c = self.get_anon_creds()
         g = gensec.Security.start_client(self.settings)
         g.set_credentials(c)
         g.want_feature(gensec.FEATURE_DCE_STYLE)
@@ -2631,8 +2973,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
         ctx1.transfer_syntaxes = tsf1_list
         ctx_list = [ctx1]
 
-        c = Credentials()
-        c.set_anonymous()
+        c = self.get_anon_creds()
         g = gensec.Security.start_client(self.settings)
         g.set_credentials(c)
         g.want_feature(gensec.FEATURE_DCE_STYLE)
@@ -2720,8 +3061,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
         ctx1.transfer_syntaxes = tsf1_list
         ctx_list = [ctx1]
 
-        c = Credentials()
-        c.set_anonymous()
+        c = self.get_anon_creds()
         g = gensec.Security.start_client(self.settings)
         g.set_credentials(c)
         g.want_feature(gensec.FEATURE_DCE_STYLE)
@@ -2806,7 +3146,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
                         auth_length=0)
         self.assertNotEquals(rep.u.alloc_hint, 0)
-        self.assertEquals(rep.u.context_id, req.u.context_id)
+        self.assertEquals(rep.u.context_id, req.u.context_id & 0xff)
         self.assertEquals(rep.u.cancel_count, 0)
         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
 
@@ -2882,8 +3222,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
         ctx1.transfer_syntaxes = tsf1_list
         ctx_list = [ctx1]
 
-        c = Credentials()
-        c.set_anonymous()
+        c = self.get_anon_creds()
         g = gensec.Security.start_client(self.settings)
         g.set_credentials(c)
         g.want_feature(gensec.FEATURE_DCE_STYLE)
@@ -3041,8 +3380,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
         ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
         ctx1.transfer_syntaxes = tsf1_list
 
-        c = Credentials()
-        c.set_anonymous()
+        c = self.get_anon_creds()
         g = gensec.Security.start_client(self.settings)
         g.set_credentials(c)
         g.want_feature(gensec.FEATURE_DCE_STYLE)
@@ -3127,8 +3465,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
         ctx1b.abstract_syntax = samba.dcerpc.epmapper.abstract_syntax()
         ctx1b.transfer_syntaxes = tsf1_list
 
-        c = Credentials()
-        c.set_anonymous()
+        c = self.get_anon_creds()
         g = gensec.Security.start_client(self.settings)
         g.set_credentials(c)
         g.want_feature(gensec.FEATURE_DCE_STYLE)
@@ -3215,8 +3552,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
         ctx1b.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
         ctx1b.transfer_syntaxes = tsf1b_list
 
-        c = Credentials()
-        c.set_anonymous()
+        c = self.get_anon_creds()
         g = gensec.Security.start_client(self.settings)
         g.set_credentials(c)
         g.want_feature(gensec.FEATURE_DCE_STYLE)
@@ -3297,8 +3633,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
         ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
         ctx1.transfer_syntaxes = tsf1_list
 
-        c = Credentials()
-        c.set_anonymous()
+        c = self.get_anon_creds()
         g = gensec.Security.start_client(self.settings)
         g.set_credentials(c)
         g.want_feature(gensec.FEATURE_DCE_STYLE)
@@ -3386,8 +3721,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
         ctx1b.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
         ctx1b.transfer_syntaxes = tsf1b_list
 
-        c = Credentials()
-        c.set_anonymous()
+        c = self.get_anon_creds()
         g = gensec.Security.start_client(self.settings)
         g.set_credentials(c)
         g.want_feature(gensec.FEATURE_DCE_STYLE)
@@ -3475,8 +3809,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
         ctx1b.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
         ctx1b.transfer_syntaxes = tsf1b_list
 
-        c = Credentials()
-        c.set_anonymous()
+        c = self.get_anon_creds()
         g = gensec.Security.start_client(self.settings)
         g.set_credentials(c)
         g.want_feature(gensec.FEATURE_DCE_STYLE)
@@ -3557,8 +3890,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
         ctx1.transfer_syntaxes = tsf1_list
         ctx_list = [ctx1]
 
-        c = Credentials()
-        c.set_anonymous()
+        c = self.get_anon_creds()
         g = gensec.Security.start_client(self.settings)
         g.set_credentials(c)
         g.want_feature(gensec.FEATURE_DCE_STYLE)
@@ -3711,8 +4043,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
         ctx1.transfer_syntaxes = tsf1_list
         ctx_list = [ctx1]
 
-        c = Credentials()
-        c.set_anonymous()
+        c = self.get_anon_creds()
         g = gensec.Security.start_client(self.settings)
         g.set_credentials(c)
         g.want_feature(gensec.FEATURE_DCE_STYLE)
@@ -3776,8 +4107,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
         ctx1.transfer_syntaxes = tsf1_list
         ctx_list = [ctx1]
 
-        c = Credentials()
-        c.set_anonymous()
+        c = self.get_anon_creds()
         g = gensec.Security.start_client(self.settings)
         g.set_credentials(c)
         g.want_feature(gensec.FEATURE_DCE_STYLE)
@@ -3890,8 +4220,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
         ctx1.transfer_syntaxes = tsf1_list
         ctx_list = [ctx1]
 
-        c = Credentials()
-        c.set_anonymous()
+        c = self.get_anon_creds()
         g = gensec.Security.start_client(self.settings)
         g.set_credentials(c)
         g.want_feature(gensec.FEATURE_DCE_STYLE)
@@ -4009,8 +4338,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
         ctx1.transfer_syntaxes = tsf1_list
         ctx_list = [ctx1]
 
-        c = Credentials()
-        c.set_anonymous()
+        c = self.get_anon_creds()
         g = gensec.Security.start_client(self.settings)
         g.set_credentials(c)
         g.want_feature(gensec.FEATURE_DCE_STYLE)
@@ -4096,6 +4424,562 @@ class TestDCERPC_BIND(RawDCERPCTest):
         self.assertIsNone(rep)
         self.assertNotConnected()
 
+    def _test_spnego_bind_auth_level(self, auth_level, auth_context_id, ctx,
+                                     g_auth_level=dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY,
+                                     alter_fault=None):
+        creds = self.get_user_creds()
+        auth_context = self.get_auth_context_creds(creds=creds,
+                                                   auth_type=dcerpc.DCERPC_AUTH_TYPE_SPNEGO,
+                                                   auth_level=auth_level,
+                                                   auth_context_id=auth_context_id,
+                                                   g_auth_level=g_auth_level)
+        if auth_context is None:
+            return None
+        ack = self.do_generic_bind(ctx=ctx,
+                                   auth_context=auth_context,
+                                   alter_fault=alter_fault)
+        if ack is None:
+            return None
+        return auth_context["gensec"]
+
+    def _test_spnego_level_bind_nak(self, auth_level,
+                                   reason=dcerpc.DCERPC_BIND_NAK_REASON_INVALID_CHECKSUM):
+        c = self.get_user_creds()
+        return self._test_auth_type_level_bind_nak(auth_type=dcerpc.DCERPC_AUTH_TYPE_SPNEGO,
+                                                   auth_level=auth_level, creds=c, reason=reason)
+
+    def _test_spnego_level_bind(self, auth_level,
+                                g_auth_level=dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY,
+                                alter_fault=None,
+                                request_fault=None,
+                                response_fault_flags=0):
+        ndr32 = base.transfer_syntax_ndr()
+
+        tsf1_list = [ndr32]
+        ctx1 = dcerpc.ctx_list()
+        ctx1.context_id = 0x1001
+        ctx1.num_transfer_syntaxes = len(tsf1_list)
+        ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
+        ctx1.transfer_syntaxes = tsf1_list
+
+        auth_type = dcerpc.DCERPC_AUTH_TYPE_SPNEGO
+        auth_context_id = 2
+
+        g = self._test_spnego_bind_auth_level(auth_level=auth_level,
+                                              auth_context_id=auth_context_id,
+                                              ctx=ctx1,
+                                              g_auth_level=g_auth_level,
+                                              alter_fault=alter_fault)
+
+        if request_fault is None:
+            return
+
+        self.assertIsNotNone(g)
+
+        stub_bin = '\x00' * 17
+        mod_len = len(stub_bin) % dcerpc.DCERPC_AUTH_PAD_ALIGNMENT
+        auth_pad_length = 0
+        if mod_len > 0:
+            auth_pad_length = dcerpc.DCERPC_AUTH_PAD_ALIGNMENT - mod_len
+        stub_bin += '\x00' * auth_pad_length
+
+        if g_auth_level >= dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY:
+            sig_size = g.sig_size(len(stub_bin))
+        else:
+            sig_size = 16
+        zero_sig = "\x00"*sig_size
+
+        auth_info = self.generate_auth(auth_type=auth_type,
+                                       auth_level=auth_level,
+                                       auth_pad_length=auth_pad_length,
+                                       auth_context_id=auth_context_id,
+                                       auth_blob=zero_sig)
+        req = self.generate_request(call_id = 4,
+                                    context_id=ctx1.context_id,
+                                    opnum=0xffff,
+                                    stub=stub_bin,
+                                    auth_info=auth_info)
+        if g_auth_level >= dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY:
+            req_blob = samba.ndr.ndr_pack(req)
+            ofs_stub = dcerpc.DCERPC_REQUEST_LENGTH
+            ofs_sig = len(req_blob) - req.auth_length
+            ofs_trailer = ofs_sig - dcerpc.DCERPC_AUTH_TRAILER_LENGTH
+            req_data = req_blob[ofs_stub:ofs_trailer]
+            req_whole = req_blob[0:ofs_sig]
+            sig = g.sign_packet(req_data, req_whole)
+            auth_info = self.generate_auth(auth_type=auth_type,
+                                           auth_level=auth_level,
+                                           auth_pad_length=auth_pad_length,
+                                           auth_context_id=auth_context_id,
+                                           auth_blob=sig)
+            req = self.generate_request(call_id = 4,
+                                        context_id=ctx1.context_id,
+                                        opnum=0xffff,
+                                        stub=stub_bin,
+                                        auth_info=auth_info)
+        self.send_pdu(req)
+        rep = self.recv_pdu()
+        self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id,
+                        pfc_flags=req.pfc_flags | response_fault_flags,
+                        auth_length=0)
+        self.assertNotEquals(rep.u.alloc_hint, 0)
+        self.assertEquals(rep.u.context_id, ctx1.context_id)
+        self.assertEquals(rep.u.cancel_count, 0)
+        self.assertEquals(rep.u.flags, 0)
+        self.assertEquals(rep.u.status, request_fault)
+        self.assertEquals(rep.u.reserved, 0)
+        self.assertEquals(len(rep.u.error_and_verifier), 0)
+
+        if response_fault_flags & dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE:
+            return
+
+        # wait for a disconnect
+        rep = self.recv_pdu()
+        self.assertIsNone(rep)
+        self.assertNotConnected()
+
+    def test_spnego_none_bind(self):
+        return self._test_spnego_level_bind_nak(dcerpc.DCERPC_AUTH_LEVEL_NONE,
+                            reason=dcerpc.DCERPC_BIND_NAK_REASON_NOT_SPECIFIED)
+
+    def test_spnego_call_bind(self):
+        return self._test_spnego_level_bind_nak(dcerpc.DCERPC_AUTH_LEVEL_CALL,
+                            reason=dcerpc.DCERPC_BIND_NAK_REASON_INVALID_CHECKSUM)
+
+    def test_spnego_0_bind(self):
+        return self._test_spnego_level_bind_nak(0,
+                            reason=dcerpc.DCERPC_BIND_NAK_REASON_NOT_SPECIFIED)
+
+    def test_spnego_7_bind(self):
+        return self._test_spnego_level_bind_nak(7,
+                            reason=dcerpc.DCERPC_BIND_NAK_REASON_NOT_SPECIFIED)
+
+    def test_spnego_255_bind(self):
+        return self._test_spnego_level_bind_nak(255,
+                            reason=dcerpc.DCERPC_BIND_NAK_REASON_NOT_SPECIFIED)
+
+    def test_spnego_connect_bind_none(self):
+        return self._test_spnego_level_bind(auth_level=dcerpc.DCERPC_AUTH_LEVEL_CONNECT,
+                                    g_auth_level=dcerpc.DCERPC_AUTH_LEVEL_CONNECT)
+
+    def test_spnego_connect_bind_sign(self):
+        return self._test_spnego_level_bind(auth_level=dcerpc.DCERPC_AUTH_LEVEL_CONNECT,
+                                    g_auth_level=dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY)
+
+    def test_spnego_connect_bind_seal(self):
+        return self._test_spnego_level_bind(auth_level=dcerpc.DCERPC_AUTH_LEVEL_CONNECT,
+                                    g_auth_level=dcerpc.DCERPC_AUTH_LEVEL_PRIVACY)
+
+    def test_spnego_packet_bind_none(self):
+        # DCERPC_AUTH_LEVEL_PACKET is handled as alias of
+        # DCERPC_AUTH_LEVEL_INTEGRITY
+        return self._test_spnego_level_bind(auth_level=dcerpc.DCERPC_AUTH_LEVEL_PACKET,
+                                    g_auth_level=dcerpc.DCERPC_AUTH_LEVEL_CONNECT,
+                                    request_fault=dcerpc.DCERPC_FAULT_SEC_PKG_ERROR)
+
+    def test_spnego_packet_bind_sign(self):
+        # DCERPC_AUTH_LEVEL_PACKET is handled as alias of
+        # DCERPC_AUTH_LEVEL_INTEGRITY
+        return self._test_spnego_level_bind(auth_level=dcerpc.DCERPC_AUTH_LEVEL_PACKET,
+                                    g_auth_level=dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY,
+                                    request_fault=dcerpc.DCERPC_NCA_S_OP_RNG_ERROR,
+                                    response_fault_flags=dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE)
+
+    def test_spnego_packet_bind_sign(self):
+        # DCERPC_AUTH_LEVEL_PACKET is handled as alias of
+        # DCERPC_AUTH_LEVEL_INTEGRITY
+        return self._test_spnego_level_bind(auth_level=dcerpc.DCERPC_AUTH_LEVEL_PACKET,
+                                    g_auth_level=dcerpc.DCERPC_AUTH_LEVEL_PRIVACY,
+                                    request_fault=dcerpc.DCERPC_NCA_S_OP_RNG_ERROR,
+                                    response_fault_flags=dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE)
+
+    def test_spnego_integrity_bind_none(self):
+        return self._test_spnego_level_bind(auth_level=dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY,
+                                    g_auth_level=dcerpc.DCERPC_AUTH_LEVEL_CONNECT,
+                                    request_fault=dcerpc.DCERPC_FAULT_SEC_PKG_ERROR)
+
+    def test_spnego_integrity_bind_sign(self):
+        return self._test_spnego_level_bind(auth_level=dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY,
+                                    g_auth_level=dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY,
+                                    request_fault=dcerpc.DCERPC_NCA_S_OP_RNG_ERROR,
+                                    response_fault_flags=dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE)
+
+    def test_spnego_integrity_bind_seal(self):
+        return self._test_spnego_level_bind(auth_level=dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY,
+                                    g_auth_level=dcerpc.DCERPC_AUTH_LEVEL_PRIVACY,
+                                    request_fault=dcerpc.DCERPC_NCA_S_OP_RNG_ERROR,
+                                    response_fault_flags=dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE)
+
+    def test_spnego_privacy_bind_none(self):
+        # This fails...
+        return self._test_spnego_level_bind(auth_level=dcerpc.DCERPC_AUTH_LEVEL_PRIVACY,
+                                    g_auth_level=dcerpc.DCERPC_AUTH_LEVEL_CONNECT,
+                                    alter_fault=dcerpc.DCERPC_FAULT_SEC_PKG_ERROR)
+
+    def test_spnego_privacy_bind_sign(self):
+        # This fails...
+        return self._test_spnego_level_bind(auth_level=dcerpc.DCERPC_AUTH_LEVEL_PRIVACY,
+                                    g_auth_level=dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY,
+                                    alter_fault=dcerpc.DCERPC_FAULT_SEC_PKG_ERROR)
+
+    def test_spnego_privacy_bind_seal(self):
+        return self._test_spnego_level_bind(auth_level=dcerpc.DCERPC_AUTH_LEVEL_PRIVACY,
+                                    g_auth_level=dcerpc.DCERPC_AUTH_LEVEL_PRIVACY)
+
+
+
+    def _test_spnego_signing_auth_level_request(self, auth_level):
+        ndr32 = base.transfer_syntax_ndr()
+
+        tsf1_list = [ndr32]
+        ctx1 = dcerpc.ctx_list()
+        ctx1.context_id = 0x1001
+        ctx1.num_transfer_syntaxes = len(tsf1_list)
+        ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
+        ctx1.transfer_syntaxes = tsf1_list
+        ctx_list = [ctx1]
+
+        auth_type = dcerpc.DCERPC_AUTH_TYPE_SPNEGO
+        auth_context_id = 2
+
+        g = self._test_spnego_bind_auth_level(auth_level=auth_level,
+                                              auth_context_id=auth_context_id,
+                                              ctx=ctx1)
+
+        stub_bin = '\x00' * 0
+        mod_len = len(stub_bin) % dcerpc.DCERPC_AUTH_PAD_ALIGNMENT
+        auth_pad_length = 0
+        if mod_len > 0:
+            auth_pad_length = dcerpc.DCERPC_AUTH_PAD_ALIGNMENT - mod_len
+        stub_bin += '\x00' * auth_pad_length
+
+        sig_size = g.sig_size(len(stub_bin))
+        zero_sig = "\x00"*sig_size
+
+        auth_info = self.generate_auth(auth_type=auth_type,
+                                       auth_level=auth_level,
+                                       auth_pad_length=auth_pad_length,
+                                       auth_context_id=auth_context_id,
+                                       auth_blob=zero_sig)
+        req = self.generate_request(call_id = 3,
+                                    context_id=ctx1.context_id,
+                                    opnum=0,
+                                    stub=stub_bin,
+                                    auth_info=auth_info)
+        req_blob = samba.ndr.ndr_pack(req)
+        ofs_stub = dcerpc.DCERPC_REQUEST_LENGTH
+        ofs_sig = len(req_blob) - req.auth_length
+        ofs_trailer = ofs_sig - dcerpc.DCERPC_AUTH_TRAILER_LENGTH
+        req_data = req_blob[ofs_stub:ofs_trailer]
+        req_whole = req_blob[0:ofs_sig]
+        sig = g.sign_packet(req_data, req_whole)
+        auth_info = self.generate_auth(auth_type=auth_type,
+                                       auth_level=auth_level,
+                                       auth_pad_length=auth_pad_length,
+                                       auth_context_id=auth_context_id,
+                                       auth_blob=sig)
+        req = self.generate_request(call_id = 3,
+                                    context_id=ctx1.context_id,
+                                    opnum=0,
+                                    stub=stub_bin,
+                                    auth_info=auth_info)
+        self.send_pdu(req)
+        (rep, rep_blob) = self.recv_pdu_raw()
+        self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
+                        auth_length=sig_size)
+        self.assertNotEquals(rep.u.alloc_hint, 0)
+        self.assertEquals(rep.u.context_id, req.u.context_id & 0xff)
+        self.assertEquals(rep.u.cancel_count, 0)
+        self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
+        self.assertEquals(rep.auth_length, sig_size)
+
+        ofs_stub = dcerpc.DCERPC_REQUEST_LENGTH
+        ofs_sig = rep.frag_length - rep.auth_length
+        ofs_trailer = ofs_sig - dcerpc.DCERPC_AUTH_TRAILER_LENGTH
+        rep_data = rep_blob[ofs_stub:ofs_trailer]
+        rep_whole = rep_blob[0:ofs_sig]
+        rep_sig = rep_blob[ofs_sig:]
+        rep_auth_info_blob = rep_blob[ofs_trailer:]
+
+        rep_auth_info = self.parse_auth(rep_auth_info_blob)
+        self.assertEquals(rep_auth_info.auth_type, auth_type)
+        self.assertEquals(rep_auth_info.auth_level, auth_level)
+        # mgmt_inq_if_ids() returns no fixed size results
+        #self.assertEquals(rep_auth_info.auth_pad_length, 0)
+        self.assertEquals(rep_auth_info.auth_reserved, 0)
+        self.assertEquals(rep_auth_info.auth_context_id, auth_context_id)
+        self.assertEquals(rep_auth_info.credentials, rep_sig)
+
+        g.check_packet(rep_data, rep_whole, rep_sig)
+
+        stub_bin = '\x00' * 17
+        mod_len = len(stub_bin) % dcerpc.DCERPC_AUTH_PAD_ALIGNMENT
+        auth_pad_length = 0
+        if mod_len > 0:
+            auth_pad_length = dcerpc.DCERPC_AUTH_PAD_ALIGNMENT - mod_len
+        stub_bin += '\x00' * auth_pad_length
+
+        sig_size = g.sig_size(len(stub_bin))
+        zero_sig = "\x00"*sig_size
+
+        auth_info = self.generate_auth(auth_type=auth_type,
+                                       auth_level=auth_level,
+                                       auth_pad_length=auth_pad_length,
+                                       auth_context_id=auth_context_id,
+                                       auth_blob=zero_sig)
+        req = self.generate_request(call_id = 4,
+                                    context_id=ctx1.context_id,
+                                    opnum=0xffff,
+                                    stub=stub_bin,
+                                    auth_info=auth_info)
+        req_blob = samba.ndr.ndr_pack(req)
+        ofs_stub = dcerpc.DCERPC_REQUEST_LENGTH
+        ofs_sig = len(req_blob) - req.auth_length
+        ofs_trailer = ofs_sig - dcerpc.DCERPC_AUTH_TRAILER_LENGTH
+        req_data = req_blob[ofs_stub:ofs_trailer]
+        req_whole = req_blob[0:ofs_sig]
+        sig = g.sign_packet(req_data, req_whole)
+        auth_info = self.generate_auth(auth_type=auth_type,
+                                       auth_level=auth_level,
+                                       auth_pad_length=auth_pad_length,
+                                       auth_context_id=auth_context_id,
+                                       auth_blob=sig)
+        req = self.generate_request(call_id = 4,
+                                    context_id=ctx1.context_id,
+                                    opnum=0xffff,
+                                    stub=stub_bin,
+                                    auth_info=auth_info)
+        self.send_pdu(req)
+        rep = self.recv_pdu()
+        self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id,
+                        pfc_flags=req.pfc_flags |
+                        dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
+                        auth_length=0)
+        self.assertNotEquals(rep.u.alloc_hint, 0)
+        self.assertEquals(rep.u.context_id, ctx1.context_id)
+        self.assertEquals(rep.u.cancel_count, 0)
+        self.assertEquals(rep.u.flags, 0)
+        self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_OP_RNG_ERROR)
+        self.assertEquals(rep.u.reserved, 0)
+        self.assertEquals(len(rep.u.error_and_verifier), 0)
+
+        stub_bin = '\x00' * 8
+        mod_len = len(stub_bin) % dcerpc.DCERPC_AUTH_PAD_ALIGNMENT
+        auth_pad_length = 0
+        if mod_len > 0:
+            auth_pad_length = dcerpc.DCERPC_AUTH_PAD_ALIGNMENT - mod_len
+        stub_bin += '\x00' * auth_pad_length
+
+        sig_size = g.sig_size(len(stub_bin))
+        zero_sig = "\x00"*sig_size
+
+        auth_info = self.generate_auth(auth_type=auth_type,
+                                       auth_level=auth_level,
+                                       auth_pad_length=auth_pad_length,
+                                       auth_context_id=auth_context_id,
+                                       auth_blob=zero_sig)
+        req = self.generate_request(call_id = 5,
+                                    context_id=ctx1.context_id,
+                                    opnum=1,
+                                    stub=stub_bin,
+                                    auth_info=auth_info)
+        req_blob = samba.ndr.ndr_pack(req)
+        ofs_stub = dcerpc.DCERPC_REQUEST_LENGTH
+        ofs_sig = len(req_blob) - req.auth_length
+        ofs_trailer = ofs_sig - dcerpc.DCERPC_AUTH_TRAILER_LENGTH
+        req_data = req_blob[ofs_stub:ofs_trailer]
+        req_whole = req_blob[0:ofs_sig]
+        sig = g.sign_packet(req_data, req_whole)
+        auth_info = self.generate_auth(auth_type=auth_type,
+                                       auth_level=auth_level,
+                                       auth_pad_length=auth_pad_length,
+                                       auth_context_id=auth_context_id,
+                                       auth_blob=sig)
+        req = self.generate_request(call_id = 5,
+                                    context_id=ctx1.context_id,
+                                    opnum=1,
+                                    stub=stub_bin,
+                                    auth_info=auth_info)
+        self.send_pdu(req)
+        (rep, rep_blob) = self.recv_pdu_raw()
+        self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
+                        auth_length=sig_size)
+        self.assertNotEquals(rep.u.alloc_hint, 0)
+        self.assertEquals(rep.u.context_id, req.u.context_id & 0xff)
+        self.assertEquals(rep.u.cancel_count, 0)
+        self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
+        self.assertEquals(rep.auth_length, sig_size)
+
+        ofs_stub = dcerpc.DCERPC_REQUEST_LENGTH
+        ofs_sig = rep.frag_length - rep.auth_length
+        ofs_trailer = ofs_sig - dcerpc.DCERPC_AUTH_TRAILER_LENGTH
+        rep_data = rep_blob[ofs_stub:ofs_trailer]
+        rep_whole = rep_blob[0:ofs_sig]
+        rep_sig = rep_blob[ofs_sig:]
+        rep_auth_info_blob = rep_blob[ofs_trailer:]
+
+        rep_auth_info = self.parse_auth(rep_auth_info_blob)
+        self.assertEquals(rep_auth_info.auth_type, auth_type)
+        self.assertEquals(rep_auth_info.auth_level, auth_level)
+        self.assertEquals(rep_auth_info.auth_pad_length, 4)
+        self.assertEquals(rep_auth_info.auth_reserved, 0)
+        self.assertEquals(rep_auth_info.auth_context_id, auth_context_id)
+        self.assertEquals(rep_auth_info.credentials, rep_sig)
+
+        g.check_packet(rep_data, rep_whole, rep_sig)
+
+        stub_bin = '\x00' * 8
+        mod_len = len(stub_bin) % dcerpc.DCERPC_AUTH_PAD_ALIGNMENT
+        auth_pad_length = 0
+        if mod_len > 0:
+            auth_pad_length = dcerpc.DCERPC_AUTH_PAD_ALIGNMENT - mod_len
+        stub_bin += '\x00' * auth_pad_length
+
+        sig_size = g.sig_size(len(stub_bin))
+        zero_sig = "\x00"*sig_size
+
+        auth_info = self.generate_auth(auth_type=auth_type,
+                                       auth_level=auth_level,
+                                       auth_pad_length=auth_pad_length,
+                                       auth_context_id=auth_context_id,
+                                       auth_blob=zero_sig)
+        req = self.generate_request(call_id = 6,
+                                    context_id=ctx1.context_id,
+                                    opnum=3,
+                                    stub=stub_bin,
+                                    auth_info=auth_info)
+        req_blob = samba.ndr.ndr_pack(req)
+        ofs_stub = dcerpc.DCERPC_REQUEST_LENGTH
+        ofs_sig = len(req_blob) - req.auth_length
+        ofs_trailer = ofs_sig - dcerpc.DCERPC_AUTH_TRAILER_LENGTH
+        req_data = req_blob[ofs_stub:ofs_trailer]
+        req_whole = req_blob[0:ofs_sig]
+        sig = g.sign_packet(req_data, req_whole)
+        auth_info = self.generate_auth(auth_type=auth_type,
+                                       auth_level=auth_level,
+                                       auth_pad_length=auth_pad_length,
+                                       auth_context_id=auth_context_id,
+                                       auth_blob=sig)
+        req = self.generate_request(call_id = 6,
+                                    context_id=ctx1.context_id,
+                                    opnum=3,
+                                    stub=stub_bin,
+                                    auth_info=auth_info)
+        self.send_pdu(req)
+        (rep, rep_blob) = self.recv_pdu_raw()
+        self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
+                        auth_length=sig_size)
+        self.assertNotEquals(rep.u.alloc_hint, 0)
+        self.assertEquals(rep.u.context_id, req.u.context_id & 0xff)
+        self.assertEquals(rep.u.cancel_count, 0)
+        self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
+        self.assertEquals(rep.auth_length, sig_size)
+
+        ofs_stub = dcerpc.DCERPC_REQUEST_LENGTH
+        ofs_sig = rep.frag_length - rep.auth_length
+        ofs_trailer = ofs_sig - dcerpc.DCERPC_AUTH_TRAILER_LENGTH
+        rep_data = rep_blob[ofs_stub:ofs_trailer]
+        rep_whole = rep_blob[0:ofs_sig]
+        rep_sig = rep_blob[ofs_sig:]
+        rep_auth_info_blob = rep_blob[ofs_trailer:]
+
+        rep_auth_info = self.parse_auth(rep_auth_info_blob)
+        self.assertEquals(rep_auth_info.auth_type, auth_type)
+        self.assertEquals(rep_auth_info.auth_level, auth_level)
+        self.assertEquals(rep_auth_info.auth_pad_length, 12)
+        self.assertEquals(rep_auth_info.auth_reserved, 0)
+        self.assertEquals(rep_auth_info.auth_context_id, auth_context_id)
+        self.assertEquals(rep_auth_info.credentials, rep_sig)
+
+        g.check_packet(rep_data, rep_whole, rep_sig)
+
+    def test_spnego_signing_packet(self):
+        # DCERPC_AUTH_LEVEL_PACKET is handled as alias of
+        # DCERPC_AUTH_LEVEL_INTEGRITY
+        return self._test_spnego_signing_auth_level_request(dcerpc.DCERPC_AUTH_LEVEL_PACKET)
+
+    def test_spnego_signing_integrity(self):
+        return self._test_spnego_signing_auth_level_request(dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY)
+
+
+    def test_assoc_group_fail1(self):
+        abstract = samba.dcerpc.mgmt.abstract_syntax()
+        transfer = base.transfer_syntax_ndr()
+
+        tsf1_list = [transfer]
+        ctx = samba.dcerpc.dcerpc.ctx_list()
+        ctx.context_id = 1
+        ctx.num_transfer_syntaxes = len(tsf1_list)
+        ctx.abstract_syntax = abstract
+        ctx.transfer_syntaxes = tsf1_list
+
+        ack = self.do_generic_bind(ctx=ctx, assoc_group_id=1,
+                                   nak_reason=dcerpc.DCERPC_BIND_NAK_REASON_NOT_SPECIFIED)
+        return
+
+    def test_assoc_group_fail2(self):
+        abstract = samba.dcerpc.mgmt.abstract_syntax()
+        transfer = base.transfer_syntax_ndr()
+
+        tsf1_list = [transfer]
+        ctx = samba.dcerpc.dcerpc.ctx_list()
+        ctx.context_id = 1
+        ctx.num_transfer_syntaxes = len(tsf1_list)
+        ctx.abstract_syntax = abstract
+        ctx.transfer_syntaxes = tsf1_list
+
+        ack = self.do_generic_bind(ctx=ctx)
+
+        self._disconnect("test_assoc_group_fail2")
+        self.assertNotConnected()
+        time.sleep(0.5)
+        self.connect()
+
+        ack2 = self.do_generic_bind(ctx=ctx,assoc_group_id=ack.u.assoc_group_id,
+                                    nak_reason=dcerpc.DCERPC_BIND_NAK_REASON_NOT_SPECIFIED)
+        return
+
+    def test_assoc_group_diff1(self):
+        abstract = samba.dcerpc.mgmt.abstract_syntax()
+        transfer = base.transfer_syntax_ndr()
+
+        (ctx1, ack1) = self.prepare_presentation(abstract, transfer,
+                                                 context_id=1, return_ack=True)
+
+        conn2 = self.second_connection()
+        (ctx2, ack2) = conn2.prepare_presentation(abstract, transfer,
+                                                  context_id=2, return_ack=True)
+        self.assertNotEqual(ack2.u.assoc_group_id, ack1.u.assoc_group_id)
+
+        return
+
+    def test_assoc_group_ok1(self):
+        abstract = samba.dcerpc.mgmt.abstract_syntax()
+        transfer = base.transfer_syntax_ndr()
+
+        (ctx1, ack1) = self.prepare_presentation(abstract, transfer,
+                                                 context_id=1, return_ack=True)
+
+        conn2 = self.second_connection()
+        (ctx2, ack2) = conn2.prepare_presentation(abstract, transfer,
+                                                  assoc_group_id=ack1.u.assoc_group_id,
+                                                  context_id=2, return_ack=True)
+
+        inq_if_ids = samba.dcerpc.mgmt.inq_if_ids()
+        self.do_single_request(call_id = 1, ctx=ctx1, io=inq_if_ids)
+        conn2.do_single_request(call_id = 1, ctx=ctx2, io=inq_if_ids)
+
+        conn2.do_single_request(call_id = 1, ctx=ctx1, io=inq_if_ids,
+                                fault_pfc_flags = samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST |
+                                samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST |
+                                samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
+                                fault_status=dcerpc.DCERPC_NCA_S_UNKNOWN_IF,
+                                fault_context_id=0)
+
+        self.do_single_request(call_id = 1, ctx=ctx1, io=inq_if_ids)
+        conn2.do_single_request(call_id = 1, ctx=ctx2, io=inq_if_ids)
+        return
+
 if __name__ == "__main__":
     global_ndr_print = True
     global_hexdump = True