Index: trunk/server/docs-xml/smbdotconf/ldap/clientldapsaslwrapping.xml
===================================================================
--- trunk/server/docs-xml/smbdotconf/ldap/clientldapsaslwrapping.xml	(revision 918)
+++ trunk/server/docs-xml/smbdotconf/ldap/clientldapsaslwrapping.xml	(revision 920)
@@ -35,10 +35,8 @@
 
 	<para>
-	The default value is <emphasis>plain</emphasis> which is not irritable 
-	to KRB5 clock skew errors. That implies synchronizing the time
-	with the KDC in the case of using <emphasis>sign</emphasis> or 
-	<emphasis>seal</emphasis>.
+	The default value is <emphasis>sign</emphasis>. That implies synchronizing the time
+	with the KDC in the case of using <emphasis>Kerberos</emphasis>.
 	</para>
 </description>
-<value type="default">plain</value>
+<value type="default">sign</value>
 </samba:parameter>
Index: trunk/server/docs-xml/smbdotconf/protocol/clientusespnego.xml
===================================================================
--- trunk/server/docs-xml/smbdotconf/protocol/clientusespnego.xml	(revision 918)
+++ trunk/server/docs-xml/smbdotconf/protocol/clientusespnego.xml	(revision 920)
@@ -10,4 +10,9 @@
     3.0) to agree upon an authentication
     mechanism.  This enables Kerberos authentication in particular.</para>
+
+    <para>When <smbconfoption name="client NTLMv2 auth"/> is also set to
+    <constant>yes</constant> extended security (SPNEGO) is required
+    in order to use NTLMv2 only within NTLMSSP. This behavior was
+    introduced with the patches for CVE-2016-2111.</para>
 </description>
 
Index: trunk/server/docs-xml/smbdotconf/security/allowdcerpcauthlevelconnect.xml
===================================================================
--- trunk/server/docs-xml/smbdotconf/security/allowdcerpcauthlevelconnect.xml	(revision 920)
+++ trunk/server/docs-xml/smbdotconf/security/allowdcerpcauthlevelconnect.xml	(revision 920)
@@ -0,0 +1,22 @@
+<samba:parameter name="allow dcerpc auth level connect"
+                 context="G"
+                 type="boolean"
+                 xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
+<description>
+	<para>This option controls whether DCERPC services are allowed to
+	be used with DCERPC_AUTH_LEVEL_CONNECT, which provides authentication,
+	but no per message integrity nor privacy protection.</para>
+
+	<para>The behavior can be controlled per interface name (e.g. lsarpc, netlogon, samr, srvsvc,
+	winreg, wkssvc ...) by using 'allow dcerpc auth level connect:interface = no' as option.</para>
+
+	<para>This option yields precedence to the implentation specific restrictions.
+	E.g. the drsuapi and backupkey protocols require DCERPC_AUTH_LEVEL_PRIVACY.
+	While others like samr and lsarpc have a hardcoded default of <constant>no</constant>.
+	</para>
+</description>
+
+<value type="default">no</value>
+<value type="example">yes</value>
+
+</samba:parameter>
Index: trunk/server/docs-xml/smbdotconf/security/clientipcsigning.xml
===================================================================
--- trunk/server/docs-xml/smbdotconf/security/clientipcsigning.xml	(revision 920)
+++ trunk/server/docs-xml/smbdotconf/security/clientipcsigning.xml	(revision 920)
@@ -0,0 +1,23 @@
+<samba:parameter name="client ipc signing"
+                 context="G"
+                 type="enum"
+                 enumlist="enum_smb_signing_vals"
+                 xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
+<description>
+    <para>This controls whether the client is allowed or required to use SMB signing for IPC$
+    connections as DCERPC transport inside of winbind. Possible values
+    are <emphasis>auto</emphasis>, <emphasis>mandatory</emphasis>
+    and <emphasis>disabled</emphasis>.
+    </para>
+
+    <para>When set to auto, SMB signing is offered, but not enforced and if set
+    to disabled, SMB signing is not offered either.</para>
+
+    <para>Connections from winbindd to Active Directory Domain Controllers
+    always enforce signing.</para>
+</description>
+
+<related>client signing</related>
+
+<value type="default">mandatory</value>
+</samba:parameter>
Index: trunk/server/docs-xml/smbdotconf/security/clientntlmv2auth.xml
===================================================================
--- trunk/server/docs-xml/smbdotconf/security/clientntlmv2auth.xml	(revision 918)
+++ trunk/server/docs-xml/smbdotconf/security/clientntlmv2auth.xml	(revision 920)
@@ -29,4 +29,9 @@
     'best practice' security polices) only allow NTLMv2 responses, and
     not the weaker LM or NTLM.</para>
+
+    <para>When <smbconfoption name="client use spnego"/> is also set to
+    <constant>yes</constant> extended security (SPNEGO) is required
+    in order to use NTLMv2 only within NTLMSSP. This behavior was
+    introduced with the patches for CVE-2016-2111.</para>
 </description>
 <value type="default">yes</value>
Index: trunk/server/docs-xml/smbdotconf/security/clientsigning.xml
===================================================================
--- trunk/server/docs-xml/smbdotconf/security/clientsigning.xml	(revision 918)
+++ trunk/server/docs-xml/smbdotconf/security/clientsigning.xml	(revision 920)
@@ -13,4 +13,7 @@
     When set to mandatory, SMB signing is required and if set 
 	to disabled, SMB signing is not offered either.
+
+    <para>IPC$ connections for DCERPC e.g. in winbindd, are handled by the
+    <smbconfoption name="client ipc signing"/> option.</para>
 </para>
 </description>
Index: trunk/server/docs-xml/smbdotconf/security/rawntlmv2auth.xml
===================================================================
--- trunk/server/docs-xml/smbdotconf/security/rawntlmv2auth.xml	(revision 920)
+++ trunk/server/docs-xml/smbdotconf/security/rawntlmv2auth.xml	(revision 920)
@@ -0,0 +1,19 @@
+<samba:parameter name="raw NTLMv2 auth"
+                 context="G"
+                 type="boolean"
+                 xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
+<description>
+    <para>This parameter determines whether or not <citerefentry><refentrytitle>smbd</refentrytitle>
+    <manvolnum>8</manvolnum></citerefentry> will allow SMB1 clients without
+    extended security (without SPNEGO) to use NTLMv2 authentication.</para>
+
+    <para>If this option, <command moreinfo="none">lanman auth</command>
+    and <command moreinfo="none">ntlm auth</command> are all disabled,
+    then only clients with SPNEGO support will be permitted.
+    That means NTLMv2 is only supported within NTLMSSP.</para>
+</description>
+
+<related>lanman auth</related>
+<related>ntlm auth</related>
+<value type="default">no</value>
+</samba:parameter>
Index: trunk/server/docs-xml/smbdotconf/winbind/winbindsealedpipes.xml
===================================================================
--- trunk/server/docs-xml/smbdotconf/winbind/winbindsealedpipes.xml	(revision 920)
+++ trunk/server/docs-xml/smbdotconf/winbind/winbindsealedpipes.xml	(revision 920)
@@ -0,0 +1,15 @@
+<samba:parameter name="winbind sealed pipes"
+                 context="G"
+                 type="boolean"
+                 xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
+<description>
+	<para>This option controls whether any requests from winbindd to domain controllers
+		pipe will be sealed. Disabling sealing can be useful for debugging
+		purposes.</para>
+
+	<para>The behavior can be controlled per netbios domain
+	by using 'winbind sealed pipes:NETBIOSDOMAIN = no' as option.</para>
+</description>
+
+<value type="default">yes</value>
+</samba:parameter>
Index: trunk/server/lib/util/bitmap.h
===================================================================
--- trunk/server/lib/util/bitmap.h	(revision 920)
+++ trunk/server/lib/util/bitmap.h	(revision 920)
@@ -0,0 +1,32 @@
+/*
+   Unix SMB/CIFS implementation.
+   simple bitmap functions
+   Copyright (C) Andrew Tridgell 1992-1998
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* The following definitions come from lib/bitmap.c  */
+
+struct bitmap {
+	uint32_t *b;
+	unsigned int n;
+};
+
+struct bitmap *bitmap_talloc(TALLOC_CTX *mem_ctx, int n);
+int bitmap_copy(struct bitmap * const dst, const struct bitmap * const src);
+bool bitmap_set(struct bitmap *bm, unsigned i);
+bool bitmap_clear(struct bitmap *bm, unsigned i);
+bool bitmap_query(struct bitmap *bm, unsigned i);
+int bitmap_find(struct bitmap *bm, unsigned ofs);
Index: trunk/server/lib/util/wscript_build
===================================================================
--- trunk/server/lib/util/wscript_build	(revision 918)
+++ trunk/server/lib/util/wscript_build	(revision 920)
@@ -100,4 +100,10 @@
                   private_library=True,
                   local_include=False
-                  )
+                 )
 
+bld.SAMBA_LIBRARY('bitmap',
+		  source='bitmap.c',
+		  deps='talloc samba-util',
+                  local_include=False,
+		  private_library=True)
+
Index: trunk/server/libcli/auth/ntlmssp.h
===================================================================
--- trunk/server/libcli/auth/ntlmssp.h	(revision 918)
+++ trunk/server/libcli/auth/ntlmssp.h	(revision 920)
@@ -84,4 +84,5 @@
 	DATA_BLOB session_key;
 
+	uint32_t required_flags;
 	uint32_t neg_flags; /* the current state of negotiation with the NTLMSSP partner */
 
Index: trunk/server/libcli/auth/proto.h
===================================================================
--- trunk/server/libcli/auth/proto.h	(revision 918)
+++ trunk/server/libcli/auth/proto.h	(revision 920)
@@ -140,4 +140,9 @@
 		      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);
 
 /***********************************************************
Index: trunk/server/libcli/auth/smbencrypt.c
===================================================================
--- trunk/server/libcli/auth/smbencrypt.c	(revision 918)
+++ trunk/server/libcli/auth/smbencrypt.c	(revision 920)
@@ -27,5 +27,5 @@
 #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])
@@ -356,9 +356,16 @@
 
 	/* 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;
 }
@@ -516,4 +523,144 @@
 }
 
+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
Index: trunk/server/libcli/auth/wscript_build
===================================================================
--- trunk/server/libcli/auth/wscript_build	(revision 918)
+++ trunk/server/libcli/auth/wscript_build	(revision 920)
@@ -20,5 +20,5 @@
 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'
 	)
Index: trunk/server/librpc/ABI/ndr-0.0.2.sigs
===================================================================
--- trunk/server/librpc/ABI/ndr-0.0.2.sigs	(revision 920)
+++ trunk/server/librpc/ABI/ndr-0.0.2.sigs	(revision 920)
@@ -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: trunk/server/librpc/ABI/ndr-0.0.3.sigs
===================================================================
--- trunk/server/librpc/ABI/ndr-0.0.3.sigs	(revision 920)
+++ trunk/server/librpc/ABI/ndr-0.0.3.sigs	(revision 920)
@@ -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: trunk/server/librpc/idl/dcerpc.idl
===================================================================
--- trunk/server/librpc/idl/dcerpc.idl	(revision 918)
+++ trunk/server/librpc/idl/dcerpc.idl	(revision 920)
@@ -10,4 +10,6 @@
 */
 import "misc.idl";
+
+cpp_quote("extern const uint8_t DCERPC_SEC_VT_MAGIC[8];")
 
 interface dcerpc
@@ -454,12 +456,19 @@
 
 	/* 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 */
@@ -467,6 +476,9 @@
 	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 */
@@ -477,5 +489,5 @@
 		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 */
