Patches from my master4-dcerpc-ok branch

Stefan (metze) Metzmacher metze at samba.org
Thu Jul 2 16:14:12 CEST 2015


Hi,

here're some patches which are ready for master...

Please review and push...

Thanks!
metze
-------------- next part --------------
From fcacdaf0f16273875517c212c7327b8c64b1b631 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Sat, 18 Oct 2014 10:42:00 +0200
Subject: [PATCH 01/22] s4:ntvfs/ipc: fix ipc_close()

Until now this always returned NT_STATUS_INVALID_LEVEL
for everything but RAW_CLOSE_CLOSE.

Now it maps everything correctly to RAW_CLOSE_GENERIC.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source4/ntvfs/ipc/vfs_ipc.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c
index 50f0e59..a5f2bb1 100644
--- a/source4/ntvfs/ipc/vfs_ipc.c
+++ b/source4/ntvfs/ipc/vfs_ipc.c
@@ -737,11 +737,13 @@ static NTSTATUS ipc_close(struct ntvfs_module_context *ntvfs,
 				    struct ipc_private);
 	struct pipe_state *p;
 
-	if (io->generic.level != RAW_CLOSE_CLOSE) {
+	if (io->generic.level != RAW_CLOSE_GENERIC) {
 		return ntvfs_map_close(ntvfs, req, io);
 	}
 
-	p = pipe_state_find(ipriv, io->close.in.file.ntvfs);
+	ZERO_STRUCT(io->generic.out);
+
+	p = pipe_state_find(ipriv, io->generic.in.file.ntvfs);
 	if (!p) {
 		return NT_STATUS_INVALID_HANDLE;
 	}
-- 
1.9.1


From 3e82b3155529cdc829b66558f750bad25562b907 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 25 Jun 2015 20:30:43 +0200
Subject: [PATCH 02/22] auth/credentials: anonymous should not try to use
 kerberos

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 auth/credentials/credentials.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/auth/credentials/credentials.c b/auth/credentials/credentials.c
index 42aa2a3..df188b0 100644
--- a/auth/credentials/credentials.c
+++ b/auth/credentials/credentials.c
@@ -945,6 +945,7 @@ _PUBLIC_ void cli_credentials_set_anonymous(struct cli_credentials *cred)
 	cli_credentials_set_password(cred, NULL, CRED_SPECIFIED);
 	cli_credentials_set_realm(cred, NULL, CRED_SPECIFIED);
 	cli_credentials_set_workstation(cred, "", CRED_UNINITIALISED);
+	cli_credentials_set_kerberos_state(cred, CRED_DONT_USE_KERBEROS);
 }
 
 /**
-- 
1.9.1


From 86100b9baa765e91331062f840ce2d949f9cd4f8 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 25 Sep 2014 21:53:46 +0200
Subject: [PATCH 03/22] midltests: add valid/midltests_DRS_EXTENSIONS.*

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 .../midltests/valid/midltests_DRS_EXTENSIONS.idl   | 64 ++++++++++++++++++++++
 .../midltests/valid/midltests_DRS_EXTENSIONS.out   | 43 +++++++++++++++
 2 files changed, 107 insertions(+)
 create mode 100644 testprogs/win32/midltests/valid/midltests_DRS_EXTENSIONS.idl
 create mode 100644 testprogs/win32/midltests/valid/midltests_DRS_EXTENSIONS.out

diff --git a/testprogs/win32/midltests/valid/midltests_DRS_EXTENSIONS.idl b/testprogs/win32/midltests/valid/midltests_DRS_EXTENSIONS.idl
new file mode 100644
index 0000000..73aeb16
--- /dev/null
+++ b/testprogs/win32/midltests/valid/midltests_DRS_EXTENSIONS.idl
@@ -0,0 +1,64 @@
+#ifndef MIDLTESTS_C_CODE
+
+/*
+ * For midltests_tcp.exe you may want to
+ * redirect the traffic via rinetd
+ * with a /etc/rinetd.conf like this:
+ *
+ * 172.31.9.1 5032 172.31.9.8 5032
+ * 172.31.9.1 5064 172.31.9.8 5064
+ *
+ * This is useful to watch the traffic with
+ * a network sniffer.
+ */
+/*
+cpp_quote("#define LISTEN_IP \"0.0.0.0\"")
+cpp_quote("#define FORWARD_IP \"127.0.0.1\"")
+cpp_quote("#define CONNECT_IP \"172.31.9.1\"")
+*/
+
+/*
+ * With midltests_tcp.exe NDR64 is enforced by default.
+ * For testing it might be needed to allow downgrades
+ * to NDR32. This is needed when you use 'pipe'.
+ */
+//cpp_quote("#define DONOT_FORCE_NDR64 1")
+
+[
+  uuid("225b9fcb-eb3d-497b-8b0b-591f049a2507"),
+  pointer_default(unique)
+]
+interface midltests
+{
+
+	typedef struct {
+		[range(1,10000)] long cb;
+		[size_is(cb)] char rcg[];
+	} DRS_EXTENSIONS;
+
+	long midltests_fn(
+		[out] DRS_EXTENSIONS **e
+	);
+}
+
+#elif MIDLTESTS_C_CODE
+
+static void midltests(void)
+{
+	DRS_EXTENSIONS *e = NULL;
+	cli_midltests_fn(&e);
+}
+
+long srv_midltests_fn(DRS_EXTENSIONS **_e)
+{
+	DRS_EXTENSIONS *e;
+	printf("srv_midltests_fn: Start\n");
+	e = (DRS_EXTENSIONS *)malloc(sizeof(DRS_EXTENSIONS) + 0x34);
+	e->cb = 0x34;
+	memset(e->rcg, 0xcd, e->cb);
+	*_e = e;
+	printf("srv_midltests_fn: End\n");
+	return 0x65757254;
+}
+
+#endif
diff --git a/testprogs/win32/midltests/valid/midltests_DRS_EXTENSIONS.out b/testprogs/win32/midltests/valid/midltests_DRS_EXTENSIONS.out
new file mode 100644
index 0000000..0252b91
--- /dev/null
+++ b/testprogs/win32/midltests/valid/midltests_DRS_EXTENSIONS.out
@@ -0,0 +1,43 @@
+Wait for setup of server threads
+
+Test NDR32
+
+ndr32: disable NDR64
+
+ndr32:in => out: ptype[request] flen[24] plen[0] ahint[0]
+
+
+srv_midltests_fn: Start
+srv_midltests_fn: End
+
+ndr32:out => in: ptype[response] flen[92] plen[68] ahint[68]
+
+[000] 00 00 02 00 34 00 00 00  34 00 00 00 CD CD CD CD  ....4... 4.......
+[010] CD CD CD CD CD CD CD CD  CD CD CD CD CD CD CD CD  ........ ........
+[020] CD CD CD CD CD CD CD CD  CD CD CD CD CD CD CD CD  ........ ........
+[030] CD CD CD CD CD CD CD CD  CD CD CD CD CD CD CD CD  ........ ........
+[040] 54 72 75 65                                       True 
+
+NDRTcpThread[ndr32] stop
+
+Test NDR64
+
+ndr64: got NDR64
+
+ndr64:in => out: ptype[request] flen[24] plen[0] ahint[0]
+
+
+srv_midltests_fn: Start
+srv_midltests_fn: End
+
+ndr64:out => in: ptype[response] flen[100] plen[76] ahint[76]
+
+[000] 00 00 02 00 00 00 00 00  34 00 00 00 00 00 00 00  ........ 4.......
+[010] 34 00 00 00 CD CD CD CD  CD CD CD CD CD CD CD CD  4....... ........
+[020] CD CD CD CD CD CD CD CD  CD CD CD CD CD CD CD CD  ........ ........
+[030] CD CD CD CD CD CD CD CD  CD CD CD CD CD CD CD CD  ........ ........
+[040] CD CD CD CD CD CD CD CD  54 72 75 65              ........ True
+
+NDRTcpThread[ndr64] stop
+
+Test OK
-- 
1.9.1


