From: Arne Fitzenreiter Date: Wed, 13 Apr 2016 20:20:58 +0000 (+0200) Subject: samba: import RHEL security fixes. X-Git-Tag: v2.19-core101~15 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=77ecb239d30f979d6fca595aaf79c40214bf758a;hp=5208ceedd90d01acc3cb0ef9b34903d449aedb9a;p=people%2Fpmueller%2Fipfire-2.x.git samba: import RHEL security fixes. CVE-2015-7560 CVE-2016-2110 CVE-2016-2111 CVE-2016-2112 CVE-2016-2115 CVE-2016-2118 aka Badlock CVE-2015-5370 Signed-off-by: Arne Fitzenreiter --- diff --git a/lfs/samba b/lfs/samba index f0dcf8359e..b58bf79ab2 100644 --- a/lfs/samba +++ b/lfs/samba @@ -1,7 +1,7 @@ ############################################################################### # # # IPFire.org - A linux based firewall # -# Copyright (C) 2007-2015 IPFire Team # +# Copyright (C) 2007-2016 IPFire Team # # # # 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 # @@ -32,7 +32,7 @@ DL_FROM = $(URL_IPFIRE) DIR_APP = $(DIR_SRC)/$(THISAPP) TARGET = $(DIR_INFO)/$(THISAPP) PROG = samba -PAK_VER = 60 +PAK_VER = 61 DEPS = "cups krb5" @@ -77,6 +77,18 @@ $(subst %,%_MD5,$(objects)) : $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) @$(PREBUILD) @rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar zxf $(DIR_DL)/$(DL_FILE) + + # Apply Redhat CVE patches + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/samba/CVE-2015-7560-v3-6.patch + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/samba/CVE-preparation-v3-6.patch + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/samba/CVE-2016-2110-v3-6.patch + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/samba/CVE-2016-2111-v3-6.patch + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/samba/CVE-2016-2112-v3-6.patch + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/samba/CVE-2016-2115-v3-6.patch + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/samba/CVE-2016-2118-v3-6.patch + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/samba/CVE-2015-5370-v3-6.patch + + cd $(DIR_APP)/source3 && ./autogen.sh cd $(DIR_APP)/source3 && ./configure \ --prefix=/usr \ --libdir=/usr/lib/ \ @@ -99,6 +111,7 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) --enable-cups \ --disable-avahi \ --with-syslog + cd $(DIR_APP)/source3 && make idl_full cd $(DIR_APP)/source3 && make proto && make all $(MAKETUNING) $(EXTRA_MAKE) cd $(DIR_APP)/source3 && make install cd $(DIR_APP)/source3 && chmod -v 644 /usr/include/libsmbclient.h diff --git a/src/patches/samba/CVE-2015-5370-v3-6.patch b/src/patches/samba/CVE-2015-5370-v3-6.patch new file mode 100644 index 0000000000..7af1dd3629 --- /dev/null +++ b/src/patches/samba/CVE-2015-5370-v3-6.patch @@ -0,0 +1,3080 @@ +From 8368c32cb69da82c8df36404ec8042c3046866ca Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +--- + 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 e3043ba5aafdb0605ab14b11917d497b59d82bec Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +--- + 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 397300d996299400842938131691fbbeb88c2c82 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +--- + 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 faa20091b4a456a5e29f852561f6f5e9863860e0 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +(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 c176174588c1119a11066b6188ac50cd3c9603f4 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +(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 b9ae0068be4dfc6f7d09144c353689ab01955b93 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +(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 05688274f03e6086e3ba4d7b4cb4409f9c4d9cb1 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +(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 57230961cee9e82ab060b54b5fb8c2b19f672111 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +(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 c35b0e37f7d37459f55d67a5037c08bea4d33acf Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +(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 2341eb0cf8395b1fed628ee6779207d916827a5d Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +(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 9ecba8f4635aa5dbd42e4838ce124a92395b64ab Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +(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 765c10dacf39a3c06c6b12651c205ac270e7fcea Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +(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 b58616bbcc810b076e5fd9dd976272847f832b06 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +(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 3e03b1e6d5b20c14d53763f22442bf510a8d6dcd Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +(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 fa884c266be5d808d19955f92921417f435b2957 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +(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 6d2767ad8b084590c572e90d1985ca6d7d36b188 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +(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 7400ac11282d540d4f5f80d0f58ec99beabb7d8e Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +(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 55da4653f5986989e46be6320f96590f8ebb4ef7 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +(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 893c840a1aac6711a081eb8e25f2c2a6078fc373 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +(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 a66baed0c65b7acb4d76ef9ea3ae1248a6b5773a Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +(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 e47becdf2c03d68662ab998c4608adb371ca2f08 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +(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 687a4801391c946a62d07a7bdad096a97da0d432 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +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 + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 + +Signed-off-by: Jeremy Allison +Signed-off-by: Stefan Metzmacher +Reviewed-by: Günther Deschner +(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 45701966d49ec1003f19c137a548c26915f75a99 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +(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 62b936e134a53662601b0f614f95dbca5ff7a369 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +(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 585e8aefafcb5f8c501cdf4454b375ebda82f7a6 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +(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 b16b1a5f331adc3bb2f3d0bee586ec084935a202 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +(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 642d2b7090e46a87bc94cabf29eccb09e329c125 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +(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 f4aa07176636982d9be3c0ce2452fc43a8781d47 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +(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 ef175975f587d73092461c36b10e4c9cf1805727 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +(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 49d0e60d28d3b615d4ee368cd3f260b3a6386858 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +(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 7ee6698f706e51568f53347f422ac6671cdba9a4 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +(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 79a238d0c868c7e182f49637b66f544dc1dd86da Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +(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 18a50ed6ead11287ff72cb38f100d0f2641c3e7d Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +(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 7dbaaca2a638406331d4653e1afdc18f7c8502f6 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +(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 82cd4e90c70d1ababd5fa1ee61206e37edbf40e4 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +(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 8d1fb1fcf58b08cbf27579382ea648aefb9e7dc6 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +(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 2a44cfc65f7dc1ccfd2d6a5abe5d26e94a085aa9 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +(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 68dcc277d5af506706d3fdac43891e43ccb4ceea Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +(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 8787dd5053974c1f42ae85a310e9522795f4ccfe Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +(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 bf0040fb860527cb0c54ab0ef301153bdad650c0 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +(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/src/patches/samba/CVE-2015-7560-v3-6.patch b/src/patches/samba/CVE-2015-7560-v3-6.patch new file mode 100644 index 0000000000..1cf30aecad --- /dev/null +++ b/src/patches/samba/CVE-2015-7560-v3-6.patch @@ -0,0 +1,341 @@ +From eb27f9b7bf9c1dc902d9545eecf805831bd4e46c Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Tue, 5 Jan 2016 11:18:12 -0800 +Subject: [PATCH 1/8] CVE-2015-7560: s3: smbd: Add refuse_symlink() function + that can be used to prevent operations on a symlink. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11648 + +Signed-off-by: Jeremy Allison +Reviewed-by: Michael Adam +--- + source3/smbd/trans2.c | 28 ++++++++++++++++++++++++++++ + 1 file changed, 28 insertions(+) + +diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c +index 26b6523..7f47579 100644 +--- a/source3/smbd/trans2.c ++++ b/source3/smbd/trans2.c +@@ -51,6 +51,34 @@ static char *store_file_unix_basic_info2(connection_struct *conn, + files_struct *fsp, + const SMB_STRUCT_STAT *psbuf); + ++/**************************************************************************** ++ Check if an open file handle or pathname is a symlink. ++****************************************************************************/ ++ ++static NTSTATUS refuse_symlink(connection_struct *conn, ++ const files_struct *fsp, ++ const char *name) ++{ ++ SMB_STRUCT_STAT sbuf; ++ const SMB_STRUCT_STAT *pst = NULL; ++ ++ if (fsp) { ++ pst = &fsp->fsp_name->st; ++ } else { ++ int ret = vfs_stat_smb_fname(conn, ++ name, ++ &sbuf); ++ if (ret == -1) { ++ return map_nt_error_from_unix(errno); ++ } ++ pst = &sbuf; ++ } ++ if (S_ISLNK(pst->st_ex_mode)) { ++ return NT_STATUS_ACCESS_DENIED; ++ } ++ return NT_STATUS_OK; ++} ++ + /******************************************************************** + Roundup a value to the nearest allocation roundup size boundary. + Only do this for Windows clients. +-- +2.5.0 + + +From f5b1bcc51e18bc85f376701bb4ae6894d97addfd Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Tue, 5 Jan 2016 10:38:28 -0800 +Subject: [PATCH 2/8] CVE-2015-7560: s3: smbd: Refuse to get an ACL from a + POSIX file handle on a symlink. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11648 + +Signed-off-by: Jeremy Allison +Reviewed-by: Michael Adam +--- + source3/smbd/nttrans.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c +index 4c145e0..7255600 100644 +--- a/source3/smbd/nttrans.c ++++ b/source3/smbd/nttrans.c +@@ -1925,6 +1925,12 @@ NTSTATUS smbd_do_query_security_desc(connection_struct *conn, + return NT_STATUS_ACCESS_DENIED; + } + ++ if (S_ISLNK(fsp->fsp_name->st.st_ex_mode)) { ++ DEBUG(10, ("ACL get on symlink %s denied.\n", ++ fsp_str_dbg(fsp))); ++ return NT_STATUS_ACCESS_DENIED; ++ } ++ + if (security_info_wanted & (SECINFO_DACL|SECINFO_OWNER| + SECINFO_GROUP|SECINFO_SACL)) { + /* Don't return SECINFO_LABEL if anything else was +-- +2.5.0 + + +From 8bdbe1c90c98efbd08fc70d773d236c4ba00b1ae Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Tue, 5 Jan 2016 10:52:50 -0800 +Subject: [PATCH 3/8] CVE-2015-7560: s3: smbd: Refuse to set an ACL from a + POSIX file handle on a symlink. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11648 + +Signed-off-by: Jeremy Allison +Reviewed-by: Michael Adam +--- + source3/smbd/nttrans.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c +index 7255600..d2102ca 100644 +--- a/source3/smbd/nttrans.c ++++ b/source3/smbd/nttrans.c +@@ -877,6 +877,12 @@ NTSTATUS set_sd(files_struct *fsp, struct security_descriptor *psd, + return NT_STATUS_OK; + } + ++ if (S_ISLNK(fsp->fsp_name->st.st_ex_mode)) { ++ DEBUG(10, ("ACL set on symlink %s denied.\n", ++ fsp_str_dbg(fsp))); ++ return NT_STATUS_ACCESS_DENIED; ++ } ++ + if (psd->owner_sid == NULL) { + security_info_sent &= ~SECINFO_OWNER; + } +-- +2.5.0 + + +From 612b032e2dedd3e07bbe79718ecbb3b68ffbb7a5 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Tue, 5 Jan 2016 11:22:12 -0800 +Subject: [PATCH 4/8] CVE-2015-7560: s3: smbd: Refuse to set a POSIX ACL on a + symlink. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11648 + +Signed-off-by: Jeremy Allison +Reviewed-by: Michael Adam +--- + source3/smbd/trans2.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c +index 7f47579..2f01e87 100644 +--- a/source3/smbd/trans2.c ++++ b/source3/smbd/trans2.c +@@ -6480,6 +6480,7 @@ static NTSTATUS smb_set_posix_acl(connection_struct *conn, + uint16 num_def_acls; + bool valid_file_acls = True; + bool valid_def_acls = True; ++ NTSTATUS status; + + if (total_data < SMB_POSIX_ACL_HEADER_SIZE) { + return NT_STATUS_INVALID_PARAMETER; +@@ -6507,6 +6508,11 @@ static NTSTATUS smb_set_posix_acl(connection_struct *conn, + return NT_STATUS_INVALID_PARAMETER; + } + ++ status = refuse_symlink(conn, fsp, smb_fname->base_name); ++ if (!NT_STATUS_IS_OK(status)) { ++ return status; ++ } ++ + DEBUG(10,("smb_set_posix_acl: file %s num_file_acls = %u, num_def_acls = %u\n", + smb_fname ? smb_fname_str_dbg(smb_fname) : fsp_str_dbg(fsp), + (unsigned int)num_file_acls, +-- +2.5.0 + + +From 28e6120d14e5a942df386db0444abaa93a764207 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Tue, 5 Jan 2016 11:24:36 -0800 +Subject: [PATCH 5/8] CVE-2015-7560: s3: smbd: Refuse to get a POSIX ACL on a + symlink. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11648 + +Signed-off-by: Jeremy Allison +Reviewed-by: Michael Adam +--- + source3/smbd/trans2.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c +index 2f01e87..3a098d1 100644 +--- a/source3/smbd/trans2.c ++++ b/source3/smbd/trans2.c +@@ -4959,6 +4959,13 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, + uint16 num_file_acls = 0; + uint16 num_def_acls = 0; + ++ status = refuse_symlink(conn, ++ fsp, ++ smb_fname->base_name); ++ if (!NT_STATUS_IS_OK(status)) { ++ return status; ++ } ++ + if (fsp && fsp->fh->fd != -1) { + file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp); + } else { +-- +2.5.0 + + +From 659bdb80aa65c02cf4f44377cc3bcffb2a817ee0 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Tue, 5 Jan 2016 11:05:48 -0800 +Subject: [PATCH 6/8] CVE-2015-7560: s3: smbd: Set return values early, allows + removal of code duplication. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11648 + +Signed-off-by: Jeremy Allison +Reviewed-by: Michael Adam +--- + source3/smbd/trans2.c | 13 +++++-------- + 1 file changed, 5 insertions(+), 8 deletions(-) + +diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c +index 3a098d1..6fdd1da 100644 +--- a/source3/smbd/trans2.c ++++ b/source3/smbd/trans2.c +@@ -210,11 +210,12 @@ NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn, + size_t num_names; + ssize_t sizeret = -1; + ++ if (pnames) { ++ *pnames = NULL; ++ } ++ *pnum_names = 0; ++ + if (!lp_ea_support(SNUM(conn))) { +- if (pnames) { +- *pnames = NULL; +- } +- *pnum_names = 0; + return NT_STATUS_OK; + } + +@@ -264,10 +265,6 @@ NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn, + + if (sizeret == 0) { + TALLOC_FREE(names); +- if (pnames) { +- *pnames = NULL; +- } +- *pnum_names = 0; + return NT_STATUS_OK; + } + +-- +2.5.0 + + +From 4ba5e7cf01b8074b0313ecb7e218355d771df1cc Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Tue, 5 Jan 2016 11:29:38 -0800 +Subject: [PATCH 7/8] CVE-2015-7560: s3: smbd: Silently return no EA's + available on a symlink. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11648 + +Signed-off-by: Jeremy Allison +Reviewed-by: Michael Adam +--- + source3/smbd/trans2.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c +index 6fdd1da..8b6e4b2 100644 +--- a/source3/smbd/trans2.c ++++ b/source3/smbd/trans2.c +@@ -209,6 +209,7 @@ NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn, + char **names, **tmp; + size_t num_names; + ssize_t sizeret = -1; ++ NTSTATUS status; + + if (pnames) { + *pnames = NULL; +@@ -219,6 +220,14 @@ NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn, + return NT_STATUS_OK; + } + ++ status = refuse_symlink(conn, fsp, fname); ++ if (!NT_STATUS_IS_OK(status)) { ++ /* ++ * Just return no EA's on a symlink. ++ */ ++ return NT_STATUS_OK; ++ } ++ + /* + * TALLOC the result early to get the talloc hierarchy right. + */ +-- +2.5.0 + + +From 9d8c7274ab87a0c07367e872ca1db7fd72886fde Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Tue, 5 Jan 2016 11:33:48 -0800 +Subject: [PATCH 8/8] CVE-2015-7560: s3: smbd: Refuse to set EA's on a symlink. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11648 + +Signed-off-by: Jeremy Allison +Reviewed-by: Michael Adam +--- + source3/smbd/trans2.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c +index 8b6e4b2..98fd2af 100644 +--- a/source3/smbd/trans2.c ++++ b/source3/smbd/trans2.c +@@ -584,6 +584,7 @@ NTSTATUS set_ea(connection_struct *conn, files_struct *fsp, + const struct smb_filename *smb_fname, struct ea_list *ea_list) + { + char *fname = NULL; ++ NTSTATUS status; + + if (!lp_ea_support(SNUM(conn))) { + return NT_STATUS_EAS_NOT_SUPPORTED; +@@ -593,6 +594,12 @@ NTSTATUS set_ea(connection_struct *conn, files_struct *fsp, + return NT_STATUS_ACCESS_DENIED; + } + ++ status = refuse_symlink(conn, fsp, smb_fname->base_name); ++ if (!NT_STATUS_IS_OK(status)) { ++ return status; ++ } ++ ++ + /* For now setting EAs on streams isn't supported. */ + fname = smb_fname->base_name; + +-- +2.5.0 + diff --git a/src/patches/samba/CVE-2016-2110-v3-6.patch b/src/patches/samba/CVE-2016-2110-v3-6.patch new file mode 100644 index 0000000000..1f454bec8a --- /dev/null +++ b/src/patches/samba/CVE-2016-2110-v3-6.patch @@ -0,0 +1,670 @@ +From 202d69267c8550b850438877fb51c3d2c992949d Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +Date: Tue, 1 Dec 2015 08:46:45 +0100 +Subject: [PATCH 01/10] 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 +Reviewed-by: Günther Deschner +--- + 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 a701bc5f8a76584a2e0680b2c3dd9afb77f12430 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +Date: Fri, 11 Dec 2015 14:50:23 +0100 +Subject: [PATCH 02/10] 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 +Reviewed-by: Günther Deschner +--- + 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 92b2f5315d135b7b83a3ae106b43d18181be2f02 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Thu, 31 Mar 2016 12:39:50 +0200 +Subject: [PATCH 03/10] 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 +Reviewed-by: Günther Deschner +--- + 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 a239a337e3c0081af1a41aaac8957bb1aa0771f8 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +Date: Tue, 1 Dec 2015 15:01:09 +0100 +Subject: [PATCH 04/10] 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 +Reviewed-by: Günther Deschner +--- + 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 e11dc9aa90420947f9fc82365b55ecb08353451c Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +Date: Thu, 31 Mar 2016 12:59:05 +0200 +Subject: [PATCH 05/10] 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 +Reviewed-by: Günther Deschner +--- + 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 06ca5b7655e577ff6e2d5817cf221c05f9bb5c86 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +Date: Thu, 31 Mar 2016 13:03:24 +0200 +Subject: [PATCH 06/10] 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 +Reviewed-by: Günther Deschner +--- + 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 f99d4469a8b09dd93eb7124f2814e15869915671 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Mon, 11 Apr 2016 16:18:44 +0200 +Subject: [PATCH 07/10] CVE-2016-2110: auth/ntlmssp: don't let + ntlmssp3_handle_neg_flags() change ntlmssp_state->use_ntlmv2 + +ntlmssp_handle_neg_flags() can only disable flags, but not +set them. All supported flags are set at start time. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 + +Signed-off-by: Andreas Schneider +Reviewed-by: Guenther Deschner +--- + source3/libsmb/ntlmssp.c | 26 +++++++++++++++++--------- + 1 file changed, 17 insertions(+), 9 deletions(-) + +diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c +index bf40404..7b17a43 100644 +--- a/source3/libsmb/ntlmssp.c ++++ b/source3/libsmb/ntlmssp.c +@@ -391,6 +391,10 @@ static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, + ntlmssp_state->allow_lm_key = false; + } + ++ if (ntlmssp_state->allow_lm_key) { ++ ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY; ++ } ++ + /* generate the ntlmssp negotiate packet */ + status = msrpc_gen(ntlmssp_state, next_request, "CddAA", + "NTLMSSP", +@@ -438,20 +442,24 @@ static NTSTATUS ntlmssp3_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, + ntlmssp_state->unicode = false; + } + +- 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; +- } else { ++ /* ++ * NTLMSSP_NEGOTIATE_NTLM2 (NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY) ++ * has priority over NTLMSSP_NEGOTIATE_LM_KEY ++ */ ++ if (!(flags & NTLMSSP_NEGOTIATE_NTLM2)) { ++ ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; ++ } ++ ++ if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; + } + +- if (!(flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)) { +- ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_ALWAYS_SIGN; ++ if (!(flags & NTLMSSP_NEGOTIATE_LM_KEY)) { ++ ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; + } + +- if (!(flags & NTLMSSP_NEGOTIATE_NTLM2)) { +- ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; ++ if (!(flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)) { ++ ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_ALWAYS_SIGN; + } + + if (!(flags & NTLMSSP_NEGOTIATE_128)) { +-- +2.8.1 + + +From 71dda1c57c36a9816af7873f169306a766e0284a Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +Date: Thu, 31 Mar 2016 14:21:12 +0200 +Subject: [PATCH 08/10] 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 +Reviewed-by: Günther Deschner +--- + 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 7b17a43..d5c83fd 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 911e171bd6fc66e2960cbcdf8c48f2f97d19313b Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Thu, 31 Mar 2016 14:30:05 +0200 +Subject: [PATCH 09/10] CVE-2016-2110: s3:ntlmssp: Change want_fetures to + require flags + +Pair-Programmed-With: Ralph Boehme +Signed-off-by: Andreas Schneider +Signed-off-by: Ralph Boehme +--- + 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 d5c83fd..309175b 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 a95a44eff90cdbd42d683567e0d511e9d52026ad Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Thu, 31 Mar 2016 15:02:11 +0200 +Subject: [PATCH 10/10] CVE-2016-2110: s3:ntlmssp: Fix downgrade also for the + ntlmssp creds cache case + +Pair-Programmed-With: Ralph Boehme +Signed-off-by: Andreas Schneider +Signed-off-by: Ralph Boehme +--- + 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 309175b..045dc87 100644 +--- a/source3/libsmb/ntlmssp.c ++++ b/source3/libsmb/ntlmssp.c +@@ -538,6 +538,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; +@@ -588,17 +608,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); +@@ -615,17 +624,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/src/patches/samba/CVE-2016-2111-v3-6.patch b/src/patches/samba/CVE-2016-2111-v3-6.patch new file mode 100644 index 0000000000..981736783f --- /dev/null +++ b/src/patches/samba/CVE-2016-2111-v3-6.patch @@ -0,0 +1,1058 @@ +From ee105156fa151ebfd34b8febc2928e144b3b7b0e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?G=C3=BCnther=20Deschner?= +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 + +Signed-off-by: Guenther Deschner +Signed-off-by: Stefan Metzmacher +--- + 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 f93668be5dffea9b67c5ec2d49ebf7495b74c7fc Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +--- + 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 70f12940ef563f83310d5c82cf0a3fc5876d98ac Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +--- + 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 d8e061a1bcbb88ab6ba0f0dffbcac16a5e1db4f9 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +--- + 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 8fe606e..7c3142c 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]) + { +@@ -522,6 +522,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 d49e3329a639a570db8e99a13796713fb5a23616 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +--- + 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 bded435d42be34099d28db69258b1b5ef95ced48 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Alexander Bokovoy +--- + 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 12c908158213b1b82aca5c4485961da89299b6cf Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Alexander Bokovoy +--- + 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 0b659fd0d7b684244c9791e01cc1370c0696e3f7 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Alexander Bokovoy +--- + 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 5ed1b3a84a1e3d9707a788a89698aa28769a79be Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Alexander Bokovoy +--- + 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. ++ ++ When is also set to ++ yes extended security (SPNEGO) is required ++ in order to use NTLMv2 only within NTLMSSP. This behavior was ++ introduced with the patches for CVE-2016-2111. + + + yes +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. ++ ++ When is also set to ++ yes extended security (SPNEGO) is required ++ in order to use NTLMv2 only within NTLMSSP. This behavior was ++ introduced with the patches for CVE-2016-2111. + + yes + +-- +2.8.1 + + +From 8ac4cd75a89732938b1e3161a884f9d5df68ffaf Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +--- + 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 @@ ++ ++ ++ This parameter determines whether or not smbd ++ 8 will allow SMB1 clients without ++ extended security (without SPNEGO) to use NTLMv2 authentication. ++ ++ If this option, lanman auth ++ and ntlm auth are all disabled, ++ then only clients with SPNEGO support will be permitted. ++ That means NTLMv2 is only supported within NTLMSSP. ++ ++ Note that the default will change to "no" with Samba 4.5. ++ ++ ++yes ++no ++ +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 de2ba16834dece138d8c0761cc3c834da42dfd33 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +Reviewed-by: Ralph Boehme +--- + 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 094fb71d1dda38894be501674c7ec3e4ec03078e Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +--- + 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 a2ef1fb0cf0b83a2799b95795d31b8fb03da11bb Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Alexander Bokovoy +--- + 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 74da0e00f3b817dd20d6429f7ba7748f66b9b6a4 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Alexander Bokovoy +--- + 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 ntlm auth are all disabled, + then only clients with SPNEGO support will be permitted. + That means NTLMv2 is only supported within NTLMSSP. +- +- Note that the default will change to "no" with Samba 4.5. + + +-yes +-no ++lanman auth ++ntlm auth ++no + +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 44530ad870745f8d649aff9cc18480aaeeccf01a Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +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 +--- + 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/src/patches/samba/CVE-2016-2112-v3-6.patch b/src/patches/samba/CVE-2016-2112-v3-6.patch new file mode 100644 index 0000000000..57c6f680aa --- /dev/null +++ b/src/patches/samba/CVE-2016-2112-v3-6.patch @@ -0,0 +1,184 @@ +From 126e3e992bed7174d60ee19212db9b717647ab2e Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +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 +--- + 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 045dc87..7e58990 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 15338742e0c7304aeecce0e8368f0dad85e8075b Mon Sep 17 00:00:00 2001 +From: Ralph Boehme +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 + +Signed-off-by: Stefan Metzmacher +Signed-off-by: Ralph Boehme +--- + 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 b020ae88f9024bcc868ed2d85879d14901db32e5 Mon Sep 17 00:00:00 2001 +From: Andrew Bartlett +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 +Signed-off-by: Garming Sam +Signed-off-by: Andrew Bartlett +(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 @@ + + + +- The default value is plain which is not irritable +- to KRB5 clock skew errors. That implies synchronizing the time +- with the KDC in the case of using sign or +- seal. ++ The default value is sign. That implies synchronizing the time ++ with the KDC in the case of using Kerberos. + + +-plain ++sign + +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/src/patches/samba/CVE-2016-2115-v3-6.patch b/src/patches/samba/CVE-2016-2115-v3-6.patch new file mode 100644 index 0000000000..6167d35a34 --- /dev/null +++ b/src/patches/samba/CVE-2016-2115-v3-6.patch @@ -0,0 +1,359 @@ +From 513bd34e4523e49e742487be32a7239111486a12 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Ralph Boehme +--- + 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 @@ ++ ++ ++ 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 auto, mandatory ++ and disabled. ++ ++ ++ When set to auto, SMB signing is offered, but not enforced and if set ++ to disabled, SMB signing is not offered either. ++ ++ Connections from winbindd to Active Directory Domain Controllers ++ always enforce signing. ++ ++ ++client signing ++ ++mandatory ++ +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 @@ + 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. ++ ++ IPC$ connections for DCERPC e.g. in winbindd, are handled by the ++ option. + + + +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 633fcce5f7f488738ef8f45393aa8990e01118f4 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +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 +Signed-off-by: Andreas Schneider +Signed-off-by: Ralph Boehme +--- + 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 e319838866bdd3f5f1602b441516d07a1171ab24 Mon Sep 17 00:00:00 2001 +From: Ralph Boehme +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 +Reviewed-by: Stefan Metzmacher +Reviewed-by: Andreas Schneider +--- + 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 @@ ++ ++ ++ This option controls whether any requests from winbindd to domain controllers ++ pipe will be sealed. Disabling sealing can be useful for debugging ++ purposes. ++ ++ The behavior can be controlled per netbios domain ++ by using 'winbind sealed pipes:NETBIOSDOMAIN = no' as option. ++ ++ ++yes ++ +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 b47d8644e6a826f01dae3911fc510a7b2ff60273 Mon Sep 17 00:00:00 2001 +From: Andrew Bartlett +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 +Reviewed-by: Stefan Metzmacher +(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..50a341e 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() && (IS_DC || domain->primary)) { ++ 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() && (IS_DC || domain->primary)) { ++ 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() && (IS_DC || domain->primary)) { ++ 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/src/patches/samba/CVE-2016-2118-v3-6.patch b/src/patches/samba/CVE-2016-2118-v3-6.patch new file mode 100644 index 0000000000..e354155e8a --- /dev/null +++ b/src/patches/samba/CVE-2016-2118-v3-6.patch @@ -0,0 +1,629 @@ +From 9519f8f5123be055a4e845f87badef8b80ab2ee4 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 + +(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 0e00f6da40e6f76d9bd56187e74841c85ea86c55 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +(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 8d53761dbcbea6439f4bfaef86ff79f42b682b22 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +(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 @@ ++ ++ ++ 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. ++ ++ 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. ++ ++ 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 no. ++ ++ ++ Note the default will very likely change to no for Samba 4.5. ++ ++ ++yes ++no ++ ++ +-- +2.8.1 + + +From 9a0e8182314c631681f2dd47da5d790168066279 Mon Sep 17 00:00:00 2001 +From: Ralph Boehme +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 +Reviewed-by: Stefan Metzmacher +(backported from commit 6e3ada2c36f527077d77a8278bd41bbc030f48cd) + +(cherry picked from commit 74172d061597c96f0e733c11daee6cb15f3277dc) +Signed-off-by: Aurelien Aptel +--- + 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 82a245ff842ea33c050a8fbe415a531497232d3d Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 + +Signed-off-by: Stefan Metzmacher +Signed-off-by: Günther Deschner +(cherry picked from commit 1fa0bad3da921fca1d34971062522b4cc3e6db2c) +(cherry picked from commit 46744bbe5e3616613b2dbee7cf6fdf0d8d5caab3) +Signed-off-by: Aurelien Aptel +--- + 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: ++ * 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 b68b204307e0b24bc2879ea667a706e11925166d Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 + +Signed-off-by: Stefan Metzmacher +Signed-off-by: Günther Deschner +(cherry picked from commit 51dd08951eb4ab9d297678f96cde61f508937721) +Signed-off-by: Aurelien Aptel + +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: +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 720b9f861322c5fe804c53eb74e7d2d6a4d8b876 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +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 +--- + 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 9b2b563a1f8247f5ec7efde52d70efc666e30f56 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Alexander Bokovoy +(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: +-- +2.8.1 + + +From 21453f6887569b162be44faaf43e1b9a81423210 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Alexander Bokovoy +(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 no. + +- +- Note the default will very likely change to no for Samba 4.5. + + +-yes +-no ++no ++yes + + +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 a5aebec4ff2f1d3b824dfcc05091da712639220d Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Günther Deschner +(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/src/patches/samba/CVE-preparation-v3-6.patch b/src/patches/samba/CVE-preparation-v3-6.patch new file mode 100644 index 0000000000..48af30c7e7 --- /dev/null +++ b/src/patches/samba/CVE-preparation-v3-6.patch @@ -0,0 +1,6964 @@ +From 39a3fa39967faaf216be8e108ca57d07de1aa95a Mon Sep 17 00:00:00 2001 +From: Vadim Zhukov +Date: Sat, 25 May 2013 15:19:24 +0100 +Subject: [PATCH 01/41] pidl: Recent Perl warns about "defined(@var)" + constructs. + +Signed-off-by: Jelmer Vernooij + +Autobuild-User(master): Jelmer Vernooij +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(-) + +Index: samba-3.6.23/pidl/lib/Parse/Pidl/ODL.pm +=================================================================== +--- samba-3.6.23.orig/pidl/lib/Parse/Pidl/ODL.pm ++++ samba-3.6.23/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"); + +Index: samba-3.6.23/pidl/pidl +=================================================================== +--- samba-3.6.23.orig/pidl/pidl ++++ samba-3.6.23/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; +Index: samba-3.6.23/source4/heimdal/cf/make-proto.pl +=================================================================== +--- samba-3.6.23.orig/source4/heimdal/cf/make-proto.pl ++++ samba-3.6.23/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; +Index: samba-3.6.23/source3/Makefile-smbtorture4 +=================================================================== +--- samba-3.6.23.orig/source3/Makefile-smbtorture4 ++++ samba-3.6.23/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 + +Index: samba-3.6.23/source4/lib/ldb/wscript +=================================================================== +--- samba-3.6.23.orig/source4/lib/ldb/wscript ++++ samba-3.6.23/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', +Index: samba-3.6.23/source3/selftest/skip +=================================================================== +--- samba-3.6.23.orig/source3/selftest/skip ++++ samba-3.6.23/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 +Index: samba-3.6.23/librpc/ndr/ndr_ntlmssp.c +=================================================================== +--- samba-3.6.23.orig/librpc/ndr/ndr_ntlmssp.c ++++ samba-3.6.23/librpc/ndr/ndr_ntlmssp.c +@@ -176,4 +176,20 @@ _PUBLIC_ void ndr_print_ntlmssp_Version( + } + } + ++_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; ++} +Index: samba-3.6.23/librpc/ndr/ndr_ntlmssp.h +=================================================================== +--- samba-3.6.23.orig/librpc/ndr/ndr_ntlmssp.h ++++ samba-3.6.23/librpc/ndr/ndr_ntlmssp.h +@@ -31,3 +31,5 @@ _PUBLIC_ void ndr_print_ntlmssp_lm_respo + 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); +Index: samba-3.6.23/librpc/ABI/ndr-0.0.2.sigs +=================================================================== +--- /dev/null ++++ samba-3.6.23/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 +Index: samba-3.6.23/librpc/ndr/libndr.h +=================================================================== +--- samba-3.6.23.orig/librpc/ndr/libndr.h ++++ samba-3.6.23/librpc/ndr/libndr.h +@@ -124,6 +124,20 @@ struct ndr_print { + #define LIBNDR_FLAG_STR_UTF8 (1<<12) + #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. ++ */ ++#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) + +@@ -163,6 +177,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) +@@ -199,7 +214,9 @@ enum ndr_err_code { + NDR_ERR_IPV6ADDRESS, + NDR_ERR_INVALID_POINTER, + NDR_ERR_UNREAD_BYTES, +- NDR_ERR_NDR64 ++ NDR_ERR_NDR64, ++ NDR_ERR_FLAGS, ++ NDR_ERR_INCOMPLETE_BUFFER + }; + + #define NDR_ERR_CODE_IS_SUCCESS(x) (x == NDR_ERR_SUCCESS) +@@ -217,20 +234,52 @@ 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)) { \ ++ 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) +@@ -247,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) +@@ -402,6 +455,8 @@ void ndr_print_dom_sid0(struct ndr_print + 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); +@@ -424,14 +479,18 @@ enum ndr_err_code ndr_pull_relative_ptr2 + 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); + 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); +Index: samba-3.6.23/librpc/ndr/ndr.c +=================================================================== +--- samba-3.6.23.orig/librpc/ndr/ndr.c ++++ samba-3.6.23/librpc/ndr/ndr.c +@@ -77,6 +77,111 @@ _PUBLIC_ struct ndr_pull *ndr_pull_init_ + 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 + */ +@@ -167,6 +272,38 @@ _PUBLIC_ enum ndr_err_code ndr_push_expa + 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;idepth;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 +375,25 @@ _PUBLIC_ void ndr_print_string_helper(st + } + + /* ++ 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) +@@ -403,6 +559,15 @@ _PUBLIC_ enum ndr_err_code ndr_pull_erro + 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); +@@ -557,6 +722,23 @@ _PUBLIC_ enum ndr_err_code ndr_pull_subc + 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); +@@ -589,13 +771,35 @@ _PUBLIC_ enum ndr_err_code ndr_pull_subc + ssize_t size_is) + { + uint32_t advance; +- if (size_is >= 0) { ++ uint32_t highest_ofs; ++ ++ 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; + } 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; + } +@@ -1440,6 +1644,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 } + }; + +Index: samba-3.6.23/librpc/idl/idl_types.h +=================================================================== +--- samba-3.6.23.orig/librpc/idl/idl_types.h ++++ samba-3.6.23/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 +Index: samba-3.6.23/librpc/idl/dcerpc.idl +=================================================================== +--- samba-3.6.23.orig/librpc/idl/dcerpc.idl ++++ samba-3.6.23/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 { +@@ -453,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; +@@ -468,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; +@@ -476,7 +486,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 */ +@@ -506,4 +516,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; + } +Index: samba-3.6.23/librpc/ndr/ndr_dcerpc.c +=================================================================== +--- /dev/null ++++ samba-3.6.23/librpc/ndr/ndr_dcerpc.c +@@ -0,0 +1,187 @@ ++/* ++ 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 . ++*/ ++ ++#include "includes.h" ++#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}; ++ ++_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; ++} ++ ++_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; ++} +Index: samba-3.6.23/librpc/wscript_build +=================================================================== +--- samba-3.6.23.orig/librpc/wscript_build ++++ samba-3.6.23/librpc/wscript_build +@@ -274,8 +274,9 @@ 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', ++ deps='bitmap', + public_headers='gen_ndr/ndr_dcerpc.h gen_ndr/dcerpc.h', + header_path= [ ('*gen_ndr*', 'gen_ndr') ], + ) +Index: samba-3.6.23/source3/Makefile.in +=================================================================== +--- samba-3.6.23.orig/source3/Makefile.in ++++ samba-3.6.23/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 +@@ -454,7 +455,7 @@ LIB_OBJ = $(LIBSAMBAUTIL_OBJ) $(UTIL_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 \ +@@ -988,7 +989,9 @@ SWAT_OBJ = $(SWAT_OBJ1) $(PARAM_OBJ) $(P + $(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 +1007,9 @@ SMBTREE_OBJ = utils/smbtree.o $(PARAM_OB + $(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 +1031,9 @@ SMBPASSWD_OBJ = utils/smbpasswd.o $(PASS + $(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 +1106,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 +1131,9 @@ CLIENT_OBJ = $(CLIENT_OBJ1) $(PARAM_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 +1245,9 @@ SMBTORTURE_OBJ = $(SMBTORTURE_OBJ1) $(PA + @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 +1282,18 @@ SMBCACLS_OBJ = utils/smbcacls.o $(PARAM_ + $(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 + +Index: samba-3.6.23/librpc/ndr/ndr_basic.c +=================================================================== +--- samba-3.6.23.orig/librpc/ndr/ndr_basic.c ++++ samba-3.6.23/librpc/ndr/ndr_basic.c +@@ -61,6 +61,7 @@ _PUBLIC_ void ndr_check_padding(struct 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 + */ + _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_uint + */ + _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_int1 + */ + _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_uint + */ + _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_uint + */ + _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_int3 + */ + _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_uint + { + 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_uint + */ + _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_ + */ + _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_udlo + */ + _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_hype + _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_poin + _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 + _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_byte + */ + _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_arra + */ + _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 + */ + _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_uint + */ + _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_int1 + */ + _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_uint + */ + _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_int3 + */ + _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_uint + */ + _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_udlo + */ + _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_hype + */ + _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_doub + _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 + */ + _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_ + */ + _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_NTTI + */ + _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_NTTI + */ + _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_NTTI + */ + _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_NTTI + */ + _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_NTTI + */ + _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 + */ + _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_ + */ + _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); + } + +Index: samba-3.6.23/source3/lib/bitmap.c +=================================================================== +--- samba-3.6.23.orig/source3/lib/bitmap.c ++++ /dev/null +@@ -1,136 +0,0 @@ +-/* +- 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 . +-*/ +- +-#include "includes.h" +- +-/* these functions provide a simple way to allocate integers from a +- pool without repetition */ +- +-/**************************************************************************** +-talloc a bitmap +-****************************************************************************/ +-struct bitmap *bitmap_talloc(TALLOC_CTX *mem_ctx, int n) +-{ +- struct bitmap *bm; +- +- bm = TALLOC_P(mem_ctx, struct bitmap); +- +- if (!bm) return NULL; +- +- bm->n = n; +- bm->b = TALLOC_ZERO_ARRAY(bm, uint32, (n+31)/32); +- if (!bm->b) { +- TALLOC_FREE(bm); +- return NULL; +- } +- return bm; +-} +- +-/**************************************************************************** +-copy as much of the source bitmap as will fit in the destination bitmap. +-****************************************************************************/ +- +-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)); +- +- return count; +-} +- +-/**************************************************************************** +-set a bit in a bitmap +-****************************************************************************/ +-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; +- } +- bm->b[i/32] |= (1<<(i%32)); +- return True; +-} +- +-/**************************************************************************** +-clear a bit in a bitmap +-****************************************************************************/ +-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; +- } +- bm->b[i/32] &= ~(1<<(i%32)); +- return True; +-} +- +-/**************************************************************************** +-query a bit in a bitmap +-****************************************************************************/ +-bool bitmap_query(struct bitmap *bm, unsigned i) +-{ +- if (i >= bm->n) return False; +- if (bm->b[i/32] & (1<<(i%32))) { +- return True; +- } +- return False; +-} +- +-/**************************************************************************** +-find a zero bit in a bitmap starting at the specified offset, with +-wraparound +-****************************************************************************/ +-int bitmap_find(struct bitmap *bm, unsigned ofs) +-{ +- unsigned int i, j; +- +- if (ofs > bm->n) ofs = 0; +- +- i = ofs; +- while (i < bm->n) { +- if (~(bm->b[i/32])) { +- j = i; +- do { +- if (!bitmap_query(bm, j)) return j; +- j++; +- } while (j & 31 && j < bm->n); +- } +- i += 32; +- i &= ~31; +- } +- +- i = 0; +- while (i < ofs) { +- if (~(bm->b[i/32])) { +- j = i; +- do { +- if (!bitmap_query(bm, j)) return j; +- j++; +- } while (j & 31 && j < bm->n); +- } +- i += 32; +- i &= ~31; +- } +- +- return -1; +-} +Index: samba-3.6.23/lib/util/bitmap.c +=================================================================== +--- /dev/null ++++ samba-3.6.23/lib/util/bitmap.c +@@ -0,0 +1,137 @@ ++/* ++ 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 . ++*/ ++ ++#include "includes.h" ++#include "lib/util/bitmap.h" ++ ++/* these functions provide a simple way to allocate integers from a ++ pool without repetition */ ++ ++/**************************************************************************** ++talloc a bitmap ++****************************************************************************/ ++struct bitmap *bitmap_talloc(TALLOC_CTX *mem_ctx, int n) ++{ ++ struct bitmap *bm; ++ ++ bm = talloc_zero(mem_ctx, struct bitmap); ++ ++ if (!bm) return NULL; ++ ++ bm->n = n; ++ bm->b = talloc_zero_array(bm, uint32_t, (n+31)/32); ++ if (!bm->b) { ++ TALLOC_FREE(bm); ++ return NULL; ++ } ++ return bm; ++} ++ ++/**************************************************************************** ++copy as much of the source bitmap as will fit in the destination bitmap. ++****************************************************************************/ ++ ++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_t)*((count+31)/32)); ++ ++ return count; ++} ++ ++/**************************************************************************** ++set a bit in a bitmap ++****************************************************************************/ ++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; ++ } ++ bm->b[i/32] |= (1<<(i%32)); ++ return true; ++} ++ ++/**************************************************************************** ++clear a bit in a bitmap ++****************************************************************************/ ++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; ++ } ++ bm->b[i/32] &= ~(1<<(i%32)); ++ return true; ++} ++ ++/**************************************************************************** ++query a bit in a bitmap ++****************************************************************************/ ++bool bitmap_query(struct bitmap *bm, unsigned i) ++{ ++ if (i >= bm->n) return false; ++ if (bm->b[i/32] & (1<<(i%32))) { ++ return true; ++ } ++ return false; ++} ++ ++/**************************************************************************** ++find a zero bit in a bitmap starting at the specified offset, with ++wraparound ++****************************************************************************/ ++int bitmap_find(struct bitmap *bm, unsigned ofs) ++{ ++ unsigned int i, j; ++ ++ if (ofs > bm->n) ofs = 0; ++ ++ i = ofs; ++ while (i < bm->n) { ++ if (~(bm->b[i/32])) { ++ j = i; ++ do { ++ if (!bitmap_query(bm, j)) return j; ++ j++; ++ } while (j & 31 && j < bm->n); ++ } ++ i += 32; ++ i &= ~31; ++ } ++ ++ i = 0; ++ while (i < ofs) { ++ if (~(bm->b[i/32])) { ++ j = i; ++ do { ++ if (!bitmap_query(bm, j)) return j; ++ j++; ++ } while (j & 31 && j < bm->n); ++ } ++ i += 32; ++ i &= ~31; ++ } ++ ++ return -1; ++} +Index: samba-3.6.23/lib/util/bitmap.h +=================================================================== +--- /dev/null ++++ samba-3.6.23/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 . ++*/ ++ ++/* 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); +Index: samba-3.6.23/lib/util/wscript_build +=================================================================== +--- samba-3.6.23.orig/lib/util/wscript_build ++++ samba-3.6.23/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) + +Index: samba-3.6.23/source3/include/proto.h +=================================================================== +--- samba-3.6.23.orig/source3/include/proto.h ++++ samba-3.6.23/source3/include/proto.h +@@ -61,15 +61,6 @@ const char *audit_description_str(uint32 + 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); +Index: samba-3.6.23/source3/include/smb.h +=================================================================== +--- samba-3.6.23.orig/source3/include/smb.h ++++ samba-3.6.23/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 +Index: samba-3.6.23/source3/modules/vfs_acl_common.c +=================================================================== +--- samba-3.6.23.orig/source3/modules/vfs_acl_common.c ++++ samba-3.6.23/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, +Index: samba-3.6.23/source3/modules/vfs_full_audit.c +=================================================================== +--- samba-3.6.23.orig/source3/modules/vfs_full_audit.c ++++ samba-3.6.23/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; + +Index: samba-3.6.23/source3/param/loadparm.c +=================================================================== +--- samba-3.6.23.orig/source3/param/loadparm.c ++++ samba-3.6.23/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 +Index: samba-3.6.23/source3/passdb/pdb_get_set.c +=================================================================== +--- samba-3.6.23.orig/source3/passdb/pdb_get_set.c ++++ samba-3.6.23/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 +Index: samba-3.6.23/source3/smbd/conn.c +=================================================================== +--- samba-3.6.23.orig/source3/smbd/conn.c ++++ samba-3.6.23/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 +Index: samba-3.6.23/source3/smbd/dir.c +=================================================================== +--- samba-3.6.23.orig/source3/smbd/dir.c ++++ samba-3.6.23/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. +Index: samba-3.6.23/source3/smbd/files.c +=================================================================== +--- samba-3.6.23.orig/source3/smbd/files.c ++++ samba-3.6.23/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)) + +Index: samba-3.6.23/source3/smbd/smb2_server.c +=================================================================== +--- samba-3.6.23.orig/source3/smbd/smb2_server.c ++++ samba-3.6.23/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) + +Index: samba-3.6.23/source3/rpc_client/cli_pipe.c +=================================================================== +--- samba-3.6.23.orig/source3/rpc_client/cli_pipe.c ++++ samba-3.6.23/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" +@@ -399,6 +400,7 @@ static NTSTATUS cli_pipe_validate_curren + struct ncacn_packet *pkt, + DATA_BLOB *pdu, + uint8_t expected_pkt_type, ++ uint32_t call_id, + DATA_BLOB *rdata, + DATA_BLOB *reply_pdu) + { +@@ -497,7 +499,7 @@ static NTSTATUS cli_pipe_validate_curren + "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) { +@@ -505,7 +507,15 @@ static NTSTATUS cli_pipe_validate_curren + "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 +@@ -898,6 +908,7 @@ static void rpc_api_pipe_got_pdu(struct + state->cli, state->pkt, + &state->incoming_frag, + state->expected_pkt_type, ++ state->call_id, + &rdata, + &state->reply_pdu); + +@@ -1269,12 +1280,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 +1326,11 @@ struct tevent_req *rpc_api_pipe_req_send + 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 +1365,161 @@ struct tevent_req *rpc_api_pipe_req_send + 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 +1529,20 @@ static NTSTATUS prepare_next_frag(struct + 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 = state->req_data->length; ++ u.request.alloc_hint = total_left; + u.request.context_id = 0; + u.request.opnum = state->op_num; + +@@ -1400,11 +1562,26 @@ static NTSTATUS prepare_next_frag(struct + * 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 +1601,6 @@ static NTSTATUS prepare_next_frag(struct + 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 +1664,20 @@ static void rpc_api_pipe_req_done(struct + 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); + } + +@@ -1647,9 +1837,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); +@@ -1753,11 +1949,14 @@ static void rpc_pipe_bind_step_one_done( + + 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: +@@ -1869,6 +2068,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) +Index: samba-3.6.23/source3/librpc/rpc/dcerpc.h +=================================================================== +--- samba-3.6.23.orig/source3/librpc/rpc/dcerpc.h ++++ samba-3.6.23/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; + +Index: samba-3.6.23/source3/rpc_client/rpc_client.h +=================================================================== +--- samba-3.6.23.orig/source3/rpc_client/rpc_client.h ++++ samba-3.6.23/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; +Index: samba-3.6.23/librpc/ndr/ndr_dcerpc.h +=================================================================== +--- /dev/null ++++ samba-3.6.23/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 . ++*/ ++ ++enum ndr_err_code ndr_pop_dcerpc_sec_verification_trailer( ++ struct ndr_pull *ndr, TALLOC_CTX *mem_ctx, ++ struct dcerpc_sec_verification_trailer **_r); +Index: samba-3.6.23/librpc/ABI/ndr-0.0.3.sigs +=================================================================== +--- /dev/null ++++ samba-3.6.23/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 +Index: samba-3.6.23/librpc/ndr/ndr_misc.c +=================================================================== +--- samba-3.6.23.orig/librpc/ndr/ndr_misc.c ++++ samba-3.6.23/librpc/ndr/ndr_misc.c +@@ -35,3 +35,50 @@ bool ndr_syntax_id_equal(const struct nd + 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; ++} +Index: samba-3.6.23/librpc/rpc/dcerpc_util.c +=================================================================== +--- samba-3.6.23.orig/librpc/rpc/dcerpc_util.c ++++ samba-3.6.23/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 */ +@@ -341,3 +342,194 @@ NTSTATUS dcerpc_read_ncacn_packet_recv(s + 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; ++} ++ ++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; ++} +Index: samba-3.6.23/librpc/rpc/rpc_common.h +=================================================================== +--- samba-3.6.23.orig/librpc/rpc/rpc_common.h ++++ samba-3.6.23/librpc/rpc/rpc_common.h +@@ -296,4 +296,45 @@ NTSTATUS dcerpc_binding_handle_call(stru + 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); ++ ++/** ++ * Check for consistency of the security verification trailer with the PDU header. ++ * See MS-RPCE 2.2.2.13. ++ * 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__ */ +Index: samba-3.6.23/source4/torture/ndr/ndr.c +=================================================================== +--- samba-3.6.23.orig/source4/torture/ndr/ndr.c ++++ samba-3.6.23/source4/torture/ndr/ndr.c +@@ -29,40 +29,65 @@ 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; ++ int 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; ++ uint32_t highest_ofs; ++ ++ ndr->flags |= data->flags; + + ndr->flags |= LIBNDR_FLAG_REF_ALLOC; + + 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) +- 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, ++ int flags, ++ bool (*check_fn) (struct torture_context *ctx, void *data)) + { + struct torture_test *test; + struct torture_tcase *tcase; +@@ -74,12 +99,16 @@ _PUBLIC_ struct torture_test *_torture_s + + 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->flags = 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 +118,7 @@ _PUBLIC_ struct torture_test *_torture_s + return test; + } + ++ + static bool wrap_ndr_inout_pull_test(struct torture_context *tctx, + struct torture_tcase *tcase, + struct torture_test *test) +@@ -97,6 +127,7 @@ static bool wrap_ndr_inout_pull_test(str + 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 */ + +@@ -109,8 +140,14 @@ static bool wrap_ndr_inout_pull_test(str + 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); + +@@ -125,8 +162,14 @@ static bool wrap_ndr_inout_pull_test(str + 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); + +Index: samba-3.6.23/source4/torture/ndr/ndr.h +=================================================================== +--- samba-3.6.23.orig/source4/torture/ndr/ndr.h ++++ samba-3.6.23/source4/torture/ndr/ndr.h +@@ -24,12 +24,15 @@ + #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, ++ int flags, + bool (*check_fn) (struct torture_context *, void *data)); + + _PUBLIC_ struct torture_test *_torture_suite_add_ndr_pull_inout_test( +@@ -41,20 +44,32 @@ _PUBLIC_ struct torture_test *_torture_s + 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)), \ +- sizeof(struct name), NDR_SCALARS|NDR_BUFFERS, (bool (*) (struct torture_context *, void *)) 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, 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_pull_test(suite, #name "_" #flags, \ +- (ndr_pull_flags_fn_t)ndr_pull_ ## name, data_blob_talloc(suite, data, sizeof(data)), \ +- sizeof(struct name), flags, (bool (*) (struct torture_context *, void *)) 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, 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, 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", \ + (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); + +Index: samba-3.6.23/source4/torture/ndr/dfsblob.c +=================================================================== +--- samba-3.6.23.orig/source4/torture/ndr/dfsblob.c ++++ samba-3.6.23/source4/torture/ndr/dfsblob.c +@@ -74,11 +74,11 @@ struct torture_suite *ndr_dfsblob_suite( + { + 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; + } +Index: samba-3.6.23/source4/torture/ndr/nbt.c +=================================================================== +--- samba-3.6.23.orig/source4/torture/ndr/nbt.c ++++ samba-3.6.23/source4/torture/ndr/nbt.c +@@ -62,9 +62,9 @@ struct torture_suite *ndr_nbt_suite(TALL + { + 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; + } +Index: samba-3.6.23/source4/torture/ndr/ntlmssp.c +=================================================================== +--- samba-3.6.23.orig/source4/torture/ndr/ntlmssp.c ++++ samba-3.6.23/source4/torture/ndr/ntlmssp.c +@@ -111,9 +111,10 @@ struct torture_suite *ndr_ntlmssp_suite( + { + 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; + } +Index: samba-3.6.23/source4/torture/ndr/drsblobs.c +=================================================================== +--- samba-3.6.23.orig/source4/torture/ndr/drsblobs.c ++++ samba-3.6.23/source4/torture/ndr/drsblobs.c +@@ -115,6 +115,34 @@ static const uint8_t trust_domain_passwo + 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 + { + 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; + } +Index: samba-3.6.23/source3/rpcclient/rpcclient.c +=================================================================== +--- samba-3.6.23.orig/source3/rpcclient/rpcclient.c ++++ samba-3.6.23/source3/rpcclient/rpcclient.c +@@ -1021,6 +1021,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; +@@ -1034,12 +1038,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 { +@@ -1047,18 +1045,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 | +Index: samba-3.6.23/source3/script/tests/test_rpcclient.sh +=================================================================== +--- /dev/null ++++ samba-3.6.23/source3/script/tests/test_rpcclient.sh +@@ -0,0 +1,19 @@ ++#!/bin/sh ++ ++if [ $# -lt 1 ]; then ++cat < ++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 +Index: samba-3.6.23/source3/selftest/tests.py +=================================================================== +--- samba-3.6.23.orig/source3/selftest/tests.py ++++ samba-3.6.23/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: +Index: samba-3.6.23/source4/torture/rpc/rpc.c +=================================================================== +--- samba-3.6.23.orig/source4/torture/rpc/rpc.c ++++ samba-3.6.23/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)); +Index: samba-3.6.23/source4/torture/rpc/samr.c +=================================================================== +--- samba-3.6.23.orig/source4/torture/rpc/samr.c ++++ samba-3.6.23/source4/torture/rpc/samr.c +@@ -7938,8 +7938,8 @@ static bool test_Connect(struct dcerpc_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(s + + 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 t + + 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_p + 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; ++} +Index: samba-3.6.23/source3/rpc_server/srv_pipe.c +=================================================================== +--- samba-3.6.23.orig/source3/rpc_server/srv_pipe.c ++++ samba-3.6.23/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 +@@ -202,7 +203,7 @@ bool create_next_pdu(struct pipes_struct + * 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; + } + +@@ -336,7 +337,7 @@ static bool check_bind_req(struct pipes_ + 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 +359,7 @@ static bool check_bind_req(struct pipes_ + 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 +1543,42 @@ static PIPE_RPC_FNS* find_pipe_fns_by_co + } + + 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); ++ ++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. +@@ -1552,46 +1589,53 @@ static bool api_rpcTNP(struct pipes_stru + static bool api_pipe_request(struct pipes_struct *p, + struct ncacn_packet *pkt) + { ++ TALLOC_CTX *frame = talloc_stackframe(); + 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); ++ 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 */ + + 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); ++ 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; + } +- 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))); ++ ++ 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 (changed_user) { +- unbecome_authenticated_pipe_user(); ++ 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); ++ 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; + } + +@@ -1600,20 +1644,21 @@ static bool api_pipe_request(struct pipe + ********************************************************************/ + + 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); +@@ -1646,37 +1691,30 @@ static bool api_rpcTNP(struct pipes_stru + /* 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; + } + +- 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) { + 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) && +@@ -1718,9 +1756,9 @@ void set_incoming_fault(struct pipes_str + 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, +Index: samba-3.6.23/source3/include/ntdomain.h +=================================================================== +--- samba-3.6.23.orig/source3/include/ntdomain.h ++++ samba-3.6.23/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; + +@@ -134,22 +135,10 @@ struct pipes_struct { + bool pipe_bound; + + /* +- * Set to true when we should return fault PDU's for everything. +- */ +- +- 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. ++ * Set the DCERPC_FAULT to return. + */ + +- bool rng_fault_state; ++ int fault_state; + + /* + * Set to RPC_BIG_ENDIAN when dealing with big-endian PDU's +Index: samba-3.6.23/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm +=================================================================== +--- samba-3.6.23.orig/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm ++++ samba-3.6.23/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;"; +Index: samba-3.6.23/source3/rpc_server/dfs/srv_dfs_nt.c +=================================================================== +--- samba-3.6.23.orig/source3/rpc_server/dfs/srv_dfs_nt.c ++++ samba-3.6.23/source3/rpc_server/dfs/srv_dfs_nt.c +@@ -411,125 +411,125 @@ WERROR _dfs_GetInfo(struct pipes_struct + 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; + } +Index: samba-3.6.23/source3/rpc_server/dssetup/srv_dssetup_nt.c +=================================================================== +--- samba-3.6.23.orig/source3/rpc_server/dssetup/srv_dssetup_nt.c ++++ samba-3.6.23/source3/rpc_server/dssetup/srv_dssetup_nt.c +@@ -130,7 +130,7 @@ WERROR _dssetup_DsRoleGetPrimaryDomainIn + 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( + 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 pipe + 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 + 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 pi + 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_DsRoleGetDcOperationProg + 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_DsRoleGetDcOperationResu + 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 pipe + 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_DsRoleServerSaveStateFor + 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_DsRoleUpgradeDownlevelSe + 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; + } +Index: samba-3.6.23/source3/rpc_server/echo/srv_echo_nt.c +=================================================================== +--- samba-3.6.23.orig/source3/rpc_server/echo/srv_echo_nt.c ++++ samba-3.6.23/source3/rpc_server/echo/srv_echo_nt.c +@@ -87,13 +87,13 @@ void _echo_SourceData(struct pipes_struc + + 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_stru + + 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; + } +Index: samba-3.6.23/source3/rpc_server/epmapper/srv_epmapper.c +=================================================================== +--- samba-3.6.23.orig/source3/rpc_server/epmapper/srv_epmapper.c ++++ samba-3.6.23/source3/rpc_server/epmapper/srv_epmapper.c +@@ -297,6 +297,7 @@ error_status_t _epm_Insert(struct pipes_ + /* 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_ + /* 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(str + 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 pip + 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 pi + 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; + } + +Index: samba-3.6.23/source3/rpc_server/eventlog/srv_eventlog_nt.c +=================================================================== +--- samba-3.6.23.orig/source3/rpc_server/eventlog/srv_eventlog_nt.c ++++ samba-3.6.23/source3/rpc_server/eventlog/srv_eventlog_nt.c +@@ -695,7 +695,7 @@ NTSTATUS _eventlog_GetNumRecords(struct + + 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 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; + } +Index: samba-3.6.23/source3/rpc_server/lsa/srv_lsa_nt.c +=================================================================== +--- samba-3.6.23.orig/source3/rpc_server/lsa/srv_lsa_nt.c ++++ samba-3.6.23/source3/rpc_server/lsa/srv_lsa_nt.c +@@ -817,7 +817,7 @@ NTSTATUS _lsa_QueryInfoPolicy2(struct pi + 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 + + 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(struc + * _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(struc + 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_lsaRSetForestTrustInformat + 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; + } +Index: samba-3.6.23/source3/rpc_server/netlogon/srv_netlog_nt.c +=================================================================== +--- samba-3.6.23.orig/source3/rpc_server/netlogon/srv_netlog_nt.c ++++ samba-3.6.23/source3/rpc_server/netlogon/srv_netlog_nt.c +@@ -1789,7 +1789,7 @@ NTSTATUS _netr_LogonSamLogonEx(struct pi + 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; + } + +@@ -1799,7 +1799,7 @@ WERROR _netr_LogonUasLogon(struct pipes_ + 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; + } + +@@ -1809,7 +1809,7 @@ WERROR _netr_LogonUasLogoff(struct pipes + 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; + } + +@@ -1819,7 +1819,7 @@ NTSTATUS _netr_DatabaseDeltas(struct pip + 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; + } + +@@ -1829,7 +1829,7 @@ NTSTATUS _netr_DatabaseSync(struct pipes + 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; + } + +@@ -1839,7 +1839,7 @@ NTSTATUS _netr_AccountDeltas(struct pipe + 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; + } + +@@ -1980,7 +1980,7 @@ WERROR _netr_GetAnyDCName(struct pipes_s + 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; + } + +@@ -1990,7 +1990,7 @@ NTSTATUS _netr_DatabaseSync2(struct pipe + 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; + } + +@@ -2000,7 +2000,7 @@ NTSTATUS _netr_DatabaseRedo(struct pipes + 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; + } + +@@ -2019,7 +2019,7 @@ NTSTATUS _netr_LogonGetCapabilities(stru + 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; + } + +@@ -2029,7 +2029,7 @@ WERROR _netr_NETRLOGONSETSERVICEBITS(str + 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; + } + +@@ -2039,7 +2039,7 @@ WERROR _netr_LogonGetTrustRid(struct pip + 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; + } + +@@ -2049,7 +2049,7 @@ WERROR _netr_NETRLOGONCOMPUTESERVERDIGES + 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; + } + +@@ -2059,7 +2059,7 @@ WERROR _netr_NETRLOGONCOMPUTECLIENTDIGES + 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; + } + +@@ -2069,7 +2069,7 @@ WERROR _netr_DsRGetDCNameEx(struct pipes + 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; + } + +@@ -2079,7 +2079,7 @@ WERROR _netr_DsRGetSiteName(struct pipes + 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; + } + +@@ -2089,7 +2089,7 @@ NTSTATUS _netr_LogonGetDomainInfo(struct + 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; + } + +@@ -2099,7 +2099,7 @@ WERROR _netr_ServerPasswordGet(struct pi + 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; + } + +@@ -2109,7 +2109,7 @@ WERROR _netr_NETRLOGONSENDTOSAM(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; + } + +@@ -2119,7 +2119,7 @@ WERROR _netr_DsRAddressToSitenamesW(stru + 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; + } + +@@ -2129,7 +2129,7 @@ WERROR _netr_DsRGetDCNameEx2(struct pipe + 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; + } + +@@ -2139,7 +2139,7 @@ WERROR _netr_NETRLOGONGETTIMESERVICEPARE + 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; + } + +@@ -2149,7 +2149,7 @@ WERROR _netr_NetrEnumerateTrustedDomains + 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; + } + +@@ -2159,7 +2159,7 @@ WERROR _netr_DsRAddressToSitenamesExW(st + 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; + } + +@@ -2169,7 +2169,7 @@ WERROR _netr_DsrGetDcSiteCoverageW(struc + 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; + } + +@@ -2179,7 +2179,7 @@ WERROR _netr_DsrEnumerateDomainTrusts(st + 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; + } + +@@ -2189,7 +2189,7 @@ WERROR _netr_DsrDeregisterDNSHostRecords + 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; + } + +@@ -2199,7 +2199,7 @@ NTSTATUS _netr_ServerTrustPasswordsGet(s + 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; + } + +@@ -2478,7 +2478,7 @@ NTSTATUS _netr_ServerGetTrustInfo(struct + 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; + } + +@@ -2488,6 +2488,6 @@ NTSTATUS _netr_Unused47(struct pipes_str + 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; + } +Index: samba-3.6.23/source3/rpc_server/ntsvcs/srv_ntsvcs_nt.c +=================================================================== +--- samba-3.6.23.orig/source3/rpc_server/ntsvcs/srv_ntsvcs_nt.c ++++ samba-3.6.23/source3/rpc_server/ntsvcs/srv_ntsvcs_nt.c +@@ -227,7 +227,7 @@ WERROR _PNP_HwProfFlags(struct pipes_str + 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_stru + 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 + 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_ + 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_s + 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_str + 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 + 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(str + 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 pipe + 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 + 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 pipe + 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 pipe + 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_struc + 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 pip + 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_s + 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_st + 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_ + 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(stru + 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(struc + 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(s + 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_RegisterDeviceClassAssociati + 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_UnregisterDeviceClassAssocia + 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 + 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 + 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_s + 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 + 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 + 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 pipe + 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_ + 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 pipe + 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_ + 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_str + 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 pi + 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 + 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_ + 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 + 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_str + 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 + 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_ + 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 pi + 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_struc + 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_stru + 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_s + 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_s + 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 pip + 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_st + 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 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 pipe + 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_struc + 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(stru + 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(stru + 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_st + 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 + 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(struc + 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 pipe + 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 pi + 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 + 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; + } +Index: samba-3.6.23/source3/rpc_server/rpc_handles.c +=================================================================== +--- samba-3.6.23.orig/source3/rpc_server/rpc_handles.c ++++ samba-3.6.23/source3/rpc_server/rpc_handles.c +@@ -242,7 +242,7 @@ static struct dcesrv_handle *find_policy + 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; + } +Index: samba-3.6.23/source3/rpc_server/rpc_ncacn_np.c +=================================================================== +--- samba-3.6.23.orig/source3/rpc_server/rpc_ncacn_np.c ++++ samba-3.6.23/source3/rpc_server/rpc_ncacn_np.c +@@ -216,24 +216,13 @@ static NTSTATUS rpcint_dispatch(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; +Index: samba-3.6.23/source3/rpc_server/samr/srv_samr_nt.c +=================================================================== +--- samba-3.6.23.orig/source3/rpc_server/samr/srv_samr_nt.c ++++ samba-3.6.23/source3/rpc_server/samr/srv_samr_nt.c +@@ -6682,7 +6682,7 @@ NTSTATUS _samr_ValidatePassword(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_str + 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_SetMemberAttributesOfGrou + 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_TestPrivateFunctionsDomai + 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( + 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 + 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_RemoveMultipleMembersFrom + 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(str + 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(str + 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; + } +Index: samba-3.6.23/source3/rpc_server/spoolss/srv_spoolss_nt.c +=================================================================== +--- samba-3.6.23.orig/source3/rpc_server/spoolss/srv_spoolss_nt.c ++++ samba-3.6.23/source3/rpc_server/spoolss/srv_spoolss_nt.c +@@ -10201,7 +10201,7 @@ WERROR _spoolss_AddPort(struct pipes_str + 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; + } + +@@ -10212,7 +10212,7 @@ WERROR _spoolss_GetPrinterDriver(struct + 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; + } + +@@ -10223,7 +10223,7 @@ WERROR _spoolss_ReadPrinter(struct pipes + 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; + } + +@@ -10234,7 +10234,7 @@ WERROR _spoolss_WaitForPrinterChange(str + 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; + } + +@@ -10245,7 +10245,7 @@ WERROR _spoolss_ConfigurePort(struct pip + 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; + } + +@@ -10256,7 +10256,7 @@ WERROR _spoolss_DeletePort(struct pipes_ + 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; + } + +@@ -10267,7 +10267,7 @@ WERROR _spoolss_CreatePrinterIC(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; + } + +@@ -10278,7 +10278,7 @@ WERROR _spoolss_PlayGDIScriptOnPrinterIC + 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; + } + +@@ -10289,7 +10289,7 @@ WERROR _spoolss_DeletePrinterIC(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; + } + +@@ -10300,7 +10300,7 @@ WERROR _spoolss_AddPrinterConnection(str + 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; + } + +@@ -10311,7 +10311,7 @@ WERROR _spoolss_DeletePrinterConnection( + 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; + } + +@@ -10322,7 +10322,7 @@ WERROR _spoolss_PrinterMessageBox(struct + 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; + } + +@@ -10333,7 +10333,7 @@ WERROR _spoolss_AddMonitor(struct pipes_ + 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; + } + +@@ -10344,7 +10344,7 @@ WERROR _spoolss_DeleteMonitor(struct pip + 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; + } + +@@ -10355,7 +10355,7 @@ WERROR _spoolss_DeletePrintProcessor(str + 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; + } + +@@ -10366,7 +10366,7 @@ WERROR _spoolss_AddPrintProvidor(struct + 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; + } + +@@ -10377,7 +10377,7 @@ WERROR _spoolss_DeletePrintProvidor(stru + 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; + } + +@@ -10388,7 +10388,7 @@ WERROR _spoolss_FindFirstPrinterChangeNo + 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; + } + +@@ -10399,7 +10399,7 @@ WERROR _spoolss_FindNextPrinterChangeNot + 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; + } + +@@ -10410,7 +10410,7 @@ WERROR _spoolss_RouterFindFirstPrinterCh + 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; + } + +@@ -10421,7 +10421,7 @@ WERROR _spoolss_ReplyOpenPrinter(struct + 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; + } + +@@ -10432,7 +10432,7 @@ WERROR _spoolss_RouterReplyPrinter(struc + 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; + } + +@@ -10443,7 +10443,7 @@ WERROR _spoolss_ReplyClosePrinter(struct + 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; + } + +@@ -10454,7 +10454,7 @@ WERROR _spoolss_AddPortEx(struct pipes_s + 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; + } + +@@ -10465,7 +10465,7 @@ WERROR _spoolss_RouterFindFirstPrinterCh + 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; + } + +@@ -10476,7 +10476,7 @@ WERROR _spoolss_SpoolerInit(struct pipes + 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; + } + +@@ -10487,7 +10487,7 @@ WERROR _spoolss_ResetPrinterEx(struct pi + 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; + } + +@@ -10498,7 +10498,7 @@ WERROR _spoolss_RouterReplyPrinterEx(str + 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; + } + +@@ -10509,7 +10509,7 @@ WERROR _spoolss_44(struct pipes_struct * + 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; + } + +@@ -10520,7 +10520,7 @@ WERROR _spoolss_SetPort(struct pipes_str + 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; + } + +@@ -10531,7 +10531,7 @@ WERROR _spoolss_4a(struct pipes_struct * + 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; + } + +@@ -10542,7 +10542,7 @@ WERROR _spoolss_4b(struct pipes_struct * + 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; + } + +@@ -10553,7 +10553,7 @@ WERROR _spoolss_4c(struct pipes_struct * + 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; + } + +@@ -10564,7 +10564,7 @@ WERROR _spoolss_53(struct pipes_struct * + 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; + } + +@@ -10575,7 +10575,7 @@ WERROR _spoolss_AddPerMachineConnection( + 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; + } + +@@ -10586,7 +10586,7 @@ WERROR _spoolss_DeletePerMachineConnecti + 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; + } + +@@ -10597,7 +10597,7 @@ WERROR _spoolss_EnumPerMachineConnection + 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; + } + +@@ -10608,7 +10608,7 @@ WERROR _spoolss_5a(struct pipes_struct * + 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; + } + +@@ -10619,7 +10619,7 @@ WERROR _spoolss_5b(struct pipes_struct * + 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; + } + +@@ -10630,7 +10630,7 @@ WERROR _spoolss_5c(struct pipes_struct * + 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; + } + +@@ -10641,7 +10641,7 @@ WERROR _spoolss_5d(struct pipes_struct * + 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; + } + +@@ -10652,7 +10652,7 @@ WERROR _spoolss_5e(struct pipes_struct * + 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; + } + +@@ -10663,7 +10663,7 @@ WERROR _spoolss_5f(struct pipes_struct * + 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; + } + +@@ -10674,7 +10674,7 @@ WERROR _spoolss_60(struct pipes_struct * + 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; + } + +@@ -10685,7 +10685,7 @@ WERROR _spoolss_61(struct pipes_struct * + 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; + } + +@@ -10696,7 +10696,7 @@ WERROR _spoolss_62(struct pipes_struct * + 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; + } + +@@ -10707,7 +10707,7 @@ WERROR _spoolss_63(struct pipes_struct * + 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; + } + +@@ -10718,7 +10718,7 @@ WERROR _spoolss_64(struct pipes_struct * + 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; + } + +@@ -10729,7 +10729,7 @@ WERROR _spoolss_65(struct pipes_struct * + 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; + } + +@@ -10740,7 +10740,7 @@ WERROR _spoolss_GetCorePrinterDrivers(st + 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; + } + +@@ -10751,7 +10751,7 @@ WERROR _spoolss_67(struct pipes_struct * + 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; + } + +@@ -10762,7 +10762,7 @@ WERROR _spoolss_GetPrinterDriverPackageP + 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; + } + +@@ -10773,7 +10773,7 @@ WERROR _spoolss_69(struct pipes_struct * + 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; + } + +@@ -10784,7 +10784,7 @@ WERROR _spoolss_6a(struct pipes_struct * + 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; + } + +@@ -10795,7 +10795,7 @@ WERROR _spoolss_6b(struct pipes_struct * + 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; + } + +@@ -10806,6 +10806,6 @@ WERROR _spoolss_6c(struct pipes_struct * + 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; + } +Index: samba-3.6.23/source3/rpc_server/srvsvc/srv_srvsvc_nt.c +=================================================================== +--- samba-3.6.23.orig/source3/rpc_server/srvsvc/srv_srvsvc_nt.c ++++ samba-3.6.23/source3/rpc_server/srvsvc/srv_srvsvc_nt.c +@@ -2549,244 +2549,244 @@ WERROR _srvsvc_NetFileClose(struct pipes + 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; + } +Index: samba-3.6.23/source3/rpc_server/svcctl/srv_svcctl_nt.c +=================================================================== +--- samba-3.6.23.orig/source3/rpc_server/svcctl/srv_svcctl_nt.c ++++ samba-3.6.23/source3/rpc_server/svcctl/srv_svcctl_nt.c +@@ -1004,195 +1004,195 @@ WERROR _svcctl_SetServiceObjectSecurity( + 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; + } +Index: samba-3.6.23/source3/rpc_server/winreg/srv_winreg_nt.c +=================================================================== +--- samba-3.6.23.orig/source3/rpc_server/winreg/srv_winreg_nt.c ++++ samba-3.6.23/source3/rpc_server/winreg/srv_winreg_nt.c +@@ -760,7 +760,7 @@ WERROR _winreg_SaveKeyEx(struct pipes_st + /* 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_st + /* 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_s + /* 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_stru + /* 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_ + /* 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; + } +Index: samba-3.6.23/source3/rpc_server/wkssvc/srv_wkssvc_nt.c +=================================================================== +--- samba-3.6.23.orig/source3/rpc_server/wkssvc/srv_wkssvc_nt.c ++++ samba-3.6.23/source3/rpc_server/wkssvc/srv_wkssvc_nt.c +@@ -405,7 +405,7 @@ WERROR _wkssvc_NetWkstaSetInfo(struct pi + 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(stru + 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(stru + 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(str + 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(str + 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(str + 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_s + 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 pip + 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_s + 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 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(str + 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_NetrWorkstationStatistics + 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(st + 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(st + 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 pip + 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 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 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 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(st + 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 + 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_NetrRenameMachineInDomain + 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 + 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(struc + 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_NetrAddAlternateComputerN + 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_NetrRemoveAlternateComput + 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_NetrSetPrimaryComputernam + 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_NetrEnumerateComputerName + 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; + } +Index: samba-3.6.23/libcli/auth/smbencrypt.c +=================================================================== +--- samba-3.6.23.orig/libcli/auth/smbencrypt.c ++++ samba-3.6.23/libcli/auth/smbencrypt.c +@@ -355,11 +355,18 @@ DATA_BLOB NTLMv2_generate_names_blob(TAL + DATA_BLOB names_blob = data_blob_talloc(mem_ctx, NULL, 0); + + /* Deliberately ignore return here.. */ +- (void)msrpc_gen(mem_ctx, &names_blob, +- "aaa", +- MsvAvNbDomainName, domain, +- MsvAvNbComputerName, hostname, +- MsvAvEOL, ""); ++ if (hostname != NULL) { ++ (void)msrpc_gen(mem_ctx, &names_blob, ++ "aaa", ++ MsvAvNbDomainName, domain, ++ MsvAvNbComputerName, hostname, ++ MsvAvEOL, ""); ++ } else { ++ (void)msrpc_gen(mem_ctx, &names_blob, ++ "aa", ++ MsvAvNbDomainName, domain, ++ MsvAvEOL, ""); ++ } + return names_blob; + } +