@@ -507,3 +519,68 @@
 		[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: trunk/server/librpc/idl/idl_types.h
===================================================================
--- trunk/server/librpc/idl/idl_types.h	(revision 918)
+++ trunk/server/librpc/idl/idl_types.h	(revision 920)
@@ -48,2 +48,4 @@
 #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: trunk/server/librpc/ndr/libndr.h
===================================================================
--- trunk/server/librpc/ndr/libndr.h	(revision 918)
+++ trunk/server/librpc/ndr/libndr.h	(revision 920)
@@ -125,4 +125,18 @@
 #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)
@@ -164,4 +178,5 @@
 /* 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)
@@ -200,5 +215,7 @@
 	NDR_ERR_INVALID_POINTER,
 	NDR_ERR_UNREAD_BYTES,
-	NDR_ERR_NDR64
+	NDR_ERR_NDR64,
+	NDR_ERR_FLAGS,
+	NDR_ERR_INCOMPLETE_BUFFER
 };
 
@@ -218,18 +235,50 @@
 /*
   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__); \
 	} \
@@ -248,4 +297,8 @@
 	} \
 	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); \
 	} \
@@ -403,4 +456,6 @@
 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);
@@ -425,4 +480,6 @@
 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);
@@ -430,7 +487,9 @@
 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);
Index: trunk/server/librpc/ndr/ndr.c
===================================================================
--- trunk/server/librpc/ndr/ndr.c	(revision 918)
+++ trunk/server/librpc/ndr/ndr.c	(revision 920)
@@ -78,4 +78,109 @@
 }
 
+_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
@@ -166,4 +271,36 @@
 
 	return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ void ndr_print_debugc_helper(struct ndr_print *ndr, const char *format, ...)
+{
+	va_list ap;
+	char *s = NULL;
+	uint32_t i;
+	int ret;
+	int dbgc_class;
+
+	va_start(ap, format);
+	ret = vasprintf(&s, format, ap);
+	va_end(ap);
+
+	if (ret == -1) {
+		return;
+	}
+
+	dbgc_class = *(int *)ndr->private_data;
+
+	if (ndr->no_newline) {
+		DEBUGADDC(dbgc_class, 1,("%s", s));
+		free(s);
+		return;
+	}
+
+	for (i=0;i<ndr->depth;i++) {
+		DEBUGADDC(dbgc_class, 1,("    "));
+	}
+
+	DEBUGADDC(dbgc_class, 1,("%s\n", s));
+	free(s);
 }
 
@@ -236,4 +373,23 @@
 								  "\n");
 	}
+}
+
+/*
+  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);
 }
 
@@ -403,4 +559,13 @@
 	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);
@@ -558,4 +723,21 @@
 		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", 
@@ -590,5 +772,9 @@
 {
 	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) {
@@ -597,4 +783,22 @@
 		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;
@@ -1441,4 +1645,5 @@
 	{ NDR_ERR_UNREAD_BYTES, "Unread Bytes" },
 	{ NDR_ERR_NDR64, "NDR64 assertion error" },
+	{ NDR_ERR_INCOMPLETE_BUFFER, "Incomplete Buffer" },
 	{ 0, NULL }
 };
Index: trunk/server/librpc/ndr/ndr_basic.c
===================================================================
--- trunk/server/librpc/ndr/ndr_basic.c	(revision 918)
+++ trunk/server/librpc/ndr/ndr_basic.c	(revision 920)
@@ -62,4 +62,5 @@
 _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);
@@ -73,4 +74,5 @@
 _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);
@@ -84,4 +86,5 @@
 _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);
@@ -96,4 +99,5 @@
 _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);
@@ -108,4 +112,5 @@
 _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;
@@ -126,4 +131,5 @@
 _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);
@@ -138,4 +144,5 @@
 _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);
@@ -152,4 +159,5 @@
 	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);
@@ -170,4 +178,5 @@
 _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);
@@ -218,4 +227,5 @@
 _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);
@@ -231,4 +241,5 @@
 _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);
@@ -265,4 +276,5 @@
 {
 	uintptr_t h;
+	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
 	NDR_PULL_ALIGN(ndr, sizeof(h));
 	NDR_PULL_NEED_BYTES(ndr, sizeof(h));
@@ -279,4 +291,5 @@
 {
 	uint32_t v;
+	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
 	NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v));
 	*status = NT_STATUS(v);
@@ -303,4 +316,5 @@
 {
 	uint32_t v;
+	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
 	NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v));
 	*status = W_ERROR(v);
@@ -415,4 +429,5 @@
 _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;
@@ -426,4 +441,5 @@
 _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);
@@ -437,4 +453,5 @@
 _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);
@@ -448,4 +465,5 @@
 _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);
@@ -460,4 +478,5 @@
 _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);
@@ -483,4 +502,5 @@
 _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);
@@ -495,4 +515,5 @@
 _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);
@@ -518,4 +539,5 @@
 _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);
@@ -531,4 +553,5 @@
 _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);
@@ -564,4 +587,5 @@
 _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);
@@ -577,4 +601,5 @@
 {
 	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));
@@ -687,4 +712,5 @@
 _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;
@@ -739,4 +765,5 @@
 _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;
@@ -748,4 +775,5 @@
 _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;
@@ -757,4 +785,5 @@
 _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));
@@ -767,4 +796,5 @@
 _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;
@@ -777,4 +807,5 @@
 _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;
@@ -786,4 +817,5 @@
 _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;
@@ -815,4 +847,5 @@
 _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);
 }
@@ -840,4 +873,5 @@
 _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: trunk/server/librpc/ndr/ndr_dcerpc.c
===================================================================
--- trunk/server/librpc/ndr/ndr_dcerpc.c	(revision 920)
+++ trunk/server/librpc/ndr/ndr_dcerpc.c	(revision 920)
@@ -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 <http://www.gnu.org/licenses/>.
+*/
+
+#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: trunk/server/librpc/ndr/ndr_dcerpc.h
===================================================================
--- trunk/server/librpc/ndr/ndr_dcerpc.h	(revision 920)
+++ trunk/server/librpc/ndr/ndr_dcerpc.h	(revision 920)
@@ -0,0 +1,25 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   Manually parsed structures found in the DCERPC protocol
+
+   Copyright (C) Stefan Metzmacher 2014
+   Copyright (C) Gregor Beck 2014
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+enum ndr_err_code ndr_pop_dcerpc_sec_verification_trailer(
+	struct ndr_pull *ndr, TALLOC_CTX *mem_ctx,
+	struct dcerpc_sec_verification_trailer **_r);
Index: trunk/server/librpc/ndr/ndr_misc.c
===================================================================
--- trunk/server/librpc/ndr/ndr_misc.c	(revision 918)
+++ trunk/server/librpc/ndr/ndr_misc.c	(revision 920)
@@ -36,2 +36,49 @@
 		&& (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: trunk/server/librpc/ndr/ndr_ntlmssp.c
===================================================================
--- trunk/server/librpc/ndr/ndr_ntlmssp.c	(revision 918)
+++ trunk/server/librpc/ndr/ndr_ntlmssp.c	(revision 920)
@@ -177,3 +177,19 @@
 }
 
+_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: trunk/server/librpc/ndr/ndr_ntlmssp.h
===================================================================
--- trunk/server/librpc/ndr/ndr_ntlmssp.h	(revision 918)
+++ trunk/server/librpc/ndr/ndr_ntlmssp.h	(revision 920)
@@ -32,2 +32,4 @@
 _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: trunk/server/librpc/rpc/dcerpc_util.c
===================================================================
--- trunk/server/librpc/rpc/dcerpc_util.c	(revision 918)
+++ trunk/server/librpc/rpc/dcerpc_util.c	(revision 920)
@@ -28,4 +28,5 @@
 #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
@@ -92,29 +93,47 @@
 * @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;
-
-	data_and_pad = pkt_trailer->length
-			- (DCERPC_AUTH_TRAILER_LENGTH + pkt->auth_length);
-
-	/* 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;
-	}
-
-	*auth_length = pkt_trailer->length - data_and_pad;
+	uint16_t data_and_pad;
+	uint16_t auth_length;
+	uint32_t tmp_length;
+
+	ZERO_STRUCTP(auth);
+	if (_auth_length != NULL) {
+		*_auth_length = 0;
+	}
+
+	/* 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;
+	}
+	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 = 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);
@@ -136,12 +155,26 @@
 	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
 		talloc_free(ndr);
+		ZERO_STRUCTP(auth);
 		return ndr_map_error2ntstatus(ndr_err);
 	}
 
-	if (auth_data_only && data_and_pad != auth->auth_pad_length) {
-		DEBUG(1, (__location__ ": WARNING: pad length mismatch. "
+	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__ ": 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;
 	}
 
@@ -151,4 +184,81 @@
 	talloc_steal(mem_ctx, auth->credentials.data);
 	talloc_free(ndr);
+
+	if (_auth_length != NULL) {
+		*_auth_length = auth_length;
+	}
+
+	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;
@@ -342,2 +452,193 @@
 	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: trunk/server/librpc/rpc/rpc_common.h
===================================================================
--- trunk/server/librpc/rpc/rpc_common.h	(revision 918)
+++ trunk/server/librpc/rpc/rpc_common.h	(revision 920)
@@ -159,10 +159,15 @@
 * @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);
+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,
@@ -297,3 +302,44 @@
 				    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 <a href="http://msdn.microsoft.com/en-us/library/cc243559.aspx">MS-RPCE 2.2.2.13</a>.
+ * A check with an empty trailer succeeds.
+ *
+ * @param[in] vt a pointer to the security verification trailer.
+ * @param[in] bitmask1 which flags were negotiated on the connection.
+ * @param[in] pcontext the syntaxes negotiatied for the presentation context.
+ * @param[in] header2 some fields from the PDU header.
+ *
+ * @retval true on success.
+ */
+bool dcerpc_sec_verification_trailer_check(
+		const struct dcerpc_sec_verification_trailer *vt,
+		const uint32_t *bitmask1,
+		const struct dcerpc_sec_vt_pcontext *pcontext,
+		const struct dcerpc_sec_vt_header2 *header2);
+
 #endif /* __DEFAULT_LIBRPC_RPCCOMMON_H__ */
Index: trunk/server/librpc/wscript_build
===================================================================
--- trunk/server/librpc/wscript_build	(revision 918)
+++ trunk/server/librpc/wscript_build	(revision 920)
@@ -275,6 +275,7 @@
 
 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: trunk/server/pidl/lib/Parse/Pidl/ODL.pm
===================================================================
--- trunk/server/pidl/lib/Parse/Pidl/ODL.pm	(revision 918)
+++ trunk/server/pidl/lib/Parse/Pidl/ODL.pm	(revision 920)
@@ -71,5 +71,5 @@
 				}
 				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: trunk/server/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm
===================================================================
--- trunk/server/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm	(revision 918)
+++ trunk/server/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm	(revision 920)
@@ -184,5 +184,5 @@
 
 	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 */";
Index: trunk/server/pidl/pidl
===================================================================
--- trunk/server/pidl/pidl	(revision 918)
+++ trunk/server/pidl/pidl	(revision 920)
@@ -606,5 +606,5 @@
 
 		$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";
 	}
 
Index: trunk/server/selftest/target/Samba3.pm
===================================================================
--- trunk/server/selftest/target/Samba3.pm	(revision 918)
+++ trunk/server/selftest/target/Samba3.pm	(revision 920)
@@ -128,4 +128,5 @@
 	domain logons = yes
 	lanman auth = yes
+	raw NTLMv2 auth = yes
 ";
 
@@ -231,4 +232,5 @@
 	security = server
         password server = $s3dcvars->{SERVER_IP}
+	client ntlmv2 auth = no
 ";
 
Index: trunk/server/source3/Makefile-smbtorture4
===================================================================
--- trunk/server/source3/Makefile-smbtorture4	(revision 918)
+++ trunk/server/source3/Makefile-smbtorture4	(revision 920)
@@ -7,5 +7,5 @@
 	@(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: trunk/server/source3/Makefile.in
===================================================================
--- trunk/server/source3/Makefile.in	(revision 918)
+++ trunk/server/source3/Makefile.in	(revision 920)
@@ -324,5 +324,6 @@
 	     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 \
@@ -455,5 +456,5 @@
 	  ../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 \
@@ -783,4 +784,5 @@
 PROFILES_OBJ = utils/profiles.o \
 	       $(LIBSMB_ERR_OBJ) \
+	       $(LIBNDR_NTLMSSP_OBJ) \
 	       $(PARAM_OBJ) \
                $(LIB_OBJ) $(LIB_DUMMY_OBJ) \
@@ -988,13 +990,15 @@
            $(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) \
              $(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) \
@@ -1004,13 +1008,15 @@
 	     $(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) \
-	       $(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 \
@@ -1026,5 +1032,7 @@
 		$(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) \
@@ -1099,5 +1107,7 @@
 		    $(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,5 +1132,7 @@
              $(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 \
@@ -1136,4 +1148,5 @@
 		  $(PARAM_OBJ) \
 		  $(LIBSMB_ERR_OBJ) \
+		  $(LIBNDR_NTLMSSP_OBJ) \
 		  $(POPT_LIB_OBJ)
 
@@ -1219,5 +1232,5 @@
 
 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 \
@@ -1234,5 +1247,7 @@
         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) \
@@ -1241,4 +1256,5 @@
 
 MSGTEST_OBJ = torture/msgtest.o $(PARAM_OBJ) $(LIBSMB_ERR_OBJ) \
+		 $(LIBNDR_NTLMSSP_OBJ) \
                  $(LIB_NONSMBD_OBJ) \
 		 $(LIBNDR_GEN_OBJ0)
@@ -1257,5 +1273,5 @@
 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
@@ -1269,5 +1285,7 @@
 		$(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) \
@@ -1276,10 +1294,12 @@
 		$(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
 
 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
@@ -1287,9 +1307,9 @@
 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 \
@@ -1307,5 +1327,5 @@
 
 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 \
@@ -1515,5 +1535,6 @@
 		  $(PARAM_OBJ) \
 		  $(LIB_NONSMBD_OBJ) \
-		  $(LIBSMB_ERR_OBJ)
+		  $(LIBSMB_ERR_OBJ) \
+		  $(LIBNDR_NTLMSSP_OBJ)
 
 DBWRAP_TORTURE_OBJ = utils/dbwrap_torture.o \
@@ -1521,4 +1542,5 @@
 		     $(LIB_NONSMBD_OBJ) \
 		     $(LIBSMB_ERR_OBJ) \
+		     $(LIBNDR_NTLMSSP_OBJ) \
 		     $(POPT_LIB_OBJ)
 
Index: trunk/server/source3/auth/auth_util.c
===================================================================
--- trunk/server/source3/auth/auth_util.c	(revision 918)
+++ trunk/server/source3/auth/auth_util.c	(revision 920)
@@ -31,4 +31,5 @@
 #include "lib/winbind_util.h"
 #include "passdb.h"
+#include "../lib/tsocket/tsocket.h"
 
 #undef DBGC_CLASS
@@ -368,4 +369,17 @@
                                       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, 
Index: trunk/server/source3/include/ntdomain.h
===================================================================
--- trunk/server/source3/include/ntdomain.h	(revision 918)
+++ trunk/server/source3/include/ntdomain.h	(revision 920)
@@ -88,5 +88,10 @@
 	int n_cmds;
 	uint32 context_id;
-
+	struct ndr_syntax_id syntax;
+
+	/*
+	 * shall we allow "connect" auth level for this interface ?
+	 */
+	bool allow_connect;
 } PIPE_RPC_FNS;
 
@@ -135,20 +140,15 @@
 
 	/*
-	 * 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.
-	 */
-
-	bool rng_fault_state;
+	 * States we can be in.
+	 */
+	bool allow_alter;
+	bool allow_bind;
+	bool allow_auth3;
+
+	/*
+	 * Set the DCERPC_FAULT to return.
+	 */
+
+	int fault_state;
 
 	/*
Index: trunk/server/source3/include/proto.h
===================================================================
--- trunk/server/source3/include/proto.h	(revision 918)
+++ trunk/server/source3/include/proto.h	(revision 920)
@@ -61,13 +61,4 @@
 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  */
@@ -1270,4 +1261,5 @@
 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) ;
@@ -1499,4 +1491,5 @@
 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);
@@ -1698,7 +1691,9 @@
 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);