From 1824b6dc59206b4b86a8478a51a234a7d9e960f0 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 19 Mar 2014 22:17:11 +0100
Subject: [PATCH 04/22] librpc/rpc: add faultcode to nt_status mappings

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 librpc/rpc/dcerpc_error.c | 143 ++++++++++++++++++++++++----------------------
 1 file changed, 75 insertions(+), 68 deletions(-)

diff --git a/librpc/rpc/dcerpc_error.c b/librpc/rpc/dcerpc_error.c
index 4f0ed6e..3366f63 100644
--- a/librpc/rpc/dcerpc_error.c
+++ b/librpc/rpc/dcerpc_error.c
@@ -26,58 +26,72 @@
 struct dcerpc_fault_table {
 	const char *errstr;
 	uint32_t faultcode;
+	NTSTATUS nt_status;
 };
 
 static const struct dcerpc_fault_table dcerpc_faults[] =
 {
-#define _FAULT_STR(x) { #x , x }
-	_FAULT_STR(DCERPC_NCA_S_COMM_FAILURE),
-	_FAULT_STR(DCERPC_NCA_S_OP_RNG_ERROR),
-	_FAULT_STR(DCERPC_NCA_S_UNKNOWN_IF),
-	_FAULT_STR(DCERPC_NCA_S_WRONG_BOOT_TIME),
-	_FAULT_STR(DCERPC_NCA_S_YOU_CRASHED),
-	_FAULT_STR(DCERPC_NCA_S_PROTO_ERROR),
-	_FAULT_STR(DCERPC_NCA_S_OUT_ARGS_TOO_BIG),
-	_FAULT_STR(DCERPC_NCA_S_SERVER_TOO_BUSY),
-	_FAULT_STR(DCERPC_NCA_S_FAULT_STRING_TOO_LARGE),
-	_FAULT_STR(DCERPC_NCA_S_UNSUPPORTED_TYPE),
-	_FAULT_STR(DCERPC_NCA_S_FAULT_INT_DIV_BY_ZERO),
-	_FAULT_STR(DCERPC_NCA_S_FAULT_ADDR_ERROR),
-	_FAULT_STR(DCERPC_NCA_S_FAULT_FP_DIV_BY_ZERO),
-	_FAULT_STR(DCERPC_NCA_S_FAULT_FP_UNDERFLOW),
-	_FAULT_STR(DCERPC_NCA_S_FAULT_FP_OVERRFLOW),
-	_FAULT_STR(DCERPC_NCA_S_FAULT_INVALID_TAG),
-	_FAULT_STR(DCERPC_NCA_S_FAULT_INVALID_BOUND),
-	_FAULT_STR(DCERPC_NCA_S_FAULT_RPC_VERSION_MISMATCH),
-	_FAULT_STR(DCERPC_NCA_S_FAULT_UNSPEC_REJECT),
-	_FAULT_STR(DCERPC_NCA_S_FAULT_BAD_ACTID),
-	_FAULT_STR(DCERPC_NCA_S_FAULT_WHO_ARE_YOU_FAILED),
-	_FAULT_STR(DCERPC_NCA_S_FAULT_MANAGER_NOT_ENTERED),
-	_FAULT_STR(DCERPC_NCA_S_FAULT_CANCEL),
-	_FAULT_STR(DCERPC_NCA_S_FAULT_ILL_INST),
-	_FAULT_STR(DCERPC_NCA_S_FAULT_FP_ERROR),
-	_FAULT_STR(DCERPC_NCA_S_FAULT_INT_OVERFLOW),
-	_FAULT_STR(DCERPC_NCA_S_UNUSED_1C000011),
-	_FAULT_STR(DCERPC_NCA_S_FAULT_UNSPEC),
-	_FAULT_STR(DCERPC_NCA_S_FAULT_REMOTE_COMM_FAILURE),
-	_FAULT_STR(DCERPC_NCA_S_FAULT_PIPE_EMPTY),
-	_FAULT_STR(DCERPC_NCA_S_FAULT_PIPE_CLOSED),
-	_FAULT_STR(DCERPC_NCA_S_FAULT_PIPE_ORDER),
-	_FAULT_STR(DCERPC_NCA_S_FAULT_PIPE_DISCIPLINE),
-	_FAULT_STR(DCERPC_NCA_S_FAULT_PIPE_COMM_ERROR),
-	_FAULT_STR(DCERPC_NCA_S_FAULT_PIPE_MEMORY),
-	_FAULT_STR(DCERPC_NCA_S_FAULT_CONTEXT_MISMATCH),
-	_FAULT_STR(DCERPC_NCA_S_FAULT_REMOTE_NO_MEMORY),
-	_FAULT_STR(DCERPC_NCA_S_INVALID_PRES_CONTEXT_ID),
-	_FAULT_STR(DCERPC_NCA_S_UNSUPPORTED_AUTHN_LEVEL),
-	_FAULT_STR(DCERPC_NCA_S_UNUSED_1C00001E),
-	_FAULT_STR(DCERPC_NCA_S_INVALID_CHECKSUM),
-	_FAULT_STR(DCERPC_NCA_S_INVALID_CRC),
-	_FAULT_STR(DCERPC_NCA_S_FAULT_USER_DEFINED),
-	_FAULT_STR(DCERPC_NCA_S_FAULT_TX_OPEN_FAILED),
-	_FAULT_STR(DCERPC_NCA_S_FAULT_CODESET_CONV_ERROR),
-	_FAULT_STR(DCERPC_NCA_S_FAULT_OBJECT_NOT_FOUND),
-	_FAULT_STR(DCERPC_NCA_S_FAULT_NO_CLIENT_STUB),
+#define _FAULT_STR(x, s) { .errstr = #x , .faultcode = x, .nt_status = s }
+#define _FAULT_STR_NO_NT_MAPPING(x) _FAULT_STR(x, NT_STATUS_RPC_NOT_RPC_ERROR)
+	_FAULT_STR(DCERPC_NCA_S_COMM_FAILURE, NT_STATUS_RPC_COMM_FAILURE),
+	_FAULT_STR(DCERPC_NCA_S_OP_RNG_ERROR, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE),
+	_FAULT_STR(DCERPC_NCA_S_UNKNOWN_IF, NT_STATUS_RPC_UNKNOWN_IF),
+	_FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_WRONG_BOOT_TIME),
+	_FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_YOU_CRASHED),
+	_FAULT_STR(DCERPC_NCA_S_PROTO_ERROR, NT_STATUS_RPC_PROTOCOL_ERROR),
+	_FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_OUT_ARGS_TOO_BIG),
+	_FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_SERVER_TOO_BUSY),
+	_FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_STRING_TOO_LARGE),
+	_FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_UNSUPPORTED_TYPE),
+	_FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_ADDR_ERROR),
+	_FAULT_STR(DCERPC_NCA_S_FAULT_FP_DIV_BY_ZERO, NT_STATUS_RPC_FP_DIV_ZERO),
+	_FAULT_STR(DCERPC_NCA_S_FAULT_FP_UNDERFLOW, NT_STATUS_RPC_FP_UNDERFLOW),
+	_FAULT_STR(DCERPC_NCA_S_FAULT_FP_OVERRFLOW, NT_STATUS_RPC_FP_OVERFLOW),
+	_FAULT_STR(DCERPC_NCA_S_FAULT_INT_DIV_BY_ZERO, NT_STATUS_RPC_FP_DIV_ZERO),
+	_FAULT_STR(DCERPC_NCA_S_FAULT_INT_OVERFLOW, NT_STATUS_RPC_FP_OVERFLOW),
+	/*
+	 * What's the difference between NT_STATUS_RPC_INVALID_TAG
+	 * and NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE ???
+	 *
+	 * Our callers expect NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE.
+	 */
+	_FAULT_STR(DCERPC_NCA_S_FAULT_INVALID_TAG, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE),
+	_FAULT_STR(DCERPC_NCA_S_FAULT_INVALID_TAG, NT_STATUS_RPC_INVALID_TAG),
+	_FAULT_STR(DCERPC_NCA_S_FAULT_INVALID_BOUND, NT_STATUS_RPC_INVALID_BOUND),
+	_FAULT_STR(DCERPC_NCA_S_FAULT_RPC_VERSION_MISMATCH, NT_STATUS_RPC_PROTOCOL_ERROR),
+	_FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_UNSPEC_REJECT),
+	_FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_BAD_ACTID),
+	_FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_WHO_ARE_YOU_FAILED),
+	_FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_MANAGER_NOT_ENTERED),
+	_FAULT_STR(DCERPC_NCA_S_FAULT_CANCEL, NT_STATUS_RPC_CALL_CANCELLED),
+	_FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_ILL_INST),
+	_FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_FP_ERROR),
+	_FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_UNUSED_1C000011),
+	_FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_UNSPEC),
+	_FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_REMOTE_COMM_FAILURE),
+	_FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_PIPE_EMPTY),
+	_FAULT_STR(DCERPC_NCA_S_FAULT_PIPE_CLOSED, NT_STATUS_RPC_PIPE_CLOSED),
+	_FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_PIPE_ORDER),
+	_FAULT_STR(DCERPC_NCA_S_FAULT_PIPE_DISCIPLINE, NT_STATUS_RPC_PIPE_DISCIPLINE_ERROR),
+	_FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_PIPE_COMM_ERROR),
+	_FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_PIPE_MEMORY),
+	_FAULT_STR(DCERPC_NCA_S_FAULT_CONTEXT_MISMATCH, NT_STATUS_RPC_SS_CONTEXT_MISMATCH),
+	_FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_REMOTE_NO_MEMORY),
+	_FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_INVALID_PRES_CONTEXT_ID),
+	_FAULT_STR(DCERPC_NCA_S_UNSUPPORTED_AUTHN_LEVEL, NT_STATUS_RPC_UNSUPPORTED_AUTHN_LEVEL),
+	_FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_UNUSED_1C00001E),
+	_FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_INVALID_CHECKSUM),
+	_FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_INVALID_CRC),
+	_FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_USER_DEFINED),
+	_FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_TX_OPEN_FAILED),
+	_FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_CODESET_CONV_ERROR),
+	_FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_OBJECT_NOT_FOUND),
+	_FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_NO_CLIENT_STUB),
+	_FAULT_STR(DCERPC_FAULT_OTHER, NT_STATUS_RPC_CALL_FAILED),
+	_FAULT_STR(DCERPC_FAULT_CANT_PERFORM, NT_STATUS_EPT_CANT_PERFORM_OP),
+	_FAULT_STR(DCERPC_FAULT_NDR, NT_STATUS_RPC_BAD_STUB_DATA),
+	_FAULT_STR(DCERPC_FAULT_ACCESS_DENIED, NT_STATUS_ACCESS_DENIED),
+	_FAULT_STR(DCERPC_FAULT_SEC_PKG_ERROR, NT_STATUS_RPC_SEC_PKG_ERROR),
 	{ NULL, 0 }
 #undef _FAULT_STR
 };
