[Pkg-samba-maint] [samba] 03/08: Add mega security patch for 3.6

Andrew Bartlett abartlet-guest at moszumanska.debian.org
Wed Apr 13 01:33:24 UTC 2016


This is an automated email from the git hooks/post-receive script.

abartlet-guest pushed a commit to branch wheezy
in repository samba.

commit b2cb9e3043ab0967955d9319d72b28ae926416af
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Fri Apr 8 15:52:55 2016 +1200

    Add mega security patch for 3.6
    
    This is the backported patchset for Samba 3.6.25. We hope that have identified
    all issues.
    
    Also Samba 3.6 doesn't support header signing. If you care about this security
    feature should migrate to Samba 4.2 or newer!
    
    The Samba 3.6 patches have been backported by Andreas Schneider (Red Hat) and
    Ralph Böhme (SerNet). Thanks goes to Stefan Metzmacher for finding and fixing
    the CVEs in the first place. Thanks for the help with backporting to Günther
    Deschner (Red Hat) and Aurélien Aptel (SUSE).
    
    This had in turn be applied to Samba 3.6.6 by Andrew Bartlett
---
 debian/patches/CVE-2015-5370-v3-6.patch   | 3080 ++++++++++++
 debian/patches/CVE-2016-2110-v3-6.patch   |  600 +++
 debian/patches/CVE-2016-2111-v3-6.patch   | 1058 ++++
 debian/patches/CVE-2016-2112-v3-6.patch   |  184 +
 debian/patches/CVE-2016-2115-v3-6.patch   |  359 ++
 debian/patches/CVE-2016-2118-v3-6.patch   |  629 +++
 debian/patches/CVE-preparation-v3-6.patch | 7813 +++++++++++++++++++++++++++++
 debian/patches/series                     |    7 +
 8 files changed, 13730 insertions(+)

diff --git a/debian/patches/CVE-2015-5370-v3-6.patch b/debian/patches/CVE-2015-5370-v3-6.patch
new file mode 100644
index 0000000..a9aad58
--- /dev/null
+++ b/debian/patches/CVE-2015-5370-v3-6.patch
@@ -0,0 +1,3080 @@
+From 9ad47ca767b7d372d3dff6f8cda4ce24e76ed0ec Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Thu, 16 Jul 2015 22:46:05 +0200
+Subject: [PATCH 01/40] CVE-2015-5370: dcerpc.idl: add
+ DCERPC_{NCACN_PAYLOAD,FRAG}_MAX_SIZE defines
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+---
+ librpc/idl/dcerpc.idl | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/librpc/idl/dcerpc.idl b/librpc/idl/dcerpc.idl
+index 75ef2ec..bbb42d1 100644
+--- a/librpc/idl/dcerpc.idl
++++ b/librpc/idl/dcerpc.idl
+@@ -475,9 +475,11 @@ interface dcerpc
+ 	const uint8 DCERPC_PFC_OFFSET      =  3;
+ 	const uint8 DCERPC_DREP_OFFSET     =  4;
+ 	const uint8 DCERPC_FRAG_LEN_OFFSET =  8;
++	const uint32 DCERPC_FRAG_MAX_SIZE  = 5840;
+ 	const uint8 DCERPC_AUTH_LEN_OFFSET = 10;
+ 	const uint8 DCERPC_CALL_ID_OFFSET  = 12;
+ 	const uint8 DCERPC_NCACN_PAYLOAD_OFFSET = 16;
++	const uint32 DCERPC_NCACN_PAYLOAD_MAX_SIZE = 0x400000; /* 4 MByte */
+ 
+ 	/* little-endian flag */
+ 	const uint8 DCERPC_DREP_LE  = 0x10;
+-- 
+2.8.1
+
+
+From dcc4ced352fdb390cb5c27f7201a6f1f4d36630d Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Sun, 28 Jun 2015 01:19:57 +0200
+Subject: [PATCH 02/40] CVE-2015-5370: librpc/rpc: simplify and harden
+ dcerpc_pull_auth_trailer()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+---
+ librpc/rpc/dcerpc_util.c | 63 ++++++++++++++++++++++++++++++++++++------------
+ librpc/rpc/rpc_common.h  |  4 +--
+ 2 files changed, 49 insertions(+), 18 deletions(-)
+
+diff --git a/librpc/rpc/dcerpc_util.c b/librpc/rpc/dcerpc_util.c
+index 97ef798..f936ef4 100644
+--- a/librpc/rpc/dcerpc_util.c
++++ b/librpc/rpc/dcerpc_util.c
+@@ -92,31 +92,44 @@ uint8_t dcerpc_get_endian_flag(DATA_BLOB *blob)
+ *
+ * @return		- A NTSTATUS error code.
+ */
+-NTSTATUS dcerpc_pull_auth_trailer(struct ncacn_packet *pkt,
++NTSTATUS dcerpc_pull_auth_trailer(const struct ncacn_packet *pkt,
+ 				  TALLOC_CTX *mem_ctx,
+-				  DATA_BLOB *pkt_trailer,
++				  const DATA_BLOB *pkt_trailer,
+ 				  struct dcerpc_auth *auth,
+-				  uint32_t *auth_length,
++				  uint32_t *_auth_length,
+ 				  bool auth_data_only)
+ {
+ 	struct ndr_pull *ndr;
+ 	enum ndr_err_code ndr_err;
+-	uint32_t data_and_pad;
++	uint16_t data_and_pad;
++	uint16_t auth_length;
++	uint32_t tmp_length;
+ 
+-	data_and_pad = pkt_trailer->length
+-			- (DCERPC_AUTH_TRAILER_LENGTH + pkt->auth_length);
++	ZERO_STRUCTP(auth);
++	if (_auth_length != NULL) {
++		*_auth_length = 0;
++	}
+ 
+-	/* paranoia check for pad size. This would be caught anyway by
+-	   the ndr_pull_advance() a few lines down, but it scared
+-	   Jeremy enough for him to call me, so we might as well check
+-	   it now, just to prevent someone posting a bogus YouTube
+-	   video in the future.
+-	*/
+-	if (data_and_pad > pkt_trailer->length) {
+-		return NT_STATUS_INFO_LENGTH_MISMATCH;
++	/* Paranoia checks for auth_length. The caller should check this... */
++	if (pkt->auth_length > pkt->frag_length) {
++		return NT_STATUS_INTERNAL_ERROR;
++	}
++	tmp_length = DCERPC_NCACN_PAYLOAD_OFFSET;
++	tmp_length += DCERPC_AUTH_TRAILER_LENGTH;
++	tmp_length += pkt->auth_length;
++	if (tmp_length > pkt->frag_length) {
++		return NT_STATUS_INTERNAL_ERROR;
++	}
++	if (pkt_trailer->length > UINT16_MAX) {
++		return NT_STATUS_INTERNAL_ERROR;
+ 	}
+ 
+-	*auth_length = pkt_trailer->length - data_and_pad;
++	auth_length = DCERPC_AUTH_TRAILER_LENGTH + pkt->auth_length;
++	if (pkt_trailer->length < auth_length) {
++		return NT_STATUS_RPC_PROTOCOL_ERROR;
++	}
++
++	data_and_pad = pkt_trailer->length - auth_length;
+ 
+ 	ndr = ndr_pull_init_blob(pkt_trailer, mem_ctx);
+ 	if (!ndr) {
+@@ -136,14 +149,28 @@ NTSTATUS dcerpc_pull_auth_trailer(struct ncacn_packet *pkt,
+ 	ndr_err = ndr_pull_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, auth);
+ 	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ 		talloc_free(ndr);
++		ZERO_STRUCTP(auth);
+ 		return ndr_map_error2ntstatus(ndr_err);
+ 	}
+ 
++	if (data_and_pad < auth->auth_pad_length) {
++		DEBUG(1, (__location__ ": ERROR: pad length mismatch. "
++			  "Calculated %u  got %u\n",
++			  (unsigned)data_and_pad,
++			  (unsigned)auth->auth_pad_length));
++		talloc_free(ndr);
++		ZERO_STRUCTP(auth);
++		return NT_STATUS_RPC_PROTOCOL_ERROR;
++	}
++
+ 	if (auth_data_only && data_and_pad != auth->auth_pad_length) {
+-		DEBUG(1, (__location__ ": WARNING: pad length mismatch. "
++		DEBUG(1, (__location__ ": ERROR: pad length mismatch. "
+ 			  "Calculated %u  got %u\n",
+ 			  (unsigned)data_and_pad,
+ 			  (unsigned)auth->auth_pad_length));
++		talloc_free(ndr);
++		ZERO_STRUCTP(auth);
++		return NT_STATUS_RPC_PROTOCOL_ERROR;
+ 	}
+ 
+ 	DEBUG(6,(__location__ ": auth_pad_length %u\n",
+@@ -152,6 +179,10 @@ NTSTATUS dcerpc_pull_auth_trailer(struct ncacn_packet *pkt,
+ 	talloc_steal(mem_ctx, auth->credentials.data);
+ 	talloc_free(ndr);
+ 
++	if (_auth_length != NULL) {
++		*_auth_length = auth_length;
++	}
++
+ 	return NT_STATUS_OK;
+ }
+ 
+diff --git a/librpc/rpc/rpc_common.h b/librpc/rpc/rpc_common.h
+index fe8129d..98a2e95 100644
+--- a/librpc/rpc/rpc_common.h
++++ b/librpc/rpc/rpc_common.h
+@@ -158,9 +158,9 @@ uint8_t dcerpc_get_endian_flag(DATA_BLOB *blob);
+ *
+ * @return		- A NTSTATUS error code.
+ */
+-NTSTATUS dcerpc_pull_auth_trailer(struct ncacn_packet *pkt,
++NTSTATUS dcerpc_pull_auth_trailer(const struct ncacn_packet *pkt,
+ 				  TALLOC_CTX *mem_ctx,
+-				  DATA_BLOB *pkt_trailer,
++				  const DATA_BLOB *pkt_trailer,
+ 				  struct dcerpc_auth *auth,
+ 				  uint32_t *auth_length,
+ 				  bool auth_data_only);
+-- 
+2.8.1
+
+
+From ccefb8e67091dc97209687d07563c1caaa072ee4 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Mon, 29 Jun 2015 10:24:45 +0200
+Subject: [PATCH 03/40] CVE-2015-5370: s3:librpc/rpc: don't call
+ dcerpc_pull_auth_trailer() if auth_length is 0
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+All other paranoia checks are done within dcerpc_pull_auth_trailer()
+now.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+---
+ source3/librpc/rpc/dcerpc_helpers.c | 12 ++----------
+ 1 file changed, 2 insertions(+), 10 deletions(-)
+
+diff --git a/source3/librpc/rpc/dcerpc_helpers.c b/source3/librpc/rpc/dcerpc_helpers.c
+index 24f2f52..76f2acc 100644
+--- a/source3/librpc/rpc/dcerpc_helpers.c
++++ b/source3/librpc/rpc/dcerpc_helpers.c
+@@ -899,16 +899,8 @@ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth,
+ 		return NT_STATUS_INVALID_PARAMETER;
+ 	}
+ 
+-	/* Paranioa checks for auth_length. */
+-	if (pkt->auth_length > pkt->frag_length) {
+-		return NT_STATUS_INFO_LENGTH_MISMATCH;
+-	}
+-	if (((unsigned int)pkt->auth_length
+-	     + DCERPC_AUTH_TRAILER_LENGTH < (unsigned int)pkt->auth_length) ||
+-	    ((unsigned int)pkt->auth_length
+-	     + DCERPC_AUTH_TRAILER_LENGTH < DCERPC_AUTH_TRAILER_LENGTH)) {
+-		/* Integer wrap attempt. */
+-		return NT_STATUS_INFO_LENGTH_MISMATCH;
++	if (pkt->auth_length == 0) {
++		return NT_STATUS_INVALID_PARAMETER;
+ 	}
+ 
+ 	status = dcerpc_pull_auth_trailer(pkt, pkt, pkt_trailer,
+-- 
+2.8.1
+
+
+From 392631de5ec9bbe07af0e6950219cc7e1ddb078b Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Fri, 26 Jun 2015 08:10:46 +0200
+Subject: [PATCH 04/40] CVE-2015-5370: librpc/rpc: add a
+ dcerpc_verify_ncacn_packet_header() helper function
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+(cherry picked from commit 8266be48f455a5e541d0f7f62a1c8c38e0835976)
+---
+ librpc/rpc/dcerpc_util.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++
+ librpc/rpc/rpc_common.h  |  5 ++++
+ 2 files changed, 78 insertions(+)
+
+diff --git a/librpc/rpc/dcerpc_util.c b/librpc/rpc/dcerpc_util.c
+index f936ef4..2f599d5 100644
+--- a/librpc/rpc/dcerpc_util.c
++++ b/librpc/rpc/dcerpc_util.c
+@@ -186,6 +186,79 @@ NTSTATUS dcerpc_pull_auth_trailer(const struct ncacn_packet *pkt,
+ 	return NT_STATUS_OK;
+ }
+ 
++/**
++* @brief	Verify the fields in ncacn_packet header.
++*
++* @param pkt		- The ncacn_packet strcuture
++* @param ptype		- The expected PDU type
++* @param max_auth_info	- The maximum size of a possible auth trailer
++* @param required_flags	- The required flags for the pdu.
++* @param optional_flags	- The possible optional flags for the pdu.
++*
++* @return		- A NTSTATUS error code.
++*/
++NTSTATUS dcerpc_verify_ncacn_packet_header(const struct ncacn_packet *pkt,
++					   enum dcerpc_pkt_type ptype,
++					   size_t max_auth_info,
++					   uint8_t required_flags,
++					   uint8_t optional_flags)
++{
++	if (pkt->rpc_vers != 5) {
++		return NT_STATUS_RPC_PROTOCOL_ERROR;
++	}
++
++	if (pkt->rpc_vers_minor != 0) {
++		return NT_STATUS_RPC_PROTOCOL_ERROR;
++	}
++
++	if (pkt->auth_length > pkt->frag_length) {
++		return NT_STATUS_RPC_PROTOCOL_ERROR;
++	}
++
++	if (pkt->ptype != ptype) {
++		return NT_STATUS_RPC_PROTOCOL_ERROR;
++	}
++
++	if (max_auth_info > UINT16_MAX) {
++		return NT_STATUS_INTERNAL_ERROR;
++	}
++
++	if (pkt->auth_length > 0) {
++		size_t max_auth_length;
++
++		if (max_auth_info <= DCERPC_AUTH_TRAILER_LENGTH) {
++			return NT_STATUS_RPC_PROTOCOL_ERROR;
++		}
++		max_auth_length = max_auth_info - DCERPC_AUTH_TRAILER_LENGTH;
++
++		if (pkt->auth_length > max_auth_length) {
++			return NT_STATUS_RPC_PROTOCOL_ERROR;
++		}
++	}
++
++	if ((pkt->pfc_flags & required_flags) != required_flags) {
++		return NT_STATUS_RPC_PROTOCOL_ERROR;
++	}
++	if (pkt->pfc_flags & ~(optional_flags|required_flags)) {
++		return NT_STATUS_RPC_PROTOCOL_ERROR;
++	}
++
++	if (pkt->drep[0] & ~DCERPC_DREP_LE) {
++		return NT_STATUS_RPC_PROTOCOL_ERROR;
++	}
++	if (pkt->drep[1] != 0) {
++		return NT_STATUS_RPC_PROTOCOL_ERROR;
++	}
++	if (pkt->drep[2] != 0) {
++		return NT_STATUS_RPC_PROTOCOL_ERROR;
++	}
++	if (pkt->drep[3] != 0) {
++		return NT_STATUS_RPC_PROTOCOL_ERROR;
++	}
++
++	return NT_STATUS_OK;
++}
++
+ struct dcerpc_read_ncacn_packet_state {
+ #if 0
+ 	struct {
+diff --git a/librpc/rpc/rpc_common.h b/librpc/rpc/rpc_common.h
+index 98a2e95..b3ae5b2 100644
+--- a/librpc/rpc/rpc_common.h
++++ b/librpc/rpc/rpc_common.h
+@@ -164,6 +164,11 @@ NTSTATUS dcerpc_pull_auth_trailer(const struct ncacn_packet *pkt,
+ 				  struct dcerpc_auth *auth,
+ 				  uint32_t *auth_length,
+ 				  bool auth_data_only);
++NTSTATUS dcerpc_verify_ncacn_packet_header(const struct ncacn_packet *pkt,
++					   enum dcerpc_pkt_type ptype,
++					   size_t max_auth_info,
++					   uint8_t required_flags,
++					   uint8_t optional_flags);
+ struct tevent_req *dcerpc_read_ncacn_packet_send(TALLOC_CTX *mem_ctx,
+ 						 struct tevent_context *ev,
+ 						 struct tstream_context *stream);
+-- 
+2.8.1
+
+
+From e7e9266a82f730b9ed1a622455a68b9956c71323 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Tue, 7 Jul 2015 13:05:01 +0200
+Subject: [PATCH 05/40] CVE-2015-5370: s3:rpc_client: move AS/U hack to the top
+ of cli_pipe_validate_current_pdu()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+(cherry picked from commit 665b874b6022bfcdec3f13a9f5a844e5d1784aba)
+---
+ source3/rpc_client/cli_pipe.c | 24 +++++++++++++-----------
+ 1 file changed, 13 insertions(+), 11 deletions(-)
+
+diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c
+index 5ddabb7..295b88f 100644
+--- a/source3/rpc_client/cli_pipe.c
++++ b/source3/rpc_client/cli_pipe.c
+@@ -414,6 +414,19 @@ static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx,
+ 	 */
+ 	*rdata = *pdu;
+ 
++	if ((pkt->ptype == DCERPC_PKT_BIND_ACK) &&
++	    !(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
++		/*
++		 * TODO: do we still need this hack which was introduced
++		 * in commit a42afcdcc7ab9aa9ed193ae36d3dbb10843447f0.
++		 *
++		 * I don't even know what AS/U might be...
++		 */
++		DEBUG(5, (__location__ ": bug in server (AS/U?), setting "
++			  "fragment first/last ON.\n"));
++		pkt->pfc_flags |= DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
++	}
++
+ 	/* Ensure we have the correct type. */
+ 	switch (pkt->ptype) {
+ 	case DCERPC_PKT_ALTER_RESP:
+@@ -518,17 +531,6 @@ static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx,
+ 		return NT_STATUS_RPC_PROTOCOL_ERROR;
+ 	}
+ 
+-	/* Do this just before return - we don't want to modify any rpc header
+-	   data before now as we may have needed to do cryptographic actions on
+-	   it before. */
+-
+-	if ((pkt->ptype == DCERPC_PKT_BIND_ACK) &&
+-	    !(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
+-		DEBUG(5, (__location__ ": bug in server (AS/U?), setting "
+-			  "fragment first/last ON.\n"));
+-		pkt->pfc_flags |= DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
+-	}
+-
+ 	return NT_STATUS_OK;
+ }
+ 
+-- 
+2.8.1
+
+
+From 684a92839c4854e4bd66ec7dd35b5f1c05b5f0fa Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Tue, 7 Jul 2015 13:05:01 +0200
+Subject: [PATCH 06/40] CVE-2015-5370: s3:rpc_client: remove useless
+ frag_length check in rpc_api_pipe_got_pdu()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+dcerpc_pull_ncacn_packet() already verifies this.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+(cherry picked from commit 9a3f045244b12ff9f77d2664396137c390042297)
+---
+ source3/rpc_client/cli_pipe.c | 8 --------
+ 1 file changed, 8 deletions(-)
+
+diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c
+index 295b88f..2787fbc 100644
+--- a/source3/rpc_client/cli_pipe.c
++++ b/source3/rpc_client/cli_pipe.c
+@@ -898,14 +898,6 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
+ 		return;
+ 	}
+ 
+-	if (state->incoming_frag.length != state->pkt->frag_length) {
+-		DEBUG(5, ("Incorrect pdu length %u, expected %u\n",
+-			  (unsigned int)state->incoming_frag.length,
+-			  (unsigned int)state->pkt->frag_length));
+-		tevent_req_nterror(req,  NT_STATUS_INVALID_PARAMETER);
+-		return;
+-	}
+-
+ 	status = cli_pipe_validate_current_pdu(state,
+ 						state->cli, state->pkt,
+ 						&state->incoming_frag,
+-- 
+2.8.1
+
+
+From f6b8c87a094400923eabb5f5c46acd3ab5c09c05 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Fri, 26 Jun 2015 08:10:46 +0200
+Subject: [PATCH 07/40] CVE-2015-5370: s4:rpc_server: no authentication is
+ indicated by pkt->auth_length == 0
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+pkt->u.*.auth_info.length is not the correct thing to check.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+(packported from commit c0236de09e542dbb168969d8ae9f0c150a75198e)
+---
+ source4/rpc_server/dcesrv_auth.c | 23 ++++++++++++++---------
+ 1 file changed, 14 insertions(+), 9 deletions(-)
+
+diff --git a/source4/rpc_server/dcesrv_auth.c b/source4/rpc_server/dcesrv_auth.c
+index 1e6aa24..61f2176 100644
+--- a/source4/rpc_server/dcesrv_auth.c
++++ b/source4/rpc_server/dcesrv_auth.c
+@@ -46,7 +46,7 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call)
+ 	NTSTATUS status;
+ 	uint32_t auth_length;
+ 
+-	if (pkt->u.bind.auth_info.length == 0) {
++	if (pkt->auth_length == 0) {
+ 		dce_conn->auth_state.auth_info = NULL;
+ 		return true;
+ 	}
+@@ -108,7 +108,7 @@ NTSTATUS dcesrv_auth_bind_ack(struct dcesrv_call_state *call, struct ncacn_packe
+ 	struct dcesrv_connection *dce_conn = call->conn;
+ 	NTSTATUS status;
+ 
+-	if (!call->conn->auth_state.gensec_security) {
++	if (call->pkt.auth_length == 0) {
+ 		return NT_STATUS_OK;
+ 	}
+ 
+@@ -155,10 +155,16 @@ bool dcesrv_auth_auth3(struct dcesrv_call_state *call)
+ 	NTSTATUS status;
+ 	uint32_t auth_length;
+ 
+-	/* We can't work without an existing gensec state, and an new blob to feed it */
+-	if (!dce_conn->auth_state.auth_info ||
+-	    !dce_conn->auth_state.gensec_security ||
+-	    pkt->u.auth3.auth_info.length == 0) {
++	if (pkt->auth_length == 0) {
++		return false;
++	}
++
++	if (!dce_conn->auth_state.auth_info) {
++		return false;
++	}
++
++	/* We can't work without an existing gensec state */
++	if (!dce_conn->auth_state.gensec_security) {
+ 		return false;
+ 	}
+ 
+@@ -203,7 +209,7 @@ bool dcesrv_auth_alter(struct dcesrv_call_state *call)
+ 	uint32_t auth_length;
+ 
+ 	/* on a pure interface change there is no auth blob */
+-	if (pkt->u.alter.auth_info.length == 0) {
++	if (pkt->auth_length == 0) {
+ 		return true;
+ 	}
+ 
+@@ -238,8 +244,7 @@ NTSTATUS dcesrv_auth_alter_ack(struct dcesrv_call_state *call, struct ncacn_pack
+ 
+ 	/* on a pure interface change there is no auth_info structure
+ 	   setup */
+-	if (!call->conn->auth_state.auth_info ||
+-	    dce_conn->auth_state.auth_info->credentials.length == 0) {
++	if (call->pkt.auth_length == 0) {
+ 		return NT_STATUS_OK;
+ 	}
+ 
+-- 
+2.8.1
+
+
+From 5b99464c8d65aeacae846d15b7a7db549d84e589 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 08/40] CVE-2015-5370: s4:librpc/rpc: check pkt->auth_length
+ before calling dcerpc_pull_auth_trailer
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344
+
+Signed-off-by: Ralph Boehme <slow at samba.org>
+(backported from 630dcb55ad7a3a89bcd8643c98a5cdbfb8735ef7)
+---
+ source4/librpc/rpc/dcerpc.c      | 13 ++++++++++---
+ source4/rpc_server/dcesrv_auth.c |  5 +++++
+ 2 files changed, 15 insertions(+), 3 deletions(-)
+
+diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c
+index 742d710..cfbccd6 100644
+--- a/source4/librpc/rpc/dcerpc.c
++++ b/source4/librpc/rpc/dcerpc.c
+@@ -701,6 +701,14 @@ static NTSTATUS ncacn_pull_request_auth(struct dcecli_connection *c, TALLOC_CTX
+ 		return NT_STATUS_INVALID_LEVEL;
+ 	}
+ 
++	if (pkt->auth_length == 0) {
++		return NT_STATUS_INVALID_NETWORK_RESPONSE;
++	}
++
++	if (c->security_state.generic_state == NULL) {
++		return NT_STATUS_INTERNAL_ERROR;
++	}
++
+ 	status = dcerpc_pull_auth_trailer(pkt, mem_ctx,
+ 					  &pkt->u.response.stub_and_verifier,
+ 					  &auth, &auth_length, false);
+@@ -1074,7 +1082,7 @@ static void dcerpc_bind_recv_handler(struct rpc_request *req,
+ 	}
+ 
+ 	/* the bind_ack might contain a reply set of credentials */
+-	if (conn->security_state.auth_info && pkt->u.bind_ack.auth_info.length) {
++	if (conn->security_state.auth_info && pkt->auth_length) {
+ 		NTSTATUS status;
+ 		uint32_t auth_length;
+ 		status = dcerpc_pull_auth_trailer(pkt, conn, &pkt->u.bind_ack.auth_info,
+@@ -1847,8 +1855,7 @@ static void dcerpc_alter_recv_handler(struct rpc_request *req,
+ 	}
+ 
+ 	/* the alter_resp might contain a reply set of credentials */
+-	if (recv_pipe->conn->security_state.auth_info &&
+-	    pkt->u.alter_resp.auth_info.length) {
++	if (recv_pipe->conn->security_state.auth_info && pkt->auth_length) {
+ 		struct dcecli_connection *conn = recv_pipe->conn;
+ 		NTSTATUS status;
+ 		uint32_t auth_length;
+diff --git a/source4/rpc_server/dcesrv_auth.c b/source4/rpc_server/dcesrv_auth.c
+index 61f2176..3051c1c 100644
+--- a/source4/rpc_server/dcesrv_auth.c
++++ b/source4/rpc_server/dcesrv_auth.c
+@@ -320,6 +320,11 @@ bool dcesrv_auth_request(struct dcesrv_call_state *call, DATA_BLOB *full_packet)
+ 		return false;
+ 	}
+ 
++	if (pkt->auth_length == 0) {
++		DEBUG(1,("dcesrv_auth_request: unexpected auth_length of 0\n"));
++		return false;
++	}
++
+ 	status = dcerpc_pull_auth_trailer(pkt, call,
+ 					  &pkt->u.request.stub_and_verifier,
+ 					  &auth, &auth_length, false);
+-- 
+2.8.1
+
+
+From 097719efa48d5c9f3d27e087b438136d3b7deeff Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Sun, 28 Jun 2015 01:19:57 +0200
+Subject: [PATCH 09/40] CVE-2015-5370: librpc/rpc: don't allow pkt->auth_length
+ == 0 in dcerpc_pull_auth_trailer()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+All callers should have already checked that.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+(cherry picked from commit 1ed83c7657a3b405db1928db06c29f41d2738186)
+---
+ librpc/rpc/dcerpc_util.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/librpc/rpc/dcerpc_util.c b/librpc/rpc/dcerpc_util.c
+index 2f599d5..89b7597 100644
+--- a/librpc/rpc/dcerpc_util.c
++++ b/librpc/rpc/dcerpc_util.c
+@@ -111,6 +111,11 @@ NTSTATUS dcerpc_pull_auth_trailer(const struct ncacn_packet *pkt,
+ 	}
+ 
+ 	/* Paranoia checks for auth_length. The caller should check this... */
++	if (pkt->auth_length == 0) {
++		return NT_STATUS_INTERNAL_ERROR;
++	}
++
++	/* Paranoia checks for auth_length. The caller should check this... */
+ 	if (pkt->auth_length > pkt->frag_length) {
+ 		return NT_STATUS_INTERNAL_ERROR;
+ 	}
+-- 
+2.8.1
+
+
+From 2b5f6b2d2055247a2746eb6b3265e54fb5ea026d Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Thu, 9 Jul 2015 07:59:24 +0200
+Subject: [PATCH 10/40] CVE-2015-5370: s3:librpc/rpc: remove auth trailer and
+ possible padding within dcerpc_check_auth()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This simplifies the callers a lot.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+(cherry picked from commit df3cdf072d1c1e6fd0a58e0374348758f5c65a49)
+---
+ source3/librpc/rpc/dcerpc.h         |  5 ++---
+ source3/librpc/rpc/dcerpc_helpers.c | 31 ++++++++++++++++++++-----------
+ source3/rpc_client/cli_pipe.c       | 33 ++++++++++-----------------------
+ source3/rpc_server/srv_pipe.c       | 17 +----------------
+ 4 files changed, 33 insertions(+), 53 deletions(-)
+
+diff --git a/source3/librpc/rpc/dcerpc.h b/source3/librpc/rpc/dcerpc.h
+index d14d8e0..e7cca9e 100644
+--- a/source3/librpc/rpc/dcerpc.h
++++ b/source3/librpc/rpc/dcerpc.h
+@@ -85,9 +85,8 @@ NTSTATUS dcerpc_add_auth_footer(struct pipe_auth_data *auth,
+ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth,
+ 			   struct ncacn_packet *pkt,
+ 			   DATA_BLOB *pkt_trailer,
+-			   size_t header_size,
+-			   DATA_BLOB *raw_pkt,
+-			   size_t *pad_len);
++			   uint8_t header_size,
++			   DATA_BLOB *raw_pkt);
+ 
+ /* The following definitions come from librpc/rpc/rpc_common.c  */
+ 
+diff --git a/source3/librpc/rpc/dcerpc_helpers.c b/source3/librpc/rpc/dcerpc_helpers.c
+index 76f2acc..d871339 100644
+--- a/source3/librpc/rpc/dcerpc_helpers.c
++++ b/source3/librpc/rpc/dcerpc_helpers.c
+@@ -844,19 +844,18 @@ NTSTATUS dcerpc_add_auth_footer(struct pipe_auth_data *auth,
+ *
+ * @param auth		The auth data for the connection
+ * @param pkt		The actual ncacn_packet
+-* @param pkt_trailer	The stub_and_verifier part of the packet
++* @param pkt_trailer [in][out]	The stub_and_verifier part of the packet,
++* 			the auth_trailer and padding will be removed.
+ * @param header_size	The header size
+ * @param raw_pkt	The whole raw packet data blob
+-* @param pad_len	[out] The padding length used in the packet
+ *
+ * @return A NTSTATUS error code
+ */
+ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth,
+ 			   struct ncacn_packet *pkt,
+ 			   DATA_BLOB *pkt_trailer,
+-			   size_t header_size,
+-			   DATA_BLOB *raw_pkt,
+-			   size_t *pad_len)
++			   uint8_t header_size,
++			   DATA_BLOB *raw_pkt)
+ {
+ 	struct schannel_state *schannel_auth;
+ 	struct auth_ntlmssp_state *ntlmssp_ctx;
+@@ -868,6 +867,14 @@ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth,
+ 	DATA_BLOB full_pkt;
+ 	DATA_BLOB data;
+ 
++	/*
++	 * These check should be done in the caller.
++	 */
++	SMB_ASSERT(raw_pkt->length == pkt->frag_length);
++	SMB_ASSERT(header_size <= pkt->frag_length);
++	SMB_ASSERT(pkt_trailer->length < pkt->frag_length);
++	SMB_ASSERT((pkt_trailer->length + header_size) <= pkt->frag_length);
++
+ 	switch (auth->auth_level) {
+ 	case DCERPC_AUTH_LEVEL_PRIVACY:
+ 		DEBUG(10, ("Requested Privacy.\n"));
+@@ -881,7 +888,6 @@ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth,
+ 		if (pkt->auth_length != 0) {
+ 			break;
+ 		}
+-		*pad_len = 0;
+ 		return NT_STATUS_OK;
+ 
+ 	case DCERPC_AUTH_LEVEL_NONE:
+@@ -890,7 +896,6 @@ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth,
+ 				  "authenticated connection!\n"));
+ 			return NT_STATUS_INVALID_PARAMETER;
+ 		}
+-		*pad_len = 0;
+ 		return NT_STATUS_OK;
+ 
+ 	default:
+@@ -909,10 +914,11 @@ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth,
+ 		return status;
+ 	}
+ 
++	pkt_trailer->length -= auth_length;
+ 	data = data_blob_const(raw_pkt->data + header_size,
+-				pkt_trailer->length - auth_length);
+-	full_pkt = data_blob_const(raw_pkt->data,
+-				raw_pkt->length - auth_info.credentials.length);
++			       pkt_trailer->length);
++	full_pkt = data_blob_const(raw_pkt->data, raw_pkt->length);
++	full_pkt.length -= auth_info.credentials.length;
+ 
+ 	switch (auth->auth_type) {
+ 	case DCERPC_AUTH_TYPE_NONE:
+@@ -988,10 +994,13 @@ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth,
+ 	 * pkt_trailer actually has a copy of the raw data, and they
+ 	 * are still both used in later calls */
+ 	if (auth->auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
++		if (pkt_trailer->length != data.length) {
++			return NT_STATUS_INVALID_PARAMETER;
++		}
+ 		memcpy(pkt_trailer->data, data.data, data.length);
+ 	}
+ 
+-	*pad_len = auth_info.auth_pad_length;
++	pkt_trailer->length -= auth_info.auth_pad_length;
+ 	data_blob_free(&auth_info.credentials);
+ 	return NT_STATUS_OK;
+ }
+diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c
+index 2787fbc..776e2bf 100644
+--- a/source3/rpc_client/cli_pipe.c
++++ b/source3/rpc_client/cli_pipe.c
+@@ -404,9 +404,9 @@ static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx,
+ 						DATA_BLOB *rdata,
+ 						DATA_BLOB *reply_pdu)
+ {
+-	struct dcerpc_response *r;
++	const struct dcerpc_response *r = NULL;
++	DATA_BLOB tmp_stub = data_blob_null;
+ 	NTSTATUS ret = NT_STATUS_OK;
+-	size_t pad_len = 0;
+ 
+ 	/*
+ 	 * Point the return values at the real data including the RPC
+@@ -440,37 +440,24 @@ static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx,
+ 
+ 		r = &pkt->u.response;
+ 
++		tmp_stub.data = r->stub_and_verifier.data;
++		tmp_stub.length = r->stub_and_verifier.length;
++
+ 		/* Here's where we deal with incoming sign/seal. */
+ 		ret = dcerpc_check_auth(cli->auth, pkt,
+-					&r->stub_and_verifier,
++					&tmp_stub,
+ 					DCERPC_RESPONSE_LENGTH,
+-					pdu, &pad_len);
++					pdu);
+ 		if (!NT_STATUS_IS_OK(ret)) {
+ 			return ret;
+ 		}
+ 
+-		if (pkt->frag_length < DCERPC_RESPONSE_LENGTH + pad_len) {
+-			return NT_STATUS_BUFFER_TOO_SMALL;
+-		}
+-
+ 		/* Point the return values at the NDR data. */
+-		rdata->data = r->stub_and_verifier.data;
+-
+-		if (pkt->auth_length) {
+-			/* We've already done integer wrap tests in
+-			 * dcerpc_check_auth(). */
+-			rdata->length = r->stub_and_verifier.length
+-					 - pad_len
+-					 - DCERPC_AUTH_TRAILER_LENGTH
+-					 - pkt->auth_length;
+-		} else {
+-			rdata->length = r->stub_and_verifier.length;
+-		}
++		*rdata = tmp_stub;
+ 
+-		DEBUG(10, ("Got pdu len %lu, data_len %lu, ss_len %u\n",
++		DEBUG(10, ("Got pdu len %lu, data_len %lu\n",
+ 			   (long unsigned int)pdu->length,
+-			   (long unsigned int)rdata->length,
+-			   (unsigned int)pad_len));
++			   (long unsigned int)rdata->length));
+ 
+ 		/*
+ 		 * If this is the first reply, and the allocation hint is
+diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
+index 964b843..0ab7dc6 100644
+--- a/source3/rpc_server/srv_pipe.c
++++ b/source3/rpc_server/srv_pipe.c
+@@ -1848,7 +1848,6 @@ static NTSTATUS dcesrv_auth_request(struct pipe_auth_data *auth,
+ {
+ 	NTSTATUS status;
+ 	size_t hdr_size = DCERPC_REQUEST_LENGTH;
+-	size_t pad_len;
+ 
+ 	DEBUG(10, ("Checking request auth.\n"));
+ 
+@@ -1859,25 +1858,11 @@ static NTSTATUS dcesrv_auth_request(struct pipe_auth_data *auth,
+ 	/* in case of sealing this function will unseal the data in place */
+ 	status = dcerpc_check_auth(auth, pkt,
+ 				   &pkt->u.request.stub_and_verifier,
+-				   hdr_size, raw_pkt,
+-				   &pad_len);
++				   hdr_size, raw_pkt);
+ 	if (!NT_STATUS_IS_OK(status)) {
+ 		return status;
+ 	}
+ 
+-
+-	/* remove padding and auth trailer,
+-	 * this way the caller will get just the data */
+-	if (pkt->auth_length) {
+-		size_t trail_len = pad_len
+-					+ DCERPC_AUTH_TRAILER_LENGTH
+-					+ pkt->auth_length;
+-		if (pkt->u.request.stub_and_verifier.length < trail_len) {
+-			return NT_STATUS_INFO_LENGTH_MISMATCH;
+-		}
+-		pkt->u.request.stub_and_verifier.length -= trail_len;
+-	}
+-
+ 	return NT_STATUS_OK;
+ }
+ 
+-- 
+2.8.1
+
+
+From ef263a9387306f805b746ae4273a544425d6d37d Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Thu, 9 Jul 2015 07:59:24 +0200
+Subject: [PATCH 11/40] CVE-2015-5370: s3:librpc/rpc: let dcerpc_check_auth()
+ auth_{type,level} against the expected values.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+(cherry picked from commit 19f489d32c03ff5fafd34fe86a075d782af1989a)
+---
+ source3/librpc/rpc/dcerpc_helpers.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/source3/librpc/rpc/dcerpc_helpers.c b/source3/librpc/rpc/dcerpc_helpers.c
+index d871339..c07835f 100644
+--- a/source3/librpc/rpc/dcerpc_helpers.c
++++ b/source3/librpc/rpc/dcerpc_helpers.c
+@@ -914,6 +914,14 @@ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth,
+ 		return status;
+ 	}
+ 
++	if (auth_info.auth_type != auth->auth_type) {
++		return NT_STATUS_INVALID_PARAMETER;
++	}
++
++	if (auth_info.auth_level != auth->auth_level) {
++		return NT_STATUS_INVALID_PARAMETER;
++	}
++
+ 	pkt_trailer->length -= auth_length;
+ 	data = data_blob_const(raw_pkt->data + header_size,
+ 			       pkt_trailer->length);
+-- 
+2.8.1
+
+
+From e609895f0fe1131bb912d1d4d54252fd909d67aa Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Tue, 7 Jul 2015 13:05:01 +0200
+Subject: [PATCH 12/40] CVE-2015-5370: s3:rpc_client: make use of
+ dcerpc_pull_auth_trailer()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The does much more validation than dcerpc_pull_dcerpc_auth().
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+(cherry picked from commit acea87f158f02c3240abff45c3e54c7d5fa60b29)
+---
+ source3/rpc_client/cli_pipe.c | 20 ++++++--------------
+ 1 file changed, 6 insertions(+), 14 deletions(-)
+
+diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c
+index 776e2bf..27e37f8 100644
+--- a/source3/rpc_client/cli_pipe.c
++++ b/source3/rpc_client/cli_pipe.c
+@@ -1938,20 +1938,15 @@ static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
+ 		rpc_pipe_bind_step_two_trigger(req);
+ 		return;
+ 
+-	case DCERPC_AUTH_TYPE_NTLMSSP:
+-	case DCERPC_AUTH_TYPE_SPNEGO:
+-	case DCERPC_AUTH_TYPE_KRB5:
+-		/* Paranoid lenght checks */
+-		if (pkt->frag_length < DCERPC_AUTH_TRAILER_LENGTH
+-						+ pkt->auth_length) {
+-			tevent_req_nterror(req,
+-					NT_STATUS_INFO_LENGTH_MISMATCH);
++	default:
++		if (pkt->auth_length == 0) {
++			tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
+ 			return;
+ 		}
+ 		/* get auth credentials */
+-		status = dcerpc_pull_dcerpc_auth(talloc_tos(),
+-						 &pkt->u.bind_ack.auth_info,
+-						 &auth, false);
++		status = dcerpc_pull_auth_trailer(pkt, talloc_tos(),
++						  &pkt->u.bind_ack.auth_info,
++						  &auth, NULL, true);
+ 		if (!NT_STATUS_IS_OK(status)) {
+ 			DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
+ 				  nt_errstr(status)));
+@@ -1959,9 +1954,6 @@ static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
+ 			return;
+ 		}
+ 		break;
+-
+-	default:
+-		goto err_out;
+ 	}
+ 
+ 	/*
+-- 
+2.8.1
+
+
+From cbbcae5d7968b43905fb0fbba7d66e5cc2f5dda9 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Tue, 7 Jul 2015 13:05:01 +0200
+Subject: [PATCH 13/40] CVE-2015-5370: s3:rpc_client: make use of
+ dcerpc_verify_ncacn_packet_header() in cli_pipe_validate_current_pdu()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+(cherry picked from commit 81bbffa14f5f6faa9801a3bf2d564d2762d49bb6)
+---
+ source3/rpc_client/cli_pipe.c | 111 ++++++++++++++++++++++++++++++++++++------
+ 1 file changed, 96 insertions(+), 15 deletions(-)
+
+diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c
+index 27e37f8..6a22d38 100644
+--- a/source3/rpc_client/cli_pipe.c
++++ b/source3/rpc_client/cli_pipe.c
+@@ -429,17 +429,89 @@ static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx,
+ 
+ 	/* Ensure we have the correct type. */
+ 	switch (pkt->ptype) {
+-	case DCERPC_PKT_ALTER_RESP:
++	case DCERPC_PKT_BIND_NAK:
++		DEBUG(1, (__location__ ": Bind NACK received from %s!\n",
++			  rpccli_pipe_txt(talloc_tos(), cli)));
++
++		ret = dcerpc_verify_ncacn_packet_header(pkt,
++						DCERPC_PKT_BIND_NAK,
++						0, /* max_auth_info */
++						DCERPC_PFC_FLAG_FIRST |
++						DCERPC_PFC_FLAG_LAST,
++						0); /* optional flags */
++		if (!NT_STATUS_IS_OK(ret)) {
++			DEBUG(1, (__location__ ": Connection to %s got an unexpected "
++				  "RPC packet type - %u, expected %u: %s\n",
++				  rpccli_pipe_txt(talloc_tos(), cli),
++				  pkt->ptype, expected_pkt_type,
++				  nt_errstr(ret)));
++			NDR_PRINT_DEBUG(ncacn_packet, pkt);
++			return ret;
++		}
++
++		/* Use this for now... */
++		return NT_STATUS_NETWORK_ACCESS_DENIED;
++
+ 	case DCERPC_PKT_BIND_ACK:
++		ret = dcerpc_verify_ncacn_packet_header(pkt,
++					expected_pkt_type,
++					pkt->u.bind_ack.auth_info.length,
++					DCERPC_PFC_FLAG_FIRST |
++					DCERPC_PFC_FLAG_LAST,
++					DCERPC_PFC_FLAG_CONC_MPX |
++					DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN);
++		if (!NT_STATUS_IS_OK(ret)) {
++			DEBUG(1, (__location__ ": Connection to %s got an unexpected "
++				  "RPC packet type - %u, expected %u: %s\n",
++				  rpccli_pipe_txt(talloc_tos(), cli),
++				  pkt->ptype, expected_pkt_type,
++				  nt_errstr(ret)));
++			NDR_PRINT_DEBUG(ncacn_packet, pkt);
++			return ret;
++		}
+ 
+-		/* Client code never receives this kind of packets */
+ 		break;
+ 
++	case DCERPC_PKT_ALTER_RESP:
++		ret = dcerpc_verify_ncacn_packet_header(pkt,
++					expected_pkt_type,
++					pkt->u.alter_resp.auth_info.length,
++					DCERPC_PFC_FLAG_FIRST |
++					DCERPC_PFC_FLAG_LAST,
++					DCERPC_PFC_FLAG_CONC_MPX |
++					DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN);
++		if (!NT_STATUS_IS_OK(ret)) {
++			DEBUG(1, (__location__ ": Connection to %s got an unexpected "
++				  "RPC packet type - %u, expected %u: %s\n",
++				  rpccli_pipe_txt(talloc_tos(), cli),
++				  pkt->ptype, expected_pkt_type,
++				  nt_errstr(ret)));
++			NDR_PRINT_DEBUG(ncacn_packet, pkt);
++			return ret;
++		}
++
++		break;
+ 
+ 	case DCERPC_PKT_RESPONSE:
+ 
+ 		r = &pkt->u.response;
+ 
++		ret = dcerpc_verify_ncacn_packet_header(pkt,
++						expected_pkt_type,
++						r->stub_and_verifier.length,
++						0, /* required_flags */
++						DCERPC_PFC_FLAG_FIRST |
++						DCERPC_PFC_FLAG_LAST);
++		if (!NT_STATUS_IS_OK(ret)) {
++			DEBUG(1, (__location__ ": Connection to %s got an unexpected "
++				  "RPC packet type - %u, expected %u: %s\n",
++				  rpccli_pipe_txt(talloc_tos(), cli),
++				  pkt->ptype, expected_pkt_type,
++				  nt_errstr(ret)));
++			NDR_PRINT_DEBUG(ncacn_packet, pkt);
++			return ret;
++		}
++
+ 		tmp_stub.data = r->stub_and_verifier.data;
+ 		tmp_stub.length = r->stub_and_verifier.length;
+ 
+@@ -449,6 +521,12 @@ static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx,
+ 					DCERPC_RESPONSE_LENGTH,
+ 					pdu);
+ 		if (!NT_STATUS_IS_OK(ret)) {
++			DEBUG(1, (__location__ ": Connection to %s got an unexpected "
++				  "RPC packet type - %u, expected %u: %s\n",
++				  rpccli_pipe_txt(talloc_tos(), cli),
++				  pkt->ptype, expected_pkt_type,
++				  nt_errstr(ret)));
++			NDR_PRINT_DEBUG(ncacn_packet, pkt);
+ 			return ret;
+ 		}
+ 
+@@ -478,14 +556,24 @@ static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx,
+ 
+ 		break;
+ 
+-	case DCERPC_PKT_BIND_NAK:
+-		DEBUG(1, (__location__ ": Bind NACK received from %s!\n",
+-			  rpccli_pipe_txt(talloc_tos(), cli)));
+-		/* Use this for now... */
+-		return NT_STATUS_NETWORK_ACCESS_DENIED;
+-
+ 	case DCERPC_PKT_FAULT:
+ 
++		ret = dcerpc_verify_ncacn_packet_header(pkt,
++						DCERPC_PKT_FAULT,
++						0, /* max_auth_info */
++						DCERPC_PFC_FLAG_FIRST |
++						DCERPC_PFC_FLAG_LAST,
++						DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
++		if (!NT_STATUS_IS_OK(ret)) {
++			DEBUG(1, (__location__ ": Connection to %s got an unexpected "
++				  "RPC packet type - %u, expected %u: %s\n",
++				  rpccli_pipe_txt(talloc_tos(), cli),
++				  pkt->ptype, expected_pkt_type,
++				  nt_errstr(ret)));
++			NDR_PRINT_DEBUG(ncacn_packet, pkt);
++			return ret;
++		}
++
+ 		DEBUG(1, (__location__ ": RPC fault code %s received "
+ 			  "from %s!\n",
+ 			  dcerpc_errstr(talloc_tos(),
+@@ -502,13 +590,6 @@ static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx,
+ 		return NT_STATUS_RPC_PROTOCOL_ERROR;
+ 	}
+ 
+-	if (pkt->ptype != expected_pkt_type) {
+-		DEBUG(3, (__location__ ": Connection to %s got an unexpected "
+-			  "RPC packet type - %u, not %u\n",
+-			  rpccli_pipe_txt(talloc_tos(), cli),
+-			  pkt->ptype, expected_pkt_type));
+-		return NT_STATUS_RPC_PROTOCOL_ERROR;
+-	}
+ 
+ 	if (pkt->call_id != call_id) {
+ 		DEBUG(3, (__location__ ": Connection to %s got an unexpected "
+-- 
+2.8.1
+
+
+From 5469d46bb74c3cdafa98fcedf6898aa3e23d5bfb Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Fri, 10 Jul 2015 14:48:38 +0200
+Subject: [PATCH 14/40] CVE-2015-5370: s3:rpc_client: protect
+ rpc_api_pipe_got_pdu() against too large payloads
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+(cherry picked from commit 98182969e761429e577064e1a0fd5cbc6b50d7d9)
+---
+ source3/rpc_client/cli_pipe.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c
+index 6a22d38..755b458 100644
+--- a/source3/rpc_client/cli_pipe.c
++++ b/source3/rpc_client/cli_pipe.c
+@@ -1007,6 +1007,11 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
+ 		return;
+ 	}
+ 
++	if (state->reply_pdu_offset + rdata.length > MAX_RPC_DATA_SIZE) {
++		tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
++		return;
++	}
++
+ 	/* Now copy the data portion out of the pdu into rbuf. */
+ 	if (state->reply_pdu.length < state->reply_pdu_offset + rdata.length) {
+ 		if (!data_blob_realloc(NULL, &state->reply_pdu,
+-- 
+2.8.1
+
+
+From 475bcafcfeeae3037e8a70b69b5638f260a33fcb Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Tue, 7 Jul 2015 22:51:18 +0200
+Subject: [PATCH 15/40] CVE-2015-5370: s3:rpc_client: verify auth_{type,level}
+ in rpc_pipe_bind_step_one_done()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+(cherry picked from commit df51c22bea7fbf906613ceb160f16f298b2e3106)
+---
+ source3/rpc_client/cli_pipe.c | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c
+index 755b458..1c4ff01 100644
+--- a/source3/rpc_client/cli_pipe.c
++++ b/source3/rpc_client/cli_pipe.c
+@@ -2039,6 +2039,21 @@ static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
+ 			tevent_req_nterror(req, status);
+ 			return;
+ 		}
++
++		if (auth.auth_type != pauth->auth_type) {
++			DEBUG(0, (__location__ " Auth type %u mismatch expected %u.\n",
++				  auth.auth_type, pauth->auth_type));
++			tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
++			return;
++		}
++
++		if (auth.auth_level != pauth->auth_level) {
++			DEBUG(0, (__location__ " Auth level %u mismatch expected %u.\n",
++				  auth.auth_level, pauth->auth_level));
++			tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
++			return;
++		}
++
+ 		break;
+ 	}
+ 
+-- 
+2.8.1
+
+
+From 245ea2177f05b5b92464f1ef85336d9ec62376da Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Tue, 7 Jul 2015 13:05:01 +0200
+Subject: [PATCH 16/40] CVE-2015-5370: s3:rpc_server: make use of
+ dcerpc_pull_auth_trailer() in api_pipe_{bind_req,alter_context,bind_auth3}()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+(cherry picked from commit 2a92546590a78760d2fe0e63067a3888dbce53be)
+---
+ source3/rpc_server/srv_pipe.c | 62 +++++++++----------------------------------
+ 1 file changed, 13 insertions(+), 49 deletions(-)
+
+diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
+index 0ab7dc6..40b1b8e 100644
+--- a/source3/rpc_server/srv_pipe.c
++++ b/source3/rpc_server/srv_pipe.c
+@@ -1012,25 +1012,12 @@ static bool api_pipe_bind_req(struct pipes_struct *p,
+ 	 * Check if this is an authenticated bind request.
+ 	 */
+ 	if (pkt->auth_length) {
+-		/* Quick length check. Won't catch a bad auth footer,
+-		 * prevents overrun. */
+-
+-		if (pkt->frag_length < RPC_HEADER_LEN +
+-					DCERPC_AUTH_TRAILER_LENGTH +
+-					pkt->auth_length) {
+-			DEBUG(0,("api_pipe_bind_req: auth_len (%u) "
+-				"too long for fragment %u.\n",
+-				(unsigned int)pkt->auth_length,
+-				(unsigned int)pkt->frag_length));
+-			goto err_exit;
+-		}
+-
+ 		/*
+ 		 * Decode the authentication verifier.
+ 		 */
+-		status = dcerpc_pull_dcerpc_auth(pkt,
+-						 &pkt->u.bind.auth_info,
+-						 &auth_info, p->endian);
++		status = dcerpc_pull_auth_trailer(pkt, pkt,
++						  &pkt->u.bind.auth_info,
++						  &auth_info, NULL, true);
+ 		if (!NT_STATUS_IS_OK(status)) {
+ 			DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
+ 			goto err_exit;
+@@ -1233,23 +1220,13 @@ bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt)
+ 		goto err;
+ 	}
+ 
+-	/* Ensure there's enough data for an authenticated request. */
+-	if (pkt->frag_length < RPC_HEADER_LEN
+-				+ DCERPC_AUTH_TRAILER_LENGTH
+-				+ pkt->auth_length) {
+-			DEBUG(0,("api_pipe_ntlmssp_auth_process: auth_len "
+-				"%u is too large.\n",
+-                        (unsigned int)pkt->auth_length));
+-		goto err;
+-	}
+-
+ 	/*
+ 	 * Decode the authentication verifier response.
+ 	 */
+ 
+-	status = dcerpc_pull_dcerpc_auth(pkt,
+-					 &pkt->u.auth3.auth_info,
+-					 &auth_info, p->endian);
++	status = dcerpc_pull_auth_trailer(pkt, pkt,
++					  &pkt->u.auth3.auth_info,
++					  &auth_info, NULL, true);
+ 	if (!NT_STATUS_IS_OK(status)) {
+ 		DEBUG(0, ("Failed to unmarshall dcerpc_auth.\n"));
+ 		goto err;
+@@ -1382,34 +1359,21 @@ static bool api_pipe_alter_context(struct pipes_struct *p,
+ 	 * Check if this is an authenticated alter context request.
+ 	 */
+ 	if (pkt->auth_length) {
+-		/* Quick length check. Won't catch a bad auth footer,
+-		 * prevents overrun. */
+-
+-		if (pkt->frag_length < RPC_HEADER_LEN +
+-					DCERPC_AUTH_TRAILER_LENGTH +
+-					pkt->auth_length) {
+-			DEBUG(0,("api_pipe_alter_context: auth_len (%u) "
+-				"too long for fragment %u.\n",
+-				(unsigned int)pkt->auth_length,
+-				(unsigned int)pkt->frag_length ));
++		/* We can only finish if the pipe is unbound for now */
++		if (p->pipe_bound) {
++			DEBUG(0, (__location__ ": Pipe already bound, "
++				  "Altering Context not yet supported!\n"));
+ 			goto err_exit;
+ 		}
+ 
+-		status = dcerpc_pull_dcerpc_auth(pkt,
+-						 &pkt->u.bind.auth_info,
+-						 &auth_info, p->endian);
++		status = dcerpc_pull_auth_trailer(pkt, pkt,
++						  &pkt->u.bind.auth_info,
++						  &auth_info, NULL, true);
+ 		if (!NT_STATUS_IS_OK(status)) {
+ 			DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
+ 			goto err_exit;
+ 		}
+ 
+-		/* We can only finish if the pipe is unbound for now */
+-		if (p->pipe_bound) {
+-			DEBUG(0, (__location__ ": Pipe already bound, "
+-				  "Altering Context not yet supported!\n"));
+-			goto err_exit;
+-		}
+-
+ 		if (auth_info.auth_type != p->auth.auth_type) {
+ 			DEBUG(0, ("Auth type mismatch! Client sent %d, "
+ 				  "but auth was started as type %d!\n",
+-- 
+2.8.1
+
+
+From cd9a734cd58c0e5c16576e7714d7651b347360e1 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Wed, 23 Dec 2015 12:38:55 +0100
+Subject: [PATCH 17/40] CVE-2015-5370: s3:rpc_server: let a failing
+ sec_verification_trailer mark the connection as broken
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+(cherry picked from commit 189c0fbb7a3405f0893f23e5b8d755d259f98eaf)
+---
+ source3/rpc_server/srv_pipe.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
+index 40b1b8e..da9b91c 100644
+--- a/source3/rpc_server/srv_pipe.c
++++ b/source3/rpc_server/srv_pipe.c
+@@ -1663,6 +1663,7 @@ static bool api_pipe_request(struct pipes_struct *p,
+ 
+ 	if (!srv_pipe_check_verification_trailer(p, pkt, pipe_fns)) {
+ 		DEBUG(1, ("srv_pipe_check_verification_trailer: failed\n"));
++		set_incoming_fault(p);
+ 		setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_ACCESS_DENIED));
+ 		data_blob_free(&p->out_data.rdata);
+ 		TALLOC_FREE(frame);
+-- 
+2.8.1
+
+
+From f36526b298905aa6c44d74e0af432f0afcc586d9 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Tue, 7 Jul 2015 13:05:01 +0200
+Subject: [PATCH 18/40] CVE-2015-5370: s3:rpc_server: don't ignore failures of
+ dcerpc_push_ncacn_packet()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+(cherry picked from commit 25bf597124f217c55b5ca71a5ea9cb0ea83943e5)
+---
+ source3/rpc_server/srv_pipe.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
+index da9b91c..71b4665 100644
+--- a/source3/rpc_server/srv_pipe.c
++++ b/source3/rpc_server/srv_pipe.c
+@@ -1152,6 +1152,7 @@ static bool api_pipe_bind_req(struct pipes_struct *p,
+ 	if (!NT_STATUS_IS_OK(status)) {
+ 		DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
+ 			  nt_errstr(status)));
++		goto err_exit;
+ 	}
+ 
+ 	if (auth_resp.length) {
+@@ -1469,6 +1470,7 @@ static bool api_pipe_alter_context(struct pipes_struct *p,
+ 	if (!NT_STATUS_IS_OK(status)) {
+ 		DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
+ 			  nt_errstr(status)));
++		goto err_exit;
+ 	}
+ 
+ 	if (auth_resp.length) {
+-- 
+2.8.1
+
+
+From 7793fd5bb25cab8cff2e868cb9a063b6f0d81c2c Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Tue, 7 Jul 2015 13:05:01 +0200
+Subject: [PATCH 19/40] CVE-2015-5370: s3:rpc_server: don't allow auth3 if the
+ authentication was already finished
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+(cherry picked from commit 69280e6acef7c3941407d4308b659c5e90ed702d)
+---
+ source3/rpc_server/srv_pipe.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
+index 71b4665..4e5b50d4 100644
+--- a/source3/rpc_server/srv_pipe.c
++++ b/source3/rpc_server/srv_pipe.c
+@@ -1216,8 +1216,15 @@ bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt)
+ 
+ 	DEBUG(5, ("api_pipe_bind_auth3: decode request. %d\n", __LINE__));
+ 
++	/* We can only finish if the pipe is unbound for now */
++	if (p->pipe_bound) {
++		DEBUG(0, (__location__ ": Pipe already bound, "
++			  "AUTH3 not supported!\n"));
++		goto err;
++	}
++
+ 	if (pkt->auth_length == 0) {
+-		DEBUG(0, ("No auth field sent for bind request!\n"));
++		DEBUG(1, ("No auth field sent for auth3 request!\n"));
+ 		goto err;
+ 	}
+ 
+-- 
+2.8.1
+
+
+From af1cbdcd1342e51ba77ed5732d42269381b2d7f7 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Tue, 14 Jul 2015 16:18:45 +0200
+Subject: [PATCH 20/40] CVE-2015-5370: s3:rpc_server: let a failing auth3 mark
+ the authentication as invalid
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+(cherry picked from commit 8c96ef7b4fbd925607b26d351b14ad9a95febd88)
+---
+ source3/rpc_server/srv_pipe.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
+index 4e5b50d4..d28ba8e 100644
+--- a/source3/rpc_server/srv_pipe.c
++++ b/source3/rpc_server/srv_pipe.c
+@@ -1304,7 +1304,7 @@ bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt)
+ 	return true;
+ 
+ err:
+-
++	p->pipe_bound = false;
+ 	TALLOC_FREE(p->auth.auth_ctx);
+ 	return false;
+ }
+-- 
+2.8.1
+
+
+From 4f86070a06b19bf901c5e3522ddcda483f580eea Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Tue, 7 Jul 2015 13:05:01 +0200
+Subject: [PATCH 21/40] CVE-2015-5370: s3:rpc_server: make sure auth_level
+ isn't changed by alter_context or auth3
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+(cherry picked from commit 63d21d2546a1064be73582a499ec15b0e11e2708)
+---
+ source3/rpc_server/srv_pipe.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
+index d28ba8e..1b81a4c 100644
+--- a/source3/rpc_server/srv_pipe.c
++++ b/source3/rpc_server/srv_pipe.c
+@@ -1252,6 +1252,13 @@ bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt)
+ 		goto err;
+ 	}
+ 
++	if (auth_info.auth_level != p->auth.auth_level) {
++		DEBUG(1, ("Auth level mismatch! Client sent %d, "
++			  "but auth was started as level %d!\n",
++			  auth_info.auth_level, p->auth.auth_level));
++		goto err;
++	}
++
+ 	switch (auth_info.auth_type) {
+ 	case DCERPC_AUTH_TYPE_NTLMSSP:
+ 		ntlmssp_ctx = talloc_get_type_abort(p->auth.auth_ctx,
+@@ -1389,6 +1396,12 @@ static bool api_pipe_alter_context(struct pipes_struct *p,
+ 			goto err_exit;
+ 		}
+ 
++		if (auth_info.auth_level != p->auth.auth_level) {
++			DEBUG(0, ("Auth level mismatch! Client sent %d, "
++				  "but auth was started as level %d!\n",
++				  auth_info.auth_level, p->auth.auth_level));
++			goto err_exit;
++		}
+ 
+ 		switch (auth_info.auth_type) {
+ 		case DCERPC_AUTH_TYPE_SPNEGO:
+-- 
+2.8.1
+
+
+From 38de42a26c52d9dbd9d01849bae7b78ac187ced6 Mon Sep 17 00:00:00 2001
+From: Jeremy Allison <jra at samba.org>
+Date: Tue, 7 Jul 2015 09:15:39 +0200
+Subject: [PATCH 22/40] CVE-2015-5370: s3:rpc_server: ensure that the message
+ ordering doesn't violate the spec
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The first pdu is always a BIND.
+
+REQUEST pdus are only allowed once the authentication
+is finished.
+
+A simple anonymous authentication is finished after the BIND.
+Real authentication may need additional ALTER or AUTH3 exchanges.
+
+Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344
+
+Signed-off-by: Jeremy Allison <jra at samba.org>
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+(cherry picked from commit 0239bfa562ee303c4ac204375b3c66ca287f6cb0)
+---
+ source3/include/ntdomain.h        |  7 ++++++
+ source3/rpc_server/rpc_ncacn_np.c |  1 +
+ source3/rpc_server/rpc_server.c   |  1 +
+ source3/rpc_server/srv_pipe.c     | 51 ++++++++++++++++++++++++++++++++++-----
+ 4 files changed, 54 insertions(+), 6 deletions(-)
+
+diff --git a/source3/include/ntdomain.h b/source3/include/ntdomain.h
+index 650f1d0..b3c5451 100644
+--- a/source3/include/ntdomain.h
++++ b/source3/include/ntdomain.h
+@@ -139,6 +139,13 @@ struct pipes_struct {
+ 	bool pipe_bound;
+ 
+ 	/*
++	 * States we can be in.
++	 */
++	bool allow_alter;
++	bool allow_bind;
++	bool allow_auth3;
++
++	/*
+ 	 * Set the DCERPC_FAULT to return.
+ 	 */
+ 
+diff --git a/source3/rpc_server/rpc_ncacn_np.c b/source3/rpc_server/rpc_ncacn_np.c
+index efdee27..f2e9d10 100644
+--- a/source3/rpc_server/rpc_ncacn_np.c
++++ b/source3/rpc_server/rpc_ncacn_np.c
+@@ -171,6 +171,7 @@ struct pipes_struct *make_internal_rpc_pipe_p(TALLOC_CTX *mem_ctx,
+ 
+ 	p->syntax = *syntax;
+ 	p->transport = NCALRPC;
++	p->allow_bind = true;
+ 
+ 	DEBUG(4,("Created internal pipe %s (pipes_open=%d)\n",
+ 		 get_pipe_name_from_syntax(talloc_tos(), syntax), pipes_open));
+diff --git a/source3/rpc_server/rpc_server.c b/source3/rpc_server/rpc_server.c
+index 8ec55bb..376d26a 100644
+--- a/source3/rpc_server/rpc_server.c
++++ b/source3/rpc_server/rpc_server.c
+@@ -102,6 +102,7 @@ static int make_server_pipes_struct(TALLOC_CTX *mem_ctx,
+ 	p->syntax = id;
+ 	p->transport = transport;
+ 	p->ncalrpc_as_system = ncalrpc_as_system;
++	p->allow_bind = true;
+ 
+ 	p->mem_ctx = talloc_named(p, 0, "pipe %s %p", pipe_name, p);
+ 	if (!p->mem_ctx) {
+diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
+index 1b81a4c..41111aa 100644
+--- a/source3/rpc_server/srv_pipe.c
++++ b/source3/rpc_server/srv_pipe.c
+@@ -279,6 +279,9 @@ static bool setup_bind_nak(struct pipes_struct *p, struct ncacn_packet *pkt)
+ 	p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
+ 	p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
+ 	p->pipe_bound = False;
++	p->allow_bind = false;
++	p->allow_alter = false;
++	p->allow_auth3 = false;
+ 
+ 	return True;
+ }
+@@ -828,6 +831,11 @@ static NTSTATUS pipe_auth_verify_final(struct pipes_struct *p)
+ 	void *mech_ctx;
+ 	NTSTATUS status;
+ 
++	if (p->auth.auth_type == DCERPC_AUTH_TYPE_NONE) {
++		p->pipe_bound = true;
++		return NT_STATUS_OK;
++	}
++
+ 	switch (p->auth.auth_type) {
+ 	case DCERPC_AUTH_TYPE_NTLMSSP:
+ 		ntlmssp_ctx = talloc_get_type_abort(p->auth.auth_ctx,
+@@ -919,13 +927,11 @@ static bool api_pipe_bind_req(struct pipes_struct *p,
+ 	DATA_BLOB auth_resp = data_blob_null;
+ 	DATA_BLOB auth_blob = data_blob_null;
+ 
+-	/* No rebinds on a bound pipe - use alter context. */
+-	if (p->pipe_bound) {
+-		DEBUG(2,("api_pipe_bind_req: rejecting bind request on bound "
+-			 "pipe %s.\n",
+-			 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
++	if (!p->allow_bind) {
++		DEBUG(2,("Pipe not in allow bind state\n"));
+ 		return setup_bind_nak(p, pkt);
+ 	}
++	p->allow_bind = false;
+ 
+ 	if (pkt->u.bind.num_contexts == 0) {
+ 		DEBUG(0, ("api_pipe_bind_req: no rpc contexts around\n"));
+@@ -1192,6 +1198,22 @@ static bool api_pipe_bind_req(struct pipes_struct *p,
+ 	p->out_data.current_pdu_sent = 0;
+ 
+ 	TALLOC_FREE(auth_blob.data);
++
++	if (bind_ack_ctx.result == 0) {
++		p->allow_alter = true;
++		p->allow_auth3 = true;
++		if (p->auth.auth_type == DCERPC_AUTH_TYPE_NONE) {
++			status = pipe_auth_verify_final(p);
++			if (!NT_STATUS_IS_OK(status)) {
++				DEBUG(0, ("pipe_auth_verify_final failed: %s\n",
++					  nt_errstr(status)));
++				goto err_exit;
++			}
++		}
++	} else {
++		goto err_exit;
++	}
++
+ 	return True;
+ 
+   err_exit:
+@@ -1216,6 +1238,11 @@ bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt)
+ 
+ 	DEBUG(5, ("api_pipe_bind_auth3: decode request. %d\n", __LINE__));
+ 
++	if (!p->allow_auth3) {
++		DEBUG(1, ("Pipe not in allow auth3 state.\n"));
++		goto err;
++	}
++
+ 	/* We can only finish if the pipe is unbound for now */
+ 	if (p->pipe_bound) {
+ 		DEBUG(0, (__location__ ": Pipe already bound, "
+@@ -1312,6 +1339,10 @@ bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt)
+ 
+ err:
+ 	p->pipe_bound = false;
++	p->allow_bind = false;
++	p->allow_alter = false;
++	p->allow_auth3 = false;
++
+ 	TALLOC_FREE(p->auth.auth_ctx);
+ 	return false;
+ }
+@@ -1338,6 +1369,11 @@ static bool api_pipe_alter_context(struct pipes_struct *p,
+ 
+ 	DEBUG(5,("api_pipe_alter_context: make response. %d\n", __LINE__));
+ 
++	if (!p->allow_alter) {
++		DEBUG(1, ("Pipe not in allow alter state.\n"));
++		goto err_exit;
++	}
++
+ 	if (pkt->u.bind.assoc_group_id != 0) {
+ 		assoc_gid = pkt->u.bind.assoc_group_id;
+ 	} else {
+@@ -1363,7 +1399,6 @@ static bool api_pipe_alter_context(struct pipes_struct *p,
+ 		bind_ack_ctx.reason = 0;
+ 		bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
+ 	} else {
+-		p->pipe_bound = False;
+ 		/* Rejection reason: abstract syntax not supported */
+ 		bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
+ 		bind_ack_ctx.reason = DCERPC_BIND_REASON_ASYNTAX;
+@@ -1826,6 +1861,10 @@ void set_incoming_fault(struct pipes_struct *p)
+ 	p->in_data.pdu.length = 0;
+ 	p->fault_state = DCERPC_FAULT_CANT_PERFORM;
+ 
++	p->allow_alter = false;
++	p->allow_auth3 = false;
++	p->pipe_bound = false;
++
+ 	DEBUG(10, ("Setting fault state\n"));
+ }
+ 
+-- 
+2.8.1
+
+
+From 671fee9ad5c6ee373d28ea1244966f82ba3ec7d8 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Tue, 7 Jul 2015 16:06:59 +0200
+Subject: [PATCH 23/40] CVE-2015-5370: s3:rpc_server: use 'alter' instead of
+ 'bind' for variables in api_pipe_alter_context()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+(cherry picked from commit cdefee174d2f8920323e9e62966df4f4ced49ed3)
+---
+ source3/rpc_server/srv_pipe.c | 32 ++++++++++++++++----------------
+ 1 file changed, 16 insertions(+), 16 deletions(-)
+
+diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
+index 41111aa..382d94a 100644
+--- a/source3/rpc_server/srv_pipe.c
++++ b/source3/rpc_server/srv_pipe.c
+@@ -1359,7 +1359,7 @@ static bool api_pipe_alter_context(struct pipes_struct *p,
+ 	uint16 assoc_gid;
+ 	NTSTATUS status;
+ 	union dcerpc_payload u;
+-	struct dcerpc_ack_ctx bind_ack_ctx;
++	struct dcerpc_ack_ctx alter_ack_ctx;
+ 	DATA_BLOB auth_resp = data_blob_null;
+ 	DATA_BLOB auth_blob = data_blob_null;
+ 	int pad_len = 0;
+@@ -1374,8 +1374,8 @@ static bool api_pipe_alter_context(struct pipes_struct *p,
+ 		goto err_exit;
+ 	}
+ 
+-	if (pkt->u.bind.assoc_group_id != 0) {
+-		assoc_gid = pkt->u.bind.assoc_group_id;
++	if (pkt->u.alter.assoc_group_id != 0) {
++		assoc_gid = pkt->u.alter.assoc_group_id;
+ 	} else {
+ 		assoc_gid = 0x53f0;
+ 	}
+@@ -1385,24 +1385,24 @@ static bool api_pipe_alter_context(struct pipes_struct *p,
+ 	 */
+ 
+ 	/* If the requested abstract synt uuid doesn't match our client pipe,
+-		reject the bind_ack & set the transfer interface synt to all 0's,
++		reject the alter_ack & set the transfer interface synt to all 0's,
+ 		ver 0 (observed when NT5 attempts to bind to abstract interfaces
+ 		unknown to NT4)
+ 		Needed when adding entries to a DACL from NT5 - SK */
+ 
+ 	if (check_bind_req(p,
+-			&pkt->u.bind.ctx_list[0].abstract_syntax,
+-			&pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
+-			pkt->u.bind.ctx_list[0].context_id)) {
++			&pkt->u.alter.ctx_list[0].abstract_syntax,
++			&pkt->u.alter.ctx_list[0].transfer_syntaxes[0],
++			pkt->u.alter.ctx_list[0].context_id)) {
+ 
+-		bind_ack_ctx.result = 0;
+-		bind_ack_ctx.reason = 0;
+-		bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
++		alter_ack_ctx.result = 0;
++		alter_ack_ctx.reason = 0;
++		alter_ack_ctx.syntax = pkt->u.alter.ctx_list[0].transfer_syntaxes[0];
+ 	} else {
+ 		/* Rejection reason: abstract syntax not supported */
+-		bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
+-		bind_ack_ctx.reason = DCERPC_BIND_REASON_ASYNTAX;
+-		bind_ack_ctx.syntax = null_ndr_syntax_id;
++		alter_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
++		alter_ack_ctx.reason = DCERPC_BIND_REASON_ASYNTAX;
++		alter_ack_ctx.syntax = null_ndr_syntax_id;
+ 	}
+ 
+ 	/*
+@@ -1417,7 +1417,7 @@ static bool api_pipe_alter_context(struct pipes_struct *p,
+ 		}
+ 
+ 		status = dcerpc_pull_auth_trailer(pkt, pkt,
+-						  &pkt->u.bind.auth_info,
++						  &pkt->u.alter.auth_info,
+ 						  &auth_info, NULL, true);
+ 		if (!NT_STATUS_IS_OK(status)) {
+ 			DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
+@@ -1503,7 +1503,7 @@ static bool api_pipe_alter_context(struct pipes_struct *p,
+ 	u.alter_resp.secondary_address_size = 1;
+ 
+ 	u.alter_resp.num_results = 1;
+-	u.alter_resp.ctx_list = &bind_ack_ctx;
++	u.alter_resp.ctx_list = &alter_ack_ctx;
+ 
+ 	/* NOTE: We leave the auth_info empty so we can calculate the padding
+ 	 * later and then append the auth_info --simo */
+@@ -1523,7 +1523,7 @@ static bool api_pipe_alter_context(struct pipes_struct *p,
+ 					  &u,
+ 					  &p->out_data.frag);
+ 	if (!NT_STATUS_IS_OK(status)) {
+-		DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
++		DEBUG(0, ("Failed to marshall alter_resp packet. (%s)\n",
+ 			  nt_errstr(status)));
+ 		goto err_exit;
+ 	}
+-- 
+2.8.1
+
+
+From 1fe6ef29eb84aac7c3359dc56d26c86387750f99 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Tue, 7 Jul 2015 16:06:59 +0200
+Subject: [PATCH 24/40] CVE-2015-5370: s3:rpc_server: verify presentation
+ context arrays
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+(cherry picked from commit 1e6b4abac14840e4cee1afc5d4811b0f0277eade)
+---
+ source3/rpc_server/srv_pipe.c | 17 ++++++++++++++++-
+ 1 file changed, 16 insertions(+), 1 deletion(-)
+
+diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
+index 382d94a..335af2a 100644
+--- a/source3/rpc_server/srv_pipe.c
++++ b/source3/rpc_server/srv_pipe.c
+@@ -934,7 +934,12 @@ static bool api_pipe_bind_req(struct pipes_struct *p,
+ 	p->allow_bind = false;
+ 
+ 	if (pkt->u.bind.num_contexts == 0) {
+-		DEBUG(0, ("api_pipe_bind_req: no rpc contexts around\n"));
++		DEBUG(1, ("api_pipe_bind_req: no rpc contexts around\n"));
++		goto err_exit;
++	}
++
++	if (pkt->u.bind.ctx_list[0].num_transfer_syntaxes == 0) {
++		DEBUG(1, ("api_pipe_bind_req: no transfer syntaxes around\n"));
+ 		goto err_exit;
+ 	}
+ 
+@@ -1374,6 +1379,16 @@ static bool api_pipe_alter_context(struct pipes_struct *p,
+ 		goto err_exit;
+ 	}
+ 
++	if (pkt->u.alter.num_contexts == 0) {
++		DEBUG(1, ("api_pipe_alter_context: no rpc contexts around\n"));
++		goto err_exit;
++	}
++
++	if (pkt->u.alter.ctx_list[0].num_transfer_syntaxes == 0) {
++		DEBUG(1, ("api_pipe_alter_context: no transfer syntaxes around\n"));
++		goto err_exit;
++	}
++
+ 	if (pkt->u.alter.assoc_group_id != 0) {
+ 		assoc_gid = pkt->u.alter.assoc_group_id;
+ 	} else {
+-- 
+2.8.1
+
+
+From 044728996d6ff3a0d7dd7ab03db70c37570db9c0 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Tue, 7 Jul 2015 16:06:59 +0200
+Subject: [PATCH 25/40] CVE-2015-5370: s3:rpc_server: make use of
+ dcerpc_verify_ncacn_packet_header() to verify incoming pdus
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+(cherry picked from commit e39fdceb25fc75b6f8c77c097bf8dbd2f4286618)
+---
+ source3/rpc_server/srv_pipe.c | 81 +++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 81 insertions(+)
+
+diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
+index 335af2a..2f404b4 100644
+--- a/source3/rpc_server/srv_pipe.c
++++ b/source3/rpc_server/srv_pipe.c
+@@ -42,6 +42,7 @@
+ #include "auth.h"
+ #include "ntdomain.h"
+ #include "rpc_server/srv_pipe.h"
++#include "../librpc/gen_ndr/ndr_dcerpc.h"
+ #include "../librpc/ndr/ndr_dcerpc.h"
+ #include "../librpc/gen_ndr/ndr_samr.h"
+ #include "../librpc/gen_ndr/ndr_lsa.h"
+@@ -933,6 +934,25 @@ static bool api_pipe_bind_req(struct pipes_struct *p,
+ 	}
+ 	p->allow_bind = false;
+ 
++	status = dcerpc_verify_ncacn_packet_header(pkt,
++			DCERPC_PKT_BIND,
++			pkt->u.bind.auth_info.length,
++			0, /* required flags */
++			DCERPC_PFC_FLAG_FIRST |
++			DCERPC_PFC_FLAG_LAST |
++			DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
++			0x08 | /* this is not defined, but should be ignored */
++			DCERPC_PFC_FLAG_CONC_MPX |
++			DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
++			DCERPC_PFC_FLAG_MAYBE |
++			DCERPC_PFC_FLAG_OBJECT_UUID);
++	if (!NT_STATUS_IS_OK(status)) {
++		DEBUG(1, ("api_pipe_bind_req: invalid pdu: %s\n",
++			  nt_errstr(status)));
++		NDR_PRINT_DEBUG(ncacn_packet, pkt);
++		goto err_exit;
++	}
++
+ 	if (pkt->u.bind.num_contexts == 0) {
+ 		DEBUG(1, ("api_pipe_bind_req: no rpc contexts around\n"));
+ 		goto err_exit;
+@@ -1248,6 +1268,25 @@ bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt)
+ 		goto err;
+ 	}
+ 
++	status = dcerpc_verify_ncacn_packet_header(pkt,
++			DCERPC_PKT_AUTH3,
++			pkt->u.auth3.auth_info.length,
++			0, /* required flags */
++			DCERPC_PFC_FLAG_FIRST |
++			DCERPC_PFC_FLAG_LAST |
++			DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
++			0x08 | /* this is not defined, but should be ignored */
++			DCERPC_PFC_FLAG_CONC_MPX |
++			DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
++			DCERPC_PFC_FLAG_MAYBE |
++			DCERPC_PFC_FLAG_OBJECT_UUID);
++	if (!NT_STATUS_IS_OK(status)) {
++		DEBUG(1, ("api_pipe_bind_auth3: invalid pdu: %s\n",
++			  nt_errstr(status)));
++		NDR_PRINT_DEBUG(ncacn_packet, pkt);
++		goto err;
++	}
++
+ 	/* We can only finish if the pipe is unbound for now */
+ 	if (p->pipe_bound) {
+ 		DEBUG(0, (__location__ ": Pipe already bound, "
+@@ -1379,6 +1418,25 @@ static bool api_pipe_alter_context(struct pipes_struct *p,
+ 		goto err_exit;
+ 	}
+ 
++	status = dcerpc_verify_ncacn_packet_header(pkt,
++			DCERPC_PKT_ALTER,
++			pkt->u.alter.auth_info.length,
++			0, /* required flags */
++			DCERPC_PFC_FLAG_FIRST |
++			DCERPC_PFC_FLAG_LAST |
++			DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
++			0x08 | /* this is not defined, but should be ignored */
++			DCERPC_PFC_FLAG_CONC_MPX |
++			DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
++			DCERPC_PFC_FLAG_MAYBE |
++			DCERPC_PFC_FLAG_OBJECT_UUID);
++	if (!NT_STATUS_IS_OK(status)) {
++		DEBUG(1, ("api_pipe_alter_context: invalid pdu: %s\n",
++			  nt_errstr(status)));
++		NDR_PRINT_DEBUG(ncacn_packet, pkt);
++		goto err_exit;
++	}
++
+ 	if (pkt->u.alter.num_contexts == 0) {
+ 		DEBUG(1, ("api_pipe_alter_context: no rpc contexts around\n"));
+ 		goto err_exit;
+@@ -1923,6 +1981,29 @@ static bool process_request_pdu(struct pipes_struct *p, struct ncacn_packet *pkt
+ 		return False;
+ 	}
+ 
++	/*
++	 * We don't ignore DCERPC_PFC_FLAG_PENDING_CANCEL.
++	 * TODO: we can reject it with DCERPC_FAULT_NO_CALL_ACTIVE later.
++	 */
++	status = dcerpc_verify_ncacn_packet_header(pkt,
++			DCERPC_PKT_REQUEST,
++			pkt->u.request.stub_and_verifier.length,
++			0, /* required_flags */
++			DCERPC_PFC_FLAG_FIRST |
++			DCERPC_PFC_FLAG_LAST |
++			0x08 | /* this is not defined, but should be ignored */
++			DCERPC_PFC_FLAG_CONC_MPX |
++			DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
++			DCERPC_PFC_FLAG_MAYBE |
++			DCERPC_PFC_FLAG_OBJECT_UUID);
++	if (!NT_STATUS_IS_OK(status)) {
++		DEBUG(1, ("process_request_pdu: invalid pdu: %s\n",
++			  nt_errstr(status)));
++		NDR_PRINT_DEBUG(ncacn_packet, pkt);
++		set_incoming_fault(p);
++		return false;
++	}
++
+ 	/* Store the opnum */
+ 	p->opnum = pkt->u.request.opnum;
+ 
+-- 
+2.8.1
+
+
+From 27ab776f3562ea32c995d6c76ab8ea9d565ce116 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Wed, 23 Dec 2015 12:40:58 +0100
+Subject: [PATCH 26/40] CVE-2015-5370: s3:rpc_server: disconnect the connection
+ after a fatal FAULT pdu
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+(cherry picked from commit 664d7ace0e68b42d2de99583757e0a985647eb4b)
+---
+ source3/rpc_server/rpc_server.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/source3/rpc_server/rpc_server.c b/source3/rpc_server/rpc_server.c
+index 376d26a..3ba83e0 100644
+--- a/source3/rpc_server/rpc_server.c
++++ b/source3/rpc_server/rpc_server.c
+@@ -664,6 +664,12 @@ static void named_pipe_packet_done(struct tevent_req *subreq)
+ 		goto fail;
+ 	}
+ 
++	if (npc->p->fault_state != 0) {
++		DEBUG(2, ("Disconnect after fault\n"));
++		sys_errno = EINVAL;
++		goto fail;
++	}
++
+ 	/* clear out any data that may have been left around */
+ 	npc->count = 0;
+ 	TALLOC_FREE(npc->iov);
+@@ -1392,6 +1398,12 @@ static void dcerpc_ncacn_packet_done(struct tevent_req *subreq)
+ 		goto fail;
+ 	}
+ 
++	if (ncacn_conn->p->fault_state != 0) {
++		DEBUG(2, ("Disconnect after fault\n"));
++		sys_errno = EINVAL;
++		goto fail;
++	}
++
+ 	/* clear out any data that may have been left around */
+ 	ncacn_conn->count = 0;
+ 	TALLOC_FREE(ncacn_conn->iov);
+-- 
+2.8.1
+
+
+From 865b9bec3d7ddc57042eb4bf65d4f797427337c3 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Wed, 23 Dec 2015 12:38:55 +0100
+Subject: [PATCH 27/40] CVE-2015-5370: s3:rpc_server: let a failing BIND mark
+ the connection as broken
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+(cherry picked from commit 8d97085efd8782e48d0f1162e3f56756acb99472)
+---
+ source3/rpc_server/srv_pipe.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
+index 2f404b4..6275190 100644
+--- a/source3/rpc_server/srv_pipe.c
++++ b/source3/rpc_server/srv_pipe.c
+@@ -276,6 +276,7 @@ static bool setup_bind_nak(struct pipes_struct *p, struct ncacn_packet *pkt)
+ 	p->out_data.data_sent_length = 0;
+ 	p->out_data.current_pdu_sent = 0;
+ 
++	set_incoming_fault(p);
+ 	TALLOC_FREE(p->auth.auth_ctx);
+ 	p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
+ 	p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
+-- 
+2.8.1
+
+
+From 0c752e2760aa5d2a01aaafe06bf864682f8459f5 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Wed, 23 Dec 2015 12:38:55 +0100
+Subject: [PATCH 28/40] CVE-2015-5370: s3:rpc_server: use
+ DCERPC_NCA_S_PROTO_ERROR FAULTs for protocol errors
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+(cherry picked from commit d30363f08efb81b22055d4445977c96df3737adf)
+---
+ source3/rpc_server/srv_pipe.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
+index 6275190..3fb8855 100644
+--- a/source3/rpc_server/srv_pipe.c
++++ b/source3/rpc_server/srv_pipe.c
+@@ -1933,7 +1933,7 @@ void set_incoming_fault(struct pipes_struct *p)
+ 	data_blob_free(&p->in_data.data);
+ 	p->in_data.pdu_needed_len = 0;
+ 	p->in_data.pdu.length = 0;
+-	p->fault_state = DCERPC_FAULT_CANT_PERFORM;
++	p->fault_state = DCERPC_NCA_S_PROTO_ERROR;
+ 
+ 	p->allow_alter = false;
+ 	p->allow_auth3 = false;
+@@ -2254,7 +2254,7 @@ done:
+ 			 "pipe %s\n", get_pipe_name_from_syntax(talloc_tos(),
+ 								&p->syntax)));
+ 		set_incoming_fault(p);
+-		setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
++		setup_fault_pdu(p, NT_STATUS(DCERPC_NCA_S_PROTO_ERROR));
+ 		TALLOC_FREE(pkt);
+ 	} else {
+ 		/*
+-- 
+2.8.1
+
+
+From 687e5def17881bd5ac8b3c1cf1653530ae227ea2 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Sat, 11 Jul 2015 10:58:07 +0200
+Subject: [PATCH 29/40] CVE-2015-5370: s3:librpc/rpc: remove unused
+ dcerpc_pull_dcerpc_auth()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+(cherry picked from commit 02aef978ff8f16009a52c2d981d414d019bc8dd9)
+---
+ source3/librpc/rpc/dcerpc.h         |  4 ----
+ source3/librpc/rpc/dcerpc_helpers.c | 41 -------------------------------------
+ 2 files changed, 45 deletions(-)
+
+diff --git a/source3/librpc/rpc/dcerpc.h b/source3/librpc/rpc/dcerpc.h
+index e7cca9e..9452e85 100644
+--- a/source3/librpc/rpc/dcerpc.h
++++ b/source3/librpc/rpc/dcerpc.h
+@@ -71,10 +71,6 @@ NTSTATUS dcerpc_push_dcerpc_auth(TALLOC_CTX *mem_ctx,
+ 				 uint32_t auth_context_id,
+ 				 const DATA_BLOB *credentials,
+ 				 DATA_BLOB *blob);
+-NTSTATUS dcerpc_pull_dcerpc_auth(TALLOC_CTX *mem_ctx,
+-				 const DATA_BLOB *blob,
+-				 struct dcerpc_auth *r,
+-				 bool bigendian);
+ NTSTATUS dcerpc_guess_sizes(struct pipe_auth_data *auth,
+ 			    size_t header_len, size_t data_left,
+ 			    size_t max_xmit_frag, size_t pad_alignment,
+diff --git a/source3/librpc/rpc/dcerpc_helpers.c b/source3/librpc/rpc/dcerpc_helpers.c
+index c07835f..e4d0e3a 100644
+--- a/source3/librpc/rpc/dcerpc_helpers.c
++++ b/source3/librpc/rpc/dcerpc_helpers.c
+@@ -210,47 +210,6 @@ NTSTATUS dcerpc_push_dcerpc_auth(TALLOC_CTX *mem_ctx,
+ }
+ 
+ /**
+-* @brief Decodes a dcerpc_auth blob
+-*
+-* @param mem_ctx	The memory context on which to allocate the packet
+-*			elements
+-* @param blob		The blob of data to decode
+-* @param r		An empty dcerpc_auth structure, must not be NULL
+-*
+-* @return a NTSTATUS error code
+-*/
+-NTSTATUS dcerpc_pull_dcerpc_auth(TALLOC_CTX *mem_ctx,
+-				 const DATA_BLOB *blob,
+-				 struct dcerpc_auth *r,
+-				 bool bigendian)
+-{
+-	enum ndr_err_code ndr_err;
+-	struct ndr_pull *ndr;
+-
+-	ndr = ndr_pull_init_blob(blob, mem_ctx);
+-	if (!ndr) {
+-		return NT_STATUS_NO_MEMORY;
+-	}
+-	if (bigendian) {
+-		ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
+-	}
+-
+-	ndr_err = ndr_pull_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, r);
+-
+-	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+-		talloc_free(ndr);
+-		return ndr_map_error2ntstatus(ndr_err);
+-	}
+-	talloc_free(ndr);
+-
+-	if (DEBUGLEVEL >= 10) {
+-		NDR_PRINT_DEBUG(dcerpc_auth, r);
+-	}
+-
+-	return NT_STATUS_OK;
+-}
+-
+-/**
+ * @brief Calculate how much data we can in a packet, including calculating
+ *	 auth token and pad lengths.
+ *
+-- 
+2.8.1
+
+
+From 765ffc9a7b65cf5850bc3460abf83c10426bddad Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Tue, 7 Jul 2015 13:05:01 +0200
+Subject: [PATCH 30/40] CVE-2015-5370: s3:rpc_server: check the transfer syntax
+ in check_bind_req() first
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+(cherry picked from commit 9464684010461947fa98d8ee084069e9cf362625)
+---
+ source3/rpc_server/srv_pipe.c | 20 ++++++++++++++------
+ 1 file changed, 14 insertions(+), 6 deletions(-)
+
+diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
+index 3fb8855..0e6b073 100644
+--- a/source3/rpc_server/srv_pipe.c
++++ b/source3/rpc_server/srv_pipe.c
+@@ -351,16 +351,24 @@ static bool check_bind_req(struct pipes_struct *p,
+ 	DEBUG(3,("check_bind_req for %s\n",
+ 		 get_pipe_name_from_syntax(talloc_tos(), abstract)));
+ 
++	ok = ndr_syntax_id_equal(transfer, &ndr_transfer_syntax);
++	if (!ok) {
++		DEBUG(1,("check_bind_req unknown transfer syntax for "
++			 "%s context_id=%u\n",
++			 get_pipe_name_from_syntax(talloc_tos(), abstract),
++			 (unsigned)context_id));
++		return false;
++	}
++
+ 	/* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */
+-	if (rpc_srv_pipe_exists_by_id(abstract) &&
+-	   ndr_syntax_id_equal(transfer, &ndr_transfer_syntax)) {
+-		DEBUG(3, ("check_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
+-			rpc_srv_get_pipe_cli_name(abstract),
+-			rpc_srv_get_pipe_srv_name(abstract)));
+-	} else {
++	if (!rpc_srv_pipe_exists_by_id(abstract)) {
+ 		return false;
+ 	}
+ 
++	DEBUG(3, ("check_bind_req: %s -> %s rpc service\n",
++		  rpc_srv_get_pipe_cli_name(abstract),
++		  rpc_srv_get_pipe_srv_name(abstract)));
++
+ 	context_fns = SMB_MALLOC_P(struct pipe_rpc_fns);
+ 	if (context_fns == NULL) {
+ 		DEBUG(0,("check_bind_req: malloc() failed!\n"));
+-- 
+2.8.1
+
+
+From 53a0f84445dd19bcca74f5cf5f7b23eab65dd410 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Tue, 7 Jul 2015 13:05:01 +0200
+Subject: [PATCH 31/40] CVE-2015-5370: s3:rpc_server: don't allow an existing
+ context to be changed in check_bind_req()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+An alter context can't change the syntax of an existing context,
+a new context_id will be used for that.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+(cherry picked from commit a995740d4e7fbd8fbb5c8c6280b73eaceae53574)
+---
+ source3/rpc_server/srv_pipe.c | 22 ++++++++++++++++++++++
+ 1 file changed, 22 insertions(+)
+
+diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
+index 0e6b073..4263a91 100644
+--- a/source3/rpc_server/srv_pipe.c
++++ b/source3/rpc_server/srv_pipe.c
+@@ -360,6 +360,28 @@ static bool check_bind_req(struct pipes_struct *p,
+ 		return false;
+ 	}
+ 
++	for (context_fns = p->contexts;
++	     context_fns != NULL;
++	     context_fns = context_fns->next)
++	{
++		if (context_fns->context_id != context_id) {
++			continue;
++		}
++
++		ok = ndr_syntax_id_equal(&context_fns->syntax,
++					 abstract);
++		if (ok) {
++			return true;
++		}
++
++		DEBUG(1,("check_bind_req: changing abstract syntax for "
++			 "%s context_id=%u into %s not supported\n",
++			 get_pipe_name_from_syntax(talloc_tos(), &context_fns->syntax),
++			 (unsigned)context_id,
++			 get_pipe_name_from_syntax(talloc_tos(), abstract)));
++		return false;
++	}
++
+ 	/* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */
+ 	if (!rpc_srv_pipe_exists_by_id(abstract)) {
+ 		return false;
+-- 
+2.8.1
+
+
+From 69183622b6ddc2b077a7598c1d3ed32587843abb Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Wed, 8 Jul 2015 00:01:37 +0200
+Subject: [PATCH 32/40] CVE-2015-5370: s3:rpc_client: pass struct
+ pipe_auth_data to create_rpc_{bind_auth3,alter_context}()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+(cherry picked from commit f556d9245c13d018d4e772f06d013ebe558703d9)
+---
+ source3/rpc_client/cli_pipe.c | 26 ++++++++++----------------
+ 1 file changed, 10 insertions(+), 16 deletions(-)
+
+diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c
+index 1c4ff01..3af3d8f 100644
+--- a/source3/rpc_client/cli_pipe.c
++++ b/source3/rpc_client/cli_pipe.c
+@@ -1816,9 +1816,8 @@ static bool check_bind_response(const struct dcerpc_bind_ack *r,
+ 
+ static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx,
+ 				struct rpc_pipe_client *cli,
+-				uint32 rpc_call_id,
+-				enum dcerpc_AuthType auth_type,
+-				enum dcerpc_AuthLevel auth_level,
++				struct pipe_auth_data *auth,
++				uint32_t rpc_call_id,
+ 				DATA_BLOB *pauth_blob,
+ 				DATA_BLOB *rpc_out)
+ {
+@@ -1828,8 +1827,8 @@ static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx,
+ 	u.auth3._pad = 0;
+ 
+ 	status = dcerpc_push_dcerpc_auth(mem_ctx,
+-					 auth_type,
+-					 auth_level,
++					 auth->auth_type,
++					 auth->auth_level,
+ 					 0, /* auth_pad_length */
+ 					 1, /* auth_context_id */
+ 					 pauth_blob,
+@@ -1861,9 +1860,8 @@ static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx,
+  ********************************************************************/
+ 
+ static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx,
+-					enum dcerpc_AuthType auth_type,
+-					enum dcerpc_AuthLevel auth_level,
+-					uint32 rpc_call_id,
++					struct pipe_auth_data *auth,
++					uint32_t rpc_call_id,
+ 					const struct ndr_syntax_id *abstract,
+ 					const struct ndr_syntax_id *transfer,
+ 					const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
+@@ -1873,8 +1871,8 @@ static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx,
+ 	NTSTATUS status;
+ 
+ 	status = dcerpc_push_dcerpc_auth(mem_ctx,
+-					 auth_type,
+-					 auth_level,
++					 auth->auth_type,
++					 auth->auth_level,
+ 					 0, /* auth_pad_length */
+ 					 1, /* auth_context_id */
+ 					 pauth_blob,
+@@ -2300,9 +2298,7 @@ static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
+ 	/* Now prepare the alter context pdu. */
+ 	data_blob_free(&state->rpc_out);
+ 
+-	status = create_rpc_alter_context(state,
+-					  auth->auth_type,
+-					  auth->auth_level,
++	status = create_rpc_alter_context(state, auth,
+ 					  state->rpc_call_id,
+ 					  &state->cli->abstract_syntax,
+ 					  &state->cli->transfer_syntax,
+@@ -2335,10 +2331,8 @@ static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
+ 	/* Now prepare the auth3 context pdu. */
+ 	data_blob_free(&state->rpc_out);
+ 
+-	status = create_rpc_bind_auth3(state, state->cli,
++	status = create_rpc_bind_auth3(state, state->cli, auth,
+ 					state->rpc_call_id,
+-					auth->auth_type,
+-					auth->auth_level,
+ 					auth_token,
+ 					&state->rpc_out);
+ 	if (!NT_STATUS_IS_OK(status)) {
+-- 
+2.8.1
+
+
+From e29a86c22c735962d2ed6eee43e3a702e87acaae Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Wed, 8 Jul 2015 00:01:37 +0200
+Subject: [PATCH 33/40] CVE-2015-5370: s3:librpc/rpc: add auth_context_id to
+ struct pipe_auth_data
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+(cherry picked from commit cbf20b43d7b40e3b6ccf044f6f51a5adff1f5e6d)
+---
+ source3/librpc/rpc/dcerpc.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/source3/librpc/rpc/dcerpc.h b/source3/librpc/rpc/dcerpc.h
+index 9452e85..c25b0f5 100644
+--- a/source3/librpc/rpc/dcerpc.h
++++ b/source3/librpc/rpc/dcerpc.h
+@@ -42,6 +42,7 @@ struct pipe_auth_data {
+ 	bool verified_bitmask1;
+ 
+ 	void *auth_ctx;
++	uint32_t auth_context_id;
+ 
+ 	/* Only the client code uses these 3 for now */
+ 	char *domain;
+-- 
+2.8.1
+
+
+From c04d24646456dd3c01c2559b5955e9de79e418ae Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Wed, 8 Jul 2015 00:01:37 +0200
+Subject: [PATCH 34/40] CVE-2015-5370: s3:rpc_client: make use of
+ pipe_auth_data->auth_context_id
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This is better than using hardcoded values.
+We need to use auth_context_id = 1 for authenticated
+connections, as old Samba server (before this patchset)
+will use a hardcoded value of 1.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+(cherry picked from commit ae68d3f325c3880144b80385779c9445897646e6)
+---
+ source3/rpc_client/cli_pipe.c | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c
+index 3af3d8f..755d676 100644
+--- a/source3/rpc_client/cli_pipe.c
++++ b/source3/rpc_client/cli_pipe.c
+@@ -1314,7 +1314,7 @@ static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx,
+ 						auth->auth_type,
+ 						auth->auth_level,
+ 						0, /* auth_pad_length */
+-						1, /* auth_context_id */
++						auth->auth_context_id,
+ 						&auth_token,
+ 						&auth_info);
+ 		if (!NT_STATUS_IS_OK(ret)) {
+@@ -1830,7 +1830,7 @@ static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx,
+ 					 auth->auth_type,
+ 					 auth->auth_level,
+ 					 0, /* auth_pad_length */
+-					 1, /* auth_context_id */
++					 auth->auth_context_id,
+ 					 pauth_blob,
+ 					 &u.auth3.auth_info);
+ 	if (!NT_STATUS_IS_OK(status)) {
+@@ -1874,7 +1874,7 @@ static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx,
+ 					 auth->auth_type,
+ 					 auth->auth_level,
+ 					 0, /* auth_pad_length */
+-					 1, /* auth_context_id */
++					 auth->auth_context_id,
+ 					 pauth_blob,
+ 					 &auth_info);
+ 	if (!NT_STATUS_IS_OK(status)) {
+@@ -2704,6 +2704,7 @@ NTSTATUS rpccli_ncalrpc_bind_data(TALLOC_CTX *mem_ctx,
+ 
+ 	result->auth_type = DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM;
+ 	result->auth_level = DCERPC_AUTH_LEVEL_CONNECT;
++	result->auth_context_id = 1;
+ 
+ 	result->user_name = talloc_strdup(result, "");
+ 	result->domain = talloc_strdup(result, "");
+@@ -2728,6 +2729,7 @@ NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
+ 
+ 	result->auth_type = DCERPC_AUTH_TYPE_NONE;
+ 	result->auth_level = DCERPC_AUTH_LEVEL_NONE;
++	result->auth_context_id = 0;
+ 
+ 	result->user_name = talloc_strdup(result, "");
+ 	result->domain = talloc_strdup(result, "");
+@@ -2765,6 +2767,7 @@ static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
+ 
+ 	result->auth_type = auth_type;
+ 	result->auth_level = auth_level;
++	result->auth_context_id = 1;
+ 
+ 	result->user_name = talloc_strdup(result, username);
+ 	result->domain = talloc_strdup(result, domain);
+@@ -2836,6 +2839,7 @@ NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
+ 
+ 	result->auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
+ 	result->auth_level = auth_level;
++	result->auth_context_id = 1;
+ 
+ 	result->user_name = talloc_strdup(result, "");
+ 	result->domain = talloc_strdup(result, domain);
+@@ -3500,6 +3504,7 @@ NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
+ 	}
+ 	auth->auth_type = DCERPC_AUTH_TYPE_KRB5;
+ 	auth->auth_level = auth_level;
++	auth->auth_context_id = 1;
+ 
+ 	if (!username) {
+ 		username = "";
+@@ -3570,6 +3575,7 @@ NTSTATUS cli_rpc_pipe_open_spnego_krb5(struct cli_state *cli,
+ 	}
+ 	auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
+ 	auth->auth_level = auth_level;
++	auth->auth_context_id = 1;
+ 
+ 	if (!username) {
+ 		username = "";
+@@ -3644,6 +3650,7 @@ NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
+ 	}
+ 	auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
+ 	auth->auth_level = auth_level;
++	auth->auth_context_id = 1;
+ 
+ 	if (!username) {
+ 		username = "";
+-- 
+2.8.1
+
+
+From e4de45d67300bed8d6931f10ba11f7c4fe282504 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Wed, 8 Jul 2015 00:01:37 +0200
+Subject: [PATCH 35/40] CVE-2015-5370: s3:rpc_server: make use of
+ pipe_auth_data->auth_context_id
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This is better than using hardcoded values.
+We need to use the value the client used in the BIND request.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+(cherry picked from commit 2bc617293a5d8652e484af69660b3646f3d48690)
+---
+ source3/rpc_server/rpc_ncacn_np.c |  1 +
+ source3/rpc_server/srv_pipe.c     | 11 +++++++----
+ 2 files changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/source3/rpc_server/rpc_ncacn_np.c b/source3/rpc_server/rpc_ncacn_np.c
+index f2e9d10..c0f24a6 100644
+--- a/source3/rpc_server/rpc_ncacn_np.c
++++ b/source3/rpc_server/rpc_ncacn_np.c
+@@ -781,6 +781,7 @@ static NTSTATUS rpc_pipe_open_external(TALLOC_CTX *mem_ctx,
+ 	}
+ 	result->auth->auth_type = DCERPC_AUTH_TYPE_NONE;
+ 	result->auth->auth_level = DCERPC_AUTH_LEVEL_NONE;
++	result->auth->auth_context_id = 0;
+ 
+ 	status = rpccli_anon_bind_data(result, &auth);
+ 	if (!NT_STATUS_IS_OK(status)) {
+diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
+index 4263a91..d6c4118 100644
+--- a/source3/rpc_server/srv_pipe.c
++++ b/source3/rpc_server/srv_pipe.c
+@@ -534,6 +534,7 @@ static bool pipe_spnego_auth_bind(struct pipes_struct *p,
+ 
+ 	p->auth.auth_ctx = spnego_ctx;
+ 	p->auth.auth_type = DCERPC_AUTH_TYPE_SPNEGO;
++	p->auth.auth_context_id = auth_info->auth_context_id;
+ 
+ 	DEBUG(10, ("SPNEGO auth started\n"));
+ 
+@@ -644,6 +645,7 @@ static bool pipe_schannel_auth_bind(struct pipes_struct *p,
+ 	/* We're finished with this bind - no more packets. */
+ 	p->auth.auth_ctx = schannel_auth;
+ 	p->auth.auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
++	p->auth.auth_context_id = auth_info->auth_context_id;
+ 
+ 	p->pipe_bound = True;
+ 
+@@ -688,6 +690,7 @@ static bool pipe_ntlmssp_auth_bind(struct pipes_struct *p,
+ 
+ 	p->auth.auth_ctx = ntlmssp_state;
+ 	p->auth.auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
++	p->auth.auth_context_id = auth_info->auth_context_id;
+ 
+ 	DEBUG(10, (__location__ ": NTLMSSP auth started\n"));
+ 
+@@ -1173,6 +1176,7 @@ static bool api_pipe_bind_req(struct pipes_struct *p,
+ 		p->pipe_bound = True;
+ 		/* The session key was initialized from the SMB
+ 		 * session in make_internal_rpc_pipe_p */
++		p->auth.auth_context_id = 0;
+ 	}
+ 
+ 	ZERO_STRUCT(u.bind_ack);
+@@ -1218,12 +1222,11 @@ static bool api_pipe_bind_req(struct pipes_struct *p,
+ 	}
+ 
+ 	if (auth_resp.length) {
+-
+ 		status = dcerpc_push_dcerpc_auth(pkt,
+ 						 auth_type,
+ 						 auth_info.auth_level,
+-						 0,
+-						 1, /* auth_context_id */
++						 0, /* pad_len */
++						 p->auth.auth_context_id,
+ 						 &auth_resp,
+ 						 &auth_blob);
+ 		if (!NT_STATUS_IS_OK(status)) {
+@@ -1646,7 +1649,7 @@ static bool api_pipe_alter_context(struct pipes_struct *p,
+ 						 auth_info.auth_type,
+ 						 auth_info.auth_level,
+ 						 pad_len,
+-						 1, /* auth_context_id */
++						 p->auth.auth_context_id,
+ 						 &auth_resp,
+ 						 &auth_blob);
+ 		if (!NT_STATUS_IS_OK(status)) {
+-- 
+2.8.1
+
+
+From 7c40975f53365d147b748aec51c55b8279b62c77 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Wed, 8 Jul 2015 00:01:37 +0200
+Subject: [PATCH 36/40] CVE-2015-5370: s3:librpc/rpc: make use of
+ auth->auth_context_id in dcerpc_add_auth_footer()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+(cherry picked from commit 61faaa63e7e610308c72ae4c41a5c7b5b7312685)
+---
+ source3/librpc/rpc/dcerpc_helpers.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/source3/librpc/rpc/dcerpc_helpers.c b/source3/librpc/rpc/dcerpc_helpers.c
+index e4d0e3a..977a372 100644
+--- a/source3/librpc/rpc/dcerpc_helpers.c
++++ b/source3/librpc/rpc/dcerpc_helpers.c
+@@ -741,7 +741,7 @@ NTSTATUS dcerpc_add_auth_footer(struct pipe_auth_data *auth,
+ 					 auth->auth_type,
+ 					 auth->auth_level,
+ 					 pad_len,
+-					 1 /* context id. */,
++					 auth->auth_context_id,
+ 					 &auth_blob,
+ 					 &auth_info);
+ 	if (!NT_STATUS_IS_OK(status)) {
+-- 
+2.8.1
+
+
+From b8c0e111624aea92fefa07a28944397680af642d Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Wed, 8 Jul 2015 00:01:37 +0200
+Subject: [PATCH 37/40] CVE-2015-5370: s3:librpc/rpc: verify auth_context_id in
+ dcerpc_check_auth()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+(cherry picked from commit 0cf3151c843e2c779b534743b455e630d89e2ba9)
+---
+ source3/librpc/rpc/dcerpc_helpers.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/source3/librpc/rpc/dcerpc_helpers.c b/source3/librpc/rpc/dcerpc_helpers.c
+index 977a372..b00cf1bf 100644
+--- a/source3/librpc/rpc/dcerpc_helpers.c
++++ b/source3/librpc/rpc/dcerpc_helpers.c
+@@ -881,6 +881,10 @@ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth,
+ 		return NT_STATUS_INVALID_PARAMETER;
+ 	}
+ 
++	if (auth_info.auth_context_id != auth->auth_context_id) {
++		return NT_STATUS_INVALID_PARAMETER;
++	}
++
+ 	pkt_trailer->length -= auth_length;
+ 	data = data_blob_const(raw_pkt->data + header_size,
+ 			       pkt_trailer->length);
+-- 
+2.8.1
+
+
+From c53147ea64a1ba0a3e0c202ec7aa8353e479d57f Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Tue, 7 Jul 2015 22:51:18 +0200
+Subject: [PATCH 38/40] CVE-2015-5370: s3:rpc_client: verify auth_context_id in
+ rpc_pipe_bind_step_one_done()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+(cherry picked from commit 93a0f92b8ebecb38f92d3b2c9a946b486ee91d3c)
+---
+ source3/rpc_client/cli_pipe.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c
+index 755d676..ee33e80 100644
+--- a/source3/rpc_client/cli_pipe.c
++++ b/source3/rpc_client/cli_pipe.c
+@@ -2052,6 +2052,14 @@ static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
+ 			return;
+ 		}
+ 
++		if (auth.auth_context_id != pauth->auth_context_id) {
++			DEBUG(0, (__location__ " Auth context id %u mismatch expected %u.\n",
++				  (unsigned)auth.auth_context_id,
++				  (unsigned)pauth->auth_context_id));
++			tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
++			return;
++		}
++
+ 		break;
+ 	}
+ 
+-- 
+2.8.1
+
+
+From 4989b97b6f2ab6017f8e3d33c7360d34a024cf0f Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Wed, 8 Jul 2015 00:01:37 +0200
+Subject: [PATCH 39/40] CVE-2015-5370: s3:rpc_server: verify auth_context_id in
+ api_pipe_{bind_auth3,alter_context}
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+(cherry picked from commit 3ef461d8304ee36184cd7a3963676eedff4ef1eb)
+---
+ source3/rpc_server/srv_pipe.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
+index d6c4118..26c4ee0 100644
+--- a/source3/rpc_server/srv_pipe.c
++++ b/source3/rpc_server/srv_pipe.c
+@@ -1364,6 +1364,14 @@ bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt)
+ 		goto err;
+ 	}
+ 
++	if (auth_info.auth_context_id != p->auth.auth_context_id) {
++		DEBUG(0, ("Auth context id mismatch! Client sent %u, "
++			  "but auth was started as level %u!\n",
++			  (unsigned)auth_info.auth_context_id,
++			  (unsigned)p->auth.auth_context_id));
++		goto err;
++	}
++
+ 	switch (auth_info.auth_type) {
+ 	case DCERPC_AUTH_TYPE_NTLMSSP:
+ 		ntlmssp_ctx = talloc_get_type_abort(p->auth.auth_ctx,
+@@ -1545,6 +1553,14 @@ static bool api_pipe_alter_context(struct pipes_struct *p,
+ 			goto err_exit;
+ 		}
+ 
++		if (auth_info.auth_context_id != p->auth.auth_context_id) {
++			DEBUG(0, ("Auth context id mismatch! Client sent %u, "
++				  "but auth was started as level %u!\n",
++				  (unsigned)auth_info.auth_context_id,
++				  (unsigned)p->auth.auth_context_id));
++			goto err_exit;
++		}
++
+ 		switch (auth_info.auth_type) {
+ 		case DCERPC_AUTH_TYPE_SPNEGO:
+ 			spnego_ctx = talloc_get_type_abort(p->auth.auth_ctx,
+-- 
+2.8.1
+
+
+From 030c87181e482abbf9abb2607966ad2d7db1d517 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Tue, 22 Dec 2015 21:23:14 +0100
+Subject: [PATCH 40/40] CVE-2015-5370: s3:rpc_client: disconnect connection on
+ protocol errors
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+(cherry picked from commit 024d3b263a2879cee4fb7794d70f253c948cc043)
+---
+ source3/rpc_client/cli_pipe.c | 67 +++++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 64 insertions(+), 3 deletions(-)
+
+diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c
+index ee33e80..a3810f0 100644
+--- a/source3/rpc_client/cli_pipe.c
++++ b/source3/rpc_client/cli_pipe.c
+@@ -953,6 +953,12 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
+ 
+ 	state->pkt = talloc(state, struct ncacn_packet);
+ 	if (!state->pkt) {
++		/*
++		 * TODO: do a real async disconnect ...
++		 *
++		 * For now do it sync...
++		 */
++		TALLOC_FREE(state->cli->transport);
+ 		tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
+ 		return;
+ 	}
+@@ -962,6 +968,12 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
+ 					  state->pkt,
+ 					  !state->endianess);
+ 	if (!NT_STATUS_IS_OK(status)) {
++		/*
++		 * TODO: do a real async disconnect ...
++		 *
++		 * For now do it sync...
++		 */
++		TALLOC_FREE(state->cli->transport);
+ 		tevent_req_nterror(req, status);
+ 		return;
+ 	}
+@@ -979,6 +991,28 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
+ 		  (unsigned)state->reply_pdu_offset,
+ 		  nt_errstr(status)));
+ 
++	if (state->pkt->ptype != DCERPC_PKT_FAULT && !NT_STATUS_IS_OK(status)) {
++		/*
++		 * TODO: do a real async disconnect ...
++		 *
++		 * For now do it sync...
++		 */
++		TALLOC_FREE(state->cli->transport);
++	} else if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
++		/*
++		 * TODO: do a real async disconnect ...
++		 *
++		 * For now do it sync...
++		 */
++		TALLOC_FREE(state->cli->transport);
++	} else if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_SEC_PKG_ERROR)) {
++		/*
++		 * TODO: do a real async disconnect ...
++		 *
++		 * For now do it sync...
++		 */
++		TALLOC_FREE(state->cli->transport);
++	}
+ 	if (!NT_STATUS_IS_OK(status)) {
+ 		tevent_req_nterror(req, status);
+ 		return;
+@@ -1003,12 +1037,24 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
+ 			 "%s\n",
+ 			 state->endianess?"little":"big",
+ 			 state->pkt->drep[0]?"little":"big"));
+-		tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
++		/*
++		 * TODO: do a real async disconnect ...
++		 *
++		 * For now do it sync...
++		 */
++		TALLOC_FREE(state->cli->transport);
++		tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
+ 		return;
+ 	}
+ 
+ 	if (state->reply_pdu_offset + rdata.length > MAX_RPC_DATA_SIZE) {
+-		tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
++		/*
++		 * TODO: do a real async disconnect ...
++		 *
++		 * For now do it sync...
++		 */
++		TALLOC_FREE(state->cli->transport);
++		tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
+ 		return;
+ 	}
+ 
+@@ -1016,6 +1062,12 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
+ 	if (state->reply_pdu.length < state->reply_pdu_offset + rdata.length) {
+ 		if (!data_blob_realloc(NULL, &state->reply_pdu,
+ 				state->reply_pdu_offset + rdata.length)) {
++			/*
++			 * TODO: do a real async disconnect ...
++			 *
++			 * For now do it sync...
++			 */
++			TALLOC_FREE(state->cli->transport);
+ 			tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
+ 			return;
+ 		}
+@@ -1045,6 +1097,14 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
+ 	subreq = get_complete_frag_send(state, state->ev, state->cli,
+ 					state->call_id,
+ 					&state->incoming_frag);
++	if (subreq == NULL) {
++		/*
++		 * TODO: do a real async disconnect ...
++		 *
++		 * For now do it sync...
++		 */
++		TALLOC_FREE(state->cli->transport);
++	}
+ 	if (tevent_req_nomem(subreq, req)) {
+ 		return;
+ 	}
+@@ -2574,8 +2634,9 @@ static struct tevent_req *rpccli_bh_disconnect_send(TALLOC_CTX *mem_ctx,
+ 	/*
+ 	 * TODO: do a real async disconnect ...
+ 	 *
+-	 * For now the caller needs to free rpc_cli
++	 * For now we do it sync...
+ 	 */
++	TALLOC_FREE(hs->rpc_cli->transport);
+ 	hs->rpc_cli = NULL;
+ 
+ 	tevent_req_done(req);
+-- 
+2.8.1
+
diff --git a/debian/patches/CVE-2016-2110-v3-6.patch b/debian/patches/CVE-2016-2110-v3-6.patch
new file mode 100644
index 0000000..86fdb53
--- /dev/null
+++ b/debian/patches/CVE-2016-2110-v3-6.patch
@@ -0,0 +1,600 @@
+From 20b39e2c22cf94a45cc160d5b032eacb276f3b68 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Tue, 1 Dec 2015 08:46:45 +0100
+Subject: [PATCH 1/9] CVE-2016-2110: s3:ntlmssp: set and use
+ ntlmssp_state->allow_lm_key
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+---
+ source3/libsmb/ntlmssp.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c
+index 1de6189..20a5987 100644
+--- a/source3/libsmb/ntlmssp.c
++++ b/source3/libsmb/ntlmssp.c
+@@ -530,7 +530,8 @@ noccache:
+ 	DEBUG(3, ("Got challenge flags:\n"));
+ 	debug_ntlmssp_flags(chal_flags);
+ 
+-	ntlmssp_handle_neg_flags(ntlmssp_state, chal_flags, lp_client_lanman_auth());
++	ntlmssp_handle_neg_flags(ntlmssp_state, chal_flags,
++				 ntlmssp_state->allow_lm_key);
+ 
+ 	if (ntlmssp_state->unicode) {
+ 		if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) {
+@@ -769,6 +770,7 @@ NTSTATUS ntlmssp_client_start(TALLOC_CTX *mem_ctx,
+ 	ntlmssp_state->unicode = True;
+ 
+ 	ntlmssp_state->use_ntlmv2 = use_ntlmv2;
++	ntlmssp_state->allow_lm_key = lp_client_lanman_auth();
+ 
+ 	ntlmssp_state->expected_state = NTLMSSP_INITIAL;
+ 
+-- 
+2.8.1
+
+
+From da8f8abd31300e217512e6a760e38381d338fe4a Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Fri, 11 Dec 2015 14:50:23 +0100
+Subject: [PATCH 2/9] CVE-2016-2110: s3:ntlmssp: add
+ ntlmssp3_handle_neg_flags()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This is a copy of ntlmssp_handle_neg_flags(), which will be changed
+in an incompatible way in the following commits.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+---
+ source3/libsmb/ntlmssp.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 56 insertions(+), 2 deletions(-)
+
+diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c
+index 20a5987..ad09f9f 100644
+--- a/source3/libsmb/ntlmssp.c
++++ b/source3/libsmb/ntlmssp.c
+@@ -422,6 +422,60 @@ static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state,
+ 	return NT_STATUS_MORE_PROCESSING_REQUIRED;
+ }
+ 
++static void ntlmssp3_handle_neg_flags(struct ntlmssp_state *ntlmssp_state,
++				      uint32_t neg_flags, bool allow_lm)
++{
++	if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) {
++		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
++		ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM;
++		ntlmssp_state->unicode = true;
++	} else {
++		ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_UNICODE;
++		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
++		ntlmssp_state->unicode = false;
++	}
++
++	if ((neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) && allow_lm) {
++		/* other end forcing us to use LM */
++		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;
++		ntlmssp_state->use_ntlmv2 = false;
++	} else {
++		ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
++	}
++
++	if (!(neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)) {
++		ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
++	}
++
++	if (!(neg_flags & NTLMSSP_NEGOTIATE_NTLM2)) {
++		ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
++	}
++
++	if (!(neg_flags & NTLMSSP_NEGOTIATE_128)) {
++		ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128;
++	}
++
++	if (!(neg_flags & NTLMSSP_NEGOTIATE_56)) {
++		ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_56;
++	}
++
++	if (!(neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) {
++		ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_KEY_EXCH;
++	}
++
++	if (!(neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
++		ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SIGN;
++	}
++
++	if (!(neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {
++		ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SEAL;
++	}
++
++	if ((neg_flags & NTLMSSP_REQUEST_TARGET)) {
++		ntlmssp_state->neg_flags |= NTLMSSP_REQUEST_TARGET;
++	}
++}
++
+ /**
+  * Next state function for the Challenge Packet.  Generate an auth packet.
+  *
+@@ -530,8 +584,8 @@ noccache:
+ 	DEBUG(3, ("Got challenge flags:\n"));
+ 	debug_ntlmssp_flags(chal_flags);
+ 
+-	ntlmssp_handle_neg_flags(ntlmssp_state, chal_flags,
+-				 ntlmssp_state->allow_lm_key);
++	ntlmssp3_handle_neg_flags(ntlmssp_state, chal_flags,
++				  ntlmssp_state->allow_lm_key);
+ 
+ 	if (ntlmssp_state->unicode) {
+ 		if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) {
+-- 
+2.8.1
+
+
+From ba2e2f98c10d805963ede277fce9f0cffad9d88b Mon Sep 17 00:00:00 2001
+From: Andreas Schneider <asn at cryptomilk.org>
+Date: Thu, 31 Mar 2016 12:39:50 +0200
+Subject: [PATCH 3/9] CVE-2016-2110: s3:ntlmssp: let
+ ntlmssp3_handle_neg_flags() return NTSTATUS
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+In future we can do a more fine granted negotiation
+and assert specific security features.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+---
+ source3/libsmb/ntlmssp.c | 33 +++++++++++++++++++--------------
+ 1 file changed, 19 insertions(+), 14 deletions(-)
+
+diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c
+index ad09f9f..81a85ce 100644
+--- a/source3/libsmb/ntlmssp.c
++++ b/source3/libsmb/ntlmssp.c
+@@ -422,10 +422,10 @@ static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state,
+ 	return NT_STATUS_MORE_PROCESSING_REQUIRED;
+ }
+ 
+-static void ntlmssp3_handle_neg_flags(struct ntlmssp_state *ntlmssp_state,
+-				      uint32_t neg_flags, bool allow_lm)
++static NTSTATUS ntlmssp3_handle_neg_flags(struct ntlmssp_state *ntlmssp_state,
++					  uint32_t flags)
+ {
+-	if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) {
++	if (flags & NTLMSSP_NEGOTIATE_UNICODE) {
+ 		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
+ 		ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM;
+ 		ntlmssp_state->unicode = true;
+@@ -435,7 +435,7 @@ static void ntlmssp3_handle_neg_flags(struct ntlmssp_state *ntlmssp_state,
+ 		ntlmssp_state->unicode = false;
+ 	}
+ 
+-	if ((neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) && allow_lm) {
++	if ((flags & NTLMSSP_NEGOTIATE_LM_KEY) && ntlmssp_state->allow_lm_key) {
+ 		/* other end forcing us to use LM */
+ 		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;
+ 		ntlmssp_state->use_ntlmv2 = false;
+@@ -443,37 +443,39 @@ static void ntlmssp3_handle_neg_flags(struct ntlmssp_state *ntlmssp_state,
+ 		ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
+ 	}
+ 
+-	if (!(neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)) {
++	if (!(flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)) {
+ 		ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
+ 	}
+ 
+-	if (!(neg_flags & NTLMSSP_NEGOTIATE_NTLM2)) {
++	if (!(flags & NTLMSSP_NEGOTIATE_NTLM2)) {
+ 		ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
+ 	}
+ 
+-	if (!(neg_flags & NTLMSSP_NEGOTIATE_128)) {
++	if (!(flags & NTLMSSP_NEGOTIATE_128)) {
+ 		ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128;
+ 	}
+ 
+-	if (!(neg_flags & NTLMSSP_NEGOTIATE_56)) {
++	if (!(flags & NTLMSSP_NEGOTIATE_56)) {
+ 		ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_56;
+ 	}
+ 
+-	if (!(neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) {
++	if (!(flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) {
+ 		ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_KEY_EXCH;
+ 	}
+ 
+-	if (!(neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
++	if (!(flags & NTLMSSP_NEGOTIATE_SIGN)) {
+ 		ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SIGN;
+ 	}
+ 
+-	if (!(neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {
++	if (!(flags & NTLMSSP_NEGOTIATE_SEAL)) {
+ 		ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SEAL;
+ 	}
+ 
+-	if ((neg_flags & NTLMSSP_REQUEST_TARGET)) {
++	if ((flags & NTLMSSP_REQUEST_TARGET)) {
+ 		ntlmssp_state->neg_flags |= NTLMSSP_REQUEST_TARGET;
+ 	}
++
++	return NT_STATUS_OK;
+ }
+ 
+ /**
+@@ -584,8 +586,11 @@ noccache:
+ 	DEBUG(3, ("Got challenge flags:\n"));
+ 	debug_ntlmssp_flags(chal_flags);
+ 
+-	ntlmssp3_handle_neg_flags(ntlmssp_state, chal_flags,
+-				  ntlmssp_state->allow_lm_key);
++	nt_status = ntlmssp3_handle_neg_flags(ntlmssp_state, chal_flags);
++	if (!NT_STATUS_IS_OK(nt_status)) {
++		return nt_status;
++	}
++
+ 
+ 	if (ntlmssp_state->unicode) {
+ 		if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) {
+-- 
+2.8.1
+
+
+From d9ed2c9b3120e5fcc97afbe8ce4bbd03abdc4c97 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Tue, 1 Dec 2015 15:01:09 +0100
+Subject: [PATCH 4/9] CVE-2016-2110: s3:ntlmssp: don't allow a downgrade from
+ NTLMv2 to LM_AUTH
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+man smb.conf says "client ntlmv2 auth = yes" the default disables,
+"client lanman auth = yes":
+
+  ...
+  Likewise, if the client ntlmv2 auth parameter is enabled, then only NTLMv2
+  logins will be attempted.
+  ...
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+---
+ source3/libsmb/ntlmssp.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c
+index 81a85ce..23a5e5d 100644
+--- a/source3/libsmb/ntlmssp.c
++++ b/source3/libsmb/ntlmssp.c
+@@ -841,6 +841,10 @@ NTSTATUS ntlmssp_client_start(TALLOC_CTX *mem_ctx,
+ 		NTLMSSP_NEGOTIATE_KEY_EXCH |
+ 		NTLMSSP_REQUEST_TARGET;
+ 
++	if (ntlmssp_state->use_ntlmv2) {
++		ntlmssp_state->allow_lm_key = false;
++	}
++
+ 	ntlmssp_state->client.netbios_name = talloc_strdup(ntlmssp_state, netbios_name);
+ 	if (!ntlmssp_state->client.netbios_name) {
+ 		talloc_free(ntlmssp_state);
+-- 
+2.8.1
+
+
+From c27686cedcd7180b733eb8e2b71778c9e4e74211 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Thu, 31 Mar 2016 12:59:05 +0200
+Subject: [PATCH 5/9] CVE-2016-2110: s3:ntlmssp: maintain a required_flags
+ variable
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+We now give an error when required flags are missing.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+---
+ libcli/auth/ntlmssp.h    |  1 +
+ source3/libsmb/ntlmssp.c | 20 ++++++++++++++++++++
+ 2 files changed, 21 insertions(+)
+
+diff --git a/libcli/auth/ntlmssp.h b/libcli/auth/ntlmssp.h
+index 495d94f..88a049b 100644
+--- a/libcli/auth/ntlmssp.h
++++ b/libcli/auth/ntlmssp.h
+@@ -83,6 +83,7 @@ struct ntlmssp_state
+ 	DATA_BLOB nt_resp;
+ 	DATA_BLOB session_key;
+ 
++	uint32_t required_flags;
+ 	uint32_t neg_flags; /* the current state of negotiation with the NTLMSSP partner */
+ 
+ 	/**
+diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c
+index 23a5e5d..48d7d45 100644
+--- a/source3/libsmb/ntlmssp.c
++++ b/source3/libsmb/ntlmssp.c
+@@ -425,6 +425,8 @@ static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state,
+ static NTSTATUS ntlmssp3_handle_neg_flags(struct ntlmssp_state *ntlmssp_state,
+ 					  uint32_t flags)
+ {
++	uint32_t missing_flags = ntlmssp_state->required_flags;
++
+ 	if (flags & NTLMSSP_NEGOTIATE_UNICODE) {
+ 		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
+ 		ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM;
+@@ -475,6 +477,24 @@ static NTSTATUS ntlmssp3_handle_neg_flags(struct ntlmssp_state *ntlmssp_state,
+ 		ntlmssp_state->neg_flags |= NTLMSSP_REQUEST_TARGET;
+ 	}
+ 
++	missing_flags &= ~ntlmssp_state->neg_flags;
++	if (missing_flags != 0) {
++		NTSTATUS status = NT_STATUS_RPC_SEC_PKG_ERROR;
++		DEBUG(1, ("%s: Got challenge flags[0x%08x] "
++			  "- possible downgrade detected! "
++			  "missing_flags[0x%08x] - %s\n",
++			  __func__,
++			  (unsigned)flags,
++			  (unsigned)missing_flags,
++			  nt_errstr(status)));
++		debug_ntlmssp_flags(missing_flags);
++		DEBUGADD(4, ("neg_flags[0x%08x]\n",
++			     (unsigned)ntlmssp_state->neg_flags));
++		debug_ntlmssp_flags(ntlmssp_state->neg_flags);
++
++		return status;
++	}
++
+ 	return NT_STATUS_OK;
+ }
+ 
+-- 
+2.8.1
+
+
+From 7af06ebbb6b36ff4204a2f58f6667ad08314a01e Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Thu, 31 Mar 2016 13:03:24 +0200
+Subject: [PATCH 6/9] CVE-2016-2110: s3:ntlmssp: don't allow a downgrade from
+ NTLMv2 to LM_AUTH
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+man smb.conf says "client ntlmv2 auth = yes" the default disables,
+"client lanman auth = yes":
+
+  ...
+  Likewise, if the client ntlmv2 auth parameter is enabled, then only
+  NTLMv2 logins will be attempted.
+  ...
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+---
+ source3/libsmb/ntlmssp.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c
+index 48d7d45..bf40404 100644
+--- a/source3/libsmb/ntlmssp.c
++++ b/source3/libsmb/ntlmssp.c
+@@ -388,6 +388,7 @@ static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state,
+ 
+ 	if (ntlmssp_state->use_ntlmv2) {
+ 		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
++		ntlmssp_state->allow_lm_key = false;
+ 	}
+ 
+ 	/* generate the ntlmssp negotiate packet */
+-- 
+2.8.1
+
+
+From 2c2d5c81cd1b810653a49ca00c774d9a1096d3ee Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Thu, 31 Mar 2016 14:21:12 +0200
+Subject: [PATCH 7/9] CVE-2016-2110: s3:ntlmssp: let ntlmssp3_client_initial
+ require NTLM2 (EXTENDED_SESSIONSECURITY) when using ntlmv2
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+---
+ source3/libsmb/ntlmssp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c
+index bf40404..00b8b85 100644
+--- a/source3/libsmb/ntlmssp.c
++++ b/source3/libsmb/ntlmssp.c
+@@ -387,7 +387,7 @@ static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state,
+ 	}
+ 
+ 	if (ntlmssp_state->use_ntlmv2) {
+-		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
++		ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_NTLM2;
+ 		ntlmssp_state->allow_lm_key = false;
+ 	}
+ 
+-- 
+2.8.1
+
+
+From 3bd43cee7be94c59944c6d70a7205398f8b7207f Mon Sep 17 00:00:00 2001
+From: Andreas Schneider <asn at cryptomilk.org>
+Date: Thu, 31 Mar 2016 14:30:05 +0200
+Subject: [PATCH 8/9] CVE-2016-2110: s3:ntlmssp: Change want_fetures to require
+ flags
+
+Pair-Programmed-With: Ralph Boehme <slow at samba.org>
+Signed-off-by: Andreas Schneider <asn at samba.org>
+Signed-off-by: Ralph Boehme <slow at samba.org>
+---
+ source3/libsmb/ntlmssp.c | 17 +++++++++++------
+ 1 file changed, 11 insertions(+), 6 deletions(-)
+
+diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c
+index 00b8b85..60dfb67 100644
+--- a/source3/libsmb/ntlmssp.c
++++ b/source3/libsmb/ntlmssp.c
+@@ -176,17 +176,19 @@ void ntlmssp_want_feature_list(struct ntlmssp_state *ntlmssp_state, char *featur
+ 	 * also add  NTLMSSP_NEGOTIATE_SEAL here. JRA.
+ 	 */
+ 	if (in_list("NTLMSSP_FEATURE_SESSION_KEY", feature_list, True)) {
+-		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
++		ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN;
+ 	}
+ 	if (in_list("NTLMSSP_FEATURE_SIGN", feature_list, True)) {
+-		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
++		ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN;
+ 	}
+ 	if(in_list("NTLMSSP_FEATURE_SEAL", feature_list, True)) {
+-		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
++		ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SEAL;
+ 	}
+ 	if (in_list("NTLMSSP_FEATURE_CCACHE", feature_list, true)) {
+ 		ntlmssp_state->use_ccache = true;
+ 	}
++
++	ntlmssp_state->neg_flags |= ntlmssp_state->required_flags;
+ }
+ 
+ /**
+@@ -199,17 +201,20 @@ void ntlmssp_want_feature(struct ntlmssp_state *ntlmssp_state, uint32_t feature)
+ {
+ 	/* As per JRA's comment above */
+ 	if (feature & NTLMSSP_FEATURE_SESSION_KEY) {
+-		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
++		ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN;
+ 	}
+ 	if (feature & NTLMSSP_FEATURE_SIGN) {
+-		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
++		ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN;
+ 	}
+ 	if (feature & NTLMSSP_FEATURE_SEAL) {
+-		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
++		ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN;
++		ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SEAL;
+ 	}
+ 	if (feature & NTLMSSP_FEATURE_CCACHE) {
+ 		ntlmssp_state->use_ccache = true;
+ 	}
++
++	ntlmssp_state->neg_flags |= ntlmssp_state->required_flags;
+ }
+ 
+ /**
+-- 
+2.8.1
+
+
+From 6bea2025f95c5e2d8fe308bc679ff9d90ea1db07 Mon Sep 17 00:00:00 2001
+From: Andreas Schneider <asn at samba.org>
+Date: Thu, 31 Mar 2016 15:02:11 +0200
+Subject: [PATCH 9/9] CVE-2016-2110: s3:ntlmssp: Fix downgrade also for the
+ ntlmssp creds cache case
+
+Pair-Programmed-With: Ralph Boehme <slow at samba.org>
+Signed-off-by: Andreas Schneider <asn at samba.org>
+Signed-off-by: Ralph Boehme <slow at samba.org>
+---
+ source3/libsmb/ntlmssp.c | 42 ++++++++++++++++++++----------------------
+ 1 file changed, 20 insertions(+), 22 deletions(-)
+
+diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c
+index 60dfb67..5b7db89 100644
+--- a/source3/libsmb/ntlmssp.c
++++ b/source3/libsmb/ntlmssp.c
+@@ -530,6 +530,26 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
+ 	DATA_BLOB encrypted_session_key = data_blob_null;
+ 	NTSTATUS nt_status = NT_STATUS_OK;
+ 
++	if (!msrpc_parse(ntlmssp_state, &reply, "CdBd",
++			 "NTLMSSP",
++			 &ntlmssp_command,
++			 &server_domain_blob,
++			 &chal_flags)) {
++		DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n"));
++		dump_data(2, reply.data, reply.length);
++
++		return NT_STATUS_INVALID_PARAMETER;
++	}
++	data_blob_free(&server_domain_blob);
++
++	DEBUG(3, ("Got challenge flags:\n"));
++	debug_ntlmssp_flags(chal_flags);
++
++	nt_status = ntlmssp3_handle_neg_flags(ntlmssp_state, chal_flags);
++	if (!NT_STATUS_IS_OK(nt_status)) {
++		return nt_status;
++	}
++
+ 	if (ntlmssp_state->use_ccache) {
+ 		struct wbcCredentialCacheParams params;
+ 		struct wbcCredentialCacheInfo *info = NULL;
+@@ -580,17 +600,6 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
+ 
+ noccache:
+ 
+-	if (!msrpc_parse(ntlmssp_state, &reply, "CdBd",
+-			 "NTLMSSP",
+-			 &ntlmssp_command,
+-			 &server_domain_blob,
+-			 &chal_flags)) {
+-		DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n"));
+-		dump_data(2, reply.data, reply.length);
+-
+-		return NT_STATUS_INVALID_PARAMETER;
+-	}
+-
+ 	if (DEBUGLEVEL >= 10) {
+ 		struct CHALLENGE_MESSAGE *challenge = talloc(
+ 			talloc_tos(), struct CHALLENGE_MESSAGE);
+@@ -607,17 +616,6 @@ noccache:
+ 		}
+ 	}
+ 
+-	data_blob_free(&server_domain_blob);
+-
+-	DEBUG(3, ("Got challenge flags:\n"));
+-	debug_ntlmssp_flags(chal_flags);
+-
+-	nt_status = ntlmssp3_handle_neg_flags(ntlmssp_state, chal_flags);
+-	if (!NT_STATUS_IS_OK(nt_status)) {
+-		return nt_status;
+-	}
+-
+-
+ 	if (ntlmssp_state->unicode) {
+ 		if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) {
+ 			chal_parse_string = "CdUdbddB";
+-- 
+2.8.1
+
diff --git a/debian/patches/CVE-2016-2111-v3-6.patch b/debian/patches/CVE-2016-2111-v3-6.patch
new file mode 100644
index 0000000..abcd629
--- /dev/null
+++ b/debian/patches/CVE-2016-2111-v3-6.patch
@@ -0,0 +1,1058 @@
+From 8367bf408bea8c0c0d9bcbe47198c272cc954e2f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd at samba.org>
+Date: Sat, 26 Sep 2015 01:29:10 +0200
+Subject: [PATCH 01/15] CVE-2016-2111: s3:rpc_server/netlogon: always go
+ through netr_creds_server_step_check()
+
+The ensures we apply the "server schannel = yes" restrictions.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749
+
+Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
+
+Signed-off-by: Guenther Deschner <gd at samba.org>
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+---
+ source3/rpc_server/netlogon/srv_netlog_nt.c | 24 ++++++++++++++----------
+ 1 file changed, 14 insertions(+), 10 deletions(-)
+
+diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c
+index 4734bfe..54b8c5c 100644
+--- a/source3/rpc_server/netlogon/srv_netlog_nt.c
++++ b/source3/rpc_server/netlogon/srv_netlog_nt.c
+@@ -2271,11 +2271,13 @@ NTSTATUS _netr_GetForestTrustInformation(struct pipes_struct *p,
+ 
+ 	/* TODO: check server name */
+ 
+-	status = schannel_check_creds_state(p->mem_ctx, lp_private_dir(),
+-					    r->in.computer_name,
+-					    r->in.credential,
+-					    r->out.return_authenticator,
+-					    &creds);
++	become_root();
++	status = netr_creds_server_step_check(p, p->mem_ctx,
++					      r->in.computer_name,
++					      r->in.credential,
++					      r->out.return_authenticator,
++					      &creds);
++	unbecome_root();
+ 	if (!NT_STATUS_IS_OK(status)) {
+ 		return status;
+ 	}
+@@ -2371,11 +2373,13 @@ NTSTATUS _netr_ServerGetTrustInfo(struct pipes_struct *p,
+ 
+ 	/* TODO: check server name */
+ 
+-	status = schannel_check_creds_state(p->mem_ctx, lp_private_dir(),
+-					    r->in.computer_name,
+-					    r->in.credential,
+-					    r->out.return_authenticator,
+-					    &creds);
++	become_root();
++	status = netr_creds_server_step_check(p, p->mem_ctx,
++					      r->in.computer_name,
++					      r->in.credential,
++					      r->out.return_authenticator,
++					      &creds);
++	unbecome_root();
+ 	if (!NT_STATUS_IS_OK(status)) {
+ 		return status;
+ 	}
+-- 
+2.8.1
+
+
+From 3bb481e0d1d177919e6f9dd651c71916de03c37b Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Fri, 7 Aug 2015 13:33:17 +0200
+Subject: [PATCH 02/15] CVE-2016-2111: s3:rpc_server/netlogon: require
+ DCERPC_AUTH_LEVEL_PRIVACY for validation level 6
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+---
+ source3/rpc_server/netlogon/srv_netlog_nt.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c
+index 54b8c5c..30e1bc0 100644
+--- a/source3/rpc_server/netlogon/srv_netlog_nt.c
++++ b/source3/rpc_server/netlogon/srv_netlog_nt.c
+@@ -1636,6 +1636,14 @@ static NTSTATUS _netr_LogonSamLogon_base(struct pipes_struct *p,
+ 						r->out.validation->sam3);
+ 		break;
+ 	case 6:
++		/* Only allow this if the pipe is protected. */
++		if (p->auth.auth_level < DCERPC_AUTH_LEVEL_PRIVACY) {
++			DEBUG(0,("netr_Validation6: client %s not using privacy for netlogon\n",
++				get_remote_machine_name()));
++			status = NT_STATUS_INVALID_PARAMETER;
++			break;
++		}
++
+ 		status = serverinfo_to_SamInfo6(server_info, pipe_session_key, 16,
+ 						r->out.validation->sam6);
+ 		break;
+-- 
+2.8.1
+
+
+From 2d9b62b0dafd619c4ef812f78a76b3f771afc8bc Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Sat, 12 Dec 2015 22:23:18 +0100
+Subject: [PATCH 03/15] CVE-2016-2111: s4:torture/rpc: fix rpc.samba3.netlogon
+ ntlmv2 test
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The computer name of the NTLMv2 blob needs to match
+the schannel connection.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+---
+ source4/torture/rpc/samba3rpc.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/source4/torture/rpc/samba3rpc.c b/source4/torture/rpc/samba3rpc.c
+index 26bed19..d39cf55 100644
+--- a/source4/torture/rpc/samba3rpc.c
++++ b/source4/torture/rpc/samba3rpc.c
+@@ -1122,8 +1122,8 @@ static bool schan(struct torture_context *tctx,
+ 		generate_random_buffer(chal.data, chal.length);
+ 		names_blob = NTLMv2_generate_names_blob(
+ 			mem_ctx,
+-			cli_credentials_get_workstation(user_creds),
+-			cli_credentials_get_domain(user_creds));
++			cli_credentials_get_workstation(wks_creds),
++			cli_credentials_get_domain(wks_creds));
+ 		status = cli_credentials_get_ntlm_response(
+ 			user_creds, mem_ctx, &flags, chal, names_blob,
+ 			&lm_resp, &nt_resp, NULL, NULL);
+-- 
+2.8.1
+
+
+From 2476a86f1a41f2dcd45994c9c40e395f5e19e505 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Tue, 23 Feb 2016 19:08:31 +0100
+Subject: [PATCH 04/15] CVE-2016-2111: libcli/auth: add
+ NTLMv2_RESPONSE_verify_netlogon_creds() helper function
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This is the function that prevents spoofing like
+Microsoft's CVE-2015-0005.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+---
+ libcli/auth/proto.h       |   5 ++
+ libcli/auth/smbencrypt.c  | 142 +++++++++++++++++++++++++++++++++++++++++++++-
+ libcli/auth/wscript_build |   2 +-
+ source3/Makefile.in       |  27 +++++----
+ 4 files changed, 163 insertions(+), 13 deletions(-)
+
+diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h
+index 11b720df..558a6eb 100644
+--- a/libcli/auth/proto.h
++++ b/libcli/auth/proto.h
+@@ -139,6 +139,11 @@ bool SMBNTLMv2encrypt(TALLOC_CTX *mem_ctx,
+ 		      const DATA_BLOB *names_blob,
+ 		      DATA_BLOB *lm_response, DATA_BLOB *nt_response, 
+ 		      DATA_BLOB *lm_session_key, DATA_BLOB *user_session_key) ;
++NTSTATUS NTLMv2_RESPONSE_verify_netlogon_creds(const char *account_name,
++			const char *account_domain,
++			const DATA_BLOB response,
++			const struct netlogon_creds_CredentialState *creds,
++			const char *workgroup);
+ 
+ /***********************************************************
+  encode a password buffer with a unicode password.  The buffer
+diff --git a/libcli/auth/smbencrypt.c b/libcli/auth/smbencrypt.c
+index e0326d4..906e652 100644
+--- a/libcli/auth/smbencrypt.c
++++ b/libcli/auth/smbencrypt.c
+@@ -26,7 +26,7 @@
+ #include "../libcli/auth/msrpc_parse.h"
+ #include "../lib/crypto/crypto.h"
+ #include "../libcli/auth/libcli_auth.h"
+-#include "../librpc/gen_ndr/ntlmssp.h"
++#include "../librpc/gen_ndr/ndr_ntlmssp.h"
+ 
+ void SMBencrypt_hash(const uint8_t lm_hash[16], const uint8_t *c8, uint8_t p24[24])
+ {
+@@ -515,6 +515,146 @@ bool SMBNTLMv2encrypt(TALLOC_CTX *mem_ctx,
+ 				     lm_response, nt_response, lm_session_key, user_session_key);
+ }
+ 
++NTSTATUS NTLMv2_RESPONSE_verify_netlogon_creds(const char *account_name,
++			const char *account_domain,
++			const DATA_BLOB response,
++			const struct netlogon_creds_CredentialState *creds,
++			const char *workgroup)
++{
++	TALLOC_CTX *frame = NULL;
++	/* RespType + HiRespType */
++	static const char *magic = "\x01\x01";
++	int cmp;
++	struct NTLMv2_RESPONSE v2_resp;
++	enum ndr_err_code err;
++	const struct AV_PAIR *av_nb_cn = NULL;
++	const struct AV_PAIR *av_nb_dn = NULL;
++
++	if (response.length < 48) {
++		/*
++		 * NTLMv2_RESPONSE has at least 48 bytes.
++		 */
++		return NT_STATUS_OK;
++	}
++
++	cmp = memcmp(response.data + 16, magic, 2);
++	if (cmp != 0) {
++		/*
++		 * It doesn't look like a valid NTLMv2_RESPONSE
++		 */
++		return NT_STATUS_OK;
++	}
++
++	frame = talloc_stackframe();
++
++	err = ndr_pull_struct_blob(&response, frame, &v2_resp,
++		(ndr_pull_flags_fn_t)ndr_pull_NTLMv2_RESPONSE);
++	if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
++		NTSTATUS status;
++		status = ndr_map_error2ntstatus(err);
++		DEBUG(2,("Failed to parse NTLMv2_RESPONSE "
++			 "length %u - %s - %s\n",
++			 (unsigned)response.length,
++			 ndr_map_error2string(err),
++			 nt_errstr(status)));
++		dump_data(2, response.data, response.length);
++		TALLOC_FREE(frame);
++		return status;
++	}
++
++	if (DEBUGLVL(10)) {
++		NDR_PRINT_DEBUG(NTLMv2_RESPONSE, &v2_resp);
++	}
++
++	/*
++	 * Make sure the netbios computer name in the
++	 * NTLMv2_RESPONSE matches the computer name
++	 * in the secure channel credentials for workstation
++	 * trusts.
++	 *
++	 * And the netbios domain name matches our
++	 * workgroup.
++	 *
++	 * This prevents workstations from requesting
++	 * the session key of NTLMSSP sessions of clients
++	 * to other hosts.
++	 */
++	if (creds->secure_channel_type == SEC_CHAN_WKSTA) {
++		av_nb_cn = ndr_ntlmssp_find_av(&v2_resp.Challenge.AvPairs,
++					       MsvAvNbComputerName);
++		av_nb_dn = ndr_ntlmssp_find_av(&v2_resp.Challenge.AvPairs,
++					       MsvAvNbDomainName);
++	}
++
++	if (av_nb_cn != NULL) {
++		const char *v = NULL;
++		char *a = NULL;
++		size_t len;
++
++		v = av_nb_cn->Value.AvNbComputerName;
++
++		a = talloc_strdup(frame, creds->account_name);
++		if (a == NULL) {
++			TALLOC_FREE(frame);
++			return NT_STATUS_NO_MEMORY;
++		}
++		len = strlen(a);
++		if (len > 0 && a[len - 1] == '$') {
++			a[len - 1] = '\0';
++		}
++
++#ifdef SAMBA4_INTERNAL_HEIMDAL /* smbtorture4 for make test */
++		cmp = strcasecmp_m(a, v);
++#else /* smbd */
++		cmp = StrCaseCmp(a, v);
++#endif
++		if (cmp != 0) {
++			DEBUG(2,("%s: NTLMv2_RESPONSE with "
++				 "NbComputerName[%s] rejected "
++				 "for user[%s\\%s] "
++				 "against SEC_CHAN_WKSTA[%s/%s] "
++				 "in workgroup[%s]\n",
++				 __func__, v,
++				 account_domain,
++				 account_name,
++				 creds->computer_name,
++				 creds->account_name,
++				 workgroup));
++			TALLOC_FREE(frame);
++			return NT_STATUS_LOGON_FAILURE;
++		}
++	}
++	if (av_nb_dn != NULL) {
++		const char *v = NULL;
++
++		v = av_nb_dn->Value.AvNbDomainName;
++
++#ifdef SAMBA4_INTERNAL_HEIMDAL /* smbtorture4 for make test */
++		cmp = strcasecmp_m(workgroup, v);
++#else /* smbd */
++		cmp = StrCaseCmp(workgroup, v);
++#endif
++		if (cmp != 0) {
++			DEBUG(2,("%s: NTLMv2_RESPONSE with "
++				 "NbDomainName[%s] rejected "
++				 "for user[%s\\%s] "
++				 "against SEC_CHAN_WKSTA[%s/%s] "
++				 "in workgroup[%s]\n",
++				 __func__, v,
++				 account_domain,
++				 account_name,
++				 creds->computer_name,
++				 creds->account_name,
++				 workgroup));
++			TALLOC_FREE(frame);
++			return NT_STATUS_LOGON_FAILURE;
++		}
++	}
++
++	TALLOC_FREE(frame);
++	return NT_STATUS_OK;
++}
++
+ /***********************************************************
+  encode a password buffer with a unicode password.  The buffer
+  is filled with random data to make it harder to attack.
+diff --git a/libcli/auth/wscript_build b/libcli/auth/wscript_build
+index 0f0e22b..dce6c80 100644
+--- a/libcli/auth/wscript_build
++++ b/libcli/auth/wscript_build
+@@ -19,7 +19,7 @@ bld.SAMBA_SUBSYSTEM('MSRPC_PARSE',
+ 
+ bld.SAMBA_SUBSYSTEM('LIBCLI_AUTH',
+ 	source='credentials.c session.c smbencrypt.c smbdes.c',
+-	public_deps='MSRPC_PARSE',
++	public_deps='MSRPC_PARSE NDR_NTLMSSP',
+ 	public_headers='credentials.h:domain_credentials.h'
+ 	)
+ 
+diff --git a/source3/Makefile.in b/source3/Makefile.in
+index 2668a6b..d562d17 100644
+--- a/source3/Makefile.in
++++ b/source3/Makefile.in
+@@ -783,6 +783,7 @@ GROUPDB_OBJ = groupdb/mapping.o groupdb/mapping_tdb.o
+ PROFILE_OBJ = profile/profile.o
+ PROFILES_OBJ = utils/profiles.o \
+ 	       $(LIBSMB_ERR_OBJ) \
++	       $(LIBNDR_NTLMSSP_OBJ) \
+ 	       $(PARAM_OBJ) \
+                $(LIB_OBJ) $(LIB_DUMMY_OBJ) \
+                $(POPT_LIB_OBJ) \
+@@ -995,10 +996,10 @@ SWAT_OBJ = $(SWAT_OBJ1) $(PARAM_OBJ) $(PRINTING_OBJ) $(PRINTBASE_OBJ) $(LIBSMB_O
+ STATUS_OBJ = utils/status.o utils/status_profile.o \
+ 	     $(LOCKING_OBJ) $(PARAM_OBJ) \
+              $(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \
+-	     $(LIBSMB_ERR_OBJ) $(FNAME_UTIL_OBJ)
++	     $(LIBSMB_ERR_OBJ) $(LIBNDR_NTLMSSP_OBJ) $(FNAME_UTIL_OBJ)
+ 
+ SMBCONTROL_OBJ = utils/smbcontrol.o $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \
+-	$(LIBSMB_ERR_OBJ) $(POPT_LIB_OBJ) $(PRINTBASE_OBJ)
++	$(LIBSMB_ERR_OBJ) $(LIBNDR_NTLMSSP_OBJ) $(POPT_LIB_OBJ) $(PRINTBASE_OBJ)
+ 
+ SMBTREE_OBJ = utils/smbtree.o $(PARAM_OBJ) \
+              $(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(LIBSMB_OBJ) \
+@@ -1012,11 +1013,11 @@ SMBTREE_OBJ = utils/smbtree.o $(PARAM_OBJ) \
+ 
+ TESTPARM_OBJ = utils/testparm.o \
+                $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \
+-	       $(LIBSMB_ERR_OBJ)
++	       $(LIBSMB_ERR_OBJ) $(LIBNDR_NTLMSSP_OBJ)
+ 
+ SMBTA_UTIL_OBJ = utils/smbta-util.o $(PARAM_OBJ) $(POPT_LIB_OBJ) \
+ 	$(LIB_NONSMBD_OBJ) \
+-	$(LIBSMB_ERR_OBJ) $(FNAME_UTIL_OBJ)
++	$(LIBSMB_ERR_OBJ) $(LIBNDR_NTLMSSP_OBJ) $(FNAME_UTIL_OBJ)
+ 
+ TEST_LP_LOAD_OBJ = param/test_lp_load.o \
+ 		   $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \
+@@ -1146,6 +1147,7 @@ SMBCONFTORT_OBJ = $(SMBCONFTORT_OBJ0) \
+ 		  $(LIB_NONSMBD_OBJ) \
+ 		  $(PARAM_OBJ) \
+ 		  $(LIBSMB_ERR_OBJ) \
++		  $(LIBNDR_NTLMSSP_OBJ) \
+ 		  $(POPT_LIB_OBJ)
+ 
+ PTHREADPOOLTEST_OBJ = lib/pthreadpool/pthreadpool.o \
+@@ -1229,7 +1231,7 @@ CUPS_OBJ = client/smbspool.o $(PARAM_OBJ) $(LIBSMB_OBJ) \
+ 	  $(LIBNDR_GEN_OBJ0)
+ 
+ NMBLOOKUP_OBJ = utils/nmblookup.o $(PARAM_OBJ) $(LIBNMB_OBJ) \
+-               $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) $(LIBSMB_ERR_OBJ)
++               $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) $(LIBSMB_ERR_OBJ) $(LIBNDR_NTLMSSP_OBJ)
+ 
+ SMBTORTURE_OBJ1 = torture/torture.o torture/nbio.o torture/scanner.o torture/utable.o \
+ 		torture/denytest.o torture/mangle_test.o \
+@@ -1253,6 +1255,7 @@ MASKTEST_OBJ = torture/masktest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \
+ 		 $(LIBNDR_GEN_OBJ0)
+ 
+ MSGTEST_OBJ = torture/msgtest.o $(PARAM_OBJ) $(LIBSMB_ERR_OBJ) \
++		 $(LIBNDR_NTLMSSP_OBJ) \
+                  $(LIB_NONSMBD_OBJ) \
+ 		 $(LIBNDR_GEN_OBJ0)
+ 
+@@ -1269,7 +1272,7 @@ PDBTEST_OBJ = torture/pdbtest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \
+ 
+ VFSTEST_OBJ = torture/cmd_vfs.o torture/vfstest.o $(SMBD_OBJ_BASE) $(READLINE_OBJ)
+ 
+-SMBICONV_OBJ = $(PARAM_OBJ) torture/smbiconv.o $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) $(LIBSMB_ERR_OBJ)
++SMBICONV_OBJ = $(PARAM_OBJ) torture/smbiconv.o $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) $(LIBSMB_ERR_OBJ) $(LIBNDR_NTLMSSP_OBJ)
+ 
+ LOG2PCAP_OBJ = utils/log2pcaphex.o
+ 
+@@ -1297,17 +1300,17 @@ SMBCQUOTAS_OBJ = utils/smbcquotas.o $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \
+ EVTLOGADM_OBJ0	= utils/eventlogadm.o
+ 
+ EVTLOGADM_OBJ	= $(EVTLOGADM_OBJ0) $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \
+-		$(LIBSMB_ERR_OBJ) $(LIB_EVENTLOG_OBJ) \
++		$(LIBSMB_ERR_OBJ) $(LIBNDR_NTLMSSP_OBJ) $(LIB_EVENTLOG_OBJ) \
+ 		librpc/gen_ndr/ndr_eventlog.o \
+ 		librpc/gen_ndr/ndr_lsa.o
+ 
+ SHARESEC_OBJ0 = utils/sharesec.o
+ SHARESEC_OBJ  = $(SHARESEC_OBJ0) $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \
+-		$(LIBSMB_ERR_OBJ) \
++		$(LIBSMB_ERR_OBJ) $(LIBNDR_NTLMSSP_OBJ) \
+                 $(POPT_LIB_OBJ)
+ 
+ TALLOCTORT_OBJ = @tallocdir@/testsuite.o @tallocdir@/testsuite_main.o \
+-		$(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(LIBSMB_ERR_OBJ)
++		$(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(LIBSMB_ERR_OBJ) $(LIBNDR_NTLMSSP_OBJ)
+ 
+ REPLACETORT_OBJ = @libreplacedir@/test/testsuite.o \
+ 		@libreplacedir@/test/getifaddrs.o \
+@@ -1323,7 +1326,7 @@ SMBFILTER_OBJ = utils/smbfilter.o $(PARAM_OBJ) $(LIBSMB_OBJ) \
+ 		 $(LIBNDR_GEN_OBJ0)
+ 
+ WINBIND_WINS_NSS_OBJ = ../nsswitch/wins.o $(PARAM_OBJ) \
+-	$(LIB_NONSMBD_OBJ) $(LIBSMB_ERR_OBJ) $(LIBNMB_OBJ)
++	$(LIB_NONSMBD_OBJ) $(LIBSMB_ERR_OBJ) $(LIBNDR_NTLMSSP_OBJ) $(LIBNMB_OBJ)
+ 
+ PAM_SMBPASS_OBJ_0 = pam_smbpass/pam_smb_auth.o pam_smbpass/pam_smb_passwd.o \
+ 		pam_smbpass/pam_smb_acct.o pam_smbpass/support.o ../lib/util/asn1.o
+@@ -1531,12 +1534,14 @@ RPC_OPEN_TCP_OBJ = torture/rpc_open_tcp.o \
+ DBWRAP_TOOL_OBJ = utils/dbwrap_tool.o \
+ 		  $(PARAM_OBJ) \
+ 		  $(LIB_NONSMBD_OBJ) \
+-		  $(LIBSMB_ERR_OBJ)
++		  $(LIBSMB_ERR_OBJ) \
++		  $(LIBNDR_NTLMSSP_OBJ)
+ 
+ DBWRAP_TORTURE_OBJ = utils/dbwrap_torture.o \
+ 		     $(PARAM_OBJ) \
+ 		     $(LIB_NONSMBD_OBJ) \
+ 		     $(LIBSMB_ERR_OBJ) \
++		     $(LIBNDR_NTLMSSP_OBJ) \
+ 		     $(POPT_LIB_OBJ)
+ 
+ SPLIT_TOKENS_OBJ = utils/split_tokens.o \
+-- 
+2.8.1
+
+
+From 138ca374deab8758c63547cc78385e240ae20971 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Wed, 9 Dec 2015 13:12:43 +0100
+Subject: [PATCH 05/15] CVE-2016-2111: s3:rpc_server/netlogon: check
+ NTLMv2_RESPONSE values for SEC_CHAN_WKSTA
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This prevents spoofing like Microsoft's CVE-2015-0005.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+---
+ source3/rpc_server/netlogon/srv_netlog_nt.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c
+index 30e1bc0..a630b47 100644
+--- a/source3/rpc_server/netlogon/srv_netlog_nt.c
++++ b/source3/rpc_server/netlogon/srv_netlog_nt.c
+@@ -1508,6 +1508,7 @@ static NTSTATUS _netr_LogonSamLogon_base(struct pipes_struct *p,
+ 	case NetlogonNetworkTransitiveInformation:
+ 	{
+ 		const char *wksname = nt_workstation;
++		const char *workgroup = lp_workgroup();
+ 
+ 		status = make_auth_context_fixed(talloc_tos(), &auth_context,
+ 						 logon->network->challenge);
+@@ -1532,6 +1533,14 @@ static NTSTATUS _netr_LogonSamLogon_base(struct pipes_struct *p,
+ 						     logon->network->nt.length)) {
+ 			status = NT_STATUS_NO_MEMORY;
+ 		}
++
++		if (NT_STATUS_IS_OK(status)) {
++			status = NTLMv2_RESPONSE_verify_netlogon_creds(
++						user_info->client.account_name,
++						user_info->client.domain_name,
++						user_info->password.response.nt,
++						creds, workgroup);
++		}
+ 		break;
+ 	}
+ 	case NetlogonInteractiveInformation:
+-- 
+2.8.1
+
+
+From 120d4c156325fc8990ad10d24dd8261555e700ee Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Sat, 26 Mar 2016 22:24:23 +0100
+Subject: [PATCH 06/15] CVE-2016-2111: s4:torture/raw: don't use ntlmv2 for dos
+ connection in raw.samba3badpath
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Alexander Bokovoy <ab at samba.org>
+---
+ source4/torture/raw/samba3misc.c | 20 ++++++++++++--------
+ 1 file changed, 12 insertions(+), 8 deletions(-)
+
+diff --git a/source4/torture/raw/samba3misc.c b/source4/torture/raw/samba3misc.c
+index a603111..b99d40f 100644
+--- a/source4/torture/raw/samba3misc.c
++++ b/source4/torture/raw/samba3misc.c
+@@ -340,6 +340,7 @@ bool torture_samba3_badpath(struct torture_context *torture)
+ 	bool ret = true;
+ 	TALLOC_CTX *mem_ctx;
+ 	bool nt_status_support;
++	bool client_ntlmv2_auth;
+ 
+ 	if (!(mem_ctx = talloc_init("torture_samba3_badpath"))) {
+ 		d_printf("talloc_init failed\n");
+@@ -347,20 +348,17 @@ bool torture_samba3_badpath(struct torture_context *torture)
+ 	}
+ 
+ 	nt_status_support = lpcfg_nt_status_support(torture->lp_ctx);
++	client_ntlmv2_auth = lpcfg_client_ntlmv2_auth(torture->lp_ctx);
+ 
+-	if (!lpcfg_set_cmdline(torture->lp_ctx, "nt status support", "yes")) {
+-		printf("Could not set 'nt status support = yes'\n");
+-		goto fail;
+-	}
++	torture_assert_goto(torture, lpcfg_set_cmdline(torture->lp_ctx, "nt status support", "yes"), ret, fail, "Could not set 'nt status support = yes'\n");
++	torture_assert_goto(torture, lpcfg_set_cmdline(torture->lp_ctx, "client ntlmv2 auth", "yes"), ret, fail, "Could not set 'client ntlmv2 auth = yes'\n");
+ 
+ 	if (!torture_open_connection(&cli_nt, torture, 0)) {
+ 		goto fail;
+ 	}
+ 
+-	if (!lpcfg_set_cmdline(torture->lp_ctx, "nt status support", "no")) {
+-		printf("Could not set 'nt status support = yes'\n");
+-		goto fail;
+-	}
++	torture_assert_goto(torture, lpcfg_set_cmdline(torture->lp_ctx, "nt status support", "no"), ret, fail, "Could not set 'nt status support = no'\n");
++	torture_assert_goto(torture, lpcfg_set_cmdline(torture->lp_ctx, "client ntlmv2 auth", "no"), ret, fail, "Could not set 'client ntlmv2 auth = no'\n");
+ 
+ 	if (!torture_open_connection(&cli_dos, torture, 1)) {
+ 		goto fail;
+@@ -373,6 +371,12 @@ bool torture_samba3_badpath(struct torture_context *torture)
+ 	}
+ 
+ 	smbcli_deltree(cli_nt->tree, dirname);
++	torture_assert_goto(torture, lpcfg_set_cmdline(torture->lp_ctx, "nt status support",
++						       nt_status_support ? "yes":"no"),
++			    ret, fail, "Could not set 'nt status support' back to where it was\n");
++	torture_assert_goto(torture, lpcfg_set_cmdline(torture->lp_ctx, "client ntlmv2 auth",
++						       client_ntlmv2_auth ? "yes":"no"),
++			    ret, fail, "Could not set 'client ntlmv2 auth' back to where it was\n");
+ 
+ 	status = smbcli_mkdir(cli_nt->tree, dirname);
+ 	if (!NT_STATUS_IS_OK(status)) {
+-- 
+2.8.1
+
+
+From 905d32faf30377269f5e4b4795b980482d421c62 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Sat, 26 Mar 2016 22:24:23 +0100
+Subject: [PATCH 07/15] CVE-2016-2111: s4:torture/base: don't use ntlmv2 for
+ dos connection in base.samba3error
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Alexander Bokovoy <ab at samba.org>
+---
+ source4/torture/basic/base.c | 19 +++++++++++++++++--
+ 1 file changed, 17 insertions(+), 2 deletions(-)
+
+diff --git a/source4/torture/basic/base.c b/source4/torture/basic/base.c
+index d7bac45..7f74bb9 100644
+--- a/source4/torture/basic/base.c
++++ b/source4/torture/basic/base.c
+@@ -1476,6 +1476,7 @@ static bool torture_chkpath_test(struct torture_context *tctx,
+ static bool torture_samba3_errorpaths(struct torture_context *tctx)
+ {
+ 	bool nt_status_support;
++	bool client_ntlmv2_auth;
+ 	struct smbcli_state *cli_nt = NULL, *cli_dos = NULL;
+ 	bool result = false;
+ 	int fnum;
+@@ -1485,18 +1486,27 @@ static bool torture_samba3_errorpaths(struct torture_context *tctx)
+ 	NTSTATUS status;
+ 
+ 	nt_status_support = lpcfg_nt_status_support(tctx->lp_ctx);
++	client_ntlmv2_auth = lpcfg_client_ntlmv2_auth(tctx->lp_ctx);
+ 
+ 	if (!lpcfg_set_cmdline(tctx->lp_ctx, "nt status support", "yes")) {
+ 		torture_comment(tctx, "Could not set 'nt status support = yes'\n");
+ 		goto fail;
+ 	}
++	if (!lpcfg_set_cmdline(tctx->lp_ctx, "client ntlmv2 auth", "yes")) {
++		torture_result(tctx, TORTURE_FAIL, "Could not set 'client ntlmv2 auth = yes'\n");
++		goto fail;
++	}
+ 
+ 	if (!torture_open_connection(&cli_nt, tctx, 0)) {
+ 		goto fail;
+ 	}
+ 
+ 	if (!lpcfg_set_cmdline(tctx->lp_ctx, "nt status support", "no")) {
+-		torture_comment(tctx, "Could not set 'nt status support = yes'\n");
++		torture_result(tctx, TORTURE_FAIL, "Could not set 'nt status support = no'\n");
++		goto fail;
++	}
++	if (!lpcfg_set_cmdline(tctx->lp_ctx, "client ntlmv2 auth", "no")) {
++		torture_result(tctx, TORTURE_FAIL, "Could not set 'client ntlmv2 auth = no'\n");
+ 		goto fail;
+ 	}
+ 
+@@ -1506,7 +1516,12 @@ static bool torture_samba3_errorpaths(struct torture_context *tctx)
+ 
+ 	if (!lpcfg_set_cmdline(tctx->lp_ctx, "nt status support",
+ 			    nt_status_support ? "yes":"no")) {
+-		torture_comment(tctx, "Could not reset 'nt status support = yes'");
++		torture_result(tctx, TORTURE_FAIL, "Could not reset 'nt status support'");
++		goto fail;
++	}
++	if (!lpcfg_set_cmdline(tctx->lp_ctx, "client ntlmv2 auth",
++			       client_ntlmv2_auth ? "yes":"no")) {
++		torture_result(tctx, TORTURE_FAIL, "Could not reset 'client ntlmv2 auth'");
+ 		goto fail;
+ 	}
+ 
+-- 
+2.8.1
+
+
+From 98ef79d88eb504ab337ce745bf1c2ac4bcffb86b Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Sat, 26 Mar 2016 18:08:16 +0100
+Subject: [PATCH 08/15] CVE-2016-2111: s3:libsmb: don't send a raw NTLMv2
+ response when we want to use spnego
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Alexander Bokovoy <ab at samba.org>
+---
+ source3/libsmb/cliconnect.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
+index 8653ba7..4c0abdf 100644
+--- a/source3/libsmb/cliconnect.c
++++ b/source3/libsmb/cliconnect.c
+@@ -2077,6 +2077,17 @@ NTSTATUS cli_session_setup(struct cli_state *cli,
+ 		NTSTATUS status;
+ 
+ 		/* otherwise do a NT1 style session setup */
++		if (lp_client_ntlmv2_auth() && lp_client_use_spnego()) {
++			/*
++			 * Don't send an NTLMv2 response without NTLMSSP
++			 * if we want to use spnego support
++			 */
++			DEBUG(1, ("Server does not support EXTENDED_SECURITY "
++				  " but 'client use spnego = yes"
++				  " and 'client ntlmv2 auth = yes'\n"));
++			return NT_STATUS_ACCESS_DENIED;
++		}
++
+ 		status = cli_session_setup_nt1(cli, user, pass, passlen,
+ 					       ntpass, ntpasslen, workgroup);
+ 		if (!NT_STATUS_IS_OK(status)) {
+-- 
+2.8.1
+
+
+From 2c6d69015bfa7bd1d0d8b55eb98677a43bdc5336 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Sun, 27 Mar 2016 01:09:05 +0100
+Subject: [PATCH 09/15] CVE-2016-2111: docs-xml: document the new "client
+ NTLMv2 auth" and "client use spnego" interaction
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Alexander Bokovoy <ab at samba.org>
+---
+ docs-xml/smbdotconf/protocol/clientusespnego.xml  | 5 +++++
+ docs-xml/smbdotconf/security/clientntlmv2auth.xml | 5 +++++
+ 2 files changed, 10 insertions(+)
+
+diff --git a/docs-xml/smbdotconf/protocol/clientusespnego.xml b/docs-xml/smbdotconf/protocol/clientusespnego.xml
+index c688a65..e538745 100644
+--- a/docs-xml/smbdotconf/protocol/clientusespnego.xml
++++ b/docs-xml/smbdotconf/protocol/clientusespnego.xml
+@@ -9,6 +9,11 @@
+     supporting servers (including WindowsXP, Windows2000 and Samba
+     3.0) to agree upon an authentication
+     mechanism.  This enables Kerberos authentication in particular.</para>
++
++    <para>When <smbconfoption name="client NTLMv2 auth"/> is also set to
++    <constant>yes</constant> extended security (SPNEGO) is required
++    in order to use NTLMv2 only within NTLMSSP. This behavior was
++    introduced with the patches for CVE-2016-2111.</para>
+ </description>
+ 
+ <value type="default">yes</value>
+diff --git a/docs-xml/smbdotconf/security/clientntlmv2auth.xml b/docs-xml/smbdotconf/security/clientntlmv2auth.xml
+index b151df2..1b6d887 100644
+--- a/docs-xml/smbdotconf/security/clientntlmv2auth.xml
++++ b/docs-xml/smbdotconf/security/clientntlmv2auth.xml
+@@ -28,6 +28,11 @@
+     NTLMv2 by default, and some sites (particularly those following
+     'best practice' security polices) only allow NTLMv2 responses, and
+     not the weaker LM or NTLM.</para>
++
++    <para>When <smbconfoption name="client use spnego"/> is also set to
++    <constant>yes</constant> extended security (SPNEGO) is required
++    in order to use NTLMv2 only within NTLMSSP. This behavior was
++    introduced with the patches for CVE-2016-2111.</para>
+ </description>
+ <value type="default">yes</value>
+ </samba:parameter>
+-- 
+2.8.1
+
+
+From 18065d539f941c6a4042a1af3741313340f5065b Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Tue, 15 Mar 2016 21:02:34 +0100
+Subject: [PATCH 10/15] CVE-2016-2111: docs-xml: add "raw NTLMv2 auth"
+ defaulting to "yes"
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+---
+ docs-xml/smbdotconf/security/rawntlmv2auth.xml | 20 ++++++++++++++++++++
+ source3/include/proto.h                        |  1 +
+ source3/param/loadparm.c                       |  3 +++
+ 3 files changed, 24 insertions(+)
+ create mode 100644 docs-xml/smbdotconf/security/rawntlmv2auth.xml
+
+diff --git a/docs-xml/smbdotconf/security/rawntlmv2auth.xml b/docs-xml/smbdotconf/security/rawntlmv2auth.xml
+new file mode 100644
+index 0000000..ef26297
+--- /dev/null
++++ b/docs-xml/smbdotconf/security/rawntlmv2auth.xml
+@@ -0,0 +1,20 @@
++<samba:parameter name="raw NTLMv2 auth"
++                 context="G"
++                 type="boolean"
++                 xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
++<description>
++    <para>This parameter determines whether or not <citerefentry><refentrytitle>smbd</refentrytitle>
++    <manvolnum>8</manvolnum></citerefentry> will allow SMB1 clients without
++    extended security (without SPNEGO) to use NTLMv2 authentication.</para>
++
++    <para>If this option, <command moreinfo="none">lanman auth</command>
++    and <command moreinfo="none">ntlm auth</command> are all disabled,
++    then only clients with SPNEGO support will be permitted.
++    That means NTLMv2 is only supported within NTLMSSP.</para>
++
++    <para>Note that the default will change to "no" with Samba 4.5.</para>
++</description>
++
++<value type="default">yes</value>
++<value type="example">no</value>
++</samba:parameter>
+diff --git a/source3/include/proto.h b/source3/include/proto.h
+index 8491d54..32b4e3d 100644
+--- a/source3/include/proto.h
++++ b/source3/include/proto.h
+@@ -1489,6 +1489,7 @@ bool lp_map_untrusted_to_domain(void);
+ int lp_restrict_anonymous(void);
+ bool lp_lanman_auth(void);
+ bool lp_ntlm_auth(void);
++bool lp_raw_ntlmv2_auth(void);
+ bool lp_client_plaintext_auth(void);
+ bool lp_client_lanman_auth(void);
+ bool lp_client_ntlmv2_auth(void);
+diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
+index 753252a..42ddcf5 100644
+--- a/source3/param/loadparm.c
++++ b/source3/param/loadparm.c
+@@ -336,6 +336,7 @@ struct global {
+ 	bool bAllowTrustedDomains;
+ 	bool bLanmanAuth;
+ 	bool bNTLMAuth;
++	bool bRawNTLMv2Auth;
+ 	bool bUseSpnego;
+ 	bool bClientLanManAuth;
+ 	bool bClientNTLMv2Auth;
+@@ -5337,6 +5338,7 @@ static void init_globals(bool reinit_globals)
+ 	Globals.bClientPlaintextAuth = False;	/* Do NOT use a plaintext password even if is requested by the server */
+ 	Globals.bLanmanAuth = False;	/* Do NOT use the LanMan hash, even if it is supplied */
+ 	Globals.bNTLMAuth = True;	/* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
++	Globals.bRawNTLMv2Auth = true;	/* Allow NTLMv2 without NTLMSSP */
+ 	Globals.bClientNTLMv2Auth = True; /* Client should always use use NTLMv2, as we can't tell that the server supports it, but most modern servers do */
+ 	/* Note, that we will also use NTLM2 session security (which is different), if it is available */
+ 
+@@ -5819,6 +5821,7 @@ FN_GLOBAL_BOOL(lp_map_untrusted_to_domain, &Globals.bMapUntrustedToDomain)
+ FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
+ FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
+ FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
++FN_GLOBAL_BOOL(lp_raw_ntlmv2_auth, &Globals.bRawNTLMv2Auth)
+ FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
+ FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
+ FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
+-- 
+2.8.1
+
+
+From 13bf1551e1fa25aa3d0d10192869d70da6ee556a Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Tue, 15 Mar 2016 21:02:34 +0100
+Subject: [PATCH 11/15] CVE-2016-2111(<=4.3): loadparm: add "raw NTLMv2 auth"
+ to param_table
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+Reviewed-by: Ralph Boehme <slow at samba.org>
+---
+ source3/param/loadparm.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
+index 42ddcf5..f806788 100644
+--- a/source3/param/loadparm.c
++++ b/source3/param/loadparm.c
+@@ -1384,6 +1384,15 @@ static struct parm_struct parm_table[] = {
+ 		.flags		= FLAG_ADVANCED,
+ 	},
+ 	{
++		.label		= "raw NTLMv2 auth",
++		.type		= P_BOOL,
++		.p_class	= P_GLOBAL,
++		.ptr		= &Globals.bRawNTLMv2Auth,
++		.special	= NULL,
++		.enum_list	= NULL,
++		.flags		= FLAG_ADVANCED,
++	},
++	{
+ 		.label		= "client NTLMv2 auth",
+ 		.type		= P_BOOL,
+ 		.p_class	= P_GLOBAL,
+-- 
+2.8.1
+
+
+From ed20bcd8047bdc120650a29f3e87b60f0384f152 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Tue, 1 Mar 2016 10:25:54 +0100
+Subject: [PATCH 12/15] CVE-2016-2111: s3:auth: implement "raw NTLMv2 auth"
+ checks
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+---
+ source3/auth/auth_util.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
+index 288f461..98bbbef 100644
+--- a/source3/auth/auth_util.c
++++ b/source3/auth/auth_util.c
+@@ -30,6 +30,7 @@
+ #include "../lib/util/util_pw.h"
+ #include "lib/winbind_util.h"
+ #include "passdb.h"
++#include "../lib/tsocket/tsocket.h"
+ 
+ #undef DBGC_CLASS
+ #define DBGC_CLASS DBGC_AUTH
+@@ -367,6 +368,19 @@ NTSTATUS make_user_info_for_reply_enc(struct auth_usersupplied_info **user_info,
+                                       const char *client_domain, 
+                                       DATA_BLOB lm_resp, DATA_BLOB nt_resp)
+ {
++	bool allow_raw = lp_raw_ntlmv2_auth();
++
++	if (!allow_raw && nt_resp.length >= 48) {
++		/*
++		 * NTLMv2_RESPONSE has at least 48 bytes
++		 * and should only be supported via NTLMSSP.
++		 */
++		DEBUG(2,("Rejecting raw NTLMv2 authentication with "
++			 "user [%s\\%s]\n",
++			 client_domain, smb_name));
++		return NT_STATUS_INVALID_PARAMETER;
++	}
++
+ 	return make_user_info_map(user_info, smb_name, 
+ 				  client_domain, 
+ 				  get_remote_machine_name(), 
+-- 
+2.8.1
+
+
+From c68847ec3bba2e9e0aae179ff176c4c804f4af3a Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Sat, 26 Mar 2016 22:08:38 +0100
+Subject: [PATCH 13/15] CVE-2016-2111: selftest:Samba3: use "raw NTLMv2 auth =
+ yes" for s3dc
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Alexander Bokovoy <ab at samba.org>
+---
+ selftest/target/Samba3.pm | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
+index 01a1c47..ee3696e 100644
+--- a/selftest/target/Samba3.pm
++++ b/selftest/target/Samba3.pm
+@@ -127,6 +127,7 @@ sub setup_dc($$)
+ 	domain master = yes
+ 	domain logons = yes
+ 	lanman auth = yes
++	raw NTLMv2 auth = yes
+ ";
+ 
+ 	my $vars = $self->provision($path,
+-- 
+2.8.1
+
+
+From 33248b5ebfe6335f217dfd0bfc3a018482077011 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Tue, 15 Mar 2016 21:59:42 +0100
+Subject: [PATCH 14/15] CVE-2016-2111: docs-xml/smbdotconf: default "raw NTLMv2
+ auth" to "no"
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Alexander Bokovoy <ab at samba.org>
+---
+ docs-xml/smbdotconf/security/rawntlmv2auth.xml | 7 +++----
+ source3/param/loadparm.c                       | 2 +-
+ 2 files changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/docs-xml/smbdotconf/security/rawntlmv2auth.xml b/docs-xml/smbdotconf/security/rawntlmv2auth.xml
+index ef26297..30e7280 100644
+--- a/docs-xml/smbdotconf/security/rawntlmv2auth.xml
++++ b/docs-xml/smbdotconf/security/rawntlmv2auth.xml
+@@ -11,10 +11,9 @@
+     and <command moreinfo="none">ntlm auth</command> are all disabled,
+     then only clients with SPNEGO support will be permitted.
+     That means NTLMv2 is only supported within NTLMSSP.</para>
+-
+-    <para>Note that the default will change to "no" with Samba 4.5.</para>
+ </description>
+ 
+-<value type="default">yes</value>
+-<value type="example">no</value>
++<related>lanman auth</related>
++<related>ntlm auth</related>
++<value type="default">no</value>
+ </samba:parameter>
+diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
+index f806788..7065cf6 100644
+--- a/source3/param/loadparm.c
++++ b/source3/param/loadparm.c
+@@ -5347,7 +5347,7 @@ static void init_globals(bool reinit_globals)
+ 	Globals.bClientPlaintextAuth = False;	/* Do NOT use a plaintext password even if is requested by the server */
+ 	Globals.bLanmanAuth = False;	/* Do NOT use the LanMan hash, even if it is supplied */
+ 	Globals.bNTLMAuth = True;	/* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
+-	Globals.bRawNTLMv2Auth = true;	/* Allow NTLMv2 without NTLMSSP */
++	Globals.bRawNTLMv2Auth = false;	/* Allow NTLMv2 without NTLMSSP */
+ 	Globals.bClientNTLMv2Auth = True; /* Client should always use use NTLMv2, as we can't tell that the server supports it, but most modern servers do */
+ 	/* Note, that we will also use NTLM2 session security (which is different), if it is available */
+ 
+-- 
+2.8.1
+
+
+From 898e2ff88b7e370c88c9e30d1238eeed760619a5 Mon Sep 17 00:00:00 2001
+From: Andreas Schneider <asn at samba.org>
+Date: Mon, 4 Apr 2016 16:44:39 +0200
+Subject: [PATCH 15/15] CVE-2016-2111: s3:selftest: Disable client ntlmv2 auth
+ for secserver
+
+The client connects with ntlmv1 to the secserver (server with
+security = share). So the secserver needs to allow to connect with
+NTLMv1 to the password server to verify the user or it will fail.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749
+
+Signed-off-by: Andreas Schneider <asn at samba.org>
+---
+ selftest/target/Samba3.pm | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
+index ee3696e..7326b22 100644
+--- a/selftest/target/Samba3.pm
++++ b/selftest/target/Samba3.pm
+@@ -231,6 +231,7 @@ sub setup_secserver($$$)
+ 	my $secserver_options = "
+ 	security = server
+         password server = $s3dcvars->{SERVER_IP}
++	client ntlmv2 auth = no
+ ";
+ 
+ 	my $ret = $self->provision($prefix,
+-- 
+2.8.1
+
diff --git a/debian/patches/CVE-2016-2112-v3-6.patch b/debian/patches/CVE-2016-2112-v3-6.patch
new file mode 100644
index 0000000..acaab89
--- /dev/null
+++ b/debian/patches/CVE-2016-2112-v3-6.patch
@@ -0,0 +1,184 @@
+From 92484160212322d6246b71145e683faa79bbbeab Mon Sep 17 00:00:00 2001
+From: Andreas Schneider <asn at cryptomilk.org>
+Date: Wed, 30 Mar 2016 16:55:44 +0200
+Subject: [PATCH 1/3] CVE-2016-2112: s3:ntlmssp: Implement missing
+ ntlmssp_have_feature()
+
+Signed-off-by: Andreas Schneider <asn at samba.org>
+---
+ source3/include/proto.h  |  1 +
+ source3/libsmb/ntlmssp.c | 30 ++++++++++++++++++++++++++++++
+ 2 files changed, 31 insertions(+)
+
+diff --git a/source3/include/proto.h b/source3/include/proto.h
+index 32b4e3d..43008ea 100644
+--- a/source3/include/proto.h
++++ b/source3/include/proto.h
+@@ -1260,6 +1260,7 @@ NTSTATUS ntlmssp_set_password(struct ntlmssp_state *ntlmssp_state, const char *p
+ NTSTATUS ntlmssp_set_domain(struct ntlmssp_state *ntlmssp_state, const char *domain) ;
+ void ntlmssp_want_feature_list(struct ntlmssp_state *ntlmssp_state, char *feature_list);
+ void ntlmssp_want_feature(struct ntlmssp_state *ntlmssp_state, uint32_t feature);
++bool ntlmssp_have_feature(struct ntlmssp_state *ntlmssp_state, uint32_t feature);
+ NTSTATUS ntlmssp_update(struct ntlmssp_state *ntlmssp_state,
+ 			const DATA_BLOB in, DATA_BLOB *out) ;
+ NTSTATUS ntlmssp_server_start(TALLOC_CTX *mem_ctx,
+diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c
+index 5b7db89..d31ae67 100644
+--- a/source3/libsmb/ntlmssp.c
++++ b/source3/libsmb/ntlmssp.c
+@@ -162,6 +162,36 @@ NTSTATUS ntlmssp_set_domain(struct ntlmssp_state *ntlmssp_state, const char *dom
+ 	return NT_STATUS_OK;
+ }
+ 
++bool ntlmssp_have_feature(struct ntlmssp_state *ntlmssp_state,
++			  uint32_t feature)
++{
++	if (feature & NTLMSSP_FEATURE_SIGN) {
++		if (ntlmssp_state->session_key.length == 0) {
++			return false;
++		}
++		if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN) {
++			return true;
++		}
++	}
++
++	if (feature & NTLMSSP_FEATURE_SEAL) {
++		if (ntlmssp_state->session_key.length == 0) {
++			return false;
++		}
++		if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL) {
++			return true;
++		}
++	}
++
++	if (feature & NTLMSSP_FEATURE_SESSION_KEY) {
++		if (ntlmssp_state->session_key.length > 0) {
++			return true;
++		}
++	}
++
++	return false;
++}
++
+ /**
+  * Request features for the NTLMSSP negotiation
+  *
+-- 
+2.8.1
+
+
+From 641060a92762c3f1c22837ce9515ad9503a344d5 Mon Sep 17 00:00:00 2001
+From: Ralph Boehme <slow at samba.org>
+Date: Thu, 24 Mar 2016 16:22:36 +0100
+Subject: [PATCH 2/3] CVE-2016-2112: s3:libads: make sure we detect downgrade
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644
+
+Pair-programmed-with: Ralph Boehme <slow at samba.org>
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Signed-off-by: Ralph Boehme <slow at samba.org>
+---
+ source3/libads/sasl.c | 31 +++++++++++++++++++++++++++++++
+ 1 file changed, 31 insertions(+)
+
+diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c
+index e7daa8a..6690f83 100644
+--- a/source3/libads/sasl.c
++++ b/source3/libads/sasl.c
+@@ -261,6 +261,37 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads)
+ 	/* we have a reference conter on ntlmssp_state, if we are signing
+ 	   then the state will be kept by the signing engine */
+ 
++	if (ads->ldap.wrap_type >= ADS_SASLWRAP_TYPE_SEAL) {
++		bool ok;
++
++		ok = ntlmssp_have_feature(ntlmssp_state,
++					  NTLMSSP_FEATURE_SEAL);
++		if (!ok) {
++			DEBUG(0,("The ntlmssp feature sealing request, but unavailable\n"));
++			TALLOC_FREE(ntlmssp_state);
++			return ADS_ERROR_NT(NT_STATUS_INVALID_NETWORK_RESPONSE);
++		}
++
++		ok = ntlmssp_have_feature(ntlmssp_state,
++					  NTLMSSP_FEATURE_SIGN);
++		if (!ok) {
++			DEBUG(0,("The ntlmssp feature signing request, but unavailable\n"));
++			TALLOC_FREE(ntlmssp_state);
++			return ADS_ERROR_NT(NT_STATUS_INVALID_NETWORK_RESPONSE);
++		}
++
++	} else if (ads->ldap.wrap_type >= ADS_SASLWRAP_TYPE_SIGN) {
++		bool ok;
++
++		ok = ntlmssp_have_feature(ntlmssp_state,
++					  NTLMSSP_FEATURE_SIGN);
++		if (!ok) {
++			DEBUG(0,("The gensec feature signing request, but unavailable\n"));
++			TALLOC_FREE(ntlmssp_state);
++			return ADS_ERROR_NT(NT_STATUS_INVALID_NETWORK_RESPONSE);
++		}
++	}
++
+ 	if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) {
+ 		ads->ldap.out.max_unwrapped = ADS_SASL_WRAPPING_OUT_MAX_WRAPPED - NTLMSSP_SIG_SIZE;
+ 		ads->ldap.out.sig_size = NTLMSSP_SIG_SIZE;
+-- 
+2.8.1
+
+
+From aa4dde5ce112083282147d61561b45c740f05cab Mon Sep 17 00:00:00 2001
+From: Andrew Bartlett <abartlet at samba.org>
+Date: Fri, 5 Sep 2014 17:38:38 +1200
+Subject: [PATCH 3/3] CVE-2016-2112: winbindd: Change value of "ldap sasl
+ wrapping" to sign
+
+This is to disrupt MITM attacks between us and our DC
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644
+
+Pair-programmed-with: Garming Sam <garming at catalyst.net.nz>
+Signed-off-by: Garming Sam <garming at catalyst.net.nz>
+Signed-off-by: Andrew Bartlett <abartlet at samba.org>
+(backported from commit afe02d12f444ad9a6abf31a61f578320520263a9)
+---
+ docs-xml/smbdotconf/ldap/clientldapsaslwrapping.xml | 8 +++-----
+ source3/param/loadparm.c                            | 2 ++
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/docs-xml/smbdotconf/ldap/clientldapsaslwrapping.xml b/docs-xml/smbdotconf/ldap/clientldapsaslwrapping.xml
+index a926cec..a7c4395 100644
+--- a/docs-xml/smbdotconf/ldap/clientldapsaslwrapping.xml
++++ b/docs-xml/smbdotconf/ldap/clientldapsaslwrapping.xml
+@@ -34,11 +34,9 @@
+ 	</para>
+ 
+ 	<para>
+-	The default value is <emphasis>plain</emphasis> which is not irritable 
+-	to KRB5 clock skew errors. That implies synchronizing the time
+-	with the KDC in the case of using <emphasis>sign</emphasis> or 
+-	<emphasis>seal</emphasis>.
++	The default value is <emphasis>sign</emphasis>. That implies synchronizing the time
++	with the KDC in the case of using <emphasis>Kerberos</emphasis>.
+ 	</para>
+ </description>
+-<value type="default">plain</value>
++<value type="default">sign</value>
+ </samba:parameter>
+diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
+index 7065cf6..c5249b7 100644
+--- a/source3/param/loadparm.c
++++ b/source3/param/loadparm.c
+@@ -5392,6 +5392,8 @@ static void init_globals(bool reinit_globals)
+ 	Globals.ldap_debug_level = 0;
+ 	Globals.ldap_debug_threshold = 10;
+ 
++	Globals.client_ldap_sasl_wrapping = ADS_AUTH_SASL_SIGN;
++
+ 	/* This is what we tell the afs client. in reality we set the token 
+ 	 * to never expire, though, when this runs out the afs client will 
+ 	 * forget the token. Set to 0 to get NEVERDATE.*/
+-- 
+2.8.1
+
diff --git a/debian/patches/CVE-2016-2115-v3-6.patch b/debian/patches/CVE-2016-2115-v3-6.patch
new file mode 100644
index 0000000..82514c4
--- /dev/null
+++ b/debian/patches/CVE-2016-2115-v3-6.patch
@@ -0,0 +1,359 @@
+From daead519703ca6953cd033d35b503549967e4d80 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Sat, 27 Feb 2016 03:43:58 +0100
+Subject: [PATCH 1/4] CVE-2016-2115: docs-xml: add "client ipc signing" option
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11756
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Ralph Boehme <slow at samba.org>
+---
+ docs-xml/smbdotconf/security/clientipcsigning.xml | 23 +++++++++++++++++++++++
+ docs-xml/smbdotconf/security/clientsigning.xml    |  3 +++
+ source3/include/proto.h                           |  1 +
+ source3/param/loadparm.c                          | 12 ++++++++++++
+ 4 files changed, 39 insertions(+)
+ create mode 100644 docs-xml/smbdotconf/security/clientipcsigning.xml
+
+diff --git a/docs-xml/smbdotconf/security/clientipcsigning.xml b/docs-xml/smbdotconf/security/clientipcsigning.xml
+new file mode 100644
+index 0000000..1897fc6
+--- /dev/null
++++ b/docs-xml/smbdotconf/security/clientipcsigning.xml
+@@ -0,0 +1,23 @@
++<samba:parameter name="client ipc signing"
++                 context="G"
++                 type="enum"
++                 enumlist="enum_smb_signing_vals"
++                 xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
++<description>
++    <para>This controls whether the client is allowed or required to use SMB signing for IPC$
++    connections as DCERPC transport inside of winbind. Possible values
++    are <emphasis>auto</emphasis>, <emphasis>mandatory</emphasis>
++    and <emphasis>disabled</emphasis>.
++    </para>
++
++    <para>When set to auto, SMB signing is offered, but not enforced and if set
++    to disabled, SMB signing is not offered either.</para>
++
++    <para>Connections from winbindd to Active Directory Domain Controllers
++    always enforce signing.</para>
++</description>
++
++<related>client signing</related>
++
++<value type="default">mandatory</value>
++</samba:parameter>
+diff --git a/docs-xml/smbdotconf/security/clientsigning.xml b/docs-xml/smbdotconf/security/clientsigning.xml
+index c657e05..189a7ae 100644
+--- a/docs-xml/smbdotconf/security/clientsigning.xml
++++ b/docs-xml/smbdotconf/security/clientsigning.xml
+@@ -12,6 +12,9 @@
+     <para>When set to auto, SMB signing is offered, but not enforced. 
+     When set to mandatory, SMB signing is required and if set 
+ 	to disabled, SMB signing is not offered either.
++
++    <para>IPC$ connections for DCERPC e.g. in winbindd, are handled by the
++    <smbconfoption name="client ipc signing"/> option.</para>
+ </para>
+ </description>
+ 
+diff --git a/source3/include/proto.h b/source3/include/proto.h
+index 43008ea..af950aa 100644
+--- a/source3/include/proto.h
++++ b/source3/include/proto.h
+@@ -1693,6 +1693,7 @@ const char **lp_winbind_nss_info(void);
+ int lp_algorithmic_rid_base(void);
+ int lp_name_cache_timeout(void);
+ int lp_client_signing(void);
++int lp_client_ipc_signing(void);
+ int lp_server_signing(void);
+ int lp_client_ldap_sasl_wrapping(void);
+ char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def);
+diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
+index c5249b7..a612e5a3 100644
+--- a/source3/param/loadparm.c
++++ b/source3/param/loadparm.c
+@@ -366,6 +366,7 @@ struct global {
+ 	int restrict_anonymous;
+ 	int name_cache_timeout;
+ 	int client_signing;
++	int client_ipc_signing;
+ 	int server_signing;
+ 	int client_ldap_sasl_wrapping;
+ 	int iUsershareMaxShares;
+@@ -2319,6 +2320,15 @@ static struct parm_struct parm_table[] = {
+ 		.flags		= FLAG_ADVANCED,
+ 	},
+ 	{
++		.label		= "client ipc signing",
++		.type		= P_ENUM,
++		.p_class	= P_GLOBAL,
++		.ptr		= &Globals.client_ipc_signing,
++		.special	= NULL,
++		.enum_list	= enum_smb_signing_vals,
++		.flags		= FLAG_ADVANCED,
++	},
++	{
+ 		.label		= "server signing",
+ 		.type		= P_ENUM,
+ 		.p_class	= P_GLOBAL,
+@@ -5470,6 +5480,7 @@ static void init_globals(bool reinit_globals)
+ 	Globals.bClientUseSpnego = True;
+ 
+ 	Globals.client_signing = Auto;
++	Globals.client_ipc_signing = Required;
+ 	Globals.server_signing = False;
+ 
+ 	Globals.bDeferSharingViolations = True;
+@@ -6071,6 +6082,7 @@ FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
+ FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
+ FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
+ FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
++FN_GLOBAL_INTEGER(lp_client_ipc_signing, &Globals.client_ipc_signing)
+ FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
+ FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
+ 
+-- 
+2.8.1
+
+
+From 11f77c7646ca80c33ff25d8aec2e3c42eace1048 Mon Sep 17 00:00:00 2001
+From: Andreas Schneider <asn at samba.org>
+Date: Tue, 5 Apr 2016 10:46:53 +0200
+Subject: [PATCH 2/4] CVE-2016-2115: s3: Use lp_client_ipc_signing() if we are
+ not an smb client
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11756
+
+Pair-Programmed-With: Ralph Boehme <slow at samba.org>
+Signed-off-by: Andreas Schneider <asn at samba.org>
+Signed-off-by: Ralph Boehme <slow at samba.org>
+---
+ source3/param/loadparm.c                    | 14 ++++++++++++++
+ source3/rpc_server/spoolss/srv_spoolss_nt.c |  2 +-
+ 2 files changed, 15 insertions(+), 1 deletion(-)
+
+diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
+index a612e5a3..c58f860 100644
+--- a/source3/param/loadparm.c
++++ b/source3/param/loadparm.c
+@@ -9712,6 +9712,20 @@ static bool lp_load_ex(const char *pszFname,
+ 		lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
+ 	}
+ 
++	if (!lp_is_in_client()) {
++		switch (lp_client_ipc_signing()) {
++		case Required:
++			lp_set_cmdline("client signing", "mandatory");
++			break;
++		case Auto:
++			lp_set_cmdline("client signing", "auto");
++			break;
++		case False:
++			lp_set_cmdline("client signing", "disabled");
++			break;
++		}
++	}
++
+ 	init_iconv();
+ 
+ 	bAllowIncludeRegistry = true;
+diff --git a/source3/rpc_server/spoolss/srv_spoolss_nt.c b/source3/rpc_server/spoolss/srv_spoolss_nt.c
+index 181a7b5..a0fcf27 100644
+--- a/source3/rpc_server/spoolss/srv_spoolss_nt.c
++++ b/source3/rpc_server/spoolss/srv_spoolss_nt.c
+@@ -2480,7 +2480,7 @@ static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe,
+ 		"", /* username */
+ 		"", /* domain */
+ 		"", /* password */
+-		0, lp_client_signing());
++		0, False);
+ 
+ 	if ( !NT_STATUS_IS_OK( ret ) ) {
+ 		DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
+-- 
+2.8.1
+
+
+From 9b5d8e20e8bbaa422c68b28d1c411bae6c596b94 Mon Sep 17 00:00:00 2001
+From: Ralph Boehme <slow at samba.org>
+Date: Thu, 31 Mar 2016 11:30:03 +0200
+Subject: [PATCH 3/4] CVE-2016-2115: s3/param: pick up s4 option "winbind
+ sealed pipes"
+
+This will be used in the next commit to prevent mitm attacks on on lsa,
+samr and netlogon in winbindd.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11756
+
+Signed-off-by: Ralph Boehme <slow at samba.org>
+Reviewed-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Andreas Schneider <asn at samba.org>
+---
+ docs-xml/smbdotconf/winbind/winbindsealedpipes.xml | 15 +++++++++++++++
+ source3/include/proto.h                            |  1 +
+ source3/param/loadparm.c                           | 12 ++++++++++++
+ 3 files changed, 28 insertions(+)
+ create mode 100644 docs-xml/smbdotconf/winbind/winbindsealedpipes.xml
+
+diff --git a/docs-xml/smbdotconf/winbind/winbindsealedpipes.xml b/docs-xml/smbdotconf/winbind/winbindsealedpipes.xml
+new file mode 100644
+index 0000000..016ac9b
+--- /dev/null
++++ b/docs-xml/smbdotconf/winbind/winbindsealedpipes.xml
+@@ -0,0 +1,15 @@
++<samba:parameter name="winbind sealed pipes"
++                 context="G"
++                 type="boolean"
++                 xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
++<description>
++	<para>This option controls whether any requests from winbindd to domain controllers
++		pipe will be sealed. Disabling sealing can be useful for debugging
++		purposes.</para>
++
++	<para>The behavior can be controlled per netbios domain
++	by using 'winbind sealed pipes:NETBIOSDOMAIN = no' as option.</para>
++</description>
++
++<value type="default">yes</value>
++</samba:parameter>
+diff --git a/source3/include/proto.h b/source3/include/proto.h
+index af950aa..ac1540f 100644
+--- a/source3/include/proto.h
++++ b/source3/include/proto.h
+@@ -1690,6 +1690,7 @@ int lp_winbind_cache_time(void);
+ int lp_winbind_reconnect_delay(void);
+ int lp_winbind_max_clients(void);
+ const char **lp_winbind_nss_info(void);
++bool lp_winbind_sealed_pipes(void);
+ int lp_algorithmic_rid_base(void);
+ int lp_name_cache_timeout(void);
+ int lp_client_signing(void);
+diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
+index c58f860..fdc9407 100644
+--- a/source3/param/loadparm.c
++++ b/source3/param/loadparm.c
+@@ -215,6 +215,7 @@ struct global {
+ 	int  winbind_expand_groups;
+ 	bool bWinbindRefreshTickets;
+ 	bool bWinbindOfflineLogon;
++	bool bWinbindSealedPipes;
+ 	bool bWinbindNormalizeNames;
+ 	bool bWinbindRpcOnly;
+ 	bool bCreateKrb5Conf;
+@@ -4775,6 +4776,15 @@ static struct parm_struct parm_table[] = {
+ 		.flags		= FLAG_ADVANCED,
+ 	},
+ 	{
++		.label		= "winbind sealed pipes",
++		.type		= P_BOOL,
++		.p_class	= P_GLOBAL,
++		.ptr		= &Globals.bWinbindSealedPipes,
++		.special	= NULL,
++		.enum_list	= NULL,
++		.flags		= FLAG_ADVANCED,
++	},
++	{
+ 		.label		= "winbind normalize names",
+ 		.type		= P_BOOL,
+ 		.p_class	= P_GLOBAL,
+@@ -5468,6 +5478,7 @@ static void init_globals(bool reinit_globals)
+ 	Globals.szWinbindNssInfo = str_list_make_v3(NULL, "template", NULL);
+ 	Globals.bWinbindRefreshTickets = False;
+ 	Globals.bWinbindOfflineLogon = False;
++	Globals.bWinbindSealedPipes = True;
+ 
+ 	Globals.iIdmapCacheTime = 86400 * 7; /* a week by default */
+ 	Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
+@@ -5747,6 +5758,7 @@ FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
+ FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
+ FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
+ FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
++FN_GLOBAL_BOOL(lp_winbind_sealed_pipes, &Globals.bWinbindSealedPipes)
+ FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
+ FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
+ FN_GLOBAL_BOOL(lp_create_krb5_conf, &Globals.bCreateKrb5Conf)
+-- 
+2.8.1
+
+
+From 0eea58205109a9f9b1b855705dba3c27b612cbd5 Mon Sep 17 00:00:00 2001
+From: Andrew Bartlett <abartlet at samba.org>
+Date: Fri, 5 Sep 2014 17:00:31 +1200
+Subject: [PATCH 4/4] CVE-2016-2115: winbindd: Do not make anonymous
+ connections by default
+
+The requirement is that we have "winbind sealed pipes = false" and
+"require strong key = false" before we make anonymous connections.
+These are a security risk as we cannot prevent MITM attacks.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11796
+
+Signed-off-by: Andrew Bartlett <abartlet at samba.org>
+Reviewed-by: Stefan Metzmacher <metze at samba.org>
+(backported from commit e2cd3257141bd4a88cda1fff5bde9df60b253a97)
+---
+ source3/winbindd/winbindd_cm.c | 32 +++++++++++++++++++++++++++++++-
+ 1 file changed, 31 insertions(+), 1 deletion(-)
+
+diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c
+index 8271279..4c55227 100644
+--- a/source3/winbindd/winbindd_cm.c
++++ b/source3/winbindd/winbindd_cm.c
+@@ -2384,6 +2384,15 @@ NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
+ 	TALLOC_FREE(conn->samr_pipe);
+ 
+  anonymous:
++	if (lp_winbind_sealed_pipes()) {
++		status = NT_STATUS_DOWNGRADE_DETECTED;
++		DEBUG(1, ("Unwilling to make SAMR connection to domain %s"
++			  "without connection level security, "
++			  "must set 'winbind sealed pipes = false' "
++			  "to proceed: %s\n",
++			  domain->name, nt_errstr(status)));
++		goto done;
++	}
+ 
+ 	/* Finally fall back to anonymous. */
+ 	status = cli_rpc_pipe_open_noauth(conn->cli, &ndr_table_samr.syntax_id,
+@@ -2610,6 +2619,16 @@ NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
+ 
+  anonymous:
+ 
++	if (lp_winbind_sealed_pipes()) {
++		result = NT_STATUS_DOWNGRADE_DETECTED;
++		DEBUG(1, ("Unwilling to make LSA connection to domain %s"
++			  "without connection level security, "
++			  "must set 'winbind sealed pipes = false' "
++			  "to proceed: %s\n",
++			  domain->name, nt_errstr(result)));
++		goto done;
++	}
++
+ 	result = cli_rpc_pipe_open_noauth(conn->cli,
+ 					  &ndr_table_lsarpc.syntax_id,
+ 					  &conn->lsa_pipe);
+@@ -2749,7 +2768,18 @@ NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
+ 
+  no_schannel:
+ 	if ((lp_client_schannel() == False) ||
+-			((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
++		((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
++		if (lp_winbind_sealed_pipes()) {
++			result = NT_STATUS_DOWNGRADE_DETECTED;
++			DEBUG(1, ("Unwilling to make connection to domain %s"
++				  "without connection level security, "
++				  "must set 'winbind sealed pipes = false' "
++				  "to proceed: %s\n",
++				  domain->name, nt_errstr(result)));
++			TALLOC_FREE(netlogon_pipe);
++			invalidate_cm_connection(conn);
++			return result;
++		}
+ 		/*
+ 		 * NetSamLogonEx only works for schannel
+ 		 */
+-- 
+2.8.1
+
diff --git a/debian/patches/CVE-2016-2118-v3-6.patch b/debian/patches/CVE-2016-2118-v3-6.patch
new file mode 100644
index 0000000..6e5b5a2
--- /dev/null
+++ b/debian/patches/CVE-2016-2118-v3-6.patch
@@ -0,0 +1,629 @@
+From 71c10424cfdfb3487b06b3572f0569581a952d56 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Tue, 15 Dec 2015 14:49:36 +0100
+Subject: [PATCH 01/10] CVE-2016-2118: s3: rpcclient: change the default auth
+ level from DCERPC_AUTH_LEVEL_CONNECT to DCERPC_AUTH_LEVEL_INTEGRITY
+
+ncacn_ip_tcp:server should get the same protection as ncacn_np:server
+if authentication and smb signing is used.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+
+(cherry picked from commit dab41dee8a4fb27dbf3913b0e44a4cc726e3ac98)
+---
+ source3/rpcclient/rpcclient.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c
+index 949e14c..81c5f42 100644
+--- a/source3/rpcclient/rpcclient.c
++++ b/source3/rpcclient/rpcclient.c
+@@ -1062,10 +1062,9 @@ out_free:
+ 		}
+ 	}
+ 	if (pipe_default_auth_type != DCERPC_AUTH_TYPE_NONE) {
+-		/* If neither Integrity or Privacy are requested then
+-		 * Use just Connect level */
++		/* If nothing is requested then default to integrity */
+ 		if (pipe_default_auth_level == DCERPC_AUTH_LEVEL_NONE) {
+-			pipe_default_auth_level = DCERPC_AUTH_LEVEL_CONNECT;
++			pipe_default_auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
+ 		}
+ 	}
+ 
+-- 
+2.8.1
+
+
+From 8dd2d22a5593c040814ef02ac5b74f741abd1984 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Fri, 11 Mar 2016 16:02:25 +0100
+Subject: [PATCH 02/10] CVE-2016-2118: s4:librpc: use integrity by default for
+ authenticated binds
+
+ncacn_ip_tcp:server should get the same protection as ncacn_np:server
+if authentication and smb signing is used.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+(cherry picked from commit 7847ee85d278adb9ce4fc7da7cf171917227c93f)
+---
+ source4/librpc/rpc/dcerpc_util.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/source4/librpc/rpc/dcerpc_util.c b/source4/librpc/rpc/dcerpc_util.c
+index 2cd9499..a6d0df5 100644
+--- a/source4/librpc/rpc/dcerpc_util.c
++++ b/source4/librpc/rpc/dcerpc_util.c
+@@ -593,15 +593,15 @@ struct composite_context *dcerpc_pipe_auth_send(struct dcerpc_pipe *p,
+ 
+ 	/* Perform an authenticated DCE-RPC bind
+ 	 */
+-	if (!(conn->flags & (DCERPC_SIGN|DCERPC_SEAL))) {
++	if (!(conn->flags & (DCERPC_CONNECT|DCERPC_SEAL))) {
+ 		/*
+ 		  we are doing an authenticated connection,
+-		  but not using sign or seal. We must force
+-		  the CONNECT dcerpc auth type as a NONE auth
+-		  type doesn't allow authentication
+-		  information to be passed.
++		  which needs to use [connect], [sign] or [seal].
++		  If nothing is specified, we default to [sign] now.
++		  This give roughly the same protection as
++		  ncacn_np with smb signing.
+ 		*/
+-		conn->flags |= DCERPC_CONNECT;
++		conn->flags |= DCERPC_SIGN;
+ 	}
+ 
+ 	if (s->binding->flags & DCERPC_AUTH_SPNEGO) {
+-- 
+2.8.1
+
+
+From b1ef57bab7cc3b6c2f1d1d4f01024068c8544b61 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Thu, 10 Mar 2016 17:03:59 +0100
+Subject: [PATCH 03/10] CVE-2016-2118: docs-xml: add "allow dcerpc auth level
+ connect" defaulting to "yes"
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+We sadly need to allow this for now by default.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+(backported from commit 56baca8619ba9ae1734c3d77524fc705ebcbd8d2)
+---
+ .../security/allowdcerpcauthlevelconnect.xml       | 24 ++++++++++++++++++++++
+ 1 file changed, 24 insertions(+)
+ create mode 100644 docs-xml/smbdotconf/security/allowdcerpcauthlevelconnect.xml
+
+diff --git a/docs-xml/smbdotconf/security/allowdcerpcauthlevelconnect.xml b/docs-xml/smbdotconf/security/allowdcerpcauthlevelconnect.xml
+new file mode 100644
+index 0000000..5552112
+--- /dev/null
++++ b/docs-xml/smbdotconf/security/allowdcerpcauthlevelconnect.xml
+@@ -0,0 +1,24 @@
++<samba:parameter name="allow dcerpc auth level connect"
++                 context="G"
++                 type="boolean"
++                 xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
++<description>
++	<para>This option controls whether DCERPC services are allowed to
++	be used with DCERPC_AUTH_LEVEL_CONNECT, which provides authentication,
++	but no per message integrity nor privacy protection.</para>
++
++	<para>The behavior can be controlled per interface name (e.g. lsarpc, netlogon, samr, srvsvc,
++	winreg, wkssvc ...) by using 'allow dcerpc auth level connect:interface = no' as option.</para>
++
++	<para>This option yields precedence to the implentation specific restrictions.
++	E.g. the drsuapi and backupkey protocols require DCERPC_AUTH_LEVEL_PRIVACY.
++	While others like samr and lsarpc have a hardcoded default of <constant>no</constant>.
++	</para>
++
++	<para>Note the default will very likely change to <constant>no</constant> for Samba 4.5.</para>
++</description>
++
++<value type="default">yes</value>
++<value type="example">no</value>
++
++</samba:parameter>
+-- 
+2.8.1
+
+
+From b2ebdf3d9423e23b090311de93e56c04f69dd486 Mon Sep 17 00:00:00 2001
+From: Ralph Boehme <slow at samba.org>
+Date: Fri, 18 Mar 2016 08:45:11 +0100
+Subject: [PATCH 04/10] CVE-2016-2118: param: add "allow dcerpc auth level
+ connect" defaulting to "yes"
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616
+
+Signed-off-by: Ralph Boehme <slow at samba.org>
+Reviewed-by: Stefan Metzmacher <metze at samba.org>
+(backported from commit 6e3ada2c36f527077d77a8278bd41bbc030f48cd)
+
+(cherry picked from commit 74172d061597c96f0e733c11daee6cb15f3277dc)
+Signed-off-by: Aurelien Aptel <aaptel at suse.com>
+---
+ source3/include/proto.h  |  1 +
+ source3/param/loadparm.c | 13 +++++++++++++
+ 2 files changed, 14 insertions(+)
+
+diff --git a/source3/include/proto.h b/source3/include/proto.h
+index ac1540f..2ed6547 100644
+--- a/source3/include/proto.h
++++ b/source3/include/proto.h
+@@ -1821,6 +1821,7 @@ char* lp_perfcount_module(void);
+ void lp_set_passdb_backend(const char *backend);
+ void widelinks_warning(int snum);
+ char *lp_ncalrpc_dir(void);
++bool lp_allow_dcerpc_auth_level_connect(void);
+ 
+ /* The following definitions come from param/loadparm_server_role.c  */
+ 
+diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
+index fdc9407..87d33c5 100644
+--- a/source3/param/loadparm.c
++++ b/source3/param/loadparm.c
+@@ -355,6 +355,7 @@ struct global {
+ 	bool bUseMmap;
+ 	bool bHostnameLookups;
+ 	bool bUnixExtensions;
++	bool bAllowDcerpcAuthLevelConnect;
+ 	bool bDisableNetbios;
+ 	char * szDedicatedKeytabFile;
+ 	int  iKerberosMethod;
+@@ -2303,6 +2304,15 @@ static struct parm_struct parm_table[] = {
+ 		.flags		= FLAG_ADVANCED,
+ 	},
+ 	{
++		.label		= "allow dcerpc auth level connect",
++		.type		= P_BOOL,
++		.p_class	= P_GLOBAL,
++		.ptr		= &Globals.bAllowDcerpcAuthLevelConnect,
++		.special	= NULL,
++		.enum_list	= NULL,
++		.flags		= FLAG_ADVANCED,
++	},
++	{
+ 		.label		= "use spnego",
+ 		.type		= P_BOOL,
+ 		.p_class	= P_GLOBAL,
+@@ -5371,6 +5381,8 @@ static void init_globals(bool reinit_globals)
+ 	Globals.bClientNTLMv2Auth = True; /* Client should always use use NTLMv2, as we can't tell that the server supports it, but most modern servers do */
+ 	/* Note, that we will also use NTLM2 session security (which is different), if it is available */
+ 
++	Globals.bAllowDcerpcAuthLevelConnect = true; /* we need to allow this for now by default */
++
+ 	Globals.map_to_guest = 0;	/* By Default, "Never" */
+ 	Globals.oplock_break_wait_time = 0;	/* By Default, 0 msecs. */
+ 	Globals.enhanced_browsing = true;
+@@ -5745,6 +5757,7 @@ FN_GLOBAL_INTEGER(lp_username_map_cache_time, &Globals.iUsernameMapCacheTime)
+ 
+ FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
+ 
++FN_GLOBAL_BOOL(lp_allow_dcerpc_auth_level_connect, &Globals.bAllowDcerpcAuthLevelConnect)
+ FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
+ FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
+ FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
+-- 
+2.8.1
+
+
+From bf1251499b1ea59b25e35a1bfe4967414bf9bd9d Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Fri, 18 Mar 2016 04:40:30 +0100
+Subject: [PATCH 05/10] CVE-2016-2118: s3:rpc_server: make use of "allow dcerpc
+ auth level connect"
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+With this option turned off we only allow DCERPC_AUTH_LEVEL_{NONE,INTEGRITY,PRIVACY},
+this means the reject any request with AUTH_LEVEL_CONNECT with ACCESS_DENIED.
+
+We sadly need to keep this enabled by default for now.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616
+
+Pair-Programmed-With: Günther Deschner <gd at samba.org>
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Signed-off-by: Günther Deschner <gd at samba.org>
+(cherry picked from commit 1fa0bad3da921fca1d34971062522b4cc3e6db2c)
+(cherry picked from commit 46744bbe5e3616613b2dbee7cf6fdf0d8d5caab3)
+Signed-off-by: Aurelien Aptel <aaptel at suse.com>
+---
+ source3/include/ntdomain.h    |  4 ++++
+ source3/rpc_server/srv_pipe.c | 49 ++++++++++++++++++++++++++++++++++++++++++-
+ 2 files changed, 52 insertions(+), 1 deletion(-)
+
+diff --git a/source3/include/ntdomain.h b/source3/include/ntdomain.h
+index 2fbeabc..650f1d0 100644
+--- a/source3/include/ntdomain.h
++++ b/source3/include/ntdomain.h
+@@ -89,6 +89,10 @@ typedef struct pipe_rpc_fns {
+ 	uint32 context_id;
+ 	struct ndr_syntax_id syntax;
+ 
++	/*
++	 * shall we allow "connect" auth level for this interface ?
++	 */
++	bool allow_connect;
+ } PIPE_RPC_FNS;
+ 
+ /*
+diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
+index d659705..c462dcf 100644
+--- a/source3/rpc_server/srv_pipe.c
++++ b/source3/rpc_server/srv_pipe.c
+@@ -335,6 +335,7 @@ static bool check_bind_req(struct pipes_struct *p,
+ 			   uint32 context_id)
+ {
+ 	struct pipe_rpc_fns *context_fns;
++	const char *interface_name = NULL;
+ 
+ 	DEBUG(3,("check_bind_req for %s\n",
+ 		 get_pipe_name_from_syntax(talloc_tos(), abstract)));
+@@ -355,12 +356,29 @@ static bool check_bind_req(struct pipes_struct *p,
+ 		return False;
+ 	}
+ 
++	interface_name = get_pipe_name_from_syntax(talloc_tos(),
++						   abstract);
++
++	SMB_ASSERT(interface_name != NULL);
++
+ 	context_fns->next = context_fns->prev = NULL;
+ 	context_fns->n_cmds = rpc_srv_get_pipe_num_cmds(abstract);
+ 	context_fns->cmds = rpc_srv_get_pipe_cmds(abstract);
+ 	context_fns->context_id = context_id;
+ 	context_fns->syntax = *abstract;
+ 
++	context_fns->allow_connect = lp_allow_dcerpc_auth_level_connect();
++	/*
++	 * every interface can be modified to allow "connect" auth_level by
++	 * using a parametric option like:
++	 * allow dcerpc auth level connect:<interface>
++	 * e.g.
++	 * allow dcerpc auth level connect:samr = yes
++	 */
++	context_fns->allow_connect = lp_parm_bool(-1,
++		"allow dcerpc auth level connect",
++		interface_name, context_fns->allow_connect);
++
+ 	/* add to the list of open contexts */
+ 
+ 	DLIST_ADD( p->contexts, context_fns );
+@@ -1592,6 +1610,7 @@ static bool api_pipe_request(struct pipes_struct *p,
+ 	TALLOC_CTX *frame = talloc_stackframe();
+ 	bool ret = False;
+ 	PIPE_RPC_FNS *pipe_fns;
++	const char *interface_name = NULL;
+ 
+ 	if (!p->pipe_bound) {
+ 		DEBUG(1, ("Pipe not bound!\n"));
+@@ -1613,8 +1632,36 @@ static bool api_pipe_request(struct pipes_struct *p,
+ 		return false;
+ 	}
+ 
++	interface_name = get_pipe_name_from_syntax(talloc_tos(),
++						   &pipe_fns->syntax);
++
++	SMB_ASSERT(interface_name != NULL);
++
+ 	DEBUG(5, ("Requested \\PIPE\\%s\n",
+-		  get_pipe_name_from_syntax(talloc_tos(), &pipe_fns->syntax)));
++		  interface_name));
++
++	switch (p->auth.auth_level) {
++	case DCERPC_AUTH_LEVEL_NONE:
++	case DCERPC_AUTH_LEVEL_INTEGRITY:
++	case DCERPC_AUTH_LEVEL_PRIVACY:
++		break;
++	default:
++		if (!pipe_fns->allow_connect) {
++			DEBUG(1, ("%s: restrict auth_level_connect access "
++				  "to [%s] with auth[type=0x%x,level=0x%x] "
++				  "on [%s] from [%s]\n",
++				  __func__, interface_name,
++				  p->auth.auth_type,
++				  p->auth.auth_level,
++				  derpc_transport_string_by_transport(p->transport),
++				  p->client_id->name));
++
++			setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_ACCESS_DENIED));
++			TALLOC_FREE(frame);
++			return true;
++		}
++		break;
++	}
+ 
+ 	if (!srv_pipe_check_verification_trailer(p, pkt, pipe_fns)) {
+ 		DEBUG(1, ("srv_pipe_check_verification_trailer: failed\n"));
+-- 
+2.8.1
+
+
+From 65f5a36ee12233c4d501b937f894a7193ba32ef8 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Fri, 7 Aug 2015 09:50:30 +0200
+Subject: [PATCH 06/10] CVE-2016-2118: s3:rpc_server/{samr,lsa,netlogon}:
+ reject DCERPC_AUTH_LEVEL_CONNECT by default
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This prevents man in the middle downgrade attacks.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616
+
+Pair-Programmed-With: Günther Deschner <gd at samba.org>
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Signed-off-by: Günther Deschner <gd at samba.org>
+(cherry picked from commit 51dd08951eb4ab9d297678f96cde61f508937721)
+Signed-off-by: Aurelien Aptel <aaptel at suse.com>
+
+Conflicts:
+	selftest/knownfail
+	source3/rpc_server/srv_pipe.c
+
+selftest/knownfail is ignored in 3.6
+---
+ source3/rpc_server/srv_pipe.c | 20 ++++++++++++++++++++
+ source3/selftest/knownfail    |  1 +
+ source3/selftest/tests.py     |  2 ++
+ 3 files changed, 23 insertions(+)
+
+diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
+index c462dcf..3086b9e 100644
+--- a/source3/rpc_server/srv_pipe.c
++++ b/source3/rpc_server/srv_pipe.c
+@@ -43,6 +43,9 @@
+ #include "ntdomain.h"
+ #include "rpc_server/srv_pipe.h"
+ #include "../librpc/ndr/ndr_dcerpc.h"
++#include "../librpc/gen_ndr/ndr_samr.h"
++#include "../librpc/gen_ndr/ndr_lsa.h"
++#include "../librpc/gen_ndr/ndr_netlogon.h"
+ 
+ #undef DBGC_CLASS
+ #define DBGC_CLASS DBGC_RPC_SRV
+@@ -336,6 +339,7 @@ static bool check_bind_req(struct pipes_struct *p,
+ {
+ 	struct pipe_rpc_fns *context_fns;
+ 	const char *interface_name = NULL;
++	bool ok;
+ 
+ 	DEBUG(3,("check_bind_req for %s\n",
+ 		 get_pipe_name_from_syntax(talloc_tos(), abstract)));
+@@ -369,6 +373,22 @@ static bool check_bind_req(struct pipes_struct *p,
+ 
+ 	context_fns->allow_connect = lp_allow_dcerpc_auth_level_connect();
+ 	/*
++	 * for the samr and the lsarpc interfaces we don't allow "connect"
++	 * auth_level by default.
++	 */
++	ok = ndr_syntax_id_equal(abstract, &ndr_table_samr.syntax_id);
++	if (ok) {
++		context_fns->allow_connect = false;
++	}
++	ok = ndr_syntax_id_equal(abstract, &ndr_table_lsarpc.syntax_id);
++	if (ok) {
++		context_fns->allow_connect = false;
++	}
++	ok = ndr_syntax_id_equal(abstract, &ndr_table_netlogon.syntax_id);
++	if (ok) {
++		context_fns->allow_connect = false;
++	}
++	/*
+ 	 * every interface can be modified to allow "connect" auth_level by
+ 	 * using a parametric option like:
+ 	 * allow dcerpc auth level connect:<interface>
+diff --git a/source3/selftest/knownfail b/source3/selftest/knownfail
+index bda1fe0..8717a4d 100644
+--- a/source3/selftest/knownfail
++++ b/source3/selftest/knownfail
+@@ -18,3 +18,4 @@ samba3.posix_s3.nbt.dgram.*netlogon2
+ samba3.*rap.sam.*.useradd # Not provided by Samba 3
+ samba3.*rap.sam.*.userdelete # Not provided by Samba 3
+ samba3.*rap.basic.*.netsessiongetinfo # Not provided by Samba 3
++samba3.blackbox.rpcclient.over.ncacn_np.with.*connect.* # we don't allow auth_level_connect anymore
+diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
+index a733f14..8dfbf1e 100755
+--- a/source3/selftest/tests.py
++++ b/source3/selftest/tests.py
+@@ -201,6 +201,8 @@ if sub.returncode == 0:
+             plansmbtorturetestsuite(t, "s3dc", '//$SERVER_IP/tmpguest -U$USERNAME%$PASSWORD')
+         elif t == "raw.samba3posixtimedlock":
+             plansmbtorturetestsuite(t, "s3dc", '//$SERVER_IP/tmpguest -U$USERNAME%$PASSWORD --option=torture:localdir=$SELFTEST_PREFIX/dc/share')
++        elif t == "rpc.samr.passwords.validate":
++            plansmbtorturetestsuite(t, "s3dc", 'ncacn_np:$SERVER_IP[seal] -U$USERNAME%$PASSWORD', 'over ncacn_np ')
+         else:
+             plansmbtorturetestsuite(t, "s3dc", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD')
+ 
+-- 
+2.8.1
+
+
+From 05cadb9cac8b7f477fe992126ca22c9bba69b6e7 Mon Sep 17 00:00:00 2001
+From: Andreas Schneider <asn at samba.org>
+Date: Tue, 5 Apr 2016 09:54:38 +0200
+Subject: [PATCH 07/10] CVE-2016-2118: s3:selftest: The lsa tests which use
+ connect need to fail
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616
+
+Signed-off-by: Andreas Schneider <asn at samba.org>
+---
+ source3/selftest/knownfail | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/source3/selftest/knownfail b/source3/selftest/knownfail
+index 8717a4d..7d9275e 100644
+--- a/source3/selftest/knownfail
++++ b/source3/selftest/knownfail
+@@ -19,3 +19,4 @@ samba3.*rap.sam.*.useradd # Not provided by Samba 3
+ samba3.*rap.sam.*.userdelete # Not provided by Samba 3
+ samba3.*rap.basic.*.netsessiongetinfo # Not provided by Samba 3
+ samba3.blackbox.rpcclient.over.ncacn_np.with.*connect.* # we don't allow auth_level_connect anymore
++samba3.posix_s3.rpc.lsa.lookupsids.*ncacn_ip_tcp.*connect.* # we don't allow auth_level_connect anymore
+-- 
+2.8.1
+
+
+From f77b2463989f68dc2a9bfe0123d23f066aa1ff42 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Sat, 26 Mar 2016 08:47:42 +0100
+Subject: [PATCH 08/10] CVE-2016-2118: s3:rpc_server/{epmapper,echo}: allow
+ DCERPC_AUTH_LEVEL_CONNECT by default
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Alexander Bokovoy <ab at samba.org>
+(cherry picked from commit 98f1a85f23d3d2a4f1c665746588688574261d90)
+---
+ source3/rpc_server/srv_pipe.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
+index 3086b9e..964b843 100644
+--- a/source3/rpc_server/srv_pipe.c
++++ b/source3/rpc_server/srv_pipe.c
+@@ -46,6 +46,8 @@
+ #include "../librpc/gen_ndr/ndr_samr.h"
+ #include "../librpc/gen_ndr/ndr_lsa.h"
+ #include "../librpc/gen_ndr/ndr_netlogon.h"
++#include "../librpc/gen_ndr/ndr_epmapper.h"
++#include "../librpc/gen_ndr/ndr_echo.h"
+ 
+ #undef DBGC_CLASS
+ #define DBGC_CLASS DBGC_RPC_SRV
+@@ -389,6 +391,18 @@ static bool check_bind_req(struct pipes_struct *p,
+ 		context_fns->allow_connect = false;
+ 	}
+ 	/*
++	 * for the epmapper and echo interfaces we allow "connect"
++	 * auth_level by default.
++	 */
++	ok = ndr_syntax_id_equal(abstract, &ndr_table_epmapper.syntax_id);
++	if (ok) {
++		context_fns->allow_connect = true;
++	}
++	ok = ndr_syntax_id_equal(abstract, &ndr_table_rpcecho.syntax_id);
++	if (ok) {
++		context_fns->allow_connect = true;
++	}
++	/*
+ 	 * every interface can be modified to allow "connect" auth_level by
+ 	 * using a parametric option like:
+ 	 * allow dcerpc auth level connect:<interface>
+-- 
+2.8.1
+
+
+From 16ae4105218430d191df6c8ad7f51021c63b6606 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Thu, 10 Mar 2016 17:03:59 +0100
+Subject: [PATCH 09/10] CVE-2016-2118: docs-xml/param: default "allow dcerpc
+ auth level connect" to "no"
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Alexander Bokovoy <ab at samba.org>
+(backported from commit 6469e21af32a2a405dd4f43e7d96a2f87c4a9902)
+
+Conflicts:
+	lib/param/loadparm.c
+	source3/param/loadparm.c
+---
+ docs-xml/smbdotconf/security/allowdcerpcauthlevelconnect.xml | 6 ++----
+ source3/param/loadparm.c                                     | 2 +-
+ 2 files changed, 3 insertions(+), 5 deletions(-)
+
+diff --git a/docs-xml/smbdotconf/security/allowdcerpcauthlevelconnect.xml b/docs-xml/smbdotconf/security/allowdcerpcauthlevelconnect.xml
+index 5552112..c8e9d18 100644
+--- a/docs-xml/smbdotconf/security/allowdcerpcauthlevelconnect.xml
++++ b/docs-xml/smbdotconf/security/allowdcerpcauthlevelconnect.xml
+@@ -14,11 +14,9 @@
+ 	E.g. the drsuapi and backupkey protocols require DCERPC_AUTH_LEVEL_PRIVACY.
+ 	While others like samr and lsarpc have a hardcoded default of <constant>no</constant>.
+ 	</para>
+-
+-	<para>Note the default will very likely change to <constant>no</constant> for Samba 4.5.</para>
+ </description>
+ 
+-<value type="default">yes</value>
+-<value type="example">no</value>
++<value type="default">no</value>
++<value type="example">yes</value>
+ 
+ </samba:parameter>
+diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
+index 87d33c5..a514727 100644
+--- a/source3/param/loadparm.c
++++ b/source3/param/loadparm.c
+@@ -5381,7 +5381,7 @@ static void init_globals(bool reinit_globals)
+ 	Globals.bClientNTLMv2Auth = True; /* Client should always use use NTLMv2, as we can't tell that the server supports it, but most modern servers do */
+ 	/* Note, that we will also use NTLM2 session security (which is different), if it is available */
+ 
+-	Globals.bAllowDcerpcAuthLevelConnect = true; /* we need to allow this for now by default */
++	Globals.bAllowDcerpcAuthLevelConnect = false; /* we don't allow this by default */
+ 
+ 	Globals.map_to_guest = 0;	/* By Default, "Never" */
+ 	Globals.oplock_break_wait_time = 0;	/* By Default, 0 msecs. */
+-- 
+2.8.1
+
+
+From 3abb6ea0e8cb7bbfdc52e7cb626628e27778726b Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Sun, 28 Feb 2016 22:48:11 +0100
+Subject: [PATCH 10/10] CVE-2016-2118: s3:rpc_server/samr: allow
+ _samr_ValidatePassword only with PRIVACY...
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This requires transport encryption.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+(cherry picked from commit d7c2f1e12544ee0f80438dcc1586e2d30c23b54a)
+---
+ source3/rpc_server/samr/srv_samr_nt.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/source3/rpc_server/samr/srv_samr_nt.c b/source3/rpc_server/samr/srv_samr_nt.c
+index 0984984..37e2e4f 100644
+--- a/source3/rpc_server/samr/srv_samr_nt.c
++++ b/source3/rpc_server/samr/srv_samr_nt.c
+@@ -6628,6 +6628,11 @@ NTSTATUS _samr_ValidatePassword(struct pipes_struct *p,
+ 	struct samr_GetDomPwInfo pw;
+ 	struct samr_PwInfo dom_pw_info;
+ 
++	if (p->auth.auth_level != DCERPC_AUTH_LEVEL_PRIVACY) {
++		p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
++		return NT_STATUS_ACCESS_DENIED;
++	}
++
+ 	if (r->in.level < 1 || r->in.level > 3) {
+ 		return NT_STATUS_INVALID_INFO_CLASS;
+ 	}
+-- 
+2.8.1
+
diff --git a/debian/patches/CVE-preparation-v3-6.patch b/debian/patches/CVE-preparation-v3-6.patch
new file mode 100644
index 0000000..a74d1c3
--- /dev/null
+++ b/debian/patches/CVE-preparation-v3-6.patch
@@ -0,0 +1,7813 @@
+From 39a3fa39967faaf216be8e108ca57d07de1aa95a Mon Sep 17 00:00:00 2001
+From: Vadim Zhukov <persgray at gmail.com>
+Date: Sat, 25 May 2013 15:19:24 +0100
+Subject: [PATCH 01/40] pidl: Recent Perl warns about "defined(@var)"
+ constructs.
+
+Signed-off-by: Jelmer Vernooij <jelmer at samba.org>
+
+Autobuild-User(master): Jelmer Vernooij <jelmer at samba.org>
+Autobuild-Date(master): Sat May 25 18:10:53 CEST 2013 on sn-devel-104
+
+(cherry picked from commit 92254d09e0ee5a7d9d0cd91fe1803f54e64d9a5f)
+---
+ pidl/lib/Parse/Pidl/ODL.pm | 2 +-
+ pidl/pidl                  | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/pidl/lib/Parse/Pidl/ODL.pm b/pidl/lib/Parse/Pidl/ODL.pm
+index 74d9ac7..14e77fa 100644
+--- a/pidl/lib/Parse/Pidl/ODL.pm
++++ b/pidl/lib/Parse/Pidl/ODL.pm
+@@ -70,7 +70,7 @@ sub ODL2IDL
+ 					next;
+ 				}
+ 				my $podl = Parse::Pidl::IDL::parse_file($idl_path, $opt_incdirs);
+-				if (defined(@$podl)) {
++				if (defined($podl)) {
+ 					require Parse::Pidl::Typelist;
+ 					my $basename = basename($idl_path, ".idl");
+ 
+diff --git a/pidl/pidl b/pidl/pidl
+index 2a46e92..c65092e 100755
+--- a/pidl/pidl
++++ b/pidl/pidl
+@@ -605,7 +605,7 @@ sub process_file($)
+ 		require Parse::Pidl::IDL;
+ 
+ 		$pidl = Parse::Pidl::IDL::parse_file($idl_file, \@opt_incdirs);
+-		defined @$pidl || die "Failed to parse $idl_file";
++		defined $pidl || die "Failed to parse $idl_file";
+ 	}
+ 
+ 	require Parse::Pidl::Typelist;
+-- 
+2.8.1
+
+
+From 853bfa0392e690fc4500a3cde23438eb0404df52 Mon Sep 17 00:00:00 2001
+From: Andreas Schneider <asn at samba.org>
+Date: Fri, 1 Apr 2016 14:53:59 +0200
+Subject: [PATCH 02/40] s4:heimdal: Fix getopt with perl5
+
+---
+ source4/heimdal/cf/make-proto.pl | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/source4/heimdal/cf/make-proto.pl b/source4/heimdal/cf/make-proto.pl
+index bc323b9..feee18a 100644
+--- a/source4/heimdal/cf/make-proto.pl
++++ b/source4/heimdal/cf/make-proto.pl
+@@ -1,8 +1,8 @@
+ # Make prototypes from .c files
+ # $Id$
+ 
+-##use Getopt::Std;
+-require 'getopts.pl';
++use Getopt::Std;
++#require 'getopts.pl';
+ 
+ my $comment = 0;
+ my $if_0 = 0;
+@@ -12,7 +12,7 @@ my $debug = 0;
+ my $oproto = 1;
+ my $private_func_re = "^_";
+ 
+-Getopts('x:m:o:p:dqE:R:P:') || die "foo";
++getopts('x:m:o:p:dqE:R:P:') || die "foo";
+ 
+ if($opt_d) {
+     $debug = 1;
+-- 
+2.8.1
+
+
+From 84087c0ff8a5e9fcfdd9d504cd24fdd77ed19f56 Mon Sep 17 00:00:00 2001
+From: Andreas Schneider <asn at samba.org>
+Date: Fri, 1 Apr 2016 15:22:17 +0200
+Subject: [PATCH 03/40] s3-selftest: Fix building smbtorture4
+
+---
+ source3/Makefile-smbtorture4 | 2 +-
+ source4/lib/ldb/wscript      | 4 +---
+ 2 files changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/source3/Makefile-smbtorture4 b/source3/Makefile-smbtorture4
+index 4a1bed7..9fe298c 100644
+--- a/source3/Makefile-smbtorture4
++++ b/source3/Makefile-smbtorture4
+@@ -6,7 +6,7 @@ SAMBA4_BINARIES="smbtorture,ndrdump"
+ samba4-configure:
+ 	@(cd .. && \
+ 		CFLAGS='' $(WAF) reconfigure || \
+-		CFLAGS='' $(WAF) configure --enable-socket-wrapper --enable-nss-wrapper --enable-uid-wrapper --nonshared-binary=$(SAMBA4_BINARIES) --enable-auto-reconfigure )
++		CFLAGS='' $(WAF) configure --enable-socket-wrapper --enable-nss-wrapper --enable-uid-wrapper --nonshared-binary=$(SAMBA4_BINARIES) --enable-auto-reconfigure --bundled-libraries=ALL --disable-gnutls )
+ 
+ .PHONY: samba4-configure
+ 
+diff --git a/source4/lib/ldb/wscript b/source4/lib/ldb/wscript
+index df08f87..245e61e 100755
+--- a/source4/lib/ldb/wscript
++++ b/source4/lib/ldb/wscript
+@@ -135,9 +135,7 @@ def build(bld):
+                           pc_files=ldb_pc_files,
+                           vnum=VERSION,
+                           private_library=private_library,
+-                          manpages='man/ldb.3',
+-                          abi_directory = 'ABI',
+-                          abi_match = abi_match)
++                          manpages='man/ldb.3')
+ 
+         # generate a include/ldb_version.h
+         t = bld.SAMBA_GENERATOR('ldb_version.h',
+-- 
+2.8.1
+
+
+From b038303b4b5beb27a436a7c7d8dbac3fa9db95fa Mon Sep 17 00:00:00 2001
+From: Andreas Schneider <asn at samba.org>
+Date: Fri, 1 Apr 2016 16:44:23 +0200
+Subject: [PATCH 04/40] selftest: Skip tests which do not work
+
+---
+ source3/selftest/skip | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/source3/selftest/skip b/source3/selftest/skip
+index b4de818..9d88dc8 100644
+--- a/source3/selftest/skip
++++ b/source3/selftest/skip
+@@ -22,3 +22,8 @@ samba3.*raw.ioctl
+ samba3.*raw.qfileinfo
+ samba3.*raw.qfsinfo
+ samba3.*raw.sfileinfo.base
++# skip, don't work for badlock backports
++samba3.posix_s3.raw.eas
++samba3.posix_s3.raw.rename
++samba3.posix_s3.raw.search
++samba3.posix_s3.raw.streams
+-- 
+2.8.1
+
+
+From 4b951db066a3a7a9931b50d5af7c1bb3f58072b0 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Tue, 24 Nov 2015 15:40:29 +0100
+Subject: [PATCH 05/40] librpc/ndr: add ndr_ntlmssp_find_av() helper function
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Andrew Bartlett <abartlet at samba.org>
+Reviewed-by: Günther Deschner <gd at samba.org>
+---
+ librpc/ndr/ndr_ntlmssp.c | 16 ++++++++++++++++
+ librpc/ndr/ndr_ntlmssp.h |  2 ++
+ 2 files changed, 18 insertions(+)
+
+diff --git a/librpc/ndr/ndr_ntlmssp.c b/librpc/ndr/ndr_ntlmssp.c
+index d024da5..7027ac0 100644
+--- a/librpc/ndr/ndr_ntlmssp.c
++++ b/librpc/ndr/ndr_ntlmssp.c
+@@ -176,4 +176,20 @@ _PUBLIC_ void ndr_print_ntlmssp_Version(struct ndr_print *ndr, const char *name,
+ 	}
+ }
+ 
++_PUBLIC_ struct AV_PAIR *ndr_ntlmssp_find_av(const struct AV_PAIR_LIST *av_list,
++					     enum ntlmssp_AvId AvId)
++{
++	struct AV_PAIR *res = NULL;
++	uint32_t i = 0;
++
++	for (i = 0; i < av_list->count; i++) {
++		if (av_list->pair[i].AvId != AvId) {
++			continue;
++		}
+ 
++		res = discard_const_p(struct AV_PAIR, &av_list->pair[i]);
++		break;
++	}
++
++	return res;
++}
+diff --git a/librpc/ndr/ndr_ntlmssp.h b/librpc/ndr/ndr_ntlmssp.h
+index e07ff15..5c979ff 100644
+--- a/librpc/ndr/ndr_ntlmssp.h
++++ b/librpc/ndr/ndr_ntlmssp.h
+@@ -31,3 +31,5 @@ _PUBLIC_ void ndr_print_ntlmssp_lm_response(TALLOC_CTX *mem_ctx,
+ 					    bool ntlmv2);
+ _PUBLIC_ void ndr_print_ntlmssp_Version(struct ndr_print *ndr, const char *name, const union ntlmssp_Version *r);
+ 
++_PUBLIC_ struct AV_PAIR *ndr_ntlmssp_find_av(const struct AV_PAIR_LIST *av_list,
++					     enum ntlmssp_AvId AvId);
+-- 
+2.8.1
+
+
+From 1b7d7ade976e9a86182b8b8cb0e32cc8d1a9f03d Mon Sep 17 00:00:00 2001
+From: Kai Blin <kai at samba.org>
+Date: Fri, 18 Jan 2013 18:35:15 +0100
+Subject: [PATCH 06/40] librpc: Add NDR_PRINT_DEBUGC to ndr print to a debug
+ class
+
+Signed-off-by: Kai Blin <kai at samba.org>
+Reviewed-by: Andrew Bartlett <abartlet at samba.org>
+(cherry picked from commit 0f5e9d29f607f9d910641632dfcd20ef800b0bc4)
+---
+ librpc/ABI/ndr-0.0.2.sigs | 247 ++++++++++++++++++++++++++++++++++++++++++++++
+ librpc/ndr/libndr.h       |   3 +
+ librpc/ndr/ndr.c          |  51 ++++++++++
+ 3 files changed, 301 insertions(+)
+ create mode 100644 librpc/ABI/ndr-0.0.2.sigs
+
+diff --git a/librpc/ABI/ndr-0.0.2.sigs b/librpc/ABI/ndr-0.0.2.sigs
+new file mode 100644
+index 0000000..66be5ba
+--- /dev/null
++++ b/librpc/ABI/ndr-0.0.2.sigs
+@@ -0,0 +1,247 @@
++GUID_all_zero: bool (const struct GUID *)
++GUID_compare: int (const struct GUID *, const struct GUID *)
++GUID_equal: bool (const struct GUID *, const struct GUID *)
++GUID_from_data_blob: NTSTATUS (const DATA_BLOB *, struct GUID *)
++GUID_from_ndr_blob: NTSTATUS (const DATA_BLOB *, struct GUID *)
++GUID_from_string: NTSTATUS (const char *, struct GUID *)
++GUID_hexstring: char *(TALLOC_CTX *, const struct GUID *)
++GUID_random: struct GUID (void)
++GUID_string: char *(TALLOC_CTX *, const struct GUID *)
++GUID_string2: char *(TALLOC_CTX *, const struct GUID *)
++GUID_to_ndr_blob: NTSTATUS (const struct GUID *, TALLOC_CTX *, DATA_BLOB *)
++GUID_zero: struct GUID (void)
++ndr_align_size: size_t (uint32_t, size_t)
++ndr_charset_length: uint32_t (const void *, charset_t)
++ndr_check_array_length: enum ndr_err_code (struct ndr_pull *, void *, uint32_t)
++ndr_check_array_size: enum ndr_err_code (struct ndr_pull *, void *, uint32_t)
++ndr_check_padding: void (struct ndr_pull *, size_t)
++ndr_check_pipe_chunk_trailer: enum ndr_err_code (struct ndr_pull *, int, uint32_t)
++ndr_check_string_terminator: enum ndr_err_code (struct ndr_pull *, uint32_t, uint32_t)
++ndr_get_array_length: uint32_t (struct ndr_pull *, const void *)
++ndr_get_array_size: uint32_t (struct ndr_pull *, const void *)
++ndr_map_error2errno: int (enum ndr_err_code)
++ndr_map_error2ntstatus: NTSTATUS (enum ndr_err_code)
++ndr_map_error2string: const char *(enum ndr_err_code)
++ndr_policy_handle_empty: bool (const struct policy_handle *)
++ndr_policy_handle_equal: bool (const struct policy_handle *, const struct policy_handle *)
++ndr_print_DATA_BLOB: void (struct ndr_print *, const char *, DATA_BLOB)
++ndr_print_GUID: void (struct ndr_print *, const char *, const struct GUID *)
++ndr_print_KRB5_EDATA_NTSTATUS: void (struct ndr_print *, const char *, const struct KRB5_EDATA_NTSTATUS *)
++ndr_print_NTSTATUS: void (struct ndr_print *, const char *, NTSTATUS)
++ndr_print_NTTIME: void (struct ndr_print *, const char *, NTTIME)
++ndr_print_NTTIME_1sec: void (struct ndr_print *, const char *, NTTIME)
++ndr_print_NTTIME_hyper: void (struct ndr_print *, const char *, NTTIME)
++ndr_print_WERROR: void (struct ndr_print *, const char *, WERROR)
++ndr_print_array_uint8: void (struct ndr_print *, const char *, const uint8_t *, uint32_t)
++ndr_print_bad_level: void (struct ndr_print *, const char *, uint16_t)
++ndr_print_bitmap_flag: void (struct ndr_print *, size_t, const char *, uint32_t, uint32_t)
++ndr_print_bool: void (struct ndr_print *, const char *, const bool)
++ndr_print_debug: void (ndr_print_fn_t, const char *, void *)
++ndr_print_debug_helper: void (struct ndr_print *, const char *, ...)
++ndr_print_debugc: void (int, ndr_print_fn_t, const char *, void *)
++ndr_print_debugc_helper: void (struct ndr_print *, const char *, ...)
++ndr_print_dlong: void (struct ndr_print *, const char *, int64_t)
++ndr_print_double: void (struct ndr_print *, const char *, double)
++ndr_print_enum: void (struct ndr_print *, const char *, const char *, const char *, uint32_t)
++ndr_print_function_debug: void (ndr_print_function_t, const char *, int, void *)
++ndr_print_function_string: char *(TALLOC_CTX *, ndr_print_function_t, const char *, int, void *)
++ndr_print_get_switch_value: uint32_t (struct ndr_print *, const void *)
++ndr_print_gid_t: void (struct ndr_print *, const char *, gid_t)
++ndr_print_hyper: void (struct ndr_print *, const char *, uint64_t)
++ndr_print_int16: void (struct ndr_print *, const char *, int16_t)
++ndr_print_int32: void (struct ndr_print *, const char *, int32_t)
++ndr_print_int3264: void (struct ndr_print *, const char *, int32_t)
++ndr_print_int8: void (struct ndr_print *, const char *, int8_t)
++ndr_print_ipv4address: void (struct ndr_print *, const char *, const char *)
++ndr_print_ipv6address: void (struct ndr_print *, const char *, const char *)
++ndr_print_ndr_syntax_id: void (struct ndr_print *, const char *, const struct ndr_syntax_id *)
++ndr_print_netr_SamDatabaseID: void (struct ndr_print *, const char *, enum netr_SamDatabaseID)
++ndr_print_netr_SchannelType: void (struct ndr_print *, const char *, enum netr_SchannelType)
++ndr_print_null: void (struct ndr_print *)
++ndr_print_pointer: void (struct ndr_print *, const char *, void *)
++ndr_print_policy_handle: void (struct ndr_print *, const char *, const struct policy_handle *)
++ndr_print_printf_helper: void (struct ndr_print *, const char *, ...)
++ndr_print_ptr: void (struct ndr_print *, const char *, const void *)
++ndr_print_set_switch_value: enum ndr_err_code (struct ndr_print *, const void *, uint32_t)
++ndr_print_sockaddr_storage: void (struct ndr_print *, const char *, const struct sockaddr_storage *)
++ndr_print_string: void (struct ndr_print *, const char *, const char *)
++ndr_print_string_array: void (struct ndr_print *, const char *, const char **)
++ndr_print_string_helper: void (struct ndr_print *, const char *, ...)
++ndr_print_struct: void (struct ndr_print *, const char *, const char *)
++ndr_print_struct_string: char *(TALLOC_CTX *, ndr_print_fn_t, const char *, void *)
++ndr_print_svcctl_ServerType: void (struct ndr_print *, const char *, uint32_t)
++ndr_print_time_t: void (struct ndr_print *, const char *, time_t)
++ndr_print_timespec: void (struct ndr_print *, const char *, const struct timespec *)
++ndr_print_timeval: void (struct ndr_print *, const char *, const struct timeval *)
++ndr_print_udlong: void (struct ndr_print *, const char *, uint64_t)
++ndr_print_udlongr: void (struct ndr_print *, const char *, uint64_t)
++ndr_print_uid_t: void (struct ndr_print *, const char *, uid_t)
++ndr_print_uint16: void (struct ndr_print *, const char *, uint16_t)
++ndr_print_uint32: void (struct ndr_print *, const char *, uint32_t)
++ndr_print_uint3264: void (struct ndr_print *, const char *, uint32_t)
++ndr_print_uint8: void (struct ndr_print *, const char *, uint8_t)
++ndr_print_union: void (struct ndr_print *, const char *, int, const char *)
++ndr_print_union_debug: void (ndr_print_fn_t, const char *, uint32_t, void *)
++ndr_print_union_string: char *(TALLOC_CTX *, ndr_print_fn_t, const char *, uint32_t, void *)
++ndr_print_winreg_Data: void (struct ndr_print *, const char *, const union winreg_Data *)
++ndr_print_winreg_Type: void (struct ndr_print *, const char *, enum winreg_Type)
++ndr_pull_DATA_BLOB: enum ndr_err_code (struct ndr_pull *, int, DATA_BLOB *)
++ndr_pull_GUID: enum ndr_err_code (struct ndr_pull *, int, struct GUID *)
++ndr_pull_KRB5_EDATA_NTSTATUS: enum ndr_err_code (struct ndr_pull *, int, struct KRB5_EDATA_NTSTATUS *)
++ndr_pull_NTSTATUS: enum ndr_err_code (struct ndr_pull *, int, NTSTATUS *)
++ndr_pull_NTTIME: enum ndr_err_code (struct ndr_pull *, int, NTTIME *)
++ndr_pull_NTTIME_1sec: enum ndr_err_code (struct ndr_pull *, int, NTTIME *)
++ndr_pull_NTTIME_hyper: enum ndr_err_code (struct ndr_pull *, int, NTTIME *)
++ndr_pull_WERROR: enum ndr_err_code (struct ndr_pull *, int, WERROR *)
++ndr_pull_advance: enum ndr_err_code (struct ndr_pull *, uint32_t)
++ndr_pull_align: enum ndr_err_code (struct ndr_pull *, size_t)
++ndr_pull_array_length: enum ndr_err_code (struct ndr_pull *, const void *)
++ndr_pull_array_size: enum ndr_err_code (struct ndr_pull *, const void *)
++ndr_pull_array_uint8: enum ndr_err_code (struct ndr_pull *, int, uint8_t *, uint32_t)
++ndr_pull_bytes: enum ndr_err_code (struct ndr_pull *, uint8_t *, uint32_t)
++ndr_pull_charset: enum ndr_err_code (struct ndr_pull *, int, const char **, uint32_t, uint8_t, charset_t)
++ndr_pull_charset_to_null: enum ndr_err_code (struct ndr_pull *, int, const char **, uint32_t, uint8_t, charset_t)
++ndr_pull_dlong: enum ndr_err_code (struct ndr_pull *, int, int64_t *)
++ndr_pull_double: enum ndr_err_code (struct ndr_pull *, int, double *)
++ndr_pull_enum_uint16: enum ndr_err_code (struct ndr_pull *, int, uint16_t *)
++ndr_pull_enum_uint1632: enum ndr_err_code (struct ndr_pull *, int, uint16_t *)
++ndr_pull_enum_uint32: enum ndr_err_code (struct ndr_pull *, int, uint32_t *)
++ndr_pull_enum_uint8: enum ndr_err_code (struct ndr_pull *, int, uint8_t *)
++ndr_pull_error: enum ndr_err_code (struct ndr_pull *, enum ndr_err_code, const char *, ...)
++ndr_pull_generic_ptr: enum ndr_err_code (struct ndr_pull *, uint32_t *)
++ndr_pull_get_relative_base_offset: uint32_t (struct ndr_pull *)
++ndr_pull_get_switch_value: uint32_t (struct ndr_pull *, const void *)
++ndr_pull_gid_t: enum ndr_err_code (struct ndr_pull *, int, gid_t *)
++ndr_pull_hyper: enum ndr_err_code (struct ndr_pull *, int, uint64_t *)
++ndr_pull_init_blob: struct ndr_pull *(const DATA_BLOB *, TALLOC_CTX *)
++ndr_pull_int16: enum ndr_err_code (struct ndr_pull *, int, int16_t *)
++ndr_pull_int32: enum ndr_err_code (struct ndr_pull *, int, int32_t *)
++ndr_pull_int8: enum ndr_err_code (struct ndr_pull *, int, int8_t *)
++ndr_pull_ipv4address: enum ndr_err_code (struct ndr_pull *, int, const char **)
++ndr_pull_ipv6address: enum ndr_err_code (struct ndr_pull *, int, const char **)
++ndr_pull_ndr_syntax_id: enum ndr_err_code (struct ndr_pull *, int, struct ndr_syntax_id *)
++ndr_pull_netr_SamDatabaseID: enum ndr_err_code (struct ndr_pull *, int, enum netr_SamDatabaseID *)
++ndr_pull_netr_SchannelType: enum ndr_err_code (struct ndr_pull *, int, enum netr_SchannelType *)
++ndr_pull_pointer: enum ndr_err_code (struct ndr_pull *, int, void **)
++ndr_pull_policy_handle: enum ndr_err_code (struct ndr_pull *, int, struct policy_handle *)
++ndr_pull_ref_ptr: enum ndr_err_code (struct ndr_pull *, uint32_t *)
++ndr_pull_relative_ptr1: enum ndr_err_code (struct ndr_pull *, const void *, uint32_t)
++ndr_pull_relative_ptr2: enum ndr_err_code (struct ndr_pull *, const void *)
++ndr_pull_relative_ptr_short: enum ndr_err_code (struct ndr_pull *, uint16_t *)
++ndr_pull_restore_relative_base_offset: void (struct ndr_pull *, uint32_t)
++ndr_pull_set_switch_value: enum ndr_err_code (struct ndr_pull *, const void *, uint32_t)
++ndr_pull_setup_relative_base_offset1: enum ndr_err_code (struct ndr_pull *, const void *, uint32_t)
++ndr_pull_setup_relative_base_offset2: enum ndr_err_code (struct ndr_pull *, const void *)
++ndr_pull_string: enum ndr_err_code (struct ndr_pull *, int, const char **)
++ndr_pull_string_array: enum ndr_err_code (struct ndr_pull *, int, const char ***)
++ndr_pull_struct_blob: enum ndr_err_code (const DATA_BLOB *, TALLOC_CTX *, void *, ndr_pull_flags_fn_t)
++ndr_pull_struct_blob_all: enum ndr_err_code (const DATA_BLOB *, TALLOC_CTX *, void *, ndr_pull_flags_fn_t)
++ndr_pull_subcontext_end: enum ndr_err_code (struct ndr_pull *, struct ndr_pull *, size_t, ssize_t)
++ndr_pull_subcontext_start: enum ndr_err_code (struct ndr_pull *, struct ndr_pull **, size_t, ssize_t)
++ndr_pull_svcctl_ServerType: enum ndr_err_code (struct ndr_pull *, int, uint32_t *)
++ndr_pull_time_t: enum ndr_err_code (struct ndr_pull *, int, time_t *)
++ndr_pull_timespec: enum ndr_err_code (struct ndr_pull *, int, struct timespec *)
++ndr_pull_timeval: enum ndr_err_code (struct ndr_pull *, int, struct timeval *)
++ndr_pull_trailer_align: enum ndr_err_code (struct ndr_pull *, size_t)
++ndr_pull_udlong: enum ndr_err_code (struct ndr_pull *, int, uint64_t *)
++ndr_pull_udlongr: enum ndr_err_code (struct ndr_pull *, int, uint64_t *)
++ndr_pull_uid_t: enum ndr_err_code (struct ndr_pull *, int, uid_t *)
++ndr_pull_uint16: enum ndr_err_code (struct ndr_pull *, int, uint16_t *)
++ndr_pull_uint1632: enum ndr_err_code (struct ndr_pull *, int, uint16_t *)
++ndr_pull_uint32: enum ndr_err_code (struct ndr_pull *, int, uint32_t *)
++ndr_pull_uint3264: enum ndr_err_code (struct ndr_pull *, int, uint32_t *)
++ndr_pull_uint8: enum ndr_err_code (struct ndr_pull *, int, uint8_t *)
++ndr_pull_union_align: enum ndr_err_code (struct ndr_pull *, size_t)
++ndr_pull_union_blob: enum ndr_err_code (const DATA_BLOB *, TALLOC_CTX *, void *, uint32_t, ndr_pull_flags_fn_t)
++ndr_pull_union_blob_all: enum ndr_err_code (const DATA_BLOB *, TALLOC_CTX *, void *, uint32_t, ndr_pull_flags_fn_t)
++ndr_pull_winreg_Data: enum ndr_err_code (struct ndr_pull *, int, union winreg_Data *)
++ndr_pull_winreg_Type: enum ndr_err_code (struct ndr_pull *, int, enum winreg_Type *)
++ndr_push_DATA_BLOB: enum ndr_err_code (struct ndr_push *, int, DATA_BLOB)
++ndr_push_GUID: enum ndr_err_code (struct ndr_push *, int, const struct GUID *)
++ndr_push_KRB5_EDATA_NTSTATUS: enum ndr_err_code (struct ndr_push *, int, const struct KRB5_EDATA_NTSTATUS *)
++ndr_push_NTSTATUS: enum ndr_err_code (struct ndr_push *, int, NTSTATUS)
++ndr_push_NTTIME: enum ndr_err_code (struct ndr_push *, int, NTTIME)
++ndr_push_NTTIME_1sec: enum ndr_err_code (struct ndr_push *, int, NTTIME)
++ndr_push_NTTIME_hyper: enum ndr_err_code (struct ndr_push *, int, NTTIME)
++ndr_push_WERROR: enum ndr_err_code (struct ndr_push *, int, WERROR)
++ndr_push_align: enum ndr_err_code (struct ndr_push *, size_t)
++ndr_push_array_uint8: enum ndr_err_code (struct ndr_push *, int, const uint8_t *, uint32_t)
++ndr_push_blob: DATA_BLOB (struct ndr_push *)
++ndr_push_bytes: enum ndr_err_code (struct ndr_push *, const uint8_t *, uint32_t)
++ndr_push_charset: enum ndr_err_code (struct ndr_push *, int, const char *, uint32_t, uint8_t, charset_t)
++ndr_push_dlong: enum ndr_err_code (struct ndr_push *, int, int64_t)
++ndr_push_double: enum ndr_err_code (struct ndr_push *, int, double)
++ndr_push_enum_uint16: enum ndr_err_code (struct ndr_push *, int, uint16_t)
++ndr_push_enum_uint1632: enum ndr_err_code (struct ndr_push *, int, uint16_t)
++ndr_push_enum_uint32: enum ndr_err_code (struct ndr_push *, int, uint32_t)
++ndr_push_enum_uint8: enum ndr_err_code (struct ndr_push *, int, uint8_t)
++ndr_push_error: enum ndr_err_code (struct ndr_push *, enum ndr_err_code, const char *, ...)
++ndr_push_expand: enum ndr_err_code (struct ndr_push *, uint32_t)
++ndr_push_full_ptr: enum ndr_err_code (struct ndr_push *, const void *)
++ndr_push_get_relative_base_offset: uint32_t (struct ndr_push *)
++ndr_push_get_switch_value: uint32_t (struct ndr_push *, const void *)
++ndr_push_gid_t: enum ndr_err_code (struct ndr_push *, int, gid_t)
++ndr_push_hyper: enum ndr_err_code (struct ndr_push *, int, uint64_t)
++ndr_push_init_ctx: struct ndr_push *(TALLOC_CTX *)
++ndr_push_int16: enum ndr_err_code (struct ndr_push *, int, int16_t)
++ndr_push_int32: enum ndr_err_code (struct ndr_push *, int, int32_t)
++ndr_push_int8: enum ndr_err_code (struct ndr_push *, int, int8_t)
++ndr_push_ipv4address: enum ndr_err_code (struct ndr_push *, int, const char *)
++ndr_push_ipv6address: enum ndr_err_code (struct ndr_push *, int, const char *)
++ndr_push_ndr_syntax_id: enum ndr_err_code (struct ndr_push *, int, const struct ndr_syntax_id *)
++ndr_push_netr_SamDatabaseID: enum ndr_err_code (struct ndr_push *, int, enum netr_SamDatabaseID)
++ndr_push_netr_SchannelType: enum ndr_err_code (struct ndr_push *, int, enum netr_SchannelType)
++ndr_push_pipe_chunk_trailer: enum ndr_err_code (struct ndr_push *, int, uint32_t)
++ndr_push_pointer: enum ndr_err_code (struct ndr_push *, int, void *)
++ndr_push_policy_handle: enum ndr_err_code (struct ndr_push *, int, const struct policy_handle *)
++ndr_push_ref_ptr: enum ndr_err_code (struct ndr_push *)
++ndr_push_relative_ptr1: enum ndr_err_code (struct ndr_push *, const void *)
++ndr_push_relative_ptr2_end: enum ndr_err_code (struct ndr_push *, const void *)
++ndr_push_relative_ptr2_start: enum ndr_err_code (struct ndr_push *, const void *)
++ndr_push_restore_relative_base_offset: void (struct ndr_push *, uint32_t)
++ndr_push_set_switch_value: enum ndr_err_code (struct ndr_push *, const void *, uint32_t)
++ndr_push_setup_relative_base_offset1: enum ndr_err_code (struct ndr_push *, const void *, uint32_t)
++ndr_push_setup_relative_base_offset2: enum ndr_err_code (struct ndr_push *, const void *)
++ndr_push_short_relative_ptr1: enum ndr_err_code (struct ndr_push *, const void *)
++ndr_push_short_relative_ptr2: enum ndr_err_code (struct ndr_push *, const void *)
++ndr_push_string: enum ndr_err_code (struct ndr_push *, int, const char *)
++ndr_push_string_array: enum ndr_err_code (struct ndr_push *, int, const char **)
++ndr_push_struct_blob: enum ndr_err_code (DATA_BLOB *, TALLOC_CTX *, const void *, ndr_push_flags_fn_t)
++ndr_push_subcontext_end: enum ndr_err_code (struct ndr_push *, struct ndr_push *, size_t, ssize_t)
++ndr_push_subcontext_start: enum ndr_err_code (struct ndr_push *, struct ndr_push **, size_t, ssize_t)
++ndr_push_svcctl_ServerType: enum ndr_err_code (struct ndr_push *, int, uint32_t)
++ndr_push_time_t: enum ndr_err_code (struct ndr_push *, int, time_t)
++ndr_push_timespec: enum ndr_err_code (struct ndr_push *, int, const struct timespec *)
++ndr_push_timeval: enum ndr_err_code (struct ndr_push *, int, const struct timeval *)
++ndr_push_trailer_align: enum ndr_err_code (struct ndr_push *, size_t)
++ndr_push_udlong: enum ndr_err_code (struct ndr_push *, int, uint64_t)
++ndr_push_udlongr: enum ndr_err_code (struct ndr_push *, int, uint64_t)
++ndr_push_uid_t: enum ndr_err_code (struct ndr_push *, int, uid_t)
++ndr_push_uint16: enum ndr_err_code (struct ndr_push *, int, uint16_t)
++ndr_push_uint1632: enum ndr_err_code (struct ndr_push *, int, uint16_t)
++ndr_push_uint32: enum ndr_err_code (struct ndr_push *, int, uint32_t)
++ndr_push_uint3264: enum ndr_err_code (struct ndr_push *, int, uint32_t)
++ndr_push_uint8: enum ndr_err_code (struct ndr_push *, int, uint8_t)
++ndr_push_union_align: enum ndr_err_code (struct ndr_push *, size_t)
++ndr_push_union_blob: enum ndr_err_code (DATA_BLOB *, TALLOC_CTX *, void *, uint32_t, ndr_push_flags_fn_t)
++ndr_push_unique_ptr: enum ndr_err_code (struct ndr_push *, const void *)
++ndr_push_winreg_Data: enum ndr_err_code (struct ndr_push *, int, const union winreg_Data *)
++ndr_push_winreg_Type: enum ndr_err_code (struct ndr_push *, int, enum winreg_Type)
++ndr_push_zero: enum ndr_err_code (struct ndr_push *, uint32_t)
++ndr_set_flags: void (uint32_t *, uint32_t)
++ndr_size_DATA_BLOB: uint32_t (int, const DATA_BLOB *, int)
++ndr_size_GUID: size_t (const struct GUID *, int)
++ndr_size_string: uint32_t (int, const char * const *, int)
++ndr_size_string_array: size_t (const char **, uint32_t, int)
++ndr_size_struct: size_t (const void *, int, ndr_push_flags_fn_t)
++ndr_size_union: size_t (const void *, int, uint32_t, ndr_push_flags_fn_t)
++ndr_string_array_size: size_t (struct ndr_push *, const char *)
++ndr_string_length: uint32_t (const void *, uint32_t)
++ndr_syntax_id_equal: bool (const struct ndr_syntax_id *, const struct ndr_syntax_id *)
++ndr_syntax_id_null: uuid = {time_low = 0, time_mid = 0, time_hi_and_version = 0, clock_seq = "\000", node = "\000\000\000\000\000"}, if_version = 0
++ndr_token_peek: uint32_t (struct ndr_token_list **, const void *)
++ndr_token_retrieve: enum ndr_err_code (struct ndr_token_list **, const void *, uint32_t *)
++ndr_token_retrieve_cmp_fn: enum ndr_err_code (struct ndr_token_list **, const void *, uint32_t *, comparison_fn_t, bool)
++ndr_token_store: enum ndr_err_code (TALLOC_CTX *, struct ndr_token_list **, const void *, uint32_t)
++ndr_transfer_syntax_ndr: uuid = {time_low = 2324192516, time_mid = 7403, time_hi_and_version = 4553, clock_seq = "\237\350", node = "\b\000+\020H`"}, if_version = 2
++ndr_transfer_syntax_ndr64: uuid = {time_low = 1903232307, time_mid = 48826, time_hi_and_version = 18743, clock_seq = "\203\031", node = "\265\333\357\234\314\066"}, if_version = 1
+diff --git a/librpc/ndr/libndr.h b/librpc/ndr/libndr.h
+index 1e40779..ce3a676 100644
+--- a/librpc/ndr/libndr.h
++++ b/librpc/ndr/libndr.h
+@@ -163,6 +163,7 @@ struct ndr_print {
+ 
+ /* useful macro for debugging */
+ #define NDR_PRINT_DEBUG(type, p) ndr_print_debug((ndr_print_fn_t)ndr_print_ ##type, #p, p)
++#define NDR_PRINT_DEBUGC(dbgc_class, type, p) ndr_print_debugc(dbgc_class, (ndr_print_fn_t)ndr_print_ ##type, #p, p)
+ #define NDR_PRINT_UNION_DEBUG(type, level, p) ndr_print_union_debug((ndr_print_fn_t)ndr_print_ ##type, #p, level, p)
+ #define NDR_PRINT_FUNCTION_DEBUG(type, flags, p) ndr_print_function_debug((ndr_print_function_t)ndr_print_ ##type, #type, flags, p)
+ #define NDR_PRINT_BOTH_DEBUG(type, p) NDR_PRINT_FUNCTION_DEBUG(type, NDR_BOTH, p)
+@@ -429,9 +430,11 @@ struct ndr_push *ndr_push_init_ctx(TALLOC_CTX *mem_ctx);
+ DATA_BLOB ndr_push_blob(struct ndr_push *ndr);
+ enum ndr_err_code ndr_push_expand(struct ndr_push *ndr, uint32_t extra_size);
+ void ndr_print_debug_helper(struct ndr_print *ndr, const char *format, ...) PRINTF_ATTRIBUTE(2,3);
++void ndr_print_debugc_helper(struct ndr_print *ndr, const char *format, ...) PRINTF_ATTRIBUTE(2,3);
+ void ndr_print_printf_helper(struct ndr_print *ndr, const char *format, ...) PRINTF_ATTRIBUTE(2,3);
+ void ndr_print_string_helper(struct ndr_print *ndr, const char *format, ...) PRINTF_ATTRIBUTE(2,3);
+ void ndr_print_debug(ndr_print_fn_t fn, const char *name, void *ptr);
++void ndr_print_debugc(int dbgc_class, ndr_print_fn_t fn, const char *name, void *ptr);
+ void ndr_print_union_debug(ndr_print_fn_t fn, const char *name, uint32_t level, void *ptr);
+ void ndr_print_function_debug(ndr_print_function_t fn, const char *name, int flags, void *ptr);
+ char *ndr_print_struct_string(TALLOC_CTX *mem_ctx, ndr_print_fn_t fn, const char *name, void *ptr);
+diff --git a/librpc/ndr/ndr.c b/librpc/ndr/ndr.c
+index 8b442b6..ba17a27 100644
+--- a/librpc/ndr/ndr.c
++++ b/librpc/ndr/ndr.c
+@@ -167,6 +167,38 @@ _PUBLIC_ enum ndr_err_code ndr_push_expand(struct ndr_push *ndr, uint32_t extra_
+ 	return NDR_ERR_SUCCESS;
+ }
+ 
++_PUBLIC_ void ndr_print_debugc_helper(struct ndr_print *ndr, const char *format, ...)
++{
++	va_list ap;
++	char *s = NULL;
++	uint32_t i;
++	int ret;
++	int dbgc_class;
++
++	va_start(ap, format);
++	ret = vasprintf(&s, format, ap);
++	va_end(ap);
++
++	if (ret == -1) {
++		return;
++	}
++
++	dbgc_class = *(int *)ndr->private_data;
++
++	if (ndr->no_newline) {
++		DEBUGADDC(dbgc_class, 1,("%s", s));
++		free(s);
++		return;
++	}
++
++	for (i=0;i<ndr->depth;i++) {
++		DEBUGADDC(dbgc_class, 1,("    "));
++	}
++
++	DEBUGADDC(dbgc_class, 1,("%s\n", s));
++	free(s);
++}
++
+ _PUBLIC_ void ndr_print_debug_helper(struct ndr_print *ndr, const char *format, ...) 
+ {
+ 	va_list ap;
+@@ -238,6 +270,25 @@ _PUBLIC_ void ndr_print_string_helper(struct ndr_print *ndr, const char *format,
+ }
+ 
+ /*
++  a useful helper function for printing idl structures via DEBUGC()
++*/
++_PUBLIC_ void ndr_print_debugc(int dbgc_class, ndr_print_fn_t fn, const char *name, void *ptr)
++{
++	struct ndr_print *ndr;
++
++	DEBUGC(dbgc_class, 1,(" "));
++
++	ndr = talloc_zero(NULL, struct ndr_print);
++	if (!ndr) return;
++	ndr->private_data = &dbgc_class;
++	ndr->print = ndr_print_debugc_helper;
++	ndr->depth = 1;
++	ndr->flags = 0;
++	fn(ndr, name, ptr);
++	talloc_free(ndr);
++}
++
++/*
+   a useful helper function for printing idl structures via DEBUG()
+ */
+ _PUBLIC_ void ndr_print_debug(ndr_print_fn_t fn, const char *name, void *ptr)
+-- 
+2.8.1
+
+
+From a78ed56ca69b44f1b35738438b019cae8b406a77 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Fri, 3 Jan 2014 09:25:23 +0100
+Subject: [PATCH 07/40] librpc/ndr: add LIBNDR_FLAG_SUBCONTEXT_NO_UNREAD_BYTES
+
+This lets ndr_pull_subcontext_end() make sure that all
+subcontext bytes are consumed otherwise it returns NDR_ERR_UNREAD_BYTES.
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Andrew Bartlett <abartlet at samba.org>
+(cherry picked from commit b62308ed994e9734dfd934d230531010d9e7cefa)
+(cherry picked from commit 8a4447553ad1aae10e42eac08d08c26ad40eac5c)
+---
+ librpc/idl/idl_types.h |  2 ++
+ librpc/ndr/libndr.h    |  6 ++++++
+ librpc/ndr/ndr.c       | 20 ++++++++++++++++++++
+ 3 files changed, 28 insertions(+)
+
+diff --git a/librpc/idl/idl_types.h b/librpc/idl/idl_types.h
+index 023c040..fd95fdd 100644
+--- a/librpc/idl/idl_types.h
++++ b/librpc/idl/idl_types.h
+@@ -47,3 +47,5 @@
+ 
+ #define NDR_RELATIVE_REVERSE LIBNDR_FLAG_RELATIVE_REVERSE
+ #define NDR_NO_RELATIVE_REVERSE LIBNDR_FLAG_NO_RELATIVE_REVERSE
++
++#define NDR_SUBCONTEXT_NO_UNREAD_BYTES LIBNDR_FLAG_SUBCONTEXT_NO_UNREAD_BYTES
+diff --git a/librpc/ndr/libndr.h b/librpc/ndr/libndr.h
+index ce3a676..2453d5a 100644
+--- a/librpc/ndr/libndr.h
++++ b/librpc/ndr/libndr.h
+@@ -124,6 +124,12 @@ struct ndr_print {
+ #define LIBNDR_FLAG_STR_UTF8		(1<<12)
+ #define LIBNDR_STRING_FLAGS		(0x7FFC)
+ 
++/*
++ * This lets ndr_pull_subcontext_end() return
++ * NDR_ERR_UNREAD_BYTES.
++ */
++#define LIBNDR_FLAG_SUBCONTEXT_NO_UNREAD_BYTES (1<<17)
++
+ /* set if relative pointers should *not* be marshalled in reverse order */
+ #define LIBNDR_FLAG_NO_RELATIVE_REVERSE	(1<<18)
+ 
+diff --git a/librpc/ndr/ndr.c b/librpc/ndr/ndr.c
+index ba17a27..fc11738 100644
+--- a/librpc/ndr/ndr.c
++++ b/librpc/ndr/ndr.c
+@@ -640,6 +640,8 @@ _PUBLIC_ enum ndr_err_code ndr_pull_subcontext_end(struct ndr_pull *ndr,
+ 				 ssize_t size_is)
+ {
+ 	uint32_t advance;
++	uint32_t highest_ofs;
++
+ 	if (size_is >= 0) {
+ 		advance = size_is;
+ 	} else if (header_size > 0) {
+@@ -647,6 +649,24 @@ _PUBLIC_ enum ndr_err_code ndr_pull_subcontext_end(struct ndr_pull *ndr,
+ 	} else {
+ 		advance = subndr->offset;
+ 	}
++
++	if (subndr->offset > ndr->relative_highest_offset) {
++		highest_ofs = subndr->offset;
++	} else {
++		highest_ofs = subndr->relative_highest_offset;
++	}
++	if (!(subndr->flags & LIBNDR_FLAG_SUBCONTEXT_NO_UNREAD_BYTES)) {
++		/*
++		 * avoid an error unless SUBCONTEXT_NO_UNREAD_BYTES is specified
++		 */
++		highest_ofs = advance;
++	}
++	if (highest_ofs < advance) {
++		return ndr_pull_error(subndr, NDR_ERR_UNREAD_BYTES,
++				      "not all bytes consumed ofs[%u] advance[%u]",
++				      highest_ofs, advance);
++	}
++
+ 	NDR_CHECK(ndr_pull_advance(ndr, advance));
+ 	return NDR_ERR_SUCCESS;
+ }
+-- 
+2.8.1
+
+
+From 26a9f8f469ed83e8d15b3c626791a76ec72415b0 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Thu, 2 Jan 2014 11:18:38 +0100
+Subject: [PATCH 08/40] dcerpc.idl: add dcerpc_sec_verification_trailer
+
+See [MS-RPCE] 2.2.2.13 Verification Trailer for details.
+
+Pair-Programmed-With: Gregor Beck <gbeck at sernet.de>
+
+Signed-off-by: Gregor Beck <gbeck at sernet.de>
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Andrew Bartlett <abartlet at samba.org>
+(cherry picked from commit c0dc2fb7e1dadcef35a132040448cb27ff1d5bfa)
+---
+ librpc/idl/dcerpc.idl   | 67 +++++++++++++++++++++++++++++++++++++++++++++++++
+ librpc/ndr/ndr_dcerpc.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++
+ librpc/wscript_build    |  2 +-
+ source3/Makefile.in     |  3 ++-
+ 4 files changed, 136 insertions(+), 2 deletions(-)
+ create mode 100644 librpc/ndr/ndr_dcerpc.c
+
+diff --git a/librpc/idl/dcerpc.idl b/librpc/idl/dcerpc.idl
+index 8949836..6c4e4c1 100644
+--- a/librpc/idl/dcerpc.idl
++++ b/librpc/idl/dcerpc.idl
+@@ -10,6 +10,8 @@
+ */
+ import "misc.idl";
+ 
++cpp_quote("extern const uint8_t DCERPC_SEC_VT_MAGIC[8];")
++
+ interface dcerpc
+ {
+ 	typedef struct {
+@@ -506,4 +508,69 @@ interface dcerpc
+ 		uint8 serial_low;
+ 		[switch_is(ptype)] dcerpc_payload u;
+ 	} ncadg_packet;
++
++	typedef [bitmap16bit] bitmap {
++		DCERPC_SEC_VT_COMMAND_ENUM  = 0x3FFF,
++		DCERPC_SEC_VT_COMMAND_END   = 0x4000,
++		DCERPC_SEC_VT_MUST_PROCESS  = 0x8000
++	} dcerpc_sec_vt_command;
++
++	typedef [enum16bit] enum {
++		DCERPC_SEC_VT_COMMAND_BITMASK1  = 0x0001,
++		DCERPC_SEC_VT_COMMAND_PCONTEXT  = 0x0002,
++		DCERPC_SEC_VT_COMMAND_HEADER2   = 0x0003
++	} dcerpc_sec_vt_command_enum;
++
++	typedef [bitmap32bit] bitmap {
++		DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING = 0x00000001
++	} dcerpc_sec_vt_bitmask1;
++
++	typedef struct {
++		ndr_syntax_id abstract_syntax;
++		ndr_syntax_id transfer_syntax;
++	} dcerpc_sec_vt_pcontext;
++
++	typedef struct {
++		dcerpc_pkt_type ptype;  /* Packet type */
++		[value(0)] uint8 reserved1;
++		[value(0)] uint16 reserved2;
++		uint8 drep[4];          /* NDR data representation */
++		uint32 call_id;         /* Call identifier */
++		uint16 context_id;
++		uint16 opnum;
++	} dcerpc_sec_vt_header2;
++
++	typedef [switch_type(dcerpc_sec_vt_command_enum),nodiscriminant] union {
++	[case(DCERPC_SEC_VT_COMMAND_BITMASK1)] dcerpc_sec_vt_bitmask1 bitmask1;
++	[case(DCERPC_SEC_VT_COMMAND_PCONTEXT)] dcerpc_sec_vt_pcontext pcontext;
++	[case(DCERPC_SEC_VT_COMMAND_HEADER2)] dcerpc_sec_vt_header2 header2;
++	[default,flag(NDR_REMAINING)] DATA_BLOB _unknown;
++	} dcerpc_sec_vt_union;
++
++	typedef struct {
++		dcerpc_sec_vt_command command;
++		[switch_is(command & DCERPC_SEC_VT_COMMAND_ENUM)]
++			[subcontext(2),flag(NDR_SUBCONTEXT_NO_UNREAD_BYTES)]
++			dcerpc_sec_vt_union u;
++	} dcerpc_sec_vt;
++
++	typedef [public,nopush,nopull] struct {
++		uint16 count;
++	} dcerpc_sec_vt_count;
++
++	/*
++	 * We assume that the whole verification trailer fits into
++	 * the last 1024 bytes after the stub data.
++	 *
++	 * There're currently only 3 commands defined and each should
++	 * only be used once.
++	 */
++	const uint16 DCERPC_SEC_VT_MAX_SIZE = 1024;
++
++	typedef [public,flag(NDR_PAHEX)] struct {
++		[flag(NDR_ALIGN4)] DATA_BLOB _pad;
++		[value(DCERPC_SEC_VT_MAGIC)] uint8 magic[8];
++		dcerpc_sec_vt_count count;
++		dcerpc_sec_vt commands[count.count];
++	} dcerpc_sec_verification_trailer;
+ }
+diff --git a/librpc/ndr/ndr_dcerpc.c b/librpc/ndr/ndr_dcerpc.c
+new file mode 100644
+index 0000000..1b4c75c
+--- /dev/null
++++ b/librpc/ndr/ndr_dcerpc.c
+@@ -0,0 +1,66 @@
++/*
++   Unix SMB/CIFS implementation.
++
++   Manually parsed structures found in the DCERPC protocol
++
++   Copyright (C) Stefan Metzmacher 2014
++   Copyright (C) Gregor Beck 2014
++
++   This program is free software; you can redistribute it and/or modify
++   it under the terms of the GNU General Public License as published by
++   the Free Software Foundation; either version 3 of the License, or
++   (at your option) any later version.
++
++   This program is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU General Public License for more details.
++
++   You should have received a copy of the GNU General Public License
++   along with this program.  If not, see <http://www.gnu.org/licenses/>.
++*/
++
++#include "includes.h"
++#include "librpc/gen_ndr/ndr_dcerpc.h"
++
++#include "librpc/gen_ndr/ndr_misc.h"
++
++const uint8_t DCERPC_SEC_VT_MAGIC[] = {0x8a,0xe3,0x13,0x71,0x02,0xf4,0x36,0x71};
++
++_PUBLIC_ enum ndr_err_code ndr_push_dcerpc_sec_vt_count(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_sec_vt_count *r)
++{
++	NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
++	/* nothing */
++	return NDR_ERR_SUCCESS;
++}
++
++_PUBLIC_ enum ndr_err_code ndr_pull_dcerpc_sec_vt_count(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_sec_vt_count *r)
++{
++	uint32_t _saved_ofs = ndr->offset;
++
++	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
++
++	if (!(ndr_flags & NDR_SCALARS)) {
++		return NDR_ERR_SUCCESS;
++	}
++
++	r->count = 0;
++
++	while (true) {
++		uint16_t command;
++		uint16_t length;
++
++		NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &command));
++		NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &length));
++		NDR_CHECK(ndr_pull_advance(ndr, length));
++
++		r->count += 1;
++
++		if (command & DCERPC_SEC_VT_COMMAND_END) {
++			break;
++		}
++	}
++
++	ndr->offset = _saved_ofs;
++	return NDR_ERR_SUCCESS;
++}
+diff --git a/librpc/wscript_build b/librpc/wscript_build
+index ce78cb6..1f8e556 100644
+--- a/librpc/wscript_build
++++ b/librpc/wscript_build
+@@ -274,7 +274,7 @@ bld.SAMBA_SUBSYSTEM('NDR_COMPRESSION',
+ 	)
+ 
+ bld.SAMBA_SUBSYSTEM('NDR_DCERPC',
+-	source='gen_ndr/ndr_dcerpc.c',
++	source='gen_ndr/ndr_dcerpc.c ndr/ndr_dcerpc.c',
+ 	public_deps='ndr',
+ 	public_headers='gen_ndr/ndr_dcerpc.h gen_ndr/dcerpc.h',
+ 	header_path= [ ('*gen_ndr*', 'gen_ndr') ],
+diff --git a/source3/Makefile.in b/source3/Makefile.in
+index 9e8e03d..4f9cbb4 100644
+--- a/source3/Makefile.in
++++ b/source3/Makefile.in
+@@ -323,7 +323,8 @@ LIBNDR_OBJ = ../librpc/ndr/ndr_basic.o \
+ 	     ../librpc/ndr/uuid.o \
+ 	     librpc/ndr/util.o \
+ 	     librpc/gen_ndr/ndr_server_id.o \
+-	     librpc/gen_ndr/ndr_dcerpc.o
++	     librpc/gen_ndr/ndr_dcerpc.o \
++	     ../librpc/ndr/ndr_dcerpc.o
+ 
+ LIBNDR_GEN_OBJ0 = librpc/gen_ndr/ndr_samr.o \
+ 		  librpc/gen_ndr/ndr_lsa.o
+-- 
+2.8.1
+
+
+From 61bffbdb21d845745261beb9107c57b8a3a163b5 Mon Sep 17 00:00:00 2001
+From: Andrew Tridgell <tridge at samba.org>
+Date: Wed, 7 Sep 2011 15:29:32 +1000
+Subject: [PATCH 09/40] libndr: moved the NDR_* flags to have less overlap
+
+We have 3 different types of flags values in our NDR layer. We've
+recently found bugs where these types of flags have been mixed up,
+especially by people adding hand written ndr code for tricky
+structures. We previously got away with this because (for example)
+NDR_SCALARS and NDR_IN had the same value, so mixing up the two
+concepts sometimes worked. Unfortunately it also led to bugs where we
+didn't do what was expected, such as in our smbtorture ndr test suite,
+where passing a ndr_flags value of zero led to only checking that two
+empty structures were equal.
+
+This changes the values of the NDR_IN|NDR_OUT and
+NDR_SCALARS|NDR_BUFFERS values to be in different bit ranges, and adds
+macros for checking the validity of passed in flags. A followup patch
+modifies the ndr calls to use these macros, and pidl to generate
+them. This should catch misuse of the APIs.
+
+Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>
+---
+ librpc/ndr/libndr.h | 44 ++++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 36 insertions(+), 8 deletions(-)
+
+diff --git a/librpc/ndr/libndr.h b/librpc/ndr/libndr.h
+index 2453d5a..924a4e4 100644
+--- a/librpc/ndr/libndr.h
++++ b/librpc/ndr/libndr.h
+@@ -206,7 +206,8 @@ enum ndr_err_code {
+ 	NDR_ERR_IPV6ADDRESS,
+ 	NDR_ERR_INVALID_POINTER,
+ 	NDR_ERR_UNREAD_BYTES,
+-	NDR_ERR_NDR64
++	NDR_ERR_NDR64,
++	NDR_ERR_FLAGS
+ };
+ 
+ #define NDR_ERR_CODE_IS_SUCCESS(x) (x == NDR_ERR_SUCCESS)
+@@ -224,17 +225,44 @@ enum ndr_compression_alg {
+ 
+ /*
+   flags passed to control parse flow
++  These are deliberately in a different range to the NDR_IN/NDR_OUT
++  flags to catch mixups
+ */
+-#define NDR_SCALARS 1
+-#define NDR_BUFFERS 2
++#define NDR_SCALARS    0x100
++#define NDR_BUFFERS    0x200
+ 
+ /*
+-  flags passed to ndr_print_*()
++  flags passed to ndr_print_*() and ndr pull/push for functions
++  These are deliberately in a different range to the NDR_SCALARS/NDR_BUFFERS
++  flags to catch mixups
+ */
+-#define NDR_IN 1
+-#define NDR_OUT 2
+-#define NDR_BOTH 3
+-#define NDR_SET_VALUES 4
++#define NDR_IN         0x10
++#define NDR_OUT        0x20
++#define NDR_BOTH       0x30
++#define NDR_SET_VALUES 0x40
++
++
++#define NDR_PULL_CHECK_FLAGS(ndr, ndr_flags) do { \
++	if ((ndr_flags) & ~(NDR_SCALARS|NDR_BUFFERS)) { \
++		return ndr_pull_error(ndr, NDR_ERR_FLAGS, "Invalid pull struct ndr_flags 0x%x", ndr_flags); \
++	} \
++} while (0)
++
++#define NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags) do { \
++	if ((ndr_flags) & ~(NDR_SCALARS|NDR_BUFFERS)) \
++		return ndr_push_error(ndr, NDR_ERR_FLAGS, "Invalid push struct ndr_flags 0x%x", ndr_flags); \
++} while (0)
++
++#define NDR_PULL_CHECK_FN_FLAGS(ndr, flags) do { \
++	if ((flags) & ~(NDR_BOTH|NDR_SET_VALUES)) { \
++		return ndr_pull_error(ndr, NDR_ERR_FLAGS, "Invalid fn pull flags 0x%x", flags); \
++	} \
++} while (0)
++
++#define NDR_PUSH_CHECK_FN_FLAGS(ndr, flags) do { \
++	if ((flags) & ~(NDR_BOTH|NDR_SET_VALUES)) \
++		return ndr_push_error(ndr, NDR_ERR_FLAGS, "Invalid fn push flags 0x%x", flags); \
++} while (0)
+ 
+ #define NDR_PULL_NEED_BYTES(ndr, n) do { \
+ 	if (unlikely((n) > ndr->data_size || ndr->offset + (n) > ndr->data_size)) { \
+-- 
+2.8.1
+
+
+From 858d2740f460140e3f2d909b1ee6eca4912ba2f4 Mon Sep 17 00:00:00 2001
+From: Andrew Tridgell <tridge at samba.org>
+Date: Wed, 7 Sep 2011 15:34:20 +1000
+Subject: [PATCH 10/40] libndr: add checking to all pull/push functions of base
+ types
+
+this checks that the passed in ndr_flags are valid
+
+Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>
+---
+ librpc/ndr/ndr_basic.c | 34 ++++++++++++++++++++++++++++++++++
+ 1 file changed, 34 insertions(+)
+
+diff --git a/librpc/ndr/ndr_basic.c b/librpc/ndr/ndr_basic.c
+index c7a2c11..2ce2dc3 100644
+--- a/librpc/ndr/ndr_basic.c
++++ b/librpc/ndr/ndr_basic.c
+@@ -61,6 +61,7 @@ _PUBLIC_ void ndr_check_padding(struct ndr_pull *ndr, size_t n)
+ */
+ _PUBLIC_ enum ndr_err_code ndr_pull_int8(struct ndr_pull *ndr, int ndr_flags, int8_t *v)
+ {
++	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
+ 	NDR_PULL_NEED_BYTES(ndr, 1);
+ 	*v = (int8_t)CVAL(ndr->data, ndr->offset);
+ 	ndr->offset += 1;
+@@ -72,6 +73,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_int8(struct ndr_pull *ndr, int ndr_flags, in
+ */
+ _PUBLIC_ enum ndr_err_code ndr_pull_uint8(struct ndr_pull *ndr, int ndr_flags, uint8_t *v)
+ {
++	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
+ 	NDR_PULL_NEED_BYTES(ndr, 1);
+ 	*v = CVAL(ndr->data, ndr->offset);
+ 	ndr->offset += 1;
+@@ -83,6 +85,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_uint8(struct ndr_pull *ndr, int ndr_flags, u
+ */
+ _PUBLIC_ enum ndr_err_code ndr_pull_int16(struct ndr_pull *ndr, int ndr_flags, int16_t *v)
+ {
++	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
+ 	NDR_PULL_ALIGN(ndr, 2);
+ 	NDR_PULL_NEED_BYTES(ndr, 2);
+ 	*v = (uint16_t)NDR_SVAL(ndr, ndr->offset);
+@@ -95,6 +98,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_int16(struct ndr_pull *ndr, int ndr_flags, i
+ */
+ _PUBLIC_ enum ndr_err_code ndr_pull_uint16(struct ndr_pull *ndr, int ndr_flags, uint16_t *v)
+ {
++	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
+ 	NDR_PULL_ALIGN(ndr, 2);
+ 	NDR_PULL_NEED_BYTES(ndr, 2);
+ 	*v = NDR_SVAL(ndr, ndr->offset);
+@@ -107,6 +111,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_uint16(struct ndr_pull *ndr, int ndr_flags,
+ */
+ _PUBLIC_ enum ndr_err_code ndr_pull_uint1632(struct ndr_pull *ndr, int ndr_flags, uint16_t *v)
+ {
++	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
+ 	if (unlikely(ndr->flags & LIBNDR_FLAG_NDR64)) {
+ 		uint32_t v32 = 0;
+ 		enum ndr_err_code err = ndr_pull_uint32(ndr, ndr_flags, &v32);
+@@ -125,6 +130,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_uint1632(struct ndr_pull *ndr, int ndr_flags
+ */
+ _PUBLIC_ enum ndr_err_code ndr_pull_int32(struct ndr_pull *ndr, int ndr_flags, int32_t *v)
+ {
++	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
+ 	NDR_PULL_ALIGN(ndr, 4);
+ 	NDR_PULL_NEED_BYTES(ndr, 4);
+ 	*v = NDR_IVALS(ndr, ndr->offset);
+@@ -137,6 +143,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_int32(struct ndr_pull *ndr, int ndr_flags, i
+ */
+ _PUBLIC_ enum ndr_err_code ndr_pull_uint32(struct ndr_pull *ndr, int ndr_flags, uint32_t *v)
+ {
++	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
+ 	NDR_PULL_ALIGN(ndr, 4);
+ 	NDR_PULL_NEED_BYTES(ndr, 4);
+ 	*v = NDR_IVAL(ndr, ndr->offset);
+@@ -151,6 +158,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_uint3264(struct ndr_pull *ndr, int ndr_flags
+ {
+ 	uint64_t v64;
+ 	enum ndr_err_code err;
++	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
+ 	if (likely(!(ndr->flags & LIBNDR_FLAG_NDR64))) {
+ 		return ndr_pull_uint32(ndr, ndr_flags, v);
+ 	}
+@@ -169,6 +177,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_uint3264(struct ndr_pull *ndr, int ndr_flags
+ */
+ _PUBLIC_ enum ndr_err_code ndr_pull_double(struct ndr_pull *ndr, int ndr_flags, double *v)
+ {
++	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
+ 	NDR_PULL_ALIGN(ndr, 8);
+ 	NDR_PULL_NEED_BYTES(ndr, 8);
+ 	memcpy(v, ndr->data+ndr->offset, 8);
+@@ -217,6 +226,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_ref_ptr(struct ndr_pull *ndr, uint32_t *v)
+ */
+ _PUBLIC_ enum ndr_err_code ndr_pull_udlong(struct ndr_pull *ndr, int ndr_flags, uint64_t *v)
+ {
++	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
+ 	NDR_PULL_ALIGN(ndr, 4);
+ 	NDR_PULL_NEED_BYTES(ndr, 8);
+ 	*v = NDR_IVAL(ndr, ndr->offset);
+@@ -230,6 +240,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_udlong(struct ndr_pull *ndr, int ndr_flags,
+ */
+ _PUBLIC_ enum ndr_err_code ndr_pull_udlongr(struct ndr_pull *ndr, int ndr_flags, uint64_t *v)
+ {
++	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
+ 	NDR_PULL_ALIGN(ndr, 4);
+ 	NDR_PULL_NEED_BYTES(ndr, 8);
+ 	*v = ((uint64_t)NDR_IVAL(ndr, ndr->offset)) << 32;
+@@ -264,6 +275,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_hyper(struct ndr_pull *ndr, int ndr_flags, u
+ _PUBLIC_ enum ndr_err_code ndr_pull_pointer(struct ndr_pull *ndr, int ndr_flags, void* *v)
+ {
+ 	uintptr_t h;
++	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
+ 	NDR_PULL_ALIGN(ndr, sizeof(h));
+ 	NDR_PULL_NEED_BYTES(ndr, sizeof(h));
+ 	memcpy(&h, ndr->data+ndr->offset, sizeof(h));
+@@ -278,6 +290,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_pointer(struct ndr_pull *ndr, int ndr_flags,
+ _PUBLIC_ enum ndr_err_code ndr_pull_NTSTATUS(struct ndr_pull *ndr, int ndr_flags, NTSTATUS *status)
+ {
+ 	uint32_t v;
++	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
+ 	NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v));
+ 	*status = NT_STATUS(v);
+ 	return NDR_ERR_SUCCESS;
+@@ -302,6 +315,7 @@ _PUBLIC_ void ndr_print_NTSTATUS(struct ndr_print *ndr, const char *name, NTSTAT
+ _PUBLIC_ enum ndr_err_code ndr_pull_WERROR(struct ndr_pull *ndr, int ndr_flags, WERROR *status)
+ {
+ 	uint32_t v;
++	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
+ 	NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v));
+ 	*status = W_ERROR(v);
+ 	return NDR_ERR_SUCCESS;
+@@ -414,6 +428,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_bytes(struct ndr_pull *ndr, uint8_t *data, u
+ */
+ _PUBLIC_ enum ndr_err_code ndr_pull_array_uint8(struct ndr_pull *ndr, int ndr_flags, uint8_t *data, uint32_t n)
+ {
++	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
+ 	if (!(ndr_flags & NDR_SCALARS)) {
+ 		return NDR_ERR_SUCCESS;
+ 	}
+@@ -425,6 +440,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_array_uint8(struct ndr_pull *ndr, int ndr_fl
+ */
+ _PUBLIC_ enum ndr_err_code ndr_push_int8(struct ndr_push *ndr, int ndr_flags, int8_t v)
+ {
++	NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
+ 	NDR_PUSH_NEED_BYTES(ndr, 1);
+ 	SCVAL(ndr->data, ndr->offset, (uint8_t)v);
+ 	ndr->offset += 1;
+@@ -436,6 +452,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_int8(struct ndr_push *ndr, int ndr_flags, in
+ */
+ _PUBLIC_ enum ndr_err_code ndr_push_uint8(struct ndr_push *ndr, int ndr_flags, uint8_t v)
+ {
++	NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
+ 	NDR_PUSH_NEED_BYTES(ndr, 1);
+ 	SCVAL(ndr->data, ndr->offset, v);
+ 	ndr->offset += 1;
+@@ -447,6 +464,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_uint8(struct ndr_push *ndr, int ndr_flags, u
+ */
+ _PUBLIC_ enum ndr_err_code ndr_push_int16(struct ndr_push *ndr, int ndr_flags, int16_t v)
+ {
++	NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
+ 	NDR_PUSH_ALIGN(ndr, 2);
+ 	NDR_PUSH_NEED_BYTES(ndr, 2);
+ 	NDR_SSVAL(ndr, ndr->offset, (uint16_t)v);
+@@ -459,6 +477,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_int16(struct ndr_push *ndr, int ndr_flags, i
+ */
+ _PUBLIC_ enum ndr_err_code ndr_push_uint16(struct ndr_push *ndr, int ndr_flags, uint16_t v)
+ {
++	NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
+ 	NDR_PUSH_ALIGN(ndr, 2);
+ 	NDR_PUSH_NEED_BYTES(ndr, 2);
+ 	NDR_SSVAL(ndr, ndr->offset, v);
+@@ -482,6 +501,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_uint1632(struct ndr_push *ndr, int ndr_flags
+ */
+ _PUBLIC_ enum ndr_err_code ndr_push_int32(struct ndr_push *ndr, int ndr_flags, int32_t v)
+ {
++	NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
+ 	NDR_PUSH_ALIGN(ndr, 4);
+ 	NDR_PUSH_NEED_BYTES(ndr, 4);
+ 	NDR_SIVALS(ndr, ndr->offset, v);
+@@ -494,6 +514,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_int32(struct ndr_push *ndr, int ndr_flags, i
+ */
+ _PUBLIC_ enum ndr_err_code ndr_push_uint32(struct ndr_push *ndr, int ndr_flags, uint32_t v)
+ {
++	NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
+ 	NDR_PUSH_ALIGN(ndr, 4);
+ 	NDR_PUSH_NEED_BYTES(ndr, 4);
+ 	NDR_SIVAL(ndr, ndr->offset, v);
+@@ -517,6 +538,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_uint3264(struct ndr_push *ndr, int ndr_flags
+ */
+ _PUBLIC_ enum ndr_err_code ndr_push_udlong(struct ndr_push *ndr, int ndr_flags, uint64_t v)
+ {
++	NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
+ 	NDR_PUSH_ALIGN(ndr, 4);
+ 	NDR_PUSH_NEED_BYTES(ndr, 8);
+ 	NDR_SIVAL(ndr, ndr->offset, (v & 0xFFFFFFFF));
+@@ -530,6 +552,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_udlong(struct ndr_push *ndr, int ndr_flags,
+ */
+ _PUBLIC_ enum ndr_err_code ndr_push_udlongr(struct ndr_push *ndr, int ndr_flags, uint64_t v)
+ {
++	NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
+ 	NDR_PUSH_ALIGN(ndr, 4);
+ 	NDR_PUSH_NEED_BYTES(ndr, 8);
+ 	NDR_SIVAL(ndr, ndr->offset, (v>>32));
+@@ -563,6 +586,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_hyper(struct ndr_push *ndr, int ndr_flags, u
+ */
+ _PUBLIC_ enum ndr_err_code ndr_push_double(struct ndr_push *ndr, int ndr_flags, double v)
+ {
++	NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
+ 	NDR_PUSH_ALIGN(ndr, 8);
+ 	NDR_PUSH_NEED_BYTES(ndr, 8);
+ 	memcpy(ndr->data+ndr->offset, &v, 8);
+@@ -576,6 +600,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_double(struct ndr_push *ndr, int ndr_flags,
+ _PUBLIC_ enum ndr_err_code ndr_push_pointer(struct ndr_push *ndr, int ndr_flags, void* v)
+ {
+ 	uintptr_t h = (intptr_t)v;
++	NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
+ 	NDR_PUSH_ALIGN(ndr, sizeof(h));
+ 	NDR_PUSH_NEED_BYTES(ndr, sizeof(h));
+ 	memcpy(ndr->data+ndr->offset, &h, sizeof(h));
+@@ -686,6 +711,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_zero(struct ndr_push *ndr, uint32_t n)
+ */
+ _PUBLIC_ enum ndr_err_code ndr_push_array_uint8(struct ndr_push *ndr, int ndr_flags, const uint8_t *data, uint32_t n)
+ {
++	NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
+ 	if (!(ndr_flags & NDR_SCALARS)) {
+ 		return NDR_ERR_SUCCESS;
+ 	}
+@@ -738,6 +764,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_ref_ptr(struct ndr_push *ndr)
+ */
+ _PUBLIC_ enum ndr_err_code ndr_push_NTTIME(struct ndr_push *ndr, int ndr_flags, NTTIME t)
+ {
++	NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
+ 	NDR_CHECK(ndr_push_udlong(ndr, ndr_flags, t));
+ 	return NDR_ERR_SUCCESS;
+ }
+@@ -747,6 +774,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_NTTIME(struct ndr_push *ndr, int ndr_flags,
+ */
+ _PUBLIC_ enum ndr_err_code ndr_pull_NTTIME(struct ndr_pull *ndr, int ndr_flags, NTTIME *t)
+ {
++	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
+ 	NDR_CHECK(ndr_pull_udlong(ndr, ndr_flags, t));
+ 	return NDR_ERR_SUCCESS;
+ }
+@@ -756,6 +784,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_NTTIME(struct ndr_pull *ndr, int ndr_flags,
+ */
+ _PUBLIC_ enum ndr_err_code ndr_push_NTTIME_1sec(struct ndr_push *ndr, int ndr_flags, NTTIME t)
+ {
++	NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
+ 	t /= 10000000;
+ 	NDR_CHECK(ndr_push_hyper(ndr, ndr_flags, t));
+ 	return NDR_ERR_SUCCESS;
+@@ -766,6 +795,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_NTTIME_1sec(struct ndr_push *ndr, int ndr_fl
+ */
+ _PUBLIC_ enum ndr_err_code ndr_pull_NTTIME_1sec(struct ndr_pull *ndr, int ndr_flags, NTTIME *t)
+ {
++	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
+ 	NDR_CHECK(ndr_pull_hyper(ndr, ndr_flags, t));
+ 	(*t) *= 10000000;
+ 	return NDR_ERR_SUCCESS;
+@@ -776,6 +806,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_NTTIME_1sec(struct ndr_pull *ndr, int ndr_fl
+ */
+ _PUBLIC_ enum ndr_err_code ndr_pull_NTTIME_hyper(struct ndr_pull *ndr, int ndr_flags, NTTIME *t)
+ {
++	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
+ 	NDR_CHECK(ndr_pull_hyper(ndr, ndr_flags, t));
+ 	return NDR_ERR_SUCCESS;
+ }
+@@ -785,6 +816,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_NTTIME_hyper(struct ndr_pull *ndr, int ndr_f
+ */
+ _PUBLIC_ enum ndr_err_code ndr_push_NTTIME_hyper(struct ndr_push *ndr, int ndr_flags, NTTIME t)
+ {
++	NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
+ 	NDR_CHECK(ndr_push_hyper(ndr, ndr_flags, t));
+ 	return NDR_ERR_SUCCESS;
+ }
+@@ -814,6 +846,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_time_t(struct ndr_pull *ndr, int ndr_flags,
+ */
+ _PUBLIC_ enum ndr_err_code ndr_push_uid_t(struct ndr_push *ndr, int ndr_flags, uid_t u)
+ {
++	NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
+ 	return ndr_push_hyper(ndr, NDR_SCALARS, (uint64_t)u);
+ }
+ 
+@@ -839,6 +872,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_uid_t(struct ndr_pull *ndr, int ndr_flags, u
+ */
+ _PUBLIC_ enum ndr_err_code ndr_push_gid_t(struct ndr_push *ndr, int ndr_flags, gid_t g)
+ {
++	NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
+ 	return ndr_push_hyper(ndr, NDR_SCALARS, (uint64_t)g);
+ }
+ 
+-- 
+2.8.1
+
+
+From 59461493d5e0fedaadad73d66afe06c606ac6155 Mon Sep 17 00:00:00 2001
+From: Andrew Bartlett <abartlet at samba.org>
+Date: Thu, 7 Jul 2011 21:04:31 +1000
+Subject: [PATCH 11/40] lib/util Move bitmap.c to lib/util
+
+---
+ {source3/lib => lib/util}/bitmap.c | 21 +++++++++++----------
+ lib/util/bitmap.h                  | 32 ++++++++++++++++++++++++++++++++
+ lib/util/wscript_build             |  8 +++++++-
+ source3/Makefile.in                |  2 +-
+ source3/include/proto.h            |  9 ---------
+ source3/include/smb.h              |  6 ------
+ source3/modules/vfs_acl_common.c   |  1 +
+ source3/modules/vfs_full_audit.c   |  1 +
+ source3/param/loadparm.c           |  1 +
+ source3/passdb/pdb_get_set.c       |  1 +
+ source3/smbd/conn.c                |  1 +
+ source3/smbd/dir.c                 |  1 +
+ source3/smbd/files.c               |  1 +
+ source3/smbd/smb2_server.c         |  1 +
+ 14 files changed, 59 insertions(+), 27 deletions(-)
+ rename {source3/lib => lib/util}/bitmap.c (91%)
+ create mode 100644 lib/util/bitmap.h
+
+diff --git a/source3/lib/bitmap.c b/lib/util/bitmap.c
+similarity index 91%
+rename from source3/lib/bitmap.c
+rename to lib/util/bitmap.c
+index bd56b4a..4748f8b 100644
+--- a/source3/lib/bitmap.c
++++ b/lib/util/bitmap.c
+@@ -18,6 +18,7 @@
+ */
+ 
+ #include "includes.h"
++#include "lib/util/bitmap.h"
+ 
+ /* these functions provide a simple way to allocate integers from a
+    pool without repetition */
+@@ -29,12 +30,12 @@ struct bitmap *bitmap_talloc(TALLOC_CTX *mem_ctx, int n)
+ {
+ 	struct bitmap *bm;
+ 
+-	bm = TALLOC_P(mem_ctx, struct bitmap);
++	bm = talloc_zero(mem_ctx, struct bitmap);
+ 
+ 	if (!bm) return NULL;
+ 
+ 	bm->n = n;
+-	bm->b = TALLOC_ZERO_ARRAY(bm, uint32, (n+31)/32);
++	bm->b = talloc_zero_array(bm, uint32_t, (n+31)/32);
+ 	if (!bm->b) {
+ 		TALLOC_FREE(bm);
+ 		return NULL;
+@@ -51,7 +52,7 @@ int bitmap_copy(struct bitmap * const dst, const struct bitmap * const src)
+         int count = MIN(dst->n, src->n);
+ 
+         SMB_ASSERT(dst->b != src->b);
+-	memcpy(dst->b, src->b, sizeof(uint32)*((count+31)/32));
++	memcpy(dst->b, src->b, sizeof(uint32_t)*((count+31)/32));
+ 
+         return count;
+ }
+@@ -64,10 +65,10 @@ bool bitmap_set(struct bitmap *bm, unsigned i)
+ 	if (i >= bm->n) {
+ 		DEBUG(0,("Setting invalid bitmap entry %d (of %d)\n",
+ 		      i, bm->n));
+-		return False;
++		return false;
+ 	}
+ 	bm->b[i/32] |= (1<<(i%32));
+-	return True;
++	return true;
+ }
+ 
+ /****************************************************************************
+@@ -78,10 +79,10 @@ bool bitmap_clear(struct bitmap *bm, unsigned i)
+ 	if (i >= bm->n) {
+ 		DEBUG(0,("clearing invalid bitmap entry %d (of %d)\n",
+ 		      i, bm->n));
+-		return False;
++		return false;
+ 	}
+ 	bm->b[i/32] &= ~(1<<(i%32));
+-	return True;
++	return true;
+ }
+ 
+ /****************************************************************************
+@@ -89,11 +90,11 @@ query a bit in a bitmap
+ ****************************************************************************/
+ bool bitmap_query(struct bitmap *bm, unsigned i)
+ {
+-	if (i >= bm->n) return False;
++	if (i >= bm->n) return false;
+ 	if (bm->b[i/32] & (1<<(i%32))) {
+-		return True;
++		return true;
+ 	}
+-	return False;
++	return false;
+ }
+ 
+ /****************************************************************************
+diff --git a/lib/util/bitmap.h b/lib/util/bitmap.h
+new file mode 100644
+index 0000000..cf7aa1b
+--- /dev/null
++++ b/lib/util/bitmap.h
+@@ -0,0 +1,32 @@
++/*
++   Unix SMB/CIFS implementation.
++   simple bitmap functions
++   Copyright (C) Andrew Tridgell 1992-1998
++
++   This program is free software; you can redistribute it and/or modify
++   it under the terms of the GNU General Public License as published by
++   the Free Software Foundation; either version 3 of the License, or
++   (at your option) any later version.
++
++   This program is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU General Public License for more details.
++
++   You should have received a copy of the GNU General Public License
++   along with this program.  If not, see <http://www.gnu.org/licenses/>.
++*/
++
++/* The following definitions come from lib/bitmap.c  */
++
++struct bitmap {
++	uint32_t *b;
++	unsigned int n;
++};
++
++struct bitmap *bitmap_talloc(TALLOC_CTX *mem_ctx, int n);
++int bitmap_copy(struct bitmap * const dst, const struct bitmap * const src);
++bool bitmap_set(struct bitmap *bm, unsigned i);
++bool bitmap_clear(struct bitmap *bm, unsigned i);
++bool bitmap_query(struct bitmap *bm, unsigned i);
++int bitmap_find(struct bitmap *bm, unsigned ofs);
+diff --git a/lib/util/wscript_build b/lib/util/wscript_build
+index b68791f..7e96946 100755
+--- a/lib/util/wscript_build
++++ b/lib/util/wscript_build
+@@ -99,5 +99,11 @@ bld.SAMBA_LIBRARY('tdb-wrap',
+                   public_headers='tdb_wrap.h',
+                   private_library=True,
+                   local_include=False
+-                  )
++                 )
++
++bld.SAMBA_LIBRARY('bitmap',
++		  source='bitmap.c',
++		  deps='talloc samba-util',
++                  local_include=False,
++		  private_library=True)
+ 
+diff --git a/source3/Makefile.in b/source3/Makefile.in
+index 4f9cbb4..d39cfee 100644
+--- a/source3/Makefile.in
++++ b/source3/Makefile.in
+@@ -455,7 +455,7 @@ LIB_OBJ = $(LIBSAMBAUTIL_OBJ) $(UTIL_OBJ) $(CRYPTO_OBJ) \
+ 	  lib/username.o \
+ 	  ../libds/common/flag_mapping.o \
+ 	  lib/access.o lib/smbrun.o \
+-	  lib/bitmap.o lib/dprintf.o $(UTIL_REG_OBJ) \
++	  ../lib/util/bitmap.o lib/dprintf.o $(UTIL_REG_OBJ) \
+ 	  lib/wins_srv.o \
+ 	  lib/util_str.o lib/clobber.o lib/util_sid.o \
+ 	  lib/util_unistr.o ../lib/util/charset/codepoints.o lib/util_file.o \
+diff --git a/source3/include/proto.h b/source3/include/proto.h
+index 7303e76..8491d54 100644
+--- a/source3/include/proto.h
++++ b/source3/include/proto.h
+@@ -61,15 +61,6 @@ const char *audit_description_str(uint32 category);
+ bool get_audit_category_from_param(const char *param, uint32 *audit_category);
+ const char *audit_policy_str(TALLOC_CTX *mem_ctx, uint32 policy);
+ 
+-/* The following definitions come from lib/bitmap.c  */
+-
+-struct bitmap *bitmap_talloc(TALLOC_CTX *mem_ctx, int n);
+-int bitmap_copy(struct bitmap * const dst, const struct bitmap * const src);
+-bool bitmap_set(struct bitmap *bm, unsigned i);
+-bool bitmap_clear(struct bitmap *bm, unsigned i);
+-bool bitmap_query(struct bitmap *bm, unsigned i);
+-int bitmap_find(struct bitmap *bm, unsigned ofs);
+-
+ /* The following definitions come from lib/charcnv.c  */
+ 
+ char lp_failed_convert_char(void);
+diff --git a/source3/include/smb.h b/source3/include/smb.h
+index 2d04373..457d2d7 100644
+--- a/source3/include/smb.h
++++ b/source3/include/smb.h
+@@ -712,7 +712,6 @@ struct connections_data {
+ 	uint32 unused_compatitibility_field;
+ };
+ 
+-
+ /* the following are used by loadparm for option lists */
+ typedef enum {
+ 	P_BOOL,P_BOOLREV,P_CHAR,P_INTEGER,P_OCTAL,P_LIST,
+@@ -759,11 +758,6 @@ struct parm_struct {
+ #define FLAG_META	0x8000 /* A meta directive - not a real parameter */
+ #define FLAG_CMDLINE	0x10000 /* option has been overridden */
+ 
+-struct bitmap {
+-	uint32 *b;
+-	unsigned int n;
+-};
+-
+ /* offsets into message for common items */
+ #define smb_com 8
+ #define smb_rcls 9
+diff --git a/source3/modules/vfs_acl_common.c b/source3/modules/vfs_acl_common.c
+index 11c34e0..ac641d5 100644
+--- a/source3/modules/vfs_acl_common.c
++++ b/source3/modules/vfs_acl_common.c
+@@ -23,6 +23,7 @@
+ #include "system/filesys.h"
+ #include "../libcli/security/security.h"
+ #include "../librpc/gen_ndr/ndr_security.h"
++#include "../lib/util/bitmap.h"
+ 
+ static NTSTATUS create_acl_blob(const struct security_descriptor *psd,
+ 			DATA_BLOB *pblob,
+diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c
+index 17713f0..ea3c139 100644
+--- a/source3/modules/vfs_full_audit.c
++++ b/source3/modules/vfs_full_audit.c
+@@ -64,6 +64,7 @@
+ #include "../librpc/gen_ndr/ndr_netlogon.h"
+ #include "auth.h"
+ #include "ntioctl.h"
++#include "lib/util/bitmap.h"
+ 
+ static int vfs_full_audit_debug_level = DBGC_VFS;
+ 
+diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
+index dd63339..753252a 100644
+--- a/source3/param/loadparm.c
++++ b/source3/param/loadparm.c
+@@ -64,6 +64,7 @@
+ #include "smb_signing.h"
+ #include "dbwrap.h"
+ #include "smbldap.h"
++#include "../lib/util/bitmap.h"
+ 
+ #ifdef HAVE_SYS_SYSCTL_H
+ #include <sys/sysctl.h>
+diff --git a/source3/passdb/pdb_get_set.c b/source3/passdb/pdb_get_set.c
+index a276c16..63082e3 100644
+--- a/source3/passdb/pdb_get_set.c
++++ b/source3/passdb/pdb_get_set.c
+@@ -25,6 +25,7 @@
+ #include "passdb.h"
+ #include "../libcli/auth/libcli_auth.h"
+ #include "../libcli/security/security.h"
++#include "../lib/util/bitmap.h"
+ 
+ #undef DBGC_CLASS
+ #define DBGC_CLASS DBGC_PASSDB
+diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c
+index 05e692f..2de3644 100644
+--- a/source3/smbd/conn.c
++++ b/source3/smbd/conn.c
+@@ -23,6 +23,7 @@
+ #include "smbd/smbd.h"
+ #include "smbd/globals.h"
+ #include "rpc_server/rpc_ncacn_np.h"
++#include "lib/util/bitmap.h"
+ 
+ /* The connections bitmap is expanded in increments of BITMAP_BLOCK_SZ. The
+  * maximum size of the bitmap is the largest positive integer, but you will hit
+diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c
+index e6c8106..18ecf06 100644
+--- a/source3/smbd/dir.c
++++ b/source3/smbd/dir.c
+@@ -23,6 +23,7 @@
+ #include "smbd/smbd.h"
+ #include "smbd/globals.h"
+ #include "libcli/security/security.h"
++#include "lib/util/bitmap.h"
+ 
+ /*
+    This module implements directory related functions for Samba.
+diff --git a/source3/smbd/files.c b/source3/smbd/files.c
+index 58c24a8..cef391d 100644
+--- a/source3/smbd/files.c
++++ b/source3/smbd/files.c
+@@ -22,6 +22,7 @@
+ #include "smbd/globals.h"
+ #include "libcli/security/security.h"
+ #include "util_tdb.h"
++#include "lib/util/bitmap.h"
+ 
+ #define VALID_FNUM(fnum)   (((fnum) >= 0) && ((fnum) < real_max_open_files))
+ 
+diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
+index 9615907..cf786db 100644
+--- a/source3/smbd/smb2_server.c
++++ b/source3/smbd/smb2_server.c
+@@ -26,6 +26,7 @@
+ #include "../lib/tsocket/tsocket.h"
+ #include "../lib/util/tevent_ntstatus.h"
+ #include "smbprofile.h"
++#include "../lib/util/bitmap.h"
+ 
+ #define OUTVEC_ALLOC_SIZE (SMB2_HDR_BODY + 9)
+ 
+-- 
+2.8.1
+
+
+From 58191de16e3ce49723361049857a62a07b75c2d3 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Sun, 5 Jan 2014 07:57:51 +0100
+Subject: [PATCH 12/40] s3:rpc_client: fill alloc_hint with the remaining data
+ not the total data.
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Andrew Bartlett <abartlet at samba.org>
+(cherry picked from commit f0532fe0cd69aeb161088ca990d376f119102e61)
+---
+ source3/rpc_client/cli_pipe.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c
+index 9636479..7d78772 100644
+--- a/source3/rpc_client/cli_pipe.c
++++ b/source3/rpc_client/cli_pipe.c
+@@ -1380,7 +1380,7 @@ static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
+ 
+ 	ZERO_STRUCT(u.request);
+ 
+-	u.request.alloc_hint	= state->req_data->length;
++	u.request.alloc_hint	= data_left;
+ 	u.request.context_id	= 0;
+ 	u.request.opnum		= state->op_num;
+ 
+-- 
+2.8.1
+
+
+From dadd2b521440a3d03038034c3dbb1f78045241c0 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Sun, 5 Jan 2014 08:12:45 +0100
+Subject: [PATCH 13/40] s3:rpc_client: send a dcerpc_sec_verification_trailer
+ if needed
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Andrew Bartlett <abartlet at samba.org>
+
+Autobuild-User(master): Stefan Metzmacher <metze at samba.org>
+Autobuild-Date(master): Tue Jan  7 02:24:42 CET 2014 on sn-devel-104
+
+(cherry picked from commit 6ab9164c74e0ad57bdde8abb568953026b644e27)
+---
+ source3/librpc/rpc/dcerpc.h     |   1 +
+ source3/rpc_client/cli_pipe.c   | 199 ++++++++++++++++++++++++++++++++++++++--
+ source3/rpc_client/rpc_client.h |   1 +
+ 3 files changed, 191 insertions(+), 10 deletions(-)
+
+diff --git a/source3/librpc/rpc/dcerpc.h b/source3/librpc/rpc/dcerpc.h
+index d7e8e0c..d14d8e0 100644
+--- a/source3/librpc/rpc/dcerpc.h
++++ b/source3/librpc/rpc/dcerpc.h
+@@ -39,6 +39,7 @@ struct NL_AUTH_MESSAGE;
+ struct pipe_auth_data {
+ 	enum dcerpc_AuthType auth_type;
+ 	enum dcerpc_AuthLevel auth_level;
++	bool verified_bitmask1;
+ 
+ 	void *auth_ctx;
+ 
+diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c
+index 7d78772..5bf4549 100644
+--- a/source3/rpc_client/cli_pipe.c
++++ b/source3/rpc_client/cli_pipe.c
+@@ -1269,12 +1269,17 @@ struct rpc_api_pipe_req_state {
+ 	uint32_t call_id;
+ 	DATA_BLOB *req_data;
+ 	uint32_t req_data_sent;
++	DATA_BLOB req_trailer;
++	uint32_t req_trailer_sent;
++	bool verify_bitmask1;
++	bool verify_pcontext;
+ 	DATA_BLOB rpc_out;
+ 	DATA_BLOB reply_pdu;
+ };
+ 
+ static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
+ static void rpc_api_pipe_req_done(struct tevent_req *subreq);
++static NTSTATUS prepare_verification_trailer(struct rpc_api_pipe_req_state *state);
+ static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
+ 				  bool *is_last_frag);
+ 
+@@ -1310,6 +1315,11 @@ struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
+ 		goto post_status;
+ 	}
+ 
++	status = prepare_verification_trailer(state);
++	if (!NT_STATUS_IS_OK(status)) {
++		goto post_status;
++	}
++
+ 	status = prepare_next_frag(state, &is_last_frag);
+ 	if (!NT_STATUS_IS_OK(status)) {
+ 		goto post_status;
+@@ -1344,25 +1354,161 @@ struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
+ 	return NULL;
+ }
+ 
++static NTSTATUS prepare_verification_trailer(struct rpc_api_pipe_req_state *state)
++{
++	struct pipe_auth_data *a = state->cli->auth;
++	struct dcerpc_sec_verification_trailer *t;
++	struct dcerpc_sec_vt *c = NULL;
++	struct ndr_push *ndr = NULL;
++	enum ndr_err_code ndr_err;
++	size_t align = 0;
++	size_t pad = 0;
++
++	if (a == NULL) {
++		return NT_STATUS_OK;
++	}
++
++	if (a->auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) {
++		return NT_STATUS_OK;
++	}
++
++	t = talloc_zero(state, struct dcerpc_sec_verification_trailer);
++	if (t == NULL) {
++		return NT_STATUS_NO_MEMORY;
++	}
++
++	if (!a->verified_bitmask1) {
++		t->commands = talloc_realloc(t, t->commands,
++					     struct dcerpc_sec_vt,
++					     t->count.count + 1);
++		if (t->commands == NULL) {
++			return NT_STATUS_NO_MEMORY;
++		}
++		c = &t->commands[t->count.count++];
++		ZERO_STRUCTP(c);
++
++		c->command = DCERPC_SEC_VT_COMMAND_BITMASK1;
++		state->verify_bitmask1 = true;
++	}
++
++	if (!state->cli->verified_pcontext) {
++		t->commands = talloc_realloc(t, t->commands,
++					     struct dcerpc_sec_vt,
++					     t->count.count + 1);
++		if (t->commands == NULL) {
++			return NT_STATUS_NO_MEMORY;
++		}
++		c = &t->commands[t->count.count++];
++		ZERO_STRUCTP(c);
++
++		c->command = DCERPC_SEC_VT_COMMAND_PCONTEXT;
++		c->u.pcontext.abstract_syntax = state->cli->abstract_syntax;
++		c->u.pcontext.transfer_syntax = state->cli->transfer_syntax;
++
++		state->verify_pcontext = true;
++	}
++
++	if (true) { /* We do not support header signing */
++		t->commands = talloc_realloc(t, t->commands,
++					     struct dcerpc_sec_vt,
++					     t->count.count + 1);
++		if (t->commands == NULL) {
++			return NT_STATUS_NO_MEMORY;
++		}
++		c = &t->commands[t->count.count++];
++		ZERO_STRUCTP(c);
++
++		c->command = DCERPC_SEC_VT_COMMAND_HEADER2;
++		c->u.header2.ptype = DCERPC_PKT_REQUEST;
++		c->u.header2.drep[0] = DCERPC_DREP_LE;
++		c->u.header2.drep[1] = 0;
++		c->u.header2.drep[2] = 0;
++		c->u.header2.drep[3] = 0;
++		c->u.header2.call_id = state->call_id;
++		c->u.header2.context_id = 0;
++		c->u.header2.opnum = state->op_num;
++	}
++
++	if (t->count.count == 0) {
++		TALLOC_FREE(t);
++		return NT_STATUS_OK;
++	}
++
++	c = &t->commands[t->count.count - 1];
++	c->command |= DCERPC_SEC_VT_COMMAND_END;
++
++	if (DEBUGLEVEL >= 10) {
++		NDR_PRINT_DEBUG(dcerpc_sec_verification_trailer, t);
++	}
++
++	ndr = ndr_push_init_ctx(state);
++	if (ndr == NULL) {
++		return NT_STATUS_NO_MEMORY;
++	}
++
++	ndr_err = ndr_push_dcerpc_sec_verification_trailer(ndr,
++						NDR_SCALARS | NDR_BUFFERS,
++						t);
++	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
++		return ndr_map_error2ntstatus(ndr_err);
++	}
++	state->req_trailer = ndr_push_blob(ndr);
++
++	align = state->req_data->length & 0x3;
++	if (align > 0) {
++		pad = 4 - align;
++	}
++	if (pad > 0) {
++		bool ok;
++		uint8_t *p;
++		const uint8_t zeros[4] = { 0, };
++
++		ok = data_blob_append(ndr, &state->req_trailer, zeros, pad);
++		if (!ok) {
++			return NT_STATUS_NO_MEMORY;
++		}
++
++		/* move the padding to the start */
++		p = state->req_trailer.data;
++		memmove(p + pad, p, state->req_trailer.length - pad);
++		memset(p, 0, pad);
++	}
++
++	return NT_STATUS_OK;
++}
++
+ static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
+ 				  bool *is_last_frag)
+ {
+-	size_t data_sent_thistime;
+ 	size_t auth_len;
+ 	size_t frag_len;
+ 	uint8_t flags = 0;
+ 	size_t pad_len;
+ 	size_t data_left;
++	size_t data_thistime;
++	size_t trailer_left;
++	size_t trailer_thistime = 0;
++	size_t total_left;
++	size_t total_thistime;
+ 	NTSTATUS status;
++	bool ok;
+ 	union dcerpc_payload u;
+ 
+ 	data_left = state->req_data->length - state->req_data_sent;
++	trailer_left = state->req_trailer.length - state->req_trailer_sent;
++	total_left = data_left + trailer_left;
++	if ((total_left < data_left) || (total_left < trailer_left)) {
++		/*
++		 * overflow
++		 */
++		return NT_STATUS_INVALID_PARAMETER_MIX;
++	}
+ 
+ 	status = dcerpc_guess_sizes(state->cli->auth,
+-				    DCERPC_REQUEST_LENGTH, data_left,
++				    DCERPC_REQUEST_LENGTH, total_left,
+ 				    state->cli->max_xmit_frag,
+ 				    CLIENT_NDR_PADDING_SIZE,
+-				    &data_sent_thistime,
++				    &total_thistime,
+ 				    &frag_len, &auth_len, &pad_len);
+ 	if (!NT_STATUS_IS_OK(status)) {
+ 		return status;
+@@ -1372,15 +1518,20 @@ static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
+ 		flags = DCERPC_PFC_FLAG_FIRST;
+ 	}
+ 
+-	if (data_sent_thistime == data_left) {
++	if (total_thistime == total_left) {
+ 		flags |= DCERPC_PFC_FLAG_LAST;
+ 	}
+ 
++	data_thistime = MIN(total_thistime, data_left);
++	if (data_thistime < total_thistime) {
++		trailer_thistime = total_thistime - data_thistime;
++	}
++
+ 	data_blob_free(&state->rpc_out);
+ 
+ 	ZERO_STRUCT(u.request);
+ 
+-	u.request.alloc_hint	= data_left;
++	u.request.alloc_hint	= total_left;
+ 	u.request.context_id	= 0;
+ 	u.request.opnum		= state->op_num;
+ 
+@@ -1400,11 +1551,26 @@ static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
+ 	 * at this stage */
+ 	dcerpc_set_frag_length(&state->rpc_out, frag_len);
+ 
+-	/* Copy in the data. */
+-	if (!data_blob_append(NULL, &state->rpc_out,
++	if (data_thistime > 0) {
++		/* Copy in the data. */
++		ok = data_blob_append(NULL, &state->rpc_out,
+ 				state->req_data->data + state->req_data_sent,
+-				data_sent_thistime)) {
+-		return NT_STATUS_NO_MEMORY;
++				data_thistime);
++		if (!ok) {
++			return NT_STATUS_NO_MEMORY;
++		}
++		state->req_data_sent += data_thistime;
++	}
++
++	if (trailer_thistime > 0) {
++		/* Copy in the verification trailer. */
++		ok = data_blob_append(NULL, &state->rpc_out,
++				state->req_trailer.data + state->req_trailer_sent,
++				trailer_thistime);
++		if (!ok) {
++			return NT_STATUS_NO_MEMORY;
++		}
++		state->req_trailer_sent += trailer_thistime;
+ 	}
+ 
+ 	switch (state->cli->auth->auth_level) {
+@@ -1424,7 +1590,6 @@ static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
+ 		return NT_STATUS_INVALID_PARAMETER;
+ 	}
+ 
+-	state->req_data_sent += data_sent_thistime;
+ 	*is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
+ 
+ 	return status;
+@@ -1488,6 +1653,20 @@ static void rpc_api_pipe_req_done(struct tevent_req *subreq)
+ 		tevent_req_nterror(req, status);
+ 		return;
+ 	}
++
++	if (state->cli->auth == NULL) {
++		tevent_req_done(req);
++		return;
++	}
++
++	if (state->verify_bitmask1) {
++		state->cli->auth->verified_bitmask1 = true;
++	}
++
++	if (state->verify_pcontext) {
++		state->cli->verified_pcontext = true;
++	}
++
+ 	tevent_req_done(req);
+ }
+ 
+diff --git a/source3/rpc_client/rpc_client.h b/source3/rpc_client/rpc_client.h
+index 6561b28..8024f01 100644
+--- a/source3/rpc_client/rpc_client.h
++++ b/source3/rpc_client/rpc_client.h
+@@ -39,6 +39,7 @@ struct rpc_pipe_client {
+ 
+ 	struct ndr_syntax_id abstract_syntax;
+ 	struct ndr_syntax_id transfer_syntax;
++	bool verified_pcontext;
+ 
+ 	char *desthost;
+ 	char *srv_name_slash;
+-- 
+2.8.1
+
+
+From 572ce89e8653d07bf81681267ee38bd29abbc4b3 Mon Sep 17 00:00:00 2001
+From: Gregor Beck <gbeck at sernet.de>
+Date: Thu, 2 Jan 2014 15:30:52 +0100
+Subject: [PATCH 14/40] librpc/ndr: add
+ ndr_pop_dcerpc_sec_verification_trailer()
+
+This extracts the dcerpc_sec_verification_trailer from the end
+of an ndr_pull structure, it found it reduces ndr->data_size.
+
+NDR_ERR_ALLOC is the only possible error, all other errors
+are ignored and a trailer with command count = 0 is returned.
+
+Pair-Programmed-With: Gregor Beck <gbeck at sernet.de>
+
+Signed-off-by: Gregor Beck <gbeck at sernet.de>
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Andreas Schneider <asn at samba.org>
+(cherry picked from commit 0f3848a8632d6f6c113d128e71171dc49f4f74b9)
+---
+ librpc/ndr/ndr_dcerpc.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++++
+ librpc/ndr/ndr_dcerpc.h |  25 ++++++++++
+ 2 files changed, 146 insertions(+)
+ create mode 100644 librpc/ndr/ndr_dcerpc.h
+
+diff --git a/librpc/ndr/ndr_dcerpc.c b/librpc/ndr/ndr_dcerpc.c
+index 1b4c75c..751f8ae 100644
+--- a/librpc/ndr/ndr_dcerpc.c
++++ b/librpc/ndr/ndr_dcerpc.c
+@@ -24,6 +24,7 @@
+ #include "librpc/gen_ndr/ndr_dcerpc.h"
+ 
+ #include "librpc/gen_ndr/ndr_misc.h"
++#include "lib/util/bitmap.h"
+ 
+ const uint8_t DCERPC_SEC_VT_MAGIC[] = {0x8a,0xe3,0x13,0x71,0x02,0xf4,0x36,0x71};
+ 
+@@ -64,3 +65,123 @@ _PUBLIC_ enum ndr_err_code ndr_pull_dcerpc_sec_vt_count(struct ndr_pull *ndr, in
+ 	ndr->offset = _saved_ofs;
+ 	return NDR_ERR_SUCCESS;
+ }
++
++_PUBLIC_ enum ndr_err_code ndr_pop_dcerpc_sec_verification_trailer(
++	struct ndr_pull *ndr, TALLOC_CTX *mem_ctx,
++	struct dcerpc_sec_verification_trailer **_r)
++{
++	enum ndr_err_code ndr_err;
++	uint32_t ofs;
++	uint32_t min_ofs = 0;
++	struct dcerpc_sec_verification_trailer *r;
++	DATA_BLOB sub_blob = data_blob_null;
++	struct ndr_pull *sub_ndr = NULL;
++	uint32_t remaining;
++
++	*_r = NULL;
++
++	r = talloc_zero(mem_ctx, struct dcerpc_sec_verification_trailer);
++	if (r == NULL) {
++		return NDR_ERR_ALLOC;
++	}
++
++	if (ndr->data_size < sizeof(DCERPC_SEC_VT_MAGIC)) {
++		/*
++		 * we return with r->count = 0
++		 */
++		*_r = r;
++		return NDR_ERR_SUCCESS;
++	}
++
++	ofs = ndr->data_size - sizeof(DCERPC_SEC_VT_MAGIC);
++	/* the magic is 4 byte aligned */
++	ofs &= ~3;
++
++	if (ofs > DCERPC_SEC_VT_MAX_SIZE) {
++		/*
++		 * We just scan the last 1024 bytes.
++		 */
++		min_ofs = ofs - DCERPC_SEC_VT_MAX_SIZE;
++	} else {
++		min_ofs = 0;
++	}
++
++	while (true) {
++		int ret;
++
++		ret = memcmp(&ndr->data[ofs],
++			     DCERPC_SEC_VT_MAGIC,
++			     sizeof(DCERPC_SEC_VT_MAGIC));
++		if (ret == 0) {
++			sub_blob = data_blob_const(&ndr->data[ofs],
++						   ndr->data_size - ofs);
++			break;
++		}
++
++		if (ofs <= min_ofs) {
++			break;
++		}
++
++		ofs -= 4;
++	}
++
++	if (sub_blob.length == 0) {
++		/*
++		 * we return with r->count = 0
++		 */
++		*_r = r;
++		return NDR_ERR_SUCCESS;
++	}
++
++	sub_ndr = ndr_pull_init_blob(&sub_blob, r);
++	if (sub_ndr == NULL) {
++		TALLOC_FREE(r);
++		return NDR_ERR_ALLOC;
++	}
++
++	ndr_err = ndr_pull_dcerpc_sec_verification_trailer(sub_ndr,
++							   NDR_SCALARS | NDR_BUFFERS,
++							   r);
++	if (ndr_err == NDR_ERR_ALLOC) {
++		TALLOC_FREE(r);
++		return NDR_ERR_ALLOC;
++	}
++
++	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
++		goto ignore_error;
++	}
++
++	remaining = sub_ndr->data_size - sub_ndr->offset;
++	if (remaining > 16) {
++		/*
++		 * we expect not more than 16 byte of additional
++		 * padding after the verification trailer.
++		 */
++		goto ignore_error;
++	}
++
++	/*
++	 * We assume that we got a real verification trailer.
++	 *
++	 * We remove it from the available stub data.
++	 */
++	ndr->data_size = ofs;
++
++	TALLOC_FREE(sub_ndr);
++
++	*_r = r;
++	return NDR_ERR_SUCCESS;
++
++ignore_error:
++	TALLOC_FREE(sub_ndr);
++	/*
++	 * just ignore the error, it's likely
++	 * that the magic we found belongs to
++	 * the stub data.
++	 *
++	 * we return with r->count = 0
++	 */
++	ZERO_STRUCTP(r);
++	*_r = r;
++	return NDR_ERR_SUCCESS;
++}
+diff --git a/librpc/ndr/ndr_dcerpc.h b/librpc/ndr/ndr_dcerpc.h
+new file mode 100644
+index 0000000..f544fb1
+--- /dev/null
++++ b/librpc/ndr/ndr_dcerpc.h
+@@ -0,0 +1,25 @@
++/*
++   Unix SMB/CIFS implementation.
++
++   Manually parsed structures found in the DCERPC protocol
++
++   Copyright (C) Stefan Metzmacher 2014
++   Copyright (C) Gregor Beck 2014
++
++   This program is free software; you can redistribute it and/or modify
++   it under the terms of the GNU General Public License as published by
++   the Free Software Foundation; either version 3 of the License, or
++   (at your option) any later version.
++
++   This program is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU General Public License for more details.
++
++   You should have received a copy of the GNU General Public License
++   along with this program.  If not, see <http://www.gnu.org/licenses/>.
++*/
++
++enum ndr_err_code ndr_pop_dcerpc_sec_verification_trailer(
++	struct ndr_pull *ndr, TALLOC_CTX *mem_ctx,
++	struct dcerpc_sec_verification_trailer **_r);
+-- 
+2.8.1
+
+
+From eec44076563f650a5e65e0d39b0a87b9e37d0373 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Tue, 8 Mar 2011 10:14:51 +0100
+Subject: [PATCH 15/40] librpc/ndr: add NDR_ERR_INCOMPLETE_BUFFER and
+ LIBNDR_FLAG_INCOMPLETE_BUFFER
+
+If we pull a pipe chunk we need a way to check if we
+have enough bytes to parse the complete chunk.
+
+Setting ndr_pull->flags |= LIBNDR_FLAG_INCOMPLETE_BUFFER
+would change NDR_ERR_BUFSIZE (and later maybe others)
+into NDR_ERR_INCOMPLETE_BUFFER.
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Guenther Deschner <gd at samba.org>
+---
+ librpc/ndr/libndr.h | 11 ++++++++++-
+ librpc/ndr/ndr.c    | 10 ++++++++++
+ 2 files changed, 20 insertions(+), 1 deletion(-)
+
+diff --git a/librpc/ndr/libndr.h b/librpc/ndr/libndr.h
+index 924a4e4..d1156e9 100644
+--- a/librpc/ndr/libndr.h
++++ b/librpc/ndr/libndr.h
+@@ -125,6 +125,14 @@ struct ndr_print {
+ #define LIBNDR_STRING_FLAGS		(0x7FFC)
+ 
+ /*
++ * don't debug NDR_ERR_BUFSIZE failures,
++ * as the available buffer might be incomplete.
++ *
++ * return NDR_ERR_INCOMPLETE_BUFFER instead.
++ */
++#define LIBNDR_FLAG_INCOMPLETE_BUFFER (1<<16)
++
++/*
+  * This lets ndr_pull_subcontext_end() return
+  * NDR_ERR_UNREAD_BYTES.
+  */
+@@ -207,7 +215,8 @@ enum ndr_err_code {
+ 	NDR_ERR_INVALID_POINTER,
+ 	NDR_ERR_UNREAD_BYTES,
+ 	NDR_ERR_NDR64,
+-	NDR_ERR_FLAGS
++	NDR_ERR_FLAGS,
++	NDR_ERR_INCOMPLETE_BUFFER
+ };
+ 
+ #define NDR_ERR_CODE_IS_SUCCESS(x) (x == NDR_ERR_SUCCESS)
+diff --git a/librpc/ndr/ndr.c b/librpc/ndr/ndr.c
+index fc11738..2c82998 100644
+--- a/librpc/ndr/ndr.c
++++ b/librpc/ndr/ndr.c
+@@ -454,6 +454,15 @@ _PUBLIC_ enum ndr_err_code ndr_pull_error(struct ndr_pull *ndr,
+ 	va_list ap;
+ 	int ret;
+ 
++	if (ndr->flags & LIBNDR_FLAG_INCOMPLETE_BUFFER) {
++		switch (ndr_err) {
++		case NDR_ERR_BUFSIZE:
++			return NDR_ERR_INCOMPLETE_BUFFER;
++		default:
++			break;
++		}
++	}
++
+ 	va_start(ap, format);
+ 	ret = vasprintf(&s, format, ap);
+ 	va_end(ap);
+@@ -1511,6 +1520,7 @@ const static struct {
+ 	{ NDR_ERR_INVALID_POINTER, "Invalid Pointer" },
+ 	{ NDR_ERR_UNREAD_BYTES, "Unread Bytes" },
+ 	{ NDR_ERR_NDR64, "NDR64 assertion error" },
++	{ NDR_ERR_INCOMPLETE_BUFFER, "Incomplete Buffer" },
+ 	{ 0, NULL }
+ };
+ 
+-- 
+2.8.1
+
+
+From d1ec252f3a7df1e7626ed27e986624f1e1eca6f9 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Sat, 21 Sep 2013 22:30:25 +0200
+Subject: [PATCH 16/40] librpc/ndr: remember INCOMPLETE_BUFFER missing bytes in
+ relative_highest_offset
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Guenther Deschner <gd at samba.org>
+---
+ librpc/ndr/libndr.h | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/librpc/ndr/libndr.h b/librpc/ndr/libndr.h
+index d1156e9..d32db16 100644
+--- a/librpc/ndr/libndr.h
++++ b/librpc/ndr/libndr.h
+@@ -275,6 +275,11 @@ enum ndr_compression_alg {
+ 
+ #define NDR_PULL_NEED_BYTES(ndr, n) do { \
+ 	if (unlikely((n) > ndr->data_size || ndr->offset + (n) > ndr->data_size)) { \
++		if (ndr->flags & LIBNDR_FLAG_INCOMPLETE_BUFFER) { \
++			uint32_t _available = ndr->data_size - ndr->offset; \
++			uint32_t _missing = n - _available; \
++			ndr->relative_highest_offset = _missing; \
++		} \
+ 		return ndr_pull_error(ndr, NDR_ERR_BUFSIZE, "Pull bytes %u (%s)", (unsigned)n, __location__); \
+ 	} \
+ } while(0)
+@@ -291,6 +296,10 @@ enum ndr_compression_alg {
+ 		ndr->offset = (ndr->offset + (n-1)) & ~(n-1); \
+ 	} \
+ 	if (unlikely(ndr->offset > ndr->data_size)) {			\
++		if (ndr->flags & LIBNDR_FLAG_INCOMPLETE_BUFFER) { \
++			uint32_t _missing = ndr->offset - ndr->data_size; \
++			ndr->relative_highest_offset = _missing; \
++		} \
+ 		return ndr_pull_error(ndr, NDR_ERR_BUFSIZE, "Pull align %u", (unsigned)n); \
+ 	} \
+ } while(0)
+-- 
+2.8.1
+
+
+From e67e8d16d970d6b76de1df4399b170cab28225e1 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Sat, 21 Sep 2013 21:58:05 +0200
+Subject: [PATCH 17/40] librpc/ndr: add support for a shallow copy to
+ ndr_pull_subcontext_start/end
+
+This will be usefull to try parsing DCERPC pipe chunks for
+LIBNDR_FLAG_INCOMPLETE_BUFFER.
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Guenther Deschner <gd at samba.org>
+---
+ librpc/ndr/ndr.c | 21 ++++++++++++++++++++-
+ 1 file changed, 20 insertions(+), 1 deletion(-)
+
+diff --git a/librpc/ndr/ndr.c b/librpc/ndr/ndr.c
+index 2c82998..f7f366e 100644
+--- a/librpc/ndr/ndr.c
++++ b/librpc/ndr/ndr.c
+@@ -617,6 +617,23 @@ _PUBLIC_ enum ndr_err_code ndr_pull_subcontext_start(struct ndr_pull *ndr,
+ 		NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &reserved));
+ 		break;
+ 	}
++	case 0xFFFFFFFF:
++		/*
++		 * a shallow copy like subcontext
++		 * useful for DCERPC pipe chunks.
++		 */
++		subndr = talloc_zero(ndr, struct ndr_pull);
++		NDR_ERR_HAVE_NO_MEMORY(subndr);
++
++		subndr->flags		= ndr->flags;
++		subndr->current_mem_ctx	= ndr->current_mem_ctx;
++		subndr->data		= ndr->data;
++		subndr->offset		= ndr->offset;
++		subndr->data_size	= ndr->data_size;
++
++		*_subndr = subndr;
++		return NDR_ERR_SUCCESS;
++
+ 	default:
+ 		return ndr_pull_error(ndr, NDR_ERR_SUBCONTEXT, "Bad subcontext (PULL) header_size %d", 
+ 				      (int)header_size);
+@@ -651,7 +668,9 @@ _PUBLIC_ enum ndr_err_code ndr_pull_subcontext_end(struct ndr_pull *ndr,
+ 	uint32_t advance;
+ 	uint32_t highest_ofs;
+ 
+-	if (size_is >= 0) {
++	if (header_size == 0xFFFFFFFF) {
++		advance = subndr->offset - ndr->offset;
++	} else if (size_is >= 0) {
+ 		advance = size_is;
+ 	} else if (header_size > 0) {
+ 		advance = subndr->data_size;
+-- 
+2.8.1
+
+
+From 52606a96c64492d17abdd87fa07743c8d5885687 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Sat, 21 Sep 2013 02:28:33 +0200
+Subject: [PATCH 18/40] librpc/ndr: add ndr_pull_append/pop()
+
+They can be used to parse a fragmented NDR byte stream.
+
+ndr_pull_append() appends more data that can be processed
+and ndr_pull_pop() removed already processed data.
+
+This will be used to implement dcerpc pipes, where we can get
+a verify large amount of pipe chunks, once we processed a chunk
+we can forget about the related data, but we may need to keep some
+bytes in order to get the alignment right.
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Guenther Deschner <gd at samba.org>
+(cherry picked from commit 7b5717058a7d7a93cda712efc7622a87d3980e48)
+---
+ librpc/ndr/libndr.h |   2 +
+ librpc/ndr/ndr.c    | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 107 insertions(+)
+
+diff --git a/librpc/ndr/libndr.h b/librpc/ndr/libndr.h
+index d32db16..f97577a 100644
+--- a/librpc/ndr/libndr.h
++++ b/librpc/ndr/libndr.h
+@@ -477,6 +477,8 @@ enum ndr_err_code ndr_pull_relative_ptr2(struct ndr_pull *ndr, const void *p);
+ enum ndr_err_code ndr_pull_relative_ptr_short(struct ndr_pull *ndr, uint16_t *v);
+ size_t ndr_align_size(uint32_t offset, size_t n);
+ struct ndr_pull *ndr_pull_init_blob(const DATA_BLOB *blob, TALLOC_CTX *mem_ctx);
++enum ndr_err_code ndr_pull_append(struct ndr_pull *ndr, DATA_BLOB *blob);
++enum ndr_err_code ndr_pull_pop(struct ndr_pull *ndr);
+ enum ndr_err_code ndr_pull_advance(struct ndr_pull *ndr, uint32_t size);
+ struct ndr_push *ndr_push_init_ctx(TALLOC_CTX *mem_ctx);
+ DATA_BLOB ndr_push_blob(struct ndr_push *ndr);
+diff --git a/librpc/ndr/ndr.c b/librpc/ndr/ndr.c
+index f7f366e..453b1c1 100644
+--- a/librpc/ndr/ndr.c
++++ b/librpc/ndr/ndr.c
+@@ -77,6 +77,111 @@ _PUBLIC_ struct ndr_pull *ndr_pull_init_blob(const DATA_BLOB *blob, TALLOC_CTX *
+ 	return ndr;
+ }
+ 
++_PUBLIC_ enum ndr_err_code ndr_pull_append(struct ndr_pull *ndr, DATA_BLOB *blob)
++{
++	enum ndr_err_code ndr_err;
++	DATA_BLOB b;
++	uint32_t append = 0;
++	bool ok;
++
++	if (blob->length == 0) {
++		return NDR_ERR_SUCCESS;
++	}
++
++	ndr_err = ndr_token_retrieve(&ndr->array_size_list, ndr, &append);
++	if (ndr_err == NDR_ERR_TOKEN) {
++		append = 0;
++		ndr_err = NDR_ERR_SUCCESS;
++	}
++	NDR_CHECK(ndr_err);
++
++	if (ndr->data_size == 0) {
++		ndr->data = NULL;
++		append = UINT32_MAX;
++	}
++
++	if (append == UINT32_MAX) {
++		/*
++		 * append == UINT32_MAX means that
++		 * ndr->data is either NULL or a valid
++		 * talloc child of ndr, which means
++		 * we can use data_blob_append() without
++		 * data_blob_talloc() of the existing callers data
++		 */
++		b = data_blob_const(ndr->data, ndr->data_size);
++	} else {
++		b = data_blob_talloc(ndr, ndr->data, ndr->data_size);
++		if (b.data == NULL) {
++			return ndr_pull_error(ndr, NDR_ERR_ALLOC, "%s", __location__);
++		}
++	}
++
++	ok = data_blob_append(ndr, &b, blob->data, blob->length);
++	if (!ok) {
++		return ndr_pull_error(ndr, NDR_ERR_ALLOC, "%s", __location__);
++	}
++
++	ndr->data = b.data;
++	ndr->data_size = b.length;
++
++	return ndr_token_store(ndr, &ndr->array_size_list, ndr, UINT32_MAX);
++}
++
++_PUBLIC_ enum ndr_err_code ndr_pull_pop(struct ndr_pull *ndr)
++{
++	uint32_t skip = 0;
++	uint32_t append = 0;
++
++	if (ndr->relative_base_offset != 0) {
++		return ndr_pull_error(ndr, NDR_ERR_RELATIVE,
++				      "%s", __location__);
++	}
++	if (ndr->relative_highest_offset != 0) {
++		return ndr_pull_error(ndr, NDR_ERR_RELATIVE,
++				      "%s", __location__);
++	}
++	if (ndr->relative_list != NULL) {
++		return ndr_pull_error(ndr, NDR_ERR_RELATIVE,
++				      "%s", __location__);
++	}
++	if (ndr->relative_base_list != NULL) {
++		return ndr_pull_error(ndr, NDR_ERR_RELATIVE,
++				      "%s", __location__);
++	}
++
++	/*
++	 * we need to keep up to 7 bytes
++	 * in order to get the aligment right.
++	 */
++	skip = ndr->offset & 0xFFFFFFF8;
++
++	if (skip == 0) {
++		return NDR_ERR_SUCCESS;
++	}
++
++	ndr->offset -= skip;
++	ndr->data_size -= skip;
++
++	append = ndr_token_peek(&ndr->array_size_list, ndr);
++	if (append != UINT32_MAX) {
++		/*
++		 * here we assume, that ndr->data is not a
++		 * talloc child of ndr.
++		 */
++		ndr->data += skip;
++		return NDR_ERR_SUCCESS;
++	}
++
++	memmove(ndr->data, ndr->data + skip, ndr->data_size);
++
++	ndr->data = talloc_realloc(ndr, ndr->data, uint8_t, ndr->data_size);
++	if (ndr->data_size != 0 && ndr->data == NULL) {
++		return ndr_pull_error(ndr, NDR_ERR_ALLOC, "%s", __location__);
++	}
++
++	return NDR_ERR_SUCCESS;
++}
++
+ /*
+   advance by 'size' bytes
+ */
+-- 
+2.8.1
+
+
+From 527e379b59cd2b3c755857cb1017cd7c0611b38d Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Tue, 4 Feb 2014 12:54:42 +0100
+Subject: [PATCH 19/40] librpc/ndr: add ndr_syntax_id_[from|to]_string()
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Guenther Deschner <gd at samba.org>
+(cherry picked from commit 3b2b0aa4d4bf07971ef016e5a2ce0fec84bbf144)
+---
+ librpc/ABI/ndr-0.0.3.sigs | 251 ++++++++++++++++++++++++++++++++++++++++++++++
+ librpc/ndr/libndr.h       |   2 +
+ librpc/ndr/ndr_misc.c     |  47 +++++++++
+ 3 files changed, 300 insertions(+)
+ create mode 100644 librpc/ABI/ndr-0.0.3.sigs
+
+diff --git a/librpc/ABI/ndr-0.0.3.sigs b/librpc/ABI/ndr-0.0.3.sigs
+new file mode 100644
+index 0000000..d9c76f0
+--- /dev/null
++++ b/librpc/ABI/ndr-0.0.3.sigs
+@@ -0,0 +1,251 @@
++GUID_all_zero: bool (const struct GUID *)
++GUID_compare: int (const struct GUID *, const struct GUID *)
++GUID_equal: bool (const struct GUID *, const struct GUID *)
++GUID_from_data_blob: NTSTATUS (const DATA_BLOB *, struct GUID *)
++GUID_from_ndr_blob: NTSTATUS (const DATA_BLOB *, struct GUID *)
++GUID_from_string: NTSTATUS (const char *, struct GUID *)
++GUID_hexstring: char *(TALLOC_CTX *, const struct GUID *)
++GUID_random: struct GUID (void)
++GUID_string: char *(TALLOC_CTX *, const struct GUID *)
++GUID_string2: char *(TALLOC_CTX *, const struct GUID *)
++GUID_to_ndr_blob: NTSTATUS (const struct GUID *, TALLOC_CTX *, DATA_BLOB *)
++GUID_zero: struct GUID (void)
++ndr_align_size: size_t (uint32_t, size_t)
++ndr_charset_length: uint32_t (const void *, charset_t)
++ndr_check_array_length: enum ndr_err_code (struct ndr_pull *, void *, uint32_t)
++ndr_check_array_size: enum ndr_err_code (struct ndr_pull *, void *, uint32_t)
++ndr_check_padding: void (struct ndr_pull *, size_t)
++ndr_check_pipe_chunk_trailer: enum ndr_err_code (struct ndr_pull *, int, uint32_t)
++ndr_check_string_terminator: enum ndr_err_code (struct ndr_pull *, uint32_t, uint32_t)
++ndr_get_array_length: uint32_t (struct ndr_pull *, const void *)
++ndr_get_array_size: uint32_t (struct ndr_pull *, const void *)
++ndr_map_error2errno: int (enum ndr_err_code)
++ndr_map_error2ntstatus: NTSTATUS (enum ndr_err_code)
++ndr_map_error2string: const char *(enum ndr_err_code)
++ndr_policy_handle_empty: bool (const struct policy_handle *)
++ndr_policy_handle_equal: bool (const struct policy_handle *, const struct policy_handle *)
++ndr_print_DATA_BLOB: void (struct ndr_print *, const char *, DATA_BLOB)
++ndr_print_GUID: void (struct ndr_print *, const char *, const struct GUID *)
++ndr_print_KRB5_EDATA_NTSTATUS: void (struct ndr_print *, const char *, const struct KRB5_EDATA_NTSTATUS *)
++ndr_print_NTSTATUS: void (struct ndr_print *, const char *, NTSTATUS)
++ndr_print_NTTIME: void (struct ndr_print *, const char *, NTTIME)
++ndr_print_NTTIME_1sec: void (struct ndr_print *, const char *, NTTIME)
++ndr_print_NTTIME_hyper: void (struct ndr_print *, const char *, NTTIME)
++ndr_print_WERROR: void (struct ndr_print *, const char *, WERROR)
++ndr_print_array_uint8: void (struct ndr_print *, const char *, const uint8_t *, uint32_t)
++ndr_print_bad_level: void (struct ndr_print *, const char *, uint16_t)
++ndr_print_bitmap_flag: void (struct ndr_print *, size_t, const char *, uint32_t, uint32_t)
++ndr_print_bool: void (struct ndr_print *, const char *, const bool)
++ndr_print_debug: void (ndr_print_fn_t, const char *, void *)
++ndr_print_debug_helper: void (struct ndr_print *, const char *, ...)
++ndr_print_debugc: void (int, ndr_print_fn_t, const char *, void *)
++ndr_print_debugc_helper: void (struct ndr_print *, const char *, ...)
++ndr_print_dlong: void (struct ndr_print *, const char *, int64_t)
++ndr_print_double: void (struct ndr_print *, const char *, double)
++ndr_print_enum: void (struct ndr_print *, const char *, const char *, const char *, uint32_t)
++ndr_print_function_debug: void (ndr_print_function_t, const char *, int, void *)
++ndr_print_function_string: char *(TALLOC_CTX *, ndr_print_function_t, const char *, int, void *)
++ndr_print_get_switch_value: uint32_t (struct ndr_print *, const void *)
++ndr_print_gid_t: void (struct ndr_print *, const char *, gid_t)
++ndr_print_hyper: void (struct ndr_print *, const char *, uint64_t)
++ndr_print_int16: void (struct ndr_print *, const char *, int16_t)
++ndr_print_int32: void (struct ndr_print *, const char *, int32_t)
++ndr_print_int3264: void (struct ndr_print *, const char *, int32_t)
++ndr_print_int8: void (struct ndr_print *, const char *, int8_t)
++ndr_print_ipv4address: void (struct ndr_print *, const char *, const char *)
++ndr_print_ipv6address: void (struct ndr_print *, const char *, const char *)
++ndr_print_ndr_syntax_id: void (struct ndr_print *, const char *, const struct ndr_syntax_id *)
++ndr_print_netr_SamDatabaseID: void (struct ndr_print *, const char *, enum netr_SamDatabaseID)
++ndr_print_netr_SchannelType: void (struct ndr_print *, const char *, enum netr_SchannelType)
++ndr_print_null: void (struct ndr_print *)
++ndr_print_pointer: void (struct ndr_print *, const char *, void *)
++ndr_print_policy_handle: void (struct ndr_print *, const char *, const struct policy_handle *)
++ndr_print_printf_helper: void (struct ndr_print *, const char *, ...)
++ndr_print_ptr: void (struct ndr_print *, const char *, const void *)
++ndr_print_set_switch_value: enum ndr_err_code (struct ndr_print *, const void *, uint32_t)
++ndr_print_sockaddr_storage: void (struct ndr_print *, const char *, const struct sockaddr_storage *)
++ndr_print_string: void (struct ndr_print *, const char *, const char *)
++ndr_print_string_array: void (struct ndr_print *, const char *, const char **)
++ndr_print_string_helper: void (struct ndr_print *, const char *, ...)
++ndr_print_struct: void (struct ndr_print *, const char *, const char *)
++ndr_print_struct_string: char *(TALLOC_CTX *, ndr_print_fn_t, const char *, void *)
++ndr_print_svcctl_ServerType: void (struct ndr_print *, const char *, uint32_t)
++ndr_print_time_t: void (struct ndr_print *, const char *, time_t)
++ndr_print_timespec: void (struct ndr_print *, const char *, const struct timespec *)
++ndr_print_timeval: void (struct ndr_print *, const char *, const struct timeval *)
++ndr_print_udlong: void (struct ndr_print *, const char *, uint64_t)
++ndr_print_udlongr: void (struct ndr_print *, const char *, uint64_t)
++ndr_print_uid_t: void (struct ndr_print *, const char *, uid_t)
++ndr_print_uint16: void (struct ndr_print *, const char *, uint16_t)
++ndr_print_uint32: void (struct ndr_print *, const char *, uint32_t)
++ndr_print_uint3264: void (struct ndr_print *, const char *, uint32_t)
++ndr_print_uint8: void (struct ndr_print *, const char *, uint8_t)
++ndr_print_union: void (struct ndr_print *, const char *, int, const char *)
++ndr_print_union_debug: void (ndr_print_fn_t, const char *, uint32_t, void *)
++ndr_print_union_string: char *(TALLOC_CTX *, ndr_print_fn_t, const char *, uint32_t, void *)
++ndr_print_winreg_Data: void (struct ndr_print *, const char *, const union winreg_Data *)
++ndr_print_winreg_Type: void (struct ndr_print *, const char *, enum winreg_Type)
++ndr_pull_DATA_BLOB: enum ndr_err_code (struct ndr_pull *, int, DATA_BLOB *)
++ndr_pull_GUID: enum ndr_err_code (struct ndr_pull *, int, struct GUID *)
++ndr_pull_KRB5_EDATA_NTSTATUS: enum ndr_err_code (struct ndr_pull *, int, struct KRB5_EDATA_NTSTATUS *)
++ndr_pull_NTSTATUS: enum ndr_err_code (struct ndr_pull *, int, NTSTATUS *)
++ndr_pull_NTTIME: enum ndr_err_code (struct ndr_pull *, int, NTTIME *)
++ndr_pull_NTTIME_1sec: enum ndr_err_code (struct ndr_pull *, int, NTTIME *)
++ndr_pull_NTTIME_hyper: enum ndr_err_code (struct ndr_pull *, int, NTTIME *)
++ndr_pull_WERROR: enum ndr_err_code (struct ndr_pull *, int, WERROR *)
++ndr_pull_advance: enum ndr_err_code (struct ndr_pull *, uint32_t)
++ndr_pull_align: enum ndr_err_code (struct ndr_pull *, size_t)
++ndr_pull_append: enum ndr_err_code (struct ndr_pull *, DATA_BLOB *)
++ndr_pull_array_length: enum ndr_err_code (struct ndr_pull *, const void *)
++ndr_pull_array_size: enum ndr_err_code (struct ndr_pull *, const void *)
++ndr_pull_array_uint8: enum ndr_err_code (struct ndr_pull *, int, uint8_t *, uint32_t)
++ndr_pull_bytes: enum ndr_err_code (struct ndr_pull *, uint8_t *, uint32_t)
++ndr_pull_charset: enum ndr_err_code (struct ndr_pull *, int, const char **, uint32_t, uint8_t, charset_t)
++ndr_pull_charset_to_null: enum ndr_err_code (struct ndr_pull *, int, const char **, uint32_t, uint8_t, charset_t)
++ndr_pull_dlong: enum ndr_err_code (struct ndr_pull *, int, int64_t *)
++ndr_pull_double: enum ndr_err_code (struct ndr_pull *, int, double *)
++ndr_pull_enum_uint16: enum ndr_err_code (struct ndr_pull *, int, uint16_t *)
++ndr_pull_enum_uint1632: enum ndr_err_code (struct ndr_pull *, int, uint16_t *)
++ndr_pull_enum_uint32: enum ndr_err_code (struct ndr_pull *, int, uint32_t *)
++ndr_pull_enum_uint8: enum ndr_err_code (struct ndr_pull *, int, uint8_t *)
++ndr_pull_error: enum ndr_err_code (struct ndr_pull *, enum ndr_err_code, const char *, ...)
++ndr_pull_generic_ptr: enum ndr_err_code (struct ndr_pull *, uint32_t *)
++ndr_pull_get_relative_base_offset: uint32_t (struct ndr_pull *)
++ndr_pull_get_switch_value: uint32_t (struct ndr_pull *, const void *)
++ndr_pull_gid_t: enum ndr_err_code (struct ndr_pull *, int, gid_t *)
++ndr_pull_hyper: enum ndr_err_code (struct ndr_pull *, int, uint64_t *)
++ndr_pull_init_blob: struct ndr_pull *(const DATA_BLOB *, TALLOC_CTX *)
++ndr_pull_int16: enum ndr_err_code (struct ndr_pull *, int, int16_t *)
++ndr_pull_int32: enum ndr_err_code (struct ndr_pull *, int, int32_t *)
++ndr_pull_int8: enum ndr_err_code (struct ndr_pull *, int, int8_t *)
++ndr_pull_ipv4address: enum ndr_err_code (struct ndr_pull *, int, const char **)
++ndr_pull_ipv6address: enum ndr_err_code (struct ndr_pull *, int, const char **)
++ndr_pull_ndr_syntax_id: enum ndr_err_code (struct ndr_pull *, int, struct ndr_syntax_id *)
++ndr_pull_netr_SamDatabaseID: enum ndr_err_code (struct ndr_pull *, int, enum netr_SamDatabaseID *)
++ndr_pull_netr_SchannelType: enum ndr_err_code (struct ndr_pull *, int, enum netr_SchannelType *)
++ndr_pull_pointer: enum ndr_err_code (struct ndr_pull *, int, void **)
++ndr_pull_policy_handle: enum ndr_err_code (struct ndr_pull *, int, struct policy_handle *)
++ndr_pull_pop: enum ndr_err_code (struct ndr_pull *)
++ndr_pull_ref_ptr: enum ndr_err_code (struct ndr_pull *, uint32_t *)
++ndr_pull_relative_ptr1: enum ndr_err_code (struct ndr_pull *, const void *, uint32_t)
++ndr_pull_relative_ptr2: enum ndr_err_code (struct ndr_pull *, const void *)
++ndr_pull_relative_ptr_short: enum ndr_err_code (struct ndr_pull *, uint16_t *)
++ndr_pull_restore_relative_base_offset: void (struct ndr_pull *, uint32_t)
++ndr_pull_set_switch_value: enum ndr_err_code (struct ndr_pull *, const void *, uint32_t)
++ndr_pull_setup_relative_base_offset1: enum ndr_err_code (struct ndr_pull *, const void *, uint32_t)
++ndr_pull_setup_relative_base_offset2: enum ndr_err_code (struct ndr_pull *, const void *)
++ndr_pull_string: enum ndr_err_code (struct ndr_pull *, int, const char **)
++ndr_pull_string_array: enum ndr_err_code (struct ndr_pull *, int, const char ***)
++ndr_pull_struct_blob: enum ndr_err_code (const DATA_BLOB *, TALLOC_CTX *, void *, ndr_pull_flags_fn_t)
++ndr_pull_struct_blob_all: enum ndr_err_code (const DATA_BLOB *, TALLOC_CTX *, void *, ndr_pull_flags_fn_t)
++ndr_pull_subcontext_end: enum ndr_err_code (struct ndr_pull *, struct ndr_pull *, size_t, ssize_t)
++ndr_pull_subcontext_start: enum ndr_err_code (struct ndr_pull *, struct ndr_pull **, size_t, ssize_t)
++ndr_pull_svcctl_ServerType: enum ndr_err_code (struct ndr_pull *, int, uint32_t *)
++ndr_pull_time_t: enum ndr_err_code (struct ndr_pull *, int, time_t *)
++ndr_pull_timespec: enum ndr_err_code (struct ndr_pull *, int, struct timespec *)
++ndr_pull_timeval: enum ndr_err_code (struct ndr_pull *, int, struct timeval *)
++ndr_pull_trailer_align: enum ndr_err_code (struct ndr_pull *, size_t)
++ndr_pull_udlong: enum ndr_err_code (struct ndr_pull *, int, uint64_t *)
++ndr_pull_udlongr: enum ndr_err_code (struct ndr_pull *, int, uint64_t *)
++ndr_pull_uid_t: enum ndr_err_code (struct ndr_pull *, int, uid_t *)
++ndr_pull_uint16: enum ndr_err_code (struct ndr_pull *, int, uint16_t *)
++ndr_pull_uint1632: enum ndr_err_code (struct ndr_pull *, int, uint16_t *)
++ndr_pull_uint32: enum ndr_err_code (struct ndr_pull *, int, uint32_t *)
++ndr_pull_uint3264: enum ndr_err_code (struct ndr_pull *, int, uint32_t *)
++ndr_pull_uint8: enum ndr_err_code (struct ndr_pull *, int, uint8_t *)
++ndr_pull_union_align: enum ndr_err_code (struct ndr_pull *, size_t)
++ndr_pull_union_blob: enum ndr_err_code (const DATA_BLOB *, TALLOC_CTX *, void *, uint32_t, ndr_pull_flags_fn_t)
++ndr_pull_union_blob_all: enum ndr_err_code (const DATA_BLOB *, TALLOC_CTX *, void *, uint32_t, ndr_pull_flags_fn_t)
++ndr_pull_winreg_Data: enum ndr_err_code (struct ndr_pull *, int, union winreg_Data *)
++ndr_pull_winreg_Type: enum ndr_err_code (struct ndr_pull *, int, enum winreg_Type *)
++ndr_push_DATA_BLOB: enum ndr_err_code (struct ndr_push *, int, DATA_BLOB)
++ndr_push_GUID: enum ndr_err_code (struct ndr_push *, int, const struct GUID *)
++ndr_push_KRB5_EDATA_NTSTATUS: enum ndr_err_code (struct ndr_push *, int, const struct KRB5_EDATA_NTSTATUS *)
++ndr_push_NTSTATUS: enum ndr_err_code (struct ndr_push *, int, NTSTATUS)
++ndr_push_NTTIME: enum ndr_err_code (struct ndr_push *, int, NTTIME)
++ndr_push_NTTIME_1sec: enum ndr_err_code (struct ndr_push *, int, NTTIME)
++ndr_push_NTTIME_hyper: enum ndr_err_code (struct ndr_push *, int, NTTIME)
++ndr_push_WERROR: enum ndr_err_code (struct ndr_push *, int, WERROR)
++ndr_push_align: enum ndr_err_code (struct ndr_push *, size_t)
++ndr_push_array_uint8: enum ndr_err_code (struct ndr_push *, int, const uint8_t *, uint32_t)
++ndr_push_blob: DATA_BLOB (struct ndr_push *)
++ndr_push_bytes: enum ndr_err_code (struct ndr_push *, const uint8_t *, uint32_t)
++ndr_push_charset: enum ndr_err_code (struct ndr_push *, int, const char *, uint32_t, uint8_t, charset_t)
++ndr_push_dlong: enum ndr_err_code (struct ndr_push *, int, int64_t)
++ndr_push_double: enum ndr_err_code (struct ndr_push *, int, double)
++ndr_push_enum_uint16: enum ndr_err_code (struct ndr_push *, int, uint16_t)
++ndr_push_enum_uint1632: enum ndr_err_code (struct ndr_push *, int, uint16_t)
++ndr_push_enum_uint32: enum ndr_err_code (struct ndr_push *, int, uint32_t)
++ndr_push_enum_uint8: enum ndr_err_code (struct ndr_push *, int, uint8_t)
++ndr_push_error: enum ndr_err_code (struct ndr_push *, enum ndr_err_code, const char *, ...)
++ndr_push_expand: enum ndr_err_code (struct ndr_push *, uint32_t)
++ndr_push_full_ptr: enum ndr_err_code (struct ndr_push *, const void *)
++ndr_push_get_relative_base_offset: uint32_t (struct ndr_push *)
++ndr_push_get_switch_value: uint32_t (struct ndr_push *, const void *)
++ndr_push_gid_t: enum ndr_err_code (struct ndr_push *, int, gid_t)
++ndr_push_hyper: enum ndr_err_code (struct ndr_push *, int, uint64_t)
++ndr_push_init_ctx: struct ndr_push *(TALLOC_CTX *)
++ndr_push_int16: enum ndr_err_code (struct ndr_push *, int, int16_t)
++ndr_push_int32: enum ndr_err_code (struct ndr_push *, int, int32_t)
++ndr_push_int8: enum ndr_err_code (struct ndr_push *, int, int8_t)
++ndr_push_ipv4address: enum ndr_err_code (struct ndr_push *, int, const char *)
++ndr_push_ipv6address: enum ndr_err_code (struct ndr_push *, int, const char *)
++ndr_push_ndr_syntax_id: enum ndr_err_code (struct ndr_push *, int, const struct ndr_syntax_id *)
++ndr_push_netr_SamDatabaseID: enum ndr_err_code (struct ndr_push *, int, enum netr_SamDatabaseID)
++ndr_push_netr_SchannelType: enum ndr_err_code (struct ndr_push *, int, enum netr_SchannelType)
++ndr_push_pipe_chunk_trailer: enum ndr_err_code (struct ndr_push *, int, uint32_t)
++ndr_push_pointer: enum ndr_err_code (struct ndr_push *, int, void *)
++ndr_push_policy_handle: enum ndr_err_code (struct ndr_push *, int, const struct policy_handle *)
++ndr_push_ref_ptr: enum ndr_err_code (struct ndr_push *)
++ndr_push_relative_ptr1: enum ndr_err_code (struct ndr_push *, const void *)
++ndr_push_relative_ptr2_end: enum ndr_err_code (struct ndr_push *, const void *)
++ndr_push_relative_ptr2_start: enum ndr_err_code (struct ndr_push *, const void *)
++ndr_push_restore_relative_base_offset: void (struct ndr_push *, uint32_t)
++ndr_push_set_switch_value: enum ndr_err_code (struct ndr_push *, const void *, uint32_t)
++ndr_push_setup_relative_base_offset1: enum ndr_err_code (struct ndr_push *, const void *, uint32_t)
++ndr_push_setup_relative_base_offset2: enum ndr_err_code (struct ndr_push *, const void *)
++ndr_push_short_relative_ptr1: enum ndr_err_code (struct ndr_push *, const void *)
++ndr_push_short_relative_ptr2: enum ndr_err_code (struct ndr_push *, const void *)
++ndr_push_string: enum ndr_err_code (struct ndr_push *, int, const char *)
++ndr_push_string_array: enum ndr_err_code (struct ndr_push *, int, const char **)
++ndr_push_struct_blob: enum ndr_err_code (DATA_BLOB *, TALLOC_CTX *, const void *, ndr_push_flags_fn_t)
++ndr_push_subcontext_end: enum ndr_err_code (struct ndr_push *, struct ndr_push *, size_t, ssize_t)
++ndr_push_subcontext_start: enum ndr_err_code (struct ndr_push *, struct ndr_push **, size_t, ssize_t)
++ndr_push_svcctl_ServerType: enum ndr_err_code (struct ndr_push *, int, uint32_t)
++ndr_push_time_t: enum ndr_err_code (struct ndr_push *, int, time_t)
++ndr_push_timespec: enum ndr_err_code (struct ndr_push *, int, const struct timespec *)
++ndr_push_timeval: enum ndr_err_code (struct ndr_push *, int, const struct timeval *)
++ndr_push_trailer_align: enum ndr_err_code (struct ndr_push *, size_t)
++ndr_push_udlong: enum ndr_err_code (struct ndr_push *, int, uint64_t)
++ndr_push_udlongr: enum ndr_err_code (struct ndr_push *, int, uint64_t)
++ndr_push_uid_t: enum ndr_err_code (struct ndr_push *, int, uid_t)
++ndr_push_uint16: enum ndr_err_code (struct ndr_push *, int, uint16_t)
++ndr_push_uint1632: enum ndr_err_code (struct ndr_push *, int, uint16_t)
++ndr_push_uint32: enum ndr_err_code (struct ndr_push *, int, uint32_t)
++ndr_push_uint3264: enum ndr_err_code (struct ndr_push *, int, uint32_t)
++ndr_push_uint8: enum ndr_err_code (struct ndr_push *, int, uint8_t)
++ndr_push_union_align: enum ndr_err_code (struct ndr_push *, size_t)
++ndr_push_union_blob: enum ndr_err_code (DATA_BLOB *, TALLOC_CTX *, void *, uint32_t, ndr_push_flags_fn_t)
++ndr_push_unique_ptr: enum ndr_err_code (struct ndr_push *, const void *)
++ndr_push_winreg_Data: enum ndr_err_code (struct ndr_push *, int, const union winreg_Data *)
++ndr_push_winreg_Type: enum ndr_err_code (struct ndr_push *, int, enum winreg_Type)
++ndr_push_zero: enum ndr_err_code (struct ndr_push *, uint32_t)
++ndr_set_flags: void (uint32_t *, uint32_t)
++ndr_size_DATA_BLOB: uint32_t (int, const DATA_BLOB *, int)
++ndr_size_GUID: size_t (const struct GUID *, int)
++ndr_size_string: uint32_t (int, const char * const *, int)
++ndr_size_string_array: size_t (const char **, uint32_t, int)
++ndr_size_struct: size_t (const void *, int, ndr_push_flags_fn_t)
++ndr_size_union: size_t (const void *, int, uint32_t, ndr_push_flags_fn_t)
++ndr_string_array_size: size_t (struct ndr_push *, const char *)
++ndr_string_length: uint32_t (const void *, uint32_t)
++ndr_syntax_id_equal: bool (const struct ndr_syntax_id *, const struct ndr_syntax_id *)
++ndr_syntax_id_from_string: bool (const char *, struct ndr_syntax_id *)
++ndr_syntax_id_null: uuid = {time_low = 0, time_mid = 0, time_hi_and_version = 0, clock_seq = "\000", node = "\000\000\000\000\000"}, if_version = 0
++ndr_syntax_id_to_string: char *(TALLOC_CTX *, const struct ndr_syntax_id *)
++ndr_token_peek: uint32_t (struct ndr_token_list **, const void *)
++ndr_token_retrieve: enum ndr_err_code (struct ndr_token_list **, const void *, uint32_t *)
++ndr_token_retrieve_cmp_fn: enum ndr_err_code (struct ndr_token_list **, const void *, uint32_t *, comparison_fn_t, bool)
++ndr_token_store: enum ndr_err_code (TALLOC_CTX *, struct ndr_token_list **, const void *, uint32_t)
++ndr_transfer_syntax_ndr: uuid = {time_low = 2324192516, time_mid = 7403, time_hi_and_version = 4553, clock_seq = "\237\350", node = "\b\000+\020H`"}, if_version = 2
++ndr_transfer_syntax_ndr64: uuid = {time_low = 1903232307, time_mid = 48826, time_hi_and_version = 18743, clock_seq = "\203\031", node = "\265\333\357\234\314\066"}, if_version = 1
+diff --git a/librpc/ndr/libndr.h b/librpc/ndr/libndr.h
+index f97577a..62e6156 100644
+--- a/librpc/ndr/libndr.h
++++ b/librpc/ndr/libndr.h
+@@ -455,6 +455,8 @@ void ndr_print_dom_sid0(struct ndr_print *ndr, const char *name, const struct do
+ size_t ndr_size_dom_sid0(const struct dom_sid *sid, int flags);
+ void ndr_print_GUID(struct ndr_print *ndr, const char *name, const struct GUID *guid);
+ bool ndr_syntax_id_equal(const struct ndr_syntax_id *i1, const struct ndr_syntax_id *i2); 
++char *ndr_syntax_id_to_string(TALLOC_CTX *mem_ctx, const struct ndr_syntax_id *id);
++bool ndr_syntax_id_from_string(const char *s, struct ndr_syntax_id *id);
+ enum ndr_err_code ndr_push_struct_blob(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, const void *p, ndr_push_flags_fn_t fn);
+ enum ndr_err_code ndr_push_union_blob(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, void *p, uint32_t level, ndr_push_flags_fn_t fn);
+ size_t ndr_size_struct(const void *p, int flags, ndr_push_flags_fn_t push);
+diff --git a/librpc/ndr/ndr_misc.c b/librpc/ndr/ndr_misc.c
+index c4a1adb..fa643c8 100644
+--- a/librpc/ndr/ndr_misc.c
++++ b/librpc/ndr/ndr_misc.c
+@@ -35,3 +35,50 @@ bool ndr_syntax_id_equal(const struct ndr_syntax_id *i1,
+ 	return GUID_equal(&i1->uuid, &i2->uuid)
+ 		&& (i1->if_version == i2->if_version);
+ }
++
++_PUBLIC_ char *ndr_syntax_id_to_string(TALLOC_CTX *mem_ctx, const struct ndr_syntax_id *id)
++{
++	return talloc_asprintf(mem_ctx,
++			       "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x/0x%08x",
++			       id->uuid.time_low, id->uuid.time_mid,
++			       id->uuid.time_hi_and_version,
++			       id->uuid.clock_seq[0],
++			       id->uuid.clock_seq[1],
++			       id->uuid.node[0], id->uuid.node[1],
++			       id->uuid.node[2], id->uuid.node[3],
++			       id->uuid.node[4], id->uuid.node[5],
++			       (unsigned)id->if_version);
++}
++
++_PUBLIC_ bool ndr_syntax_id_from_string(const char *s, struct ndr_syntax_id *id)
++{
++	int ret;
++	size_t i;
++	uint32_t time_low;
++	uint32_t time_mid, time_hi_and_version;
++	uint32_t clock_seq[2];
++	uint32_t node[6];
++	uint32_t if_version;
++
++	ret = sscanf(s,
++		     "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x/0x%08x",
++		     &time_low, &time_mid, &time_hi_and_version,
++		     &clock_seq[0], &clock_seq[1],
++		     &node[0], &node[1], &node[2], &node[3], &node[4], &node[5],
++		     &if_version);
++	if (ret != 12) {
++		return false;
++	}
++
++	id->uuid.time_low = time_low;
++	id->uuid.time_mid = time_mid;
++	id->uuid.time_hi_and_version = time_hi_and_version;
++	id->uuid.clock_seq[0] = clock_seq[0];
++	id->uuid.clock_seq[1] = clock_seq[1];
++	for (i=0; i<6; i++) {
++		id->uuid.node[i] = node[i];
++	}
++	id->if_version = if_version;
++
++	return true;
++}
+-- 
+2.8.1
+
+
+From f9dcc92e71353524fd090265350dcb2aeb4e40d4 Mon Sep 17 00:00:00 2001
+From: Gregor Beck <gbeck at sernet.de>
+Date: Mon, 13 Jan 2014 13:33:09 +0100
+Subject: [PATCH 20/40] librpc/rpc: add
+ dcerpc_sec_vt_header2_[from_ncacn_packet|equal]()
+
+Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
+
+Signed-off-by: Gregor Beck <gbeck at sernet.de>
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Guenther Deschner <gd at samba.org>
+(cherry picked from commit 9c5664f58d1e8674ce5a53c6aa10d6343001b6c7)
+---
+ librpc/rpc/dcerpc_util.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++
+ librpc/rpc/rpc_common.h  | 23 ++++++++++++++++++++
+ 2 files changed, 79 insertions(+)
+
+diff --git a/librpc/rpc/dcerpc_util.c b/librpc/rpc/dcerpc_util.c
+index cb21312..3e3616e 100644
+--- a/librpc/rpc/dcerpc_util.c
++++ b/librpc/rpc/dcerpc_util.c
+@@ -341,3 +341,59 @@ NTSTATUS dcerpc_read_ncacn_packet_recv(struct tevent_req *req,
+ 	tevent_req_received(req);
+ 	return NT_STATUS_OK;
+ }
++
++struct dcerpc_sec_vt_header2 dcerpc_sec_vt_header2_from_ncacn_packet(const struct ncacn_packet *pkt)
++{
++	struct dcerpc_sec_vt_header2 ret;
++
++	ZERO_STRUCT(ret);
++	ret.ptype = pkt->ptype;
++	memcpy(&ret.drep, pkt->drep, sizeof(ret.drep));
++	ret.call_id = pkt->call_id;
++
++	switch (pkt->ptype) {
++	case DCERPC_PKT_REQUEST:
++		ret.context_id = pkt->u.request.context_id;
++		ret.opnum      = pkt->u.request.opnum;
++		break;
++
++	case DCERPC_PKT_RESPONSE:
++		ret.context_id = pkt->u.response.context_id;
++		break;
++
++	case DCERPC_PKT_FAULT:
++		ret.context_id = pkt->u.fault.context_id;
++		break;
++
++	default:
++		break;
++	}
++
++	return ret;
++}
++
++bool dcerpc_sec_vt_header2_equal(const struct dcerpc_sec_vt_header2 *v1,
++				 const struct dcerpc_sec_vt_header2 *v2)
++{
++	if (v1->ptype != v2->ptype) {
++		return false;
++	}
++
++	if (memcmp(v1->drep, v2->drep, sizeof(v1->drep)) != 0) {
++		return false;
++	}
++
++	if (v1->call_id != v2->call_id) {
++		return false;
++	}
++
++	if (v1->context_id != v2->context_id) {
++		return false;
++	}
++
++	if (v1->opnum != v2->opnum) {
++		return false;
++	}
++
++	return true;
++}
+diff --git a/librpc/rpc/rpc_common.h b/librpc/rpc/rpc_common.h
+index 924645d..4f9190d 100644
+--- a/librpc/rpc/rpc_common.h
++++ b/librpc/rpc/rpc_common.h
+@@ -296,4 +296,27 @@ NTSTATUS dcerpc_binding_handle_call(struct dcerpc_binding_handle *h,
+ 				    TALLOC_CTX *r_mem,
+ 				    void *r_ptr);
+ 
++/**
++ * Extract header information from a ncacn_packet
++ * as a dcerpc_sec_vt_header2 as used by the security verification trailer.
++ *
++ * @param[in] pkt a packet
++ *
++ * @return a dcerpc_sec_vt_header2
++ */
++struct dcerpc_sec_vt_header2 dcerpc_sec_vt_header2_from_ncacn_packet(const struct ncacn_packet *pkt);
++
++
++/**
++ * Test if two dcerpc_sec_vt_header2 structures are equal
++ * without consideration of reserved fields.
++ *
++ * @param v1 a pointer to a dcerpc_sec_vt_header2 structure
++ * @param v2 a pointer to a dcerpc_sec_vt_header2 structure
++ *
++ * @retval true if *v1 equals *v2
++ */
++bool dcerpc_sec_vt_header2_equal(const struct dcerpc_sec_vt_header2 *v1,
++				 const struct dcerpc_sec_vt_header2 *v2);
++
+ #endif /* __DEFAULT_LIBRPC_RPCCOMMON_H__ */
+-- 
+2.8.1
+
+
+From d9c11a2fd6d2e63ba3f024f7f82ea2cc11a6eb53 Mon Sep 17 00:00:00 2001
+From: Gregor Beck <gbeck at sernet.de>
+Date: Wed, 8 Jan 2014 09:50:33 +0100
+Subject: [PATCH 21/40] librpc/rpc: add dcerpc_sec_verification_trailer_check()
+
+Signed-off-by: Gregor Beck <gbeck at sernet.de>
+Reviewed-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Guenther Deschner <gd at samba.org>
+(cherry picked from commit 1fd484270153ba8d47e95b8961db175d50b8b9cb)
+---
+ librpc/rpc/dcerpc_util.c | 136 +++++++++++++++++++++++++++++++++++++++++++++++
+ librpc/rpc/rpc_common.h  |  18 +++++++
+ librpc/wscript_build     |   1 +
+ 3 files changed, 155 insertions(+)
+
+diff --git a/librpc/rpc/dcerpc_util.c b/librpc/rpc/dcerpc_util.c
+index 3e3616e..97ef798 100644
+--- a/librpc/rpc/dcerpc_util.c
++++ b/librpc/rpc/dcerpc_util.c
+@@ -27,6 +27,7 @@
+ #include "librpc/rpc/dcerpc.h"
+ #include "librpc/gen_ndr/ndr_dcerpc.h"
+ #include "rpc_common.h"
++#include "lib/util/bitmap.h"
+ 
+ /* we need to be able to get/set the fragment length without doing a full
+    decode */
+@@ -397,3 +398,138 @@ bool dcerpc_sec_vt_header2_equal(const struct dcerpc_sec_vt_header2 *v1,
+ 
+ 	return true;
+ }
++
++static bool dcerpc_sec_vt_is_valid(const struct dcerpc_sec_verification_trailer *r)
++{
++	bool ret = false;
++	TALLOC_CTX *frame = talloc_stackframe();
++	struct bitmap *commands_seen;
++	int i;
++
++	if (r->count.count == 0) {
++		ret = true;
++		goto done;
++	}
++
++	if (memcmp(r->magic, DCERPC_SEC_VT_MAGIC, sizeof(r->magic)) != 0) {
++		goto done;
++	}
++
++	commands_seen = bitmap_talloc(frame, DCERPC_SEC_VT_COMMAND_ENUM + 1);
++	if (commands_seen == NULL) {
++		goto done;
++	}
++
++	for (i=0; i < r->count.count; i++) {
++		enum dcerpc_sec_vt_command_enum cmd =
++			r->commands[i].command & DCERPC_SEC_VT_COMMAND_ENUM;
++
++		if (bitmap_query(commands_seen, cmd)) {
++			/* Each command must appear at most once. */
++			goto done;
++		}
++		bitmap_set(commands_seen, cmd);
++
++		switch (cmd) {
++		case DCERPC_SEC_VT_COMMAND_BITMASK1:
++		case DCERPC_SEC_VT_COMMAND_PCONTEXT:
++		case DCERPC_SEC_VT_COMMAND_HEADER2:
++			break;
++		default:
++			if ((r->commands[i].u._unknown.length % 4) != 0) {
++				goto done;
++			}
++			break;
++		}
++	}
++	ret = true;
++done:
++	TALLOC_FREE(frame);
++	return ret;
++}
++
++#define CHECK(msg, ok)						\
++do {								\
++	if (!ok) {						\
++		DEBUG(10, ("SEC_VT check %s failed\n", msg));	\
++		return false;					\
++	}							\
++} while(0)
++
++#define CHECK_SYNTAX(msg, s1, s2)					\
++do {								\
++	if (!ndr_syntax_id_equal(&s1, &s2)) {				\
++		TALLOC_CTX *frame = talloc_stackframe();		\
++		DEBUG(10, ("SEC_VT check %s failed: %s vs. %s\n", msg,	\
++			   ndr_syntax_id_to_string(frame, &s1),		\
++			   ndr_syntax_id_to_string(frame, &s1)));	\
++		TALLOC_FREE(frame);					\
++		return false;						\
++	}								\
++} while(0)
++
++
++bool dcerpc_sec_verification_trailer_check(
++		const struct dcerpc_sec_verification_trailer *vt,
++		const uint32_t *bitmask1,
++		const struct dcerpc_sec_vt_pcontext *pcontext,
++		const struct dcerpc_sec_vt_header2 *header2)
++{
++	size_t i;
++
++	if (!dcerpc_sec_vt_is_valid(vt)) {
++		return false;
++	}
++
++	for (i=0; i < vt->count.count; i++) {
++		struct dcerpc_sec_vt *c = &vt->commands[i];
++
++		switch (c->command & DCERPC_SEC_VT_COMMAND_ENUM) {
++		case DCERPC_SEC_VT_COMMAND_BITMASK1:
++			if (bitmask1 == NULL) {
++				CHECK("Bitmask1 must_process_command",
++				      !(c->command & DCERPC_SEC_VT_MUST_PROCESS));
++				break;
++			}
++
++			if (c->u.bitmask1 & DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING) {
++				CHECK("Bitmask1 client_header_signing",
++				      *bitmask1 & DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING);
++			}
++			break;
++
++		case DCERPC_SEC_VT_COMMAND_PCONTEXT:
++			if (pcontext == NULL) {
++				CHECK("Pcontext must_process_command",
++				      !(c->command & DCERPC_SEC_VT_MUST_PROCESS));
++				break;
++			}
++
++			CHECK_SYNTAX("Pcontect abstract_syntax",
++				     pcontext->abstract_syntax,
++				     c->u.pcontext.abstract_syntax);
++			CHECK_SYNTAX("Pcontext transfer_syntax",
++				     pcontext->transfer_syntax,
++				     c->u.pcontext.transfer_syntax);
++			break;
++
++		case DCERPC_SEC_VT_COMMAND_HEADER2: {
++			if (header2 == NULL) {
++				CHECK("Header2 must_process_command",
++				      !(c->command & DCERPC_SEC_VT_MUST_PROCESS));
++				break;
++			}
++
++			CHECK("Header2", dcerpc_sec_vt_header2_equal(header2, &c->u.header2));
++			break;
++		}
++
++		default:
++			CHECK("Unknown must_process_command",
++			      !(c->command & DCERPC_SEC_VT_MUST_PROCESS));
++			break;
++		}
++	}
++
++	return true;
++}
+diff --git a/librpc/rpc/rpc_common.h b/librpc/rpc/rpc_common.h
+index 4f9190d..fe8129d 100644
+--- a/librpc/rpc/rpc_common.h
++++ b/librpc/rpc/rpc_common.h
+@@ -319,4 +319,22 @@ struct dcerpc_sec_vt_header2 dcerpc_sec_vt_header2_from_ncacn_packet(const struc
+ bool dcerpc_sec_vt_header2_equal(const struct dcerpc_sec_vt_header2 *v1,
+ 				 const struct dcerpc_sec_vt_header2 *v2);
+ 
++/**
++ * Check for consistency of the security verification trailer with the PDU header.
++ * See <a href="http://msdn.microsoft.com/en-us/library/cc243559.aspx">MS-RPCE 2.2.2.13</a>.
++ * A check with an empty trailer succeeds.
++ *
++ * @param[in] vt a pointer to the security verification trailer.
++ * @param[in] bitmask1 which flags were negotiated on the connection.
++ * @param[in] pcontext the syntaxes negotiatied for the presentation context.
++ * @param[in] header2 some fields from the PDU header.
++ *
++ * @retval true on success.
++ */
++bool dcerpc_sec_verification_trailer_check(
++		const struct dcerpc_sec_verification_trailer *vt,
++		const uint32_t *bitmask1,
++		const struct dcerpc_sec_vt_pcontext *pcontext,
++		const struct dcerpc_sec_vt_header2 *header2);
++
+ #endif /* __DEFAULT_LIBRPC_RPCCOMMON_H__ */
+diff --git a/librpc/wscript_build b/librpc/wscript_build
+index 1f8e556..751d4a3 100644
+--- a/librpc/wscript_build
++++ b/librpc/wscript_build
+@@ -276,6 +276,7 @@ bld.SAMBA_SUBSYSTEM('NDR_COMPRESSION',
+ bld.SAMBA_SUBSYSTEM('NDR_DCERPC',
+ 	source='gen_ndr/ndr_dcerpc.c ndr/ndr_dcerpc.c',
+ 	public_deps='ndr',
++	deps='bitmap',
+ 	public_headers='gen_ndr/ndr_dcerpc.h gen_ndr/dcerpc.h',
+ 	header_path= [ ('*gen_ndr*', 'gen_ndr') ],
+ 	)
+-- 
+2.8.1
+
+
+From 1337bc1628e555ceb3784a41d750f35ca1dad9f4 Mon Sep 17 00:00:00 2001
+From: Andrew Tridgell <tridge at samba.org>
+Date: Wed, 7 Sep 2011 15:35:55 +1000
+Subject: [PATCH 22/40] torture-ndr: added support for testing push functions
+
+this allows us to check the symmetry of pull/push functions in NDR
+tests
+
+Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>
+---
+ source4/torture/ndr/ndr.c | 50 ++++++++++++++++++++++++++++++++---------------
+ source4/torture/ndr/ndr.h | 25 ++++++++++++++++--------
+ 2 files changed, 51 insertions(+), 24 deletions(-)
+
+diff --git a/source4/torture/ndr/ndr.c b/source4/torture/ndr/ndr.c
+index c5fd6b8..5df25b0 100644
+--- a/source4/torture/ndr/ndr.c
++++ b/source4/torture/ndr/ndr.c
+@@ -29,17 +29,19 @@ struct ndr_pull_test_data {
+ 	DATA_BLOB data_context;
+ 	size_t struct_size;
+ 	ndr_pull_flags_fn_t pull_fn;
++	ndr_push_flags_fn_t push_fn;
+ 	int ndr_flags;
+ };
+ 
+-static bool wrap_ndr_pull_test(struct torture_context *tctx,
+-			       struct torture_tcase *tcase,
+-			       struct torture_test *test)
++static bool wrap_ndr_pullpush_test(struct torture_context *tctx,
++				   struct torture_tcase *tcase,
++				   struct torture_test *test)
+ {
+ 	bool (*check_fn) (struct torture_context *ctx, void *data) = test->fn;
+ 	const struct ndr_pull_test_data *data = (const struct ndr_pull_test_data *)test->data;
+-	void *ds = talloc_zero_size(tctx, data->struct_size);
+ 	struct ndr_pull *ndr = ndr_pull_init_blob(&(data->data), tctx);
++	void *ds = talloc_zero_size(ndr, data->struct_size);
++	bool ret;
+ 
+ 	ndr->flags |= LIBNDR_FLAG_REF_ALLOC;
+ 
+@@ -50,19 +52,31 @@ static bool wrap_ndr_pull_test(struct torture_context *tctx,
+ 				   talloc_asprintf(tctx,
+ 					   "%d unread bytes", ndr->data_size - ndr->offset));
+ 
+-	if (check_fn != NULL)
+-		return check_fn(tctx, ds);
+-	else
+-		return true;
++	if (check_fn != NULL) {
++		ret = check_fn(tctx, ds);
++	} else {
++		ret = true;
++	}
++
++	if (data->push_fn != NULL) {
++		DATA_BLOB outblob;
++		torture_assert_ndr_success(tctx, ndr_push_struct_blob(&outblob, ndr, ds, data->push_fn), "pushing");
++		torture_assert_data_blob_equal(tctx, outblob, data->data, "ndr push compare");
++	}
++
++	talloc_free(ndr);
++	return ret;
+ }
+ 
+-_PUBLIC_ struct torture_test *_torture_suite_add_ndr_pull_test(
+-					struct torture_suite *suite,
+-					const char *name, ndr_pull_flags_fn_t pull_fn,
+-					DATA_BLOB db,
+-					size_t struct_size,
+-					int ndr_flags,
+-					bool (*check_fn) (struct torture_context *ctx, void *data))
++_PUBLIC_ struct torture_test *_torture_suite_add_ndr_pullpush_test(
++	struct torture_suite *suite,
++	const char *name,
++	ndr_pull_flags_fn_t pull_fn,
++	ndr_push_flags_fn_t push_fn,
++	DATA_BLOB db,
++	size_t struct_size,
++	int ndr_flags,
++	bool (*check_fn) (struct torture_context *ctx, void *data))
+ {
+ 	struct torture_test *test;
+ 	struct torture_tcase *tcase;
+@@ -74,12 +88,15 @@ _PUBLIC_ struct torture_test *_torture_suite_add_ndr_pull_test(
+ 
+ 	test->name = talloc_strdup(test, name);
+ 	test->description = NULL;
+-	test->run = wrap_ndr_pull_test;
++	test->run = wrap_ndr_pullpush_test;
++
+ 	data = talloc(test, struct ndr_pull_test_data);
+ 	data->data = db;
+ 	data->ndr_flags = ndr_flags;
+ 	data->struct_size = struct_size;
+ 	data->pull_fn = pull_fn;
++	data->push_fn = push_fn;
++
+ 	test->data = data;
+ 	test->fn = check_fn;
+ 	test->dangerous = false;
+@@ -89,6 +106,7 @@ _PUBLIC_ struct torture_test *_torture_suite_add_ndr_pull_test(
+ 	return test;
+ }
+ 
++
+ static bool wrap_ndr_inout_pull_test(struct torture_context *tctx,
+ 				     struct torture_tcase *tcase,
+ 				     struct torture_test *test)
+diff --git a/source4/torture/ndr/ndr.h b/source4/torture/ndr/ndr.h
+index b248527..ee4db0a 100644
+--- a/source4/torture/ndr/ndr.h
++++ b/source4/torture/ndr/ndr.h
+@@ -24,9 +24,11 @@
+ #include "librpc/ndr/libndr.h"
+ #include "libcli/security/security.h"
+ 
+-_PUBLIC_ struct torture_test *_torture_suite_add_ndr_pull_test(
++_PUBLIC_ struct torture_test *_torture_suite_add_ndr_pullpush_test(
+ 					struct torture_suite *suite,
+-					const char *name, ndr_pull_flags_fn_t fn,
++					const char *name,
++					ndr_pull_flags_fn_t pull_fn,
++					ndr_push_flags_fn_t push_fn,
+ 					DATA_BLOB db,
+ 					size_t struct_size,
+ 					int ndr_flags,
+@@ -41,20 +43,27 @@ _PUBLIC_ struct torture_test *_torture_suite_add_ndr_pull_inout_test(
+ 					bool (*check_fn) (struct torture_context *ctx, void *data));
+ 
+ #define torture_suite_add_ndr_pull_test(suite,name,data,check_fn) \
+-		_torture_suite_add_ndr_pull_test(suite, #name, \
+-			 (ndr_pull_flags_fn_t)ndr_pull_ ## name, data_blob_talloc(suite, data, sizeof(data)), \
++		_torture_suite_add_ndr_pullpush_test(suite, #name, \
++			 (ndr_pull_flags_fn_t)ndr_pull_ ## name, NULL, data_blob_const(data, sizeof(data)), \
+ 			 sizeof(struct name), NDR_SCALARS|NDR_BUFFERS, (bool (*) (struct torture_context *, void *)) check_fn);
+ 
+ #define torture_suite_add_ndr_pull_fn_test(suite,name,data,flags,check_fn) \
+-		_torture_suite_add_ndr_pull_test(suite, #name "_" #flags, \
+-			 (ndr_pull_flags_fn_t)ndr_pull_ ## name, data_blob_talloc(suite, data, sizeof(data)), \
++		_torture_suite_add_ndr_pullpush_test(suite, #name "_" #flags, \
++			 (ndr_pull_flags_fn_t)ndr_pull_ ## name, NULL, data_blob_const(data, sizeof(data)), \
+ 			 sizeof(struct name), flags, (bool (*) (struct torture_context *, void *)) check_fn);
+ 
++#define torture_suite_add_ndr_pullpush_test(suite,name,data_blob,check_fn) \
++		_torture_suite_add_ndr_pullpush_test(suite, #name, \
++			 (ndr_pull_flags_fn_t)ndr_pull_ ## name, \
++			 (ndr_push_flags_fn_t)ndr_push_ ## name, \
++			 data_blob, \
++			 sizeof(struct name), NDR_SCALARS|NDR_BUFFERS, (bool (*) (struct torture_context *, void *)) check_fn);
++
+ #define torture_suite_add_ndr_pull_io_test(suite,name,data_in,data_out,check_fn_out) \
+ 		_torture_suite_add_ndr_pull_inout_test(suite, #name "_INOUT", \
+ 			 (ndr_pull_flags_fn_t)ndr_pull_ ## name, \
+-			 data_blob_talloc(suite, data_in, sizeof(data_in)), \
+-			 data_blob_talloc(suite, data_out, sizeof(data_out)), \
++			 data_blob_const(data_in, sizeof(data_in)), \
++			 data_blob_const(data_out, sizeof(data_out)), \
+ 			 sizeof(struct name), \
+ 			 (bool (*) (struct torture_context *, void *)) check_fn_out);
+ 
+-- 
+2.8.1
+
+
+From 07c59161786705a447cbda8555f64102d381e9c7 Mon Sep 17 00:00:00 2001
+From: Andrew Tridgell <tridge at samba.org>
+Date: Wed, 7 Sep 2011 15:36:22 +1000
+Subject: [PATCH 23/40] torture-ndr: fixed NDR tests for DFS blobs
+
+Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>
+---
+ source4/torture/ndr/dfsblob.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/source4/torture/ndr/dfsblob.c b/source4/torture/ndr/dfsblob.c
+index 23a32e1..8f62497 100644
+--- a/source4/torture/ndr/dfsblob.c
++++ b/source4/torture/ndr/dfsblob.c
+@@ -74,11 +74,11 @@ struct torture_suite *ndr_dfsblob_suite(TALLOC_CTX *ctx)
+ {
+ 	struct torture_suite *suite = torture_suite_create(ctx, "dfsblob");
+ 
+-	torture_suite_add_ndr_pull_fn_test(suite, dfs_GetDFSReferral_in, dfs_get_ref_in, NDR_IN, NULL);
++	torture_suite_add_ndr_pull_test(suite, dfs_GetDFSReferral_in, dfs_get_ref_in, NULL);
+ 
+-	torture_suite_add_ndr_pull_fn_test(suite, dfs_referral_resp, dfs_get_ref_out2, NDR_BUFFERS|NDR_SCALARS, NULL);
++	torture_suite_add_ndr_pull_test(suite, dfs_referral_resp, dfs_get_ref_out2, NULL);
+ 
+-	torture_suite_add_ndr_pull_fn_test(suite, dfs_referral_resp, dfs_get_ref_out, NDR_BUFFERS|NDR_SCALARS,dfs_referral_out_check);
++	torture_suite_add_ndr_pull_test(suite, dfs_referral_resp, dfs_get_ref_out,dfs_referral_out_check);
+ 
+ 	return suite;
+ }
+-- 
+2.8.1
+
+
+From 5d681fbe64867bd7581a0fb81c4222afd64e7d1b Mon Sep 17 00:00:00 2001
+From: Andrew Tridgell <tridge at samba.org>
+Date: Wed, 7 Sep 2011 15:36:38 +1000
+Subject: [PATCH 24/40] torture-ndr: fixed NDR tests for NBT blobs
+
+Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>
+---
+ source4/torture/ndr/nbt.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/source4/torture/ndr/nbt.c b/source4/torture/ndr/nbt.c
+index 8955f4d..5c35e7a 100644
+--- a/source4/torture/ndr/nbt.c
++++ b/source4/torture/ndr/nbt.c
+@@ -62,9 +62,9 @@ struct torture_suite *ndr_nbt_suite(TALLOC_CTX *ctx)
+ {
+ 	struct torture_suite *suite = torture_suite_create(ctx, "nbt");
+ 
+-	torture_suite_add_ndr_pull_fn_test(suite, nbt_netlogon_packet, netlogon_logon_request_req_data, NDR_IN, netlogon_logon_request_req_check);
++	torture_suite_add_ndr_pull_test(suite, nbt_netlogon_packet, netlogon_logon_request_req_data, netlogon_logon_request_req_check);
+ 
+-	torture_suite_add_ndr_pull_fn_test(suite, nbt_netlogon_response2, netlogon_logon_request_resp_data, NDR_IN, netlogon_logon_request_resp_check);
++	torture_suite_add_ndr_pull_test(suite, nbt_netlogon_response2, netlogon_logon_request_resp_data, netlogon_logon_request_resp_check);
+ 
+ 	return suite;
+ }
+-- 
+2.8.1
+
+
+From e5606230a49cec5c87332feb85eb105fa23a6894 Mon Sep 17 00:00:00 2001
+From: Andrew Tridgell <tridge at samba.org>
+Date: Wed, 7 Sep 2011 15:36:57 +1000
+Subject: [PATCH 25/40] torture-ndr: fixed NDR tests for NTLMSSP blobs
+
+Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>
+---
+ source4/torture/ndr/ntlmssp.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/source4/torture/ndr/ntlmssp.c b/source4/torture/ndr/ntlmssp.c
+index b139fdf..038b360 100644
+--- a/source4/torture/ndr/ntlmssp.c
++++ b/source4/torture/ndr/ntlmssp.c
+@@ -111,9 +111,10 @@ struct torture_suite *ndr_ntlmssp_suite(TALLOC_CTX *ctx)
+ {
+ 	struct torture_suite *suite = torture_suite_create(ctx, "ntlmssp");
+ 
+-	torture_suite_add_ndr_pull_fn_test(suite, NEGOTIATE_MESSAGE, ntlmssp_NEGOTIATE_MESSAGE_data, NDR_IN, ntlmssp_NEGOTIATE_MESSAGE_check);
+-	/* torture_suite_add_ndr_pull_fn_test(suite, CHALLENGE_MESSAGE, ntlmssp_CHALLENGE_MESSAGE_data, NDR_IN, ntlmssp_CHALLENGE_MESSAGE_check);
+-	torture_suite_add_ndr_pull_fn_test(suite, AUTHENTICATE_MESSAGE, ntlmssp_AUTHENTICATE_MESSAGE_data, NDR_IN, ntlmssp_AUTHENTICATE_MESSAGE_check); */
+-
++	torture_suite_add_ndr_pull_test(suite, NEGOTIATE_MESSAGE, ntlmssp_NEGOTIATE_MESSAGE_data, ntlmssp_NEGOTIATE_MESSAGE_check);
++#if 0
++	torture_suite_add_ndr_pull_test(suite, CHALLENGE_MESSAGE, ntlmssp_CHALLENGE_MESSAGE_data, ntlmssp_CHALLENGE_MESSAGE_check);
++	torture_suite_add_ndr_pull_test(suite, AUTHENTICATE_MESSAGE, ntlmssp_AUTHENTICATE_MESSAGE_data, ntlmssp_AUTHENTICATE_MESSAGE_check);
++#endif
+ 	return suite;
+ }
+-- 
+2.8.1
+
+
+From 2bea7253c1916cc9cf6375d92bcbacff9621d917 Mon Sep 17 00:00:00 2001
+From: Andrew Tridgell <tridge at samba.org>
+Date: Wed, 7 Sep 2011 15:37:22 +1000
+Subject: [PATCH 26/40] torture-drs: fixed NDR tests for DRS blobs
+
+this also adds new tests for trustAuthInOutBlob blobs
+
+Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>
+---
+ source4/torture/ndr/drsblobs.c | 44 ++++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 42 insertions(+), 2 deletions(-)
+
+diff --git a/source4/torture/ndr/drsblobs.c b/source4/torture/ndr/drsblobs.c
+index ca3fa1d..d127819 100644
+--- a/source4/torture/ndr/drsblobs.c
++++ b/source4/torture/ndr/drsblobs.c
+@@ -115,6 +115,34 @@ static const uint8_t trust_domain_passwords_in[] = {
+ 	0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00
+ };
+ 
++/* these are taken from the trust objects of a w2k8r2 forest, with a
++ * trust relationship between the forest parent and a child domain
++ */
++static const char *trustAuthIncoming =
++"AQAAAAwAAAAcAQAASuQ+RXJdzAECAAAAAAEAAMOWL6UVfVKiJOUsGcT03H"
++"jHxr2ACsMMOV5ynM617Tp7idNC+c4egdqk4S9YEpvR2YvHmdZdymL6F7QKm8OkXazYZF2r/gZ/bI+"
++"jkWbsn4O8qyAc3OUKQRZwBbf+lxBW+vM4O3ZpUjz5BSKCcFQgM+MY91yVU8Nji3HNnvGnDquobFAZ"
++"hxjL+S1l5+QZgkfyfv5mQScGRbU1Lar1xg9G3JznUb7S6pvrBO2nwK8g+KZBfJy5UeULigDH4IWo/"
++"JmtaEGkKE2uiKIjdsEQd/uwnkouW26XzRc0ulfJnPFftGnT9KIcShPf7DLj/tstmQAAceRMFHJTY3"
++"PmxoowoK8HUyBK5D5Fcl3MAQIAAAAAAQAAw5YvpRV9UqIk5SwZxPTceMfGvYAKwww5XnKczrXtOnu"
++"J00L5zh6B2qThL1gSm9HZi8eZ1l3KYvoXtAqbw6RdrNhkXav+Bn9sj6ORZuyfg7yrIBzc5QpBFnAF"
++"t/6XEFb68zg7dmlSPPkFIoJwVCAz4xj3XJVTw2OLcc2e8acOq6hsUBmHGMv5LWXn5BmCR/J+/mZBJ"
++"wZFtTUtqvXGD0bcnOdRvtLqm+sE7afAryD4pkF8nLlR5QuKAMfghaj8ma1oQaQoTa6IoiN2wRB3+7"
++"CeSi5bbpfNFzS6V8mc8V+0adP0ohxKE9/sMuP+2y2ZAABx5EwUclNjc+bGijCgrwdTIA==";
++
++static const char *trustAuthOutgoing =
++"AQAAAAwAAAAcAQAASuQ+RXJdzAECAAAAAAEAAMOWL6UVfVKiJOUsGcT03H"
++"jHxr2ACsMMOV5ynM617Tp7idNC+c4egdqk4S9YEpvR2YvHmdZdymL6F7QKm8OkXazYZF2r/gZ/bI+"
++"jkWbsn4O8qyAc3OUKQRZwBbf+lxBW+vM4O3ZpUjz5BSKCcFQgM+MY91yVU8Nji3HNnvGnDquobFAZ"
++"hxjL+S1l5+QZgkfyfv5mQScGRbU1Lar1xg9G3JznUb7S6pvrBO2nwK8g+KZBfJy5UeULigDH4IWo/"
++"JmtaEGkKE2uiKIjdsEQd/uwnkouW26XzRc0ulfJnPFftGnT9KIcShPf7DLj/tstmQAAceRMFHJTY3"
++"PmxoowoK8HUyBK5D5Fcl3MAQIAAAAAAQAAw5YvpRV9UqIk5SwZxPTceMfGvYAKwww5XnKczrXtOnu"
++"J00L5zh6B2qThL1gSm9HZi8eZ1l3KYvoXtAqbw6RdrNhkXav+Bn9sj6ORZuyfg7yrIBzc5QpBFnAF"
++"t/6XEFb68zg7dmlSPPkFIoJwVCAz4xj3XJVTw2OLcc2e8acOq6hsUBmHGMv5LWXn5BmCR/J+/mZBJ"
++"wZFtTUtqvXGD0bcnOdRvtLqm+sE7afAryD4pkF8nLlR5QuKAMfghaj8ma1oQaQoTa6IoiN2wRB3+7"
++"CeSi5bbpfNFzS6V8mc8V+0adP0ohxKE9/sMuP+2y2ZAABx5EwUclNjc+bGijCgrwdTIA==";
++
++
+ static bool trust_domain_passwords_check_in(struct torture_context *tctx,
+ 					    struct trustDomainPasswords *r)
+ {
+@@ -154,8 +182,20 @@ struct torture_suite *ndr_drsblobs_suite(TALLOC_CTX *ctx)
+ {
+ 	struct torture_suite *suite = torture_suite_create(ctx, "drsblobs");
+ 
+-	torture_suite_add_ndr_pull_fn_test(suite, ForestTrustInfo, forest_trust_info_data_out, NDR_IN, forest_trust_info_check_out);
+-	torture_suite_add_ndr_pull_fn_test(suite, trustDomainPasswords, trust_domain_passwords_in, NDR_IN, trust_domain_passwords_check_in);
++	torture_suite_add_ndr_pull_test(suite, ForestTrustInfo, forest_trust_info_data_out, forest_trust_info_check_out);
++	torture_suite_add_ndr_pull_test(suite, trustDomainPasswords, trust_domain_passwords_in, trust_domain_passwords_check_in);
++
++#if 0
++	torture_suite_add_ndr_pullpush_test(suite,
++					    trustAuthInOutBlob,
++					    base64_decode_data_blob_talloc(suite, trustAuthIncoming),
++					    NULL);
++
++	torture_suite_add_ndr_pullpush_test(suite,
++					    trustAuthInOutBlob,
++					    base64_decode_data_blob_talloc(suite, trustAuthOutgoing),
++					    NULL);
++#endif
+ 
+ 	return suite;
+ }
+-- 
+2.8.1
+
+
+From d9f8f02cf06cc1a1235de1b23b0ee9368a557a36 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd at samba.org>
+Date: Tue, 15 Jan 2013 17:04:08 +0100
+Subject: [PATCH 27/40] s4-torture: allow to do ndr tests with flags, not only
+ ndr_flags.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Guenther
+
+Signed-off-by: Günther Deschner <gd at samba.org>
+Reviewed-by: Andreas Schneider <asn at samba.org>
+---
+ source4/torture/ndr/ndr.c |  5 +++++
+ source4/torture/ndr/ndr.h | 12 +++++++++---
+ 2 files changed, 14 insertions(+), 3 deletions(-)
+
+diff --git a/source4/torture/ndr/ndr.c b/source4/torture/ndr/ndr.c
+index 5df25b0..2a87d14 100644
+--- a/source4/torture/ndr/ndr.c
++++ b/source4/torture/ndr/ndr.c
+@@ -31,6 +31,7 @@ struct ndr_pull_test_data {
+ 	ndr_pull_flags_fn_t pull_fn;
+ 	ndr_push_flags_fn_t push_fn;
+ 	int ndr_flags;
++	int flags;
+ };
+ 
+ static bool wrap_ndr_pullpush_test(struct torture_context *tctx,
+@@ -43,6 +44,8 @@ static bool wrap_ndr_pullpush_test(struct torture_context *tctx,
+ 	void *ds = talloc_zero_size(ndr, data->struct_size);
+ 	bool ret;
+ 
++	ndr->flags |= data->flags;
++
+ 	ndr->flags |= LIBNDR_FLAG_REF_ALLOC;
+ 
+ 	torture_assert_ndr_success(tctx, data->pull_fn(ndr, data->ndr_flags, ds),
+@@ -76,6 +79,7 @@ _PUBLIC_ struct torture_test *_torture_suite_add_ndr_pullpush_test(
+ 	DATA_BLOB db,
+ 	size_t struct_size,
+ 	int ndr_flags,
++	int flags,
+ 	bool (*check_fn) (struct torture_context *ctx, void *data))
+ {
+ 	struct torture_test *test;
+@@ -93,6 +97,7 @@ _PUBLIC_ struct torture_test *_torture_suite_add_ndr_pullpush_test(
+ 	data = talloc(test, struct ndr_pull_test_data);
+ 	data->data = db;
+ 	data->ndr_flags = ndr_flags;
++	data->flags = flags;
+ 	data->struct_size = struct_size;
+ 	data->pull_fn = pull_fn;
+ 	data->push_fn = push_fn;
+diff --git a/source4/torture/ndr/ndr.h b/source4/torture/ndr/ndr.h
+index ee4db0a..068d5f6 100644
+--- a/source4/torture/ndr/ndr.h
++++ b/source4/torture/ndr/ndr.h
+@@ -32,6 +32,7 @@ _PUBLIC_ struct torture_test *_torture_suite_add_ndr_pullpush_test(
+ 					DATA_BLOB db,
+ 					size_t struct_size,
+ 					int ndr_flags,
++					int flags,
+ 					bool (*check_fn) (struct torture_context *, void *data));
+ 
+ _PUBLIC_ struct torture_test *_torture_suite_add_ndr_pull_inout_test(
+@@ -45,19 +46,24 @@ _PUBLIC_ struct torture_test *_torture_suite_add_ndr_pull_inout_test(
+ #define torture_suite_add_ndr_pull_test(suite,name,data,check_fn) \
+ 		_torture_suite_add_ndr_pullpush_test(suite, #name, \
+ 			 (ndr_pull_flags_fn_t)ndr_pull_ ## name, NULL, data_blob_const(data, sizeof(data)), \
+-			 sizeof(struct name), NDR_SCALARS|NDR_BUFFERS, (bool (*) (struct torture_context *, void *)) check_fn);
++			 sizeof(struct name), NDR_SCALARS|NDR_BUFFERS, 0, (bool (*) (struct torture_context *, void *)) check_fn);
+ 
+ #define torture_suite_add_ndr_pull_fn_test(suite,name,data,flags,check_fn) \
+ 		_torture_suite_add_ndr_pullpush_test(suite, #name "_" #flags, \
+ 			 (ndr_pull_flags_fn_t)ndr_pull_ ## name, NULL, data_blob_const(data, sizeof(data)), \
+-			 sizeof(struct name), flags, (bool (*) (struct torture_context *, void *)) check_fn);
++			 sizeof(struct name), flags, 0, (bool (*) (struct torture_context *, void *)) check_fn);
++
++#define torture_suite_add_ndr_pull_fn_test_flags(suite,name,data,flags,flags2,check_fn) \
++		_torture_suite_add_ndr_pullpush_test(suite, #name "_" #flags "_" #flags2, \
++			 (ndr_pull_flags_fn_t)ndr_pull_ ## name, NULL, data_blob_const(data, sizeof(data)), \
++			 sizeof(struct name), flags, flags2, (bool (*) (struct torture_context *, void *)) check_fn);
+ 
+ #define torture_suite_add_ndr_pullpush_test(suite,name,data_blob,check_fn) \
+ 		_torture_suite_add_ndr_pullpush_test(suite, #name, \
+ 			 (ndr_pull_flags_fn_t)ndr_pull_ ## name, \
+ 			 (ndr_push_flags_fn_t)ndr_push_ ## name, \
+ 			 data_blob, \
+-			 sizeof(struct name), NDR_SCALARS|NDR_BUFFERS, (bool (*) (struct torture_context *, void *)) check_fn);
++			 sizeof(struct name), NDR_SCALARS|NDR_BUFFERS, 0, (bool (*) (struct torture_context *, void *)) check_fn);
+ 
+ #define torture_suite_add_ndr_pull_io_test(suite,name,data_in,data_out,check_fn_out) \
+ 		_torture_suite_add_ndr_pull_inout_test(suite, #name "_INOUT", \
+-- 
+2.8.1
+
+
+From 6375a7a93f9bee57b1bdebf4348598b819aa7c3f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd at samba.org>
+Date: Fri, 1 Feb 2013 17:45:02 +0100
+Subject: [PATCH 28/40] s4-torture: make sure to deal with the highest relative
+ pointer offset correctly.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Guenther
+
+Signed-off-by: Günther Deschner <gd at samba.org>
+Reviewed-by: Stefan Metzmacher <metze at samba.org>
+---
+ source4/torture/ndr/ndr.c | 32 ++++++++++++++++++++++++++------
+ 1 file changed, 26 insertions(+), 6 deletions(-)
+
+diff --git a/source4/torture/ndr/ndr.c b/source4/torture/ndr/ndr.c
+index 2a87d14..8cdc4e7 100644
+--- a/source4/torture/ndr/ndr.c
++++ b/source4/torture/ndr/ndr.c
+@@ -43,6 +43,7 @@ static bool wrap_ndr_pullpush_test(struct torture_context *tctx,
+ 	struct ndr_pull *ndr = ndr_pull_init_blob(&(data->data), tctx);
+ 	void *ds = talloc_zero_size(ndr, data->struct_size);
+ 	bool ret;
++	uint32_t highest_ofs;
+ 
+ 	ndr->flags |= data->flags;
+ 
+@@ -51,9 +52,15 @@ static bool wrap_ndr_pullpush_test(struct torture_context *tctx,
+ 	torture_assert_ndr_success(tctx, data->pull_fn(ndr, data->ndr_flags, ds),
+ 				   "pulling");
+ 
+-	torture_assert(tctx, ndr->offset == ndr->data_size,
++	if (ndr->offset > ndr->relative_highest_offset) {
++		highest_ofs = ndr->offset;
++	} else {
++		highest_ofs = ndr->relative_highest_offset;
++	}
++
++	torture_assert(tctx, highest_ofs == ndr->data_size,
+ 				   talloc_asprintf(tctx,
+-					   "%d unread bytes", ndr->data_size - ndr->offset));
++					   "%d unread bytes", ndr->data_size - highest_ofs));
+ 
+ 	if (check_fn != NULL) {
+ 		ret = check_fn(tctx, ds);
+@@ -120,6 +127,7 @@ static bool wrap_ndr_inout_pull_test(struct torture_context *tctx,
+ 	const struct ndr_pull_test_data *data = (const struct ndr_pull_test_data *)test->data;
+ 	void *ds = talloc_zero_size(tctx, data->struct_size);
+ 	struct ndr_pull *ndr;
++	uint32_t highest_ofs;
+ 
+ 	/* handle NDR_IN context */
+ 
+@@ -132,8 +140,14 @@ static bool wrap_ndr_inout_pull_test(struct torture_context *tctx,
+ 		data->pull_fn(ndr, NDR_IN, ds),
+ 		"ndr pull of context failed");
+ 
+-	torture_assert(tctx, ndr->offset == ndr->data_size,
+-		talloc_asprintf(tctx, "%d unread bytes", ndr->data_size - ndr->offset));
++	if (ndr->offset > ndr->relative_highest_offset) {
++		highest_ofs = ndr->offset;
++	} else {
++		highest_ofs = ndr->relative_highest_offset;
++	}
++
++	torture_assert(tctx, highest_ofs == ndr->data_size,
++		talloc_asprintf(tctx, "%d unread bytes", ndr->data_size - highest_ofs));
+ 
+ 	talloc_free(ndr);
+ 
+@@ -148,8 +162,14 @@ static bool wrap_ndr_inout_pull_test(struct torture_context *tctx,
+ 		data->pull_fn(ndr, NDR_OUT, ds),
+ 		"ndr pull failed");
+ 
+-	torture_assert(tctx, ndr->offset == ndr->data_size,
+-		talloc_asprintf(tctx, "%d unread bytes", ndr->data_size - ndr->offset));
++	if (ndr->offset > ndr->relative_highest_offset) {
++		highest_ofs = ndr->offset;
++	} else {
++		highest_ofs = ndr->relative_highest_offset;
++	}
++
++	torture_assert(tctx, highest_ofs == ndr->data_size,
++		talloc_asprintf(tctx, "%d unread bytes", ndr->data_size - highest_ofs));
+ 
+ 	talloc_free(ndr);
+ 
+-- 
+2.8.1
+
+
+From e06603fa6ddac5e846711c8503616ee5e1978fb9 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Sat, 11 Jan 2014 11:52:37 +0100
+Subject: [PATCH 29/40] dcerpc.idl: add a bitmap for dcerpc_pfc_flags
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Guenther Deschner <gd at samba.org>
+(cherry picked from commit e6fc98989a4c0d184ef310360d42741f61baa7db)
+(cherry picked from commit f1489a994cf0666c74d8b80314a3b9e17045c463)
+---
+ librpc/idl/dcerpc.idl | 25 ++++++++++++++++---------
+ 1 file changed, 16 insertions(+), 9 deletions(-)
+
+diff --git a/librpc/idl/dcerpc.idl b/librpc/idl/dcerpc.idl
+index 6c4e4c1..4f99021 100644
+--- a/librpc/idl/dcerpc.idl
++++ b/librpc/idl/dcerpc.idl
+@@ -455,14 +455,21 @@ interface dcerpc
+ 	} dcerpc_payload;
+ 
+ 	/* pfc_flags values */
+-	const uint8 DCERPC_PFC_FLAG_FIRST		= 0x01; /* First fragment */
+-	const uint8 DCERPC_PFC_FLAG_LAST		= 0x02; /* Last fragment */
+-	const uint8 DCERPC_PFC_FLAG_PENDING_CANCEL	= 0x04; /* Cancel was pending at sender */
+-	const uint8 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN	= DCERPC_PFC_FLAG_PENDING_CANCEL; /* depends on the pdu type */
+-	const uint8 DCERPC_PFC_FLAG_CONC_MPX		= 0x10; /* supports concurrent multiplexing of a single connection. */
+-	const uint8 DCERPC_PFC_FLAG_DID_NOT_EXECUTE	= 0x20; /* on a fault it means the server hasn't done anything */
+-	const uint8 DCERPC_PFC_FLAG_MAYBE		= 0x40; /* `maybe' call semantics requested */
+-	const uint8 DCERPC_PFC_FLAG_OBJECT_UUID		= 0x80; /* on valid guid is in the optional object field */
++	typedef [bitmap8bit] bitmap {
++		DCERPC_PFC_FLAG_FIRST		= 0x01, /* First fragment */
++		DCERPC_PFC_FLAG_LAST		= 0x02, /* Last fragment */
++		DCERPC_PFC_FLAG_PENDING_CANCEL_OR_HDR_SIGNING = 0x04, /* depends on the pdu type */
++		DCERPC_PFC_FLAG_CONC_MPX	= 0x10, /* supports concurrent multiplexing of a single connection. */
++		DCERPC_PFC_FLAG_DID_NOT_EXECUTE	= 0x20, /* on a fault it means the server hasn't done anything */
++		DCERPC_PFC_FLAG_MAYBE		= 0x40, /* `maybe' call semantics requested */
++		DCERPC_PFC_FLAG_OBJECT_UUID	= 0x80 /* on valid guid is in the optional object field */
++	} dcerpc_pfc_flags;
++
++	/* Cancel was pending at sender */
++	const int DCERPC_PFC_FLAG_PENDING_CANCEL =
++		DCERPC_PFC_FLAG_PENDING_CANCEL_OR_HDR_SIGNING;
++	const ist DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN =
++		DCERPC_PFC_FLAG_PENDING_CANCEL_OR_HDR_SIGNING;
+ 
+ 	/* these offsets are needed by the signing code */
+ 	const uint8 DCERPC_PFC_OFFSET      =  3;
+@@ -478,7 +485,7 @@ interface dcerpc
+ 		uint8 rpc_vers;	        /* RPC version */
+ 		uint8 rpc_vers_minor;   /* Minor version */
+ 		dcerpc_pkt_type ptype;  /* Packet type */
+-		uint8 pfc_flags;        /* Fragmentation flags */
++		dcerpc_pfc_flags pfc_flags; /* Fragmentation flags */
+ 		uint8 drep[4];	        /* NDR data representation */
+ 		uint16 frag_length;     /* Total length of fragment */
+ 		uint16 auth_length;     /* authenticator length */
+-- 
+2.8.1
+
+
+From 67e2b1dca0cf65aa6bb24ed35e2fb008a5212a20 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Sun, 15 Sep 2013 16:43:22 +0200
+Subject: [PATCH 30/40] dcerpc.idl: add DCERPC_NCACN_PAYLOAD_OFFSET
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Michael Adam <obnox at samba.org>
+(cherry picked from commit cd4643730552674b2a10a37665eeac13c58940a8)
+(cherry picked from commit 8b4f608d2bec33d6bc48574b45f28fab891ec0c0)
+---
+ librpc/idl/dcerpc.idl | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/librpc/idl/dcerpc.idl b/librpc/idl/dcerpc.idl
+index 4f99021..75ef2ec 100644
+--- a/librpc/idl/dcerpc.idl
++++ b/librpc/idl/dcerpc.idl
+@@ -477,6 +477,7 @@ interface dcerpc
+ 	const uint8 DCERPC_FRAG_LEN_OFFSET =  8;
+ 	const uint8 DCERPC_AUTH_LEN_OFFSET = 10;
+ 	const uint8 DCERPC_CALL_ID_OFFSET  = 12;
++	const uint8 DCERPC_NCACN_PAYLOAD_OFFSET = 16;
+ 
+ 	/* little-endian flag */
+ 	const uint8 DCERPC_DREP_LE  = 0x10;
+-- 
+2.8.1
+
+
+From 610bdbc90cf2db843d1f45ce6d9f37b3ebf38ae1 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze at samba.org>
+Date: Mon, 13 Jan 2014 10:16:40 +0100
+Subject: [PATCH 31/40] s3:rpcclient: add support for DCERPC_AUTH_LEVEL_CONNECT
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Guenther Deschner <gd at samba.org>
+---
+ source3/rpcclient/rpcclient.c | 23 +++++++++++------------
+ 1 file changed, 11 insertions(+), 12 deletions(-)
+
+diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c
+index c2f3e4c..949e14c 100644
+--- a/source3/rpcclient/rpcclient.c
++++ b/source3/rpcclient/rpcclient.c
+@@ -1031,6 +1031,10 @@ out_free:
+ 		binding->transport = NCACN_NP;
+ 	}
+ 
++	if (binding->flags & DCERPC_CONNECT) {
++		pipe_default_auth_level = DCERPC_AUTH_LEVEL_CONNECT;
++		pipe_default_auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
++	}
+ 	if (binding->flags & DCERPC_SIGN) {
+ 		pipe_default_auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
+ 		pipe_default_auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
+@@ -1044,12 +1048,6 @@ out_free:
+ 		pipe_default_auth_spnego_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP;
+ 	}
+ 	if (binding->flags & DCERPC_AUTH_NTLM) {
+-		/* If neither Integrity or Privacy are requested then
+-		 * Use just Connect level */
+-		if (pipe_default_auth_level == DCERPC_AUTH_LEVEL_NONE) {
+-			pipe_default_auth_level = DCERPC_AUTH_LEVEL_CONNECT;
+-		}
+-
+ 		if (pipe_default_auth_type == DCERPC_AUTH_TYPE_SPNEGO) {
+ 			pipe_default_auth_spnego_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP;
+ 		} else {
+@@ -1057,18 +1055,19 @@ out_free:
+ 		}
+ 	}
+ 	if (binding->flags & DCERPC_AUTH_KRB5) {
+-		/* If neither Integrity or Privacy are requested then
+-		 * Use just Connect level */
+-		if (pipe_default_auth_level == DCERPC_AUTH_LEVEL_NONE) {
+-			pipe_default_auth_level = DCERPC_AUTH_LEVEL_CONNECT;
+-		}
+-
+ 		if (pipe_default_auth_type == DCERPC_AUTH_TYPE_SPNEGO) {
+ 			pipe_default_auth_spnego_type = PIPE_AUTH_TYPE_SPNEGO_KRB5;
+ 		} else {
+ 			pipe_default_auth_type = DCERPC_AUTH_TYPE_KRB5;
+ 		}
+ 	}
++	if (pipe_default_auth_type != DCERPC_AUTH_TYPE_NONE) {
++		/* If neither Integrity or Privacy are requested then
++		 * Use just Connect level */
++		if (pipe_default_auth_level == DCERPC_AUTH_LEVEL_NONE) {
++			pipe_default_auth_level = DCERPC_AUTH_LEVEL_CONNECT;
++		}
++	}
+ 
+ 	if (get_cmdline_auth_info_use_kerberos(rpcclient_auth_info)) {
+ 		flags |= CLI_FULL_CONNECTION_USE_KERBEROS |
+-- 
+2.8.1
+
+
+From edba19cd2d347d1bcfc527f2bda4f6a6f660bfff Mon Sep 17 00:00:00 2001
+From: Andreas Schneider <asn at samba.org>
+Date: Mon, 2 Jan 2012 18:54:47 +0100
+Subject: [PATCH 32/40] s3-rpc_client: Add capabilities check for AES encrypted
+ connections.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Günther Deschner <gd at samba.org>
+---
+ source3/Makefile.in           |  32 ++++++---
+ source3/rpc_client/cli_pipe.c | 159 +++++++++++++++++++++++++++++++++++++++++-
+ 2 files changed, 182 insertions(+), 9 deletions(-)
+
+diff --git a/source3/Makefile.in b/source3/Makefile.in
+index d39cfee..2668a6b 100644
+--- a/source3/Makefile.in
++++ b/source3/Makefile.in
+@@ -988,7 +988,9 @@ SWAT_OBJ = $(SWAT_OBJ1) $(PARAM_OBJ) $(PRINTING_OBJ) $(PRINTBASE_OBJ) $(LIBSMB_O
+ 	   $(POPT_LIB_OBJ) $(SMBLDAP_OBJ) $(LIBMSRPC_GEN_OBJ) $(LIBMSRPC_OBJ) \
+            $(PASSCHANGE_OBJ) $(FNAME_UTIL_OBJ) \
+ 	   $(LIBCLI_SAMR_OBJ) \
+-	   rpc_client/init_lsa.o
++	   $(LIBCLI_NETLOGON_OBJ) \
++	   rpc_client/init_lsa.o \
++	   rpc_client/init_netlogon.o
+ 
+ STATUS_OBJ = utils/status.o utils/status_profile.o \
+ 	     $(LOCKING_OBJ) $(PARAM_OBJ) \
+@@ -1004,7 +1006,9 @@ SMBTREE_OBJ = utils/smbtree.o $(PARAM_OBJ) \
+ 	     $(PASSDB_OBJ) $(SMBLDAP_OBJ) $(GROUPDB_OBJ) \
+ 	     $(LIBMSRPC_GEN_OBJ) \
+ 	     $(LIBMSRPC_OBJ) \
+-	     $(LIBCLI_SRVSVC_OBJ)
++	     $(LIBCLI_SRVSVC_OBJ) \
++	     $(LIBCLI_NETLOGON_OBJ) \
++	     rpc_client/init_netlogon.o
+ 
+ TESTPARM_OBJ = utils/testparm.o \
+                $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \
+@@ -1026,7 +1030,9 @@ SMBPASSWD_OBJ = utils/smbpasswd.o $(PASSWD_UTIL_OBJ) $(PASSCHANGE_OBJ) \
+ 		$(POPT_LIB_OBJ) $(SMBLDAP_OBJ) \
+ 		$(LIBMSRPC_GEN_OBJ) $(LIBMSRPC_OBJ) \
+ 		$(LIBCLI_SAMR_OBJ) \
+-		rpc_client/init_lsa.o
++		$(LIBCLI_NETLOGON_OBJ) \
++		rpc_client/init_lsa.o \
++		rpc_client/init_netlogon.o
+ 
+ PDBEDIT_OBJ = utils/pdbedit.o $(PASSWD_UTIL_OBJ) $(PARAM_OBJ) $(PASSDB_OBJ) \
+ 		$(LIBSAMBA_OBJ) $(LIBTSOCKET_OBJ) \
+@@ -1099,7 +1105,9 @@ LIBSMBCLIENT_OBJ1 = $(LIBSMBCLIENT_OBJ0) \
+ 		    $(LIBMSRPC_OBJ) $(LIBMSRPC_GEN_OBJ) \
+ 		    $(PASSDB_OBJ) $(SMBLDAP_OBJ) $(GROUPDB_OBJ) \
+ 		    $(LIBCLI_SRVSVC_OBJ) \
+-		    $(LIBCLI_LSA_OBJ)
++		    $(LIBCLI_LSA_OBJ) \
++		    $(LIBCLI_NETLOGON_OBJ) \
++		    rpc_client/init_netlogon.o
+ 
+ LIBSMBCLIENT_OBJ = $(LIBSMBCLIENT_OBJ1)
+ 
+@@ -1122,7 +1130,9 @@ CLIENT_OBJ = $(CLIENT_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) \
+              $(READLINE_OBJ) $(POPT_LIB_OBJ) \
+              $(PASSDB_OBJ) $(SMBLDAP_OBJ) $(GROUPDB_OBJ) \
+ 	     $(DISPLAY_SEC_OBJ) \
+-	     $(LIBCLI_SRVSVC_OBJ)
++	     $(LIBCLI_SRVSVC_OBJ) \
++	     $(LIBCLI_NETLOGON_OBJ) \
++	     rpc_client/init_netlogon.o
+ 
+ LIBSMBCONF_OBJ = ../lib/smbconf/smbconf.o \
+ 		 ../lib/smbconf/smbconf_util.o \
+@@ -1234,7 +1244,9 @@ SMBTORTURE_OBJ = $(SMBTORTURE_OBJ1) $(PARAM_OBJ) $(TLDAP_OBJ) \
+ 	@LIBWBCLIENT_STATIC@ \
+         torture/wbc_async.o \
+         ../nsswitch/wb_reqtrans.o \
+-	$(LIBMSRPC_OBJ) $(LIBMSRPC_GEN_OBJ) $(LIBCLI_ECHO_OBJ)
++	$(LIBMSRPC_OBJ) $(LIBMSRPC_GEN_OBJ) $(LIBCLI_ECHO_OBJ) \
++	$(LIBCLI_NETLOGON_OBJ) rpc_client/init_netlogon.o
++
+ 
+ MASKTEST_OBJ = torture/masktest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \
+                  $(LIB_NONSMBD_OBJ) \
+@@ -1269,14 +1281,18 @@ SMBCACLS_OBJ = utils/smbcacls.o $(PARAM_OBJ) $(LIBSMB_OBJ) \
+ 		$(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) \
+ 		$(PASSDB_OBJ) $(GROUPDB_OBJ) $(LIBMSRPC_OBJ) $(LIBMSRPC_GEN_OBJ) \
+ 		$(POPT_LIB_OBJ) $(SMBLDAP_OBJ) \
+-		$(LIBCLI_LSA_OBJ)
++		$(LIBCLI_LSA_OBJ) \
++		$(LIBCLI_NETLOGON_OBJ) \
++		rpc_client/init_netlogon.o
+ 
+ SMBCQUOTAS_OBJ = utils/smbcquotas.o $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \
+ 		$(PARAM_OBJ) \
+ 		$(LIB_NONSMBD_OBJ) \
+ 		$(LIBMSRPC_OBJ) $(LIBMSRPC_GEN_OBJ) $(POPT_LIB_OBJ) \
+ 		$(PASSDB_OBJ) $(SMBLDAP_OBJ) $(GROUPDB_OBJ) \
+-		$(LIBCLI_LSA_OBJ)
++		$(LIBCLI_LSA_OBJ) \
++		$(LIBCLI_NETLOGON_OBJ) \
++		rpc_client/init_netlogon.o
+ 
+ EVTLOGADM_OBJ0	= utils/eventlogadm.o
+ 
+diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c
+index 5bf4549..6663656 100644
+--- a/source3/rpc_client/cli_pipe.c
++++ b/source3/rpc_client/cli_pipe.c
+@@ -28,6 +28,7 @@
+ #include "../libcli/auth/ntlmssp.h"
+ #include "ntlmssp_wrap.h"
+ #include "librpc/gen_ndr/ndr_dcerpc.h"
++#include "librpc/gen_ndr/ndr_netlogon_c.h"
+ #include "librpc/rpc/dcerpc.h"
+ #include "librpc/crypto/gse.h"
+ #include "librpc/crypto/spnego.h"
+@@ -1826,9 +1827,15 @@ struct rpc_pipe_bind_state {
+ 	DATA_BLOB rpc_out;
+ 	bool auth3;
+ 	uint32_t rpc_call_id;
++	struct netr_Authenticator auth;
++	struct netr_Authenticator return_auth;
++	struct netlogon_creds_CredentialState *creds;
++	union netr_Capabilities capabilities;
++	struct netr_LogonGetCapabilities r;
+ };
+ 
+ static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
++static void rpc_pipe_bind_step_two_trigger(struct tevent_req *req);
+ static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
+ 				   struct rpc_pipe_bind_state *state,
+ 				   DATA_BLOB *credentials);
+@@ -1932,11 +1939,14 @@ static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
+ 
+ 	case DCERPC_AUTH_TYPE_NONE:
+ 	case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
+-	case DCERPC_AUTH_TYPE_SCHANNEL:
+ 		/* Bind complete. */
+ 		tevent_req_done(req);
+ 		return;
+ 
++	case DCERPC_AUTH_TYPE_SCHANNEL:
++		rpc_pipe_bind_step_two_trigger(req);
++		return;
++
+ 	case DCERPC_AUTH_TYPE_NTLMSSP:
+ 	case DCERPC_AUTH_TYPE_SPNEGO:
+ 	case DCERPC_AUTH_TYPE_KRB5:
+@@ -2048,6 +2058,153 @@ err_out:
+ 	tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
+ }
+ 
++static void rpc_pipe_bind_step_two_done(struct tevent_req *subreq);
++
++static void rpc_pipe_bind_step_two_trigger(struct tevent_req *req)
++{
++	struct rpc_pipe_bind_state *state =
++		tevent_req_data(req,
++				struct rpc_pipe_bind_state);
++	struct dcerpc_binding_handle *b = state->cli->binding_handle;
++	struct schannel_state *schannel_auth =
++		talloc_get_type_abort(state->cli->auth->auth_ctx,
++				      struct schannel_state);
++	struct tevent_req *subreq;
++
++	if (schannel_auth == NULL ||
++	    !ndr_syntax_id_equal(&state->cli->abstract_syntax,
++				 &ndr_table_netlogon.syntax_id)) {
++		tevent_req_done(req);
++		return;
++	}
++
++	ZERO_STRUCT(state->return_auth);
++
++	state->creds = netlogon_creds_copy(state, schannel_auth->creds);
++	if (state->creds == NULL) {
++		tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
++		return;
++	}
++
++	netlogon_creds_client_authenticator(state->creds, &state->auth);
++
++	state->r.in.server_name = state->cli->srv_name_slash;
++	state->r.in.computer_name = state->creds->computer_name;
++	state->r.in.credential = &state->auth;
++	state->r.in.query_level = 1;
++	state->r.in.return_authenticator = &state->return_auth;
++
++	state->r.out.capabilities = &state->capabilities;
++	state->r.out.return_authenticator = &state->return_auth;
++
++	subreq = dcerpc_netr_LogonGetCapabilities_r_send(talloc_tos(),
++							 state->ev,
++							 b,
++							 &state->r);
++	if (subreq == NULL) {
++		tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
++		return;
++	}
++
++	tevent_req_set_callback(subreq, rpc_pipe_bind_step_two_done, req);
++	return;
++}
++
++static void rpc_pipe_bind_step_two_done(struct tevent_req *subreq)
++{
++	struct tevent_req *req =
++		tevent_req_callback_data(subreq,
++					 struct tevent_req);
++	struct rpc_pipe_bind_state *state =
++		tevent_req_data(req,
++				struct rpc_pipe_bind_state);
++	struct schannel_state *schannel_auth =
++		talloc_get_type_abort(state->cli->auth->auth_ctx,
++				      struct schannel_state);
++	NTSTATUS status;
++
++	status = dcerpc_netr_LogonGetCapabilities_r_recv(subreq, talloc_tos());
++	TALLOC_FREE(subreq);
++	if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
++		if (state->cli->dc->negotiate_flags &
++		    NETLOGON_NEG_SUPPORTS_AES) {
++			DEBUG(5, ("AES is not supported and the error was %s\n",
++				  nt_errstr(status)));
++			tevent_req_nterror(req,
++					   NT_STATUS_INVALID_NETWORK_RESPONSE);
++			return;
++		}
++
++		/* This is probably NT */
++		DEBUG(5, ("We are checking against an NT - %s\n",
++			  nt_errstr(status)));
++		tevent_req_done(req);
++		return;
++	} else if (!NT_STATUS_IS_OK(status)) {
++		DEBUG(0, ("dcerpc_netr_LogonGetCapabilities_r_recv failed with %s\n",
++			  nt_errstr(status)));
++		tevent_req_nterror(req, status);
++		return;
++	}
++
++	if (NT_STATUS_EQUAL(state->r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
++		if (state->creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
++			/* This means AES isn't supported. */
++			DEBUG(5, ("AES is not supported and the error was %s\n",
++				  nt_errstr(state->r.out.result)));
++			tevent_req_nterror(req,
++					   NT_STATUS_INVALID_NETWORK_RESPONSE);
++			return;
++		}
++
++		/* This is probably an old Samba version */
++		DEBUG(5, ("We are checking against an old Samba version - %s\n",
++			  nt_errstr(state->r.out.result)));
++		tevent_req_done(req);
++		return;
++	}
++
++	/* We need to check the credential state here, cause win2k3 and earlier
++	 * returns NT_STATUS_NOT_IMPLEMENTED */
++	if (!netlogon_creds_client_check(state->creds,
++					 &state->r.out.return_authenticator->cred)) {
++		/*
++		 * Server replied with bad credential. Fail.
++		 */
++		DEBUG(0,("rpc_pipe_bind_step_two_done: server %s "
++			 "replied with bad credential\n",
++			 state->cli->desthost));
++		tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
++		return;
++	}
++
++	TALLOC_FREE(schannel_auth->creds);
++	schannel_auth->creds = talloc_steal(state->cli, state->creds);
++
++	if (!NT_STATUS_IS_OK(state->r.out.result)) {
++		DEBUG(0, ("dcerpc_netr_LogonGetCapabilities_r_recv failed with %s\n",
++			  nt_errstr(state->r.out.result)));
++		tevent_req_nterror(req, state->r.out.result);
++		return;
++	}
++
++	if (state->creds->negotiate_flags !=
++	    state->r.out.capabilities->server_capabilities) {
++		DEBUG(0, ("The client capabilities don't match the server "
++			  "capabilities: local[0x%08X] remote[0x%08X]\n",
++			  state->creds->negotiate_flags,
++			  state->capabilities.server_capabilities));
++		tevent_req_nterror(req,
++				   NT_STATUS_INVALID_NETWORK_RESPONSE);
++		return;
++	}
++
++	/* TODO: Add downgrade dectection. */
++
++	tevent_req_done(req);
++	return;
++}
++
+ static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
+ 				   struct rpc_pipe_bind_state *state,
+ 				   DATA_BLOB *auth_token)
+-- 
+2.8.1
+
+
+From 686a10e801a58133f7f8cef9751c9fe7c5896d05 Mon Sep 17 00:00:00 2001
+From: Andrew Bartlett <abartlet at samba.org>
+Date: Tue, 3 Jan 2012 15:57:40 +1100
+Subject: [PATCH 33/40] s3-selftest: Add test for rpcclient
+
+Andrew Bartlett
+
+Signed-off-by: Stefan Metzmacher <metze at samba.org>
+---
+ source3/script/tests/test_rpcclient.sh | 19 +++++++++++++++++++
+ source3/selftest/tests.py              |  5 ++++-
+ 2 files changed, 23 insertions(+), 1 deletion(-)
+ create mode 100755 source3/script/tests/test_rpcclient.sh
+
+diff --git a/source3/script/tests/test_rpcclient.sh b/source3/script/tests/test_rpcclient.sh
+new file mode 100755
+index 0000000..6c29316
+--- /dev/null
++++ b/source3/script/tests/test_rpcclient.sh
+@@ -0,0 +1,19 @@
++#!/bin/sh
++
++if [ $# -lt 1 ]; then
++cat <<EOF
++Usage: test_rpcclient.sh ccache binding <rpcclient commands>
++EOF
++exit 1;
++fi
++
++KRB5CCNAME=$1
++shift 1
++export KRB5CCNAME
++ADDARGS="$*"
++
++incdir=`dirname $0`/../../../testprogs/blackbox
++. $incdir/subunit.sh
++testit "rpcclient" $VALGRIND $BINDIR/rpcclient -c 'getusername' $ADDARGS || failed=`expr $failed + 1`
++
++testok $0 $failed
+diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
+index 028012c..a733f14 100755
+--- a/source3/selftest/tests.py
++++ b/source3/selftest/tests.py
+@@ -208,7 +208,7 @@ if sub.returncode == 0:
+             plansmbtorturetestsuite(t, "s3dc", '//$SERVER_IP/tmpcase -U$USERNAME%$PASSWORD')
+ 
+     test = 'rpc.lsa.lookupsids'
+-    auth_options = ["", "ntlm", "spnego" ]
++    auth_options = ["", "ntlm", "spnego", "spnego,ntlm" ]
+     signseal_options = ["", ",connect", ",sign", ",seal"]
+     smb_options = ["", ",smb2"]
+     endianness_options = ["", ",bigendian"]
+@@ -219,6 +219,9 @@ if sub.returncode == 0:
+                     binding_string = "ncacn_np:$SERVER_IP[%s%s%s%s]" % (a, s, z, e)
+                     options = binding_string + " -U$USERNAME%$PASSWORD"
+                     plansmbtorturetestsuite(test, "s3dc", options, 'over ncacn_np with [%s%s%s%s] ' % (a, s, z, e))
++                    plantestsuite("samba3.blackbox.rpcclient over ncacn_np with [%s%s%s%s] " % (a, s, z, e), "s3dc:local", [os.path.join(samba3srcdir, "script/tests/test_rpcclient.sh"),
++                                                                 "none", options, configuration])
++
+     for e in endianness_options:
+         for a in auth_options:
+             for s in signseal_options:
+-- 
+2.8.1
+
+
+From 20f3bdf575b3e6d5dcc970a633f6d0756ec2bb86 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd at samba.org>
+Date: Tue, 11 Dec 2012 09:25:53 +0100
+Subject: [PATCH 34/40] s4-torture: move samr_ValidatePassword test out of main
+ samr test.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Makes it easier to call with ncacn_ip_tcp transport (Windows does not allow
+other transports).
+
+Guenther
+
+Signed-off-by: Günther Deschner <gd at samba.org>
+Reviewed-by: Stefan Metzmacher <metze at samba.org>
+---
+ source4/torture/rpc/rpc.c  |  1 +
+ source4/torture/rpc/samr.c | 21 +++++++++++++++++----
+ 2 files changed, 18 insertions(+), 4 deletions(-)
+
+diff --git a/source4/torture/rpc/rpc.c b/source4/torture/rpc/rpc.c
+index 03936f2..f9cfc61 100644
+--- a/source4/torture/rpc/rpc.c
++++ b/source4/torture/rpc/rpc.c
+@@ -501,6 +501,7 @@ NTSTATUS torture_rpc_init(void)
+ 	torture_suite_add_suite(suite, torture_rpc_samr_passwords_pwdlastset(suite));
+ 	torture_suite_add_suite(suite, torture_rpc_samr_passwords_badpwdcount(suite));
+ 	torture_suite_add_suite(suite, torture_rpc_samr_passwords_lockout(suite));
++	torture_suite_add_suite(suite, torture_rpc_samr_passwords_validate(suite));
+ 	torture_suite_add_suite(suite, torture_rpc_samr_user_privileges(suite));
+ 	torture_suite_add_suite(suite, torture_rpc_samr_large_dc(suite));
+ 	torture_suite_add_suite(suite, torture_rpc_epmapper(suite));
+diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c
+index adfc5d4..8806763 100644
+--- a/source4/torture/rpc/samr.c
++++ b/source4/torture/rpc/samr.c
+@@ -7938,8 +7938,8 @@ static bool test_Connect(struct dcerpc_binding_handle *b,
+ }
+ 
+ 
+-static bool test_samr_ValidatePassword(struct dcerpc_pipe *p,
+-				       struct torture_context *tctx)
++static bool test_samr_ValidatePassword(struct torture_context *tctx,
++				       struct dcerpc_pipe *p)
+ {
+ 	struct samr_ValidatePassword r;
+ 	union samr_ValidatePasswordReq req;
+@@ -7951,6 +7951,10 @@ static bool test_samr_ValidatePassword(struct dcerpc_pipe *p,
+ 
+ 	torture_comment(tctx, "Testing samr_ValidatePassword\n");
+ 
++	if (p->conn->transport.transport != NCACN_IP_TCP) {
++		torture_comment(tctx, "samr_ValidatePassword only should succeed over NCACN_IP_TCP!\n");
++	}
++
+ 	ZERO_STRUCT(r);
+ 	r.in.level = NetValidatePasswordReset;
+ 	r.in.req = &req;
+@@ -8074,8 +8078,6 @@ bool torture_rpc_samr_passwords(struct torture_context *torture)
+ 
+ 	ret &= test_samr_handle_Close(b, torture, &ctx->handle);
+ 
+-	ret &= test_samr_ValidatePassword(p, torture);
+-
+ 	return ret;
+ }
+ 
+@@ -8370,4 +8372,15 @@ struct torture_suite *torture_rpc_samr_passwords_lockout(TALLOC_CTX *mem_ctx)
+ 	return suite;
+ }
+ 
++struct torture_suite *torture_rpc_samr_passwords_validate(TALLOC_CTX *mem_ctx)
++{
++	struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.validate");
++	struct torture_rpc_tcase *tcase;
++
++	tcase = torture_suite_add_rpc_iface_tcase(suite, "samr",
++						  &ndr_table_samr);
++	torture_rpc_tcase_add_test(tcase, "validate",
++				   test_samr_ValidatePassword);
+ 
++	return suite;
++}
+-- 
+2.8.1
+
+
+From 0dd65ea3941450b191d44cac180aaa58735639b7 Mon Sep 17 00:00:00 2001
+From: Andreas Schneider <asn at samba.org>
+Date: Tue, 30 Aug 2011 16:37:40 +0200
+Subject: [PATCH 35/40] s3-rpc_server: Make sure we switch always the
+ connecting user.
+
+We always have a valid session info and if it is a anonymous connection
+we have a session info of the guest user. This means we should always
+call become_authenticated_pipe_user() else and anonymous user could do
+things as root.
+
+Autobuild-User: Andreas Schneider <asn at cryptomilk.org>
+Autobuild-Date: Tue Aug 30 20:50:54 CEST 2011 on sn-devel-104
+---
+ source3/rpc_server/srv_pipe.c | 24 +++++++++++-------------
+ 1 file changed, 11 insertions(+), 13 deletions(-)
+
+diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
+index cb50573..eace128 100644
+--- a/source3/rpc_server/srv_pipe.c
++++ b/source3/rpc_server/srv_pipe.c
+@@ -1553,18 +1553,18 @@ static bool api_pipe_request(struct pipes_struct *p,
+ 				struct ncacn_packet *pkt)
+ {
+ 	bool ret = False;
+-	bool changed_user = False;
+ 	PIPE_RPC_FNS *pipe_fns;
+ 
+-	if (p->pipe_bound &&
+-	    ((p->auth.auth_type == DCERPC_AUTH_TYPE_NTLMSSP) ||
+-	     (p->auth.auth_type == DCERPC_AUTH_TYPE_KRB5) ||
+-	     (p->auth.auth_type == DCERPC_AUTH_TYPE_SPNEGO))) {
+-		if(!become_authenticated_pipe_user(p->session_info)) {
+-			data_blob_free(&p->out_data.rdata);
+-			return False;
+-		}
+-		changed_user = True;
++	if (!p->pipe_bound) {
++		DEBUG(1, ("Pipe not bound!\n"));
++		data_blob_free(&p->out_data.rdata);
++		return false;
++	}
++
++	if (!become_authenticated_pipe_user(p->session_info)) {
++		DEBUG(1, ("Failed to become pipe user!\n"));
++		data_blob_free(&p->out_data.rdata);
++		return false;
+ 	}
+ 
+ 	DEBUG(5, ("Requested \\PIPE\\%s\n",
+@@ -1588,9 +1588,7 @@ static bool api_pipe_request(struct pipes_struct *p,
+ 						    &p->syntax)));
+ 	}
+ 
+-	if (changed_user) {
+-		unbecome_authenticated_pipe_user();
+-	}
++	unbecome_authenticated_pipe_user();
+ 
+ 	return ret;
+ }
+-- 
+2.8.1
+
+
+From c6f5caa838a3fc1890286759cc6c6e7b4b5aeec3 Mon Sep 17 00:00:00 2001
+From: Andreas Schneider <asn at samba.org>
+Date: Fri, 8 Apr 2016 14:18:28 +0200
+Subject: [PATCH 36/40] s3:rpc_server: Store the syntax in the pipes_fn
+ structure
+
+---
+ source3/include/ntdomain.h    |  1 +
+ source3/rpc_server/srv_pipe.c | 22 +++++++++++++---------
+ 2 files changed, 14 insertions(+), 9 deletions(-)
+
+diff --git a/source3/include/ntdomain.h b/source3/include/ntdomain.h
+index ed97182..4560c5f 100644
+--- a/source3/include/ntdomain.h
++++ b/source3/include/ntdomain.h
+@@ -87,6 +87,7 @@ typedef struct pipe_rpc_fns {
+ 	const struct api_struct *cmds;
+ 	int n_cmds;
+ 	uint32 context_id;
++	struct ndr_syntax_id syntax;
+ 
+ } PIPE_RPC_FNS;
+ 
+diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
+index eace128..6e4e760 100644
+--- a/source3/rpc_server/srv_pipe.c
++++ b/source3/rpc_server/srv_pipe.c
+@@ -336,7 +336,7 @@ static bool check_bind_req(struct pipes_struct *p,
+ 	struct pipe_rpc_fns *context_fns;
+ 
+ 	DEBUG(3,("check_bind_req for %s\n",
+-		 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
++		 get_pipe_name_from_syntax(talloc_tos(), abstract)));
+ 
+ 	/* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */
+ 	if (rpc_srv_pipe_exists_by_id(abstract) &&
+@@ -358,6 +358,7 @@ static bool check_bind_req(struct pipes_struct *p,
+ 	context_fns->n_cmds = rpc_srv_get_pipe_num_cmds(abstract);
+ 	context_fns->cmds = rpc_srv_get_pipe_cmds(abstract);
+ 	context_fns->context_id = context_id;
++	context_fns->syntax = *abstract;
+ 
+ 	/* add to the list of open contexts */
+ 
+@@ -1541,7 +1542,8 @@ static PIPE_RPC_FNS* find_pipe_fns_by_context( PIPE_RPC_FNS *list, uint32 contex
+ }
+ 
+ static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
+-		       const struct api_struct *api_rpc_cmds, int n_cmds);
++		       const struct api_struct *api_rpc_cmds, int n_cmds,
++		       const struct ndr_syntax_id *syntax);
+ 
+ /****************************************************************************
+  Find the correct RPC function to call for this request.
+@@ -1577,7 +1579,8 @@ static bool api_pipe_request(struct pipes_struct *p,
+ 
+ 	if ( pipe_fns ) {
+ 		TALLOC_CTX *frame = talloc_stackframe();
+-		ret = api_rpcTNP(p, pkt, pipe_fns->cmds, pipe_fns->n_cmds);
++		ret = api_rpcTNP(p, pkt, pipe_fns->cmds, pipe_fns->n_cmds,
++				 &pipe_fns->syntax);
+ 		TALLOC_FREE(frame);
+ 	}
+ 	else {
+@@ -1598,20 +1601,21 @@ static bool api_pipe_request(struct pipes_struct *p,
+  ********************************************************************/
+ 
+ static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
+-		       const struct api_struct *api_rpc_cmds, int n_cmds)
++		       const struct api_struct *api_rpc_cmds, int n_cmds,
++		       const struct ndr_syntax_id *syntax)
+ {
+ 	int fn_num;
+ 	uint32_t offset1;
+ 
+ 	/* interpret the command */
+ 	DEBUG(4,("api_rpcTNP: %s op 0x%x - ",
+-		 get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
++		 get_pipe_name_from_syntax(talloc_tos(), syntax),
+ 		 pkt->u.request.opnum));
+ 
+ 	if (DEBUGLEVEL >= 50) {
+ 		fstring name;
+ 		slprintf(name, sizeof(name)-1, "in_%s",
+-			 get_pipe_name_from_syntax(talloc_tos(), &p->syntax));
++			 get_pipe_name_from_syntax(talloc_tos(), syntax));
+ 		dump_pdu_region(name, pkt->u.request.opnum,
+ 				&p->in_data.data, 0,
+ 				p->in_data.data.length);
+@@ -1644,7 +1648,7 @@ static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
+ 	/* do the actual command */
+ 	if(!api_rpc_cmds[fn_num].fn(p)) {
+ 		DEBUG(0,("api_rpcTNP: %s: %s failed.\n",
+-			 get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
++			 get_pipe_name_from_syntax(talloc_tos(), syntax),
+ 			 api_rpc_cmds[fn_num].name));
+ 		data_blob_free(&p->out_data.rdata);
+ 		return False;
+@@ -1667,14 +1671,14 @@ static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
+ 	if (DEBUGLEVEL >= 50) {
+ 		fstring name;
+ 		slprintf(name, sizeof(name)-1, "out_%s",
+-			 get_pipe_name_from_syntax(talloc_tos(), &p->syntax));
++			 get_pipe_name_from_syntax(talloc_tos(), syntax));
+ 		dump_pdu_region(name, pkt->u.request.opnum,
+ 				&p->out_data.rdata, offset1,
+ 				p->out_data.rdata.length);
+ 	}
+ 
+ 	DEBUG(5,("api_rpcTNP: called %s successfully\n",
+-		 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
++		 get_pipe_name_from_syntax(talloc_tos(), syntax)));
+ 
+ 	/* Check for buffer underflow in rpc parsing */
+ 	if ((DEBUGLEVEL >= 10) &&
+-- 
+2.8.1
+
+
+From 09e5c8f477f70d81467794a51ab1f30269e80fb3 Mon Sep 17 00:00:00 2001
+From: Andreas Schneider <asn at samba.org>
+Date: Fri, 8 Apr 2016 14:27:43 +0200
+Subject: [PATCH 37/40] s3:rpc_server: Simplify api_pipe_request() logic.
+
+Signed-off-by: Andreas Schneider <asn at samba.org>
+---
+ source3/rpc_server/srv_pipe.c | 38 +++++++++++++++++++-------------------
+ 1 file changed, 19 insertions(+), 19 deletions(-)
+
+diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
+index 6e4e760..57386b2 100644
+--- a/source3/rpc_server/srv_pipe.c
++++ b/source3/rpc_server/srv_pipe.c
+@@ -1554,45 +1554,45 @@ static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
+ static bool api_pipe_request(struct pipes_struct *p,
+ 				struct ncacn_packet *pkt)
+ {
++	TALLOC_CTX *frame = talloc_stackframe();
+ 	bool ret = False;
+ 	PIPE_RPC_FNS *pipe_fns;
+ 
+ 	if (!p->pipe_bound) {
+ 		DEBUG(1, ("Pipe not bound!\n"));
+ 		data_blob_free(&p->out_data.rdata);
++		TALLOC_FREE(frame);
+ 		return false;
+ 	}
+ 
+-	if (!become_authenticated_pipe_user(p->session_info)) {
+-		DEBUG(1, ("Failed to become pipe user!\n"));
++	/* get the set of RPC functions for this context */
++
++	pipe_fns = find_pipe_fns_by_context(p->contexts,
++					    pkt->u.request.context_id);
++	if (pipe_fns == NULL) {
++		DEBUG(0, ("No rpc function table associated with context "
++			  "[%d]\n",
++			  pkt->u.request.context_id));
+ 		data_blob_free(&p->out_data.rdata);
++		TALLOC_FREE(frame);
+ 		return false;
+ 	}
+ 
+ 	DEBUG(5, ("Requested \\PIPE\\%s\n",
+-		  get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
+-
+-	/* get the set of RPC functions for this context */
++		  get_pipe_name_from_syntax(talloc_tos(), &pipe_fns->syntax)));
+ 
+-	pipe_fns = find_pipe_fns_by_context(p->contexts,
+-					    pkt->u.request.context_id);
+-
+-	if ( pipe_fns ) {
+-		TALLOC_CTX *frame = talloc_stackframe();
+-		ret = api_rpcTNP(p, pkt, pipe_fns->cmds, pipe_fns->n_cmds,
+-				 &pipe_fns->syntax);
++	if (!become_authenticated_pipe_user(p->session_info)) {
++		DEBUG(1, ("Failed to become pipe user!\n"));
++		data_blob_free(&p->out_data.rdata);
+ 		TALLOC_FREE(frame);
+-	}
+-	else {
+-		DEBUG(0, ("No rpc function table associated with context "
+-			  "[%d] on pipe [%s]\n",
+-			  pkt->u.request.context_id,
+-			  get_pipe_name_from_syntax(talloc_tos(),
+-						    &p->syntax)));
++		return false;
+ 	}
+ 
++	ret = api_rpcTNP(p, pkt, pipe_fns->cmds, pipe_fns->n_cmds,
++			 &pipe_fns->syntax);
+ 	unbecome_authenticated_pipe_user();
+ 
++	TALLOC_FREE(frame);
+ 	return ret;
+ }
+ 
+-- 
+2.8.1
+
+
+From 9d6412e6860d6934fd2c6e1e4590e48e419133de Mon Sep 17 00:00:00 2001
+From: Gregor Beck <gbeck at sernet.de>
+Date: Fri, 10 Jan 2014 13:56:06 +0100
+Subject: [PATCH 38/40] s3:rpc_server: check verification trailer
+
+Signed-off-by: Gregor Beck <gbeck at sernet.de>
+Reviewed-by: Stefan Metzmacher <metze at samba.org>
+Reviewed-by: Guenther Deschner <gd at samba.org>
+---
+ source3/rpc_server/srv_pipe.c | 43 +++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 43 insertions(+)
+
+diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
+index 57386b2..3d49d79 100644
+--- a/source3/rpc_server/srv_pipe.c
++++ b/source3/rpc_server/srv_pipe.c
+@@ -42,6 +42,7 @@
+ #include "auth.h"
+ #include "ntdomain.h"
+ #include "rpc_server/srv_pipe.h"
++#include "../librpc/ndr/ndr_dcerpc.h"
+ 
+ #undef DBGC_CLASS
+ #define DBGC_CLASS DBGC_RPC_SRV
+@@ -1545,6 +1546,40 @@ static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
+ 		       const struct api_struct *api_rpc_cmds, int n_cmds,
+ 		       const struct ndr_syntax_id *syntax);
+ 
++static bool srv_pipe_check_verification_trailer(struct pipes_struct *p,
++						struct ncacn_packet *pkt,
++						struct pipe_rpc_fns *pipe_fns)
++{
++	TALLOC_CTX *frame = talloc_stackframe();
++	struct dcerpc_sec_verification_trailer *vt = NULL;
++	const uint32_t bitmask1 = 0;
++	const struct dcerpc_sec_vt_pcontext pcontext = {
++		.abstract_syntax = pipe_fns->syntax,
++		.transfer_syntax = ndr_transfer_syntax,
++	};
++	const struct dcerpc_sec_vt_header2 header2 =
++	       dcerpc_sec_vt_header2_from_ncacn_packet(pkt);
++	struct ndr_pull *ndr;
++	enum ndr_err_code ndr_err;
++	bool ret = false;
++
++	ndr = ndr_pull_init_blob(&p->in_data.data, frame);
++	if (ndr == NULL) {
++		goto done;
++	}
++
++	ndr_err = ndr_pop_dcerpc_sec_verification_trailer(ndr, frame, &vt);
++	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
++		goto done;
++	}
++
++	ret = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
++						    &pcontext, &header2);
++done:
++	TALLOC_FREE(frame);
++	return ret;
++}
++
+ /****************************************************************************
+  Find the correct RPC function to call for this request.
+  If the pipe is authenticated then become the correct UNIX user
+@@ -1581,6 +1616,14 @@ static bool api_pipe_request(struct pipes_struct *p,
+ 	DEBUG(5, ("Requested \\PIPE\\%s\n",
+ 		  get_pipe_name_from_syntax(talloc_tos(), &pipe_fns->syntax)));
+ 
++	if (!srv_pipe_check_verification_trailer(p, pkt, pipe_fns)) {
++		DEBUG(1, ("srv_pipe_check_verification_trailer: failed\n"));
++		setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_ACCESS_DENIED));
++		data_blob_free(&p->out_data.rdata);
++		TALLOC_FREE(frame);
++		return true;
++	}
++
+ 	if (!become_authenticated_pipe_user(p->session_info)) {
+ 		DEBUG(1, ("Failed to become pipe user!\n"));
+ 		data_blob_free(&p->out_data.rdata);
+-- 
+2.8.1
+
+
+From 5b3d5fa29425ca03189547b133f929dea992fceb Mon Sep 17 00:00:00 2001
+From: Andreas Schneider <asn at samba.org>
+Date: Wed, 27 Jun 2012 15:21:11 +0200
+Subject: [PATCH 39/40] s3-rpc_server: Make it possible to use more rpc
+ exceptions.
+
+---
+ pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm       |   2 +-
+ source3/include/ntdomain.h                    |  16 +---
+ source3/rpc_server/dfs/srv_dfs_nt.c           |  36 ++++----
+ source3/rpc_server/dssetup/srv_dssetup_nt.c   |  20 ++---
+ source3/rpc_server/echo/srv_echo_nt.c         |  10 +--
+ source3/rpc_server/epmapper/srv_epmapper.c    |   8 +-
+ source3/rpc_server/eventlog/srv_eventlog_nt.c |  32 +++----
+ source3/rpc_server/lsa/srv_lsa_nt.c           |  72 ++++++++--------
+ source3/rpc_server/netlogon/srv_netlog_nt.c   |  60 ++++++-------
+ source3/rpc_server/ntsvcs/srv_ntsvcs_nt.c     | 116 +++++++++++++-------------
+ source3/rpc_server/rpc_handles.c              |   2 +-
+ source3/rpc_server/rpc_ncacn_np.c             |  19 +----
+ source3/rpc_server/samr/srv_samr_nt.c         |  16 ++--
+ source3/rpc_server/spoolss/srv_spoolss_nt.c   | 112 ++++++++++++-------------
+ source3/rpc_server/srv_pipe.c                 |  25 ++----
+ source3/rpc_server/srvsvc/srv_srvsvc_nt.c     |  70 ++++++++--------
+ source3/rpc_server/svcctl/srv_svcctl_nt.c     |  56 ++++++-------
+ source3/rpc_server/winreg/srv_winreg_nt.c     |  10 +--
+ source3/rpc_server/wkssvc/srv_wkssvc_nt.c     |  53 ++++++------
+ 19 files changed, 355 insertions(+), 380 deletions(-)
+
+diff --git a/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm b/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm
+index c4374ba..d433f60 100644
+--- a/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm
++++ b/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm
+@@ -183,7 +183,7 @@ sub ParseFunction($$)
+ 	);
+ 
+ 	pidl "";
+-	pidl "if (p->rng_fault_state) {";
++	pidl "if (p->fault_state) {";
+ 	pidl "\ttalloc_free(r);";
+ 	pidl "\t/* Return true here, srv_pipe_hnd.c will take care */";
+ 	pidl "\treturn true;";
+diff --git a/source3/include/ntdomain.h b/source3/include/ntdomain.h
+index 4560c5f..2fbeabc 100644
+--- a/source3/include/ntdomain.h
++++ b/source3/include/ntdomain.h
+@@ -135,22 +135,10 @@ struct pipes_struct {
+ 	bool pipe_bound;
+ 
+ 	/*
+-	 * Set to true when we should return fault PDU's for everything.
++	 * Set the DCERPC_FAULT to return.
+ 	 */
+ 
+-	bool fault_state;
+-
+-	/*
+-	 * Set to true when we should return fault PDU's for a bad handle.
+-	 */
+-
+-	bool bad_handle_fault_state;
+-
+-	/*
+-	 * Set to true when the backend does not support a call.
+-	 */
+-
+-	bool rng_fault_state;
++	int fault_state;
+ 
+ 	/*
+ 	 * Set to RPC_BIG_ENDIAN when dealing with big-endian PDU's
+diff --git a/source3/rpc_server/dfs/srv_dfs_nt.c b/source3/rpc_server/dfs/srv_dfs_nt.c
+index 324af53..6851db6 100644
+--- a/source3/rpc_server/dfs/srv_dfs_nt.c
++++ b/source3/rpc_server/dfs/srv_dfs_nt.c
+@@ -411,125 +411,125 @@ WERROR _dfs_GetInfo(struct pipes_struct *p, struct dfs_GetInfo *r)
+ WERROR _dfs_SetInfo(struct pipes_struct *p, struct dfs_SetInfo *r)
+ {
+ 	/* FIXME: Implement your code here */
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _dfs_Rename(struct pipes_struct *p, struct dfs_Rename *r)
+ {
+ 	/* FIXME: Implement your code here */
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _dfs_Move(struct pipes_struct *p, struct dfs_Move *r)
+ {
+ 	/* FIXME: Implement your code here */
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _dfs_ManagerGetConfigInfo(struct pipes_struct *p, struct dfs_ManagerGetConfigInfo *r)
+ {
+ 	/* FIXME: Implement your code here */
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _dfs_ManagerSendSiteInfo(struct pipes_struct *p, struct dfs_ManagerSendSiteInfo *r)
+ {
+ 	/* FIXME: Implement your code here */
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _dfs_AddFtRoot(struct pipes_struct *p, struct dfs_AddFtRoot *r)
+ {
+ 	/* FIXME: Implement your code here */
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _dfs_RemoveFtRoot(struct pipes_struct *p, struct dfs_RemoveFtRoot *r)
+ {
+ 	/* FIXME: Implement your code here */
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _dfs_AddStdRoot(struct pipes_struct *p, struct dfs_AddStdRoot *r)
+ {
+ 	/* FIXME: Implement your code here */
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _dfs_RemoveStdRoot(struct pipes_struct *p, struct dfs_RemoveStdRoot *r)
+ {
+ 	/* FIXME: Implement your code here */
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _dfs_ManagerInitialize(struct pipes_struct *p, struct dfs_ManagerInitialize *r)
+ {
+ 	/* FIXME: Implement your code here */
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _dfs_AddStdRootForced(struct pipes_struct *p, struct dfs_AddStdRootForced *r)
+ {
+ 	/* FIXME: Implement your code here */
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _dfs_GetDcAddress(struct pipes_struct *p, struct dfs_GetDcAddress *r)
+ {
+ 	/* FIXME: Implement your code here */
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _dfs_SetDcAddress(struct pipes_struct *p, struct dfs_SetDcAddress *r)
+ {
+ 	/* FIXME: Implement your code here */
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _dfs_FlushFtTable(struct pipes_struct *p, struct dfs_FlushFtTable *r)
+ {
+ 	/* FIXME: Implement your code here */
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _dfs_Add2(struct pipes_struct *p, struct dfs_Add2 *r)
+ {
+ 	/* FIXME: Implement your code here */
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _dfs_Remove2(struct pipes_struct *p, struct dfs_Remove2 *r)
+ {
+ 	/* FIXME: Implement your code here */
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _dfs_EnumEx(struct pipes_struct *p, struct dfs_EnumEx *r)
+ {
+ 	/* FIXME: Implement your code here */
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _dfs_SetInfo2(struct pipes_struct *p, struct dfs_SetInfo2 *r)
+ {
+ 	/* FIXME: Implement your code here */
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+diff --git a/source3/rpc_server/dssetup/srv_dssetup_nt.c b/source3/rpc_server/dssetup/srv_dssetup_nt.c
+index d90ad42..39bb649 100644
+--- a/source3/rpc_server/dssetup/srv_dssetup_nt.c
++++ b/source3/rpc_server/dssetup/srv_dssetup_nt.c
+@@ -130,7 +130,7 @@ WERROR _dssetup_DsRoleGetPrimaryDomainInformation(struct pipes_struct *p,
+ WERROR _dssetup_DsRoleDnsNameToFlatName(struct pipes_struct *p,
+ 					struct dssetup_DsRoleDnsNameToFlatName *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -140,7 +140,7 @@ WERROR _dssetup_DsRoleDnsNameToFlatName(struct pipes_struct *p,
+ WERROR _dssetup_DsRoleDcAsDc(struct pipes_struct *p,
+ 			     struct dssetup_DsRoleDcAsDc *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -150,7 +150,7 @@ WERROR _dssetup_DsRoleDcAsDc(struct pipes_struct *p,
+ WERROR _dssetup_DsRoleDcAsReplica(struct pipes_struct *p,
+ 				  struct dssetup_DsRoleDcAsReplica *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -160,7 +160,7 @@ WERROR _dssetup_DsRoleDcAsReplica(struct pipes_struct *p,
+ WERROR _dssetup_DsRoleDemoteDc(struct pipes_struct *p,
+ 			       struct dssetup_DsRoleDemoteDc *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -170,7 +170,7 @@ WERROR _dssetup_DsRoleDemoteDc(struct pipes_struct *p,
+ WERROR _dssetup_DsRoleGetDcOperationProgress(struct pipes_struct *p,
+ 					     struct dssetup_DsRoleGetDcOperationProgress *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -180,7 +180,7 @@ WERROR _dssetup_DsRoleGetDcOperationProgress(struct pipes_struct *p,
+ WERROR _dssetup_DsRoleGetDcOperationResults(struct pipes_struct *p,
+ 					    struct dssetup_DsRoleGetDcOperationResults *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -190,7 +190,7 @@ WERROR _dssetup_DsRoleGetDcOperationResults(struct pipes_struct *p,
+ WERROR _dssetup_DsRoleCancel(struct pipes_struct *p,
+ 			     struct dssetup_DsRoleCancel *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -200,7 +200,7 @@ WERROR _dssetup_DsRoleCancel(struct pipes_struct *p,
+ WERROR _dssetup_DsRoleServerSaveStateForUpgrade(struct pipes_struct *p,
+ 						struct dssetup_DsRoleServerSaveStateForUpgrade *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -210,7 +210,7 @@ WERROR _dssetup_DsRoleServerSaveStateForUpgrade(struct pipes_struct *p,
+ WERROR _dssetup_DsRoleUpgradeDownlevelServer(struct pipes_struct *p,
+ 					     struct dssetup_DsRoleUpgradeDownlevelServer *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -220,6 +220,6 @@ WERROR _dssetup_DsRoleUpgradeDownlevelServer(struct pipes_struct *p,
+ WERROR _dssetup_DsRoleAbortDownlevelServerUpgrade(struct pipes_struct *p,
+ 						  struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+diff --git a/source3/rpc_server/echo/srv_echo_nt.c b/source3/rpc_server/echo/srv_echo_nt.c
+index c7a9e1a..029b09f 100644
+--- a/source3/rpc_server/echo/srv_echo_nt.c
++++ b/source3/rpc_server/echo/srv_echo_nt.c
+@@ -87,13 +87,13 @@ void _echo_SourceData(struct pipes_struct *p, struct echo_SourceData *r)
+ 
+ void _echo_TestCall(struct pipes_struct *p, struct echo_TestCall *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return;
+ }
+ 
+ NTSTATUS _echo_TestCall2(struct pipes_struct *p, struct echo_TestCall2 *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_OK;
+ }
+ 
+@@ -105,18 +105,18 @@ uint32 _echo_TestSleep(struct pipes_struct *p, struct echo_TestSleep *r)
+ 
+ void _echo_TestEnum(struct pipes_struct *p, struct echo_TestEnum *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return;
+ }
+ 
+ void _echo_TestSurrounding(struct pipes_struct *p, struct echo_TestSurrounding *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return;
+ }
+ 
+ uint16 _echo_TestDoublePointer(struct pipes_struct *p, struct echo_TestDoublePointer *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return 0;
+ }
+diff --git a/source3/rpc_server/epmapper/srv_epmapper.c b/source3/rpc_server/epmapper/srv_epmapper.c
+index efa9b6f..5c100d1 100644
+--- a/source3/rpc_server/epmapper/srv_epmapper.c
++++ b/source3/rpc_server/epmapper/srv_epmapper.c
+@@ -297,6 +297,7 @@ error_status_t _epm_Insert(struct pipes_struct *p,
+ 	/* If this is not a priviledged users, return */
+ 	if (p->transport != NCALRPC ||
+ 	    !is_priviledged_pipe(p->session_info)) {
++		p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 		return EPMAPPER_STATUS_CANT_PERFORM_OP;
+ 	}
+ 
+@@ -433,6 +434,7 @@ error_status_t _epm_Delete(struct pipes_struct *p,
+ 	/* If this is not a priviledged users, return */
+ 	if (p->transport != NCALRPC ||
+ 	    !is_priviledged_pipe(p->session_info)) {
++		p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 		return EPMAPPER_STATUS_CANT_PERFORM_OP;
+ 	}
+ 
+@@ -1096,7 +1098,7 @@ error_status_t _epm_LookupHandleFree(struct pipes_struct *p,
+ error_status_t _epm_InqObject(struct pipes_struct *p,
+ 		      struct epm_InqObject *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return EPMAPPER_STATUS_CANT_PERFORM_OP;
+ }
+ 
+@@ -1110,7 +1112,7 @@ error_status_t _epm_InqObject(struct pipes_struct *p,
+ error_status_t _epm_MgmtDelete(struct pipes_struct *p,
+ 		       struct epm_MgmtDelete *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return EPMAPPER_STATUS_CANT_PERFORM_OP;
+ }
+ 
+@@ -1121,7 +1123,7 @@ error_status_t _epm_MgmtDelete(struct pipes_struct *p,
+ error_status_t _epm_MapAuth(struct pipes_struct *p,
+ 		    struct epm_MapAuth *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return EPMAPPER_STATUS_CANT_PERFORM_OP;
+ }
+ 
+diff --git a/source3/rpc_server/eventlog/srv_eventlog_nt.c b/source3/rpc_server/eventlog/srv_eventlog_nt.c
+index b4c59ba..3455f6f 100644
+--- a/source3/rpc_server/eventlog/srv_eventlog_nt.c
++++ b/source3/rpc_server/eventlog/srv_eventlog_nt.c
+@@ -695,7 +695,7 @@ NTSTATUS _eventlog_GetNumRecords(struct pipes_struct *p,
+ 
+ NTSTATUS _eventlog_BackupEventLogW(struct pipes_struct *p, struct eventlog_BackupEventLogW *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+@@ -838,104 +838,104 @@ NTSTATUS _eventlog_ReportEventW(struct pipes_struct *p,
+ NTSTATUS _eventlog_DeregisterEventSource(struct pipes_struct *p,
+ 					 struct eventlog_DeregisterEventSource *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _eventlog_ChangeNotify(struct pipes_struct *p,
+ 				struct eventlog_ChangeNotify *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _eventlog_RegisterEventSourceW(struct pipes_struct *p,
+ 					struct eventlog_RegisterEventSourceW *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _eventlog_OpenBackupEventLogW(struct pipes_struct *p,
+ 				       struct eventlog_OpenBackupEventLogW *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _eventlog_ClearEventLogA(struct pipes_struct *p,
+ 				  struct eventlog_ClearEventLogA *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _eventlog_BackupEventLogA(struct pipes_struct *p,
+ 				   struct eventlog_BackupEventLogA *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _eventlog_OpenEventLogA(struct pipes_struct *p,
+ 				 struct eventlog_OpenEventLogA *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _eventlog_RegisterEventSourceA(struct pipes_struct *p,
+ 					struct eventlog_RegisterEventSourceA *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _eventlog_OpenBackupEventLogA(struct pipes_struct *p,
+ 				       struct eventlog_OpenBackupEventLogA *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _eventlog_ReadEventLogA(struct pipes_struct *p,
+ 				 struct eventlog_ReadEventLogA *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _eventlog_ReportEventA(struct pipes_struct *p,
+ 				struct eventlog_ReportEventA *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _eventlog_RegisterClusterSvc(struct pipes_struct *p,
+ 				      struct eventlog_RegisterClusterSvc *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _eventlog_DeregisterClusterSvc(struct pipes_struct *p,
+ 					struct eventlog_DeregisterClusterSvc *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _eventlog_WriteClusterEvents(struct pipes_struct *p,
+ 				      struct eventlog_WriteClusterEvents *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _eventlog_ReportEventAndSourceW(struct pipes_struct *p,
+ 					 struct eventlog_ReportEventAndSourceW *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+diff --git a/source3/rpc_server/lsa/srv_lsa_nt.c b/source3/rpc_server/lsa/srv_lsa_nt.c
+index a7b55e7..12b5849 100644
+--- a/source3/rpc_server/lsa/srv_lsa_nt.c
++++ b/source3/rpc_server/lsa/srv_lsa_nt.c
+@@ -817,7 +817,7 @@ NTSTATUS _lsa_QueryInfoPolicy2(struct pipes_struct *p,
+ 	struct lsa_QueryInfoPolicy r;
+ 
+ 	if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
+-		p->rng_fault_state = True;
++		p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 		return NT_STATUS_NOT_IMPLEMENTED;
+ 	}
+ 
+@@ -3210,88 +3210,88 @@ NTSTATUS _lsa_Delete(struct pipes_struct *p,
+ 
+ NTSTATUS _lsa_SetSecObj(struct pipes_struct *p, struct lsa_SetSecObj *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _lsa_ChangePassword(struct pipes_struct *p,
+ 			     struct lsa_ChangePassword *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _lsa_SetInfoPolicy(struct pipes_struct *p, struct lsa_SetInfoPolicy *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _lsa_ClearAuditLog(struct pipes_struct *p, struct lsa_ClearAuditLog *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _lsa_GetQuotasForAccount(struct pipes_struct *p,
+ 				  struct lsa_GetQuotasForAccount *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _lsa_SetQuotasForAccount(struct pipes_struct *p,
+ 				  struct lsa_SetQuotasForAccount *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _lsa_SetInformationTrustedDomain(struct pipes_struct *p,
+ 					  struct lsa_SetInformationTrustedDomain *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _lsa_QuerySecret(struct pipes_struct *p, struct lsa_QuerySecret *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _lsa_SetTrustedDomainInfo(struct pipes_struct *p,
+ 				   struct lsa_SetTrustedDomainInfo *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _lsa_StorePrivateData(struct pipes_struct *p,
+ 			       struct lsa_StorePrivateData *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _lsa_RetrievePrivateData(struct pipes_struct *p,
+ 				  struct lsa_RetrievePrivateData *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _lsa_SetInfoPolicy2(struct pipes_struct *p,
+ 			     struct lsa_SetInfoPolicy2 *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _lsa_SetTrustedDomainInfoByName(struct pipes_struct *p,
+ 					 struct lsa_SetTrustedDomainInfoByName *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+@@ -3310,7 +3310,7 @@ NTSTATUS _lsa_EnumTrustedDomainsEx(struct pipes_struct *p,
+ 	 * _lsa_EnumTrustedDomains() afterwards - gd */
+ 
+ 	if (!(pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX)) {
+-		p->rng_fault_state = True;
++		p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 		return NT_STATUS_NOT_IMPLEMENTED;
+ 	}
+ 
+@@ -3379,107 +3379,107 @@ NTSTATUS _lsa_EnumTrustedDomainsEx(struct pipes_struct *p,
+ NTSTATUS _lsa_QueryDomainInformationPolicy(struct pipes_struct *p,
+ 					   struct lsa_QueryDomainInformationPolicy *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _lsa_SetDomainInformationPolicy(struct pipes_struct *p,
+ 					 struct lsa_SetDomainInformationPolicy *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _lsa_TestCall(struct pipes_struct *p, struct lsa_TestCall *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _lsa_CREDRWRITE(struct pipes_struct *p, struct lsa_CREDRWRITE *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _lsa_CREDRREAD(struct pipes_struct *p, struct lsa_CREDRREAD *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _lsa_CREDRENUMERATE(struct pipes_struct *p, struct lsa_CREDRENUMERATE *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(struct pipes_struct *p,
+ 					  struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(struct pipes_struct *p,
+ 					 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _lsa_CREDRDELETE(struct pipes_struct *p, struct lsa_CREDRDELETE *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _lsa_CREDRGETTARGETINFO(struct pipes_struct *p,
+ 				 struct lsa_CREDRGETTARGETINFO *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _lsa_CREDRPROFILELOADED(struct pipes_struct *p,
+ 				 struct lsa_CREDRPROFILELOADED *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _lsa_CREDRGETSESSIONTYPES(struct pipes_struct *p,
+ 				   struct lsa_CREDRGETSESSIONTYPES *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _lsa_LSARREGISTERAUDITEVENT(struct pipes_struct *p,
+ 				     struct lsa_LSARREGISTERAUDITEVENT *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _lsa_LSARGENAUDITEVENT(struct pipes_struct *p,
+ 				struct lsa_LSARGENAUDITEVENT *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(struct pipes_struct *p,
+ 				       struct lsa_LSARUNREGISTERAUDITEVENT *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _lsa_lsaRQueryForestTrustInformation(struct pipes_struct *p,
+ 					      struct lsa_lsaRQueryForestTrustInformation *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+@@ -3992,34 +3992,34 @@ NTSTATUS _lsa_lsaRSetForestTrustInformation(struct pipes_struct *p,
+ NTSTATUS _lsa_CREDRRENAME(struct pipes_struct *p,
+ 			  struct lsa_CREDRRENAME *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _lsa_LSAROPENPOLICYSCE(struct pipes_struct *p,
+ 				struct lsa_LSAROPENPOLICYSCE *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
+ 						 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
+ 						   struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+ NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT(struct pipes_struct *p,
+ 					 struct lsa_LSARADTREPORTSECURITYEVENT *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c
+index 060ca0b..4734bfe 100644
+--- a/source3/rpc_server/netlogon/srv_netlog_nt.c
++++ b/source3/rpc_server/netlogon/srv_netlog_nt.c
+@@ -1787,7 +1787,7 @@ NTSTATUS _netr_LogonSamLogonEx(struct pipes_struct *p,
+ WERROR _netr_LogonUasLogon(struct pipes_struct *p,
+ 			   struct netr_LogonUasLogon *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -1797,7 +1797,7 @@ WERROR _netr_LogonUasLogon(struct pipes_struct *p,
+ WERROR _netr_LogonUasLogoff(struct pipes_struct *p,
+ 			    struct netr_LogonUasLogoff *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -1807,7 +1807,7 @@ WERROR _netr_LogonUasLogoff(struct pipes_struct *p,
+ NTSTATUS _netr_DatabaseDeltas(struct pipes_struct *p,
+ 			      struct netr_DatabaseDeltas *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+@@ -1817,7 +1817,7 @@ NTSTATUS _netr_DatabaseDeltas(struct pipes_struct *p,
+ NTSTATUS _netr_DatabaseSync(struct pipes_struct *p,
+ 			    struct netr_DatabaseSync *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+@@ -1827,7 +1827,7 @@ NTSTATUS _netr_DatabaseSync(struct pipes_struct *p,
+ NTSTATUS _netr_AccountDeltas(struct pipes_struct *p,
+ 			     struct netr_AccountDeltas *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+@@ -1837,7 +1837,7 @@ NTSTATUS _netr_AccountDeltas(struct pipes_struct *p,
+ NTSTATUS _netr_AccountSync(struct pipes_struct *p,
+ 			   struct netr_AccountSync *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+@@ -1978,7 +1978,7 @@ WERROR _netr_GetAnyDCName(struct pipes_struct *p,
+ NTSTATUS _netr_DatabaseSync2(struct pipes_struct *p,
+ 			     struct netr_DatabaseSync2 *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+@@ -1988,7 +1988,7 @@ NTSTATUS _netr_DatabaseSync2(struct pipes_struct *p,
+ NTSTATUS _netr_DatabaseRedo(struct pipes_struct *p,
+ 			    struct netr_DatabaseRedo *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+@@ -1998,7 +1998,7 @@ NTSTATUS _netr_DatabaseRedo(struct pipes_struct *p,
+ WERROR _netr_DsRGetDCName(struct pipes_struct *p,
+ 			  struct netr_DsRGetDCName *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -2017,7 +2017,7 @@ NTSTATUS _netr_LogonGetCapabilities(struct pipes_struct *p,
+ WERROR _netr_NETRLOGONSETSERVICEBITS(struct pipes_struct *p,
+ 				     struct netr_NETRLOGONSETSERVICEBITS *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -2027,7 +2027,7 @@ WERROR _netr_NETRLOGONSETSERVICEBITS(struct pipes_struct *p,
+ WERROR _netr_LogonGetTrustRid(struct pipes_struct *p,
+ 			      struct netr_LogonGetTrustRid *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -2037,7 +2037,7 @@ WERROR _netr_LogonGetTrustRid(struct pipes_struct *p,
+ WERROR _netr_NETRLOGONCOMPUTESERVERDIGEST(struct pipes_struct *p,
+ 					  struct netr_NETRLOGONCOMPUTESERVERDIGEST *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -2047,7 +2047,7 @@ WERROR _netr_NETRLOGONCOMPUTESERVERDIGEST(struct pipes_struct *p,
+ WERROR _netr_NETRLOGONCOMPUTECLIENTDIGEST(struct pipes_struct *p,
+ 					  struct netr_NETRLOGONCOMPUTECLIENTDIGEST *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -2057,7 +2057,7 @@ WERROR _netr_NETRLOGONCOMPUTECLIENTDIGEST(struct pipes_struct *p,
+ WERROR _netr_DsRGetDCNameEx(struct pipes_struct *p,
+ 			    struct netr_DsRGetDCNameEx *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -2067,7 +2067,7 @@ WERROR _netr_DsRGetDCNameEx(struct pipes_struct *p,
+ WERROR _netr_DsRGetSiteName(struct pipes_struct *p,
+ 			    struct netr_DsRGetSiteName *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -2077,7 +2077,7 @@ WERROR _netr_DsRGetSiteName(struct pipes_struct *p,
+ NTSTATUS _netr_LogonGetDomainInfo(struct pipes_struct *p,
+ 				  struct netr_LogonGetDomainInfo *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+@@ -2087,7 +2087,7 @@ NTSTATUS _netr_LogonGetDomainInfo(struct pipes_struct *p,
+ WERROR _netr_ServerPasswordGet(struct pipes_struct *p,
+ 			       struct netr_ServerPasswordGet *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -2097,7 +2097,7 @@ WERROR _netr_ServerPasswordGet(struct pipes_struct *p,
+ WERROR _netr_NETRLOGONSENDTOSAM(struct pipes_struct *p,
+ 				struct netr_NETRLOGONSENDTOSAM *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -2107,7 +2107,7 @@ WERROR _netr_NETRLOGONSENDTOSAM(struct pipes_struct *p,
+ WERROR _netr_DsRAddressToSitenamesW(struct pipes_struct *p,
+ 				    struct netr_DsRAddressToSitenamesW *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -2117,7 +2117,7 @@ WERROR _netr_DsRAddressToSitenamesW(struct pipes_struct *p,
+ WERROR _netr_DsRGetDCNameEx2(struct pipes_struct *p,
+ 			     struct netr_DsRGetDCNameEx2 *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -2127,7 +2127,7 @@ WERROR _netr_DsRGetDCNameEx2(struct pipes_struct *p,
+ WERROR _netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct pipes_struct *p,
+ 						 struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -2137,7 +2137,7 @@ WERROR _netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct pipes_struct *p,
+ WERROR _netr_NetrEnumerateTrustedDomainsEx(struct pipes_struct *p,
+ 					   struct netr_NetrEnumerateTrustedDomainsEx *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -2147,7 +2147,7 @@ WERROR _netr_NetrEnumerateTrustedDomainsEx(struct pipes_struct *p,
+ WERROR _netr_DsRAddressToSitenamesExW(struct pipes_struct *p,
+ 				      struct netr_DsRAddressToSitenamesExW *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -2157,7 +2157,7 @@ WERROR _netr_DsRAddressToSitenamesExW(struct pipes_struct *p,
+ WERROR _netr_DsrGetDcSiteCoverageW(struct pipes_struct *p,
+ 				   struct netr_DsrGetDcSiteCoverageW *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -2167,7 +2167,7 @@ WERROR _netr_DsrGetDcSiteCoverageW(struct pipes_struct *p,
+ WERROR _netr_DsrEnumerateDomainTrusts(struct pipes_struct *p,
+ 				      struct netr_DsrEnumerateDomainTrusts *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -2177,7 +2177,7 @@ WERROR _netr_DsrEnumerateDomainTrusts(struct pipes_struct *p,
+ WERROR _netr_DsrDeregisterDNSHostRecords(struct pipes_struct *p,
+ 					 struct netr_DsrDeregisterDNSHostRecords *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -2187,7 +2187,7 @@ WERROR _netr_DsrDeregisterDNSHostRecords(struct pipes_struct *p,
+ NTSTATUS _netr_ServerTrustPasswordsGet(struct pipes_struct *p,
+ 				       struct netr_ServerTrustPasswordsGet *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+@@ -2197,7 +2197,7 @@ NTSTATUS _netr_ServerTrustPasswordsGet(struct pipes_struct *p,
+ WERROR _netr_DsRGetForestTrustInformation(struct pipes_struct *p,
+ 					  struct netr_DsRGetForestTrustInformation *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -2476,7 +2476,7 @@ NTSTATUS _netr_ServerGetTrustInfo(struct pipes_struct *p,
+ NTSTATUS _netr_Unused47(struct pipes_struct *p,
+ 			struct netr_Unused47 *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+@@ -2486,6 +2486,6 @@ NTSTATUS _netr_Unused47(struct pipes_struct *p,
+ NTSTATUS _netr_DsrUpdateReadOnlyServerDnsRecords(struct pipes_struct *p,
+ 						 struct netr_DsrUpdateReadOnlyServerDnsRecords *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+diff --git a/source3/rpc_server/ntsvcs/srv_ntsvcs_nt.c b/source3/rpc_server/ntsvcs/srv_ntsvcs_nt.c
+index 0a00e00..bd8a614 100644
+--- a/source3/rpc_server/ntsvcs/srv_ntsvcs_nt.c
++++ b/source3/rpc_server/ntsvcs/srv_ntsvcs_nt.c
+@@ -227,7 +227,7 @@ WERROR _PNP_HwProfFlags(struct pipes_struct *p,
+ WERROR _PNP_Disconnect(struct pipes_struct *p,
+ 		       struct PNP_Disconnect *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -237,7 +237,7 @@ WERROR _PNP_Disconnect(struct pipes_struct *p,
+ WERROR _PNP_Connect(struct pipes_struct *p,
+ 		    struct PNP_Connect *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -247,7 +247,7 @@ WERROR _PNP_Connect(struct pipes_struct *p,
+ WERROR _PNP_GetGlobalState(struct pipes_struct *p,
+ 			   struct PNP_GetGlobalState *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -257,7 +257,7 @@ WERROR _PNP_GetGlobalState(struct pipes_struct *p,
+ WERROR _PNP_InitDetection(struct pipes_struct *p,
+ 			  struct PNP_InitDetection *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -267,7 +267,7 @@ WERROR _PNP_InitDetection(struct pipes_struct *p,
+ WERROR _PNP_ReportLogOn(struct pipes_struct *p,
+ 			struct PNP_ReportLogOn *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -277,7 +277,7 @@ WERROR _PNP_ReportLogOn(struct pipes_struct *p,
+ WERROR _PNP_GetRootDeviceInstance(struct pipes_struct *p,
+ 				  struct PNP_GetRootDeviceInstance *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -287,7 +287,7 @@ WERROR _PNP_GetRootDeviceInstance(struct pipes_struct *p,
+ WERROR _PNP_GetRelatedDeviceInstance(struct pipes_struct *p,
+ 				     struct PNP_GetRelatedDeviceInstance *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -297,7 +297,7 @@ WERROR _PNP_GetRelatedDeviceInstance(struct pipes_struct *p,
+ WERROR _PNP_EnumerateSubKeys(struct pipes_struct *p,
+ 			     struct PNP_EnumerateSubKeys *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -307,7 +307,7 @@ WERROR _PNP_EnumerateSubKeys(struct pipes_struct *p,
+ WERROR _PNP_GetDepth(struct pipes_struct *p,
+ 		     struct PNP_GetDepth *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -317,7 +317,7 @@ WERROR _PNP_GetDepth(struct pipes_struct *p,
+ WERROR _PNP_SetDeviceRegProp(struct pipes_struct *p,
+ 			     struct PNP_SetDeviceRegProp *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -327,7 +327,7 @@ WERROR _PNP_SetDeviceRegProp(struct pipes_struct *p,
+ WERROR _PNP_GetClassInstance(struct pipes_struct *p,
+ 			     struct PNP_GetClassInstance *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -337,7 +337,7 @@ WERROR _PNP_GetClassInstance(struct pipes_struct *p,
+ WERROR _PNP_CreateKey(struct pipes_struct *p,
+ 		      struct PNP_CreateKey *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -347,7 +347,7 @@ WERROR _PNP_CreateKey(struct pipes_struct *p,
+ WERROR _PNP_DeleteRegistryKey(struct pipes_struct *p,
+ 			      struct PNP_DeleteRegistryKey *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -357,7 +357,7 @@ WERROR _PNP_DeleteRegistryKey(struct pipes_struct *p,
+ WERROR _PNP_GetClassCount(struct pipes_struct *p,
+ 			  struct PNP_GetClassCount *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -367,7 +367,7 @@ WERROR _PNP_GetClassCount(struct pipes_struct *p,
+ WERROR _PNP_GetClassName(struct pipes_struct *p,
+ 			 struct PNP_GetClassName *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -377,7 +377,7 @@ WERROR _PNP_GetClassName(struct pipes_struct *p,
+ WERROR _PNP_DeleteClassKey(struct pipes_struct *p,
+ 			   struct PNP_DeleteClassKey *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -387,7 +387,7 @@ WERROR _PNP_DeleteClassKey(struct pipes_struct *p,
+ WERROR _PNP_GetInterfaceDeviceAlias(struct pipes_struct *p,
+ 				    struct PNP_GetInterfaceDeviceAlias *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -397,7 +397,7 @@ WERROR _PNP_GetInterfaceDeviceAlias(struct pipes_struct *p,
+ WERROR _PNP_GetInterfaceDeviceList(struct pipes_struct *p,
+ 				   struct PNP_GetInterfaceDeviceList *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -407,7 +407,7 @@ WERROR _PNP_GetInterfaceDeviceList(struct pipes_struct *p,
+ WERROR _PNP_GetInterfaceDeviceListSize(struct pipes_struct *p,
+ 				       struct PNP_GetInterfaceDeviceListSize *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -417,7 +417,7 @@ WERROR _PNP_GetInterfaceDeviceListSize(struct pipes_struct *p,
+ WERROR _PNP_RegisterDeviceClassAssociation(struct pipes_struct *p,
+ 					   struct PNP_RegisterDeviceClassAssociation *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -427,7 +427,7 @@ WERROR _PNP_RegisterDeviceClassAssociation(struct pipes_struct *p,
+ WERROR _PNP_UnregisterDeviceClassAssociation(struct pipes_struct *p,
+ 					     struct PNP_UnregisterDeviceClassAssociation *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -437,7 +437,7 @@ WERROR _PNP_UnregisterDeviceClassAssociation(struct pipes_struct *p,
+ WERROR _PNP_GetClassRegProp(struct pipes_struct *p,
+ 			    struct PNP_GetClassRegProp *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -447,7 +447,7 @@ WERROR _PNP_GetClassRegProp(struct pipes_struct *p,
+ WERROR _PNP_SetClassRegProp(struct pipes_struct *p,
+ 			    struct PNP_SetClassRegProp *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -457,7 +457,7 @@ WERROR _PNP_SetClassRegProp(struct pipes_struct *p,
+ WERROR _PNP_CreateDevInst(struct pipes_struct *p,
+ 			  struct PNP_CreateDevInst *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -467,7 +467,7 @@ WERROR _PNP_CreateDevInst(struct pipes_struct *p,
+ WERROR _PNP_DeviceInstanceAction(struct pipes_struct *p,
+ 				 struct PNP_DeviceInstanceAction *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -477,7 +477,7 @@ WERROR _PNP_DeviceInstanceAction(struct pipes_struct *p,
+ WERROR _PNP_GetDeviceStatus(struct pipes_struct *p,
+ 			    struct PNP_GetDeviceStatus *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -487,7 +487,7 @@ WERROR _PNP_GetDeviceStatus(struct pipes_struct *p,
+ WERROR _PNP_SetDeviceProblem(struct pipes_struct *p,
+ 			     struct PNP_SetDeviceProblem *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -497,7 +497,7 @@ WERROR _PNP_SetDeviceProblem(struct pipes_struct *p,
+ WERROR _PNP_DisableDevInst(struct pipes_struct *p,
+ 			   struct PNP_DisableDevInst *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -507,7 +507,7 @@ WERROR _PNP_DisableDevInst(struct pipes_struct *p,
+ WERROR _PNP_UninstallDevInst(struct pipes_struct *p,
+ 			     struct PNP_UninstallDevInst *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -517,7 +517,7 @@ WERROR _PNP_UninstallDevInst(struct pipes_struct *p,
+ WERROR _PNP_AddID(struct pipes_struct *p,
+ 		  struct PNP_AddID *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -527,7 +527,7 @@ WERROR _PNP_AddID(struct pipes_struct *p,
+ WERROR _PNP_RegisterDriver(struct pipes_struct *p,
+ 			   struct PNP_RegisterDriver *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -537,7 +537,7 @@ WERROR _PNP_RegisterDriver(struct pipes_struct *p,
+ WERROR _PNP_QueryRemove(struct pipes_struct *p,
+ 			struct PNP_QueryRemove *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -547,7 +547,7 @@ WERROR _PNP_QueryRemove(struct pipes_struct *p,
+ WERROR _PNP_RequestDeviceEject(struct pipes_struct *p,
+ 			       struct PNP_RequestDeviceEject *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -557,7 +557,7 @@ WERROR _PNP_RequestDeviceEject(struct pipes_struct *p,
+ WERROR _PNP_IsDockStationPresent(struct pipes_struct *p,
+ 				 struct PNP_IsDockStationPresent *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -567,7 +567,7 @@ WERROR _PNP_IsDockStationPresent(struct pipes_struct *p,
+ WERROR _PNP_RequestEjectPC(struct pipes_struct *p,
+ 			   struct PNP_RequestEjectPC *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -577,7 +577,7 @@ WERROR _PNP_RequestEjectPC(struct pipes_struct *p,
+ WERROR _PNP_AddEmptyLogConf(struct pipes_struct *p,
+ 			    struct PNP_AddEmptyLogConf *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -587,7 +587,7 @@ WERROR _PNP_AddEmptyLogConf(struct pipes_struct *p,
+ WERROR _PNP_FreeLogConf(struct pipes_struct *p,
+ 			struct PNP_FreeLogConf *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -597,7 +597,7 @@ WERROR _PNP_FreeLogConf(struct pipes_struct *p,
+ WERROR _PNP_GetFirstLogConf(struct pipes_struct *p,
+ 			    struct PNP_GetFirstLogConf *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -607,7 +607,7 @@ WERROR _PNP_GetFirstLogConf(struct pipes_struct *p,
+ WERROR _PNP_GetNextLogConf(struct pipes_struct *p,
+ 			   struct PNP_GetNextLogConf *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -617,7 +617,7 @@ WERROR _PNP_GetNextLogConf(struct pipes_struct *p,
+ WERROR _PNP_GetLogConfPriority(struct pipes_struct *p,
+ 			       struct PNP_GetLogConfPriority *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -627,7 +627,7 @@ WERROR _PNP_GetLogConfPriority(struct pipes_struct *p,
+ WERROR _PNP_AddResDes(struct pipes_struct *p,
+ 		      struct PNP_AddResDes *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -637,7 +637,7 @@ WERROR _PNP_AddResDes(struct pipes_struct *p,
+ WERROR _PNP_FreeResDes(struct pipes_struct *p,
+ 		       struct PNP_FreeResDes *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -647,7 +647,7 @@ WERROR _PNP_FreeResDes(struct pipes_struct *p,
+ WERROR _PNP_GetNextResDes(struct pipes_struct *p,
+ 			  struct PNP_GetNextResDes *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -657,7 +657,7 @@ WERROR _PNP_GetNextResDes(struct pipes_struct *p,
+ WERROR _PNP_GetResDesData(struct pipes_struct *p,
+ 			  struct PNP_GetResDesData *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -667,7 +667,7 @@ WERROR _PNP_GetResDesData(struct pipes_struct *p,
+ WERROR _PNP_GetResDesDataSize(struct pipes_struct *p,
+ 			      struct PNP_GetResDesDataSize *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -677,7 +677,7 @@ WERROR _PNP_GetResDesDataSize(struct pipes_struct *p,
+ WERROR _PNP_ModifyResDes(struct pipes_struct *p,
+ 			 struct PNP_ModifyResDes *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -687,7 +687,7 @@ WERROR _PNP_ModifyResDes(struct pipes_struct *p,
+ WERROR _PNP_DetectResourceLimit(struct pipes_struct *p,
+ 				struct PNP_DetectResourceLimit *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -697,7 +697,7 @@ WERROR _PNP_DetectResourceLimit(struct pipes_struct *p,
+ WERROR _PNP_QueryResConfList(struct pipes_struct *p,
+ 			     struct PNP_QueryResConfList *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -707,7 +707,7 @@ WERROR _PNP_QueryResConfList(struct pipes_struct *p,
+ WERROR _PNP_SetHwProf(struct pipes_struct *p,
+ 		      struct PNP_SetHwProf *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -717,7 +717,7 @@ WERROR _PNP_SetHwProf(struct pipes_struct *p,
+ WERROR _PNP_QueryArbitratorFreeData(struct pipes_struct *p,
+ 				    struct PNP_QueryArbitratorFreeData *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -727,7 +727,7 @@ WERROR _PNP_QueryArbitratorFreeData(struct pipes_struct *p,
+ WERROR _PNP_QueryArbitratorFreeSize(struct pipes_struct *p,
+ 				    struct PNP_QueryArbitratorFreeSize *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -737,7 +737,7 @@ WERROR _PNP_QueryArbitratorFreeSize(struct pipes_struct *p,
+ WERROR _PNP_RunDetection(struct pipes_struct *p,
+ 			 struct PNP_RunDetection *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -747,7 +747,7 @@ WERROR _PNP_RunDetection(struct pipes_struct *p,
+ WERROR _PNP_RegisterNotification(struct pipes_struct *p,
+ 				 struct PNP_RegisterNotification *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -757,7 +757,7 @@ WERROR _PNP_RegisterNotification(struct pipes_struct *p,
+ WERROR _PNP_UnregisterNotification(struct pipes_struct *p,
+ 				   struct PNP_UnregisterNotification *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -767,7 +767,7 @@ WERROR _PNP_UnregisterNotification(struct pipes_struct *p,
+ WERROR _PNP_GetCustomDevProp(struct pipes_struct *p,
+ 			     struct PNP_GetCustomDevProp *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -777,7 +777,7 @@ WERROR _PNP_GetCustomDevProp(struct pipes_struct *p,
+ WERROR _PNP_GetVersionInternal(struct pipes_struct *p,
+ 			       struct PNP_GetVersionInternal *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -787,7 +787,7 @@ WERROR _PNP_GetVersionInternal(struct pipes_struct *p,
+ WERROR _PNP_GetBlockedDriverInfo(struct pipes_struct *p,
+ 				 struct PNP_GetBlockedDriverInfo *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -797,6 +797,6 @@ WERROR _PNP_GetBlockedDriverInfo(struct pipes_struct *p,
+ WERROR _PNP_GetServerSideDeviceInstallFlags(struct pipes_struct *p,
+ 					    struct PNP_GetServerSideDeviceInstallFlags *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+diff --git a/source3/rpc_server/rpc_handles.c b/source3/rpc_server/rpc_handles.c
+index 0c2789e..d3393ec 100644
+--- a/source3/rpc_server/rpc_handles.c
++++ b/source3/rpc_server/rpc_handles.c
+@@ -242,7 +242,7 @@ static struct dcesrv_handle *find_policy_by_hnd_internal(struct pipes_struct *p,
+ 	DEBUG(4,("Policy not found: "));
+ 	dump_data(4, (uint8_t *)hnd, sizeof(*hnd));
+ 
+-	p->bad_handle_fault_state = true;
++	p->fault_state = DCERPC_FAULT_CONTEXT_MISMATCH;
+ 
+ 	return NULL;
+ }
+diff --git a/source3/rpc_server/rpc_ncacn_np.c b/source3/rpc_server/rpc_ncacn_np.c
+index 87f36fc..efdee27 100644
+--- a/source3/rpc_server/rpc_ncacn_np.c
++++ b/source3/rpc_server/rpc_ncacn_np.c
+@@ -216,24 +216,13 @@ static NTSTATUS rpcint_dispatch(struct pipes_struct *p,
+ 	}
+ 
+ 	if (p->fault_state) {
+-		p->fault_state = false;
+-		data_blob_free(&p->out_data.rdata);
+-		talloc_free_children(p->mem_ctx);
+-		return NT_STATUS_RPC_CALL_FAILED;
+-	}
+-
+-	if (p->bad_handle_fault_state) {
+-		p->bad_handle_fault_state = false;
+-		data_blob_free(&p->out_data.rdata);
+-		talloc_free_children(p->mem_ctx);
+-		return NT_STATUS_RPC_SS_CONTEXT_MISMATCH;
+-	}
++		NTSTATUS status;
+ 
+-	if (p->rng_fault_state) {
+-		p->rng_fault_state = false;
++		status = NT_STATUS(p->fault_state);
++		p->fault_state = 0;
+ 		data_blob_free(&p->out_data.rdata);
+ 		talloc_free_children(p->mem_ctx);
+-		return NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE;
++		return status;
+ 	}
+ 
+ 	*out_data = p->out_data.rdata;
+diff --git a/source3/rpc_server/samr/srv_samr_nt.c b/source3/rpc_server/samr/srv_samr_nt.c
+index 2519a3f..0984984 100644
+--- a/source3/rpc_server/samr/srv_samr_nt.c
++++ b/source3/rpc_server/samr/srv_samr_nt.c
+@@ -6682,7 +6682,7 @@ NTSTATUS _samr_ValidatePassword(struct pipes_struct *p,
+ NTSTATUS _samr_Shutdown(struct pipes_struct *p,
+ 			struct samr_Shutdown *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+@@ -6692,7 +6692,7 @@ NTSTATUS _samr_Shutdown(struct pipes_struct *p,
+ NTSTATUS _samr_SetMemberAttributesOfGroup(struct pipes_struct *p,
+ 					  struct samr_SetMemberAttributesOfGroup *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+@@ -6702,6 +6702,7 @@ NTSTATUS _samr_SetMemberAttributesOfGroup(struct pipes_struct *p,
+ NTSTATUS _samr_TestPrivateFunctionsDomain(struct pipes_struct *p,
+ 					  struct samr_TestPrivateFunctionsDomain *r)
+ {
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+@@ -6711,6 +6712,7 @@ NTSTATUS _samr_TestPrivateFunctionsDomain(struct pipes_struct *p,
+ NTSTATUS _samr_TestPrivateFunctionsUser(struct pipes_struct *p,
+ 					struct samr_TestPrivateFunctionsUser *r)
+ {
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+@@ -6720,7 +6722,7 @@ NTSTATUS _samr_TestPrivateFunctionsUser(struct pipes_struct *p,
+ NTSTATUS _samr_AddMultipleMembersToAlias(struct pipes_struct *p,
+ 					 struct samr_AddMultipleMembersToAlias *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+@@ -6730,7 +6732,7 @@ NTSTATUS _samr_AddMultipleMembersToAlias(struct pipes_struct *p,
+ NTSTATUS _samr_RemoveMultipleMembersFromAlias(struct pipes_struct *p,
+ 					      struct samr_RemoveMultipleMembersFromAlias *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+@@ -6740,7 +6742,7 @@ NTSTATUS _samr_RemoveMultipleMembersFromAlias(struct pipes_struct *p,
+ NTSTATUS _samr_SetBootKeyInformation(struct pipes_struct *p,
+ 				     struct samr_SetBootKeyInformation *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+@@ -6750,7 +6752,7 @@ NTSTATUS _samr_SetBootKeyInformation(struct pipes_struct *p,
+ NTSTATUS _samr_GetBootKeyInformation(struct pipes_struct *p,
+ 				     struct samr_GetBootKeyInformation *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
+@@ -6760,6 +6762,6 @@ NTSTATUS _samr_GetBootKeyInformation(struct pipes_struct *p,
+ NTSTATUS _samr_SetDsrmPassword(struct pipes_struct *p,
+ 			       struct samr_SetDsrmPassword *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+diff --git a/source3/rpc_server/spoolss/srv_spoolss_nt.c b/source3/rpc_server/spoolss/srv_spoolss_nt.c
+index 8372c43..181a7b5 100644
+--- a/source3/rpc_server/spoolss/srv_spoolss_nt.c
++++ b/source3/rpc_server/spoolss/srv_spoolss_nt.c
+@@ -10156,7 +10156,7 @@ WERROR _spoolss_AddPort(struct pipes_struct *p,
+ WERROR _spoolss_GetPrinterDriver(struct pipes_struct *p,
+ 				 struct spoolss_GetPrinterDriver *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10167,7 +10167,7 @@ WERROR _spoolss_GetPrinterDriver(struct pipes_struct *p,
+ WERROR _spoolss_ReadPrinter(struct pipes_struct *p,
+ 			    struct spoolss_ReadPrinter *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10178,7 +10178,7 @@ WERROR _spoolss_ReadPrinter(struct pipes_struct *p,
+ WERROR _spoolss_WaitForPrinterChange(struct pipes_struct *p,
+ 				     struct spoolss_WaitForPrinterChange *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10189,7 +10189,7 @@ WERROR _spoolss_WaitForPrinterChange(struct pipes_struct *p,
+ WERROR _spoolss_ConfigurePort(struct pipes_struct *p,
+ 			      struct spoolss_ConfigurePort *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10200,7 +10200,7 @@ WERROR _spoolss_ConfigurePort(struct pipes_struct *p,
+ WERROR _spoolss_DeletePort(struct pipes_struct *p,
+ 			   struct spoolss_DeletePort *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10211,7 +10211,7 @@ WERROR _spoolss_DeletePort(struct pipes_struct *p,
+ WERROR _spoolss_CreatePrinterIC(struct pipes_struct *p,
+ 				struct spoolss_CreatePrinterIC *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10222,7 +10222,7 @@ WERROR _spoolss_CreatePrinterIC(struct pipes_struct *p,
+ WERROR _spoolss_PlayGDIScriptOnPrinterIC(struct pipes_struct *p,
+ 					 struct spoolss_PlayGDIScriptOnPrinterIC *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10233,7 +10233,7 @@ WERROR _spoolss_PlayGDIScriptOnPrinterIC(struct pipes_struct *p,
+ WERROR _spoolss_DeletePrinterIC(struct pipes_struct *p,
+ 				struct spoolss_DeletePrinterIC *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10244,7 +10244,7 @@ WERROR _spoolss_DeletePrinterIC(struct pipes_struct *p,
+ WERROR _spoolss_AddPrinterConnection(struct pipes_struct *p,
+ 				     struct spoolss_AddPrinterConnection *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10255,7 +10255,7 @@ WERROR _spoolss_AddPrinterConnection(struct pipes_struct *p,
+ WERROR _spoolss_DeletePrinterConnection(struct pipes_struct *p,
+ 					struct spoolss_DeletePrinterConnection *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10266,7 +10266,7 @@ WERROR _spoolss_DeletePrinterConnection(struct pipes_struct *p,
+ WERROR _spoolss_PrinterMessageBox(struct pipes_struct *p,
+ 				  struct spoolss_PrinterMessageBox *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10277,7 +10277,7 @@ WERROR _spoolss_PrinterMessageBox(struct pipes_struct *p,
+ WERROR _spoolss_AddMonitor(struct pipes_struct *p,
+ 			   struct spoolss_AddMonitor *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10288,7 +10288,7 @@ WERROR _spoolss_AddMonitor(struct pipes_struct *p,
+ WERROR _spoolss_DeleteMonitor(struct pipes_struct *p,
+ 			      struct spoolss_DeleteMonitor *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10299,7 +10299,7 @@ WERROR _spoolss_DeleteMonitor(struct pipes_struct *p,
+ WERROR _spoolss_DeletePrintProcessor(struct pipes_struct *p,
+ 				     struct spoolss_DeletePrintProcessor *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10310,7 +10310,7 @@ WERROR _spoolss_DeletePrintProcessor(struct pipes_struct *p,
+ WERROR _spoolss_AddPrintProvidor(struct pipes_struct *p,
+ 				 struct spoolss_AddPrintProvidor *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10321,7 +10321,7 @@ WERROR _spoolss_AddPrintProvidor(struct pipes_struct *p,
+ WERROR _spoolss_DeletePrintProvidor(struct pipes_struct *p,
+ 				    struct spoolss_DeletePrintProvidor *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10332,7 +10332,7 @@ WERROR _spoolss_DeletePrintProvidor(struct pipes_struct *p,
+ WERROR _spoolss_FindFirstPrinterChangeNotification(struct pipes_struct *p,
+ 						   struct spoolss_FindFirstPrinterChangeNotification *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10343,7 +10343,7 @@ WERROR _spoolss_FindFirstPrinterChangeNotification(struct pipes_struct *p,
+ WERROR _spoolss_FindNextPrinterChangeNotification(struct pipes_struct *p,
+ 						  struct spoolss_FindNextPrinterChangeNotification *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10354,7 +10354,7 @@ WERROR _spoolss_FindNextPrinterChangeNotification(struct pipes_struct *p,
+ WERROR _spoolss_RouterFindFirstPrinterChangeNotificationOld(struct pipes_struct *p,
+ 							    struct spoolss_RouterFindFirstPrinterChangeNotificationOld *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10365,7 +10365,7 @@ WERROR _spoolss_RouterFindFirstPrinterChangeNotificationOld(struct pipes_struct
+ WERROR _spoolss_ReplyOpenPrinter(struct pipes_struct *p,
+ 				 struct spoolss_ReplyOpenPrinter *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10376,7 +10376,7 @@ WERROR _spoolss_ReplyOpenPrinter(struct pipes_struct *p,
+ WERROR _spoolss_RouterReplyPrinter(struct pipes_struct *p,
+ 				   struct spoolss_RouterReplyPrinter *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10387,7 +10387,7 @@ WERROR _spoolss_RouterReplyPrinter(struct pipes_struct *p,
+ WERROR _spoolss_ReplyClosePrinter(struct pipes_struct *p,
+ 				  struct spoolss_ReplyClosePrinter *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10398,7 +10398,7 @@ WERROR _spoolss_ReplyClosePrinter(struct pipes_struct *p,
+ WERROR _spoolss_AddPortEx(struct pipes_struct *p,
+ 			  struct spoolss_AddPortEx *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10409,7 +10409,7 @@ WERROR _spoolss_AddPortEx(struct pipes_struct *p,
+ WERROR _spoolss_RouterFindFirstPrinterChangeNotification(struct pipes_struct *p,
+ 							 struct spoolss_RouterFindFirstPrinterChangeNotification *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10420,7 +10420,7 @@ WERROR _spoolss_RouterFindFirstPrinterChangeNotification(struct pipes_struct *p,
+ WERROR _spoolss_SpoolerInit(struct pipes_struct *p,
+ 			    struct spoolss_SpoolerInit *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10431,7 +10431,7 @@ WERROR _spoolss_SpoolerInit(struct pipes_struct *p,
+ WERROR _spoolss_ResetPrinterEx(struct pipes_struct *p,
+ 			       struct spoolss_ResetPrinterEx *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10442,7 +10442,7 @@ WERROR _spoolss_ResetPrinterEx(struct pipes_struct *p,
+ WERROR _spoolss_RouterReplyPrinterEx(struct pipes_struct *p,
+ 				     struct spoolss_RouterReplyPrinterEx *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10453,7 +10453,7 @@ WERROR _spoolss_RouterReplyPrinterEx(struct pipes_struct *p,
+ WERROR _spoolss_44(struct pipes_struct *p,
+ 		   struct spoolss_44 *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10464,7 +10464,7 @@ WERROR _spoolss_44(struct pipes_struct *p,
+ WERROR _spoolss_SetPort(struct pipes_struct *p,
+ 			struct spoolss_SetPort *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10475,7 +10475,7 @@ WERROR _spoolss_SetPort(struct pipes_struct *p,
+ WERROR _spoolss_4a(struct pipes_struct *p,
+ 		   struct spoolss_4a *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10486,7 +10486,7 @@ WERROR _spoolss_4a(struct pipes_struct *p,
+ WERROR _spoolss_4b(struct pipes_struct *p,
+ 		   struct spoolss_4b *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10497,7 +10497,7 @@ WERROR _spoolss_4b(struct pipes_struct *p,
+ WERROR _spoolss_4c(struct pipes_struct *p,
+ 		   struct spoolss_4c *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10508,7 +10508,7 @@ WERROR _spoolss_4c(struct pipes_struct *p,
+ WERROR _spoolss_53(struct pipes_struct *p,
+ 		   struct spoolss_53 *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10519,7 +10519,7 @@ WERROR _spoolss_53(struct pipes_struct *p,
+ WERROR _spoolss_AddPerMachineConnection(struct pipes_struct *p,
+ 					struct spoolss_AddPerMachineConnection *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10530,7 +10530,7 @@ WERROR _spoolss_AddPerMachineConnection(struct pipes_struct *p,
+ WERROR _spoolss_DeletePerMachineConnection(struct pipes_struct *p,
+ 					   struct spoolss_DeletePerMachineConnection *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10541,7 +10541,7 @@ WERROR _spoolss_DeletePerMachineConnection(struct pipes_struct *p,
+ WERROR _spoolss_EnumPerMachineConnections(struct pipes_struct *p,
+ 					  struct spoolss_EnumPerMachineConnections *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10552,7 +10552,7 @@ WERROR _spoolss_EnumPerMachineConnections(struct pipes_struct *p,
+ WERROR _spoolss_5a(struct pipes_struct *p,
+ 		   struct spoolss_5a *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10563,7 +10563,7 @@ WERROR _spoolss_5a(struct pipes_struct *p,
+ WERROR _spoolss_5b(struct pipes_struct *p,
+ 		   struct spoolss_5b *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10574,7 +10574,7 @@ WERROR _spoolss_5b(struct pipes_struct *p,
+ WERROR _spoolss_5c(struct pipes_struct *p,
+ 		   struct spoolss_5c *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10585,7 +10585,7 @@ WERROR _spoolss_5c(struct pipes_struct *p,
+ WERROR _spoolss_5d(struct pipes_struct *p,
+ 		   struct spoolss_5d *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10596,7 +10596,7 @@ WERROR _spoolss_5d(struct pipes_struct *p,
+ WERROR _spoolss_5e(struct pipes_struct *p,
+ 		   struct spoolss_5e *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10607,7 +10607,7 @@ WERROR _spoolss_5e(struct pipes_struct *p,
+ WERROR _spoolss_5f(struct pipes_struct *p,
+ 		   struct spoolss_5f *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10618,7 +10618,7 @@ WERROR _spoolss_5f(struct pipes_struct *p,
+ WERROR _spoolss_60(struct pipes_struct *p,
+ 		   struct spoolss_60 *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10629,7 +10629,7 @@ WERROR _spoolss_60(struct pipes_struct *p,
+ WERROR _spoolss_61(struct pipes_struct *p,
+ 		   struct spoolss_61 *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10640,7 +10640,7 @@ WERROR _spoolss_61(struct pipes_struct *p,
+ WERROR _spoolss_62(struct pipes_struct *p,
+ 		   struct spoolss_62 *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10651,7 +10651,7 @@ WERROR _spoolss_62(struct pipes_struct *p,
+ WERROR _spoolss_63(struct pipes_struct *p,
+ 		   struct spoolss_63 *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10662,7 +10662,7 @@ WERROR _spoolss_63(struct pipes_struct *p,
+ WERROR _spoolss_64(struct pipes_struct *p,
+ 		   struct spoolss_64 *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10673,7 +10673,7 @@ WERROR _spoolss_64(struct pipes_struct *p,
+ WERROR _spoolss_65(struct pipes_struct *p,
+ 		   struct spoolss_65 *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10684,7 +10684,7 @@ WERROR _spoolss_65(struct pipes_struct *p,
+ WERROR _spoolss_GetCorePrinterDrivers(struct pipes_struct *p,
+ 				      struct spoolss_GetCorePrinterDrivers *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10695,7 +10695,7 @@ WERROR _spoolss_GetCorePrinterDrivers(struct pipes_struct *p,
+ WERROR _spoolss_67(struct pipes_struct *p,
+ 		   struct spoolss_67 *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10706,7 +10706,7 @@ WERROR _spoolss_67(struct pipes_struct *p,
+ WERROR _spoolss_GetPrinterDriverPackagePath(struct pipes_struct *p,
+ 					    struct spoolss_GetPrinterDriverPackagePath *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10717,7 +10717,7 @@ WERROR _spoolss_GetPrinterDriverPackagePath(struct pipes_struct *p,
+ WERROR _spoolss_69(struct pipes_struct *p,
+ 		   struct spoolss_69 *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10728,7 +10728,7 @@ WERROR _spoolss_69(struct pipes_struct *p,
+ WERROR _spoolss_6a(struct pipes_struct *p,
+ 		   struct spoolss_6a *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10739,7 +10739,7 @@ WERROR _spoolss_6a(struct pipes_struct *p,
+ WERROR _spoolss_6b(struct pipes_struct *p,
+ 		   struct spoolss_6b *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10750,7 +10750,7 @@ WERROR _spoolss_6b(struct pipes_struct *p,
+ WERROR _spoolss_6c(struct pipes_struct *p,
+ 		   struct spoolss_6c *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -10761,6 +10761,6 @@ WERROR _spoolss_6c(struct pipes_struct *p,
+ WERROR _spoolss_6d(struct pipes_struct *p,
+ 		   struct spoolss_6d *r)
+ {
+-	p->rng_fault_state = true;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
+index 3d49d79..d659705 100644
+--- a/source3/rpc_server/srv_pipe.c
++++ b/source3/rpc_server/srv_pipe.c
+@@ -203,7 +203,7 @@ bool create_next_pdu(struct pipes_struct *p)
+ 	 * the pipe gets closed. JRA.
+ 	 */
+ 	if (p->fault_state) {
+-		setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
++		setup_fault_pdu(p, NT_STATUS(p->fault_state));
+ 		return true;
+ 	}
+ 
+@@ -1697,18 +1697,11 @@ static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
+ 		return False;
+ 	}
+ 
+-	if (p->bad_handle_fault_state) {
+-		DEBUG(4,("api_rpcTNP: bad handle fault return.\n"));
+-		p->bad_handle_fault_state = False;
+-		setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_CONTEXT_MISMATCH));
+-		return True;
+-	}
+-
+-	if (p->rng_fault_state) {
+-		DEBUG(4, ("api_rpcTNP: rng fault return\n"));
+-		p->rng_fault_state = False;
+-		setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
+-		return True;
++	if (p->fault_state) {
++		DEBUG(4,("api_rpcTNP: fault(%d) return.\n", p->fault_state));
++		setup_fault_pdu(p, NT_STATUS(p->fault_state));
++		p->fault_state = 0;
++		return true;
+ 	}
+ 
+ 	if (DEBUGLEVEL >= 50) {
+@@ -1763,9 +1756,9 @@ void set_incoming_fault(struct pipes_struct *p)
+ 	data_blob_free(&p->in_data.data);
+ 	p->in_data.pdu_needed_len = 0;
+ 	p->in_data.pdu.length = 0;
+-	p->fault_state = True;
+-	DEBUG(10, ("set_incoming_fault: Setting fault state on pipe %s\n",
+-		   get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
++	p->fault_state = DCERPC_FAULT_CANT_PERFORM;
++
++	DEBUG(10, ("Setting fault state\n"));
+ }
+ 
+ static NTSTATUS dcesrv_auth_request(struct pipe_auth_data *auth,
+diff --git a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
+index b9345d6..71fd0e2 100644
+--- a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
++++ b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
+@@ -2548,244 +2548,244 @@ WERROR _srvsvc_NetFileClose(struct pipes_struct *p,
+ WERROR _srvsvc_NetCharDevEnum(struct pipes_struct *p,
+ 			      struct srvsvc_NetCharDevEnum *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _srvsvc_NetCharDevGetInfo(struct pipes_struct *p,
+ 				 struct srvsvc_NetCharDevGetInfo *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _srvsvc_NetCharDevControl(struct pipes_struct *p,
+ 				 struct srvsvc_NetCharDevControl *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _srvsvc_NetCharDevQEnum(struct pipes_struct *p,
+ 			       struct srvsvc_NetCharDevQEnum *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _srvsvc_NetCharDevQGetInfo(struct pipes_struct *p,
+ 				  struct srvsvc_NetCharDevQGetInfo *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _srvsvc_NetCharDevQSetInfo(struct pipes_struct *p,
+ 				  struct srvsvc_NetCharDevQSetInfo *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _srvsvc_NetCharDevQPurge(struct pipes_struct *p,
+ 				struct srvsvc_NetCharDevQPurge *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _srvsvc_NetCharDevQPurgeSelf(struct pipes_struct *p,
+ 				    struct srvsvc_NetCharDevQPurgeSelf *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _srvsvc_NetFileGetInfo(struct pipes_struct *p,
+ 			      struct srvsvc_NetFileGetInfo *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _srvsvc_NetShareCheck(struct pipes_struct *p,
+ 			     struct srvsvc_NetShareCheck *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _srvsvc_NetServerStatisticsGet(struct pipes_struct *p,
+ 				      struct srvsvc_NetServerStatisticsGet *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _srvsvc_NetTransportAdd(struct pipes_struct *p,
+ 			       struct srvsvc_NetTransportAdd *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _srvsvc_NetTransportEnum(struct pipes_struct *p,
+ 				struct srvsvc_NetTransportEnum *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _srvsvc_NetTransportDel(struct pipes_struct *p,
+ 			       struct srvsvc_NetTransportDel *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _srvsvc_NetSetServiceBits(struct pipes_struct *p,
+ 				 struct srvsvc_NetSetServiceBits *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _srvsvc_NetPathType(struct pipes_struct *p,
+ 			   struct srvsvc_NetPathType *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _srvsvc_NetPathCanonicalize(struct pipes_struct *p,
+ 				   struct srvsvc_NetPathCanonicalize *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _srvsvc_NetPathCompare(struct pipes_struct *p,
+ 			      struct srvsvc_NetPathCompare *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _srvsvc_NETRPRNAMECANONICALIZE(struct pipes_struct *p,
+ 				      struct srvsvc_NETRPRNAMECANONICALIZE *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _srvsvc_NetPRNameCompare(struct pipes_struct *p,
+ 				struct srvsvc_NetPRNameCompare *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _srvsvc_NetShareDelStart(struct pipes_struct *p,
+ 				struct srvsvc_NetShareDelStart *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _srvsvc_NetShareDelCommit(struct pipes_struct *p,
+ 				 struct srvsvc_NetShareDelCommit *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _srvsvc_NetServerTransportAddEx(struct pipes_struct *p,
+ 				       struct srvsvc_NetServerTransportAddEx *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _srvsvc_NetServerSetServiceBitsEx(struct pipes_struct *p,
+ 					 struct srvsvc_NetServerSetServiceBitsEx *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _srvsvc_NETRDFSGETVERSION(struct pipes_struct *p,
+ 				 struct srvsvc_NETRDFSGETVERSION *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(struct pipes_struct *p,
+ 					   struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(struct pipes_struct *p,
+ 					   struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(struct pipes_struct *p,
+ 					  struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _srvsvc_NETRDFSSETSERVERINFO(struct pipes_struct *p,
+ 				    struct srvsvc_NETRDFSSETSERVERINFO *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _srvsvc_NETRDFSCREATEEXITPOINT(struct pipes_struct *p,
+ 				      struct srvsvc_NETRDFSCREATEEXITPOINT *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _srvsvc_NETRDFSDELETEEXITPOINT(struct pipes_struct *p,
+ 				      struct srvsvc_NETRDFSDELETEEXITPOINT *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _srvsvc_NETRDFSMODIFYPREFIX(struct pipes_struct *p,
+ 				   struct srvsvc_NETRDFSMODIFYPREFIX *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(struct pipes_struct *p,
+ 				     struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(struct pipes_struct *p,
+ 					    struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(struct pipes_struct *p,
+ 					struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+diff --git a/source3/rpc_server/svcctl/srv_svcctl_nt.c b/source3/rpc_server/svcctl/srv_svcctl_nt.c
+index 044dd15..18fefad 100644
+--- a/source3/rpc_server/svcctl/srv_svcctl_nt.c
++++ b/source3/rpc_server/svcctl/srv_svcctl_nt.c
+@@ -1004,195 +1004,195 @@ WERROR _svcctl_SetServiceObjectSecurity(struct pipes_struct *p,
+ WERROR _svcctl_DeleteService(struct pipes_struct *p,
+ 			     struct svcctl_DeleteService *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _svcctl_SetServiceStatus(struct pipes_struct *p,
+ 				struct svcctl_SetServiceStatus *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _svcctl_NotifyBootConfigStatus(struct pipes_struct *p,
+ 				      struct svcctl_NotifyBootConfigStatus *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _svcctl_SCSetServiceBitsW(struct pipes_struct *p,
+ 				 struct svcctl_SCSetServiceBitsW *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _svcctl_ChangeServiceConfigW(struct pipes_struct *p,
+ 				    struct svcctl_ChangeServiceConfigW *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _svcctl_CreateServiceW(struct pipes_struct *p,
+ 			      struct svcctl_CreateServiceW *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _svcctl_QueryServiceLockStatusW(struct pipes_struct *p,
+ 				       struct svcctl_QueryServiceLockStatusW *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _svcctl_GetServiceKeyNameW(struct pipes_struct *p,
+ 				  struct svcctl_GetServiceKeyNameW *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _svcctl_SCSetServiceBitsA(struct pipes_struct *p,
+ 				 struct svcctl_SCSetServiceBitsA *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _svcctl_ChangeServiceConfigA(struct pipes_struct *p,
+ 				    struct svcctl_ChangeServiceConfigA *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _svcctl_CreateServiceA(struct pipes_struct *p,
+ 			      struct svcctl_CreateServiceA *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _svcctl_EnumDependentServicesA(struct pipes_struct *p,
+ 				      struct svcctl_EnumDependentServicesA *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _svcctl_EnumServicesStatusA(struct pipes_struct *p,
+ 				   struct svcctl_EnumServicesStatusA *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _svcctl_OpenSCManagerA(struct pipes_struct *p,
+ 			      struct svcctl_OpenSCManagerA *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _svcctl_OpenServiceA(struct pipes_struct *p,
+ 			    struct svcctl_OpenServiceA *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _svcctl_QueryServiceConfigA(struct pipes_struct *p,
+ 				   struct svcctl_QueryServiceConfigA *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _svcctl_QueryServiceLockStatusA(struct pipes_struct *p,
+ 				       struct svcctl_QueryServiceLockStatusA *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _svcctl_StartServiceA(struct pipes_struct *p,
+ 			     struct svcctl_StartServiceA *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _svcctl_GetServiceDisplayNameA(struct pipes_struct *p,
+ 				      struct svcctl_GetServiceDisplayNameA *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _svcctl_GetServiceKeyNameA(struct pipes_struct *p,
+ 				  struct svcctl_GetServiceKeyNameA *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _svcctl_GetCurrentGroupeStateW(struct pipes_struct *p,
+ 				      struct svcctl_GetCurrentGroupeStateW *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _svcctl_EnumServiceGroupW(struct pipes_struct *p,
+ 				 struct svcctl_EnumServiceGroupW *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _svcctl_ChangeServiceConfig2A(struct pipes_struct *p,
+ 				     struct svcctl_ChangeServiceConfig2A *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _svcctl_ChangeServiceConfig2W(struct pipes_struct *p,
+ 				     struct svcctl_ChangeServiceConfig2W *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _svcctl_QueryServiceConfig2A(struct pipes_struct *p,
+ 				    struct svcctl_QueryServiceConfig2A *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _EnumServicesStatusExA(struct pipes_struct *p,
+ 			      struct EnumServicesStatusExA *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _EnumServicesStatusExW(struct pipes_struct *p,
+ 			      struct EnumServicesStatusExW *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+ WERROR _svcctl_SCSendTSMessage(struct pipes_struct *p,
+ 			       struct svcctl_SCSendTSMessage *r)
+ {
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+diff --git a/source3/rpc_server/winreg/srv_winreg_nt.c b/source3/rpc_server/winreg/srv_winreg_nt.c
+index 1b3cab8..34898ea 100644
+--- a/source3/rpc_server/winreg/srv_winreg_nt.c
++++ b/source3/rpc_server/winreg/srv_winreg_nt.c
+@@ -760,7 +760,7 @@ WERROR _winreg_SaveKeyEx(struct pipes_struct *p,
+ 	/* fill in your code here if you think this call should
+ 	   do anything */
+ 
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -948,7 +948,7 @@ WERROR _winreg_UnLoadKey(struct pipes_struct *p,
+ 	/* fill in your code here if you think this call should
+ 	   do anything */
+ 
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -962,7 +962,7 @@ WERROR _winreg_ReplaceKey(struct pipes_struct *p,
+ 	/* fill in your code here if you think this call should
+ 	   do anything */
+ 
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -976,7 +976,7 @@ WERROR _winreg_LoadKey(struct pipes_struct *p,
+ 	/* fill in your code here if you think this call should
+ 	   do anything */
+ 
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -1139,6 +1139,6 @@ WERROR _winreg_DeleteKeyEx(struct pipes_struct *p,
+ 	/* fill in your code here if you think this call should
+ 	   do anything */
+ 
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+diff --git a/source3/rpc_server/wkssvc/srv_wkssvc_nt.c b/source3/rpc_server/wkssvc/srv_wkssvc_nt.c
+index 2d3ec1e..be16250 100644
+--- a/source3/rpc_server/wkssvc/srv_wkssvc_nt.c
++++ b/source3/rpc_server/wkssvc/srv_wkssvc_nt.c
+@@ -405,7 +405,7 @@ WERROR _wkssvc_NetWkstaSetInfo(struct pipes_struct *p,
+ 			       struct wkssvc_NetWkstaSetInfo *r)
+ {
+ 	/* FIXME: Add implementation code here */
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -608,7 +608,7 @@ WERROR _wkssvc_NetrWkstaUserGetInfo(struct pipes_struct *p,
+ 				    struct wkssvc_NetrWkstaUserGetInfo *r)
+ {
+ 	/* FIXME: Add implementation code here */
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -619,7 +619,7 @@ WERROR _wkssvc_NetrWkstaUserSetInfo(struct pipes_struct *p,
+ 				    struct wkssvc_NetrWkstaUserSetInfo *r)
+ {
+ 	/* FIXME: Add implementation code here */
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -630,7 +630,7 @@ WERROR _wkssvc_NetWkstaTransportEnum(struct pipes_struct *p,
+ 				     struct wkssvc_NetWkstaTransportEnum *r)
+ {
+ 	/* FIXME: Add implementation code here */
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -641,7 +641,7 @@ WERROR _wkssvc_NetrWkstaTransportAdd(struct pipes_struct *p,
+ 				     struct wkssvc_NetrWkstaTransportAdd *r)
+ {
+ 	/* FIXME: Add implementation code here */
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -652,7 +652,7 @@ WERROR _wkssvc_NetrWkstaTransportDel(struct pipes_struct *p,
+ 				     struct wkssvc_NetrWkstaTransportDel *r)
+ {
+ 	/* FIXME: Add implementation code here */
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -663,7 +663,7 @@ WERROR _wkssvc_NetrUseAdd(struct pipes_struct *p,
+ 			  struct wkssvc_NetrUseAdd *r)
+ {
+ 	/* FIXME: Add implementation code here */
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -674,7 +674,7 @@ WERROR _wkssvc_NetrUseGetInfo(struct pipes_struct *p,
+ 			      struct wkssvc_NetrUseGetInfo *r)
+ {
+ 	/* FIXME: Add implementation code here */
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -685,7 +685,7 @@ WERROR _wkssvc_NetrUseDel(struct pipes_struct *p,
+ 			  struct wkssvc_NetrUseDel *r)
+ {
+ 	/* FIXME: Add implementation code here */
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -696,7 +696,7 @@ WERROR _wkssvc_NetrUseEnum(struct pipes_struct *p,
+ 			   struct wkssvc_NetrUseEnum *r)
+ {
+ 	/* FIXME: Add implementation code here */
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -707,7 +707,7 @@ WERROR _wkssvc_NetrMessageBufferSend(struct pipes_struct *p,
+ 				     struct wkssvc_NetrMessageBufferSend *r)
+ {
+ 	/* FIXME: Add implementation code here */
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -718,7 +718,7 @@ WERROR _wkssvc_NetrWorkstationStatisticsGet(struct pipes_struct *p,
+ 					    struct wkssvc_NetrWorkstationStatisticsGet *r)
+ {
+ 	/* FIXME: Add implementation code here */
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -729,7 +729,7 @@ WERROR _wkssvc_NetrLogonDomainNameAdd(struct pipes_struct *p,
+ 				      struct wkssvc_NetrLogonDomainNameAdd *r)
+ {
+ 	/* FIXME: Add implementation code here */
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -740,7 +740,7 @@ WERROR _wkssvc_NetrLogonDomainNameDel(struct pipes_struct *p,
+ 				      struct wkssvc_NetrLogonDomainNameDel *r)
+ {
+ 	/* FIXME: Add implementation code here */
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -751,7 +751,7 @@ WERROR _wkssvc_NetrJoinDomain(struct pipes_struct *p,
+ 			      struct wkssvc_NetrJoinDomain *r)
+ {
+ 	/* FIXME: Add implementation code here */
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -762,7 +762,7 @@ WERROR _wkssvc_NetrUnjoinDomain(struct pipes_struct *p,
+ 				struct wkssvc_NetrUnjoinDomain *r)
+ {
+ 	/* FIXME: Add implementation code here */
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -773,7 +773,7 @@ WERROR _wkssvc_NetrRenameMachineInDomain(struct pipes_struct *p,
+ 					 struct wkssvc_NetrRenameMachineInDomain *r)
+ {
+ 	/* FIXME: Add implementation code here */
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -784,7 +784,7 @@ WERROR _wkssvc_NetrValidateName(struct pipes_struct *p,
+ 				struct wkssvc_NetrValidateName *r)
+ {
+ 	/* FIXME: Add implementation code here */
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -795,7 +795,7 @@ WERROR _wkssvc_NetrGetJoinInformation(struct pipes_struct *p,
+ 				      struct wkssvc_NetrGetJoinInformation *r)
+ {
+ 	/* FIXME: Add implementation code here */
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -806,7 +806,7 @@ WERROR _wkssvc_NetrGetJoinableOus(struct pipes_struct *p,
+ 				  struct wkssvc_NetrGetJoinableOus *r)
+ {
+ 	/* FIXME: Add implementation code here */
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -962,6 +962,7 @@ WERROR _wkssvc_NetrRenameMachineInDomain2(struct pipes_struct *p,
+ 					  struct wkssvc_NetrRenameMachineInDomain2 *r)
+ {
+ 	/* for now just return not supported */
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -972,7 +973,7 @@ WERROR _wkssvc_NetrValidateName2(struct pipes_struct *p,
+ 				 struct wkssvc_NetrValidateName2 *r)
+ {
+ 	/* FIXME: Add implementation code here */
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -983,7 +984,7 @@ WERROR _wkssvc_NetrGetJoinableOus2(struct pipes_struct *p,
+ 				   struct wkssvc_NetrGetJoinableOus2 *r)
+ {
+ 	/* FIXME: Add implementation code here */
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -994,7 +995,7 @@ WERROR _wkssvc_NetrAddAlternateComputerName(struct pipes_struct *p,
+ 					    struct wkssvc_NetrAddAlternateComputerName *r)
+ {
+ 	/* FIXME: Add implementation code here */
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -1005,7 +1006,7 @@ WERROR _wkssvc_NetrRemoveAlternateComputerName(struct pipes_struct *p,
+ 					       struct wkssvc_NetrRemoveAlternateComputerName *r)
+ {
+ 	/* FIXME: Add implementation code here */
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -1016,7 +1017,7 @@ WERROR _wkssvc_NetrSetPrimaryComputername(struct pipes_struct *p,
+ 					  struct wkssvc_NetrSetPrimaryComputername *r)
+ {
+ 	/* FIXME: Add implementation code here */
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+ 
+@@ -1027,6 +1028,6 @@ WERROR _wkssvc_NetrEnumerateComputerNames(struct pipes_struct *p,
+ 					  struct wkssvc_NetrEnumerateComputerNames *r)
+ {
+ 	/* FIXME: Add implementation code here */
+-	p->rng_fault_state = True;
++	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ 	return WERR_NOT_SUPPORTED;
+ }
+-- 
+2.8.1
+
+
+From 079831e3d8fe62ad00f31a67688251ea4991c037 Mon Sep 17 00:00:00 2001
+From: Jeremy Allison <jra at samba.org>
+Date: Thu, 17 Oct 2013 14:44:35 -0700
+Subject: [PATCH 40/40] CVE-2013-4408:s3:Ensure we always check call_id when
+ validating an RPC reply.
+
+Bug: https://bugzilla.samba.org/show_bug.cgi?id=10185
+
+Signed-off-by: Jeremy Allison <jra at samba.org>
+Reviewed-by: Stefan Metzmacher <metze at samba.org>
+---
+ source3/rpc_client/cli_pipe.c | 14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c
+index 6663656..5ddabb7 100644
+--- a/source3/rpc_client/cli_pipe.c
++++ b/source3/rpc_client/cli_pipe.c
+@@ -400,6 +400,7 @@ static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx,
+ 						struct ncacn_packet *pkt,
+ 						DATA_BLOB *pdu,
+ 						uint8_t expected_pkt_type,
++						uint32_t call_id,
+ 						DATA_BLOB *rdata,
+ 						DATA_BLOB *reply_pdu)
+ {
+@@ -498,7 +499,7 @@ static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx,
+ 			  "from %s!\n",
+ 			  (unsigned int)pkt->ptype,
+ 			  rpccli_pipe_txt(talloc_tos(), cli)));
+-		return NT_STATUS_INVALID_INFO_CLASS;
++		return NT_STATUS_RPC_PROTOCOL_ERROR;
+ 	}
+ 
+ 	if (pkt->ptype != expected_pkt_type) {
+@@ -506,7 +507,15 @@ static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx,
+ 			  "RPC packet type - %u, not %u\n",
+ 			  rpccli_pipe_txt(talloc_tos(), cli),
+ 			  pkt->ptype, expected_pkt_type));
+-		return NT_STATUS_INVALID_INFO_CLASS;
++		return NT_STATUS_RPC_PROTOCOL_ERROR;
++	}
++
++	if (pkt->call_id != call_id) {
++		DEBUG(3, (__location__ ": Connection to %s got an unexpected "
++			  "RPC call_id - %u, not %u\n",
++			  rpccli_pipe_txt(talloc_tos(), cli),
++			  pkt->call_id, call_id));
++		return NT_STATUS_RPC_PROTOCOL_ERROR;
+ 	}
+ 
+ 	/* Do this just before return - we don't want to modify any rpc header
+@@ -899,6 +908,7 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
+ 						state->cli, state->pkt,
+ 						&state->incoming_frag,
+ 						state->expected_pkt_type,
++						state->call_id,
+ 						&rdata,
+ 						&state->reply_pdu);
+ 
+-- 
+2.8.1
+
diff --git a/debian/patches/series b/debian/patches/series
index 4435c04..f67b916 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -39,3 +39,10 @@ CVE-2015-5296-v3-6-bso11536.patch
 s3-smbd-fix-a-corner-case-of-the-symlink-verificatio.patch
 CVE-2015-7560-v3-6.patch
 0001-s4-torture-let-torture_suite_add_ndr_pull_test-alway.patch
+CVE-preparation-v3-6.patch
+CVE-2016-2110-v3-6.patch
+CVE-2016-2111-v3-6.patch
+CVE-2016-2112-v3-6.patch
+CVE-2016-2115-v3-6.patch
+CVE-2016-2118-v3-6.patch
+CVE-2015-5370-v3-6.patch

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-samba/samba.git




More information about the Pkg-samba-maint mailing list