+int lp_client_ipc_signing(void);
 int lp_server_signing(void);
 int lp_client_ldap_sasl_wrapping(void);
@@ -1827,4 +1822,5 @@
 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  */
Index: trunk/server/source3/include/smb.h
===================================================================
--- trunk/server/source3/include/smb.h	(revision 918)
+++ trunk/server/source3/include/smb.h	(revision 920)
@@ -713,5 +713,4 @@
 };
 
-
 /* the following are used by loadparm for option lists */
 typedef enum {
@@ -759,9 +758,4 @@
 #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 */
Index: trunk/server/source3/lib/bitmap.c
===================================================================
--- trunk/server/source3/lib/bitmap.c	(revision 918)
+++ trunk/server/source3/lib/bitmap.c	(revision 920)
@@ -19,4 +19,5 @@
 
 #include "includes.h"
+#include "lib/util/bitmap.h"
 
 /* these functions provide a simple way to allocate integers from a
@@ -30,10 +31,10 @@
 	struct bitmap *bm;
 
-	bm = TALLOC_P(mem_ctx, struct bitmap);
+	bm = talloc_zero(mem_ctx, struct bitmap);
 
 	if (!bm) return NULL;
 
 	bm->n = n;
-	bm->b = TALLOC_ZERO_ARRAY(bm, uint32, (n+31)/32);
+	bm->b = talloc_zero_array(bm, uint32_t, (n+31)/32);
 	if (!bm->b) {
 		TALLOC_FREE(bm);
@@ -52,5 +53,5 @@
 
         SMB_ASSERT(dst->b != src->b);
-	memcpy(dst->b, src->b, sizeof(uint32)*((count+31)/32));
+	memcpy(dst->b, src->b, sizeof(uint32_t)*((count+31)/32));
 
         return count;
@@ -65,8 +66,8 @@
 		DEBUG(0,("Setting invalid bitmap entry %d (of %d)\n",
 		      i, bm->n));
-		return False;
+		return false;
 	}
 	bm->b[i/32] |= (1<<(i%32));
-	return True;
+	return true;
 }
 
@@ -79,8 +80,8 @@
 		DEBUG(0,("clearing invalid bitmap entry %d (of %d)\n",
 		      i, bm->n));
-		return False;
+		return false;
 	}
 	bm->b[i/32] &= ~(1<<(i%32));
-	return True;
+	return true;
 }
 
@@ -90,9 +91,9 @@
 bool bitmap_query(struct bitmap *bm, unsigned i)
 {
-	if (i >= bm->n) return False;
+	if (i >= bm->n) return false;
 	if (bm->b[i/32] & (1<<(i%32))) {
-		return True;
+		return true;
 	}
-	return False;
+	return false;
 }
 
Index: trunk/server/source3/libads/sasl.c
===================================================================
--- trunk/server/source3/libads/sasl.c	(revision 918)
+++ trunk/server/source3/libads/sasl.c	(revision 920)
@@ -261,4 +261,35 @@
 	/* 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) {
Index: trunk/server/source3/librpc/rpc/dcerpc.h
===================================================================
--- trunk/server/source3/librpc/rpc/dcerpc.h	(revision 918)
+++ trunk/server/source3/librpc/rpc/dcerpc.h	(revision 920)
@@ -40,6 +40,8 @@
 	enum dcerpc_AuthType auth_type;
 	enum dcerpc_AuthLevel auth_level;
+	bool verified_bitmask1;
 
 	void *auth_ctx;
+	uint32_t auth_context_id;
 
 	/* Only the client code uses these 3 for now */
@@ -71,8 +73,4 @@
 				 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,
@@ -85,7 +83,6 @@
 			   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  */
Index: trunk/server/source3/librpc/rpc/dcerpc_helpers.c
===================================================================
--- trunk/server/source3/librpc/rpc/dcerpc_helpers.c	(revision 918)
+++ trunk/server/source3/librpc/rpc/dcerpc_helpers.c	(revision 920)
@@ -211,45 +211,4 @@
 
 /**
-* @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.
@@ -783,5 +742,5 @@
 					 auth->auth_level,
 					 pad_len,
-					 1 /* context id. */,
+					 auth->auth_context_id,
 					 &auth_blob,
 					 &auth_info);
@@ -845,8 +804,8 @@
 * @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
@@ -855,7 +814,6 @@
 			   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;
@@ -869,4 +827,12 @@
 	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:
@@ -882,5 +848,4 @@
 			break;
 		}
-		*pad_len = 0;
 		return NT_STATUS_OK;
 
@@ -891,5 +856,4 @@
 			return NT_STATUS_INVALID_PARAMETER;
 		}
-		*pad_len = 0;
 		return NT_STATUS_OK;
 
@@ -900,14 +864,6 @@
 	}
 
-	/* 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;
 	}
 
@@ -918,8 +874,21 @@
 	}
 
+	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;
+	}
+
+	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 - 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) {
@@ -997,8 +966,11 @@
 	 * 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;
Index: trunk/server/source3/libsmb/cliconnect.c
===================================================================
--- trunk/server/source3/libsmb/cliconnect.c	(revision 918)
+++ trunk/server/source3/libsmb/cliconnect.c	(revision 920)
@@ -2078,4 +2078,15 @@
 
 		/* 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);
Index: trunk/server/source3/libsmb/clidfs.c
===================================================================
--- trunk/server/source3/libsmb/clidfs.c	(revision 918)
+++ trunk/server/source3/libsmb/clidfs.c	(revision 920)
@@ -99,4 +99,9 @@
 	const char *password;
 	NTSTATUS status;
+	int signing_state = get_cmdline_auth_info_signing_state(auth_info);
+
+	if (force_encrypt) {
+		signing_state = Required;
+	}
 
 	/* make a copy so we don't modify the global string 'service' */
@@ -133,5 +138,5 @@
 
 	/* have to open a new connection */
-	c = cli_initialise_ex(get_cmdline_auth_info_signing_state(auth_info));
+	c = cli_initialise_ex(signing_state);
 	if (c == NULL) {
 		d_printf("Connection to %s failed\n", server_n);
Index: trunk/server/source3/libsmb/libsmb_server.c
===================================================================
--- trunk/server/source3/libsmb/libsmb_server.c	(revision 918)
+++ trunk/server/source3/libsmb/libsmb_server.c	(revision 920)
@@ -259,4 +259,5 @@
  	NTSTATUS status;
 	char *newserver, *newshare;
+	int signing_state = Undefined;
 
 	zero_sockaddr(&ss);
@@ -405,6 +406,10 @@
 	zero_sockaddr(&ss);
 
+	if (context->internal->smb_encryption_level != SMBC_ENCRYPTLEVEL_NONE) {
+		signing_state = Required;
+	}
+
 	/* have to open a new connection */
-	if ((c = cli_initialise()) == NULL) {
+	if ((c = cli_initialise_ex(signing_state)) == NULL) {
 		errno = ENOMEM;
 		return NULL;
@@ -751,4 +756,5 @@
                                    pp_workgroup, pp_username, pp_password);
         if (!ipc_srv) {
+		int signing_state = Undefined;
 
                 /* We didn't find a cached connection.  Get the password */
@@ -772,4 +778,7 @@
                         flags |= CLI_FULL_CONNECTION_USE_CCACHE;
                 }
+		if (context->internal->smb_encryption_level != SMBC_ENCRYPTLEVEL_NONE) {
+			signing_state = Required;
+		}
 
                 zero_sockaddr(&ss);
@@ -781,5 +790,5 @@
 						*pp_password,
 						flags,
-						Undefined);
+						signing_state);
                 if (! NT_STATUS_IS_OK(nt_status)) {
                         DEBUG(1,("cli_full_connection failed! (%s)\n",
Index: trunk/server/source3/libsmb/ntlmssp.c
===================================================================
--- trunk/server/source3/libsmb/ntlmssp.c	(revision 918)
+++ trunk/server/source3/libsmb/ntlmssp.c	(revision 920)
@@ -163,4 +163,34 @@
 }
 
+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
@@ -177,15 +207,17 @@
 	 */
 	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;
 }
 
@@ -200,15 +232,18 @@
 	/* 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;
 }
 
@@ -388,5 +423,10 @@
 
 	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;
+	}
+
+	if (ntlmssp_state->allow_lm_key) {
+		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;
 	}
 
@@ -421,4 +461,84 @@
 
 	return NT_STATUS_MORE_PROCESSING_REQUIRED;
+}
+
+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;
+		ntlmssp_state->unicode = true;
+	} else {
+		ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_UNICODE;
+		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
+		ntlmssp_state->unicode = false;
+	}
+
+	/*
+	 * 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_LM_KEY)) {
+		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_128)) {
+		ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128;
+	}
+
+	if (!(flags & NTLMSSP_NEGOTIATE_56)) {
+		ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_56;
+	}
+
+	if (!(flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) {
+		ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_KEY_EXCH;
+	}
+
+	if (!(flags & NTLMSSP_NEGOTIATE_SIGN)) {
+		ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SIGN;
+	}
+
+	if (!(flags & NTLMSSP_NEGOTIATE_SEAL)) {
+		ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SEAL;
+	}
+
+	if ((flags & NTLMSSP_REQUEST_TARGET)) {
+		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;
 }
 
@@ -449,4 +569,24 @@
 	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;
@@ -498,15 +638,4 @@
 
 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) {
@@ -525,11 +654,4 @@
 		}
 	}
-
-	data_blob_free(&server_domain_blob);
-
-	DEBUG(3, ("Got challenge flags:\n"));
-	debug_ntlmssp_flags(chal_flags);
-
-	ntlmssp_handle_neg_flags(ntlmssp_state, chal_flags, lp_client_lanman_auth());
 
 	if (ntlmssp_state->unicode) {
@@ -770,4 +892,5 @@
 
 	ntlmssp_state->use_ntlmv2 = use_ntlmv2;
+	ntlmssp_state->allow_lm_key = lp_client_lanman_auth();
 
 	ntlmssp_state->expected_state = NTLMSSP_INITIAL;
@@ -781,4 +904,8 @@
 		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) {
Index: trunk/server/source3/modules/vfs_acl_common.c
===================================================================
--- trunk/server/source3/modules/vfs_acl_common.c	(revision 918)
+++ trunk/server/source3/modules/vfs_acl_common.c	(revision 920)
@@ -24,4 +24,5 @@
 #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,
Index: trunk/server/source3/modules/vfs_full_audit.c
===================================================================
--- trunk/server/source3/modules/vfs_full_audit.c	(revision 918)
+++ trunk/server/source3/modules/vfs_full_audit.c	(revision 920)
@@ -65,4 +65,5 @@
 #include "auth.h"
 #include "ntioctl.h"
+#include "lib/util/bitmap.h"
 
 static int vfs_full_audit_debug_level = DBGC_VFS;
Index: trunk/server/source3/modules/vfs_shadow_copy2.c
===================================================================
--- trunk/server/source3/modules/vfs_shadow_copy2.c	(revision 918)
+++ trunk/server/source3/modules/vfs_shadow_copy2.c	(revision 920)
@@ -22,4 +22,6 @@
 #include "includes.h"
 #include "smbd/smbd.h"
+#include "smbd/globals.h"
+#include "../libcli/security/security.h"
 #include "system/filesys.h"
 #include "ntioctl.h"
@@ -765,4 +767,41 @@
 }
 
+static bool check_access_snapdir(struct vfs_handle_struct *handle,
+				const char *path)
+{
+	struct smb_filename smb_fname;
+	int ret;
+	NTSTATUS status;
+	uint32_t access_granted = 0;
+
+	ZERO_STRUCT(smb_fname);
+	smb_fname.base_name = talloc_asprintf(talloc_tos(),
+						"%s",
+						path);
+	if (smb_fname.base_name == NULL) {
+		return false;
+	}
+
+	ret = SMB_VFS_NEXT_STAT(handle, &smb_fname);
+	if (ret != 0 || !S_ISDIR(smb_fname.st.st_ex_mode)) {
+		TALLOC_FREE(smb_fname.base_name);
+		return false;
+	}
+
+	status = smbd_check_open_rights(handle->conn,
+					&smb_fname,
+					SEC_DIR_LIST,
+					&access_granted);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(0,("user does not have list permission "
+			"on snapdir %s\n",
+			smb_fname.base_name));
+		TALLOC_FREE(smb_fname.base_name);
+		return false;
+	}
+	TALLOC_FREE(smb_fname.base_name);
+	return true;
+}
+
 static int shadow_copy2_rmdir(vfs_handle_struct *handle,  const char *fname)
 {
@@ -878,4 +917,5 @@
 	TALLOC_CTX *tmp_ctx = talloc_new(handle->data);
 	char *snapshot;
+	bool ret;
 
 	snapdir = shadow_copy2_find_snapdir(tmp_ctx, handle);
@@ -884,4 +924,11 @@
 			 handle->conn->connectpath));
 		errno = EINVAL;
+		talloc_free(tmp_ctx);
+		return -1;
+	}
+	ret = check_access_snapdir(handle, snapdir);
+	if (!ret) {
+		DEBUG(0,("access denied on listing snapdir %s\n", snapdir));
+		errno = EACCES;
 		talloc_free(tmp_ctx);
 		return -1;
Index: trunk/server/source3/param/loadparm.c
===================================================================
--- trunk/server/source3/param/loadparm.c	(revision 918)
+++ trunk/server/source3/param/loadparm.c	(revision 920)
@@ -65,4 +65,5 @@
 #include "dbwrap.h"
 #include "smbldap.h"
+#include "../lib/util/bitmap.h"
 
 #ifdef HAVE_SYS_SYSCTL_H
@@ -219,4 +220,5 @@
 	bool bWinbindRefreshTickets;
 	bool bWinbindOfflineLogon;
+	bool bWinbindSealedPipes;
 	bool bWinbindNormalizeNames;
 	bool bWinbindRpcOnly;
@@ -340,4 +342,5 @@
 	bool bLanmanAuth;
 	bool bNTLMAuth;
+	bool bRawNTLMv2Auth;
 	bool bUseSpnego;
 	bool bClientLanManAuth;
@@ -357,4 +360,5 @@
 	bool bHostnameLookups;
 	bool bUnixExtensions;
+	bool bAllowDcerpcAuthLevelConnect;
 	bool bDisableNetbios;
 	char * szDedicatedKeytabFile;
@@ -369,4 +373,5 @@
 	int name_cache_timeout;
 	int client_signing;
+	int client_ipc_signing;
 	int server_signing;
 	int client_ldap_sasl_wrapping;
@@ -1387,4 +1392,13 @@
 	},
 	{
+		.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,
@@ -2295,4 +2309,13 @@
 	},
 	{
+		.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,
@@ -2308,4 +2331,13 @@
 		.p_class	= P_GLOBAL,
 		.ptr		= &Globals.client_signing,
+		.special	= NULL,
+		.enum_list	= enum_smb_signing_vals,
+		.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,
@@ -4754,4 +4786,13 @@
 		.p_class	= P_GLOBAL,
 		.ptr		= &Globals.bWinbindOfflineLogon,
+		.special	= NULL,
+		.enum_list	= NULL,
+		.flags		= FLAG_ADVANCED,
+	},
+	{
+		.label		= "winbind sealed pipes",
+		.type		= P_BOOL,
+		.p_class	= P_GLOBAL,
+		.ptr		= &Globals.bWinbindSealedPipes,
 		.special	= NULL,
 		.enum_list	= NULL,
@@ -5381,6 +5422,9 @@
 	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 = 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 */
+
+	Globals.bAllowDcerpcAuthLevelConnect = false; /* we don't allow this by default */
 
 	Globals.map_to_guest = 0;	/* By Default, "Never" */
@@ -5425,4 +5469,6 @@
 	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 
@@ -5489,4 +5535,5 @@
 	Globals.bWinbindRefreshTickets = False;
 	Globals.bWinbindOfflineLogon = False;
+	Globals.bWinbindSealedPipes = True;
 
 	Globals.iIdmapCacheTime = 86400 * 7; /* a week by default */
@@ -5501,4 +5548,5 @@
 
 	Globals.client_signing = Auto;
+	Globals.client_ipc_signing = Required;
 	Globals.server_signing = False;
 
@@ -5754,4 +5802,5 @@
 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)