@@ -99,26 +113,19 @@ _PUBLIC_ const char *dcerpc_errstr(TALLOC_CTX *mem_ctx, uint32_t fault_code)
 
 _PUBLIC_ NTSTATUS dcerpc_fault_to_nt_status(uint32_t fault_code)
 {
-	/* TODO: add more mappings */
-	switch (fault_code) {
-	case DCERPC_NCA_S_OP_RNG_ERROR:
-		return NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE;
-	case DCERPC_NCA_S_UNKNOWN_IF:
-		return NT_STATUS_RPC_UNKNOWN_IF;
-	case DCERPC_FAULT_NDR:
-		return NT_STATUS_RPC_BAD_STUB_DATA;
-	case DCERPC_NCA_S_FAULT_INVALID_TAG:
-		return NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE;
-	case DCERPC_NCA_S_FAULT_CONTEXT_MISMATCH:
-		return NT_STATUS_RPC_SS_CONTEXT_MISMATCH;
-	case DCERPC_FAULT_OTHER:
-		return NT_STATUS_RPC_CALL_FAILED;
-	case DCERPC_FAULT_ACCESS_DENIED:
-		return NT_STATUS_ACCESS_DENIED;
-	case DCERPC_FAULT_SEC_PKG_ERROR:
-		return NT_STATUS_RPC_SEC_PKG_ERROR;
+	int idx = 0;
+	WERROR werr = W_ERROR(fault_code);
+
+	if (fault_code == 0) {
+		return NT_STATUS_RPC_PROTOCOL_ERROR;
 	}
 
-	return NT_STATUS_RPC_PROTOCOL_ERROR;
-}
+	while (dcerpc_faults[idx].errstr != NULL) {
+		if (dcerpc_faults[idx].faultcode == fault_code) {
+			return dcerpc_faults[idx].nt_status;
+		}
+		idx++;
+	}
 
+	return werror_to_ntstatus(werr);
+}
-- 
1.9.1


From 63a493ac175b645b78739f63913547a32ceb3b77 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 19 Mar 2014 22:22:58 +0100
Subject: [PATCH 05/22] librpc/rpc: add dcerpc_fault_from_nt_status()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 librpc/rpc/dcerpc_error.c | 21 +++++++++++++++++++++
 librpc/rpc/rpc_common.h   |  1 +
 2 files changed, 22 insertions(+)

diff --git a/librpc/rpc/dcerpc_error.c b/librpc/rpc/dcerpc_error.c
index 3366f63..2b90334 100644
--- a/librpc/rpc/dcerpc_error.c
+++ b/librpc/rpc/dcerpc_error.c
@@ -129,3 +129,24 @@ _PUBLIC_ NTSTATUS dcerpc_fault_to_nt_status(uint32_t fault_code)
 
 	return werror_to_ntstatus(werr);
 }
+
+_PUBLIC_ uint32_t dcerpc_fault_from_nt_status(NTSTATUS nt_status)
+{
+	int idx = 0;
+	WERROR werr;
+
+	if (NT_STATUS_IS_OK(nt_status)) {
+		return DCERPC_NCA_S_PROTO_ERROR;
+	}
+
+	while (dcerpc_faults[idx].errstr != NULL) {
+		if (NT_STATUS_EQUAL(dcerpc_faults[idx].nt_status, nt_status)) {
+			return dcerpc_faults[idx].faultcode;
+		}
+		idx++;
+	}
+
+	werr = ntstatus_to_werror(nt_status);
+
+	return W_ERROR_V(werr);
+}
diff --git a/librpc/rpc/rpc_common.h b/librpc/rpc/rpc_common.h
index 61a8eab..4210228 100644
--- a/librpc/rpc/rpc_common.h
+++ b/librpc/rpc/rpc_common.h
@@ -108,6 +108,7 @@ struct dcerpc_binding;
 
 const char *dcerpc_errstr(TALLOC_CTX *mem_ctx, uint32_t fault_code);
 NTSTATUS dcerpc_fault_to_nt_status(uint32_t fault_code);
+uint32_t dcerpc_fault_from_nt_status(NTSTATUS nt_status);
 
 /* The following definitions come from ../librpc/rpc/binding.c  */
 
-- 
1.9.1


From e18168134df3c444425cc4328cae36a3a0bf296f Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 9 Jan 2014 12:35:58 +0100
Subject: [PATCH 06/22] librpc/rpc: add
 dcerpc_[extract|construct]_bind_time_features()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 librpc/rpc/dcerpc_util.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++
 librpc/rpc/rpc_common.h  | 30 +++++++++++++++++++++++
 2 files changed, 93 insertions(+)