@@ -5767,4 +5816,5 @@
 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)
@@ -5863,4 +5913,5 @@
 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)
@@ -6101,4 +6152,5 @@
 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)
@@ -9753,4 +9805,19 @@
         }
 #endif
+
+	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();
 
Index: trunk/server/source3/passdb/pdb_get_set.c
===================================================================
--- trunk/server/source3/passdb/pdb_get_set.c	(revision 918)
+++ trunk/server/source3/passdb/pdb_get_set.c	(revision 920)
@@ -26,4 +26,5 @@
 #include "../libcli/auth/libcli_auth.h"
 #include "../libcli/security/security.h"
+#include "../lib/util/bitmap.h"
 
 #undef DBGC_CLASS
Index: trunk/server/source3/rpc_client/cli_pipe.c
===================================================================
--- trunk/server/source3/rpc_client/cli_pipe.c	(revision 918)
+++ trunk/server/source3/rpc_client/cli_pipe.c	(revision 920)
@@ -29,4 +29,5 @@
 #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"
@@ -400,10 +401,11 @@
 						DATA_BLOB *pdu,
 						uint8_t expected_pkt_type,
+						uint32_t call_id,
 						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;
 
 	/*
@@ -413,48 +415,126 @@
 	*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_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;
+		}
+
+		break;
+
 	case DCERPC_PKT_ALTER_RESP:
-	case DCERPC_PKT_BIND_ACK:
-
-		/* Client code never receives this kind of packets */
+		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;
 
 		/* 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)) {
+			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;
 		}
 
-		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;
-		}
-
-		DEBUG(10, ("Got pdu len %lu, data_len %lu, ss_len %u\n",
+		*rdata = tmp_stub;
+
+		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));
 
 		/*
@@ -477,11 +557,21 @@
 		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 "
@@ -498,24 +588,14 @@
 			  (unsigned int)pkt->ptype,
 			  rpccli_pipe_txt(talloc_tos(), cli)));
-		return NT_STATUS_INVALID_INFO_CLASS;
-	}
-
-	if (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 "
-			  "RPC packet type - %u, not %u\n",
+			  "RPC call_id - %u, not %u\n",
 			  rpccli_pipe_txt(talloc_tos(), cli),
-			  pkt->ptype, expected_pkt_type));
-		return NT_STATUS_INVALID_INFO_CLASS;
-	}
-
-	/* 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;
+			  pkt->call_id, call_id));
+		return NT_STATUS_RPC_PROTOCOL_ERROR;
 	}
 
@@ -874,4 +954,10 @@
 	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;
@@ -883,13 +969,11 @@
 					  !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;
-	}
-
-	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;
 	}
@@ -899,4 +983,5 @@
 						&state->incoming_frag,
 						state->expected_pkt_type,
+						state->call_id,
 						&rdata,
 						&state->reply_pdu);
@@ -907,4 +992,26 @@
 		  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);
@@ -931,5 +1038,22 @@
 			 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) {
+		/*
+		 * 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;
 	}
@@ -939,4 +1063,10 @@
 		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;
@@ -968,4 +1098,12 @@
 					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;
@@ -1237,5 +1375,5 @@
 						auth->auth_level,
 						0, /* auth_pad_length */
-						1, /* auth_context_id */
+						auth->auth_context_id,
 						&auth_token,
 						&auth_info);
@@ -1270,4 +1408,8 @@
 	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;
@@ -1276,4 +1418,5 @@
 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);
@@ -1311,4 +1454,9 @@
 	}
 
+	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)) {
@@ -1345,8 +1493,130 @@
 }
 
+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;
@@ -1354,14 +1624,28 @@
 	size_t pad_len;
 	size_t data_left;
-	NTSTATUS status;
+	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)) {
@@ -1373,13 +1657,18 @@
 	}
 
-	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;
@@ -1401,9 +1690,24 @@
 	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;
 	}
 
@@ -1425,5 +1729,4 @@
 	}
 
-	state->req_data_sent += data_sent_thistime;
 	*is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
 
@@ -1489,4 +1792,18 @@
 		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);
 }
@@ -1560,7 +1877,6 @@
 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)
@@ -1572,8 +1888,8 @@
 
 	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 */
+					 auth->auth_context_id,
 					 pauth_blob,
 					 &u.auth3.auth_info);
@@ -1605,7 +1921,6 @@
 
 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,
@@ -1617,8 +1932,8 @@
 
 	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 */
+					 auth->auth_context_id,
 					 pauth_blob,
 					 &auth_info);
@@ -1648,7 +1963,13 @@
 	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,
@@ -1754,23 +2075,21 @@
 	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_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);
+	case DCERPC_AUTH_TYPE_SCHANNEL:
+		rpc_pipe_bind_step_two_trigger(req);
+		return;
+
+	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",
@@ -1779,8 +2098,28 @@
 			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;
+		}
+
+		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;
-
-	default:
-		goto err_out;
 	}
 
@@ -1870,4 +2209,151 @@
 }
 
+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,
@@ -1881,7 +2367,5 @@
 	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,
@@ -1916,8 +2400,6 @@
 	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);
@@ -2153,6 +2635,7 @@
 	 * 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;
 
@@ -2291,4 +2774,5 @@
 	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, "");
@@ -2315,4 +2799,5 @@
 	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, "");
@@ -2352,4 +2837,5 @@
 	result->auth_type = auth_type;
 	result->auth_level = auth_level;
+	result->auth_context_id = 1;
 
 	result->user_name = talloc_strdup(result, username);
@@ -2423,4 +2909,5 @@
 	result->auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
 	result->auth_level = auth_level;
+	result->auth_context_id = 1;
 
 	result->user_name = talloc_strdup(result, "");
@@ -3087,4 +3574,5 @@
 	auth->auth_type = DCERPC_AUTH_TYPE_KRB5;
 	auth->auth_level = auth_level;
+	auth->auth_context_id = 1;
 
 	if (!username) {
@@ -3157,4 +3645,5 @@
 	auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
 	auth->auth_level = auth_level;
+	auth->auth_context_id = 1;
 
 	if (!username) {
@@ -3231,4 +3720,5 @@
 	auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
 	auth->auth_level = auth_level;
+	auth->auth_context_id = 1;
 
 	if (!username) {
Index: trunk/server/source3/rpc_client/rpc_client.h
===================================================================
--- trunk/server/source3/rpc_client/rpc_client.h	(revision 918)
+++ trunk/server/source3/rpc_client/rpc_client.h	(revision 920)
@@ -40,4 +40,5 @@
 	struct ndr_syntax_id abstract_syntax;
 	struct ndr_syntax_id transfer_syntax;
+	bool verified_pcontext;
 
 	char *desthost;
Index: trunk/server/source3/rpc_server/dfs/srv_dfs_nt.c
===================================================================
--- trunk/server/source3/rpc_server/dfs/srv_dfs_nt.c	(revision 918)
+++ trunk/server/source3/rpc_server/dfs/srv_dfs_nt.c	(revision 920)
@@ -412,5 +412,5 @@
 {
 	/* FIXME: Implement your code here */
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -419,5 +419,5 @@
 {
 	/* FIXME: Implement your code here */
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -426,5 +426,5 @@
 {
 	/* FIXME: Implement your code here */
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -433,5 +433,5 @@
 {
 	/* FIXME: Implement your code here */
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -440,5 +440,5 @@
 {
 	/* FIXME: Implement your code here */
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -447,5 +447,5 @@
 {
 	/* FIXME: Implement your code here */
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -454,5 +454,5 @@
 {
 	/* FIXME: Implement your code here */
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -461,5 +461,5 @@
 {
 	/* FIXME: Implement your code here */
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -468,5 +468,5 @@
 {
 	/* FIXME: Implement your code here */
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -475,5 +475,5 @@
 {
 	/* FIXME: Implement your code here */
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -482,5 +482,5 @@
 {
 	/* FIXME: Implement your code here */
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -489,5 +489,5 @@
 {
 	/* FIXME: Implement your code here */
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -496,5 +496,5 @@
 {
 	/* FIXME: Implement your code here */
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -503,5 +503,5 @@
 {
 	/* FIXME: Implement your code here */
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -510,5 +510,5 @@
 {
 	/* FIXME: Implement your code here */
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -517,5 +517,5 @@
 {
 	/* FIXME: Implement your code here */
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -524,5 +524,5 @@
 {
 	/* FIXME: Implement your code here */
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -531,5 +531,5 @@
 {
 	/* FIXME: Implement your code here */
-	p->rng_fault_state = True;
-	return WERR_NOT_SUPPORTED;
-}
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+	return WERR_NOT_SUPPORTED;
+}
Index: trunk/server/source3/rpc_server/dssetup/srv_dssetup_nt.c
===================================================================
--- trunk/server/source3/rpc_server/dssetup/srv_dssetup_nt.c	(revision 918)
+++ trunk/server/source3/rpc_server/dssetup/srv_dssetup_nt.c	(revision 920)
@@ -131,5 +131,5 @@
 					struct dssetup_DsRoleDnsNameToFlatName *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -141,5 +141,5 @@
 			     struct dssetup_DsRoleDcAsDc *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -151,5 +151,5 @@
 				  struct dssetup_DsRoleDcAsReplica *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -161,5 +161,5 @@
 			       struct dssetup_DsRoleDemoteDc *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -171,5 +171,5 @@
 					     struct dssetup_DsRoleGetDcOperationProgress *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -181,5 +181,5 @@
 					    struct dssetup_DsRoleGetDcOperationResults *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -191,5 +191,5 @@
 			     struct dssetup_DsRoleCancel *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -201,5 +201,5 @@
 						struct dssetup_DsRoleServerSaveStateForUpgrade *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -211,5 +211,5 @@
 					     struct dssetup_DsRoleUpgradeDownlevelServer *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -221,5 +221,5 @@
 						  struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
 {
-	p->rng_fault_state = true;
-	return WERR_NOT_SUPPORTED;
-}
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+	return WERR_NOT_SUPPORTED;
+}
Index: trunk/server/source3/rpc_server/echo/srv_echo_nt.c
===================================================================
--- trunk/server/source3/rpc_server/echo/srv_echo_nt.c	(revision 918)
+++ trunk/server/source3/rpc_server/echo/srv_echo_nt.c	(revision 920)
@@ -88,5 +88,5 @@
 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;
 }
@@ -94,5 +94,5 @@
 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;
 }
@@ -106,5 +106,5 @@
 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;
 }
@@ -112,5 +112,5 @@
 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;
 }
@@ -118,5 +118,5 @@
 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: trunk/server/source3/rpc_server/epmapper/srv_epmapper.c
===================================================================
--- trunk/server/source3/rpc_server/epmapper/srv_epmapper.c	(revision 918)
+++ trunk/server/source3/rpc_server/epmapper/srv_epmapper.c	(revision 920)
@@ -298,4 +298,5 @@
 	if (p->transport != NCALRPC ||
 	    !is_priviledged_pipe(p->session_info)) {
+		p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 		return EPMAPPER_STATUS_CANT_PERFORM_OP;
 	}
@@ -434,4 +435,5 @@
 	if (p->transport != NCALRPC ||
 	    !is_priviledged_pipe(p->session_info)) {
+		p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 		return EPMAPPER_STATUS_CANT_PERFORM_OP;
 	}
@@ -1097,5 +1099,5 @@
 		      struct epm_InqObject *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return EPMAPPER_STATUS_CANT_PERFORM_OP;
 }
@@ -1111,5 +1113,5 @@
 		       struct epm_MgmtDelete *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return EPMAPPER_STATUS_CANT_PERFORM_OP;
 }
@@ -1122,5 +1124,5 @@
 		    struct epm_MapAuth *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return EPMAPPER_STATUS_CANT_PERFORM_OP;
 }
Index: trunk/server/source3/rpc_server/eventlog/srv_eventlog_nt.c
===================================================================
--- trunk/server/source3/rpc_server/eventlog/srv_eventlog_nt.c	(revision 918)
+++ trunk/server/source3/rpc_server/eventlog/srv_eventlog_nt.c	(revision 920)
@@ -696,5 +696,5 @@
 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;
 }
@@ -839,5 +839,5 @@
 					 struct eventlog_DeregisterEventSource *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -846,5 +846,5 @@
 				struct eventlog_ChangeNotify *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -853,5 +853,5 @@
 					struct eventlog_RegisterEventSourceW *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -860,5 +860,5 @@
 				       struct eventlog_OpenBackupEventLogW *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -867,5 +867,5 @@
 				  struct eventlog_ClearEventLogA *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -874,5 +874,5 @@
 				   struct eventlog_BackupEventLogA *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -881,5 +881,5 @@
 				 struct eventlog_OpenEventLogA *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -888,5 +888,5 @@
 					struct eventlog_RegisterEventSourceA *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -895,5 +895,5 @@
 				       struct eventlog_OpenBackupEventLogA *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -902,5 +902,5 @@
 				 struct eventlog_ReadEventLogA *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -909,5 +909,5 @@
 				struct eventlog_ReportEventA *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -916,5 +916,5 @@
 				      struct eventlog_RegisterClusterSvc *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -923,5 +923,5 @@
 					struct eventlog_DeregisterClusterSvc *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -930,5 +930,5 @@
 				      struct eventlog_WriteClusterEvents *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -937,5 +937,5 @@
 					 struct eventlog_ReportEventAndSourceW *r)
 {
-	p->rng_fault_state = True;
-	return NT_STATUS_NOT_IMPLEMENTED;
-}
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+	return NT_STATUS_NOT_IMPLEMENTED;
+}
Index: trunk/server/source3/rpc_server/lsa/srv_lsa_nt.c
===================================================================
--- trunk/server/source3/rpc_server/lsa/srv_lsa_nt.c	(revision 918)
+++ trunk/server/source3/rpc_server/lsa/srv_lsa_nt.c	(revision 920)
@@ -818,5 +818,5 @@
 
 	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;
 	}
@@ -3211,5 +3211,5 @@
 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;
 }
@@ -3218,5 +3218,5 @@
 			     struct lsa_ChangePassword *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -3224,5 +3224,5 @@
 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;
 }
@@ -3230,5 +3230,5 @@
 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;
 }
@@ -3237,5 +3237,5 @@
 				  struct lsa_GetQuotasForAccount *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -3244,5 +3244,5 @@
 				  struct lsa_SetQuotasForAccount *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -3251,5 +3251,5 @@
 					  struct lsa_SetInformationTrustedDomain *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -3257,5 +3257,5 @@
 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;
 }
@@ -3264,5 +3264,5 @@
 				   struct lsa_SetTrustedDomainInfo *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -3271,5 +3271,5 @@
 			       struct lsa_StorePrivateData *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -3278,5 +3278,5 @@
 				  struct lsa_RetrievePrivateData *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -3285,5 +3285,5 @@
 			     struct lsa_SetInfoPolicy2 *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -3292,5 +3292,5 @@
 					 struct lsa_SetTrustedDomainInfoByName *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -3311,5 +3311,5 @@
 
 	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;
 	}
@@ -3380,5 +3380,5 @@
 					   struct lsa_QueryDomainInformationPolicy *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -3387,5 +3387,5 @@
 					 struct lsa_SetDomainInformationPolicy *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -3393,5 +3393,5 @@
 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;
 }
@@ -3399,5 +3399,5 @@
 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;
 }
@@ -3405,5 +3405,5 @@
 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;
 }
@@ -3411,5 +3411,5 @@
 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;
 }
@@ -3418,5 +3418,5 @@
 					  struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -3425,5 +3425,5 @@
 					 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -3431,5 +3431,5 @@
 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;
 }
@@ -3438,5 +3438,5 @@
 				 struct lsa_CREDRGETTARGETINFO *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -3445,5 +3445,5 @@
 				 struct lsa_CREDRPROFILELOADED *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -3452,5 +3452,5 @@
 				   struct lsa_CREDRGETSESSIONTYPES *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -3459,5 +3459,5 @@
 				     struct lsa_LSARREGISTERAUDITEVENT *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -3466,5 +3466,5 @@
 				struct lsa_LSARGENAUDITEVENT *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -3473,5 +3473,5 @@
 				       struct lsa_LSARUNREGISTERAUDITEVENT *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -3480,5 +3480,5 @@
 					      struct lsa_lsaRQueryForestTrustInformation *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -3993,5 +3993,5 @@
 			  struct lsa_CREDRRENAME *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -4000,5 +4000,5 @@
 				struct lsa_LSAROPENPOLICYSCE *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -4007,5 +4007,5 @@
 						 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -4014,5 +4014,5 @@
 						   struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -4021,5 +4021,5 @@
 					 struct lsa_LSARADTREPORTSECURITYEVENT *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
Index: trunk/server/source3/rpc_server/netlogon/srv_netlog_nt.c
===================================================================
--- trunk/server/source3/rpc_server/netlogon/srv_netlog_nt.c	(revision 918)
+++ trunk/server/source3/rpc_server/netlogon/srv_netlog_nt.c	(revision 920)
@@ -1509,4 +1509,5 @@
 	{
 		const char *wksname = nt_workstation;
+		const char *workgroup = lp_workgroup();
 
 		status = make_auth_context_fixed(talloc_tos(), &auth_context,
@@ -1533,4 +1534,12 @@
 			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;
 	}
@@ -1637,4 +1646,12 @@
 		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);
@@ -1788,5 +1805,5 @@
 			   struct netr_LogonUasLogon *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -1798,5 +1815,5 @@
 			    struct netr_LogonUasLogoff *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -1808,5 +1825,5 @@
 			      struct netr_DatabaseDeltas *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -1818,5 +1835,5 @@
 			    struct netr_DatabaseSync *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -1828,5 +1845,5 @@
 			     struct netr_AccountDeltas *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -1838,5 +1855,5 @@
 			   struct netr_AccountSync *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -1979,5 +1996,5 @@
 			     struct netr_DatabaseSync2 *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -1989,5 +2006,5 @@
 			    struct netr_DatabaseRedo *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -1999,5 +2016,5 @@
 			  struct netr_DsRGetDCName *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2018,5 +2035,5 @@
 				     struct netr_NETRLOGONSETSERVICEBITS *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2028,5 +2045,5 @@
 			      struct netr_LogonGetTrustRid *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2038,5 +2055,5 @@
 					  struct netr_NETRLOGONCOMPUTESERVERDIGEST *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2048,5 +2065,5 @@
 					  struct netr_NETRLOGONCOMPUTECLIENTDIGEST *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2058,5 +2075,5 @@
 			    struct netr_DsRGetDCNameEx *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2068,5 +2085,5 @@
 			    struct netr_DsRGetSiteName *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2078,5 +2095,5 @@
 				  struct netr_LogonGetDomainInfo *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -2088,5 +2105,5 @@
 			       struct netr_ServerPasswordGet *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2098,5 +2115,5 @@
 				struct netr_NETRLOGONSENDTOSAM *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2108,5 +2125,5 @@
 				    struct netr_DsRAddressToSitenamesW *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2118,5 +2135,5 @@
 			     struct netr_DsRGetDCNameEx2 *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2128,5 +2145,5 @@
 						 struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2138,5 +2155,5 @@
 					   struct netr_NetrEnumerateTrustedDomainsEx *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2148,5 +2165,5 @@
 				      struct netr_DsRAddressToSitenamesExW *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2158,5 +2175,5 @@
 				   struct netr_DsrGetDcSiteCoverageW *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2168,5 +2185,5 @@
 				      struct netr_DsrEnumerateDomainTrusts *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2178,5 +2195,5 @@
 					 struct netr_DsrDeregisterDNSHostRecords *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2188,5 +2205,5 @@
 				       struct netr_ServerTrustPasswordsGet *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -2198,5 +2215,5 @@
 					  struct netr_DsRGetForestTrustInformation *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2272,9 +2289,11 @@
 	/* 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;
@@ -2372,9 +2391,11 @@
 	/* 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;
@@ -2477,5 +2498,5 @@
 			struct netr_Unused47 *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -2487,5 +2508,5 @@
 						 struct netr_DsrUpdateReadOnlyServerDnsRecords *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
Index: trunk/server/source3/rpc_server/ntsvcs/srv_ntsvcs_nt.c
===================================================================
--- trunk/server/source3/rpc_server/ntsvcs/srv_ntsvcs_nt.c	(revision 918)
+++ trunk/server/source3/rpc_server/ntsvcs/srv_ntsvcs_nt.c	(revision 920)
@@ -228,5 +228,5 @@
 		       struct PNP_Disconnect *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -238,5 +238,5 @@
 		    struct PNP_Connect *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -248,5 +248,5 @@
 			   struct PNP_GetGlobalState *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -258,5 +258,5 @@
 			  struct PNP_InitDetection *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -268,5 +268,5 @@
 			struct PNP_ReportLogOn *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -278,5 +278,5 @@
 				  struct PNP_GetRootDeviceInstance *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -288,5 +288,5 @@
 				     struct PNP_GetRelatedDeviceInstance *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -298,5 +298,5 @@
 			     struct PNP_EnumerateSubKeys *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -308,5 +308,5 @@
 		     struct PNP_GetDepth *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -318,5 +318,5 @@
 			     struct PNP_SetDeviceRegProp *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -328,5 +328,5 @@
 			     struct PNP_GetClassInstance *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -338,5 +338,5 @@
 		      struct PNP_CreateKey *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -348,5 +348,5 @@
 			      struct PNP_DeleteRegistryKey *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -358,5 +358,5 @@
 			  struct PNP_GetClassCount *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -368,5 +368,5 @@
 			 struct PNP_GetClassName *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -378,5 +378,5 @@
 			   struct PNP_DeleteClassKey *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -388,5 +388,5 @@
 				    struct PNP_GetInterfaceDeviceAlias *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -398,5 +398,5 @@
 				   struct PNP_GetInterfaceDeviceList *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -408,5 +408,5 @@
 				       struct PNP_GetInterfaceDeviceListSize *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -418,5 +418,5 @@
 					   struct PNP_RegisterDeviceClassAssociation *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -428,5 +428,5 @@
 					     struct PNP_UnregisterDeviceClassAssociation *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -438,5 +438,5 @@
 			    struct PNP_GetClassRegProp *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -448,5 +448,5 @@
 			    struct PNP_SetClassRegProp *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -458,5 +458,5 @@
 			  struct PNP_CreateDevInst *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -468,5 +468,5 @@
 				 struct PNP_DeviceInstanceAction *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -478,5 +478,5 @@
 			    struct PNP_GetDeviceStatus *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -488,5 +488,5 @@
 			     struct PNP_SetDeviceProblem *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -498,5 +498,5 @@
 			   struct PNP_DisableDevInst *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -508,5 +508,5 @@
 			     struct PNP_UninstallDevInst *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -518,5 +518,5 @@
 		  struct PNP_AddID *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -528,5 +528,5 @@
 			   struct PNP_RegisterDriver *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -538,5 +538,5 @@
 			struct PNP_QueryRemove *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -548,5 +548,5 @@
 			       struct PNP_RequestDeviceEject *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -558,5 +558,5 @@
 				 struct PNP_IsDockStationPresent *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -568,5 +568,5 @@
 			   struct PNP_RequestEjectPC *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -578,5 +578,5 @@
 			    struct PNP_AddEmptyLogConf *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -588,5 +588,5 @@
 			struct PNP_FreeLogConf *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -598,5 +598,5 @@
 			    struct PNP_GetFirstLogConf *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -608,5 +608,5 @@
 			   struct PNP_GetNextLogConf *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -618,5 +618,5 @@
 			       struct PNP_GetLogConfPriority *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -628,5 +628,5 @@
 		      struct PNP_AddResDes *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -638,5 +638,5 @@
 		       struct PNP_FreeResDes *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -648,5 +648,5 @@
 			  struct PNP_GetNextResDes *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -658,5 +658,5 @@
 			  struct PNP_GetResDesData *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -668,5 +668,5 @@
 			      struct PNP_GetResDesDataSize *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -678,5 +678,5 @@
 			 struct PNP_ModifyResDes *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -688,5 +688,5 @@
 				struct PNP_DetectResourceLimit *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -698,5 +698,5 @@
 			     struct PNP_QueryResConfList *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -708,5 +708,5 @@
 		      struct PNP_SetHwProf *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -718,5 +718,5 @@
 				    struct PNP_QueryArbitratorFreeData *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -728,5 +728,5 @@
 				    struct PNP_QueryArbitratorFreeSize *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -738,5 +738,5 @@
 			 struct PNP_RunDetection *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -748,5 +748,5 @@
 				 struct PNP_RegisterNotification *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -758,5 +758,5 @@
 				   struct PNP_UnregisterNotification *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -768,5 +768,5 @@
 			     struct PNP_GetCustomDevProp *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -778,5 +778,5 @@
 			       struct PNP_GetVersionInternal *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -788,5 +788,5 @@
 				 struct PNP_GetBlockedDriverInfo *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -798,5 +798,5 @@
 					    struct PNP_GetServerSideDeviceInstallFlags *r)
 {
-	p->rng_fault_state = true;
-	return WERR_NOT_SUPPORTED;
-}
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+	return WERR_NOT_SUPPORTED;
+}
Index: trunk/server/source3/rpc_server/rpc_handles.c
===================================================================
--- trunk/server/source3/rpc_server/rpc_handles.c	(revision 918)
+++ trunk/server/source3/rpc_server/rpc_handles.c	(revision 920)
@@ -243,5 +243,5 @@
 	dump_data(4, (uint8_t *)hnd, sizeof(*hnd));
 
-	p->bad_handle_fault_state = true;
+	p->fault_state = DCERPC_FAULT_CONTEXT_MISMATCH;
 
 	return NULL;
Index: trunk/server/source3/rpc_server/rpc_ncacn_np.c
===================================================================
--- trunk/server/source3/rpc_server/rpc_ncacn_np.c	(revision 918)
+++ trunk/server/source3/rpc_server/rpc_ncacn_np.c	(revision 920)
@@ -172,4 +172,5 @@
 	p->syntax = *syntax;
 	p->transport = NCALRPC;
+	p->allow_bind = true;
 
 	DEBUG(4,("Created internal pipe %s (pipes_open=%d)\n",
@@ -217,22 +218,11 @@
 
 	if (p->fault_state) {
-		p->fault_state = false;
+		NTSTATUS status;
+
+		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_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;
-	}
-
-	if (p->rng_fault_state) {
-		p->rng_fault_state = false;
-		data_blob_free(&p->out_data.rdata);
-		talloc_free_children(p->mem_ctx);
-		return NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE;
+		return status;
 	}
 
@@ -792,4 +782,5 @@
 	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);
Index: trunk/server/source3/rpc_server/rpc_server.c
===================================================================
--- trunk/server/source3/rpc_server/rpc_server.c	(revision 918)
+++ trunk/server/source3/rpc_server/rpc_server.c	(revision 920)
@@ -103,4 +103,5 @@
 	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);
@@ -661,4 +662,10 @@
 	if (ret == -1) {
 		DEBUG(2, ("Writev failed!\n"));
+		goto fail;
+	}
+
+	if (npc->p->fault_state != 0) {
+		DEBUG(2, ("Disconnect after fault\n"));
+		sys_errno = EINVAL;
 		goto fail;
 	}
@@ -1392,4 +1399,10 @@
 	}
 
+	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;
Index: trunk/server/source3/rpc_server/samr/srv_samr_nt.c
===================================================================
--- trunk/server/source3/rpc_server/samr/srv_samr_nt.c	(revision 918)
+++ trunk/server/source3/rpc_server/samr/srv_samr_nt.c	(revision 920)
@@ -6629,4 +6629,9 @@
 	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;
@@ -6683,5 +6688,5 @@
 			struct samr_Shutdown *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -6693,5 +6698,5 @@
 					  struct samr_SetMemberAttributesOfGroup *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -6703,4 +6708,5 @@
 					  struct samr_TestPrivateFunctionsDomain *r)
 {
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -6712,4 +6718,5 @@
 					struct samr_TestPrivateFunctionsUser *r)
 {
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -6721,5 +6728,5 @@
 					 struct samr_AddMultipleMembersToAlias *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -6731,5 +6738,5 @@
 					      struct samr_RemoveMultipleMembersFromAlias *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -6741,5 +6748,5 @@
 				     struct samr_SetBootKeyInformation *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -6751,5 +6758,5 @@
 				     struct samr_GetBootKeyInformation *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
@@ -6761,5 +6768,5 @@
 			       struct samr_SetDsrmPassword *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
Index: trunk/server/source3/rpc_server/spoolss/srv_spoolss_nt.c
===================================================================
--- trunk/server/source3/rpc_server/spoolss/srv_spoolss_nt.c	(revision 918)
+++ trunk/server/source3/rpc_server/spoolss/srv_spoolss_nt.c	(revision 920)
@@ -2481,5 +2481,5 @@
 		"", /* domain */
 		"", /* password */