diff --git a/librpc/rpc/dcerpc_util.c b/librpc/rpc/dcerpc_util.c
index a4dd569..696bcda 100644
--- a/librpc/rpc/dcerpc_util.c
+++ b/librpc/rpc/dcerpc_util.c
@@ -652,3 +652,66 @@ bool dcerpc_sec_verification_trailer_check(
 
 	return true;
 }
+
+static const struct ndr_syntax_id dcerpc_bind_time_features_prefix  = {
+	.uuid = {
+		.time_low = 0x6cb71c2c,
+		.time_mid = 0x9812,
+		.time_hi_and_version = 0x4540,
+		.clock_seq = {0x00, 0x00},
+		.node = {0x00,0x00,0x00,0x00,0x00,0x00}
+	},
+	.if_version = 1,
+};
+
+bool dcerpc_extract_bind_time_features(struct ndr_syntax_id s, uint64_t *_features)
+{
+	uint8_t values[8];
+	uint64_t features = 0;
+
+	values[0] = s.uuid.clock_seq[0];
+	values[1] = s.uuid.clock_seq[1];
+	values[2] = s.uuid.node[0];
+	values[3] = s.uuid.node[1];
+	values[4] = s.uuid.node[2];
+	values[5] = s.uuid.node[3];
+	values[6] = s.uuid.node[4];
+	values[7] = s.uuid.node[5];
+
+	ZERO_STRUCT(s.uuid.clock_seq);
+	ZERO_STRUCT(s.uuid.node);
+
+	if (!ndr_syntax_id_equal(&s, &dcerpc_bind_time_features_prefix)) {
+		if (_features != NULL) {
+			*_features = 0;
+		}
+		return false;
+	}
+
+	features = BVAL(values, 0);
+
+	if (_features != NULL) {
+		*_features = features;
+	}
+
+	return true;
+}
+
+struct ndr_syntax_id dcerpc_construct_bind_time_features(uint64_t features)
+{
+	struct ndr_syntax_id s = dcerpc_bind_time_features_prefix;
+	uint8_t values[8];
+
+	SBVAL(values, 0, features);
+
+	s.uuid.clock_seq[0] = values[0];
+	s.uuid.clock_seq[1] = values[1];
+	s.uuid.node[0]      = values[2];
+	s.uuid.node[1]      = values[3];
+	s.uuid.node[2]      = values[4];
+	s.uuid.node[3]      = values[5];
+	s.uuid.node[4]      = values[6];
+	s.uuid.node[5]      = values[7];
+
+	return s;
+}
diff --git a/librpc/rpc/rpc_common.h b/librpc/rpc/rpc_common.h
index 4210228..28600c9 100644
--- a/librpc/rpc/rpc_common.h
+++ b/librpc/rpc/rpc_common.h
@@ -373,6 +373,36 @@ bool dcerpc_sec_verification_trailer_check(
 		const struct dcerpc_sec_vt_pcontext *pcontext,
 		const struct dcerpc_sec_vt_header2 *header2);
 
+/**
+ * @brief check and optionally extract the Bind Time Features from
+ * the given ndr_syntax_id.
+ *
+ * <a href="http://msdn.microsoft.com/en-us/library/cc243715.aspx">MS-RPCE 3.3.1.5.3 Bind Time Feature Negotiation</a>.
+ *
+ * @param[in]  s the syntax that should be checked.
+ *
+ * @param[out] features This is optional, it will be filled with the extracted
+ *                      features the on success, otherwise it's filled with 0.
+ *
+ * @return true if the syntax matches the 6CB71C2C-9812-4540 prefix with version 1, false otherwise.
+ *
+ * @see dcerpc_construct_bind_time_features
+ */
+bool dcerpc_extract_bind_time_features(struct ndr_syntax_id syntax, uint64_t *features);
+
+/**
+ * @brief Construct a ndr_syntax_id used for Bind Time Features Negotiation.
+ *
+ * <a href="http://msdn.microsoft.com/en-us/library/cc243715.aspx">MS-RPCE 3.3.1.5.3 Bind Time Feature Negotiation</a>.
+ *
+ * @param[in] features The supported features.
+ *
+ * @return The ndr_syntax_id with the given features.
+ *
+ * @see dcerpc_extract_bind_time_features
+ */
+struct ndr_syntax_id dcerpc_construct_bind_time_features(uint64_t features);
+
 #define DCERPC_AUTH_PAD_LENGTH(stub_length) (\
 	(((stub_length) % DCERPC_AUTH_PAD_ALIGNMENT) > 0)?\
 	(DCERPC_AUTH_PAD_ALIGNMENT - (stub_length) % DCERPC_AUTH_PAD_ALIGNMENT):\
-- 
1.9.1


From 59c3360672b27e19f549e687cac7d4e34ad0006a Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 2 Apr 2014 19:53:18 +0200
Subject: [PATCH 07/22] s4:pyrpc: add base.bind_time_features_syntax(features)

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source4/librpc/rpc/pyrpc.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/source4/librpc/rpc/pyrpc.c b/source4/librpc/rpc/pyrpc.c
index 09f6632..12199d4 100644
--- a/source4/librpc/rpc/pyrpc.c
+++ b/source4/librpc/rpc/pyrpc.c
@@ -398,6 +398,45 @@ static PyTypeObject py_transfer_syntax_ndr64_SyntaxType = {
 	.tp_new = py_transfer_syntax_ndr64_new,
 };
 
+static PyObject *py_bind_time_features_syntax_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
+{
+	const char *kwnames[] = {
+		"features", NULL
+	};
+	unsigned long long features = 0;
+	struct ndr_syntax_id syntax;
+	PyObject *args2 = Py_None;
+	PyObject *kwargs2 = Py_None;
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "K:features", discard_const_p(char *, kwnames), &features)) {
+		return NULL;
+	}
+
+	args2 = Py_BuildValue("()");
+	if (args2 == NULL) {
+		return NULL;
+	}
+
+	kwargs2 = Py_BuildValue("{}");
+	if (kwargs2 == NULL) {
+		Py_DECREF(args2);
+		return NULL;
+	}
+
+	syntax = dcerpc_construct_bind_time_features(features);
+
+	return py_dcerpc_syntax_init_helper(type, args2, kwargs2, &syntax);
+}
+
+static PyTypeObject py_bind_time_features_syntax_SyntaxType = {
+	PyObject_HEAD_INIT(NULL) 0,
+	.tp_name = "base.bind_time_features_syntax",
+	.tp_basicsize = sizeof(pytalloc_Object),
+	.tp_doc = "bind_time_features_syntax(features)\n",
+	.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+	.tp_new = py_bind_time_features_syntax_new,
+};
+
 void initbase(void)
 {
 	PyObject *m;
@@ -413,6 +452,7 @@ void initbase(void)
 
 	py_transfer_syntax_ndr_SyntaxType.tp_base = ndr_syntax_id_Type;
 	py_transfer_syntax_ndr64_SyntaxType.tp_base = ndr_syntax_id_Type;
+	py_bind_time_features_syntax_SyntaxType.tp_base = ndr_syntax_id_Type;
 
 	if (PyType_Ready(&dcerpc_InterfaceType) < 0)
 		return;
@@ -421,6 +461,8 @@ void initbase(void)
 		return;
 	if (PyType_Ready(&py_transfer_syntax_ndr64_SyntaxType) < 0)
 		return;
+	if (PyType_Ready(&py_bind_time_features_syntax_SyntaxType) < 0)
+		return;
 
 	m = Py_InitModule3("base", NULL, "DCE/RPC protocol implementation");
 	if (m == NULL)
@@ -433,4 +475,6 @@ void initbase(void)
 	PyModule_AddObject(m, "transfer_syntax_ndr", (PyObject *)(void *)&py_transfer_syntax_ndr_SyntaxType);
 	Py_INCREF((PyObject *)(void *)&py_transfer_syntax_ndr64_SyntaxType);
 	PyModule_AddObject(m, "transfer_syntax_ndr64", (PyObject *)(void *)&py_transfer_syntax_ndr64_SyntaxType);
+	Py_INCREF((PyObject *)(void *)&py_bind_time_features_syntax_SyntaxType);
+	PyModule_AddObject(m, "bind_time_features_syntax", (PyObject *)(void *)&py_bind_time_features_syntax_SyntaxType);
 }