-		0, lp_client_signing());
+		0, False);
 
 	if ( !NT_STATUS_IS_OK( ret ) ) {
@@ -10157,5 +10157,5 @@
 				 struct spoolss_GetPrinterDriver *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10168,5 +10168,5 @@
 			    struct spoolss_ReadPrinter *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10179,5 +10179,5 @@
 				     struct spoolss_WaitForPrinterChange *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10190,5 +10190,5 @@
 			      struct spoolss_ConfigurePort *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10201,5 +10201,5 @@
 			   struct spoolss_DeletePort *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10212,5 +10212,5 @@
 				struct spoolss_CreatePrinterIC *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10223,5 +10223,5 @@
 					 struct spoolss_PlayGDIScriptOnPrinterIC *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10234,5 +10234,5 @@
 				struct spoolss_DeletePrinterIC *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10245,5 +10245,5 @@
 				     struct spoolss_AddPrinterConnection *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10256,5 +10256,5 @@
 					struct spoolss_DeletePrinterConnection *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10267,5 +10267,5 @@
 				  struct spoolss_PrinterMessageBox *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10278,5 +10278,5 @@
 			   struct spoolss_AddMonitor *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10289,5 +10289,5 @@
 			      struct spoolss_DeleteMonitor *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10300,5 +10300,5 @@
 				     struct spoolss_DeletePrintProcessor *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10311,5 +10311,5 @@
 				 struct spoolss_AddPrintProvidor *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10322,5 +10322,5 @@
 				    struct spoolss_DeletePrintProvidor *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10333,5 +10333,5 @@
 						   struct spoolss_FindFirstPrinterChangeNotification *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10344,5 +10344,5 @@
 						  struct spoolss_FindNextPrinterChangeNotification *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10355,5 +10355,5 @@
 							    struct spoolss_RouterFindFirstPrinterChangeNotificationOld *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10366,5 +10366,5 @@
 				 struct spoolss_ReplyOpenPrinter *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10377,5 +10377,5 @@
 				   struct spoolss_RouterReplyPrinter *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10388,5 +10388,5 @@
 				  struct spoolss_ReplyClosePrinter *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10399,5 +10399,5 @@
 			  struct spoolss_AddPortEx *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10410,5 +10410,5 @@
 							 struct spoolss_RouterFindFirstPrinterChangeNotification *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10421,5 +10421,5 @@
 			    struct spoolss_SpoolerInit *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10432,5 +10432,5 @@
 			       struct spoolss_ResetPrinterEx *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10443,5 +10443,5 @@
 				     struct spoolss_RouterReplyPrinterEx *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10454,5 +10454,5 @@
 		   struct spoolss_44 *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10465,5 +10465,5 @@
 			struct spoolss_SetPort *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10476,5 +10476,5 @@
 		   struct spoolss_4a *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10487,5 +10487,5 @@
 		   struct spoolss_4b *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10498,5 +10498,5 @@
 		   struct spoolss_4c *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10509,5 +10509,5 @@
 		   struct spoolss_53 *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10520,5 +10520,5 @@
 					struct spoolss_AddPerMachineConnection *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10531,5 +10531,5 @@
 					   struct spoolss_DeletePerMachineConnection *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10542,5 +10542,5 @@
 					  struct spoolss_EnumPerMachineConnections *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10553,5 +10553,5 @@
 		   struct spoolss_5a *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10564,5 +10564,5 @@
 		   struct spoolss_5b *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10575,5 +10575,5 @@
 		   struct spoolss_5c *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10586,5 +10586,5 @@
 		   struct spoolss_5d *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10597,5 +10597,5 @@
 		   struct spoolss_5e *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10608,5 +10608,5 @@
 		   struct spoolss_5f *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10619,5 +10619,5 @@
 		   struct spoolss_60 *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10630,5 +10630,5 @@
 		   struct spoolss_61 *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10641,5 +10641,5 @@
 		   struct spoolss_62 *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10652,5 +10652,5 @@
 		   struct spoolss_63 *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10663,5 +10663,5 @@
 		   struct spoolss_64 *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10674,5 +10674,5 @@
 		   struct spoolss_65 *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10685,5 +10685,5 @@
 				      struct spoolss_GetCorePrinterDrivers *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10696,5 +10696,5 @@
 		   struct spoolss_67 *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10707,5 +10707,5 @@
 					    struct spoolss_GetPrinterDriverPackagePath *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10718,5 +10718,5 @@
 		   struct spoolss_69 *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10729,5 +10729,5 @@
 		   struct spoolss_6a *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10740,5 +10740,5 @@
 		   struct spoolss_6b *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10751,5 +10751,5 @@
 		   struct spoolss_6c *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -10762,5 +10762,5 @@
 		   struct spoolss_6d *r)
 {
-	p->rng_fault_state = true;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
Index: trunk/server/source3/rpc_server/srv_pipe.c
===================================================================
--- trunk/server/source3/rpc_server/srv_pipe.c	(revision 918)
+++ trunk/server/source3/rpc_server/srv_pipe.c	(revision 920)
@@ -43,4 +43,11 @@
 #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"
+#include "../librpc/gen_ndr/ndr_netlogon.h"
+#include "../librpc/gen_ndr/ndr_epmapper.h"
+#include "../librpc/gen_ndr/ndr_echo.h"
 
 #undef DBGC_CLASS
@@ -203,5 +210,5 @@
 	 */
 	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;
 	}
@@ -270,8 +277,12 @@
 	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;
 	p->pipe_bound = False;
+	p->allow_bind = false;
+	p->allow_alter = false;
+	p->allow_auth3 = false;
 
 	return True;
@@ -335,17 +346,49 @@
 {
 	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(), &p->syntax)));
+		 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;
+	}
+
+	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) &&
-	   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);
@@ -355,8 +398,54 @@
 	}
 
+	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();
+	/*
+	 * 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;
+	}
+	/*
+	 * for the epmapper and echo interfaces we allow "connect"
+	 * auth_level by default.
+	 */
+	ok = ndr_syntax_id_equal(abstract, &ndr_table_epmapper.syntax_id);
+	if (ok) {
+		context_fns->allow_connect = true;
+	}
+	ok = ndr_syntax_id_equal(abstract, &ndr_table_rpcecho.syntax_id);
+	if (ok) {
+		context_fns->allow_connect = true;
+	}
+	/*
+	 * every interface can be modified to allow "connect" auth_level by
+	 * using a parametric option like:
+	 * allow dcerpc auth level connect:<interface>
+	 * 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 */
@@ -446,4 +535,5 @@
 	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"));
@@ -556,4 +646,5 @@
 	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;
@@ -600,4 +691,5 @@
 	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"));
@@ -774,4 +866,9 @@
 	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) {
@@ -866,14 +963,36 @@
 	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;
+
+	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(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;
 	}
@@ -959,23 +1078,10 @@
 	 */
 	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"));
@@ -1071,4 +1177,5 @@
 		/* The session key was initialized from the SMB
 		 * session in make_internal_rpc_pipe_p */
+		p->auth.auth_context_id = 0;
 	}
 
@@ -1112,13 +1219,13 @@
 		DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
 			  nt_errstr(status)));
+		goto err_exit;
 	}
 
 	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);
@@ -1151,4 +1258,20 @@
 
 	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;
 
@@ -1175,26 +1298,47 @@
 	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;
+	}
+
+	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, "
+			  "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;
 	}
 
-	/* 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"));
@@ -1211,4 +1355,19 @@
 			  "but auth was started as type %d!\n",
 			  auth_info.auth_type, p->auth.auth_type));
+		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;
+	}
+
+	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;
 	}
@@ -1266,4 +1425,8 @@
 
 err:
+	p->pipe_bound = false;
+	p->allow_bind = false;
+	p->allow_alter = false;
+	p->allow_auth3 = false;
 
 	TALLOC_FREE(p->auth.auth_ctx);
@@ -1283,5 +1446,5 @@
 	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;
@@ -1293,6 +1456,40 @@
 	DEBUG(5,("api_pipe_alter_context: make response. %d\n", __LINE__));
 
-	if (pkt->u.bind.assoc_group_id != 0) {
-		assoc_gid = pkt->u.bind.assoc_group_id;
+	if (!p->allow_alter) {
+		DEBUG(1, ("Pipe not in allow alter state.\n"));
+		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;
+	}
+
+	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 {
 		assoc_gid = 0x53f0;
@@ -1304,5 +1501,5 @@
 
 	/* 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)
@@ -1310,17 +1507,16 @@
 
 	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)) {
-
-		bind_ack_ctx.result = 0;
-		bind_ack_ctx.reason = 0;
-		bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
+			&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)) {
+
+		alter_ack_ctx.result = 0;
+		alter_ack_ctx.reason = 0;
+		alter_ack_ctx.syntax = pkt->u.alter.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;
-		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;
 	}
 
@@ -1329,25 +1525,4 @@
 	 */
 	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 ));