-- 
1.9.1


From e719e75228469e0793708f996a6a801593920aca Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 25 Jun 2015 13:53:41 +0200
Subject: [PATCH 08/22] lib/util: fix output format in dump_data*()

This changes:

  [0000] 4E 54 4C 4D 53 53 50 00   01 00 00 00 05 82 08 60   NTLMSSP. .......`
  [0010] 09 00 09 00 20 00 00 00   00 00 00 00 29 00 00 00   .... ... ....)...
  [0020] 57 4F 52 4B 47 52 4F 55   50                       WORKGROU P

into:

  [0000] 4E 54 4C 4D 53 53 50 00   01 00 00 00 05 82 08 60   NTLMSSP. .......`
  [0010] 09 00 09 00 20 00 00 00   00 00 00 00 29 00 00 00   .... ... ....)...
  [0020] 57 4F 52 4B 47 52 4F 55   50                        WORKGROU P

Note the alignment of 'WORKGROU P'.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 lib/util/util.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/util/util.c b/lib/util/util.c
index 9ef7124..4f0e67f 100644
--- a/lib/util/util.c
+++ b/lib/util/util.c
@@ -530,7 +530,7 @@ void dump_data_cb(const uint8_t *buf, int len,
 	if (i%16) {
 		int n;
 		n = 16 - (i%16);
-		cb(" ", private_data);
+		cb("  ", private_data);
 		if (n>8) {
 			cb(" ", private_data);
 		}
-- 
1.9.1


From 6b2b81f4dd58b5038bdb2b58f12424414f85139e Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 25 Jun 2015 14:05:37 +0200
Subject: [PATCH 09/22] librpc/ndr: make use of dump_data_cb() in
 ndr_dump_data()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 librpc/ndr/ndr_basic.c | 39 +++++----------------------------------
 1 file changed, 5 insertions(+), 34 deletions(-)

diff --git a/librpc/ndr/ndr_basic.c b/librpc/ndr/ndr_basic.c
index 67aebe4..12e3942 100644
--- a/librpc/ndr/ndr_basic.c
+++ b/librpc/ndr/ndr_basic.c
@@ -1229,11 +1229,11 @@ _PUBLIC_ void ndr_print_array_uint8(struct ndr_print *ndr, const char *name,
 #undef _ONELINE_LIMIT
 }
 
-static void ndr_print_asc(struct ndr_print *ndr, const uint8_t *buf, int len)
+static void ndr_print_dump_data_cb(const char *buf, void *private_data)
 {
-	int i;
-	for (i=0;i<len;i++)
-		ndr->print(ndr, "%c", isprint(buf[i])?buf[i]:'.');
+	struct ndr_print *ndr = (struct ndr_print *)private_data;
+
+	ndr->print(ndr, "%s", buf);
 }
 
 /*
@@ -1241,37 +1241,8 @@ static void ndr_print_asc(struct ndr_print *ndr, const uint8_t *buf, int len)
  */
 static void ndr_dump_data(struct ndr_print *ndr, const uint8_t *buf, int len)
 {
-	int i=0;
-
 	ndr->no_newline = true;
-
-	for (i=0;i<len;) {
-		if (i%16 == 0 && i<len) {
-			ndr->print(ndr, "[%04X] ",i);
-		}
-
-		ndr->print(ndr, "%02X ",(int)buf[i]);
-		i++;
-		if (i%8 == 0) ndr->print(ndr,"  ");
-		if (i%16 == 0) {
-			ndr_print_asc(ndr,&buf[i-16],8); ndr->print(ndr," ");
-			ndr_print_asc(ndr,&buf[i-8],8); ndr->print(ndr, "\n");
-		}
-	}
-
-	if (i%16) {
-		int n;
-		n = 16 - (i%16);
-		ndr->print(ndr, " ");
-		if (n>8) ndr->print(ndr," ");
-		while (n--) ndr->print(ndr,"   ");
-		n = MIN(8,i%16);
-		ndr_print_asc(ndr,&buf[i-(i%16)],n); ndr->print(ndr, " ");
-		n = (i%16) - n;
-		if (n>0) ndr_print_asc(ndr,&buf[i-n],n);
-		ndr->print(ndr,"\n");
-	}
-
+	dump_data_cb(buf, len, true, ndr_print_dump_data_cb, ndr);
 	ndr->no_newline = false;
 }
 
-- 
1.9.1


From 05d45cf70c06bcc040025518e97ebacd44cc046c Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 25 Jun 2015 10:28:31 +0200
Subject: [PATCH 10/22] python/samba/tests: move hexdump() from DNSTest to
 TestCase

This is useful in a lot of test cases.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 python/samba/tests/__init__.py | 12 ++++++++++++
 python/samba/tests/dns.py      | 14 --------------
 2 files changed, 12 insertions(+), 14 deletions(-)

diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py
index 3e7094f..984b1bf 100644
--- a/python/samba/tests/__init__.py
+++ b/python/samba/tests/__init__.py
@@ -35,6 +35,7 @@ except ImportError:
     class SkipTest(Exception):
         """Test skipped."""
 
+HEXDUMP_FILTER=''.join([(len(repr(chr(x)))==3) and chr(x) or '.' for x in range(256)])
 
 class TestCase(unittest.TestCase):
     """A Samba test case."""
@@ -54,6 +55,17 @@ class TestCase(unittest.TestCase):
     def get_credentials(self):
         return cmdline_credentials
 
+    def hexdump(self, src, length=8):
+        N = 0
+        result = ''
+        while src:
+            s, src = src[:length], src[length:]
+            hexa = ' '.join(["%02X" % ord(x) for x in s])
+            s = s.translate(HEXDUMP_FILTER)
+            result += "%04X   %-*s   %s\n" % (N, length*3, hexa, s)
+            N += length
+        return result
+
     # These functions didn't exist before Python2.7:
     if sys.version_info < (2, 7):
         import warnings
diff --git a/python/samba/tests/dns.py b/python/samba/tests/dns.py
index 92ac876..04ac356 100644
--- a/python/samba/tests/dns.py
+++ b/python/samba/tests/dns.py
@@ -25,8 +25,6 @@ from samba import credentials, param
 from samba.tests import TestCase
 from samba.dcerpc import dnsp, dnsserver
 
-FILTER=''.join([(len(repr(chr(x)))==3) and chr(x) or '.' for x in range(256)])
-
 
 class DNSTest(TestCase):
 
@@ -125,18 +123,6 @@ class DNSTest(TestCase):
                 if s is not None:
                     s.close()
 
-    def hexdump(self, src, length=8):
-        N = 0
-        result = ''
-        while src:
-            s, src = src[:length], src[length:]
-            hexa = ' '.join(["%02X" % ord(x) for x in s])
-            s = s.translate(FILTER)
-            result += "%04X   %-*s   %s\n" % (N, length*3, hexa, s)
-            N += length
-        return result
-
-
 class TestSimpleQueries(DNSTest):
 
     def test_one_a_query(self):
-- 
1.9.1


From 43549cc4b35cbeedbcd487eddca156ed6835d306 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 25 Jun 2015 14:06:40 +0200
Subject: [PATCH 11/22] python/samba/tests: let the output of hexdump() match
 our C code in dump_data_cb()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 python/samba/tests/__init__.py | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py
index 984b1bf..558e1b7 100644
--- a/python/samba/tests/__init__.py
+++ b/python/samba/tests/__init__.py
@@ -55,15 +55,19 @@ class TestCase(unittest.TestCase):
     def get_credentials(self):
         return cmdline_credentials
 
-    def hexdump(self, src, length=8):
+    def hexdump(self, src):
         N = 0
         result = ''
         while src:
-            s, src = src[:length], src[length:]
-            hexa = ' '.join(["%02X" % ord(x) for x in s])
-            s = s.translate(HEXDUMP_FILTER)
-            result += "%04X   %-*s   %s\n" % (N, length*3, hexa, s)
-            N += length
+            ll = src[:8]
+            lr = src[8:16]
+            src = src[16:]
+            hl = ' '.join(["%02X" % ord(x) for x in ll])
+            hr = ' '.join(["%02X" % ord(x) for x in lr])
+            ll = ll.translate(HEXDUMP_FILTER)
+            lr = lr.translate(HEXDUMP_FILTER)
+            result += "[%04X] %-*s  %-*s  %s %s\n" % (N, 8*3, hl, 8*3, hr, ll, lr)
+            N += 16
         return result
 
     # These functions didn't exist before Python2.7:
-- 
1.9.1


From e823f178c475adaa111882b85e6f5c939318d8b8 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Mon, 29 Jun 2015 08:41:22 +0200
Subject: [PATCH 12/22] python/samba/tests: add fallbacks for
 assert{Less,Greater}[Equal]()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 python/samba/tests/__init__.py | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py
index 558e1b7..b53c4ea 100644
--- a/python/samba/tests/__init__.py
+++ b/python/samba/tests/__init__.py
@@ -95,6 +95,18 @@ class TestCase(unittest.TestCase):
         def assertIsNone(self, a, msg=None):
             self.assertTrue(a is None, msg)
 
+        def assertGreater(self, a, b, msg=None):
+            self.assertTrue(a > b, msg)
+
+        def assertGreaterEqual(self, a, b, msg=None):
+            self.assertTrue(a >= b, msg)
+
+        def assertLess(self, a, b, msg=None):
+            self.assertTrue(a < b, msg)
+
+        def assertLessEqual(self, a, b, msg=None):
+            self.assertTrue(a <= b, msg)
+
         def addCleanup(self, fn, *args, **kwargs):
             self._cleanups = getattr(self, "_cleanups", []) + [
                 (fn, args, kwargs)]
-- 
1.9.1


From b7eeba60ac3b37dbb3a8c7cc4c229c4537019833 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Mon, 29 Jun 2015 09:52:45 +0200
Subject: [PATCH 13/22] s3:winbindd: use check
 dcerpc_binding_handle_is_connected() instead of a specific status

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/winbindd/winbindd_dual_srv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c
index 97d8a1b..40919d7 100644
--- a/source3/winbindd/winbindd_dual_srv.c
+++ b/source3/winbindd/winbindd_dual_srv.c
@@ -774,7 +774,7 @@ reconnect:
 					  logon_server, NETLOGON_CONTROL_QUERY,
 					  2, &info, &werr);
 
-	if (NT_STATUS_EQUAL(status, NT_STATUS_IO_DEVICE_ERROR) && !retry) {
+	if (!dcerpc_binding_handle_is_connected(b) && !retry) {
 		DEBUG(10, ("Session might have expired. "
 			   "Reconnect and retry once.\n"));
 		invalidate_cm_connection(domain);
-- 
1.9.1


From c0c3845ac7b6889dd193b3b87cf1e358fa78ab86 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Sat, 27 Jun 2015 22:55:22 +0200
Subject: [PATCH 14/22] libcli/smb: let tstream_smbXcli_np report connection
 errors as EPIPE instead of EIO

This maps to NT_STATUS_CONNECTION_DISCONNECTED instead of
NT_STATUS_IO_DEVICE_ERROR.

EPIPE, NT_STATUS_CONNECTION_DISCONNECTED matches what other tstream backends
e.g. tcp and unix report.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 libcli/smb/tstream_smbXcli_np.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/libcli/smb/tstream_smbXcli_np.c b/libcli/smb/tstream_smbXcli_np.c
index 77a326b..9cd6302 100644
--- a/libcli/smb/tstream_smbXcli_np.c
+++ b/libcli/smb/tstream_smbXcli_np.c
@@ -632,7 +632,7 @@ static void tstream_smbXcli_np_writev_write_done(struct tevent_req *subreq)
 	}
 	TALLOC_FREE(subreq);
 	if (!NT_STATUS_IS_OK(status)) {
-		tstream_smbXcli_np_writev_disconnect_now(req, EIO, __location__);
+		tstream_smbXcli_np_writev_disconnect_now(req, EPIPE, __location__);
 		return;
 	}
 
@@ -980,7 +980,7 @@ static void tstream_smbXcli_np_readv_trans_done(struct tevent_req *subreq)
 		status = NT_STATUS_OK;
 	}
 	if (!NT_STATUS_IS_OK(status)) {
-		tstream_smbXcli_np_readv_disconnect_now(req, EIO, __location__);
+		tstream_smbXcli_np_readv_disconnect_now(req, EPIPE, __location__);
 		return;
 	}
 
@@ -1064,7 +1064,7 @@ static void tstream_smbXcli_np_readv_read_done(struct tevent_req *subreq)
 	}
 	if (!NT_STATUS_IS_OK(status)) {
 		TALLOC_FREE(subreq);
-		tstream_smbXcli_np_readv_disconnect_now(req, EIO, __location__);
+		tstream_smbXcli_np_readv_disconnect_now(req, EPIPE, __location__);
 		return;
 	}
 
@@ -1290,7 +1290,7 @@ static void tstream_smbXcli_np_disconnect_done(struct tevent_req *subreq)
 	}
 	TALLOC_FREE(subreq);
 	if (!NT_STATUS_IS_OK(status)) {
-		tevent_req_error(req, EIO);
+		tevent_req_error(req, EPIPE);
 		return;
 	}
 
-- 
1.9.1


From 3d422fdb3c194d07626164aeac934a2a09675fd2 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Mon, 29 Jun 2015 09:46:57 +0200
Subject: [PATCH 15/22] s4:torture/rpc: expect
 NT_STATUS_CONNECTION_DISCONNECTED when a dcerpc connection is not connected

We still also allow NT_STATUS_INVALID_HANDLE and NT_STATUS_IO_DEVICE_ERROR for now.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source4/torture/rpc/samba3rpc.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/source4/torture/rpc/samba3rpc.c b/source4/torture/rpc/samba3rpc.c
index ff1a53c..6f5477f 100644
--- a/source4/torture/rpc/samba3rpc.c
+++ b/source4/torture/rpc/samba3rpc.c
@@ -192,13 +192,19 @@ bool torture_bind_authcontext(struct torture_context *torture)
 
 	if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
 		torture_comment(torture, "dcerpc_lsa_OpenPolicy2 with wrong vuid gave %s, "
-			 "expected NT_STATUS_IO_DEVICE_ERROR\n",
+			 "expected NT_STATUS_CONNECTION_DISCONNECTED\n",
 			 nt_errstr(status));
-		status = NT_STATUS_IO_DEVICE_ERROR;
+		status = NT_STATUS_CONNECTION_DISCONNECTED;
+	}
+	if (NT_STATUS_EQUAL(status, NT_STATUS_IO_DEVICE_ERROR)) {
+		torture_comment(torture, "dcerpc_lsa_OpenPolicy2 with wrong vuid gave %s, "
+			 "expected NT_STATUS_CONNECTION_DISCONNECTED\n",
+			 nt_errstr(status));
+		status = NT_STATUS_CONNECTION_DISCONNECTED;
 	}
 
-	torture_assert_ntstatus_equal(torture, status, NT_STATUS_IO_DEVICE_ERROR,
-				      "lsa io device error");
+	torture_assert_ntstatus_equal(torture, status, NT_STATUS_CONNECTION_DISCONNECTED,
+				      "lsa connection disconnected");
 
 	smb1cli_session_set_id(tmp->smbXcli, tmp_vuid);
 	cli->tree->session = tmp;
-- 
1.9.1