-			goto err_exit;
-		}
-
-		status = dcerpc_pull_dcerpc_auth(pkt,
-						 &pkt->u.bind.auth_info,
-						 &auth_info, p->endian);
-		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) {
@@ -1357,4 +1532,12 @@
 		}
 
+		status = dcerpc_pull_auth_trailer(pkt, pkt,
+						  &pkt->u.alter.auth_info,
+						  &auth_info, NULL, true);
+		if (!NT_STATUS_IS_OK(status)) {
+			DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
+			goto err_exit;
+		}
+
 		if (auth_info.auth_type != p->auth.auth_type) {
 			DEBUG(0, ("Auth type mismatch! Client sent %d, "
@@ -1364,4 +1547,18 @@
 		}
 
+		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;
+		}
+
+		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) {
@@ -1430,5 +1627,5 @@
 
 	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
@@ -1450,6 +1647,7 @@
 					  &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;
 	}
 
@@ -1468,5 +1666,5 @@
 						 auth_info.auth_level,
 						 pad_len,
-						 1, /* auth_context_id */
+						 p->auth.auth_context_id,
 						 &auth_resp,
 						 &auth_blob);
@@ -1542,5 +1740,40 @@
 
 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
-		       const struct api_struct *api_rpc_cmds, int n_cmds);
+		       const struct 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;
+}
 
 /****************************************************************************
@@ -1553,21 +1786,15 @@
 				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;
-	}
-
-	DEBUG(5, ("Requested \\PIPE\\%s\n",
-		  get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
+	const char *interface_name = NULL;
+
+	if (!p->pipe_bound) {
+		DEBUG(1, ("Pipe not bound!\n"));
+		data_blob_free(&p->out_data.rdata);
+		TALLOC_FREE(frame);
+		return false;
+	}
 
 	/* get the set of RPC functions for this context */
@@ -1575,22 +1802,65 @@
 	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);
-	}
-	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)));
-	}
-
-	if (changed_user) {
-		unbecome_authenticated_pipe_user();
-	}
-
+		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",
+		  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"));
+		set_incoming_fault(p);
+		setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_ACCESS_DENIED));
+		data_blob_free(&p->out_data.rdata);
+		TALLOC_FREE(frame);
+		return true;
+	}
+
+	if (!become_authenticated_pipe_user(p->session_info)) {
+		DEBUG(1, ("Failed to become pipe user!\n"));
+		data_blob_free(&p->out_data.rdata);
+		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;
 }
@@ -1601,5 +1871,6 @@
 
 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;
@@ -1608,5 +1879,5 @@
 	/* 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));
 
@@ -1614,5 +1885,5 @@
 		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,
@@ -1647,5 +1918,5 @@
 	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);
@@ -1653,16 +1924,9 @@
 	}
 
-	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;
 	}
 
@@ -1670,5 +1934,5 @@
 		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,
@@ -1677,5 +1941,5 @@
 
 	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 */
@@ -1719,7 +1983,11 @@
 	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_NCA_S_PROTO_ERROR;
+
+	p->allow_alter = false;
+	p->allow_auth3 = false;
+	p->pipe_bound = false;
+
+	DEBUG(10, ("Setting fault state\n"));
 }
 
@@ -1730,5 +1998,4 @@
 	NTSTATUS status;
 	size_t hdr_size = DCERPC_REQUEST_LENGTH;
-	size_t pad_len;
 
 	DEBUG(10, ("Checking request auth.\n"));
@@ -1741,21 +2008,7 @@
 	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;
 	}
 
@@ -1777,4 +2030,27 @@
 		set_incoming_fault(p);
 		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;
 	}
 