From d7c854f3892266d45341dc4ab89beadfa58b455f Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Mon, 29 Jun 2015 09:49:05 +0200
Subject: [PATCH 16/22] s4:torture/rpc: expect
 NT_STATUS_CONNECTION_DISCONNECTED in torture_rpc_alter_context()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source4/torture/rpc/alter_context.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source4/torture/rpc/alter_context.c b/source4/torture/rpc/alter_context.c
index d14cabc..60e03db 100644
--- a/source4/torture/rpc/alter_context.c
+++ b/source4/torture/rpc/alter_context.c
@@ -85,7 +85,7 @@ bool torture_rpc_alter_context(struct torture_context *torture)
 	if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
 
 		ret &= test_lsa_OpenPolicy2_ex(p->binding_handle, torture, &handle,
-					       NT_STATUS_IO_DEVICE_ERROR);
+					       NT_STATUS_CONNECTION_DISCONNECTED);
 
 		torture_assert(torture, !dcerpc_binding_handle_is_connected(p->binding_handle),
 			       "dcerpc disonnected");
-- 
1.9.1


From d8bac1ac9a0859a4fb974d86742cc8ae4dcd28fd Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Mon, 29 Jun 2015 10:03:40 +0200
Subject: [PATCH 17/22] python:samba/tests: don't use the x.alter_context()
 method in dcerpc/bare.py

Establishing a new context on a given connection using alter_context
is supposed to be done by using y = ClientConnection(..., basis_connection=x)

The current x.alter_context() can work as it's not allowed to
change the abstract or transfer syntax of an existing presentation
context.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 python/samba/tests/dcerpc/bare.py | 13 ++-----------
 1 file changed, 2 insertions(+), 11 deletions(-)

diff --git a/python/samba/tests/dcerpc/bare.py b/python/samba/tests/dcerpc/bare.py
index 3efbf9d..e101c5b 100644
--- a/python/samba/tests/dcerpc/bare.py
+++ b/python/samba/tests/dcerpc/bare.py
@@ -31,21 +31,12 @@ class BareTestCase(samba.tests.TestCase):
                 lp_ctx=samba.tests.env_loadparm())
         self.assertEquals("\x01\x00\x00\x00", x.request(0, chr(0) * 4))
 
-    def test_alter_context(self):
+    def test_two_contexts(self):
         x = ClientConnection("ncalrpc:localhost[DEFAULT]",
                 ("12345778-1234-abcd-ef00-0123456789ac", 1),
                 lp_ctx=samba.tests.env_loadparm())
         y = ClientConnection("ncalrpc:localhost",
                 ("60a15ec5-4de8-11d7-a637-005056a20182", 1),
                 basis_connection=x, lp_ctx=samba.tests.env_loadparm())
-        x.alter_context(("60a15ec5-4de8-11d7-a637-005056a20182", 1))
-        # FIXME: self.assertEquals("\x01\x00\x00\x00", x.request(0, chr(0) * 4))
-
-    def test_two_connections(self):
-        x = ClientConnection("ncalrpc:localhost[DEFAULT]",
-                ("60a15ec5-4de8-11d7-a637-005056a20182", 1),
-                lp_ctx=samba.tests.env_loadparm())
-        y = ClientConnection("ncalrpc:localhost",
-                ("60a15ec5-4de8-11d7-a637-005056a20182", 1),
-                basis_connection=x, lp_ctx=samba.tests.env_loadparm())
+        self.assertEquals(24, len(x.request(0, chr(0) * 8)))
         self.assertEquals("\x01\x00\x00\x00", y.request(0, chr(0) * 4))
-- 
1.9.1


From 09dfc8ea6b2db3cb743d74072c0d610523a24bde Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Mon, 29 Jun 2015 10:07:17 +0200
Subject: [PATCH 18/22] s4:pyrpc: remove pointless alter_context() method

This will always result in a rpc protocol error.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source4/librpc/rpc/pyrpc.c | 36 ------------------------------------
 1 file changed, 36 deletions(-)

diff --git a/source4/librpc/rpc/pyrpc.c b/source4/librpc/rpc/pyrpc.c
index 12199d4..243e96b 100644
--- a/source4/librpc/rpc/pyrpc.c
+++ b/source4/librpc/rpc/pyrpc.c
@@ -246,44 +246,8 @@ static PyObject *py_iface_request(PyObject *self, PyObject *args, PyObject *kwar
 	return ret;
 }
 
-static PyObject *py_iface_alter_context(PyObject *self, PyObject *args, PyObject *kwargs)
-{
-	dcerpc_InterfaceObject *iface = (dcerpc_InterfaceObject *)self;
-	NTSTATUS status;
-	const char *kwnames[] = { "abstract_syntax", "transfer_syntax", NULL };
-	PyObject *py_abstract_syntax = Py_None, *py_transfer_syntax = Py_None;
-	struct ndr_syntax_id abstract_syntax, transfer_syntax;
-
-	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:alter_context", 
-		discard_const_p(char *, kwnames), &py_abstract_syntax,
-		&py_transfer_syntax)) {
-		return NULL;
-	}
-
-	if (!ndr_syntax_from_py_object(py_abstract_syntax, &abstract_syntax))
-		return NULL;
-
-	if (py_transfer_syntax == Py_None) {
-		transfer_syntax = ndr_transfer_syntax_ndr;
-	} else {
-		if (!ndr_syntax_from_py_object(py_transfer_syntax, &transfer_syntax))
-			return NULL;
-	}
-
-	status = dcerpc_alter_context(iface->pipe, iface->pipe, &abstract_syntax, 
-				      &transfer_syntax);
-
-	if (!NT_STATUS_IS_OK(status)) {
-		PyErr_SetDCERPCStatus(iface->pipe, status);
-		return NULL;
-	}
-
-	Py_RETURN_NONE;
-}
-
 static PyMethodDef dcerpc_interface_methods[] = {
 	{ "request", (PyCFunction)py_iface_request, METH_VARARGS|METH_KEYWORDS, "S.request(opnum, data, object=None) -> data\nMake a raw request" },
-	{ "alter_context", (PyCFunction)py_iface_alter_context, METH_VARARGS|METH_KEYWORDS, "S.alter_context(syntax)\nChange to a different interface" },
 	{ NULL, NULL, 0, NULL },
 };
 
-- 
1.9.1


From 39d9ead9bc0a520c20e46806fbfe6ffd5cd29d55 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Sat, 27 Jun 2015 10:31:48 +0200
Subject: [PATCH 19/22] s4:librpc: don't send an auth header for alter contexts
 without authentication

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source4/librpc/rpc/dcerpc.c      | 2 +-
 source4/librpc/rpc/dcerpc.h      | 1 +
 source4/librpc/rpc/dcerpc_auth.c | 2 ++
 3 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c
index 6e3410b..2347417 100644
--- a/source4/librpc/rpc/dcerpc.c
+++ b/source4/librpc/rpc/dcerpc.c
@@ -2119,7 +2119,7 @@ struct tevent_req *dcerpc_alter_context_send(TALLOC_CTX *mem_ctx,
 
 	/* construct the NDR form of the packet */
 	status = ncacn_push_auth(&blob, state, &pkt,
-				 p->conn->security_state.auth_info);
+				 p->conn->security_state.alter_auth_info);
 	if (tevent_req_nterror(req, status)) {
 		return tevent_req_post(req, ev);
 	}
diff --git a/source4/librpc/rpc/dcerpc.h b/source4/librpc/rpc/dcerpc.h
index a7d1694..0b123b6 100644
--- a/source4/librpc/rpc/dcerpc.h
+++ b/source4/librpc/rpc/dcerpc.h
@@ -47,6 +47,7 @@ struct gensec_settings;
 struct cli_credentials;
 struct dcecli_security {
 	struct dcerpc_auth *auth_info;
+	struct dcerpc_auth *alter_auth_info;
 	struct gensec_security *generic_state;
 
 	/* get the session key */
diff --git a/source4/librpc/rpc/dcerpc_auth.c b/source4/librpc/rpc/dcerpc_auth.c
index 2d60d38..f1c90a7 100644
--- a/source4/librpc/rpc/dcerpc_auth.c
+++ b/source4/librpc/rpc/dcerpc_auth.c
@@ -193,12 +193,14 @@ static void bind_auth_next_step(struct composite_context *c)
 
 	/* We are demanding a reply, so use a request that will get us one */
 
+	sec->alter_auth_info = sec->auth_info;
 	subreq = dcerpc_alter_context_send(state, state->pipe->conn->event_ctx,
 					   state->pipe,
 					   &state->pipe->syntax,
 					   &state->pipe->transfer_syntax);
 	data_blob_free(&state->credentials);
 	sec->auth_info->credentials = data_blob(NULL, 0);
+	sec->alter_auth_info = NULL;
 	if (composite_nomem(subreq, c)) return;
 	tevent_req_set_callback(subreq, bind_auth_recv_alter, c);
 }
-- 
1.9.1


From a6d354d0bdcf86cd6ab7485a1d8ae1271d49b042 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Sat, 27 Jun 2015 10:12:29 +0200
Subject: [PATCH 20/22] lib/util: add strlen_m_ext_term_null() helper function

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 lib/util/charset/charset.h  |  5 ++++-
 lib/util/charset/util_str.c | 16 ++++++++++++++++
 2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/lib/util/charset/charset.h b/lib/util/charset/charset.h
index 66b09a5..0d69d31 100644
--- a/lib/util/charset/charset.h
+++ b/lib/util/charset/charset.h
@@ -105,9 +105,12 @@ size_t strlen_m_ext_handle(struct smb_iconv_handle *ic,
 size_t strlen_m_ext(const char *s, charset_t src_charset, charset_t dst_charset);
 size_t strlen_m_ext_term(const char *s, charset_t src_charset,
 			 charset_t dst_charset);
+size_t strlen_m_ext_term_null(const char *s,
+			      charset_t src_charset,
+			      charset_t dst_charset);
+size_t strlen_m(const char *s);
 size_t strlen_m_term(const char *s);
 size_t strlen_m_term_null(const char *s);
-size_t strlen_m(const char *s);
 char *alpha_strcpy(char *dest, const char *src, const char *other_safe_chars, size_t maxlength);
 void string_replace_m(char *s, char oldc, char newc);
 bool strcsequal(const char *s1,const char *s2);
diff --git a/lib/util/charset/util_str.c b/lib/util/charset/util_str.c
index 1cbc1cd..70ecf6e 100644
--- a/lib/util/charset/util_str.c
+++ b/lib/util/charset/util_str.c
@@ -274,6 +274,22 @@ _PUBLIC_ size_t strlen_m_ext_term(const char *s, const charset_t src_charset,
 	return strlen_m_ext(s, src_charset, dst_charset) + 1;
 }
 
+_PUBLIC_ size_t strlen_m_ext_term_null(const char *s,
+				       const charset_t src_charset,
+				       const charset_t dst_charset)
+{
+	size_t len;
+	if (!s) {
+		return 0;
+	}
+	len = strlen_m_ext(s, src_charset, dst_charset);
+	if (len == 0) {
+		return 0;
+	}
+
+	return len+1;
+}
+
 /**
  * Calculate the number of 16-bit units that would be needed to convert
  * the input string which is expected to be in CH_UNIX encoding to UTF16.
-- 
1.9.1


From 2c7c4f6e558767fda2150ad193a1fd5642d582b9 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Sat, 27 Jun 2015 10:13:02 +0200
Subject: [PATCH 21/22] lib/util: let strlen_m_term[_null]() use
 strlen_m_ext_term[_null]()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 lib/util/charset/util_str.c | 17 ++---------------
 1 file changed, 2 insertions(+), 15 deletions(-)

diff --git a/lib/util/charset/util_str.c b/lib/util/charset/util_str.c
index 70ecf6e..33466ec 100644
--- a/lib/util/charset/util_str.c
+++ b/lib/util/charset/util_str.c
@@ -308,11 +308,7 @@ _PUBLIC_ size_t strlen_m(const char *s)
 **/
 _PUBLIC_ size_t strlen_m_term(const char *s)
 {
-	if (!s) {
-		return 0;
-	}
-
-	return strlen_m(s) + 1;
+	return strlen_m_ext_term(s, CH_UNIX, CH_UTF16LE);
 }
 
 /*
@@ -322,16 +318,7 @@ _PUBLIC_ size_t strlen_m_term(const char *s)
 
 _PUBLIC_ size_t strlen_m_term_null(const char *s)
 {
-	size_t len;
-	if (!s) {
-		return 0;
-	}
-	len = strlen_m(s);
-	if (len == 0) {
-		return 0;
-	}
-
-	return len+1;
+	return strlen_m_ext_term_null(s, CH_UNIX, CH_UTF16LE);
 }
 
 /**
-- 
1.9.1


From 202155d9e62ea4464c26eafd345d463d290891a1 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Mon, 29 Jun 2015 20:37:01 +0200
Subject: [PATCH 22/22] lib/util:charset/tests: improve
 strlen_m[_term[_null]]() testing

They differ in their "" vs. NULL handling.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 lib/util/charset/tests/charset.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/lib/util/charset/tests/charset.c b/lib/util/charset/tests/charset.c
index a47670e..7f33656 100644
--- a/lib/util/charset/tests/charset.c
+++ b/lib/util/charset/tests/charset.c
@@ -217,6 +217,7 @@ static bool test_strlen_m(struct torture_context *tctx)
 {
 	torture_assert_int_equal(tctx, strlen_m("foo"), 3, "simple len");
 	torture_assert_int_equal(tctx, strlen_m("foo\x83l"), 6, "extended len");
+	torture_assert_int_equal(tctx, strlen_m(""), 0, "empty");
 	torture_assert_int_equal(tctx, strlen_m(NULL), 0, "NULL");
 	return true;
 }
@@ -225,7 +226,17 @@ static bool test_strlen_m_term(struct torture_context *tctx)
 {
 	torture_assert_int_equal(tctx, strlen_m_term("foo"), 4, "simple len");
 	torture_assert_int_equal(tctx, strlen_m_term("foo\x83l"), 7, "extended len");
-	torture_assert_int_equal(tctx, strlen_m(NULL), 0, "NULL");
+	torture_assert_int_equal(tctx, strlen_m_term(""), 1, "empty");
+	torture_assert_int_equal(tctx, strlen_m_term(NULL), 0, "NULL");
+	return true;
+}
+
+static bool test_strlen_m_term_null(struct torture_context *tctx)
+{
+	torture_assert_int_equal(tctx, strlen_m_term_null("foo"), 4, "simple len");
+	torture_assert_int_equal(tctx, strlen_m_term_null("foo\x83l"), 7, "extended len");
+	torture_assert_int_equal(tctx, strlen_m_term_null(""), 0, "empty");
+	torture_assert_int_equal(tctx, strlen_m_term_null(NULL), 0, "NULL");
 	return true;
 }
 
@@ -278,6 +289,7 @@ struct torture_suite *torture_local_charset(TALLOC_CTX *mem_ctx)
 	torture_suite_add_simple_test(suite, "next_token_quote_wrong", test_next_token_quote_wrong);
 	torture_suite_add_simple_test(suite, "strlen_m", test_strlen_m);
 	torture_suite_add_simple_test(suite, "strlen_m_term", test_strlen_m_term);
+	torture_suite_add_simple_test(suite, "strlen_m_term_null", test_strlen_m_term_null);
 	torture_suite_add_simple_test(suite, "strhaslower", test_strhaslower);
 	torture_suite_add_simple_test(suite, "strhasupper", test_strhasupper);
 	torture_suite_add_simple_test(suite, "count_chars_m", test_count_chars_m);
-- 
1.9.1
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: OpenPGP digital signature
URL: <http://lists.samba.org/pipermail/samba-technical/attachments/20150702/bc816eba/attachment.pgp>


More information about the samba-technical mailing list