@@ -2028,5 +2304,5 @@
 								&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 {
Index: trunk/server/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
===================================================================
--- trunk/server/source3/rpc_server/srvsvc/srv_srvsvc_nt.c	(revision 918)
+++ trunk/server/source3/rpc_server/srvsvc/srv_srvsvc_nt.c	(revision 920)
@@ -2549,5 +2549,5 @@
 			      struct srvsvc_NetCharDevEnum *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2556,5 +2556,5 @@
 				 struct srvsvc_NetCharDevGetInfo *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2563,5 +2563,5 @@
 				 struct srvsvc_NetCharDevControl *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2570,5 +2570,5 @@
 			       struct srvsvc_NetCharDevQEnum *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2577,5 +2577,5 @@
 				  struct srvsvc_NetCharDevQGetInfo *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2584,5 +2584,5 @@
 				  struct srvsvc_NetCharDevQSetInfo *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2591,5 +2591,5 @@
 				struct srvsvc_NetCharDevQPurge *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2598,5 +2598,5 @@
 				    struct srvsvc_NetCharDevQPurgeSelf *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2605,5 +2605,5 @@
 			      struct srvsvc_NetFileGetInfo *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2612,5 +2612,5 @@
 			     struct srvsvc_NetShareCheck *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2619,5 +2619,5 @@
 				      struct srvsvc_NetServerStatisticsGet *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2626,5 +2626,5 @@
 			       struct srvsvc_NetTransportAdd *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2633,5 +2633,5 @@
 				struct srvsvc_NetTransportEnum *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2640,5 +2640,5 @@
 			       struct srvsvc_NetTransportDel *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2647,5 +2647,5 @@
 				 struct srvsvc_NetSetServiceBits *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2654,5 +2654,5 @@
 			   struct srvsvc_NetPathType *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2661,5 +2661,5 @@
 				   struct srvsvc_NetPathCanonicalize *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2668,5 +2668,5 @@
 			      struct srvsvc_NetPathCompare *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2675,5 +2675,5 @@
 				      struct srvsvc_NETRPRNAMECANONICALIZE *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2682,5 +2682,5 @@
 				struct srvsvc_NetPRNameCompare *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2689,5 +2689,5 @@
 				struct srvsvc_NetShareDelStart *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2696,5 +2696,5 @@
 				 struct srvsvc_NetShareDelCommit *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2703,5 +2703,5 @@
 				       struct srvsvc_NetServerTransportAddEx *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2710,5 +2710,5 @@
 					 struct srvsvc_NetServerSetServiceBitsEx *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2717,5 +2717,5 @@
 				 struct srvsvc_NETRDFSGETVERSION *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2724,5 +2724,5 @@
 					   struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2731,5 +2731,5 @@
 					   struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2738,5 +2738,5 @@
 					  struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2745,5 +2745,5 @@
 				    struct srvsvc_NETRDFSSETSERVERINFO *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2752,5 +2752,5 @@
 				      struct srvsvc_NETRDFSCREATEEXITPOINT *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2759,5 +2759,5 @@
 				      struct srvsvc_NETRDFSDELETEEXITPOINT *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2766,5 +2766,5 @@
 				   struct srvsvc_NETRDFSMODIFYPREFIX *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2773,5 +2773,5 @@
 				     struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2780,5 +2780,5 @@
 					    struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -2787,5 +2787,5 @@
 					struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
 {
-	p->rng_fault_state = True;
-	return WERR_NOT_SUPPORTED;
-}
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+	return WERR_NOT_SUPPORTED;
+}
Index: trunk/server/source3/rpc_server/svcctl/srv_svcctl_nt.c
===================================================================
--- trunk/server/source3/rpc_server/svcctl/srv_svcctl_nt.c	(revision 918)
+++ trunk/server/source3/rpc_server/svcctl/srv_svcctl_nt.c	(revision 920)
@@ -1005,5 +1005,5 @@
 			     struct svcctl_DeleteService *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -1012,5 +1012,5 @@
 				struct svcctl_SetServiceStatus *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -1019,5 +1019,5 @@
 				      struct svcctl_NotifyBootConfigStatus *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -1026,5 +1026,5 @@
 				 struct svcctl_SCSetServiceBitsW *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -1033,5 +1033,5 @@
 				    struct svcctl_ChangeServiceConfigW *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -1040,5 +1040,5 @@
 			      struct svcctl_CreateServiceW *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -1047,5 +1047,5 @@
 				       struct svcctl_QueryServiceLockStatusW *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -1054,5 +1054,5 @@
 				  struct svcctl_GetServiceKeyNameW *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -1061,5 +1061,5 @@
 				 struct svcctl_SCSetServiceBitsA *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -1068,5 +1068,5 @@
 				    struct svcctl_ChangeServiceConfigA *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -1075,5 +1075,5 @@
 			      struct svcctl_CreateServiceA *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -1082,5 +1082,5 @@
 				      struct svcctl_EnumDependentServicesA *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -1089,5 +1089,5 @@
 				   struct svcctl_EnumServicesStatusA *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -1096,5 +1096,5 @@
 			      struct svcctl_OpenSCManagerA *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -1103,5 +1103,5 @@
 			    struct svcctl_OpenServiceA *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -1110,5 +1110,5 @@
 				   struct svcctl_QueryServiceConfigA *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -1117,5 +1117,5 @@
 				       struct svcctl_QueryServiceLockStatusA *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -1124,5 +1124,5 @@
 			     struct svcctl_StartServiceA *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -1131,5 +1131,5 @@
 				      struct svcctl_GetServiceDisplayNameA *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -1138,5 +1138,5 @@
 				  struct svcctl_GetServiceKeyNameA *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -1145,5 +1145,5 @@
 				      struct svcctl_GetCurrentGroupeStateW *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -1152,5 +1152,5 @@
 				 struct svcctl_EnumServiceGroupW *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -1159,5 +1159,5 @@
 				     struct svcctl_ChangeServiceConfig2A *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -1166,5 +1166,5 @@
 				     struct svcctl_ChangeServiceConfig2W *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -1173,5 +1173,5 @@
 				    struct svcctl_QueryServiceConfig2A *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -1180,5 +1180,5 @@
 			      struct EnumServicesStatusExA *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -1187,5 +1187,5 @@
 			      struct EnumServicesStatusExW *r)
 {
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -1194,5 +1194,5 @@
 			       struct svcctl_SCSendTSMessage *r)
 {
-	p->rng_fault_state = True;
-	return WERR_NOT_SUPPORTED;
-}
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+	return WERR_NOT_SUPPORTED;
+}
Index: trunk/server/source3/rpc_server/winreg/srv_winreg_nt.c
===================================================================
--- trunk/server/source3/rpc_server/winreg/srv_winreg_nt.c	(revision 918)
+++ trunk/server/source3/rpc_server/winreg/srv_winreg_nt.c	(revision 920)
@@ -761,5 +761,5 @@
 	   do anything */
 
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -949,5 +949,5 @@
 	   do anything */
 
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -963,5 +963,5 @@
 	   do anything */
 
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -977,5 +977,5 @@
 	   do anything */
 
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -1140,5 +1140,5 @@
 	   do anything */
 
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
Index: trunk/server/source3/rpc_server/wkssvc/srv_wkssvc_nt.c
===================================================================
--- trunk/server/source3/rpc_server/wkssvc/srv_wkssvc_nt.c	(revision 918)
+++ trunk/server/source3/rpc_server/wkssvc/srv_wkssvc_nt.c	(revision 920)
@@ -406,5 +406,5 @@
 {
 	/* FIXME: Add implementation code here */
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -609,5 +609,5 @@
 {
 	/* FIXME: Add implementation code here */
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -620,5 +620,5 @@
 {
 	/* FIXME: Add implementation code here */
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -631,5 +631,5 @@
 {
 	/* FIXME: Add implementation code here */
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -642,5 +642,5 @@
 {
 	/* FIXME: Add implementation code here */
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -653,5 +653,5 @@
 {
 	/* FIXME: Add implementation code here */
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -664,5 +664,5 @@
 {
 	/* FIXME: Add implementation code here */
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -675,5 +675,5 @@
 {
 	/* FIXME: Add implementation code here */
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -686,5 +686,5 @@
 {
 	/* FIXME: Add implementation code here */
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -697,5 +697,5 @@
 {
 	/* FIXME: Add implementation code here */
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -708,5 +708,5 @@
 {
 	/* FIXME: Add implementation code here */
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -719,5 +719,5 @@
 {
 	/* FIXME: Add implementation code here */
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -730,5 +730,5 @@
 {
 	/* FIXME: Add implementation code here */
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -741,5 +741,5 @@
 {
 	/* FIXME: Add implementation code here */
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -752,5 +752,5 @@
 {
 	/* FIXME: Add implementation code here */
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -763,5 +763,5 @@
 {
 	/* FIXME: Add implementation code here */
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -774,5 +774,5 @@
 {
 	/* FIXME: Add implementation code here */
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -785,5 +785,5 @@
 {
 	/* FIXME: Add implementation code here */
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -796,5 +796,5 @@
 {
 	/* FIXME: Add implementation code here */
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -807,5 +807,5 @@
 {
 	/* FIXME: Add implementation code here */
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -963,4 +963,5 @@
 {
 	/* for now just return not supported */
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -973,5 +974,5 @@
 {
 	/* FIXME: Add implementation code here */
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -984,5 +985,5 @@
 {
 	/* FIXME: Add implementation code here */
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -995,5 +996,5 @@
 {
 	/* FIXME: Add implementation code here */
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -1006,5 +1007,5 @@
 {
 	/* FIXME: Add implementation code here */
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -1017,5 +1018,5 @@
 {
 	/* FIXME: Add implementation code here */
-	p->rng_fault_state = True;
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
 	return WERR_NOT_SUPPORTED;
 }
@@ -1028,5 +1029,5 @@
 {
 	/* FIXME: Add implementation code here */
-	p->rng_fault_state = True;
-	return WERR_NOT_SUPPORTED;
-}
+	p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+	return WERR_NOT_SUPPORTED;
+}
Index: trunk/server/source3/rpcclient/rpcclient.c
===================================================================
--- trunk/server/source3/rpcclient/rpcclient.c	(revision 918)
+++ trunk/server/source3/rpcclient/rpcclient.c	(revision 920)
@@ -1032,4 +1032,8 @@
 	}
 
+	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;
@@ -1045,10 +1049,4 @@
 	}
 	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;
@@ -1058,14 +1056,14 @@
 	}
 	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 nothing is requested then default to integrity */
+		if (pipe_default_auth_level == DCERPC_AUTH_LEVEL_NONE) {
+			pipe_default_auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
 		}
 	}
Index: trunk/server/source3/script/tests/test_rpcclient.sh
===================================================================
--- trunk/server/source3/script/tests/test_rpcclient.sh	(revision 920)
+++ trunk/server/source3/script/tests/test_rpcclient.sh	(revision 920)
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+if [ $# -lt 1 ]; then
+cat <<EOF
+Usage: test_rpcclient.sh ccache binding <rpcclient commands>
+EOF
+exit 1;
+fi
+
+KRB5CCNAME=$1
+shift 1
+export KRB5CCNAME
+ADDARGS="$*"
+
+incdir=`dirname $0`/../../../testprogs/blackbox
+. $incdir/subunit.sh
+testit "rpcclient" $VALGRIND $BINDIR/rpcclient -c 'getusername' $ADDARGS || failed=`expr $failed + 1`
+
+testok $0 $failed
Index: trunk/server/source3/selftest/knownfail
===================================================================
--- trunk/server/source3/selftest/knownfail	(revision 918)
+++ trunk/server/source3/selftest/knownfail	(revision 920)
@@ -19,2 +19,4 @@
 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
Index: trunk/server/source3/selftest/skip
===================================================================
--- trunk/server/source3/selftest/skip	(revision 918)
+++ trunk/server/source3/selftest/skip	(revision 920)
@@ -23,2 +23,7 @@
 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: trunk/server/source3/selftest/tests.py
===================================================================
--- trunk/server/source3/selftest/tests.py	(revision 918)
+++ trunk/server/source3/selftest/tests.py	(revision 920)
@@ -202,4 +202,6 @@
         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')
@@ -209,5 +211,5 @@
 
     test = 'rpc.lsa.lookupsids'
-    auth_options = ["", "ntlm", "spnego" ]
+    auth_options = ["", "ntlm", "spnego", "spnego,ntlm" ]
     signseal_options = ["", ",connect", ",sign", ",seal"]
     smb_options = ["", ",smb2"]
@@ -220,4 +222,7 @@
                     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:
Index: trunk/server/source3/smbd/conn.c
===================================================================
--- trunk/server/source3/smbd/conn.c	(revision 918)
+++ trunk/server/source3/smbd/conn.c	(revision 920)
@@ -24,4 +24,5 @@
 #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
Index: trunk/server/source3/smbd/dir.c
===================================================================
--- trunk/server/source3/smbd/dir.c	(revision 918)
+++ trunk/server/source3/smbd/dir.c	(revision 920)
@@ -24,4 +24,5 @@
 #include "smbd/globals.h"
 #include "libcli/security/security.h"
+#include "lib/util/bitmap.h"
 
 /*
Index: trunk/server/source3/smbd/files.c
===================================================================
--- trunk/server/source3/smbd/files.c	(revision 918)
+++ trunk/server/source3/smbd/files.c	(revision 920)
@@ -23,4 +23,5 @@
 #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: trunk/server/source3/smbd/smb2_server.c
===================================================================
--- trunk/server/source3/smbd/smb2_server.c	(revision 918)
+++ trunk/server/source3/smbd/smb2_server.c	(revision 920)
@@ -27,4 +27,5 @@
 #include "../lib/util/tevent_ntstatus.h"
 #include "smbprofile.h"
+#include "../lib/util/bitmap.h"
 
 #define OUTVEC_ALLOC_SIZE (SMB2_HDR_BODY + 9)
Index: trunk/server/source3/smbd/vfs.c
===================================================================
--- trunk/server/source3/smbd/vfs.c	(revision 918)
+++ trunk/server/source3/smbd/vfs.c	(revision 920)
@@ -991,4 +991,5 @@
 		const char *conn_rootdir;
 		size_t rootdir_len;
+		bool matched;
 
 		conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
@@ -1001,6 +1002,8 @@
 
 		rootdir_len = strlen(conn_rootdir);
-		if (strncmp(conn_rootdir, resolved_name,
-				rootdir_len) != 0) {
+		matched = (strncmp(conn_rootdir, resolved_name,
+				rootdir_len) == 0);
+		if (!matched || (resolved_name[rootdir_len] != '/' &&
+				 resolved_name[rootdir_len] != '\0')) {
 			DEBUG(2, ("check_reduced_name: Bad access "
 				"attempt: %s is a symlink outside the "
Index: trunk/server/source3/winbindd/winbindd_cm.c
===================================================================
--- trunk/server/source3/winbindd/winbindd_cm.c	(revision 918)
+++ trunk/server/source3/winbindd/winbindd_cm.c	(revision 920)
@@ -2385,4 +2385,13 @@
 
  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. */
@@ -2611,4 +2620,14 @@
  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,
@@ -2750,5 +2769,16 @@
  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
Index: trunk/server/source4/heimdal/cf/make-proto.pl
===================================================================
--- trunk/server/source4/heimdal/cf/make-proto.pl	(revision 918)
+++ trunk/server/source4/heimdal/cf/make-proto.pl	(revision 920)
@@ -2,6 +2,6 @@
 # $Id$
 
-##use Getopt::Std;
-require 'getopts.pl';
+use Getopt::Std;
+#require 'getopts.pl';
 
 my $comment = 0;
@@ -13,5 +13,5 @@
 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) {
Index: trunk/server/source4/lib/ldb/wscript
===================================================================
--- trunk/server/source4/lib/ldb/wscript	(revision 918)
+++ trunk/server/source4/lib/ldb/wscript	(revision 920)
@@ -136,7 +136,5 @@
                           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
Index: trunk/server/source4/librpc/rpc/dcerpc.c
===================================================================
--- trunk/server/source4/librpc/rpc/dcerpc.c	(revision 918)
+++ trunk/server/source4/librpc/rpc/dcerpc.c	(revision 920)
@@ -700,4 +700,12 @@
 	default:
 		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;
 	}
 
@@ -1075,5 +1083,5 @@
 
 	/* 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;
@@ -1848,6 +1856,5 @@
 
 	/* 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;
Index: trunk/server/source4/librpc/rpc/dcerpc_util.c
===================================================================
--- trunk/server/source4/librpc/rpc/dcerpc_util.c	(revision 918)
+++ trunk/server/source4/librpc/rpc/dcerpc_util.c	(revision 920)
@@ -594,13 +594,13 @@
 	/* 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;
 	}
 
Index: trunk/server/source4/rpc_server/dcesrv_auth.c
===================================================================
--- trunk/server/source4/rpc_server/dcesrv_auth.c	(revision 918)
+++ trunk/server/source4/rpc_server/dcesrv_auth.c	(revision 920)
@@ -47,5 +47,5 @@
 	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;
@@ -109,5 +109,5 @@
 	NTSTATUS status;
 
-	if (!call->conn->auth_state.gensec_security) {
+	if (call->pkt.auth_length == 0) {
 		return NT_STATUS_OK;
 	}
@@ -156,8 +156,14 @@
 	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;
 	}
@@ -204,5 +210,5 @@
 
 	/* 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;
 	}
@@ -239,6 +245,5 @@
 	/* 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;
 	}
@@ -313,4 +318,9 @@
 
 	default:
+		return false;
+	}
+
+	if (pkt->auth_length == 0) {
+		DEBUG(1,("dcesrv_auth_request: unexpected auth_length of 0\n"));
 		return false;
 	}
Index: trunk/server/source4/torture/basic/base.c
===================================================================
--- trunk/server/source4/torture/basic/base.c	(revision 918)
+++ trunk/server/source4/torture/basic/base.c	(revision 920)
@@ -1477,4 +1477,5 @@
 {
 	bool nt_status_support;
+	bool client_ntlmv2_auth;
 	struct smbcli_state *cli_nt = NULL, *cli_dos = NULL;
 	bool result = false;
@@ -1486,4 +1487,5 @@
 
 	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")) {
@@ -1491,4 +1493,8 @@
 		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)) {
@@ -1497,5 +1503,9 @@
 
 	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;
 	}
@@ -1507,5 +1517,10 @@
 	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;
 	}
Index: trunk/server/source4/torture/ndr/dfsblob.c
===================================================================
--- trunk/server/source4/torture/ndr/dfsblob.c	(revision 918)
+++ trunk/server/source4/torture/ndr/dfsblob.c	(revision 920)
@@ -75,9 +75,9 @@
 	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: trunk/server/source4/torture/ndr/drsblobs.c
===================================================================
--- trunk/server/source4/torture/ndr/drsblobs.c	(revision 918)
+++ trunk/server/source4/torture/ndr/drsblobs.c	(revision 920)
@@ -116,4 +116,32 @@
 };
 
+/* 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)
@@ -155,6 +183,18 @@
 	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: trunk/server/source4/torture/ndr/nbt.c
===================================================================
--- trunk/server/source4/torture/ndr/nbt.c	(revision 918)
+++ trunk/server/source4/torture/ndr/nbt.c	(revision 920)
@@ -63,7 +63,7 @@
 	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: trunk/server/source4/torture/ndr/ndr.c
===================================================================
--- trunk/server/source4/torture/ndr/ndr.c	(revision 918)
+++ trunk/server/source4/torture/ndr/ndr.c	(revision 920)
@@ -30,15 +30,21 @@
 	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;
@@ -47,21 +53,40 @@
 				   "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));
-
-	if (check_fn != NULL)
-		return check_fn(tctx, ds);
-	else
-		return true;
-}
-
-_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))
+					   "%d unread bytes", ndr->data_size - highest_ofs));
+
+	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_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;
@@ -75,10 +100,14 @@
 	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;
@@ -89,4 +118,5 @@
 	return test;
 }
+
 
 static bool wrap_ndr_inout_pull_test(struct torture_context *tctx,
@@ -98,4 +128,5 @@
 	void *ds = talloc_zero_size(tctx, data->struct_size);
 	struct ndr_pull *ndr;
+	uint32_t highest_ofs;
 
 	/* handle NDR_IN context */
@@ -110,6 +141,12 @@
 		"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);
@@ -126,6 +163,12 @@
 		"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: trunk/server/source4/torture/ndr/ndr.h
===================================================================
--- trunk/server/source4/torture/ndr/ndr.h	(revision 918)
+++ trunk/server/source4/torture/ndr/ndr.h	(revision 920)
@@ -25,10 +25,13 @@
 #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));
 
@@ -42,18 +45,30 @@
 
 #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: trunk/server/source4/torture/ndr/ntlmssp.c
===================================================================
--- trunk/server/source4/torture/ndr/ntlmssp.c	(revision 918)
+++ trunk/server/source4/torture/ndr/ntlmssp.c	(revision 920)
@@ -112,8 +112,9 @@
 	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: trunk/server/source4/torture/raw/samba3misc.c
===================================================================
--- trunk/server/source4/torture/raw/samba3misc.c	(revision 918)
+++ trunk/server/source4/torture/raw/samba3misc.c	(revision 920)
@@ -341,4 +341,5 @@
 	TALLOC_CTX *mem_ctx;
 	bool nt_status_support;
+	bool client_ntlmv2_auth;
 
 	if (!(mem_ctx = talloc_init("torture_samba3_badpath"))) {
@@ -348,9 +349,8 @@
 
 	nt_status_support = lpcfg_nt_status_support(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;
-	}
+	client_ntlmv2_auth = lpcfg_client_ntlmv2_auth(torture->lp_ctx);
+
+	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)) {
@@ -358,8 +358,6 @@
 	}
 
-	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)) {
@@ -374,4 +372,10 @@
 
 	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);
Index: trunk/server/source4/torture/rpc/rpc.c
===================================================================
--- trunk/server/source4/torture/rpc/rpc.c	(revision 918)
+++ trunk/server/source4/torture/rpc/rpc.c	(revision 920)
@@ -502,4 +502,5 @@
 	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));
Index: trunk/server/source4/torture/rpc/samba3rpc.c
===================================================================
--- trunk/server/source4/torture/rpc/samba3rpc.c	(revision 918)
+++ trunk/server/source4/torture/rpc/samba3rpc.c	(revision 920)
@@ -1123,6 +1123,6 @@
 		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,
Index: trunk/server/source4/torture/rpc/samr.c
===================================================================
--- trunk/server/source4/torture/rpc/samr.c	(revision 918)
+++ trunk/server/source4/torture/rpc/samr.c	(revision 920)
@@ -7939,6 +7939,6 @@
 
 
-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;
@@ -7952,4 +7952,8 @@
 	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;
@@ -8075,6 +8079,4 @@
 	ret &= test_samr_handle_Close(b, torture, &ctx->handle);
 
-	ret &= test_samr_ValidatePassword(p, torture);
-
 	return ret;
 }
@@ -8371,3 +8373,14 @@
 }
 
-
+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;
+}
