diff --git a/.gitignore b/.gitignore
index 0db09e0..41cd890 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,2 @@
-SOURCES/samba-4.14.5.tar.xz
+SOURCES/samba-4.15.5.tar.xz
 SOURCES/samba-pubkey_AA99442FB680B620.gpg
diff --git a/.samba.metadata b/.samba.metadata
index 707bb47..b1ff8f6 100644
--- a/.samba.metadata
+++ b/.samba.metadata
@@ -1,2 +1,2 @@
-46925b3ed9f63b1b936f2271253fdccccbf1575f SOURCES/samba-4.14.5.tar.xz
+f7e367a546d6523d21be3602b3f2a22a76016844 SOURCES/samba-4.15.5.tar.xz
 971f563c447eda8d144d6c9e743cd0f0488c0d9e SOURCES/samba-pubkey_AA99442FB680B620.gpg
diff --git a/SOURCES/CVE-2016-2124.patch b/SOURCES/CVE-2016-2124.patch
deleted file mode 100644
index a4e015d..0000000
--- a/SOURCES/CVE-2016-2124.patch
+++ /dev/null
@@ -1,108 +0,0 @@
-From 2a961e883b624219a72f212c554d34a18f22d4d1 Mon Sep 17 00:00:00 2001
-From: Stefan Metzmacher <metze@samba.org>
-Date: Thu, 24 Nov 2016 09:12:59 +0100
-Subject: [PATCH 1/2] CVE-2016-2124: s4:libcli/sesssetup: don't fallback to non
- spnego authentication if we require kerberos
-
-We should not send NTLM[v2] data on the wire if the user asked for kerberos
-only.
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=12444
-
-Signed-off-by: Stefan Metzmacher <metze@samba.org>
----
- source4/libcli/smb_composite/sesssetup.c | 14 ++++++++++++++
- 1 file changed, 14 insertions(+)
-
-diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c
-index 51e121bdce6b..391ee081fe62 100644
---- a/source4/libcli/smb_composite/sesssetup.c
-+++ b/source4/libcli/smb_composite/sesssetup.c
-@@ -622,6 +622,8 @@ struct composite_context *smb_composite_sesssetup_send(struct smbcli_session *se
- 	NTSTATUS status;
- 	enum smb_encryption_setting encryption_state =
- 		cli_credentials_get_smb_encryption(io->in.credentials);
-+	enum credentials_use_kerberos krb5_state =
-+		cli_credentials_get_kerberos_state(io->in.credentials);
- 
- 	c = composite_create(session, session->transport->ev);
- 	if (c == NULL) return NULL;
-@@ -642,6 +644,10 @@ struct composite_context *smb_composite_sesssetup_send(struct smbcli_session *se
- 
- 	/* no session setup at all in earliest protocol varients */
- 	if (session->transport->negotiate.protocol < PROTOCOL_LANMAN1) {
-+		if (krb5_state == CRED_USE_KERBEROS_REQUIRED) {
-+			composite_error(c, NT_STATUS_NETWORK_CREDENTIAL_CONFLICT);
-+			return c;
-+		}
- 		ZERO_STRUCT(io->out);
- 		composite_done(c);
- 		return c;
-@@ -649,9 +655,17 @@ struct composite_context *smb_composite_sesssetup_send(struct smbcli_session *se
- 
- 	/* see what session setup interface we will use */
- 	if (session->transport->negotiate.protocol < PROTOCOL_NT1) {
-+		if (krb5_state == CRED_USE_KERBEROS_REQUIRED) {
-+			composite_error(c, NT_STATUS_NETWORK_CREDENTIAL_CONFLICT);
-+			return c;
-+		}
- 		status = session_setup_old(c, session, io, &state->req);
- 	} else if (!session->transport->options.use_spnego ||
- 		   !(io->in.capabilities & CAP_EXTENDED_SECURITY)) {
-+		if (krb5_state == CRED_USE_KERBEROS_REQUIRED) {
-+			composite_error(c, NT_STATUS_NETWORK_CREDENTIAL_CONFLICT);
-+			return c;
-+		}
- 		status = session_setup_nt1(c, session, io, &state->req);
- 	} else {
- 		struct tevent_req *subreq = NULL;
--- 
-2.25.1
-
-
-From 31a67554cf6c3d9368bef58d1249844f8eeb0059 Mon Sep 17 00:00:00 2001
-From: Stefan Metzmacher <metze@samba.org>
-Date: Thu, 27 Oct 2016 10:40:28 +0200
-Subject: [PATCH 2/2] CVE-2016-2124: s3:libsmb: don't fallback to non spnego
- authentication if we require kerberos
-
-We should not send NTLM[v2] nor plaintext data on the wire if the user
-asked for kerberos only.
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=12444
-
-Signed-off-by: Stefan Metzmacher <metze@samba.org>
----
- source3/libsmb/cliconnect.c | 9 +++++++++
- 1 file changed, 9 insertions(+)
-
-diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
-index 853fb344bcd6..c01846ac8119 100644
---- a/source3/libsmb/cliconnect.c
-+++ b/source3/libsmb/cliconnect.c
-@@ -1442,6 +1442,8 @@ struct tevent_req *cli_session_setup_creds_send(TALLOC_CTX *mem_ctx,
- 	uint32_t in_sess_key = 0;
- 	const char *in_native_os = NULL;
- 	const char *in_native_lm = NULL;
-+	enum credentials_use_kerberos krb5_state =
-+		cli_credentials_get_kerberos_state(creds);
- 	NTSTATUS status;
- 
- 	req = tevent_req_create(mem_ctx, &state,
-@@ -1483,6 +1485,13 @@ struct tevent_req *cli_session_setup_creds_send(TALLOC_CTX *mem_ctx,
- 		return req;
- 	}
- 
-+	if (krb5_state == CRED_USE_KERBEROS_REQUIRED) {
-+		DBG_WARNING("Kerberos authentication requested, but "
-+			    "the server does not support SPNEGO authentication\n");
-+		tevent_req_nterror(req, NT_STATUS_NETWORK_CREDENTIAL_CONFLICT);
-+		return tevent_req_post(req, ev);
-+	}
-+
- 	if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_LANMAN1) {
- 		/*
- 		 * SessionSetupAndX was introduced by LANMAN 1.0. So we skip
--- 
-2.25.1
-
diff --git a/SOURCES/CVE-2020-25717.patch b/SOURCES/CVE-2020-25717.patch
deleted file mode 100644
index 7ffaa23..0000000
--- a/SOURCES/CVE-2020-25717.patch
+++ /dev/null
@@ -1,3771 +0,0 @@
-From 5ec536b3549edf118d2f88ca8a9265878a7c9fc5 Mon Sep 17 00:00:00 2001
-From: Stefan Metzmacher <metze@samba.org>
-Date: Fri, 8 Oct 2021 18:04:55 +0200
-Subject: [PATCH 01/39] selftest/Samba3: remove unused close(USERMAP); calls
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14869
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881
-
-Signed-off-by: Stefan Metzmacher <metze@samba.org>
-Reviewed-by: Andrew Bartlett <abartlet@samba.org>
-
-[abartlet@samba.org backported from commit d998f7f8df215866ab32e05be772e24fc0b2131c
- as offline login tests are not in Samba 4.14]
----
- selftest/target/Samba3.pm | 4 ----
- 1 file changed, 4 deletions(-)
-
-diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
-index b0910433940..914b8d40c89 100755
---- a/selftest/target/Samba3.pm
-+++ b/selftest/target/Samba3.pm
-@@ -771,7 +771,6 @@ sub provision_ad_member
- 
- 	mkdir($_, 0777) foreach(@dirs);
- 
--	close(USERMAP);
- 	$ret->{DOMAIN} = $dcvars->{DOMAIN};
- 	$ret->{REALM} = $dcvars->{REALM};
- 	$ret->{DOMSID} = $dcvars->{DOMSID};
-@@ -920,7 +919,6 @@ sub setup_ad_member_rfc2307
- 
- 	$ret or return undef;
- 
--	close(USERMAP);
- 	$ret->{DOMAIN} = $dcvars->{DOMAIN};
- 	$ret->{REALM} = $dcvars->{REALM};
- 	$ret->{DOMSID} = $dcvars->{DOMSID};
-@@ -1018,7 +1016,6 @@ sub setup_ad_member_idmap_rid
- 
- 	$ret or return undef;
- 
--	close(USERMAP);
- 	$ret->{DOMAIN} = $dcvars->{DOMAIN};
- 	$ret->{REALM} = $dcvars->{REALM};
- 	$ret->{DOMSID} = $dcvars->{DOMSID};
-@@ -1118,7 +1115,6 @@ sub setup_ad_member_idmap_ad
- 
- 	$ret or return undef;
- 
--	close(USERMAP);
- 	$ret->{DOMAIN} = $dcvars->{DOMAIN};
- 	$ret->{REALM} = $dcvars->{REALM};
- 	$ret->{DOMSID} = $dcvars->{DOMSID};
--- 
-2.33.1
-
-
-From 6ad8a242a682abd7baa1e4d3672bb24c9e65ab0b Mon Sep 17 00:00:00 2001
-From: Stefan Metzmacher <metze@samba.org>
-Date: Tue, 5 Oct 2021 16:42:00 +0200
-Subject: [PATCH 02/39] selftest/Samba3: replace (winbindd => "yes", skip_wait
- => 1) with (winbindd => "offline")
-
-This is much more flexible and concentrates the logic in a single place.
-
-We'll use winbindd => "offline" in other places soon.
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14870
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881
-
-Signed-off-by: Stefan Metzmacher <metze@samba.org>
-Reviewed-by: Andrew Bartlett <abartlet@samba.org>
-(cherry picked from commit 4dc3c68c9a28f71888e3d6dd3b1f0bcdb8fa45de)
----
- selftest/target/Samba3.pm | 12 ++++++++----
- 1 file changed, 8 insertions(+), 4 deletions(-)
-
-diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
-index 914b8d40c89..9534d06b597 100755
---- a/selftest/target/Samba3.pm
-+++ b/selftest/target/Samba3.pm
-@@ -827,7 +827,7 @@ sub provision_ad_member
- 		nmbd => "yes",
- 		winbindd => "yes",
- 		smbd => "yes")) {
--		return undef;
-+	    return undef;
- 	}
- 
- 	$ret->{DC_SERVER} = $dcvars->{SERVER};
-@@ -1909,7 +1909,7 @@ sub check_or_start($$) {
- 		LOG_FILE => $env_vars->{WINBINDD_TEST_LOG},
- 		PCAP_FILE => "env-$ENV{ENVNAME}-winbindd",
- 	};
--	if ($winbindd ne "yes") {
-+	if ($winbindd ne "yes" and $winbindd ne "offline") {
- 		$daemon_ctx->{SKIP_DAEMON} = 1;
- 	}
- 
-@@ -3130,13 +3130,17 @@ sub wait_for_start($$$$$)
- 		}
- 	}
- 
--	if ($winbindd eq "yes") {
-+	if ($winbindd eq "yes" or $winbindd eq "offline") {
- 	    print "checking for winbindd\n";
- 	    my $count = 0;
- 	    $cmd = "SELFTEST_WINBINDD_SOCKET_DIR='$envvars->{SELFTEST_WINBINDD_SOCKET_DIR}' ";
- 	    $cmd .= "NSS_WRAPPER_PASSWD='$envvars->{NSS_WRAPPER_PASSWD}' ";
- 	    $cmd .= "NSS_WRAPPER_GROUP='$envvars->{NSS_WRAPPER_GROUP}' ";
--	    $cmd .= Samba::bindir_path($self, "wbinfo") . " --ping-dc";
-+	    if ($winbindd eq "yes") {
-+		$cmd .= Samba::bindir_path($self, "wbinfo") . " --ping-dc";
-+	    } elsif ($winbindd eq "offline") {
-+		$cmd .= Samba::bindir_path($self, "wbinfo") . " --ping";
-+	    }
- 
- 	    do {
- 		$ret = system($cmd);
--- 
-2.33.1
-
-
-From c25f4625813b0f7f3baf33ce17c3d6691c9fd602 Mon Sep 17 00:00:00 2001
-From: Andreas Schneider <asn@samba.org>
-Date: Tue, 11 May 2021 17:59:51 +0200
-Subject: [PATCH 03/39] CVE-2020-25717 selftest: Pass down the machine account
- name to provision_ad_member
-
-Signed-off-by: Andreas Schneider <asn@samba.org>
-Reviewed-by: Jeremy Allison <jra@samba.org>
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
-
-(cherry picked from commit fbe68dcbb783409589cdefd8ee551c9971c51f08)
-
-Needed as preparation for CVE-2020-25717
----
- selftest/target/Samba.pm  |  1 +
- selftest/target/Samba3.pm | 10 ++++++++--
- 2 files changed, 9 insertions(+), 2 deletions(-)
-
-diff --git a/selftest/target/Samba.pm b/selftest/target/Samba.pm
-index 5a7efa9c280..d48ac2c64a1 100644
---- a/selftest/target/Samba.pm
-+++ b/selftest/target/Samba.pm
-@@ -588,6 +588,7 @@ sub get_interface($)
- 		addcsmb1	  => 54,
- 		lclnt4dc2smb1	  => 55,
- 		fipsdc            => 56,
-+		fipsadmember      => 57,
- 
- 		rootdnsforwarder  => 64,
- 
-diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
-index 9534d06b597..4686f5d36aa 100755
---- a/selftest/target/Samba3.pm
-+++ b/selftest/target/Samba3.pm
-@@ -646,6 +646,7 @@ sub provision_ad_member
- {
- 	my ($self,
- 	    $prefix,
-+	    $machine_account,
- 	    $dcvars,
- 	    $trustvars_f,
- 	    $trustvars_e,
-@@ -762,7 +763,7 @@ sub provision_ad_member
- 	    prefix => $prefix,
- 	    domain => $dcvars->{DOMAIN},
- 	    realm => $dcvars->{REALM},
--	    server => "LOCALADMEMBER",
-+	    server => $machine_account,
- 	    password => "loCalMemberPass",
- 	    extra_options => $member_options,
- 	    resolv_conf => $dcvars->{RESOLV_CONF});
-@@ -876,7 +877,11 @@ sub setup_ad_member
- 
- 	print "PROVISIONING AD MEMBER...";
- 
--	return $self->provision_ad_member($prefix, $dcvars, $trustvars_f, $trustvars_e);
-+	return $self->provision_ad_member($prefix,
-+					  "LOCALADMEMBER",
-+					  $dcvars,
-+					  $trustvars_f,
-+					  $trustvars_e);
- }
- 
- sub setup_ad_member_rfc2307
-@@ -1199,6 +1204,7 @@ sub setup_ad_member_fips
- 	print "PROVISIONING AD FIPS MEMBER...";
- 
- 	return $self->provision_ad_member($prefix,
-+					  "FIPSADMEMBER",
- 					  $dcvars,
- 					  $trustvars_f,
- 					  $trustvars_e,
--- 
-2.33.1
-
-
-From 449503537d409f5774433ea19f520f560bfff981 Mon Sep 17 00:00:00 2001
-From: Andreas Schneider <asn@samba.org>
-Date: Thu, 10 Jun 2021 16:20:28 +0200
-Subject: [PATCH 04/39] CVE-2020-25717 selftest: Only set netbios aliases for
- the ad_member env
-
-The provision_ad_member() function is reused by different
-setup_ad_member*() functions. Each environment needs to have unique
-netbios aliases as they are all in the same network.
-The aliases should only be set for the 'ad_member' environment.
-
-Signed-Off-By: Andreas Schneider <asn@samba.org>
-Reviewed-by: Jeremy Allison <jra@samba.org>
-
-Autobuild-User(master): Jeremy Allison <jra@samba.org>
-Autobuild-Date(master): Fri Jun 11 01:26:36 UTC 2021 on sn-devel-184
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
-
-(cherry picked from commit e165dcc770ec58c3749d653d6cb85f6ecf9479d6)
----
- selftest/target/Samba3.pm | 8 +++++++-
- 1 file changed, 7 insertions(+), 1 deletion(-)
-
-diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
-index 4686f5d36aa..5c0f71757ef 100755
---- a/selftest/target/Samba3.pm
-+++ b/selftest/target/Samba3.pm
-@@ -682,11 +682,17 @@ sub provision_ad_member
- 	$substitution_path = "$share_dir/D_$dcvars->{DOMAIN}/u_$dcvars->{DOMAIN}/alice/g_$dcvars->{DOMAIN}/domain users";
- 	push(@dirs, $substitution_path);
- 
-+
-+	my $netbios_aliases = "";
-+	if ($machine_account eq "LOCALADMEMBER") {
-+		$netbios_aliases = "netbios aliases = foo bar";
-+	}
-+
- 	my $member_options = "
- 	security = ads
-         workgroup = $dcvars->{DOMAIN}
-         realm = $dcvars->{REALM}
--        netbios aliases = foo bar
-+        $netbios_aliases
- 	template homedir = /home/%D/%G/%U
- 	auth event notification = true
- 	password server = $dcvars->{SERVER}
--- 
-2.33.1
-
-
-From 930722757311af95dbd516222e21a4a107f11ce4 Mon Sep 17 00:00:00 2001
-From: Volker Lendecke <vl@samba.org>
-Date: Wed, 14 Apr 2021 10:05:59 +0200
-Subject: [PATCH 05/39] CVE-2020-25717 auth3: Simplify check_samba4_security()
-
-First set up "server_info" in a local variable and once it's fully set
-up, assign it to the out parameter "pserver_info".
-
-Pointer dereferencing obfuscates the code for me.
-
-Signed-off-by: Volker Lendecke <vl@samba.org>
-Reviewed-by: Jeremy Allison <jra@samba.org>
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
-
-(cherry picked from commit 062a0c14c6ee0b74e7619af73747df59c5e67672)
----
- source3/auth/auth_samba4.c | 29 +++++++++++++++++------------
- 1 file changed, 17 insertions(+), 12 deletions(-)
-
-diff --git a/source3/auth/auth_samba4.c b/source3/auth/auth_samba4.c
-index 0a7c67be232..ac141354747 100644
---- a/source3/auth/auth_samba4.c
-+++ b/source3/auth/auth_samba4.c
-@@ -108,11 +108,12 @@ static struct server_id *new_server_id_task(TALLOC_CTX *mem_ctx)
-  * services the AD DC.  It is tested via pdbtest.
-  */
- 
--static NTSTATUS check_samba4_security(const struct auth_context *auth_context,
--				      void *my_private_data,
--				      TALLOC_CTX *mem_ctx,
--				      const struct auth_usersupplied_info *user_info,
--				      struct auth_serversupplied_info **server_info)
-+static NTSTATUS check_samba4_security(
-+	const struct auth_context *auth_context,
-+	void *my_private_data,
-+	TALLOC_CTX *mem_ctx,
-+	const struct auth_usersupplied_info *user_info,
-+	struct auth_serversupplied_info **pserver_info)
- {
- 	TALLOC_CTX *frame = talloc_stackframe();
- 	struct netr_SamInfo3 *info3 = NULL;
-@@ -120,6 +121,7 @@ static NTSTATUS check_samba4_security(const struct auth_context *auth_context,
- 	struct auth_user_info_dc *user_info_dc;
- 	struct auth4_context *auth4_context;
- 	uint8_t authoritative = 0;
-+	struct auth_serversupplied_info *server_info = NULL;
- 
- 	nt_status = make_auth4_context_s4(auth_context, mem_ctx, &auth4_context);
- 	if (!NT_STATUS_IS_OK(nt_status)) {
-@@ -161,17 +163,19 @@ static NTSTATUS check_samba4_security(const struct auth_context *auth_context,
- 	}
- 
- 	if (user_info->flags & USER_INFO_INFO3_AND_NO_AUTHZ) {
--		*server_info = make_server_info(mem_ctx);
--		if (*server_info == NULL) {
-+		server_info = make_server_info(mem_ctx);
-+		if (server_info == NULL) {
- 			nt_status = NT_STATUS_NO_MEMORY;
- 			goto done;
- 		}
--		(*server_info)->info3 = talloc_steal(*server_info, info3);
--
-+		server_info->info3 = talloc_move(server_info, &info3);
- 	} else {
--		nt_status = make_server_info_info3(mem_ctx, user_info->client.account_name,
--						   user_info->mapped.domain_name, server_info,
--						   info3);
-+		nt_status = make_server_info_info3(
-+			mem_ctx,
-+			user_info->client.account_name,
-+			user_info->mapped.domain_name,
-+			&server_info,
-+			info3);
- 		if (!NT_STATUS_IS_OK(nt_status)) {
- 			DEBUG(10, ("make_server_info_info3 failed: %s\n",
- 				   nt_errstr(nt_status)));
-@@ -179,6 +183,7 @@ static NTSTATUS check_samba4_security(const struct auth_context *auth_context,
- 		}
- 	}
- 
-+	*pserver_info = server_info;
- 	nt_status = NT_STATUS_OK;
- 
-  done:
--- 
-2.33.1
-
-
-From bf52e64053a0f4369d005782d2f9a75d03328ddb Mon Sep 17 00:00:00 2001
-From: Volker Lendecke <vl@samba.org>
-Date: Tue, 13 Apr 2021 15:14:01 +0000
-Subject: [PATCH 06/39] CVE-2020-25717 auth: Simplify DEBUG statements in
- make_auth3_context_for_ntlm()
-
-Signed-off-by: Volker Lendecke <vl@samba.org>
-Reviewed-by: Jeremy Allison <jra@samba.org>
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
-
-(cherry picked from commit 8536bf7fce41c43bbed25f7ed4ce5775a1b9c0d5)
----
- source3/auth/auth.c | 15 +++++++++------
- 1 file changed, 9 insertions(+), 6 deletions(-)
-
-diff --git a/source3/auth/auth.c b/source3/auth/auth.c
-index fa73c4e4db2..6d2a40f0f29 100644
---- a/source3/auth/auth.c
-+++ b/source3/auth/auth.c
-@@ -530,28 +530,28 @@ NTSTATUS make_auth3_context_for_ntlm(TALLOC_CTX *mem_ctx,
- 				     struct auth_context **auth_context)
- {
- 	const char *methods = NULL;
-+	const char *role = NULL;
- 
- 	switch (lp_server_role()) {
- 	case ROLE_ACTIVE_DIRECTORY_DC:
--		DEBUG(5,("Making default auth method list for server role = "
--			 "'active directory domain controller'\n"));
-+		role = "'active directory domain controller'";
- 		methods = "samba4";
- 		break;
- 	case ROLE_DOMAIN_MEMBER:
--		DEBUG(5,("Making default auth method list for server role = 'domain member'\n"));
-+		role = "'domain member'";
- 		methods = "anonymous sam winbind sam_ignoredomain";
- 		break;
- 	case ROLE_DOMAIN_BDC:
- 	case ROLE_DOMAIN_PDC:
--		DEBUG(5,("Making default auth method list for DC\n"));
-+		role = "'DC'";
- 		methods = "anonymous sam winbind sam_ignoredomain";
- 		break;
- 	case ROLE_STANDALONE:
--		DEBUG(5,("Making default auth method list for server role = 'standalone server', encrypt passwords = yes\n"));
- 		if (lp_encrypt_passwords()) {
-+			role = "'standalone server', encrypt passwords = yes";
- 			methods = "anonymous sam_ignoredomain";
- 		} else {
--			DEBUG(5,("Making default auth method list for server role = 'standalone server', encrypt passwords = no\n"));
-+			role = "'standalone server', encrypt passwords = no";
- 			methods = "anonymous unix";
- 		}
- 		break;
-@@ -560,6 +560,9 @@ NTSTATUS make_auth3_context_for_ntlm(TALLOC_CTX *mem_ctx,
- 		return NT_STATUS_UNSUCCESSFUL;
- 	}
- 
-+	DBG_INFO("Making default auth method list for server role = %s\n",
-+		 role);
-+
- 	return make_auth_context_specific(mem_ctx, auth_context, methods);
- }
- 
--- 
-2.33.1
-
-
-From fe1188475e15269321a62b4d11cc520e5b7d0c6e Mon Sep 17 00:00:00 2001
-From: Volker Lendecke <vl@samba.org>
-Date: Wed, 14 Apr 2021 21:48:32 +0200
-Subject: [PATCH 07/39] CVE-2020-25717 auth4: Make auth_anonymous pseudo-async
-
-Signed-off-by: Volker Lendecke <vl@samba.org>
-Reviewed-by: Andrew Bartlett <abartlet@samba.org>
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
-
-(cherry picked from commit 759573136876ef2b1b1c7484f99570d7de957e0d)
----
- source4/auth/ntlm/auth_anonymous.c | 66 ++++++++++++++++++++++++++----
- source4/auth/ntlm/wscript_build    |  2 +-
- 2 files changed, 58 insertions(+), 10 deletions(-)
-
-diff --git a/source4/auth/ntlm/auth_anonymous.c b/source4/auth/ntlm/auth_anonymous.c
-index 83aeb431f5f..a25aacaa137 100644
---- a/source4/auth/ntlm/auth_anonymous.c
-+++ b/source4/auth/ntlm/auth_anonymous.c
-@@ -20,9 +20,11 @@
- */
- 
- #include "includes.h"
-+#include <tevent.h>
- #include "auth/auth.h"
- #include "auth/ntlm/auth_proto.h"
- #include "param/param.h"
-+#include "lib/util/tevent_ntstatus.h"
- 
- #undef DBGC_CLASS
- #define DBGC_CLASS DBGC_AUTH
-@@ -84,19 +86,65 @@ static NTSTATUS anonymous_want_check(struct auth_method_context *ctx,
-  * anonymou logons to be dealt with in one place.  Non-anonymou logons 'fail'
-  * and pass onto the next module.
-  **/
--static NTSTATUS anonymous_check_password(struct auth_method_context *ctx,
--			      		 TALLOC_CTX *mem_ctx,
--					 const struct auth_usersupplied_info *user_info, 
--					 struct auth_user_info_dc **_user_info_dc,
--					 bool *authoritative)
-+
-+struct anonymous_check_password_state {
-+	struct auth_user_info_dc *user_info_dc;
-+};
-+
-+static struct tevent_req *anonymous_check_password_send(
-+	TALLOC_CTX *mem_ctx,
-+	struct tevent_context *ev,
-+	struct auth_method_context *ctx,
-+	const struct auth_usersupplied_info *user_info)
-+{
-+	struct tevent_req *req = NULL;
-+	struct anonymous_check_password_state *state = NULL;
-+	NTSTATUS status;
-+
-+	req = tevent_req_create(
-+		mem_ctx,
-+		&state,
-+		struct anonymous_check_password_state);
-+	if (req == NULL) {
-+		return NULL;
-+	}
-+
-+	status = auth_anonymous_user_info_dc(
-+		state,
-+		lpcfg_netbios_name(ctx->auth_ctx->lp_ctx),
-+		&state->user_info_dc);
-+	if (tevent_req_nterror(req, status)) {
-+		return tevent_req_post(req, ev);
-+	}
-+	tevent_req_done(req);
-+	return tevent_req_post(req, ev);
-+}
-+
-+static NTSTATUS anonymous_check_password_recv(
-+	struct tevent_req *req,
-+	TALLOC_CTX *mem_ctx,
-+	struct auth_user_info_dc **interim_info,
-+	bool *authoritative)
- {
--	return auth_anonymous_user_info_dc(mem_ctx, lpcfg_netbios_name(ctx->auth_ctx->lp_ctx), _user_info_dc);
-+	struct anonymous_check_password_state *state = tevent_req_data(
-+		req, struct anonymous_check_password_state);
-+	NTSTATUS status;
-+
-+	if (tevent_req_is_nterror(req, &status)) {
-+		tevent_req_received(req);
-+		return status;
-+	}
-+	*interim_info = talloc_move(mem_ctx, &state->user_info_dc);
-+	tevent_req_received(req);
-+	return NT_STATUS_OK;
- }
- 
-+
- static const struct auth_operations anonymous_auth_ops = {
--	.name		= "anonymous",
--	.want_check	= anonymous_want_check,
--	.check_password	= anonymous_check_password
-+	.name			= "anonymous",
-+	.want_check		= anonymous_want_check,
-+	.check_password_send	= anonymous_check_password_send,
-+	.check_password_recv	= anonymous_check_password_recv,
- };
- 
- _PUBLIC_ NTSTATUS auth4_anonymous_init(TALLOC_CTX *ctx)
-diff --git a/source4/auth/ntlm/wscript_build b/source4/auth/ntlm/wscript_build
-index 04a760c3e49..6ea0c4d7e3a 100644
---- a/source4/auth/ntlm/wscript_build
-+++ b/source4/auth/ntlm/wscript_build
-@@ -12,7 +12,7 @@ bld.SAMBA_MODULE('auth4_anonymous',
- 	source='auth_anonymous.c',
- 	subsystem='auth4',
- 	init_function='auth4_anonymous_init',
--	deps='talloc'
-+	deps='tevent'
- 	)
- 
- 
--- 
-2.33.1
-
-
-From c72dd26cd46ca9dc7e68649f444accf0da9b7d51 Mon Sep 17 00:00:00 2001
-From: Volker Lendecke <vl@samba.org>
-Date: Wed, 14 Apr 2021 22:22:18 +0200
-Subject: [PATCH 08/39] CVE-2020-25717 auth4: Make auth_developer pseudo-async
-
-This is a simpler approach to really just wrap the code.
-
-Signed-off-by: Volker Lendecke <vl@samba.org>
-Reviewed-by: Andrew Bartlett <abartlet@samba.org>
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
-
-(cherry picked from commit 43a1e42815718591faa8d526319b96d089a758fa)
----
- source4/auth/ntlm/auth_developer.c | 61 +++++++++++++++++++++++++++++-
- source4/auth/ntlm/wscript_build    |  2 +-
- 2 files changed, 61 insertions(+), 2 deletions(-)
-
-diff --git a/source4/auth/ntlm/auth_developer.c b/source4/auth/ntlm/auth_developer.c
-index 209786b63b2..1823989c68d 100644
---- a/source4/auth/ntlm/auth_developer.c
-+++ b/source4/auth/ntlm/auth_developer.c
-@@ -20,9 +20,11 @@
- */
- 
- #include "includes.h"
-+#include <tevent.h>
- #include "auth/auth.h"
- #include "auth/ntlm/auth_proto.h"
- #include "libcli/security/security.h"
-+#include "lib/util/tevent_ntstatus.h"
- 
- #undef DBGC_CLASS
- #define DBGC_CLASS DBGC_AUTH
-@@ -137,10 +139,67 @@ static NTSTATUS name_to_ntstatus_check_password(struct auth_method_context *ctx,
- 	return nt_status;
- }
- 
-+struct name_to_ntstatus_check_password_state {
-+	struct auth_user_info_dc *user_info_dc;
-+	bool authoritative;
-+};
-+
-+static struct tevent_req *name_to_ntstatus_check_password_send(
-+	TALLOC_CTX *mem_ctx,
-+	struct tevent_context *ev,
-+	struct auth_method_context *ctx,
-+	const struct auth_usersupplied_info *user_info)
-+{
-+	struct tevent_req *req = NULL;
-+	struct name_to_ntstatus_check_password_state *state = NULL;
-+	NTSTATUS status;
-+
-+	req = tevent_req_create(
-+		mem_ctx,
-+		&state,
-+		struct name_to_ntstatus_check_password_state);
-+	if (req == NULL) {
-+		return NULL;
-+	}
-+
-+	status = name_to_ntstatus_check_password(
-+		ctx,
-+		state,
-+		user_info,
-+		&state->user_info_dc,
-+		&state->authoritative);
-+	if (tevent_req_nterror(req, status)) {
-+		return tevent_req_post(req, ev);
-+	}
-+	tevent_req_done(req);
-+	return tevent_req_post(req, ev);
-+}
-+
-+static NTSTATUS name_to_ntstatus_check_password_recv(
-+	struct tevent_req *req,
-+	TALLOC_CTX *mem_ctx,
-+	struct auth_user_info_dc **interim_info,
-+	bool *authoritative)
-+{
-+	struct name_to_ntstatus_check_password_state *state = tevent_req_data(
-+		req, struct name_to_ntstatus_check_password_state);
-+	NTSTATUS status;
-+
-+	if (tevent_req_is_nterror(req, &status)) {
-+		tevent_req_received(req);
-+		return status;
-+	}
-+	*interim_info = talloc_move(mem_ctx, &state->user_info_dc);
-+	*authoritative = state->authoritative;
-+	tevent_req_received(req);
-+	return NT_STATUS_OK;
-+}
-+
- static const struct auth_operations name_to_ntstatus_auth_ops = {
- 	.name		= "name_to_ntstatus",
- 	.want_check	= name_to_ntstatus_want_check,
--	.check_password	= name_to_ntstatus_check_password
-+	.check_password_send	= name_to_ntstatus_check_password_send,
-+	.check_password_recv	= name_to_ntstatus_check_password_recv,
- };
- 
- _PUBLIC_ NTSTATUS auth4_developer_init(TALLOC_CTX *ctx)
-diff --git a/source4/auth/ntlm/wscript_build b/source4/auth/ntlm/wscript_build
-index 6ea0c4d7e3a..1ee8d79563a 100644
---- a/source4/auth/ntlm/wscript_build
-+++ b/source4/auth/ntlm/wscript_build
-@@ -28,7 +28,7 @@ bld.SAMBA_MODULE('auth4_developer',
- 	source='auth_developer.c',
- 	subsystem='auth4',
- 	init_function='auth4_developer_init',
--	deps='talloc'
-+	deps='tevent'
- 	)
- 
- 
--- 
-2.33.1
-
-
-From a5f3c5d48c490c637cf4e5854dbd01a585c9c0eb Mon Sep 17 00:00:00 2001
-From: Volker Lendecke <vl@samba.org>
-Date: Wed, 14 Apr 2021 21:59:55 +0200
-Subject: [PATCH 09/39] CVE-2020-25717 auth4: Make auth_unix pseudo-async
-
-Signed-off-by: Volker Lendecke <vl@samba.org>
-Reviewed-by: Andrew Bartlett <abartlet@samba.org>
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
-
-(cherry picked from commit a6f42ab8a778b9863990da3112c2e868cd006303)
----
- source4/auth/ntlm/auth_unix.c | 85 ++++++++++++++++++++++++-----------
- 1 file changed, 59 insertions(+), 26 deletions(-)
-
-diff --git a/source4/auth/ntlm/auth_unix.c b/source4/auth/ntlm/auth_unix.c
-index 67cd5f3dc44..cfe4f1a073f 100644
---- a/source4/auth/ntlm/auth_unix.c
-+++ b/source4/auth/ntlm/auth_unix.c
-@@ -27,6 +27,7 @@
- #include "lib/tsocket/tsocket.h"
- #include "../libcli/auth/pam_errors.h"
- #include "param/param.h"
-+#include "lib/util/tevent_ntstatus.h"
- 
- #undef DBGC_CLASS
- #define DBGC_CLASS DBGC_AUTH
-@@ -713,46 +714,78 @@ static NTSTATUS authunix_want_check(struct auth_method_context *ctx,
- 	return NT_STATUS_OK;
- }
- 
--static NTSTATUS authunix_check_password(struct auth_method_context *ctx,
--					TALLOC_CTX *mem_ctx,
--					const struct auth_usersupplied_info *user_info,
--					struct auth_user_info_dc **user_info_dc,
--					bool *authoritative)
-+struct authunix_check_password_state {
-+	struct auth_user_info_dc *user_info_dc;
-+};
-+
-+static struct tevent_req *authunix_check_password_send(
-+	TALLOC_CTX *mem_ctx,
-+	struct tevent_context *ev,
-+	struct auth_method_context *ctx,
-+	const struct auth_usersupplied_info *user_info)
- {
--	TALLOC_CTX *check_ctx;
--	NTSTATUS nt_status;
--	struct passwd *pwd;
-+	struct tevent_req *req = NULL;
-+	struct authunix_check_password_state *state = NULL;
-+	struct passwd *pwd = NULL;
-+	NTSTATUS status;
- 
--	if (user_info->password_state != AUTH_PASSWORD_PLAIN) {
--		return NT_STATUS_INVALID_PARAMETER;
-+	req = tevent_req_create(
-+		mem_ctx,
-+		&state,
-+		struct authunix_check_password_state);
-+	if (req == NULL) {
-+		return NULL;
- 	}
- 
--	check_ctx = talloc_named_const(mem_ctx, 0, "check_unix_password");
--	if (check_ctx == NULL) {
--		return NT_STATUS_NO_MEMORY;
-+	if (user_info->password_state != AUTH_PASSWORD_PLAIN) {
-+		tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
-+		return tevent_req_post(req, ev);
- 	}
- 
--	nt_status = check_unix_password(check_ctx, ctx->auth_ctx->lp_ctx, user_info, &pwd);
--	if (!NT_STATUS_IS_OK(nt_status)) {
--		talloc_free(check_ctx);
--		return nt_status;
-+	status = check_unix_password(
-+		state, ctx->auth_ctx->lp_ctx, user_info, &pwd);
-+	if (tevent_req_nterror(req, status)) {
-+		return tevent_req_post(req, ev);
- 	}
- 
--	nt_status = authunix_make_user_info_dc(mem_ctx, lpcfg_netbios_name(ctx->auth_ctx->lp_ctx),
--					      user_info, pwd, user_info_dc);
--	if (!NT_STATUS_IS_OK(nt_status)) {
--		talloc_free(check_ctx);
--		return nt_status;
-+	status = authunix_make_user_info_dc(
-+		state,
-+		lpcfg_netbios_name(ctx->auth_ctx->lp_ctx),
-+		user_info,
-+		pwd,
-+		&state->user_info_dc);
-+	if (tevent_req_nterror(req, status)) {
-+		return tevent_req_post(req, ev);
- 	}
- 
--	talloc_free(check_ctx);
-+	tevent_req_done(req);
-+	return tevent_req_post(req, ev);
-+}
-+
-+static NTSTATUS authunix_check_password_recv(
-+	struct tevent_req *req,
-+	TALLOC_CTX *mem_ctx,
-+	struct auth_user_info_dc **interim_info,
-+	bool *authoritative)
-+{
-+	struct authunix_check_password_state *state = tevent_req_data(
-+		req, struct authunix_check_password_state);
-+	NTSTATUS status;
-+
-+	if (tevent_req_is_nterror(req, &status)) {
-+		tevent_req_received(req);
-+		return status;
-+	}
-+	*interim_info = talloc_move(mem_ctx, &state->user_info_dc);
-+	tevent_req_received(req);
- 	return NT_STATUS_OK;
- }
- 
- static const struct auth_operations unix_ops = {
--	.name		= "unix",
--	.want_check	= authunix_want_check,
--	.check_password	= authunix_check_password
-+	.name			= "unix",
-+	.want_check		= authunix_want_check,
-+	.check_password_send	= authunix_check_password_send,
-+	.check_password_recv	= authunix_check_password_recv,
- };
- 
- _PUBLIC_ NTSTATUS auth4_unix_init(TALLOC_CTX *ctx)
--- 
-2.33.1
-
-
-From e655b408ee2bf4fb4535140c03dd1d795be861dd Mon Sep 17 00:00:00 2001
-From: Volker Lendecke <vl@samba.org>
-Date: Thu, 15 Apr 2021 10:04:21 +0200
-Subject: [PATCH 10/39] CVE-2020-25717 auth4: Make auth_sam pseudo-async
-
-Signed-off-by: Volker Lendecke <vl@samba.org>
-Reviewed-by: Andrew Bartlett <abartlet@samba.org>
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
-
-(cherry picked from commit f852fb4cd4e2bcd676a9ea104c5bf00979771eed)
----
- source4/auth/ntlm/auth_sam.c | 69 ++++++++++++++++++++++++++++++++++--
- 1 file changed, 67 insertions(+), 2 deletions(-)
-
-diff --git a/source4/auth/ntlm/auth_sam.c b/source4/auth/ntlm/auth_sam.c
-index c5b27171937..a521bc94bc4 100644
---- a/source4/auth/ntlm/auth_sam.c
-+++ b/source4/auth/ntlm/auth_sam.c
-@@ -36,6 +36,7 @@
- #include "lib/messaging/irpc.h"
- #include "libcli/auth/libcli_auth.h"
- #include "libds/common/roles.h"
-+#include "lib/util/tevent_ntstatus.h"
- 
- #undef DBGC_CLASS
- #define DBGC_CLASS DBGC_AUTH
-@@ -733,6 +734,68 @@ static NTSTATUS authsam_check_password_internals(struct auth_method_context *ctx
- 	return NT_STATUS_OK;
- }
- 
-+struct authsam_check_password_state {
-+	struct auth_user_info_dc *user_info_dc;
-+	bool authoritative;
-+};
-+
-+static struct tevent_req *authsam_check_password_send(
-+	TALLOC_CTX *mem_ctx,
-+	struct tevent_context *ev,
-+	struct auth_method_context *ctx,
-+	const struct auth_usersupplied_info *user_info)
-+{
-+	struct tevent_req *req = NULL;
-+	struct authsam_check_password_state *state = NULL;
-+	NTSTATUS status;
-+
-+	req = tevent_req_create(
-+		mem_ctx, &state, struct authsam_check_password_state);
-+	if (req == NULL) {
-+		return NULL;
-+	}
-+	/*
-+	 * authsam_check_password_internals() sets this to false in
-+	 * the rodc case, otherwise it leaves it untouched. Default to
-+	 * "we're authoritative".
-+	 */
-+	state->authoritative = true;
-+
-+	status = authsam_check_password_internals(
-+		ctx,
-+		state,
-+		user_info,
-+		&state->user_info_dc,
-+		&state->authoritative);
-+	if (tevent_req_nterror(req, status)) {
-+		return tevent_req_post(req, ev);
-+	}
-+
-+	tevent_req_done(req);
-+	return tevent_req_post(req, ev);
-+}
-+
-+static NTSTATUS authsam_check_password_recv(
-+	struct tevent_req *req,
-+	TALLOC_CTX *mem_ctx,
-+	struct auth_user_info_dc **interim_info,
-+	bool *authoritative)
-+{
-+	struct authsam_check_password_state *state = tevent_req_data(
-+		req, struct authsam_check_password_state);
-+	NTSTATUS status;
-+
-+	*authoritative = state->authoritative;
-+
-+	if (tevent_req_is_nterror(req, &status)) {
-+		tevent_req_received(req);
-+		return status;
-+	}
-+	*interim_info = talloc_move(mem_ctx, &state->user_info_dc);
-+	tevent_req_received(req);
-+	return NT_STATUS_OK;
-+}
-+
- static NTSTATUS authsam_ignoredomain_want_check(struct auth_method_context *ctx,
- 						TALLOC_CTX *mem_ctx,
- 						const struct auth_usersupplied_info *user_info)
-@@ -888,14 +951,16 @@ static NTSTATUS authsam_get_user_info_dc_principal_wrapper(TALLOC_CTX *mem_ctx,
- static const struct auth_operations sam_ignoredomain_ops = {
- 	.name		           = "sam_ignoredomain",
- 	.want_check	           = authsam_ignoredomain_want_check,
--	.check_password	           = authsam_check_password_internals,
-+	.check_password_send	   = authsam_check_password_send,
-+	.check_password_recv	   = authsam_check_password_recv,
- 	.get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper,
- };
- 
- static const struct auth_operations sam_ops = {
- 	.name		           = "sam",
- 	.want_check	           = authsam_want_check,
--	.check_password	           = authsam_check_password_internals,
-+	.check_password_send	   = authsam_check_password_send,
-+	.check_password_recv	   = authsam_check_password_recv,
- 	.get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper,
- };
- 
--- 
-2.33.1
-
-
-From 61e6c5f7c5d1df83350ae4969a1f365b4302a240 Mon Sep 17 00:00:00 2001
-From: Volker Lendecke <vl@samba.org>
-Date: Wed, 14 Apr 2021 22:24:44 +0200
-Subject: [PATCH 11/39] CVE-2020-25717 auth4: Remove sync check_password from
- auth_operations
-
-Remove complexity in the data structures, and pushes the async-ness
-one level down.
-
-Signed-off-by: Volker Lendecke <vl@samba.org>
-Reviewed-by: Andrew Bartlett <abartlet@samba.org>
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
-
-(cherry picked from commit 254af19ba89b4c42e5f45ec731e6577d2fcc6736)
----
- source4/auth/auth.h      |  4 ----
- source4/auth/ntlm/auth.c | 44 ++++------------------------------------
- 2 files changed, 4 insertions(+), 44 deletions(-)
-
-diff --git a/source4/auth/auth.h b/source4/auth/auth.h
-index 51895c9259f..3f9fb1ae3cb 100644
---- a/source4/auth/auth.h
-+++ b/source4/auth/auth.h
-@@ -61,10 +61,6 @@ struct auth_operations {
- 
- 	/* Given the user supplied info, check a password */
- 
--	NTSTATUS (*check_password)(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx,
--				   const struct auth_usersupplied_info *user_info,
--				   struct auth_user_info_dc **interim_info,
--				   bool *authoritative);
- 	struct tevent_req *(*check_password_send)(TALLOC_CTX *mem_ctx,
- 				struct tevent_context *ev,
- 				struct auth_method_context *ctx,
-diff --git a/source4/auth/ntlm/auth.c b/source4/auth/ntlm/auth.c
-index 75cf12c5742..e54eb7719f5 100644
---- a/source4/auth/ntlm/auth.c
-+++ b/source4/auth/ntlm/auth.c
-@@ -332,7 +332,6 @@ static void auth_check_password_next(struct tevent_req *req)
- 	struct auth_check_password_state *state =
- 		tevent_req_data(req, struct auth_check_password_state);
- 	struct tevent_req *subreq = NULL;
--	bool authoritative = true;
- 	NTSTATUS status;
- 
- 	if (state->method == NULL) {
-@@ -357,47 +356,12 @@ static void auth_check_password_next(struct tevent_req *req)
- 		return;
- 	}
- 
--	if (state->method->ops->check_password_send != NULL) {
--		subreq = state->method->ops->check_password_send(state,
--								 state->ev,
--								 state->method,
--								 state->user_info);
--		if (tevent_req_nomem(subreq, req)) {
--			return;
--		}
--		tevent_req_set_callback(subreq,
--					auth_check_password_done,
--					req);
--		return;
--	}
--
--	if (state->method->ops->check_password == NULL) {
--		tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
--		return;
--	}
--
--	status = state->method->ops->check_password(state->method,
--						    state,
--						    state->user_info,
--						    &state->user_info_dc,
--						    &authoritative);
--	if (!authoritative ||
--	    NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
--		DEBUG(11,("auth_check_password_send: "
--			  "%s passes to the next method\n",
--			  state->method->ops->name));
--		state->method = state->method->next;
--		auth_check_password_next(req);
--		return;
--	}
--
--	/* the backend has handled the request */
--
--	if (tevent_req_nterror(req, status)) {
-+	subreq = state->method->ops->check_password_send(
-+		state, state->ev, state->method, state->user_info);
-+	if (tevent_req_nomem(subreq, req)) {
- 		return;
- 	}
--
--	tevent_req_done(req);
-+	tevent_req_set_callback(subreq, auth_check_password_done, req);
- }
- 
- static void auth_check_password_done(struct tevent_req *subreq)
--- 
-2.33.1
-
-
-From 557c44fe666b758eebb8ffab2b540722d995f3cd Mon Sep 17 00:00:00 2001
-From: Stefan Metzmacher <metze@samba.org>
-Date: Mon, 4 Oct 2021 17:29:34 +0200
-Subject: [PATCH 12/39] CVE-2020-25717: s3:winbindd: make sure we default to
- r->out.authoritative = true
-
-We need to make sure that temporary failures don't trigger a fallback
-to the local SAM that silently ignores the domain name part for users.
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
-
-Signed-off-by: Stefan Metzmacher <metze@samba.org>
-Reviewed-by: Andrew Bartlett <abartlet@samba.org>
----
- source3/winbindd/winbindd_dual_srv.c      |  7 +++++++
- source3/winbindd/winbindd_irpc.c          |  7 +++++++
- source3/winbindd/winbindd_pam.c           | 15 +++++++++++----
- source3/winbindd/winbindd_pam_auth_crap.c |  9 ++++++++-
- source3/winbindd/winbindd_util.c          |  7 +++++++
- 5 files changed, 40 insertions(+), 5 deletions(-)
-
-diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c
-index 32d11e1fa57..0be5ae5554b 100644
---- a/source3/winbindd/winbindd_dual_srv.c
-+++ b/source3/winbindd/winbindd_dual_srv.c
-@@ -941,6 +941,13 @@ NTSTATUS _winbind_SamLogon(struct pipes_struct *p,
- 	union netr_Validation *validation = NULL;
- 	bool interactive = false;
- 
-+	/*
-+	 * Make sure we start with authoritative=true,
-+	 * it will only set to false if we don't know the
-+	 * domain.
-+	 */
-+	r->out.authoritative = true;
-+
- 	domain = wb_child_domain();
- 	if (domain == NULL) {
- 		return NT_STATUS_REQUEST_NOT_ACCEPTED;
-diff --git a/source3/winbindd/winbindd_irpc.c b/source3/winbindd/winbindd_irpc.c
-index e419736010b..918393c0827 100644
---- a/source3/winbindd/winbindd_irpc.c
-+++ b/source3/winbindd/winbindd_irpc.c
-@@ -142,6 +142,13 @@ static NTSTATUS wb_irpc_SamLogon(struct irpc_message *msg,
- 	const char *target_domain_name = NULL;
- 	const char *account_name = NULL;
- 
-+	/*
-+	 * Make sure we start with authoritative=true,
-+	 * it will only set to false if we don't know the
-+	 * domain.
-+	 */
-+	req->out.authoritative = true;
-+
- 	switch (req->in.logon_level) {
- 	case NetlogonInteractiveInformation:
- 	case NetlogonServiceInformation:
-diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c
-index f27802ee065..f71eb8197a4 100644
---- a/source3/winbindd/winbindd_pam.c
-+++ b/source3/winbindd/winbindd_pam.c
-@@ -1799,7 +1799,7 @@ static NTSTATUS winbindd_dual_pam_auth_samlogon(
- {
- 	fstring name_namespace, name_domain, name_user;
- 	NTSTATUS result;
--	uint8_t authoritative = 0;
-+	uint8_t authoritative = 1;
- 	uint32_t flags = 0;
- 	uint16_t validation_level = 0;
- 	union netr_Validation *validation = NULL;
-@@ -2453,6 +2453,13 @@ done:
- 		result = NT_STATUS_NO_LOGON_SERVERS;
- 	}
- 
-+	/*
-+	 * Here we don't alter
-+	 * state->response->data.auth.authoritative based
-+	 * on the servers response
-+	 * as we don't want a fallback to the local sam
-+	 * for interactive PAM logons
-+	 */
- 	set_auth_errors(state->response, result);
- 
- 	DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, ("Plain-text authentication for user %s returned %s (PAM: %d)\n",
-@@ -2667,7 +2674,7 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
- 	const char *name_domain = NULL;
- 	const char *workstation;
- 	uint64_t logon_id = 0;
--	uint8_t authoritative = 0;
-+	uint8_t authoritative = 1;
- 	uint32_t flags = 0;
- 	uint16_t validation_level;
- 	union netr_Validation *validation = NULL;
-@@ -2740,7 +2747,6 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
- 				       &validation_level,
- 				       &validation);
- 	if (!NT_STATUS_IS_OK(result)) {
--		state->response->data.auth.authoritative = authoritative;
- 		goto done;
- 	}
- 
-@@ -2772,7 +2778,6 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
- 				   "from firewalled domain [%s]\n",
- 				   info3->base.account_name.string,
- 				   info3->base.logon_domain.string);
--			state->response->data.auth.authoritative = true;
- 			result = NT_STATUS_AUTHENTICATION_FIREWALL_FAILED;
- 			goto done;
- 		}
-@@ -2794,6 +2799,8 @@ done:
- 	}
- 
- 	set_auth_errors(state->response, result);
-+	state->response->data.auth.authoritative = authoritative;
-+
- 	/*
- 	 * Log the winbind pam authentication, the logon_id will tie this to
- 	 * any of the logons invoked from this request.
-diff --git a/source3/winbindd/winbindd_pam_auth_crap.c b/source3/winbindd/winbindd_pam_auth_crap.c
-index dacb6566be6..a6f13806df9 100644
---- a/source3/winbindd/winbindd_pam_auth_crap.c
-+++ b/source3/winbindd/winbindd_pam_auth_crap.c
-@@ -26,6 +26,7 @@
- 
- struct winbindd_pam_auth_crap_state {
- 	struct winbindd_response *response;
-+	bool authoritative;
- 	uint32_t flags;
- };
- 
-@@ -47,7 +48,7 @@ struct tevent_req *winbindd_pam_auth_crap_send(
- 	if (req == NULL) {
- 		return NULL;
- 	}
--
-+	state->authoritative = true;
- 	state->flags = request->flags;
- 
- 	if (state->flags & WBFLAG_PAM_AUTH_PAC) {
-@@ -126,6 +127,11 @@ struct tevent_req *winbindd_pam_auth_crap_send(
- 
- 	domain = find_auth_domain(request->flags, auth_domain);
- 	if (domain == NULL) {
-+		/*
-+		 * We don't know the domain so
-+		 * we're not authoritative
-+		 */
-+		state->authoritative = false;
- 		tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER);
- 		return tevent_req_post(req, ev);
- 	}
-@@ -186,6 +192,7 @@ NTSTATUS winbindd_pam_auth_crap_recv(struct tevent_req *req,
- 
- 	if (tevent_req_is_nterror(req, &status)) {
- 		set_auth_errors(response, status);
-+		response->data.auth.authoritative = state->authoritative;
- 		return status;
- 	}
- 
-diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c
-index 414b770a271..ac4cd731c09 100644
---- a/source3/winbindd/winbindd_util.c
-+++ b/source3/winbindd/winbindd_util.c
-@@ -2095,6 +2095,13 @@ void winbindd_unset_locator_kdc_env(const struct winbindd_domain *domain)
- 
- void set_auth_errors(struct winbindd_response *resp, NTSTATUS result)
- {
-+	/*
-+	 * Make sure we start with authoritative=true,
-+	 * it will only set to false if we don't know the
-+	 * domain.
-+	 */
-+	resp->data.auth.authoritative = true;
-+
- 	resp->data.auth.nt_status = NT_STATUS_V(result);
- 	fstrcpy(resp->data.auth.nt_status_string, nt_errstr(result));
- 
--- 
-2.33.1
-
-
-From 3733dfeb24e5b58f9d92940573afbcd4a4d418fa Mon Sep 17 00:00:00 2001
-From: Stefan Metzmacher <metze@samba.org>
-Date: Mon, 4 Oct 2021 17:29:34 +0200
-Subject: [PATCH 13/39] CVE-2020-25717: s4:auth/ntlm: make sure
- auth_check_password() defaults to r->out.authoritative = true
-
-We need to make sure that temporary failures don't trigger a fallback
-to the local SAM that silently ignores the domain name part for users.
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
-
-Signed-off-by: Stefan Metzmacher <metze@samba.org>
-Reviewed-by: Andrew Bartlett <abartlet@samba.org>
----
- source4/auth/ntlm/auth.c | 5 +++++
- 1 file changed, 5 insertions(+)
-
-diff --git a/source4/auth/ntlm/auth.c b/source4/auth/ntlm/auth.c
-index e54eb7719f5..4c66f2c23cb 100644
---- a/source4/auth/ntlm/auth.c
-+++ b/source4/auth/ntlm/auth.c
-@@ -169,6 +169,11 @@ _PUBLIC_ NTSTATUS auth_check_password(struct auth4_context *auth_ctx,
- 	/*TODO: create a new event context here! */
- 	ev = auth_ctx->event_ctx;
- 
-+	/*
-+	 * We are authoritative by default
-+	 */
-+	*pauthoritative = 1;
-+
- 	subreq = auth_check_password_send(mem_ctx,
- 					  ev,
- 					  auth_ctx,
--- 
-2.33.1
-
-
-From fb466bcff4f42287e2895cf3b1b0dc20776ec607 Mon Sep 17 00:00:00 2001
-From: Stefan Metzmacher <metze@samba.org>
-Date: Tue, 26 Oct 2021 17:42:41 +0200
-Subject: [PATCH 14/39] CVE-2020-25717: s4:torture: start with authoritative =
- 1
-
-This is not strictly needed, but makes it easier to audit
-that we don't miss important places.
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
-
-Signed-off-by: Stefan Metzmacher <metze@samba.org>
-Reviewed-by: Andrew Bartlett <abartlet@samba.org>
----
- source4/torture/rpc/samlogon.c | 4 ++--
- source4/torture/rpc/schannel.c | 2 +-
- 2 files changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/source4/torture/rpc/samlogon.c b/source4/torture/rpc/samlogon.c
-index 76933b8869e..703e25fe3c5 100644
---- a/source4/torture/rpc/samlogon.c
-+++ b/source4/torture/rpc/samlogon.c
-@@ -1407,7 +1407,7 @@ static bool test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
- 
- 	union netr_LogonLevel logon;
- 	union netr_Validation validation;
--	uint8_t authoritative = 0;
-+	uint8_t authoritative = 1;
- 	uint32_t flags = 0;
- 
- 	ZERO_STRUCT(logon);
-@@ -1520,7 +1520,7 @@ bool test_InteractiveLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
- 
- 	union netr_LogonLevel logon;
- 	union netr_Validation validation;
--	uint8_t authoritative = 0;
-+	uint8_t authoritative = 1;
- 	struct dcerpc_binding_handle *b = p->binding_handle;
- 
- 	ZERO_STRUCT(a);
-diff --git a/source4/torture/rpc/schannel.c b/source4/torture/rpc/schannel.c
-index a5755041040..08a5120b66d 100644
---- a/source4/torture/rpc/schannel.c
-+++ b/source4/torture/rpc/schannel.c
-@@ -50,7 +50,7 @@ bool test_netlogon_ex_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
- 	struct netr_NetworkInfo ninfo;
- 	union netr_LogonLevel logon;
- 	union netr_Validation validation;
--	uint8_t authoritative = 0;
-+	uint8_t authoritative = 1;
- 	uint32_t _flags = 0;
- 	DATA_BLOB names_blob, chal, lm_resp, nt_resp;
- 	int i;
--- 
-2.33.1
-
-
-From 7e3934334f6d532a087db43a308c404d34b81458 Mon Sep 17 00:00:00 2001
-From: Stefan Metzmacher <metze@samba.org>
-Date: Tue, 26 Oct 2021 17:42:41 +0200
-Subject: [PATCH 15/39] CVE-2020-25717: s4:smb_server: start with authoritative
- = 1
-
-This is not strictly needed, but makes it easier to audit
-that we don't miss important places.
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
-
-Signed-off-by: Stefan Metzmacher <metze@samba.org>
-Reviewed-by: Andrew Bartlett <abartlet@samba.org>
----
- source4/smb_server/smb/sesssetup.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/source4/smb_server/smb/sesssetup.c b/source4/smb_server/smb/sesssetup.c
-index 68cdd70feff..8428ca3fabb 100644
---- a/source4/smb_server/smb/sesssetup.c
-+++ b/source4/smb_server/smb/sesssetup.c
-@@ -102,7 +102,7 @@ static void sesssetup_old_send(struct tevent_req *subreq)
- 	struct auth_session_info *session_info;
- 	struct smbsrv_session *smb_sess;
- 	NTSTATUS status;
--	uint8_t authoritative = 0;
-+	uint8_t authoritative = 1;
- 	uint32_t flags;
- 
- 	status = auth_check_password_recv(subreq, req, &user_info_dc,
-@@ -243,7 +243,7 @@ static void sesssetup_nt1_send(struct tevent_req *subreq)
- 	struct auth_user_info_dc *user_info_dc = NULL;
- 	struct auth_session_info *session_info;
- 	struct smbsrv_session *smb_sess;
--	uint8_t authoritative = 0;
-+	uint8_t authoritative = 1;
- 	uint32_t flags;
- 	NTSTATUS status;
- 
--- 
-2.33.1
-
-
-From c4a595518b453ecc5c0e2bfe7ba2cf531ea37e13 Mon Sep 17 00:00:00 2001
-From: Stefan Metzmacher <metze@samba.org>
-Date: Tue, 26 Oct 2021 17:42:41 +0200
-Subject: [PATCH 16/39] CVE-2020-25717: s4:auth_simple: start with
- authoritative = 1
-
-This is not strictly needed, but makes it easier to audit
-that we don't miss important places.
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
-
-Signed-off-by: Stefan Metzmacher <metze@samba.org>
-Reviewed-by: Andrew Bartlett <abartlet@samba.org>
----
- source4/auth/ntlm/auth_simple.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/source4/auth/ntlm/auth_simple.c b/source4/auth/ntlm/auth_simple.c
-index 8df160cefc3..8301aec519c 100644
---- a/source4/auth/ntlm/auth_simple.c
-+++ b/source4/auth/ntlm/auth_simple.c
-@@ -150,7 +150,7 @@ static void authenticate_ldap_simple_bind_done(struct tevent_req *subreq)
- 	const struct tsocket_address *local_address = user_info->local_host;
- 	const char *transport_protection = AUTHZ_TRANSPORT_PROTECTION_NONE;
- 	struct auth_user_info_dc *user_info_dc = NULL;
--	uint8_t authoritative = 0;
-+	uint8_t authoritative = 1;
- 	uint32_t flags = 0;
- 	NTSTATUS nt_status;
- 
--- 
-2.33.1
-
-
-From 0e32b75b21d5daf08fffbe25b6c40197ed04cbf8 Mon Sep 17 00:00:00 2001
-From: Stefan Metzmacher <metze@samba.org>
-Date: Tue, 26 Oct 2021 17:42:41 +0200
-Subject: [PATCH 17/39] CVE-2020-25717: s3:ntlm_auth: start with authoritative
- = 1
-
-This is not strictly needed, but makes it easier to audit
-that we don't miss important places.
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
-
-Signed-off-by: Stefan Metzmacher <metze@samba.org>
-Reviewed-by: Andrew Bartlett <abartlet@samba.org>
----
- source3/utils/ntlm_auth.c             |  4 ++--
- source3/utils/ntlm_auth_diagnostics.c | 10 +++++-----
- 2 files changed, 7 insertions(+), 7 deletions(-)
-
-diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c
-index 0370803167f..b3ab3a473bf 100644
---- a/source3/utils/ntlm_auth.c
-+++ b/source3/utils/ntlm_auth.c
-@@ -1927,7 +1927,7 @@ static void manage_ntlm_server_1_request(enum stdio_helper_mode stdio_helper_mod
- 				TALLOC_FREE(mem_ctx);
- 
- 			} else {
--				uint8_t authoritative = 0;
-+				uint8_t authoritative = 1;
- 
- 				if (!domain) {
- 					domain = smb_xstrdup(get_winbind_domain());
-@@ -2443,7 +2443,7 @@ static bool check_auth_crap(void)
- 	char *hex_lm_key;
- 	char *hex_user_session_key;
- 	char *error_string;
--	uint8_t authoritative = 0;
-+	uint8_t authoritative = 1;
- 
- 	setbuf(stdout, NULL);
- 
-diff --git a/source3/utils/ntlm_auth_diagnostics.c b/source3/utils/ntlm_auth_diagnostics.c
-index 41591a8de33..fc0fc19bacb 100644
---- a/source3/utils/ntlm_auth_diagnostics.c
-+++ b/source3/utils/ntlm_auth_diagnostics.c
-@@ -54,7 +54,7 @@ static bool test_lm_ntlm_broken(enum ntlm_break break_which)
- 	DATA_BLOB lm_response = data_blob(NULL, 24);
- 	DATA_BLOB nt_response = data_blob(NULL, 24);
- 	DATA_BLOB session_key = data_blob(NULL, 16);
--	uint8_t authoritative = 0;
-+	uint8_t authoritative = 1;
- 	uchar lm_key[8];
- 	uchar user_session_key[16];
- 	uchar lm_hash[16];
-@@ -177,7 +177,7 @@ static bool test_ntlm_in_lm(void)
- 	NTSTATUS nt_status;
- 	uint32_t flags = 0;
- 	DATA_BLOB nt_response = data_blob(NULL, 24);
--	uint8_t authoritative = 0;
-+	uint8_t authoritative = 1;
- 	uchar lm_key[8];
- 	uchar lm_hash[16];
- 	uchar user_session_key[16];
-@@ -245,7 +245,7 @@ static bool test_ntlm_in_both(void)
- 	uint32_t flags = 0;
- 	DATA_BLOB nt_response = data_blob(NULL, 24);
- 	DATA_BLOB session_key = data_blob(NULL, 16);
--	uint8_t authoritative = 0;
-+	uint8_t authoritative = 1;
- 	uint8_t lm_key[8];
- 	uint8_t lm_hash[16];
- 	uint8_t user_session_key[16];
-@@ -322,7 +322,7 @@ static bool test_lmv2_ntlmv2_broken(enum ntlm_break break_which)
- 	DATA_BLOB lmv2_response = data_blob_null;
- 	DATA_BLOB ntlmv2_session_key = data_blob_null;
- 	DATA_BLOB names_blob = NTLMv2_generate_names_blob(NULL, get_winbind_netbios_name(), get_winbind_domain());
--	uint8_t authoritative = 0;
-+	uint8_t authoritative = 1;
- 	uchar user_session_key[16];
- 	DATA_BLOB chall = get_challenge();
- 	char *error_string;
-@@ -452,7 +452,7 @@ static bool test_plaintext(enum ntlm_break break_which)
- 	char *password;
- 	smb_ucs2_t *nt_response_ucs2;
- 	size_t converted_size;
--	uint8_t authoritative = 0;
-+	uint8_t authoritative = 1;
- 	uchar user_session_key[16];
- 	uchar lm_key[16];
- 	static const uchar zeros[8] = { 0, };
--- 
-2.33.1
-
-
-From aa52008a73b9960acbb6b39684c5c460480e365b Mon Sep 17 00:00:00 2001
-From: Stefan Metzmacher <metze@samba.org>
-Date: Tue, 26 Oct 2021 17:42:41 +0200
-Subject: [PATCH 18/39] CVE-2020-25717: s3:torture: start with authoritative =
- 1
-
-This is not strictly needed, but makes it easier to audit
-that we don't miss important places.
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
-
-Signed-off-by: Stefan Metzmacher <metze@samba.org>
-Reviewed-by: Andrew Bartlett <abartlet@samba.org>
----
- source3/torture/pdbtest.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/source3/torture/pdbtest.c b/source3/torture/pdbtest.c
-index 5d74aa9ab78..b300504c4cb 100644
---- a/source3/torture/pdbtest.c
-+++ b/source3/torture/pdbtest.c
-@@ -277,7 +277,7 @@ static bool test_auth(TALLOC_CTX *mem_ctx, struct samu *pdb_entry)
- 	struct netr_SamInfo6 *info6_wbc = NULL;
- 	NTSTATUS status;
- 	bool ok;
--	uint8_t authoritative = 0;
-+	uint8_t authoritative = 1;
- 	int rc;
- 
- 	rc = SMBOWFencrypt(pdb_get_nt_passwd(pdb_entry), challenge_8,
--- 
-2.33.1
-
-
-From 9c133372ac3687e9316f1b76fdbcc9d95d54db42 Mon Sep 17 00:00:00 2001
-From: Stefan Metzmacher <metze@samba.org>
-Date: Tue, 26 Oct 2021 17:42:41 +0200
-Subject: [PATCH 19/39] CVE-2020-25717: s3:rpcclient: start with authoritative
- = 1
-
-This is not strictly needed, but makes it easier to audit
-that we don't miss important places.
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
-
-Signed-off-by: Stefan Metzmacher <metze@samba.org>
-Reviewed-by: Andrew Bartlett <abartlet@samba.org>
----
- source3/rpcclient/cmd_netlogon.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/source3/rpcclient/cmd_netlogon.c b/source3/rpcclient/cmd_netlogon.c
-index d5c1b91f2be..4ea63e40b8d 100644
---- a/source3/rpcclient/cmd_netlogon.c
-+++ b/source3/rpcclient/cmd_netlogon.c
-@@ -496,7 +496,7 @@ static NTSTATUS cmd_netlogon_sam_logon(struct rpc_pipe_client *cli,
- 	uint32_t logon_param = 0;
- 	const char *workstation = NULL;
- 	struct netr_SamInfo3 *info3 = NULL;
--	uint8_t authoritative = 0;
-+	uint8_t authoritative = 1;
- 	uint32_t flags = 0;
- 	uint16_t validation_level;
- 	union netr_Validation *validation = NULL;
--- 
-2.33.1
-
-
-From 7a2bf7eb4be1c7988bfe14dbbf297f79a05220ad Mon Sep 17 00:00:00 2001
-From: Stefan Metzmacher <metze@samba.org>
-Date: Tue, 26 Oct 2021 17:42:41 +0200
-Subject: [PATCH 20/39] CVE-2020-25717: s3:auth: start with authoritative = 1
-
-This is not strictly needed, but makes it easier to audit
-that we don't miss important places.
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
-
-Signed-off-by: Stefan Metzmacher <metze@samba.org>
-Reviewed-by: Andrew Bartlett <abartlet@samba.org>
----
- source3/auth/auth_generic.c | 2 +-
- source3/auth/auth_samba4.c  | 2 +-
- 2 files changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/source3/auth/auth_generic.c b/source3/auth/auth_generic.c
-index e62585e919c..57281874b35 100644
---- a/source3/auth/auth_generic.c
-+++ b/source3/auth/auth_generic.c
-@@ -416,7 +416,7 @@ NTSTATUS auth_check_password_session_info(struct auth4_context *auth_context,
- {
- 	NTSTATUS nt_status;
- 	void *server_info;
--	uint8_t authoritative = 0;
-+	uint8_t authoritative = 1;
- 	struct tevent_context *ev = NULL;
- 	struct tevent_req *subreq = NULL;
- 	bool ok;
-diff --git a/source3/auth/auth_samba4.c b/source3/auth/auth_samba4.c
-index ac141354747..fde78d5e74e 100644
---- a/source3/auth/auth_samba4.c
-+++ b/source3/auth/auth_samba4.c
-@@ -120,7 +120,7 @@ static NTSTATUS check_samba4_security(
- 	NTSTATUS nt_status;
- 	struct auth_user_info_dc *user_info_dc;
- 	struct auth4_context *auth4_context;
--	uint8_t authoritative = 0;
-+	uint8_t authoritative = 1;
- 	struct auth_serversupplied_info *server_info = NULL;
- 
- 	nt_status = make_auth4_context_s4(auth_context, mem_ctx, &auth4_context);
--- 
-2.33.1
-
-
-From 97f2108d84017998d2612139b787fdb674c235e2 Mon Sep 17 00:00:00 2001
-From: Stefan Metzmacher <metze@samba.org>
-Date: Tue, 26 Oct 2021 17:42:41 +0200
-Subject: [PATCH 21/39] CVE-2020-25717: auth/ntlmssp: start with authoritative
- = 1
-
-This is not strictly needed, but makes it easier to audit
-that we don't miss important places.
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
-
-Signed-off-by: Stefan Metzmacher <metze@samba.org>
-Reviewed-by: Andrew Bartlett <abartlet@samba.org>
----
- auth/ntlmssp/ntlmssp_server.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/auth/ntlmssp/ntlmssp_server.c b/auth/ntlmssp/ntlmssp_server.c
-index 001238278d7..939aa0ef4aa 100644
---- a/auth/ntlmssp/ntlmssp_server.c
-+++ b/auth/ntlmssp/ntlmssp_server.c
-@@ -799,7 +799,7 @@ static void ntlmssp_server_auth_done(struct tevent_req *subreq)
- 	struct gensec_security *gensec_security = state->gensec_security;
- 	struct gensec_ntlmssp_context *gensec_ntlmssp = state->gensec_ntlmssp;
- 	struct auth4_context *auth_context = gensec_security->auth_context;
--	uint8_t authoritative = 0;
-+	uint8_t authoritative = 1;
- 	NTSTATUS status;
- 
- 	status = auth_context->check_ntlm_password_recv(subreq,
--- 
-2.33.1
-
-
-From 59e3ccaaced1fa3f7db250d44c7e9a94070d583b Mon Sep 17 00:00:00 2001
-From: Samuel Cabrero <scabrero@samba.org>
-Date: Tue, 28 Sep 2021 10:43:40 +0200
-Subject: [PATCH 22/39] CVE-2020-25717: loadparm: Add new parameter "min domain
- uid"
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
-
-Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>
-
-Signed-off-by: Samuel Cabrero <scabrero@samba.org>
-Signed-off-by: Stefan Metzmacher <metze@samba.org>
-
-[abartlet@samba.org Backported from master/4.15 due to
- conflicts with other new parameters]
----
- docs-xml/smbdotconf/security/mindomainuid.xml | 17 +++++++++++++++++
- docs-xml/smbdotconf/winbind/idmapconfig.xml   |  4 ++++
- lib/param/loadparm.c                          |  4 ++++
- source3/param/loadparm.c                      |  2 ++
- 4 files changed, 27 insertions(+)
- create mode 100644 docs-xml/smbdotconf/security/mindomainuid.xml
-
-diff --git a/docs-xml/smbdotconf/security/mindomainuid.xml b/docs-xml/smbdotconf/security/mindomainuid.xml
-new file mode 100644
-index 00000000000..46ae795d730
---- /dev/null
-+++ b/docs-xml/smbdotconf/security/mindomainuid.xml
-@@ -0,0 +1,17 @@
-+<samba:parameter name="min domain uid"
-+                 type="integer"
-+                 context="G"
-+                 xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
-+<description>
-+  <para>
-+    The integer parameter specifies the minimum uid allowed when mapping a
-+    local account to a domain account.
-+  </para>
-+
-+  <para>
-+    Note that this option interacts with the configured <emphasis>idmap ranges</emphasis>!
-+  </para>
-+</description>
-+
-+<value type="default">1000</value>
-+</samba:parameter>
-diff --git a/docs-xml/smbdotconf/winbind/idmapconfig.xml b/docs-xml/smbdotconf/winbind/idmapconfig.xml
-index 1374040fb29..f70f11df757 100644
---- a/docs-xml/smbdotconf/winbind/idmapconfig.xml
-+++ b/docs-xml/smbdotconf/winbind/idmapconfig.xml
-@@ -80,6 +80,9 @@
- 		authoritative for a unix ID to SID mapping, so it must be set
- 		for each individually configured domain and for the default
- 		configuration. The configured ranges must be mutually disjoint.
-+		</para>
-+		<para>
-+		Note that the low value interacts with the <smbconfoption name="min domain uid"/> option!
- 		</para></listitem>
- 		</varlistentry>
- 
-@@ -115,4 +118,5 @@
- 	</programlisting>
- 	
- </description>
-+<related>min domain uid</related>
- </samba:parameter>
-diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c
-index 3548c47d857..eedfa00bcb0 100644
---- a/lib/param/loadparm.c
-+++ b/lib/param/loadparm.c
-@@ -3090,6 +3090,10 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx)
- 				  "client smb encrypt",
- 				  "default");
- 
-+	lpcfg_do_global_parameter(lp_ctx,
-+				  "min domain uid",
-+				  "1000");
-+
- 	for (i = 0; parm_table[i].label; i++) {
- 		if (!(lp_ctx->flags[i] & FLAG_CMDLINE)) {
- 			lp_ctx->flags[i] |= FLAG_DEFAULT;
-diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
-index acb4d149f0b..300b539748b 100644
---- a/source3/param/loadparm.c
-+++ b/source3/param/loadparm.c
-@@ -967,6 +967,8 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
- 
- 	Globals.client_smb_encrypt = SMB_ENCRYPTION_DEFAULT;
- 
-+	Globals.min_domain_uid = 1000;
-+
- 	/* Now put back the settings that were set with lp_set_cmdline() */
- 	apply_lp_set_cmdline();
- }
--- 
-2.33.1
-
-
-From 977bbda9fed9362bfa46e541c8cdb9666d43b57a Mon Sep 17 00:00:00 2001
-From: Stefan Metzmacher <metze@samba.org>
-Date: Fri, 8 Oct 2021 19:57:18 +0200
-Subject: [PATCH 23/39] CVE-2020-25717: s3:auth: let
- auth3_generate_session_info_pac() forward the low level errors
-
-Mapping everything to ACCESS_DENIED makes it hard to debug problems,
-which may happen because of our more restrictive behaviour in future.
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
-
-Signed-off-by: Stefan Metzmacher <metze@samba.org>
-Reviewed-by: Andrew Bartlett <abartlet@samba.org>
----
- source3/auth/auth_generic.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/source3/auth/auth_generic.c b/source3/auth/auth_generic.c
-index 57281874b35..f6a501f1df7 100644
---- a/source3/auth/auth_generic.c
-+++ b/source3/auth/auth_generic.c
-@@ -166,7 +166,7 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx,
- 	if (!NT_STATUS_IS_OK(status)) {
- 		DEBUG(1, ("Failed to map kerberos pac to server info (%s)\n",
- 			  nt_errstr(status)));
--		status = NT_STATUS_ACCESS_DENIED;
-+		status = nt_status_squash(status);
- 		goto done;
- 	}
- 
--- 
-2.33.1
-
-
-From ed88e24afbf85cc6a61c236604f3fc43a10f0d97 Mon Sep 17 00:00:00 2001
-From: Samuel Cabrero <scabrero@samba.org>
-Date: Tue, 28 Sep 2021 10:45:11 +0200
-Subject: [PATCH 24/39] CVE-2020-25717: s3:auth: Check minimum domain uid
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
-
-Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>
-
-Signed-off-by: Samuel Cabrero <scabrero@samba.org>
-Signed-off-by: Stefan Metzmacher <metze@samba.org>
-Reviewed-by: Andrew Bartlett <abartlet@samba.org>
-
-[abartlet@samba.org Removed knownfail on advice from metze]
----
- source3/auth/auth_util.c | 16 ++++++++++++++++
- 1 file changed, 16 insertions(+)
-
-diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
-index 4686b29111e..4de4bc74374 100644
---- a/source3/auth/auth_util.c
-+++ b/source3/auth/auth_util.c
-@@ -2103,6 +2103,22 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
- 			}
- 		}
- 		goto out;
-+	} else if ((lp_security() == SEC_ADS || lp_security() == SEC_DOMAIN) &&
-+		   !is_myname(domain) && pwd->pw_uid < lp_min_domain_uid()) {
-+		/*
-+		 * !is_myname(domain) because when smbd starts tries to setup
-+		 * the guest user info, calling this function with nobody
-+		 * username. Nobody is usually uid 65535 but it can be changed
-+		 * to a regular user with 'guest account' parameter
-+		 */
-+		nt_status = NT_STATUS_INVALID_TOKEN;
-+		DBG_NOTICE("Username '%s%s%s' is invalid on this system, "
-+			   "it does not meet 'min domain uid' "
-+			   "restriction (%u < %u): %s\n",
-+			   nt_domain, lp_winbind_separator(), nt_username,
-+			   pwd->pw_uid, lp_min_domain_uid(),
-+			   nt_errstr(nt_status));
-+		goto out;
- 	}
- 
- 	result = make_server_info(tmp_ctx);
--- 
-2.33.1
-
-
-From 51a78934575b47e6add3110904c5de6c97566fd7 Mon Sep 17 00:00:00 2001
-From: Stefan Metzmacher <metze@samba.org>
-Date: Fri, 8 Oct 2021 17:40:30 +0200
-Subject: [PATCH 25/39] CVE-2020-25717: s3:auth: we should not try to
- autocreate the guest account
-
-We should avoid autocreation of users as much as possible.
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
-
-Signed-off-by: Stefan Metzmacher <metze@samba.org>
-Reviewed-by: Andrew Bartlett <abartlet@samba.org>
----
- source3/auth/user_krb5.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/source3/auth/user_krb5.c b/source3/auth/user_krb5.c
-index 8998f9c8f8a..074e8c7eb71 100644
---- a/source3/auth/user_krb5.c
-+++ b/source3/auth/user_krb5.c
-@@ -155,7 +155,7 @@ NTSTATUS get_user_from_kerberos_info(TALLOC_CTX *mem_ctx,
- 			if (!fuser) {
- 				return NT_STATUS_NO_MEMORY;
- 			}
--			pw = smb_getpwnam(mem_ctx, fuser, &unixuser, true);
-+			pw = smb_getpwnam(mem_ctx, fuser, &unixuser, false);
- 		}
- 
- 		/* extra sanity check that the guest account is valid */
--- 
-2.33.1
-
-
-From 0ef009b205acf1b14f8763cf2e6ce13ec8bea151 Mon Sep 17 00:00:00 2001
-From: Stefan Metzmacher <metze@samba.org>
-Date: Fri, 8 Oct 2021 18:08:20 +0200
-Subject: [PATCH 26/39] CVE-2020-25717: s3:auth: no longer let check_account()
- autocreate local users
-
-So far we autocreated local user accounts based on just the
-account_name (just ignoring any domain part).
-
-This only happens via a possible 'add user script',
-which is not typically defined on domain members
-and on NT4 DCs local users already exist in the
-local passdb anyway.
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801
-
-Signed-off-by: Stefan Metzmacher <metze@samba.org>
-Reviewed-by: Andrew Bartlett <abartlet@samba.org>
----
- source3/auth/auth_util.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
-index 4de4bc74374..99b85d47a5f 100644
---- a/source3/auth/auth_util.c
-+++ b/source3/auth/auth_util.c
-@@ -1898,7 +1898,7 @@ static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain,
- 		return NT_STATUS_NO_MEMORY;
- 	}
- 
--	passwd = smb_getpwnam(mem_ctx, dom_user, &real_username, true );
-+	passwd = smb_getpwnam(mem_ctx, dom_user, &real_username, false);
- 	if (!passwd) {
- 		DEBUG(3, ("Failed to find authenticated user %s via "
- 			  "getpwnam(), denying access.\n", dom_user));
--- 
-2.33.1
-
-
-From de475a3eba52cb4599330f6932e98f97c3749ec7 Mon Sep 17 00:00:00 2001
-From: Ralph Boehme <slow@samba.org>
-Date: Fri, 8 Oct 2021 12:33:16 +0200
-Subject: [PATCH 27/39] CVE-2020-25717: s3:auth: remove fallbacks in
- smb_getpwnam()
-
-So far we tried getpwnam("DOMAIN\account") first and
-always did a fallback to getpwnam("account") completely
-ignoring the domain part, this just causes problems
-as we mix "DOMAIN1\account", "DOMAIN2\account",
-and "account"!
-
-As we require a running winbindd for domain member setups
-we should no longer do a fallback to just "account" for
-users served by winbindd!
-
-For users of the local SAM don't use this code path,
-as check_sam_security() doesn't call check_account().
-
-The only case where smb_getpwnam("account") happens is
-when map_username() via ("username map [script]")  mapped
-"DOMAIN\account" to something without '\', but that is
-explicitly desired by the admin.
-
-Note: use 'git show -w'
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
-
-Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>
-
-Signed-off-by: Ralph Boehme <slow@samba.org>
-Signed-off-by: Stefan Metzmacher <metze@samba.org>
-Reviewed-by: Andrew Bartlett <abartlet@samba.org>
----
- selftest/knownfail.d/ktest | 26 +++++++++++++
- source3/auth/auth_util.c   | 77 +++++++++++++++++++++-----------------
- 2 files changed, 68 insertions(+), 35 deletions(-)
- create mode 100644 selftest/knownfail.d/ktest
-
-diff --git a/selftest/knownfail.d/ktest b/selftest/knownfail.d/ktest
-new file mode 100644
-index 00000000000..809612ba0b9
---- /dev/null
-+++ b/selftest/knownfail.d/ktest
-@@ -0,0 +1,26 @@
-+^samba3.rpc.lsa.lookupsids.krb5.with.old.ccache.ncacn_np.with..smb2...lsa.LookupSidsReply.ktest
-+^samba3.rpc.lsa.lookupsids.krb5.ncacn_np.with..smb2...lsa.LookupSidsReply.ktest
-+^samba3.blackbox.rpcclient.krb5.ncacn_np.with..krb5...rpcclient.ktest:local
-+^samba3.blackbox.rpcclient.krb5.ncacn_np.with..spnego,krb5...rpcclient.ktest:local
-+^samba3.rpc.lsa.lookupsids.krb5.with.old.ccache.ncacn_np.with..smb2,connect...lsa.LookupSidsReply.ktest
-+^samba3.rpc.lsa.lookupsids.krb5.ncacn_np.with..smb2,connect...lsa.LookupSidsReply.ktest
-+^samba3.rpc.lsa.lookupsids.krb5.with.old.ccache.ncacn_np.with..smb2,packet...lsa.LookupSidsReply.ktest
-+^samba3.rpc.lsa.lookupsids.krb5.ncacn_np.with..smb2,packet...lsa.LookupSidsReply.ktest
-+^samba3.blackbox.rpcclient.krb5.ncacn_np.with..krb5,packet...rpcclient.ktest:local
-+^samba3.blackbox.rpcclient.krb5.ncacn_np.with..spnego,krb5,packet...rpcclient.ktest:local
-+^samba3.rpc.lsa.lookupsids.krb5.with.old.ccache.ncacn_np.with..smb2,sign...lsa.LookupSidsReply.ktest
-+^samba3.rpc.lsa.lookupsids.krb5.ncacn_np.with..smb2,sign...lsa.LookupSidsReply.ktest
-+^samba3.blackbox.rpcclient.krb5.ncacn_np.with..krb5,sign...rpcclient.ktest:local
-+^samba3.blackbox.rpcclient.krb5.ncacn_np.with..spnego,krb5,sign...rpcclient.ktest:local
-+^samba3.rpc.lsa.lookupsids.krb5.with.old.ccache.ncacn_np.with..smb2,seal...lsa.LookupSidsReply.ktest
-+^samba3.rpc.lsa.lookupsids.krb5.ncacn_np.with..smb2,seal...lsa.LookupSidsReply.ktest
-+^samba3.blackbox.rpcclient.krb5.ncacn_np.with..krb5,seal...rpcclient.ktest:local
-+^samba3.blackbox.rpcclient.krb5.ncacn_np.with..spnego,krb5,seal...rpcclient.ktest:local
-+^samba3.blackbox.smbclient_krb5.old.ccache..smbclient.ktest:local
-+^samba3.blackbox.smbclient_krb5.new.ccache..smbclient.ktest:local
-+^samba3.blackbox.smbclient_large_file..krb5.smbclient.large.posix.write.read.ktest:local
-+^samba3.blackbox.smbclient_large_file..krb5.cmp.of.read.and.written.files.ktest:local
-+^samba3.blackbox.smbclient_krb5.old.ccache.--client-protection=encrypt.smbclient.ktest:local
-+^samba3.blackbox.smbclient_krb5.new.ccache.--client-protection=encrypt.smbclient.ktest:local
-+^samba3.blackbox.smbclient_large_file.--client-protection=encrypt.krb5.smbclient.large.posix.write.read.ktest:local
-+^samba3.blackbox.smbclient_large_file.--client-protection=encrypt.krb5.cmp.of.read.and.written.files.ktest:local
-diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
-index 99b85d47a5f..d81313a0495 100644
---- a/source3/auth/auth_util.c
-+++ b/source3/auth/auth_util.c
-@@ -1933,7 +1933,7 @@ struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, const char *domuser,
- {
- 	struct passwd *pw = NULL;
- 	char *p = NULL;
--	char *username = NULL;
-+	const char *username = NULL;
- 
- 	/* we only save a copy of the username it has been mangled 
- 	   by winbindd use default domain */
-@@ -1952,48 +1952,55 @@ struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, const char *domuser,
- 	/* code for a DOMAIN\user string */
- 
- 	if ( p ) {
--		pw = Get_Pwnam_alloc( mem_ctx, domuser );
--		if ( pw ) {
--			/* make sure we get the case of the username correct */
--			/* work around 'winbind use default domain = yes' */
--
--			if ( lp_winbind_use_default_domain() &&
--			     !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
--				char *domain;
--
--				/* split the domain and username into 2 strings */
--				*p = '\0';
--				domain = username;
--
--				*p_save_username = talloc_asprintf(mem_ctx,
--								"%s%c%s",
--								domain,
--								*lp_winbind_separator(),
--								pw->pw_name);
--				if (!*p_save_username) {
--					TALLOC_FREE(pw);
--					return NULL;
--				}
--			} else {
--				*p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
--			}
-+		const char *domain = NULL;
- 
--			/* whew -- done! */
--			return pw;
-+		/* split the domain and username into 2 strings */
-+		*p = '\0';
-+		domain = username;
-+		p++;
-+		username = p;
-+
-+		if (strequal(domain, get_global_sam_name())) {
-+			/*
-+			 * This typically don't happen
-+			 * as check_sam_Security()
-+			 * don't call make_server_info_info3()
-+			 * and thus check_account().
-+			 *
-+			 * But we better keep this.
-+			 */
-+			goto username_only;
- 		}
- 
--		/* setup for lookup of just the username */
--		/* remember that p and username are overlapping memory */
--
--		p++;
--		username = talloc_strdup(mem_ctx, p);
--		if (!username) {
-+		pw = Get_Pwnam_alloc( mem_ctx, domuser );
-+		if (pw == NULL) {
- 			return NULL;
- 		}
-+		/* make sure we get the case of the username correct */
-+		/* work around 'winbind use default domain = yes' */
-+
-+		if ( lp_winbind_use_default_domain() &&
-+		     !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
-+			*p_save_username = talloc_asprintf(mem_ctx,
-+							"%s%c%s",
-+							domain,
-+							*lp_winbind_separator(),
-+							pw->pw_name);
-+			if (!*p_save_username) {
-+				TALLOC_FREE(pw);
-+				return NULL;
-+			}
-+		} else {
-+			*p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
-+		}
-+
-+		/* whew -- done! */
-+		return pw;
-+
- 	}
- 
- 	/* just lookup a plain username */
--
-+username_only:
- 	pw = Get_Pwnam_alloc(mem_ctx, username);
- 
- 	/* Create local user if requested but only if winbindd
--- 
-2.33.1
-
-
-From debd9501c568ebd536275a240cd796187d1ce39b Mon Sep 17 00:00:00 2001
-From: Stefan Metzmacher <metze@samba.org>
-Date: Tue, 21 Sep 2021 13:13:52 +0200
-Subject: [PATCH 28/39] CVE-2020-25717: s3:lib: add lp_allow_trusted_domains()
- logic to is_allowed_domain()
-
-is_allowed_domain() is a central place we already use to
-trigger NT_STATUS_AUTHENTICATION_FIREWALL_FAILED, so
-we can add additional logic there.
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
-
-Signed-off-by: Stefan Metzmacher <metze@samba.org>
-Reviewed-by: Andrew Bartlett <abartlet@samba.org>
----
- source3/lib/util_names.c | 15 ++++++++++++++-
- 1 file changed, 14 insertions(+), 1 deletion(-)
-
-diff --git a/source3/lib/util_names.c b/source3/lib/util_names.c
-index 630a25875c7..876035cbe29 100644
---- a/source3/lib/util_names.c
-+++ b/source3/lib/util_names.c
-@@ -200,5 +200,18 @@ bool is_allowed_domain(const char *domain_name)
- 		}
- 	}
- 
--	return true;
-+	if (lp_allow_trusted_domains()) {
-+		return true;
-+	}
-+
-+	if (strequal(lp_workgroup(), domain_name)) {
-+		return true;
-+	}
-+
-+	if (is_myname(domain_name)) {
-+		return true;
-+	}
-+
-+	DBG_NOTICE("Not trusted domain '%s'\n", domain_name);
-+	return false;
- }
--- 
-2.33.1
-
-
-From d2b7d75eccee7575c3dab25cc8c61e2cf00994d3 Mon Sep 17 00:00:00 2001
-From: Stefan Metzmacher <metze@samba.org>
-Date: Mon, 4 Oct 2021 18:03:55 +0200
-Subject: [PATCH 29/39] CVE-2020-25717: s3:auth: don't let create_local_token
- depend on !winbind_ping()
-
-We always require a running winbindd on a domain member, so
-we should better fail a request instead of silently alter
-the behaviour, which results in a different unix token, just
-because winbindd might be restarted.
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
-
-Signed-off-by: Stefan Metzmacher <metze@samba.org>
-Reviewed-by: Andrew Bartlett <abartlet@samba.org>
----
- source3/auth/auth_util.c | 10 ++++------
- 1 file changed, 4 insertions(+), 6 deletions(-)
-
-diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
-index d81313a0495..065b525500f 100644
---- a/source3/auth/auth_util.c
-+++ b/source3/auth/auth_util.c
-@@ -576,13 +576,11 @@ NTSTATUS create_local_token(TALLOC_CTX *mem_ctx,
- 	}
- 
- 	/*
--	 * If winbind is not around, we can not make much use of the SIDs the
--	 * domain controller provided us with. Likewise if the user name was
--	 * mapped to some local unix user.
-+	 * If the user name was mapped to some local unix user,
-+	 * we can not make much use of the SIDs the
-+	 * domain controller provided us with.
- 	 */
--
--	if (((lp_server_role() == ROLE_DOMAIN_MEMBER) && !winbind_ping()) ||
--	    (server_info->nss_token)) {
-+	if (server_info->nss_token) {
- 		char *found_username = NULL;
- 		status = create_token_from_username(session_info,
- 						    server_info->unix_name,
--- 
-2.33.1
-
-
-From 045a019e452c512224a13cfbd98c592cb7f2e912 Mon Sep 17 00:00:00 2001
-From: Alexander Bokovoy <ab@samba.org>
-Date: Wed, 11 Nov 2020 18:50:45 +0200
-Subject: [PATCH 30/39] CVE-2020-25717: Add FreeIPA domain controller role
-
-As we want to reduce use of 'classic domain controller' role but FreeIPA
-relies on it internally, add a separate role to mark FreeIPA domain
-controller role.
-
-It means that role won't result in ROLE_STANDALONE.
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
-
-Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>
-
-Signed-off-by: Alexander Bokovoy <ab@samba.org>
-Signed-off-by: Stefan Metzmacher <metze@samba.org>
-Reviewed-by: Andrew Bartlett <abartlet@samba.org>
----
- docs-xml/smbdotconf/security/serverrole.xml |  7 ++++
- lib/param/loadparm_server_role.c            |  2 ++
- lib/param/param_table.c                     |  1 +
- lib/param/util.c                            |  1 +
- libcli/netlogon/netlogon.c                  |  2 +-
- libds/common/roles.h                        |  1 +
- source3/auth/auth.c                         |  3 ++
- source3/auth/auth_sam.c                     | 14 ++++----
- source3/include/smb_macros.h                |  2 +-
- source3/lib/netapi/joindomain.c             |  1 +
- source3/param/loadparm.c                    |  4 ++-
- source3/passdb/lookup_sid.c                 |  2 +-
- source3/passdb/machine_account_secrets.c    |  7 ++--
- source3/registry/reg_backend_prod_options.c |  1 +
- source3/rpc_server/dssetup/srv_dssetup_nt.c |  1 +
- source3/smbd/server.c                       |  2 +-
- source3/winbindd/winbindd_misc.c            |  2 +-
- source3/winbindd/winbindd_util.c            | 40 ++++++++++++++++-----
- source4/auth/ntlm/auth.c                    |  1 +
- source4/kdc/kdc-heimdal.c                   |  1 +
- source4/rpc_server/samr/dcesrv_samr.c       |  2 ++
- 21 files changed, 72 insertions(+), 25 deletions(-)
-
-diff --git a/docs-xml/smbdotconf/security/serverrole.xml b/docs-xml/smbdotconf/security/serverrole.xml
-index 9511c61c96d..b8b83a127b5 100644
---- a/docs-xml/smbdotconf/security/serverrole.xml
-+++ b/docs-xml/smbdotconf/security/serverrole.xml
-@@ -78,6 +78,13 @@
-     url="http://wiki.samba.org/index.php/Samba4/HOWTO">Samba4
-     HOWTO</ulink></para>
- 
-+    <para><anchor id="IPA-DC"/><emphasis>SERVER ROLE = IPA DOMAIN CONTROLLER</emphasis></para>
-+
-+    <para>This mode of operation runs Samba in a hybrid mode for IPA
-+    domain controller, providing forest trust to Active Directory.
-+    This role requires special configuration performed by IPA installers
-+    and should not be used manually by any administrator.
-+    </para>
- </description>
- 
- <related>security</related>
-diff --git a/lib/param/loadparm_server_role.c b/lib/param/loadparm_server_role.c
-index 7a6bc770723..a78d1ab9cf3 100644
---- a/lib/param/loadparm_server_role.c
-+++ b/lib/param/loadparm_server_role.c
-@@ -42,6 +42,7 @@ static const struct srv_role_tab {
- 	{ ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
- 	{ ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
- 	{ ROLE_ACTIVE_DIRECTORY_DC, "ROLE_ACTIVE_DIRECTORY_DC" },
-+	{ ROLE_IPA_DC, "ROLE_IPA_DC"},
- 	{ 0, NULL }
- };
- 
-@@ -140,6 +141,7 @@ bool lp_is_security_and_server_role_valid(int server_role, int security)
- 	case ROLE_DOMAIN_PDC:
- 	case ROLE_DOMAIN_BDC:
- 	case ROLE_ACTIVE_DIRECTORY_DC:
-+	case ROLE_IPA_DC:
- 		if (security == SEC_USER) {
- 			valid = true;
- 		}
-diff --git a/lib/param/param_table.c b/lib/param/param_table.c
-index e2f737279dc..3dc5fc59991 100644
---- a/lib/param/param_table.c
-+++ b/lib/param/param_table.c
-@@ -111,6 +111,7 @@ static const struct enum_list enum_server_role[] = {
- 	{ROLE_ACTIVE_DIRECTORY_DC, "active directory domain controller"},
- 	{ROLE_ACTIVE_DIRECTORY_DC, "domain controller"},
- 	{ROLE_ACTIVE_DIRECTORY_DC, "dc"},
-+	{ROLE_IPA_DC, "IPA primary domain controller"},
- 	{-1, NULL}
- };
- 
-diff --git a/lib/param/util.c b/lib/param/util.c
-index cd8e74b9d8f..9a0fc102de8 100644
---- a/lib/param/util.c
-+++ b/lib/param/util.c
-@@ -255,6 +255,7 @@ const char *lpcfg_sam_name(struct loadparm_context *lp_ctx)
- 	case ROLE_DOMAIN_BDC:
- 	case ROLE_DOMAIN_PDC:
- 	case ROLE_ACTIVE_DIRECTORY_DC:
-+	case ROLE_IPA_DC:
- 		return lpcfg_workgroup(lp_ctx);
- 	default:
- 		return lpcfg_netbios_name(lp_ctx);
-diff --git a/libcli/netlogon/netlogon.c b/libcli/netlogon/netlogon.c
-index 239503e85b6..59af460dc4e 100644
---- a/libcli/netlogon/netlogon.c
-+++ b/libcli/netlogon/netlogon.c
-@@ -93,7 +93,7 @@ NTSTATUS pull_netlogon_samlogon_response(DATA_BLOB *data, TALLOC_CTX *mem_ctx,
- 		if (ndr->offset < ndr->data_size) {
- 			TALLOC_FREE(ndr);
- 			/*
--			 * We need to handle a bug in FreeIPA (at least <= 4.1.2).
-+			 * We need to handle a bug in IPA (at least <= 4.1.2).
- 			 *
- 			 * They include the ip address information without setting
- 			 * NETLOGON_NT_VERSION_5EX_WITH_IP, while using
-diff --git a/libds/common/roles.h b/libds/common/roles.h
-index 4772c8d7d3f..03ba1915b21 100644
---- a/libds/common/roles.h
-+++ b/libds/common/roles.h
-@@ -33,6 +33,7 @@ enum server_role {
- 	
- 	/* not in samr.idl */
- 	ROLE_ACTIVE_DIRECTORY_DC = 4,
-+	ROLE_IPA_DC = 5,
- 
- 	/* To determine the role automatically, this is not a valid role */
- 	ROLE_AUTO          = 100
-diff --git a/source3/auth/auth.c b/source3/auth/auth.c
-index 6d2a40f0f29..d0036ea6b30 100644
---- a/source3/auth/auth.c
-+++ b/source3/auth/auth.c
-@@ -543,6 +543,7 @@ NTSTATUS make_auth3_context_for_ntlm(TALLOC_CTX *mem_ctx,
- 		break;
- 	case ROLE_DOMAIN_BDC:
- 	case ROLE_DOMAIN_PDC:
-+	case ROLE_IPA_DC:
- 		role = "'DC'";
- 		methods = "anonymous sam winbind sam_ignoredomain";
- 		break;
-@@ -574,6 +575,7 @@ NTSTATUS make_auth3_context_for_netlogon(TALLOC_CTX *mem_ctx,
- 	switch (lp_server_role()) {
- 	case ROLE_DOMAIN_BDC:
- 	case ROLE_DOMAIN_PDC:
-+	case ROLE_IPA_DC:
- 		methods = "sam_netlogon3 winbind";
- 		break;
- 
-@@ -595,6 +597,7 @@ NTSTATUS make_auth3_context_for_winbind(TALLOC_CTX *mem_ctx,
- 	case ROLE_DOMAIN_MEMBER:
- 	case ROLE_DOMAIN_BDC:
- 	case ROLE_DOMAIN_PDC:
-+	case ROLE_IPA_DC:
- 		methods = "sam";
- 		break;
- 	case ROLE_ACTIVE_DIRECTORY_DC:
-diff --git a/source3/auth/auth_sam.c b/source3/auth/auth_sam.c
-index e8e0d543f8c..a2ce1013975 100644
---- a/source3/auth/auth_sam.c
-+++ b/source3/auth/auth_sam.c
-@@ -143,12 +143,13 @@ static NTSTATUS auth_samstrict_auth(const struct auth_context *auth_context,
- 			break;
- 		case ROLE_DOMAIN_PDC:
- 		case ROLE_DOMAIN_BDC:
-+		case ROLE_IPA_DC:
- 			if (!is_local_name && !is_my_domain) {
- 			       /* If we are running on a DC that has PASSDB module with domain
- 				* information, check if DNS forest name is matching the domain
--				* name. This is the case of FreeIPA domain controller when
--				* trusted AD DCs attempt to authenticate FreeIPA users using
--				* the forest root domain (which is the only domain in FreeIPA).
-+				* name. This is the case of IPA domain controller when
-+				* trusted AD DCs attempt to authenticate IPA users using
-+				* the forest root domain (which is the only domain in IPA).
- 				*/
- 				struct pdb_domain_info *dom_info = NULL;
- 
-@@ -234,6 +235,7 @@ static NTSTATUS auth_sam_netlogon3_auth(const struct auth_context *auth_context,
- 	switch (lp_server_role()) {
- 	case ROLE_DOMAIN_PDC:
- 	case ROLE_DOMAIN_BDC:
-+	case ROLE_IPA_DC:
- 		break;
- 	default:
- 		DBG_ERR("Invalid server role\n");
-@@ -252,9 +254,9 @@ static NTSTATUS auth_sam_netlogon3_auth(const struct auth_context *auth_context,
- 	if (!is_my_domain) {
- 	       /* If we are running on a DC that has PASSDB module with domain
- 		* information, check if DNS forest name is matching the domain
--		* name. This is the case of FreeIPA domain controller when
--		* trusted AD DCs attempt to authenticate FreeIPA users using
--		* the forest root domain (which is the only domain in FreeIPA).
-+		* name. This is the case of IPA domain controller when
-+		* trusted AD DCs attempt to authenticate IPA users using
-+		* the forest root domain (which is the only domain in IPA).
- 		*/
- 		struct pdb_domain_info *dom_info = NULL;
- 		dom_info = pdb_get_domain_info(mem_ctx);
-diff --git a/source3/include/smb_macros.h b/source3/include/smb_macros.h
-index d9583945c55..def122727f0 100644
---- a/source3/include/smb_macros.h
-+++ b/source3/include/smb_macros.h
-@@ -203,7 +203,7 @@ copy an IP address from one buffer to another
-  Check to see if we are a DC for this domain
- *****************************************************************************/
- 
--#define IS_DC  (lp_server_role()==ROLE_DOMAIN_PDC || lp_server_role()==ROLE_DOMAIN_BDC || lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) 
-+#define IS_DC  (lp_server_role()==ROLE_DOMAIN_PDC || lp_server_role()==ROLE_DOMAIN_BDC || lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC || lp_server_role() == ROLE_IPA_DC)
- #define IS_AD_DC  (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC)
- 
- /*
-diff --git a/source3/lib/netapi/joindomain.c b/source3/lib/netapi/joindomain.c
-index f2d36fc00db..d1710c4b938 100644
---- a/source3/lib/netapi/joindomain.c
-+++ b/source3/lib/netapi/joindomain.c
-@@ -375,6 +375,7 @@ WERROR NetGetJoinInformation_l(struct libnetapi_ctx *ctx,
- 		case ROLE_DOMAIN_MEMBER:
- 		case ROLE_DOMAIN_PDC:
- 		case ROLE_DOMAIN_BDC:
-+		case ROLE_IPA_DC:
- 			*r->out.name_type = NetSetupDomainName;
- 			break;
- 		case ROLE_STANDALONE:
-diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
-index 300b539748b..8bcd35f3d88 100644
---- a/source3/param/loadparm.c
-+++ b/source3/param/loadparm.c
-@@ -4412,6 +4412,7 @@ int lp_default_server_announce(void)
- 			default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
- 			break;
- 		case ROLE_DOMAIN_PDC:
-+		case ROLE_IPA_DC:
- 			default_server_announce |= SV_TYPE_DOMAIN_CTRL;
- 			break;
- 		case ROLE_DOMAIN_BDC:
-@@ -4437,7 +4438,8 @@ int lp_default_server_announce(void)
- bool lp_domain_master(void)
- {
- 	if (Globals._domain_master == Auto)
--		return (lp_server_role() == ROLE_DOMAIN_PDC);
-+		return (lp_server_role() == ROLE_DOMAIN_PDC ||
-+			lp_server_role() == ROLE_IPA_DC);
- 
- 	return (bool)Globals._domain_master;
- }
-diff --git a/source3/passdb/lookup_sid.c b/source3/passdb/lookup_sid.c
-index 0e01467b3cb..a551bcfd24a 100644
---- a/source3/passdb/lookup_sid.c
-+++ b/source3/passdb/lookup_sid.c
-@@ -121,7 +121,7 @@ bool lookup_name(TALLOC_CTX *mem_ctx,
- 
- 		/* If we are running on a DC that has PASSDB module with domain
- 		 * information, check if DNS forest name is matching the domain
--		 * name. This is the case of FreeIPA domain controller when
-+		 * name. This is the case of IPA domain controller when
- 		 * trusted AD DC looks up users found in a Global Catalog of
- 		 * the forest root domain. */
- 		if (!check_global_sam && (IS_DC)) {
-diff --git a/source3/passdb/machine_account_secrets.c b/source3/passdb/machine_account_secrets.c
-index d81f79c705b..618019b8322 100644
---- a/source3/passdb/machine_account_secrets.c
-+++ b/source3/passdb/machine_account_secrets.c
-@@ -198,7 +198,8 @@ bool secrets_fetch_domain_guid(const char *domain, struct GUID *guid)
- 	dyn_guid = (struct GUID *)secrets_fetch(key, &size);
- 
- 	if (!dyn_guid) {
--		if (lp_server_role() == ROLE_DOMAIN_PDC) {
-+		if (lp_server_role() == ROLE_DOMAIN_PDC ||
-+		    lp_server_role() == ROLE_IPA_DC) {
- 			new_guid = GUID_random();
- 			if (!secrets_store_domain_guid(domain, &new_guid))
- 				return False;
-@@ -314,9 +315,7 @@ static const char *trust_keystr(const char *domain)
- 
- enum netr_SchannelType get_default_sec_channel(void)
- {
--	if (lp_server_role() == ROLE_DOMAIN_BDC ||
--	    lp_server_role() == ROLE_DOMAIN_PDC ||
--	    lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
-+	if (IS_DC) {
- 		return SEC_CHAN_BDC;
- 	} else {
- 		return SEC_CHAN_WKSTA;
-diff --git a/source3/registry/reg_backend_prod_options.c b/source3/registry/reg_backend_prod_options.c
-index 655c587ac40..7bd3f324c37 100644
---- a/source3/registry/reg_backend_prod_options.c
-+++ b/source3/registry/reg_backend_prod_options.c
-@@ -40,6 +40,7 @@ static int prod_options_fetch_values(const char *key, struct regval_ctr *regvals
- 	switch (lp_server_role()) {
- 		case ROLE_DOMAIN_PDC:
- 		case ROLE_DOMAIN_BDC:
-+		case ROLE_IPA_DC:
- 			value_ascii = "LanmanNT";
- 			break;
- 		case ROLE_STANDALONE:
-diff --git a/source3/rpc_server/dssetup/srv_dssetup_nt.c b/source3/rpc_server/dssetup/srv_dssetup_nt.c
-index 64569382695..932452bc13b 100644
---- a/source3/rpc_server/dssetup/srv_dssetup_nt.c
-+++ b/source3/rpc_server/dssetup/srv_dssetup_nt.c
-@@ -63,6 +63,7 @@ static WERROR fill_dsrole_dominfo_basic(TALLOC_CTX *ctx,
- 			basic->domain = get_global_sam_name();
- 			break;
- 		case ROLE_DOMAIN_PDC:
-+		case ROLE_IPA_DC:
- 			basic->role = DS_ROLE_PRIMARY_DC;
- 			basic->domain = get_global_sam_name();
- 			break;
-diff --git a/source3/smbd/server.c b/source3/smbd/server.c
-index a0456100afe..26961fa6cf4 100644
---- a/source3/smbd/server.c
-+++ b/source3/smbd/server.c
-@@ -1979,7 +1979,7 @@ extern void build_options(bool screen);
- 		exit_daemon("smbd can not open secrets.tdb", EACCES);
- 	}
- 
--	if (lp_server_role() == ROLE_DOMAIN_BDC || lp_server_role() == ROLE_DOMAIN_PDC) {
-+	if (lp_server_role() == ROLE_DOMAIN_BDC || lp_server_role() == ROLE_DOMAIN_PDC || lp_server_role() == ROLE_IPA_DC) {
- 		struct loadparm_context *lp_ctx = loadparm_init_s3(NULL, loadparm_s3_helpers());
- 		if (!open_schannel_session_store(NULL, lp_ctx)) {
- 			exit_daemon("ERROR: Samba cannot open schannel store for secured NETLOGON operations.", EACCES);
-diff --git a/source3/winbindd/winbindd_misc.c b/source3/winbindd/winbindd_misc.c
-index 451ad6aee14..db7e1c87dee 100644
---- a/source3/winbindd/winbindd_misc.c
-+++ b/source3/winbindd/winbindd_misc.c
-@@ -76,7 +76,7 @@ static char *get_trust_type_string(TALLOC_CTX *mem_ctx,
- 	case SEC_CHAN_BDC: {
- 		int role = lp_server_role();
- 
--		if (role == ROLE_DOMAIN_PDC) {
-+		if (role == ROLE_DOMAIN_PDC || role == ROLE_IPA_DC) {
- 			s = talloc_strdup(mem_ctx, "PDC");
- 			if (s == NULL) {
- 				return NULL;
-diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c
-index ac4cd731c09..42ddbfd2f44 100644
---- a/source3/winbindd/winbindd_util.c
-+++ b/source3/winbindd/winbindd_util.c
-@@ -1254,15 +1254,37 @@ bool init_domain_list(void)
- 			secure_channel_type = SEC_CHAN_LOCAL;
- 		}
- 
--		status = add_trusted_domain(get_global_sam_name(),
--					    NULL,
--					    get_global_sam_sid(),
--					    LSA_TRUST_TYPE_DOWNLEVEL,
--					    trust_flags,
--					    0, /* trust_attribs */
--					    secure_channel_type,
--					    NULL,
--					    &domain);
-+		if ((pdb_domain_info != NULL) && (role == ROLE_IPA_DC)) {
-+			/* This is IPA DC that presents itself as
-+			 * an Active Directory domain controller to trusted AD
-+			 * forests but in fact is a classic domain controller.
-+			 */
-+			trust_flags = NETR_TRUST_FLAG_PRIMARY;
-+			trust_flags |= NETR_TRUST_FLAG_IN_FOREST;
-+			trust_flags |= NETR_TRUST_FLAG_NATIVE;
-+			trust_flags |= NETR_TRUST_FLAG_OUTBOUND;
-+			trust_flags |= NETR_TRUST_FLAG_TREEROOT;
-+			status = add_trusted_domain(pdb_domain_info->name,
-+						    pdb_domain_info->dns_domain,
-+						    &pdb_domain_info->sid,
-+						    LSA_TRUST_TYPE_UPLEVEL,
-+						    trust_flags,
-+						    LSA_TRUST_ATTRIBUTE_WITHIN_FOREST,
-+						    secure_channel_type,
-+						    NULL,
-+						    &domain);
-+			TALLOC_FREE(pdb_domain_info);
-+		} else {
-+			status = add_trusted_domain(get_global_sam_name(),
-+						    NULL,
-+						    get_global_sam_sid(),
-+						    LSA_TRUST_TYPE_DOWNLEVEL,
-+						    trust_flags,
-+						    0, /* trust_attribs */
-+						    secure_channel_type,
-+						    NULL,
-+						    &domain);
-+		}
- 		if (!NT_STATUS_IS_OK(status)) {
- 			DBG_ERR("Failed to add local SAM to "
- 				"domain to winbindd's internal list\n");
-diff --git a/source4/auth/ntlm/auth.c b/source4/auth/ntlm/auth.c
-index 4c66f2c23cb..ea9ff70ce80 100644
---- a/source4/auth/ntlm/auth.c
-+++ b/source4/auth/ntlm/auth.c
-@@ -737,6 +737,7 @@ const char **auth_methods_from_lp(TALLOC_CTX *mem_ctx, struct loadparm_context *
- 	case ROLE_DOMAIN_BDC:
- 	case ROLE_DOMAIN_PDC:
- 	case ROLE_ACTIVE_DIRECTORY_DC:
-+	case ROLE_IPA_DC:
- 		auth_methods = str_list_make(mem_ctx, "anonymous sam winbind sam_ignoredomain", NULL);
- 		break;
- 	}
-diff --git a/source4/kdc/kdc-heimdal.c b/source4/kdc/kdc-heimdal.c
-index a3c357ca1a6..ba74df4f2ec 100644
---- a/source4/kdc/kdc-heimdal.c
-+++ b/source4/kdc/kdc-heimdal.c
-@@ -276,6 +276,7 @@ static NTSTATUS kdc_task_init(struct task_server *task)
- 		return NT_STATUS_INVALID_DOMAIN_ROLE;
- 	case ROLE_DOMAIN_PDC:
- 	case ROLE_DOMAIN_BDC:
-+	case ROLE_IPA_DC:
- 		task_server_terminate(
- 		    task, "Cannot start KDC as a 'classic Samba' DC", false);
- 		return NT_STATUS_INVALID_DOMAIN_ROLE;
-diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c
-index cda887d45ee..29c509522be 100644
---- a/source4/rpc_server/samr/dcesrv_samr.c
-+++ b/source4/rpc_server/samr/dcesrv_samr.c
-@@ -575,6 +575,7 @@ static NTSTATUS dcesrv_samr_info_DomGeneralInformation(struct samr_domain_state
- 		break;
- 	case ROLE_DOMAIN_PDC:
- 	case ROLE_DOMAIN_BDC:
-+	case ROLE_IPA_DC:
- 	case ROLE_AUTO:
- 		return NT_STATUS_INTERNAL_ERROR;
- 	case ROLE_DOMAIN_MEMBER:
-@@ -723,6 +724,7 @@ static NTSTATUS dcesrv_samr_info_DomInfo7(struct samr_domain_state *state,
- 		break;
- 	case ROLE_DOMAIN_PDC:
- 	case ROLE_DOMAIN_BDC:
-+	case ROLE_IPA_DC:
- 	case ROLE_AUTO:
- 		return NT_STATUS_INTERNAL_ERROR;
- 	case ROLE_DOMAIN_MEMBER:
--- 
-2.33.1
-
-
-From 4b3a3fa914b79c548100eda1baa5c589fd8f04bf Mon Sep 17 00:00:00 2001
-From: Stefan Metzmacher <metze@samba.org>
-Date: Tue, 5 Oct 2021 18:11:57 +0200
-Subject: [PATCH 31/39] CVE-2020-25719 CVE-2020-25717: auth/gensec: always
- require a PAC in domain mode (DC or member)
-
-AD domains always provide a PAC unless UF_NO_AUTH_DATA_REQUIRED is set
-on the service account, which can only be explicitly configured,
-but that's an invalid configuration!
-
-We still try to support standalone servers in an MIT realm,
-as legacy setup.
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
-
-Signed-off-by: Stefan Metzmacher <metze@samba.org>
-Reviewed-by: Andrew Bartlett <abartlet@samba.org>
-
-[jsutton@samba.org Removed knownfail entries]
----
- auth/gensec/gensec_util.c | 27 +++++++++++++++++++++++----
- 1 file changed, 23 insertions(+), 4 deletions(-)
-
-diff --git a/auth/gensec/gensec_util.c b/auth/gensec/gensec_util.c
-index e185acc0c20..694661b53b5 100644
---- a/auth/gensec/gensec_util.c
-+++ b/auth/gensec/gensec_util.c
-@@ -25,6 +25,8 @@
- #include "auth/gensec/gensec_internal.h"
- #include "auth/common_auth.h"
- #include "../lib/util/asn1.h"
-+#include "param/param.h"
-+#include "libds/common/roles.h"
- 
- #undef DBGC_CLASS
- #define DBGC_CLASS DBGC_AUTH
-@@ -46,10 +48,27 @@ NTSTATUS gensec_generate_session_info_pac(TALLOC_CTX *mem_ctx,
- 	session_info_flags |= AUTH_SESSION_INFO_DEFAULT_GROUPS;
- 
- 	if (!pac_blob) {
--		if (gensec_setting_bool(gensec_security->settings, "gensec", "require_pac", false)) {
--			DEBUG(1, ("Unable to find PAC in ticket from %s, failing to allow access\n",
--				  principal_string));
--			return NT_STATUS_ACCESS_DENIED;
-+		enum server_role server_role =
-+			lpcfg_server_role(gensec_security->settings->lp_ctx);
-+
-+		/*
-+		 * For any domain setup (DC or member) we require having
-+		 * a PAC, as the service ticket comes from an AD DC,
-+		 * which will always provide a PAC, unless
-+		 * UF_NO_AUTH_DATA_REQUIRED is configured for our
-+		 * account, but that's just an invalid configuration,
-+		 * the admin configured for us!
-+		 *
-+		 * As a legacy case, we still allow kerberos tickets from an MIT
-+		 * realm, but only in standalone mode. In that mode we'll only
-+		 * ever accept a kerberos authentication with a keytab file
-+		 * being explicitly configured via the 'keytab method' option.
-+		 */
-+		if (server_role != ROLE_STANDALONE) {
-+			DBG_WARNING("Unable to find PAC in ticket from %s, "
-+				    "failing to allow access\n",
-+				    principal_string);
-+			return NT_STATUS_NO_IMPERSONATION_TOKEN;
- 		}
- 		DBG_NOTICE("Unable to find PAC for %s, resorting to local "
- 			   "user lookup\n", principal_string);
--- 
-2.33.1
-
-
-From 5b7e9cc45370601553e464e539d0243eeec98659 Mon Sep 17 00:00:00 2001
-From: Stefan Metzmacher <metze@samba.org>
-Date: Mon, 11 Oct 2021 23:17:19 +0200
-Subject: [PATCH 32/39] CVE-2020-25719 CVE-2020-25717: s4:auth: remove unused
- auth_generate_session_info_principal()
-
-We'll require a PAC at the main gensec layer already.
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
-
-Signed-off-by: Stefan Metzmacher <metze@samba.org>
-Reviewed-by: Andrew Bartlett <abartlet@samba.org>
----
- source4/auth/auth.h          |  8 ------
- source4/auth/ntlm/auth.c     | 49 ++++--------------------------------
- source4/auth/ntlm/auth_sam.c | 12 ---------
- 3 files changed, 5 insertions(+), 64 deletions(-)
-
-diff --git a/source4/auth/auth.h b/source4/auth/auth.h
-index 3f9fb1ae3cb..6b7db99cbe2 100644
---- a/source4/auth/auth.h
-+++ b/source4/auth/auth.h
-@@ -69,14 +69,6 @@ struct auth_operations {
- 				TALLOC_CTX *mem_ctx,
- 				struct auth_user_info_dc **interim_info,
- 				bool *authoritative);
--
--	/* Lookup a 'session info interim' return based only on the principal or DN */
--	NTSTATUS (*get_user_info_dc_principal)(TALLOC_CTX *mem_ctx,
--						       struct auth4_context *auth_context,
--						       const char *principal,
--						       struct ldb_dn *user_dn,
--						       struct auth_user_info_dc **interim_info);
--	uint32_t flags;
- };
- 
- struct auth_method_context {
-diff --git a/source4/auth/ntlm/auth.c b/source4/auth/ntlm/auth.c
-index ea9ff70ce80..3dd2ffc9276 100644
---- a/source4/auth/ntlm/auth.c
-+++ b/source4/auth/ntlm/auth.c
-@@ -86,48 +86,6 @@ _PUBLIC_ NTSTATUS auth_get_challenge(struct auth4_context *auth_ctx, uint8_t cha
- 	return NT_STATUS_OK;
- }
- 
--/****************************************************************************
--Used in the gensec_gssapi and gensec_krb5 server-side code, where the
--PAC isn't available, and for tokenGroups in the DSDB stack.
--
-- Supply either a principal or a DN
--****************************************************************************/
--static NTSTATUS auth_generate_session_info_principal(struct auth4_context *auth_ctx,
--						  TALLOC_CTX *mem_ctx,
--						  const char *principal,
--						  struct ldb_dn *user_dn,
--                                                  uint32_t session_info_flags,
--                                                  struct auth_session_info **session_info)
--{
--	NTSTATUS nt_status;
--	struct auth_method_context *method;
--	struct auth_user_info_dc *user_info_dc;
--
--	for (method = auth_ctx->methods; method; method = method->next) {
--		if (!method->ops->get_user_info_dc_principal) {
--			continue;
--		}
--
--		nt_status = method->ops->get_user_info_dc_principal(mem_ctx, auth_ctx, principal, user_dn, &user_info_dc);
--		if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NOT_IMPLEMENTED)) {
--			continue;
--		}
--		if (!NT_STATUS_IS_OK(nt_status)) {
--			return nt_status;
--		}
--
--		nt_status = auth_generate_session_info_wrapper(auth_ctx, mem_ctx, 
--							       user_info_dc,
--							       user_info_dc->info->account_name,
--							       session_info_flags, session_info);
--		talloc_free(user_info_dc);
--
--		return nt_status;
--	}
--
--	return NT_STATUS_NOT_IMPLEMENTED;
--}
--
- /**
-  * Check a user's Plaintext, LM or NTLM password.
-  * (sync version)
-@@ -627,8 +585,11 @@ static NTSTATUS auth_generate_session_info_pac(struct auth4_context *auth_ctx,
- 	TALLOC_CTX *tmp_ctx;
- 
- 	if (!pac_blob) {
--		return auth_generate_session_info_principal(auth_ctx, mem_ctx, principal_name,
--						       NULL, session_info_flags, session_info);
-+		/*
-+		 * This should already be catched at the main
-+		 * gensec layer, but better check twice
-+		 */
-+		return NT_STATUS_INTERNAL_ERROR;
- 	}
- 
- 	tmp_ctx = talloc_named(mem_ctx, 0, "gensec_gssapi_session_info context");
-diff --git a/source4/auth/ntlm/auth_sam.c b/source4/auth/ntlm/auth_sam.c
-index a521bc94bc4..dbbf97665db 100644
---- a/source4/auth/ntlm/auth_sam.c
-+++ b/source4/auth/ntlm/auth_sam.c
-@@ -938,22 +938,11 @@ static NTSTATUS authsam_want_check(struct auth_method_context *ctx,
- 	return NT_STATUS_OK;
- }
- 
--/* Wrapper for the auth subsystem pointer */
--static NTSTATUS authsam_get_user_info_dc_principal_wrapper(TALLOC_CTX *mem_ctx,
--							  struct auth4_context *auth_context,
--							  const char *principal,
--							  struct ldb_dn *user_dn,
--							  struct auth_user_info_dc **user_info_dc)
--{
--	return authsam_get_user_info_dc_principal(mem_ctx, auth_context->lp_ctx, auth_context->sam_ctx,
--						 principal, user_dn, user_info_dc);
--}
- static const struct auth_operations sam_ignoredomain_ops = {
- 	.name		           = "sam_ignoredomain",
- 	.want_check	           = authsam_ignoredomain_want_check,
- 	.check_password_send	   = authsam_check_password_send,
- 	.check_password_recv	   = authsam_check_password_recv,
--	.get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper,
- };
- 
- static const struct auth_operations sam_ops = {
-@@ -961,7 +950,6 @@ static const struct auth_operations sam_ops = {
- 	.want_check	           = authsam_want_check,
- 	.check_password_send	   = authsam_check_password_send,
- 	.check_password_recv	   = authsam_check_password_recv,
--	.get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper,
- };
- 
- _PUBLIC_ NTSTATUS auth4_sam_init(TALLOC_CTX *);
--- 
-2.33.1
-
-
-From 85914f7dbe62cb0092f106ee89a4cff46b91fb3e Mon Sep 17 00:00:00 2001
-From: Stefan Metzmacher <metze@samba.org>
-Date: Tue, 21 Sep 2021 12:27:28 +0200
-Subject: [PATCH 33/39] CVE-2020-25717: s3:ntlm_auth: fix memory leaks in
- ntlm_auth_generate_session_info_pac()
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
-
-Signed-off-by: Stefan Metzmacher <metze@samba.org>
-Reviewed-by: Andrew Bartlett <abartlet@samba.org>
----
- source3/utils/ntlm_auth.c | 18 ++++++++++++------
- 1 file changed, 12 insertions(+), 6 deletions(-)
-
-diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c
-index b3ab3a473bf..16431771e74 100644
---- a/source3/utils/ntlm_auth.c
-+++ b/source3/utils/ntlm_auth.c
-@@ -818,23 +818,27 @@ static NTSTATUS ntlm_auth_generate_session_info_pac(struct auth4_context *auth_c
- 	if (!p) {
- 		DEBUG(3, ("[%s] Doesn't look like a valid principal\n",
- 			  princ_name));
--		return NT_STATUS_LOGON_FAILURE;
-+		status = NT_STATUS_LOGON_FAILURE;
-+		goto done;
- 	}
- 
- 	user = talloc_strndup(mem_ctx, princ_name, p - princ_name);
- 	if (!user) {
--		return NT_STATUS_NO_MEMORY;
-+		status = NT_STATUS_NO_MEMORY;
-+		goto done;
- 	}
- 
- 	realm = talloc_strdup(talloc_tos(), p + 1);
- 	if (!realm) {
--		return NT_STATUS_NO_MEMORY;
-+		status = NT_STATUS_NO_MEMORY;
-+		goto done;
- 	}
- 
- 	if (!strequal(realm, lp_realm())) {
- 		DEBUG(3, ("Ticket for foreign realm %s@%s\n", user, realm));
- 		if (!lp_allow_trusted_domains()) {
--			return NT_STATUS_LOGON_FAILURE;
-+			status = NT_STATUS_LOGON_FAILURE;
-+			goto done;
- 		}
- 	}
- 
-@@ -842,7 +846,8 @@ static NTSTATUS ntlm_auth_generate_session_info_pac(struct auth4_context *auth_c
- 		domain = talloc_strdup(mem_ctx,
- 					logon_info->info3.base.logon_domain.string);
- 		if (!domain) {
--			return NT_STATUS_NO_MEMORY;
-+			status = NT_STATUS_NO_MEMORY;
-+			goto done;
- 		}
- 		DEBUG(10, ("Domain is [%s] (using PAC)\n", domain));
- 	} else {
-@@ -872,7 +877,8 @@ static NTSTATUS ntlm_auth_generate_session_info_pac(struct auth4_context *auth_c
- 			domain = talloc_strdup(mem_ctx, realm);
- 		}
- 		if (!domain) {
--			return NT_STATUS_NO_MEMORY;
-+			status = NT_STATUS_NO_MEMORY;
-+			goto done;
- 		}
- 		DEBUG(10, ("Domain is [%s] (using Winbind)\n", domain));
- 	}
--- 
-2.33.1
-
-
-From 128802ff973fd3a3089e672f7d81c517a779c6be Mon Sep 17 00:00:00 2001
-From: Stefan Metzmacher <metze@samba.org>
-Date: Tue, 21 Sep 2021 12:44:01 +0200
-Subject: [PATCH 34/39] CVE-2020-25717: s3:ntlm_auth: let
- ntlm_auth_generate_session_info_pac() base the name on the PAC LOGON_INFO
- only
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
-
-Signed-off-by: Stefan Metzmacher <metze@samba.org>
-Reviewed-by: Andrew Bartlett <abartlet@samba.org>
----
- source3/utils/ntlm_auth.c | 91 ++++++++++++---------------------------
- 1 file changed, 28 insertions(+), 63 deletions(-)
-
-diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c
-index 16431771e74..02a23792890 100644
---- a/source3/utils/ntlm_auth.c
-+++ b/source3/utils/ntlm_auth.c
-@@ -790,10 +790,8 @@ static NTSTATUS ntlm_auth_generate_session_info_pac(struct auth4_context *auth_c
- 	struct PAC_LOGON_INFO *logon_info = NULL;
- 	char *unixuser;
- 	NTSTATUS status;
--	char *domain = NULL;
--	char *realm = NULL;
--	char *user = NULL;
--	char *p;
-+	const char *domain = "";
-+	const char *user = "";
- 
- 	tmp_ctx = talloc_new(mem_ctx);
- 	if (!tmp_ctx) {
-@@ -810,79 +808,46 @@ static NTSTATUS ntlm_auth_generate_session_info_pac(struct auth4_context *auth_c
- 		if (!NT_STATUS_IS_OK(status)) {
- 			goto done;
- 		}
--	}
--
--	DEBUG(3, ("Kerberos ticket principal name is [%s]\n", princ_name));
--
--	p = strchr_m(princ_name, '@');
--	if (!p) {
--		DEBUG(3, ("[%s] Doesn't look like a valid principal\n",
--			  princ_name));
--		status = NT_STATUS_LOGON_FAILURE;
-+	} else {
-+		status = NT_STATUS_ACCESS_DENIED;
-+		DBG_WARNING("Kerberos ticket for[%s] has no PAC: %s\n",
-+			    princ_name, nt_errstr(status));
- 		goto done;
- 	}
- 
--	user = talloc_strndup(mem_ctx, princ_name, p - princ_name);
--	if (!user) {
--		status = NT_STATUS_NO_MEMORY;
--		goto done;
-+	if (logon_info->info3.base.account_name.string != NULL) {
-+		user = logon_info->info3.base.account_name.string;
-+	} else {
-+		user = "";
-+	}
-+	if (logon_info->info3.base.logon_domain.string != NULL) {
-+		domain = logon_info->info3.base.logon_domain.string;
-+	} else {
-+		domain = "";
- 	}
- 
--	realm = talloc_strdup(talloc_tos(), p + 1);
--	if (!realm) {
--		status = NT_STATUS_NO_MEMORY;
-+	if (strlen(user) == 0 || strlen(domain) == 0) {
-+		status = NT_STATUS_ACCESS_DENIED;
-+		DBG_WARNING("Kerberos ticket for[%s] has invalid "
-+			    "account_name[%s]/logon_domain[%s]: %s\n",
-+			    princ_name,
-+			    logon_info->info3.base.account_name.string,
-+			    logon_info->info3.base.logon_domain.string,
-+			    nt_errstr(status));
- 		goto done;
- 	}
- 
--	if (!strequal(realm, lp_realm())) {
--		DEBUG(3, ("Ticket for foreign realm %s@%s\n", user, realm));
-+	DBG_NOTICE("Kerberos ticket principal name is [%s] "
-+		   "account_name[%s]/logon_domain[%s]\n",
-+		   princ_name, user, domain);
-+
-+	if (!strequal(domain, lp_workgroup())) {
- 		if (!lp_allow_trusted_domains()) {
- 			status = NT_STATUS_LOGON_FAILURE;
- 			goto done;
- 		}
- 	}
- 
--	if (logon_info && logon_info->info3.base.logon_domain.string) {
--		domain = talloc_strdup(mem_ctx,
--					logon_info->info3.base.logon_domain.string);
--		if (!domain) {
--			status = NT_STATUS_NO_MEMORY;
--			goto done;
--		}
--		DEBUG(10, ("Domain is [%s] (using PAC)\n", domain));
--	} else {
--
--		/* If we have winbind running, we can (and must) shorten the
--		   username by using the short netbios name. Otherwise we will
--		   have inconsistent user names. With Kerberos, we get the
--		   fully qualified realm, with ntlmssp we get the short
--		   name. And even w2k3 does use ntlmssp if you for example
--		   connect to an ip address. */
--
--		wbcErr wbc_status;
--		struct wbcDomainInfo *info = NULL;
--
--		DEBUG(10, ("Mapping [%s] to short name using winbindd\n",
--			   realm));
--
--		wbc_status = wbcDomainInfo(realm, &info);
--
--		if (WBC_ERROR_IS_OK(wbc_status)) {
--			domain = talloc_strdup(mem_ctx,
--						info->short_name);
--			wbcFreeMemory(info);
--		} else {
--			DEBUG(3, ("Could not find short name: %s\n",
--				  wbcErrorString(wbc_status)));
--			domain = talloc_strdup(mem_ctx, realm);
--		}
--		if (!domain) {
--			status = NT_STATUS_NO_MEMORY;
--			goto done;
--		}
--		DEBUG(10, ("Domain is [%s] (using Winbind)\n", domain));
--	}
--
- 	unixuser = talloc_asprintf(tmp_ctx, "%s%c%s", domain, winbind_separator(), user);
- 	if (!unixuser) {
- 		status = NT_STATUS_NO_MEMORY;
--- 
-2.33.1
-
-
-From e9063c114461ac82c5db3fa32f59b57a87be65be Mon Sep 17 00:00:00 2001
-From: Stefan Metzmacher <metze@samba.org>
-Date: Mon, 4 Oct 2021 19:42:20 +0200
-Subject: [PATCH 35/39] CVE-2020-25717: s3:auth: let
- auth3_generate_session_info_pac() delegate everything to
- make_server_info_wbcAuthUserInfo()
-
-This consolidates the code paths used for NTLMSSP and Kerberos!
-
-I checked what we were already doing for NTLMSSP, which is this:
-
-a) source3/auth/auth_winbind.c calls wbcAuthenticateUserEx()
-b) as a domain member we require a valid response from winbindd,
-   otherwise we'll return NT_STATUS_NO_LOGON_SERVERS
-c) we call make_server_info_wbcAuthUserInfo(), which internally
-   calls make_server_info_info3()
-d) auth_check_ntlm_password() calls
-   smb_pam_accountcheck(unix_username, rhost), where rhost
-   is only an ipv4 or ipv6 address (without reverse dns lookup)
-e) from auth3_check_password_send/auth3_check_password_recv()
-   server_returned_info will be passed to auth3_generate_session_info(),
-   triggered by gensec_session_info(), which means we'll call into
-   create_local_token() in order to transform auth_serversupplied_info
-   into auth_session_info.
-
-For Kerberos gensec_session_info() will call
-auth3_generate_session_info_pac() via the gensec_generate_session_info_pac()
-helper function. The current logic is this:
-
-a) gensec_generate_session_info_pac() is the function that
-   evaluates the 'gensec:require_pac', which defaulted to 'no'
-   before.
-b) auth3_generate_session_info_pac() called
-   wbcAuthenticateUserEx() in order to pass the PAC blob
-   to winbindd, but only to prime its cache, e.g. netsamlogon cache
-   and others. Most failures were just ignored.
-c) If the PAC blob is available, it extracted the PAC_LOGON_INFO
-   from it.
-d) Then we called the horrible get_user_from_kerberos_info() function:
-   - It uses a first part of the tickets principal name (before the @)
-     as username and combines that with the 'logon_info->base.logon_domain'
-     if the logon_info (PAC) is present.
-   - As a fallback without a PAC it's tries to ask winbindd for a mapping
-     from realm to netbios domain name.
-   - Finally is falls back to using the realm as netbios domain name
-   With this information is builds 'userdomain+winbind_separator+useraccount'
-   and calls map_username() followed by smb_getpwnam() with create=true,
-   Note this is similar to the make_server_info_info3() => check_account()
-   => smb_getpwnam() logic under 3.
-   - It also calls smb_pam_accountcheck(), but may pass the reverse DNS lookup name
-     instead of the ip address as rhost.
-   - It does some MAP_TO_GUEST_ON_BAD_UID logic and auto creates the
-     guest account.
-e) We called create_info3_from_pac_logon_info()
-f) make_session_info_krb5() calls gets called and triggers this:
-   - If get_user_from_kerberos_info() mapped to guest, it calls
-     make_server_info_guest()
-   - If create_info3_from_pac_logon_info() created a info3 from logon_info,
-     it calls make_server_info_info3()
-   - Without a PAC it tries pdb_getsampwnam()/make_server_info_sam() with
-     a fallback to make_server_info_pw()
-   From there it calls create_local_token()
-
-I tried to change auth3_generate_session_info_pac() to behave similar
-to auth_winbind.c together with auth3_generate_session_info() as
-a domain member, as we now rely on a PAC:
-
-a) As domain member we require a PAC and always call wbcAuthenticateUserEx()
-   and require a valid response!
-b) we call make_server_info_wbcAuthUserInfo(), which internally
-   calls make_server_info_info3(). Note make_server_info_info3()
-   handles MAP_TO_GUEST_ON_BAD_UID and make_server_info_guest()
-   internally.
-c) Similar to auth_check_ntlm_password() we now call
-   smb_pam_accountcheck(unix_username, rhost), where rhost
-   is only an ipv4 or ipv6 address (without reverse dns lookup)
-d) From there it calls create_local_token()
-
-As standalone server (in an MIT realm) we continue
-with the already existing code logic, which works without a PAC:
-a) we keep smb_getpwnam() with create=true logic as it
-   also requires an explicit 'add user script' option.
-b) In the following commits we assert that there's
-   actually no PAC in this mode, which means we can
-   remove unused and confusing code.
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14646
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
-
-Signed-off-by: Stefan Metzmacher <metze@samba.org>
-Reviewed-by: Andrew Bartlett <abartlet@samba.org>
----
- source3/auth/auth_generic.c | 137 ++++++++++++++++++++++++++++--------
- 1 file changed, 109 insertions(+), 28 deletions(-)
-
-diff --git a/source3/auth/auth_generic.c b/source3/auth/auth_generic.c
-index f6a501f1df7..a8390b1b156 100644
---- a/source3/auth/auth_generic.c
-+++ b/source3/auth/auth_generic.c
-@@ -46,6 +46,7 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx,
- 						uint32_t session_info_flags,
- 						struct auth_session_info **session_info)
- {
-+	enum server_role server_role = lp_server_role();
- 	TALLOC_CTX *tmp_ctx;
- 	struct PAC_LOGON_INFO *logon_info = NULL;
- 	struct netr_SamInfo3 *info3_copy = NULL;
-@@ -54,39 +55,59 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx,
- 	char *ntuser;
- 	char *ntdomain;
- 	char *username;
--	char *rhost;
-+	const char *rhost;
- 	struct passwd *pw;
- 	NTSTATUS status;
--	int rc;
- 
- 	tmp_ctx = talloc_new(mem_ctx);
- 	if (!tmp_ctx) {
- 		return NT_STATUS_NO_MEMORY;
- 	}
- 
--	if (pac_blob) {
--#ifdef HAVE_KRB5
-+	if (tsocket_address_is_inet(remote_address, "ip")) {
-+		rhost = tsocket_address_inet_addr_string(
-+			remote_address, tmp_ctx);
-+		if (rhost == NULL) {
-+			status = NT_STATUS_NO_MEMORY;
-+			goto done;
-+		}
-+	} else {
-+		rhost = "127.0.0.1";
-+	}
-+
-+	if (server_role != ROLE_STANDALONE) {
- 		struct wbcAuthUserParams params = { 0 };
- 		struct wbcAuthUserInfo *info = NULL;
- 		struct wbcAuthErrorInfo *err = NULL;
-+		struct auth_serversupplied_info *server_info = NULL;
-+		char *original_user_name = NULL;
-+		char *p = NULL;
- 		wbcErr wbc_err;
- 
-+		if (pac_blob == NULL) {
-+			/*
-+			 * This should already be catched at the main
-+			 * gensec layer, but better check twice
-+			 */
-+			status = NT_STATUS_INTERNAL_ERROR;
-+			goto done;
-+		}
-+
- 		/*
- 		 * Let winbind decode the PAC.
- 		 * This will also store the user
- 		 * data in the netsamlogon cache.
- 		 *
--		 * We need to do this *before* we
--		 * call get_user_from_kerberos_info()
--		 * as that does a user lookup that
--		 * expects info in the netsamlogon cache.
--		 *
--		 * See BUG: https://bugzilla.samba.org/show_bug.cgi?id=11259
-+		 * This used to be a cache prime
-+		 * optimization, but now we delegate
-+		 * all logic to winbindd, as we require
-+		 * winbindd as domain member anyway.
- 		 */
- 		params.level = WBC_AUTH_USER_LEVEL_PAC;
- 		params.password.pac.data = pac_blob->data;
- 		params.password.pac.length = pac_blob->length;
- 
-+		/* we are contacting the privileged pipe */
- 		become_root();
- 		wbc_err = wbcAuthenticateUserEx(&params, &info, &err);
- 		unbecome_root();
-@@ -99,18 +120,90 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx,
- 		 */
- 
- 		switch (wbc_err) {
--			case WBC_ERR_WINBIND_NOT_AVAILABLE:
- 			case WBC_ERR_SUCCESS:
- 				break;
-+			case WBC_ERR_WINBIND_NOT_AVAILABLE:
-+				status = NT_STATUS_NO_LOGON_SERVERS;
-+				DBG_ERR("winbindd not running - "
-+					"but required as domain member: %s\n",
-+					nt_errstr(status));
-+				goto done;
- 			case WBC_ERR_AUTH_ERROR:
- 				status = NT_STATUS(err->nt_status);
- 				wbcFreeMemory(err);
- 				goto done;
-+			case WBC_ERR_NO_MEMORY:
-+				status = NT_STATUS_NO_MEMORY;
-+				goto done;
- 			default:
- 				status = NT_STATUS_LOGON_FAILURE;
- 				goto done;
- 		}
- 
-+		status = make_server_info_wbcAuthUserInfo(tmp_ctx,
-+							  info->account_name,
-+							  info->domain_name,
-+							  info, &server_info);
-+		if (!NT_STATUS_IS_OK(status)) {
-+			DEBUG(10, ("make_server_info_wbcAuthUserInfo failed: %s\n",
-+				   nt_errstr(status)));
-+			goto done;
-+		}
-+
-+		/* We skip doing this step if the caller asked us not to */
-+		if (!(server_info->guest)) {
-+			const char *unix_username = server_info->unix_name;
-+
-+			/* We might not be root if we are an RPC call */
-+			become_root();
-+			status = smb_pam_accountcheck(unix_username, rhost);
-+			unbecome_root();
-+
-+			if (!NT_STATUS_IS_OK(status)) {
-+				DEBUG(3, ("check_ntlm_password:  PAM Account for user [%s] "
-+					  "FAILED with error %s\n",
-+					  unix_username, nt_errstr(status)));
-+				goto done;
-+			}
-+
-+			DEBUG(5, ("check_ntlm_password:  PAM Account for user [%s] "
-+				  "succeeded\n", unix_username));
-+		}
-+
-+		DEBUG(3, ("Kerberos ticket principal name is [%s]\n", princ_name));
-+
-+		p = strchr_m(princ_name, '@');
-+		if (!p) {
-+			DEBUG(3, ("[%s] Doesn't look like a valid principal\n",
-+				  princ_name));
-+			status = NT_STATUS_LOGON_FAILURE;
-+			goto done;
-+		}
-+
-+		original_user_name = talloc_strndup(tmp_ctx, princ_name, p - princ_name);
-+		if (original_user_name == NULL) {
-+			status = NT_STATUS_NO_MEMORY;
-+			goto done;
-+		}
-+
-+		status = create_local_token(mem_ctx,
-+					    server_info,
-+					    NULL,
-+					    original_user_name,
-+					    session_info);
-+		if (!NT_STATUS_IS_OK(status)) {
-+			DEBUG(10, ("create_local_token failed: %s\n",
-+				   nt_errstr(status)));
-+			goto done;
-+		}
-+
-+		goto session_info_ready;
-+	}
-+
-+	/* This is the standalone legacy code path */
-+
-+	if (pac_blob != NULL) {
-+#ifdef HAVE_KRB5
- 		status = kerberos_pac_logon_info(tmp_ctx, *pac_blob, NULL, NULL,
- 						 NULL, NULL, 0, &logon_info);
- #else
-@@ -121,22 +214,6 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx,
- 		}
- 	}
- 
--	rc = get_remote_hostname(remote_address,
--				 &rhost,
--				 tmp_ctx);
--	if (rc < 0) {
--		status = NT_STATUS_NO_MEMORY;
--		goto done;
--	}
--	if (strequal(rhost, "UNKNOWN")) {
--		rhost = tsocket_address_inet_addr_string(remote_address,
--							 tmp_ctx);
--		if (rhost == NULL) {
--			status = NT_STATUS_NO_MEMORY;
--			goto done;
--		}
--	}
--
- 	status = get_user_from_kerberos_info(tmp_ctx, rhost,
- 					     princ_name, logon_info,
- 					     &is_mapped, &is_guest,
-@@ -170,6 +247,8 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx,
- 		goto done;
- 	}
- 
-+session_info_ready:
-+
- 	/* setup the string used by %U */
- 	set_current_user_info((*session_info)->unix_info->sanitized_username,
- 			      (*session_info)->unix_info->unix_name,
-@@ -179,7 +258,9 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx,
- 	lp_load_with_shares(get_dyn_CONFIGFILE());
- 
- 	DEBUG(5, (__location__ "OK: user: %s domain: %s client: %s\n",
--		  ntuser, ntdomain, rhost));
-+		  (*session_info)->info->account_name,
-+		  (*session_info)->info->domain_name,
-+		  rhost));
- 
- 	status = NT_STATUS_OK;
- 
--- 
-2.33.1
-
-
-From a05d4ea28d68fda457c12a66052cb3712939279a Mon Sep 17 00:00:00 2001
-From: Stefan Metzmacher <metze@samba.org>
-Date: Tue, 5 Oct 2021 17:14:01 +0200
-Subject: [PATCH 36/39] CVE-2020-25717: selftest: configure 'ktest' env with
- winbindd and idmap_autorid
-
-The 'ktest' environment was/is designed to test kerberos in an active
-directory member setup. It was created at a time we wanted to test
-smbd/winbindd with kerberos without having the source4 ad dc available.
-
-This still applies to testing the build with system krb5 libraries
-but without relying on a running ad dc.
-
-As a domain member setup requires a running winbindd, we should test it
-that way, in order to reflect a valid setup.
-
-As a side effect it provides a way to demonstrate that we can accept
-smb connections authenticated via kerberos, but no connection to
-a domain controller! In order get this working offline, we need an
-idmap backend with ID_TYPE_BOTH support, so we use 'autorid', which
-should be the default choice.
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14646
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
-
-Signed-off-by: Stefan Metzmacher <metze@samba.org>
-Reviewed-by: Andrew Bartlett <abartlet@samba.org>
----
- selftest/knownfail.d/ktest | 26 --------------------------
- selftest/target/Samba3.pm  | 12 +++++-------
- 2 files changed, 5 insertions(+), 33 deletions(-)
- delete mode 100644 selftest/knownfail.d/ktest
-
-diff --git a/selftest/knownfail.d/ktest b/selftest/knownfail.d/ktest
-deleted file mode 100644
-index 809612ba0b9..00000000000
---- a/selftest/knownfail.d/ktest
-+++ /dev/null
-@@ -1,26 +0,0 @@
--^samba3.rpc.lsa.lookupsids.krb5.with.old.ccache.ncacn_np.with..smb2...lsa.LookupSidsReply.ktest
--^samba3.rpc.lsa.lookupsids.krb5.ncacn_np.with..smb2...lsa.LookupSidsReply.ktest
--^samba3.blackbox.rpcclient.krb5.ncacn_np.with..krb5...rpcclient.ktest:local
--^samba3.blackbox.rpcclient.krb5.ncacn_np.with..spnego,krb5...rpcclient.ktest:local
--^samba3.rpc.lsa.lookupsids.krb5.with.old.ccache.ncacn_np.with..smb2,connect...lsa.LookupSidsReply.ktest
--^samba3.rpc.lsa.lookupsids.krb5.ncacn_np.with..smb2,connect...lsa.LookupSidsReply.ktest
--^samba3.rpc.lsa.lookupsids.krb5.with.old.ccache.ncacn_np.with..smb2,packet...lsa.LookupSidsReply.ktest
--^samba3.rpc.lsa.lookupsids.krb5.ncacn_np.with..smb2,packet...lsa.LookupSidsReply.ktest
--^samba3.blackbox.rpcclient.krb5.ncacn_np.with..krb5,packet...rpcclient.ktest:local
--^samba3.blackbox.rpcclient.krb5.ncacn_np.with..spnego,krb5,packet...rpcclient.ktest:local
--^samba3.rpc.lsa.lookupsids.krb5.with.old.ccache.ncacn_np.with..smb2,sign...lsa.LookupSidsReply.ktest
--^samba3.rpc.lsa.lookupsids.krb5.ncacn_np.with..smb2,sign...lsa.LookupSidsReply.ktest
--^samba3.blackbox.rpcclient.krb5.ncacn_np.with..krb5,sign...rpcclient.ktest:local
--^samba3.blackbox.rpcclient.krb5.ncacn_np.with..spnego,krb5,sign...rpcclient.ktest:local
--^samba3.rpc.lsa.lookupsids.krb5.with.old.ccache.ncacn_np.with..smb2,seal...lsa.LookupSidsReply.ktest
--^samba3.rpc.lsa.lookupsids.krb5.ncacn_np.with..smb2,seal...lsa.LookupSidsReply.ktest
--^samba3.blackbox.rpcclient.krb5.ncacn_np.with..krb5,seal...rpcclient.ktest:local
--^samba3.blackbox.rpcclient.krb5.ncacn_np.with..spnego,krb5,seal...rpcclient.ktest:local
--^samba3.blackbox.smbclient_krb5.old.ccache..smbclient.ktest:local
--^samba3.blackbox.smbclient_krb5.new.ccache..smbclient.ktest:local
--^samba3.blackbox.smbclient_large_file..krb5.smbclient.large.posix.write.read.ktest:local
--^samba3.blackbox.smbclient_large_file..krb5.cmp.of.read.and.written.files.ktest:local
--^samba3.blackbox.smbclient_krb5.old.ccache.--client-protection=encrypt.smbclient.ktest:local
--^samba3.blackbox.smbclient_krb5.new.ccache.--client-protection=encrypt.smbclient.ktest:local
--^samba3.blackbox.smbclient_large_file.--client-protection=encrypt.krb5.smbclient.large.posix.write.read.ktest:local
--^samba3.blackbox.smbclient_large_file.--client-protection=encrypt.krb5.cmp.of.read.and.written.files.ktest:local
-diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
-index 5c0f71757ef..577e3170daa 100755
---- a/selftest/target/Samba3.pm
-+++ b/selftest/target/Samba3.pm
-@@ -1675,7 +1675,6 @@ sub setup_ktest
-         workgroup = KTEST
-         realm = ktest.samba.example.com
- 	security = ads
--        username map = $prefix/lib/username.map
-         server signing = required
- 	server min protocol = SMB3_00
- 	client max protocol = SMB3
-@@ -1683,6 +1682,10 @@ sub setup_ktest
-         # This disables NTLM auth against the local SAM, which
-         # we use can then test this setting by.
-         ntlm auth = disabled
-+
-+        idmap config * : backend = autorid
-+        idmap config * : range = 1000000-1999999
-+        idmap config * : rangesize = 100000
- ";
- 
- 	my $ret = $self->provision(
-@@ -1708,12 +1711,6 @@ sub setup_ktest
- 
- 	$ret->{KRB5_CONFIG} = $ctx->{krb5_conf};
- 
--	open(USERMAP, ">$prefix/lib/username.map") or die("Unable to open $prefix/lib/username.map");
--	print USERMAP "
--$ret->{USERNAME} = KTEST\\Administrator
--";
--	close(USERMAP);
--
- #This is the secrets.tdb created by 'net ads join' from Samba3 to a
- #Samba4 DC with the same parameters as are being used here.  The
- #domain SID is S-1-5-21-1071277805-689288055-3486227160
-@@ -1765,6 +1762,7 @@ $ret->{USERNAME} = KTEST\\Administrator
- 	if (not $self->check_or_start(
- 		env_vars => $ret,
- 		nmbd => "yes",
-+		winbindd => "offline",
- 		smbd => "yes")) {
- 	       return undef;
- 	}
--- 
-2.33.1
-
-
-From 0d821434ccdccad38659d76b54159b6335e351c5 Mon Sep 17 00:00:00 2001
-From: Stefan Metzmacher <metze@samba.org>
-Date: Tue, 5 Oct 2021 18:12:49 +0200
-Subject: [PATCH 37/39] CVE-2020-25717: s3:auth: let
- auth3_generate_session_info_pac() reject a PAC in standalone mode
-
-We should be strict in standalone mode, that we only support MIT realms
-without a PAC in order to keep the code sane.
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
-
-Signed-off-by: Stefan Metzmacher <metze@samba.org>
-Reviewed-by: Andrew Bartlett <abartlet@samba.org>
----
- source3/auth/auth_generic.c | 29 +++++++++--------------------
- 1 file changed, 9 insertions(+), 20 deletions(-)
-
-diff --git a/source3/auth/auth_generic.c b/source3/auth/auth_generic.c
-index a8390b1b156..babda46fc92 100644
---- a/source3/auth/auth_generic.c
-+++ b/source3/auth/auth_generic.c
-@@ -48,8 +48,6 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx,
- {
- 	enum server_role server_role = lp_server_role();
- 	TALLOC_CTX *tmp_ctx;
--	struct PAC_LOGON_INFO *logon_info = NULL;
--	struct netr_SamInfo3 *info3_copy = NULL;
- 	bool is_mapped;
- 	bool is_guest;
- 	char *ntuser;
-@@ -203,19 +201,20 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx,
- 	/* This is the standalone legacy code path */
- 
- 	if (pac_blob != NULL) {
--#ifdef HAVE_KRB5
--		status = kerberos_pac_logon_info(tmp_ctx, *pac_blob, NULL, NULL,
--						 NULL, NULL, 0, &logon_info);
--#else
--		status = NT_STATUS_ACCESS_DENIED;
--#endif
-+		/*
-+		 * In standalone mode we don't expect a PAC!
-+		 * we only support MIT realms
-+		 */
-+		status = NT_STATUS_BAD_TOKEN_TYPE;
-+		DBG_WARNING("Unexpected PAC for [%s] in standalone mode - %s\n",
-+			    princ_name, nt_errstr(status));
- 		if (!NT_STATUS_IS_OK(status)) {
- 			goto done;
- 		}
- 	}
- 
- 	status = get_user_from_kerberos_info(tmp_ctx, rhost,
--					     princ_name, logon_info,
-+					     princ_name, NULL,
- 					     &is_mapped, &is_guest,
- 					     &ntuser, &ntdomain,
- 					     &username, &pw);
-@@ -226,19 +225,9 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx,
- 		goto done;
- 	}
- 
--	/* Get the info3 from the PAC data if we have it */
--	if (logon_info) {
--		status = create_info3_from_pac_logon_info(tmp_ctx,
--					logon_info,
--					&info3_copy);
--		if (!NT_STATUS_IS_OK(status)) {
--			goto done;
--		}
--	}
--
- 	status = make_session_info_krb5(mem_ctx,
- 					ntuser, ntdomain, username, pw,
--					info3_copy, is_guest, is_mapped, NULL /* No session key for now, caller will sort it out */,
-+					NULL, is_guest, is_mapped, NULL /* No session key for now, caller will sort it out */,
- 					session_info);
- 	if (!NT_STATUS_IS_OK(status)) {
- 		DEBUG(1, ("Failed to map kerberos pac to server info (%s)\n",
--- 
-2.33.1
-
-
-From 2292c83cc012473d6729e578ec5a84d6be415fab Mon Sep 17 00:00:00 2001
-From: Stefan Metzmacher <metze@samba.org>
-Date: Fri, 8 Oct 2021 17:59:59 +0200
-Subject: [PATCH 38/39] CVE-2020-25717: s3:auth: simplify
- get_user_from_kerberos_info() by removing the unused logon_info argument
-
-This code is only every called in standalone mode on a MIT realm,
-it means we never have a PAC and we also don't have winbindd arround.
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
-
-Signed-off-by: Stefan Metzmacher <metze@samba.org>
-Reviewed-by: Andrew Bartlett <abartlet@samba.org>
----
- source3/auth/auth_generic.c |  2 +-
- source3/auth/proto.h        |  1 -
- source3/auth/user_krb5.c    | 57 +++++++------------------------------
- 3 files changed, 11 insertions(+), 49 deletions(-)
-
-diff --git a/source3/auth/auth_generic.c b/source3/auth/auth_generic.c
-index babda46fc92..8923aec0a4d 100644
---- a/source3/auth/auth_generic.c
-+++ b/source3/auth/auth_generic.c
-@@ -214,7 +214,7 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx,
- 	}
- 
- 	status = get_user_from_kerberos_info(tmp_ctx, rhost,
--					     princ_name, NULL,
-+					     princ_name,
- 					     &is_mapped, &is_guest,
- 					     &ntuser, &ntdomain,
- 					     &username, &pw);
-diff --git a/source3/auth/proto.h b/source3/auth/proto.h
-index 097b17fee44..46fae447347 100644
---- a/source3/auth/proto.h
-+++ b/source3/auth/proto.h
-@@ -423,7 +423,6 @@ struct PAC_LOGON_INFO;
- NTSTATUS get_user_from_kerberos_info(TALLOC_CTX *mem_ctx,
- 				     const char *cli_name,
- 				     const char *princ_name,
--				     struct PAC_LOGON_INFO *logon_info,
- 				     bool *is_mapped,
- 				     bool *mapped_to_guest,
- 				     char **ntuser,
-diff --git a/source3/auth/user_krb5.c b/source3/auth/user_krb5.c
-index 074e8c7eb71..7b69ca6c222 100644
---- a/source3/auth/user_krb5.c
-+++ b/source3/auth/user_krb5.c
-@@ -31,7 +31,6 @@
- NTSTATUS get_user_from_kerberos_info(TALLOC_CTX *mem_ctx,
- 				     const char *cli_name,
- 				     const char *princ_name,
--				     struct PAC_LOGON_INFO *logon_info,
- 				     bool *is_mapped,
- 				     bool *mapped_to_guest,
- 				     char **ntuser,
-@@ -40,8 +39,8 @@ NTSTATUS get_user_from_kerberos_info(TALLOC_CTX *mem_ctx,
- 				     struct passwd **_pw)
- {
- 	NTSTATUS status;
--	char *domain = NULL;
--	char *realm = NULL;
-+	const char *domain = NULL;
-+	const char *realm = NULL;
- 	char *user = NULL;
- 	char *p;
- 	char *fuser = NULL;
-@@ -62,55 +61,16 @@ NTSTATUS get_user_from_kerberos_info(TALLOC_CTX *mem_ctx,
- 		return NT_STATUS_NO_MEMORY;
- 	}
- 
--	realm = talloc_strdup(talloc_tos(), p + 1);
--	if (!realm) {
--		return NT_STATUS_NO_MEMORY;
--	}
-+	realm = p + 1;
- 
- 	if (!strequal(realm, lp_realm())) {
- 		DEBUG(3, ("Ticket for foreign realm %s@%s\n", user, realm));
- 		if (!lp_allow_trusted_domains()) {
- 			return NT_STATUS_LOGON_FAILURE;
- 		}
--	}
--
--	if (logon_info && logon_info->info3.base.logon_domain.string) {
--		domain = talloc_strdup(mem_ctx,
--					logon_info->info3.base.logon_domain.string);
--		if (!domain) {
--			return NT_STATUS_NO_MEMORY;
--		}
--		DEBUG(10, ("Domain is [%s] (using PAC)\n", domain));
-+		domain = realm;
- 	} else {
--
--		/* If we have winbind running, we can (and must) shorten the
--		   username by using the short netbios name. Otherwise we will
--		   have inconsistent user names. With Kerberos, we get the
--		   fully qualified realm, with ntlmssp we get the short
--		   name. And even w2k3 does use ntlmssp if you for example
--		   connect to an ip address. */
--
--		wbcErr wbc_status;
--		struct wbcDomainInfo *info = NULL;
--
--		DEBUG(10, ("Mapping [%s] to short name using winbindd\n",
--			   realm));
--
--		wbc_status = wbcDomainInfo(realm, &info);
--
--		if (WBC_ERROR_IS_OK(wbc_status)) {
--			domain = talloc_strdup(mem_ctx,
--						info->short_name);
--			wbcFreeMemory(info);
--		} else {
--			DEBUG(3, ("Could not find short name: %s\n",
--				  wbcErrorString(wbc_status)));
--			domain = talloc_strdup(mem_ctx, realm);
--		}
--		if (!domain) {
--			return NT_STATUS_NO_MEMORY;
--		}
--		DEBUG(10, ("Domain is [%s] (using Winbind)\n", domain));
-+		domain = lp_workgroup();
- 	}
- 
- 	fuser = talloc_asprintf(mem_ctx,
-@@ -175,7 +135,11 @@ NTSTATUS get_user_from_kerberos_info(TALLOC_CTX *mem_ctx,
- 		return NT_STATUS_NO_MEMORY;
- 	}
- 	*ntuser = user;
--	*ntdomain = domain;
-+	*ntdomain = talloc_strdup(mem_ctx, domain);
-+	if (*ntdomain == NULL) {
-+		return NT_STATUS_NO_MEMORY;
-+	}
-+
- 	*_pw = pw;
- 
- 	return NT_STATUS_OK;
-@@ -282,7 +246,6 @@ NTSTATUS make_session_info_krb5(TALLOC_CTX *mem_ctx,
- NTSTATUS get_user_from_kerberos_info(TALLOC_CTX *mem_ctx,
- 				     const char *cli_name,
- 				     const char *princ_name,
--				     struct PAC_LOGON_INFO *logon_info,
- 				     bool *is_mapped,
- 				     bool *mapped_to_guest,
- 				     char **ntuser,
--- 
-2.33.1
-
-
-From 5607df9a4601a89735c1f9a3eaa700310d89c79a Mon Sep 17 00:00:00 2001
-From: Stefan Metzmacher <metze@samba.org>
-Date: Fri, 8 Oct 2021 18:03:04 +0200
-Subject: [PATCH 39/39] CVE-2020-25717: s3:auth: simplify
- make_session_info_krb5() by removing unused arguments
-
-This is only ever be called in standalone mode with an MIT realm,
-so we don't have a PAC/info3 structure.
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556
-
-Signed-off-by: Stefan Metzmacher <metze@samba.org>
-Reviewed-by: Andrew Bartlett <abartlet@samba.org>
----
- source3/auth/auth_generic.c |  2 +-
- source3/auth/proto.h        |  2 --
- source3/auth/user_krb5.c    | 20 +-------------------
- 3 files changed, 2 insertions(+), 22 deletions(-)
-
-diff --git a/source3/auth/auth_generic.c b/source3/auth/auth_generic.c
-index 8923aec0a4d..fa22a0b2339 100644
---- a/source3/auth/auth_generic.c
-+++ b/source3/auth/auth_generic.c
-@@ -227,7 +227,7 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx,
- 
- 	status = make_session_info_krb5(mem_ctx,
- 					ntuser, ntdomain, username, pw,
--					NULL, is_guest, is_mapped, NULL /* No session key for now, caller will sort it out */,
-+					is_guest, is_mapped,
- 					session_info);
- 	if (!NT_STATUS_IS_OK(status)) {
- 		DEBUG(1, ("Failed to map kerberos pac to server info (%s)\n",
-diff --git a/source3/auth/proto.h b/source3/auth/proto.h
-index 46fae447347..fb7f663512b 100644
---- a/source3/auth/proto.h
-+++ b/source3/auth/proto.h
-@@ -434,9 +434,7 @@ NTSTATUS make_session_info_krb5(TALLOC_CTX *mem_ctx,
- 				char *ntdomain,
- 				char *username,
- 				struct passwd *pw,
--				const struct netr_SamInfo3 *info3,
- 				bool mapped_to_guest, bool username_was_mapped,
--				DATA_BLOB *session_key,
- 				struct auth_session_info **session_info);
- 
- /* The following definitions come from auth/auth_samba4.c  */
-diff --git a/source3/auth/user_krb5.c b/source3/auth/user_krb5.c
-index 7b69ca6c222..b8f37cbeee0 100644
---- a/source3/auth/user_krb5.c
-+++ b/source3/auth/user_krb5.c
-@@ -150,9 +150,7 @@ NTSTATUS make_session_info_krb5(TALLOC_CTX *mem_ctx,
- 				char *ntdomain,
- 				char *username,
- 				struct passwd *pw,
--				const struct netr_SamInfo3 *info3,
- 				bool mapped_to_guest, bool username_was_mapped,
--				DATA_BLOB *session_key,
- 				struct auth_session_info **session_info)
- {
- 	NTSTATUS status;
-@@ -166,20 +164,6 @@ NTSTATUS make_session_info_krb5(TALLOC_CTX *mem_ctx,
- 			return status;
- 		}
- 
--	} else if (info3) {
--		/* pass the unmapped username here since map_username()
--		   will be called again in make_server_info_info3() */
--
--		status = make_server_info_info3(mem_ctx,
--						ntuser, ntdomain,
--						&server_info,
--						info3);
--		if (!NT_STATUS_IS_OK(status)) {
--			DEBUG(1, ("make_server_info_info3 failed: %s!\n",
--				  nt_errstr(status)));
--			return status;
--		}
--
- 	} else {
- 		/*
- 		 * We didn't get a PAC, we have to make up the user
-@@ -231,7 +215,7 @@ NTSTATUS make_session_info_krb5(TALLOC_CTX *mem_ctx,
- 
- 	server_info->nss_token |= username_was_mapped;
- 
--	status = create_local_token(mem_ctx, server_info, session_key, ntuser, session_info);
-+	status = create_local_token(mem_ctx, server_info, NULL, ntuser, session_info);
- 	talloc_free(server_info);
- 	if (!NT_STATUS_IS_OK(status)) {
- 		DEBUG(10,("failed to create local token: %s\n",
-@@ -261,9 +245,7 @@ NTSTATUS make_session_info_krb5(TALLOC_CTX *mem_ctx,
- 				char *ntdomain,
- 				char *username,
- 				struct passwd *pw,
--				const struct netr_SamInfo3 *info3,
- 				bool mapped_to_guest, bool username_was_mapped,
--				DATA_BLOB *session_key,
- 				struct auth_session_info **session_info)
- {
- 	return NT_STATUS_NOT_IMPLEMENTED;
--- 
-2.33.1
-
diff --git a/SOURCES/CVE-2021-23192.patch b/SOURCES/CVE-2021-23192.patch
deleted file mode 100644
index 5e14212..0000000
--- a/SOURCES/CVE-2021-23192.patch
+++ /dev/null
@@ -1,4996 +0,0 @@
-From d6310598bd205240950410d59a3453f45c45d644 Mon Sep 17 00:00:00 2001
-From: Volker Lendecke <vl@samba.org>
-Date: Fri, 2 Apr 2021 12:20:38 +0200
-Subject: [PATCH 1/9] rpc: Give dcerpc_util.c its own header
-
-Signed-off-by: Volker Lendecke <vl@samba.org>
-Reviewed-by: Jeremy Allison <jra@samba.org>
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14875
-
-(cherry picked from commit 8945d99758d8bedd374f1c51304b87a6cf10498c)
----
- librpc/rpc/dcerpc_util.c                    |   1 +
- librpc/rpc/dcerpc_util.h                    | 103 ++++++++++++++++++++
- librpc/rpc/dcesrv_auth.c                    |   1 +
- librpc/rpc/dcesrv_core.c                    |   1 +
- librpc/rpc/dcesrv_reply.c                   |   1 +
- librpc/rpc/rpc_common.h                     |  74 --------------
- source3/librpc/rpc/dcerpc_helpers.c         |   1 +
- source3/rpc_client/cli_pipe.c               |   1 +
- source3/rpc_client/rpc_transport_np.c       |   1 +
- source3/rpc_server/rpc_ncacn_np.c           |   1 +
- source4/librpc/rpc/dcerpc.c                 |   1 +
- source4/librpc/rpc/dcerpc_roh_channel_out.c |   1 +
- 12 files changed, 113 insertions(+), 74 deletions(-)
- create mode 100644 librpc/rpc/dcerpc_util.h
-
-diff --git a/librpc/rpc/dcerpc_util.c b/librpc/rpc/dcerpc_util.c
-index 42e8e611019..925fb70ad7c 100644
---- a/librpc/rpc/dcerpc_util.c
-+++ b/librpc/rpc/dcerpc_util.c
-@@ -25,6 +25,7 @@
- #include "lib/tsocket/tsocket.h"
- #include "lib/util/tevent_ntstatus.h"
- #include "librpc/rpc/dcerpc.h"
-+#include "librpc/rpc/dcerpc_util.h"
- #include "librpc/gen_ndr/ndr_dcerpc.h"
- #include "rpc_common.h"
- #include "lib/util/bitmap.h"
-diff --git a/librpc/rpc/dcerpc_util.h b/librpc/rpc/dcerpc_util.h
-new file mode 100644
-index 00000000000..0ecaf428c3c
---- /dev/null
-+++ b/librpc/rpc/dcerpc_util.h
-@@ -0,0 +1,103 @@
-+/*
-+   Unix SMB/CIFS implementation.
-+
-+   Copyright (C) Stefan Metzmacher 2010-2011
-+   Copyright (C) Andrew Tridgell 2010-2011
-+   Copyright (C) Simo Sorce 2010
-+
-+   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/>.
-+*/
-+
-+#ifndef __LIBRPC_RPC_DCERPC_UTIL_H__
-+#define __LIBRPC_RPC_DCERPC_UTIL_H__
-+
-+#include "replace.h"
-+#include <talloc.h>
-+#include "lib/util/data_blob.h"
-+#include "librpc/rpc/rpc_common.h"
-+#include "librpc/gen_ndr/dcerpc.h"
-+
-+void dcerpc_set_frag_length(DATA_BLOB *blob, uint16_t v);
-+uint16_t dcerpc_get_frag_length(const DATA_BLOB *blob);
-+void dcerpc_set_auth_length(DATA_BLOB *blob, uint16_t v);
-+uint16_t dcerpc_get_auth_length(const DATA_BLOB *blob);
-+uint8_t dcerpc_get_endian_flag(DATA_BLOB *blob);
-+uint8_t dcerpc_get_auth_type(const DATA_BLOB *blob);
-+uint8_t dcerpc_get_auth_level(const DATA_BLOB *blob);
-+uint32_t dcerpc_get_auth_context_id(const DATA_BLOB *blob);
-+const char *dcerpc_default_transport_endpoint(TALLOC_CTX *mem_ctx,
-+					      enum dcerpc_transport_t transport,
-+					      const struct ndr_interface_table *table);
-+
-+NTSTATUS dcerpc_pull_ncacn_packet(TALLOC_CTX *mem_ctx,
-+				  const DATA_BLOB *blob,
-+				  struct ncacn_packet *r);
-+
-+/**
-+* @brief	Pull a dcerpc_auth structure, taking account of any auth
-+*		padding in the blob. For request/response packets we pass
-+*		the whole data blob, so auth_data_only must be set to false
-+*		as the blob contains data+pad+auth and no just pad+auth.
-+*
-+* @param pkt		- The ncacn_packet strcuture
-+* @param mem_ctx	- The mem_ctx used to allocate dcerpc_auth elements
-+* @param pkt_trailer	- The packet trailer data, usually the trailing
-+*			  auth_info blob, but in the request/response case
-+*			  this is the stub_and_verifier blob.
-+* @param auth		- A preallocated dcerpc_auth *empty* structure
-+* @param auth_length	- The length of the auth trail, sum of auth header
-+*			  lenght and pkt->auth_length
-+* @param auth_data_only	- Whether the pkt_trailer includes only the auth_blob
-+*			  (+ padding) or also other data.
-+*
-+* @return		- A NTSTATUS error code.
-+*/
-+NTSTATUS dcerpc_pull_auth_trailer(const struct ncacn_packet *pkt,
-+				  TALLOC_CTX *mem_ctx,
-+				  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);
-+NTSTATUS dcerpc_ncacn_pull_pkt_auth(const struct dcerpc_auth *auth_state,
-+				    struct gensec_security *gensec,
-+				    TALLOC_CTX *mem_ctx,
-+				    enum dcerpc_pkt_type ptype,
-+				    uint8_t required_flags,
-+				    uint8_t optional_flags,
-+				    uint8_t payload_offset,
-+				    DATA_BLOB *payload_and_verifier,
-+				    DATA_BLOB *raw_packet,
-+				    const struct ncacn_packet *pkt);
-+NTSTATUS dcerpc_ncacn_push_pkt_auth(const struct dcerpc_auth *auth_state,
-+				    struct gensec_security *gensec,
-+				    TALLOC_CTX *mem_ctx,
-+				    DATA_BLOB *raw_packet,
-+				    size_t sig_size,
-+				    uint8_t payload_offset,
-+				    const DATA_BLOB *payload,
-+				    const struct ncacn_packet *pkt);
-+struct tevent_req *dcerpc_read_ncacn_packet_send(TALLOC_CTX *mem_ctx,
-+						 struct tevent_context *ev,
-+						 struct tstream_context *stream);
-+NTSTATUS dcerpc_read_ncacn_packet_recv(struct tevent_req *req,
-+				       TALLOC_CTX *mem_ctx,
-+				       struct ncacn_packet **pkt,
-+				       DATA_BLOB *buffer);
-+
-+#endif
-diff --git a/librpc/rpc/dcesrv_auth.c b/librpc/rpc/dcesrv_auth.c
-index 8ac90f2a2bd..f7919ebf575 100644
---- a/librpc/rpc/dcesrv_auth.c
-+++ b/librpc/rpc/dcesrv_auth.c
-@@ -23,6 +23,7 @@
- #include "includes.h"
- #include "librpc/rpc/dcesrv_core.h"
- #include "librpc/rpc/dcesrv_core_proto.h"
-+#include "librpc/rpc/dcerpc_util.h"
- #include "librpc/gen_ndr/ndr_dcerpc.h"
- #include "auth/credentials/credentials.h"
- #include "auth/gensec/gensec.h"
-diff --git a/librpc/rpc/dcesrv_core.c b/librpc/rpc/dcesrv_core.c
-index 06f6c4b2382..74730f22c7c 100644
---- a/librpc/rpc/dcesrv_core.c
-+++ b/librpc/rpc/dcesrv_core.c
-@@ -24,6 +24,7 @@
- #include "includes.h"
- #include "librpc/rpc/dcesrv_core.h"
- #include "librpc/rpc/dcesrv_core_proto.h"
-+#include "librpc/rpc/dcerpc_util.h"
- #include "librpc/gen_ndr/auth.h"
- #include "auth/gensec/gensec.h"
- #include "lib/util/dlinklist.h"
-diff --git a/librpc/rpc/dcesrv_reply.c b/librpc/rpc/dcesrv_reply.c
-index 96bd98f53e1..5b4429956e7 100644
---- a/librpc/rpc/dcesrv_reply.c
-+++ b/librpc/rpc/dcesrv_reply.c
-@@ -23,6 +23,7 @@
- #include "includes.h"
- #include "librpc/rpc/dcesrv_core.h"
- #include "librpc/rpc/dcesrv_core_proto.h"
-+#include "librpc/rpc/dcerpc_util.h"
- #include "auth/gensec/gensec.h"
- #include "lib/util/dlinklist.h"
- #include "param/param.h"
-diff --git a/librpc/rpc/rpc_common.h b/librpc/rpc/rpc_common.h
-index 82fe2eb7e80..55a35f31096 100644
---- a/librpc/rpc/rpc_common.h
-+++ b/librpc/rpc/rpc_common.h
-@@ -165,80 +165,6 @@ const char *derpc_transport_string_by_transport(enum dcerpc_transport_t t);
- enum dcerpc_transport_t dcerpc_transport_by_name(const char *name);
- enum dcerpc_transport_t dcerpc_transport_by_tower(const struct epm_tower *tower);
- 
--/* The following definitions come from ../librpc/rpc/dcerpc_util.c  */
--
--void dcerpc_set_frag_length(DATA_BLOB *blob, uint16_t v);
--uint16_t dcerpc_get_frag_length(const DATA_BLOB *blob);
--void dcerpc_set_auth_length(DATA_BLOB *blob, uint16_t v);
--uint16_t dcerpc_get_auth_length(const DATA_BLOB *blob);
--uint8_t dcerpc_get_endian_flag(DATA_BLOB *blob);
--uint8_t dcerpc_get_auth_type(const DATA_BLOB *blob);
--uint8_t dcerpc_get_auth_level(const DATA_BLOB *blob);
--uint32_t dcerpc_get_auth_context_id(const DATA_BLOB *blob);
--const char *dcerpc_default_transport_endpoint(TALLOC_CTX *mem_ctx,
--					      enum dcerpc_transport_t transport,
--					      const struct ndr_interface_table *table);
--
--NTSTATUS dcerpc_pull_ncacn_packet(TALLOC_CTX *mem_ctx,
--				  const DATA_BLOB *blob,
--				  struct ncacn_packet *r);
--
--/**
--* @brief	Pull a dcerpc_auth structure, taking account of any auth
--*		padding in the blob. For request/response packets we pass
--*		the whole data blob, so auth_data_only must be set to false
--*		as the blob contains data+pad+auth and no just pad+auth.
--*
--* @param pkt		- The ncacn_packet strcuture
--* @param mem_ctx	- The mem_ctx used to allocate dcerpc_auth elements
--* @param pkt_trailer	- The packet trailer data, usually the trailing
--*			  auth_info blob, but in the request/response case
--*			  this is the stub_and_verifier blob.
--* @param auth		- A preallocated dcerpc_auth *empty* structure
--* @param auth_length	- The length of the auth trail, sum of auth header
--*			  lenght and pkt->auth_length
--* @param auth_data_only	- Whether the pkt_trailer includes only the auth_blob
--*			  (+ padding) or also other data.
--*
--* @return		- A NTSTATUS error code.
--*/
--NTSTATUS dcerpc_pull_auth_trailer(const struct ncacn_packet *pkt,
--				  TALLOC_CTX *mem_ctx,
--				  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);
--NTSTATUS dcerpc_ncacn_pull_pkt_auth(const struct dcerpc_auth *auth_state,
--				    struct gensec_security *gensec,
--				    TALLOC_CTX *mem_ctx,
--				    enum dcerpc_pkt_type ptype,
--				    uint8_t required_flags,
--				    uint8_t optional_flags,
--				    uint8_t payload_offset,
--				    DATA_BLOB *payload_and_verifier,
--				    DATA_BLOB *raw_packet,
--				    const struct ncacn_packet *pkt);
--NTSTATUS dcerpc_ncacn_push_pkt_auth(const struct dcerpc_auth *auth_state,
--				    struct gensec_security *gensec,
--				    TALLOC_CTX *mem_ctx,
--				    DATA_BLOB *raw_packet,
--				    size_t sig_size,
--				    uint8_t payload_offset,
--				    const DATA_BLOB *payload,
--				    const struct ncacn_packet *pkt);
--struct tevent_req *dcerpc_read_ncacn_packet_send(TALLOC_CTX *mem_ctx,
--						 struct tevent_context *ev,
--						 struct tstream_context *stream);
--NTSTATUS dcerpc_read_ncacn_packet_recv(struct tevent_req *req,
--				       TALLOC_CTX *mem_ctx,
--				       struct ncacn_packet **pkt,
--				       DATA_BLOB *buffer);
--
- /* The following definitions come from ../librpc/rpc/binding_handle.c  */
- 
- struct dcerpc_binding_handle_ops {
-diff --git a/source3/librpc/rpc/dcerpc_helpers.c b/source3/librpc/rpc/dcerpc_helpers.c
-index 1f67987561c..c609efd5b07 100644
---- a/source3/librpc/rpc/dcerpc_helpers.c
-+++ b/source3/librpc/rpc/dcerpc_helpers.c
-@@ -20,6 +20,7 @@
- 
- #include "includes.h"
- #include "librpc/rpc/dcerpc.h"
-+#include "librpc/rpc/dcerpc_util.h"
- #include "librpc/gen_ndr/ndr_dcerpc.h"
- #include "librpc/crypto/gse.h"
- #include "auth/gensec/gensec.h"
-diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c
-index 8f52acadec8..3d16f1092db 100644
---- a/source3/rpc_client/cli_pipe.c
-+++ b/source3/rpc_client/cli_pipe.c
-@@ -30,6 +30,7 @@
- #include "librpc/gen_ndr/ndr_dcerpc.h"
- #include "librpc/gen_ndr/ndr_netlogon_c.h"
- #include "librpc/rpc/dcerpc.h"
-+#include "librpc/rpc/dcerpc_util.h"
- #include "rpc_dce.h"
- #include "cli_pipe.h"
- #include "libsmb/libsmb.h"
-diff --git a/source3/rpc_client/rpc_transport_np.c b/source3/rpc_client/rpc_transport_np.c
-index 9dc5c5634fc..b24023661ff 100644
---- a/source3/rpc_client/rpc_transport_np.c
-+++ b/source3/rpc_client/rpc_transport_np.c
-@@ -19,6 +19,7 @@
- 
- #include "includes.h"
- #include "../lib/util/tevent_ntstatus.h"
-+#include "librpc/rpc/dcerpc_util.h"
- #include "rpc_client/rpc_transport.h"
- #include "librpc/ndr/ndr_table.h"
- #include "libcli/smb/smbXcli_base.h"
-diff --git a/source3/rpc_server/rpc_ncacn_np.c b/source3/rpc_server/rpc_ncacn_np.c
-index 494b002e714..a874a2376d1 100644
---- a/source3/rpc_server/rpc_ncacn_np.c
-+++ b/source3/rpc_server/rpc_ncacn_np.c
-@@ -37,6 +37,7 @@
- #include "rpc_server/rpc_config.h"
- #include "librpc/ndr/ndr_table.h"
- #include "rpc_server/rpc_server.h"
-+#include "librpc/rpc/dcerpc_util.h"
- 
- #undef DBGC_CLASS
- #define DBGC_CLASS DBGC_RPC_SRV
-diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c
-index 87a99a8df89..f97263dcc5b 100644
---- a/source4/librpc/rpc/dcerpc.c
-+++ b/source4/librpc/rpc/dcerpc.c
-@@ -26,6 +26,7 @@
- #include "lib/events/events.h"
- #include "librpc/rpc/dcerpc.h"
- #include "librpc/rpc/dcerpc_proto.h"
-+#include "librpc/rpc/dcerpc_util.h"
- #include "librpc/gen_ndr/ndr_misc.h"
- #include "librpc/gen_ndr/ndr_dcerpc.h"
- #include "auth/gensec/gensec.h"
-diff --git a/source4/librpc/rpc/dcerpc_roh_channel_out.c b/source4/librpc/rpc/dcerpc_roh_channel_out.c
-index e431689d419..2abafb0bab5 100644
---- a/source4/librpc/rpc/dcerpc_roh_channel_out.c
-+++ b/source4/librpc/rpc/dcerpc_roh_channel_out.c
-@@ -37,6 +37,7 @@
- #include "librpc/rpc/dcerpc.h"
- #include "librpc/rpc/dcerpc_roh.h"
- #include "librpc/rpc/dcerpc_proto.h"
-+#include "librpc/rpc/dcerpc_util.h"
- #include "libcli/http/http.h"
- 
- struct roh_request_state {
--- 
-2.25.1
-
-
-From fc8592c7e3aa24c3b6819641908f21311840e6cb Mon Sep 17 00:00:00 2001
-From: Volker Lendecke <vl@samba.org>
-Date: Fri, 2 Apr 2021 13:41:21 +0200
-Subject: [PATCH 2/9] librpc: Remove the gensec dependency from library
- dcerpc-binding
-
-This means yet another library, but having to depend on gensec just
-for dcerpc_parse_binding() and basic packet parsing seems like a bit
-overkill to me.
-
-Signed-off-by: Volker Lendecke <vl@samba.org>
-Reviewed-by: Jeremy Allison <jra@samba.org>
-
-Autobuild-User(master): Jeremy Allison <jra@samba.org>
-Autobuild-Date(master): Tue Apr  6 23:33:14 UTC 2021 on sn-devel-184
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14875
-
-(cherry picked from commit 4d3b6506d30e4bf302f832493dad00a83b73d370)
----
- libcli/auth/wscript_build    |  10 +-
- librpc/rpc/dcerpc_pkt_auth.c | 497 +++++++++++++++++++++++++++++++++++
- librpc/rpc/dcerpc_pkt_auth.h |  58 ++++
- librpc/rpc/dcerpc_util.c     | 464 --------------------------------
- librpc/rpc/dcerpc_util.h     |  18 --
- librpc/rpc/dcesrv_auth.c     |   1 +
- librpc/wscript_build         |  25 +-
- source3/wscript_build        |   8 +-
- source4/librpc/rpc/dcerpc.c  |   1 +
- source4/librpc/wscript_build |  21 +-
- 10 files changed, 613 insertions(+), 490 deletions(-)
- create mode 100644 librpc/rpc/dcerpc_pkt_auth.c
- create mode 100644 librpc/rpc/dcerpc_pkt_auth.h
-
-diff --git a/libcli/auth/wscript_build b/libcli/auth/wscript_build
-index 2a6a7468e45..24ab68fac1e 100644
---- a/libcli/auth/wscript_build
-+++ b/libcli/auth/wscript_build
-@@ -30,7 +30,15 @@ bld.SAMBA_SUBSYSTEM('COMMON_SCHANNEL',
- 
- bld.SAMBA_SUBSYSTEM('NETLOGON_CREDS_CLI',
-         source='netlogon_creds_cli.c',
--        deps='dbwrap util_tdb tevent-util samba-hostconfig RPC_NDR_NETLOGON NDR_NETLOGON'
-+        deps='''
-+        dbwrap
-+        util_tdb
-+        tevent-util
-+        samba-hostconfig
-+        gensec
-+        RPC_NDR_NETLOGON
-+        NDR_NETLOGON
-+        '''
-         )
- 
- bld.SAMBA_SUBSYSTEM('PAM_ERRORS',
-diff --git a/librpc/rpc/dcerpc_pkt_auth.c b/librpc/rpc/dcerpc_pkt_auth.c
-new file mode 100644
-index 00000000000..322d7497893
---- /dev/null
-+++ b/librpc/rpc/dcerpc_pkt_auth.c
-@@ -0,0 +1,497 @@
-+/*
-+   Unix SMB/CIFS implementation.
-+   raw dcerpc operations
-+
-+   Copyright (C) Andrew Tridgell 2003-2005
-+   Copyright (C) Jelmer Vernooij 2004-2005
-+
-+   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 "replace.h"
-+#include "system/network.h"
-+#include <tevent.h>
-+#include "lib/util/talloc_stack.h"
-+#include "lib/util/debug.h"
-+#include "lib/util/byteorder.h"
-+#include "lib/util/samba_util.h"
-+#include "librpc/rpc/dcerpc.h"
-+#include "librpc/rpc/dcerpc_util.h"
-+#include "librpc/rpc/dcerpc_pkt_auth.h"
-+#include "librpc/gen_ndr/ndr_dcerpc.h"
-+#include "rpc_common.h"
-+#include "lib/util/bitmap.h"
-+#include "auth/gensec/gensec.h"
-+#include "lib/util/mkdir_p.h"
-+#include "lib/crypto/gnutls_helpers.h"
-+#include <gnutls/crypto.h>
-+
-+NTSTATUS dcerpc_ncacn_pull_pkt_auth(const struct dcerpc_auth *auth_state,
-+				    struct gensec_security *gensec,
-+				    TALLOC_CTX *mem_ctx,
-+				    enum dcerpc_pkt_type ptype,
-+				    uint8_t required_flags,
-+				    uint8_t optional_flags,
-+				    uint8_t payload_offset,
-+				    DATA_BLOB *payload_and_verifier,
-+				    DATA_BLOB *raw_packet,
-+				    const struct ncacn_packet *pkt)
-+{
-+	NTSTATUS status;
-+	struct dcerpc_auth auth;
-+	uint32_t auth_length;
-+
-+	if (auth_state == NULL) {
-+		return NT_STATUS_INTERNAL_ERROR;
-+	}
-+
-+	status = dcerpc_verify_ncacn_packet_header(pkt, ptype,
-+					payload_and_verifier->length,
-+					required_flags, optional_flags);
-+	if (!NT_STATUS_IS_OK(status)) {
-+		return status;
-+	}
-+
-+	switch (auth_state->auth_level) {
-+	case DCERPC_AUTH_LEVEL_PRIVACY:
-+	case DCERPC_AUTH_LEVEL_INTEGRITY:
-+	case DCERPC_AUTH_LEVEL_PACKET:
-+		break;
-+
-+	case DCERPC_AUTH_LEVEL_CONNECT:
-+		if (pkt->auth_length != 0) {
-+			break;
-+		}
-+		return NT_STATUS_OK;
-+	case DCERPC_AUTH_LEVEL_NONE:
-+		if (pkt->auth_length != 0) {
-+			return NT_STATUS_ACCESS_DENIED;
-+		}
-+		return NT_STATUS_OK;
-+
-+	default:
-+		return NT_STATUS_RPC_UNSUPPORTED_AUTHN_LEVEL;
-+	}
-+
-+	if (pkt->auth_length == 0) {
-+		return NT_STATUS_RPC_PROTOCOL_ERROR;
-+	}
-+
-+	if (gensec == NULL) {
-+		return NT_STATUS_INTERNAL_ERROR;
-+	}
-+
-+	status = dcerpc_pull_auth_trailer(pkt, mem_ctx,
-+					  payload_and_verifier,
-+					  &auth, &auth_length, false);
-+	if (!NT_STATUS_IS_OK(status)) {
-+		return status;
-+	}
-+
-+	if (payload_and_verifier->length < auth_length) {
-+		/*
-+		 * should be checked in dcerpc_pull_auth_trailer()
-+		 */
-+		return NT_STATUS_INTERNAL_ERROR;
-+	}
-+
-+	payload_and_verifier->length -= auth_length;
-+
-+	if (payload_and_verifier->length < auth.auth_pad_length) {
-+		/*
-+		 * should be checked in dcerpc_pull_auth_trailer()
-+		 */
-+		return NT_STATUS_INTERNAL_ERROR;
-+	}
-+
-+	if (auth.auth_type != auth_state->auth_type) {
-+		return NT_STATUS_ACCESS_DENIED;
-+	}
-+
-+	if (auth.auth_level != auth_state->auth_level) {
-+		return NT_STATUS_ACCESS_DENIED;
-+	}
-+
-+	if (auth.auth_context_id != auth_state->auth_context_id) {
-+		return NT_STATUS_ACCESS_DENIED;
-+	}
-+
-+	/* check signature or unseal the packet */
-+	switch (auth_state->auth_level) {
-+	case DCERPC_AUTH_LEVEL_PRIVACY:
-+		status = gensec_unseal_packet(gensec,
-+					      raw_packet->data + payload_offset,
-+					      payload_and_verifier->length,
-+					      raw_packet->data,
-+					      raw_packet->length -
-+					      auth.credentials.length,
-+					      &auth.credentials);
-+		if (!NT_STATUS_IS_OK(status)) {
-+			return NT_STATUS_RPC_SEC_PKG_ERROR;
-+		}
-+		memcpy(payload_and_verifier->data,
-+		       raw_packet->data + payload_offset,
-+		       payload_and_verifier->length);
-+		break;
-+
-+	case DCERPC_AUTH_LEVEL_INTEGRITY:
-+	case DCERPC_AUTH_LEVEL_PACKET:
-+		status = gensec_check_packet(gensec,
-+					     payload_and_verifier->data,
-+					     payload_and_verifier->length,
-+					     raw_packet->data,
-+					     raw_packet->length -
-+					     auth.credentials.length,
-+					     &auth.credentials);
-+		if (!NT_STATUS_IS_OK(status)) {
-+			return NT_STATUS_RPC_SEC_PKG_ERROR;
-+		}
-+		break;
-+
-+	case DCERPC_AUTH_LEVEL_CONNECT:
-+		/* for now we ignore possible signatures here */
-+		break;
-+
-+	default:
-+		return NT_STATUS_RPC_UNSUPPORTED_AUTHN_LEVEL;
-+	}
-+
-+	/*
-+	 * remove the indicated amount of padding
-+	 *
-+	 * A possible overflow is checked above.
-+	 */
-+	payload_and_verifier->length -= auth.auth_pad_length;
-+
-+	return NT_STATUS_OK;
-+}
-+
-+NTSTATUS dcerpc_ncacn_push_pkt_auth(const struct dcerpc_auth *auth_state,
-+				    struct gensec_security *gensec,
-+				    TALLOC_CTX *mem_ctx,
-+				    DATA_BLOB *raw_packet,
-+				    size_t sig_size,
-+				    uint8_t payload_offset,
-+				    const DATA_BLOB *payload,
-+				    const struct ncacn_packet *pkt)
-+{
-+	TALLOC_CTX *frame = talloc_stackframe();
-+	NTSTATUS status;
-+	enum ndr_err_code ndr_err;
-+	struct ndr_push *ndr = NULL;
-+	uint32_t payload_length;
-+	uint32_t whole_length;
-+	DATA_BLOB blob = data_blob_null;
-+	DATA_BLOB sig = data_blob_null;
-+	struct dcerpc_auth _out_auth_info;
-+	struct dcerpc_auth *out_auth_info = NULL;
-+
-+	*raw_packet = data_blob_null;
-+
-+	if (auth_state == NULL) {
-+		TALLOC_FREE(frame);
-+		return NT_STATUS_INTERNAL_ERROR;
-+	}
-+
-+	switch (auth_state->auth_level) {
-+	case DCERPC_AUTH_LEVEL_PRIVACY:
-+	case DCERPC_AUTH_LEVEL_INTEGRITY:
-+	case DCERPC_AUTH_LEVEL_PACKET:
-+		if (sig_size == 0) {
-+			TALLOC_FREE(frame);
-+			return NT_STATUS_INTERNAL_ERROR;
-+		}
-+
-+		if (gensec == NULL) {
-+			TALLOC_FREE(frame);
-+			return NT_STATUS_INTERNAL_ERROR;
-+		}
-+
-+		_out_auth_info = (struct dcerpc_auth) {
-+			.auth_type = auth_state->auth_type,
-+			.auth_level = auth_state->auth_level,
-+			.auth_context_id = auth_state->auth_context_id,
-+		};
-+		out_auth_info = &_out_auth_info;
-+		break;
-+
-+	case DCERPC_AUTH_LEVEL_CONNECT:
-+		/*
-+		 * TODO: let the gensec mech decide if it wants to generate a
-+		 *       signature that might be needed for schannel...
-+		 */
-+		if (sig_size != 0) {
-+			TALLOC_FREE(frame);
-+			return NT_STATUS_INTERNAL_ERROR;
-+		}
-+
-+		if (gensec == NULL) {
-+			TALLOC_FREE(frame);
-+			return NT_STATUS_INTERNAL_ERROR;
-+		}
-+		break;
-+
-+	case DCERPC_AUTH_LEVEL_NONE:
-+		if (sig_size != 0) {
-+			TALLOC_FREE(frame);
-+			return NT_STATUS_INTERNAL_ERROR;
-+		}
-+		break;
-+
-+	default:
-+		TALLOC_FREE(frame);
-+		return NT_STATUS_INTERNAL_ERROR;
-+	}
-+
-+	ndr = ndr_push_init_ctx(frame);
-+	if (ndr == NULL) {
-+		TALLOC_FREE(frame);
-+		return NT_STATUS_NO_MEMORY;
-+	}
-+
-+	ndr_err = ndr_push_ncacn_packet(ndr, NDR_SCALARS|NDR_BUFFERS, pkt);
-+	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-+		TALLOC_FREE(frame);
-+		return ndr_map_error2ntstatus(ndr_err);
-+	}
-+
-+	if (out_auth_info != NULL) {
-+		/*
-+		 * pad to 16 byte multiple in the payload portion of the
-+		 * packet. This matches what w2k3 does. Note that we can't use
-+		 * ndr_push_align() as that is relative to the start of the
-+		 * whole packet, whereas w2k8 wants it relative to the start
-+		 * of the stub.
-+		 */
-+		out_auth_info->auth_pad_length =
-+			DCERPC_AUTH_PAD_LENGTH(payload->length);
-+		ndr_err = ndr_push_zero(ndr, out_auth_info->auth_pad_length);
-+		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-+			TALLOC_FREE(frame);
-+			return ndr_map_error2ntstatus(ndr_err);
-+		}
-+
-+		payload_length = payload->length +
-+			out_auth_info->auth_pad_length;
-+
-+		ndr_err = ndr_push_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS,
-+					       out_auth_info);
-+		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-+			TALLOC_FREE(frame);
-+			return ndr_map_error2ntstatus(ndr_err);
-+		}
-+
-+		whole_length = ndr->offset;
-+
-+		ndr_err = ndr_push_zero(ndr, sig_size);
-+		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-+			TALLOC_FREE(frame);
-+			return ndr_map_error2ntstatus(ndr_err);
-+		}
-+	} else {
-+		payload_length = payload->length;
-+		whole_length = ndr->offset;
-+	}
-+
-+	/* extract the whole packet as a blob */
-+	blob = ndr_push_blob(ndr);
-+
-+	/*
-+	 * Setup the frag and auth length in the packet buffer.
-+	 * This is needed if the GENSEC mech does AEAD signing
-+	 * of the packet headers. The signature itself will be
-+	 * appended later.
-+	 */
-+	dcerpc_set_frag_length(&blob, blob.length);
-+	dcerpc_set_auth_length(&blob, sig_size);
-+
-+	/* sign or seal the packet */
-+	switch (auth_state->auth_level) {
-+	case DCERPC_AUTH_LEVEL_PRIVACY:
-+		status = gensec_seal_packet(gensec,
-+					    frame,
-+					    blob.data + payload_offset,
-+					    payload_length,
-+					    blob.data,
-+					    whole_length,
-+					    &sig);
-+		if (!NT_STATUS_IS_OK(status)) {
-+			TALLOC_FREE(frame);
-+			return status;
-+		}
-+		break;
-+
-+	case DCERPC_AUTH_LEVEL_INTEGRITY:
-+	case DCERPC_AUTH_LEVEL_PACKET:
-+		status = gensec_sign_packet(gensec,
-+					    frame,
-+					    blob.data + payload_offset,
-+					    payload_length,
-+					    blob.data,
-+					    whole_length,
-+					    &sig);
-+		if (!NT_STATUS_IS_OK(status)) {
-+			TALLOC_FREE(frame);
-+			return status;
-+		}
-+		break;
-+
-+	case DCERPC_AUTH_LEVEL_CONNECT:
-+	case DCERPC_AUTH_LEVEL_NONE:
-+		break;
-+
-+	default:
-+		TALLOC_FREE(frame);
-+		return NT_STATUS_INTERNAL_ERROR;
-+	}
-+
-+	if (sig.length != sig_size) {
-+		TALLOC_FREE(frame);
-+		return NT_STATUS_RPC_SEC_PKG_ERROR;
-+	}
-+
-+	if (sig_size != 0) {
-+		memcpy(blob.data + whole_length, sig.data, sig_size);
-+	}
-+
-+	*raw_packet = blob;
-+	talloc_steal(mem_ctx, raw_packet->data);
-+	TALLOC_FREE(frame);
-+	return NT_STATUS_OK;
-+}
-+
-+#ifdef DEVELOPER
-+
-+/*
-+ * Save valid, well-formed DCE/RPC stubs to use as a seed for
-+ * ndr_fuzz_X
-+ */
-+void dcerpc_save_ndr_fuzz_seed(TALLOC_CTX *mem_ctx,
-+			       DATA_BLOB raw_blob,
-+			       const char *dump_dir,
-+			       const char *iface_name,
-+			       int flags,
-+			       int opnum,
-+			       bool ndr64)
-+{
-+	char *fname = NULL;
-+	const char *sub_dir = NULL;
-+	TALLOC_CTX *temp_ctx = talloc_new(mem_ctx);
-+	DATA_BLOB blob;
-+	int ret, rc;
-+	uint8_t digest[20];
-+	DATA_BLOB digest_blob;
-+	char *digest_hex;
-+	uint16_t fuzz_flags = 0;
-+
-+	/*
-+	 * We want to save the 'stub' in a per-pipe subdirectory, with
-+	 * the ndr_fuzz_X header 4 byte header. For the sake of
-+	 * convenience (this is a developer only function), we mkdir
-+	 * -p the sub-directories when they are needed.
-+	 */
-+
-+	if (dump_dir == NULL) {
-+		return;
-+	}
-+
-+	temp_ctx = talloc_stackframe();
-+
-+	sub_dir = talloc_asprintf(temp_ctx, "%s/%s",
-+				  dump_dir,
-+				  iface_name);
-+	if (sub_dir == NULL) {
-+		talloc_free(temp_ctx);
-+		return;
-+	}
-+	ret = mkdir_p(sub_dir, 0755);
-+	if (ret && errno != EEXIST) {
-+		DBG_ERR("could not create %s\n", sub_dir);
-+		talloc_free(temp_ctx);
-+		return;
-+	}
-+
-+	blob.length = raw_blob.length + 4;
-+	blob.data = talloc_array(sub_dir,
-+				 uint8_t,
-+				 blob.length);
-+	if (blob.data == NULL) {
-+		DBG_ERR("could not allocate for fuzz seeds! (%s)\n",
-+			iface_name);
-+		talloc_free(temp_ctx);
-+		return;
-+	}
-+
-+	if (ndr64) {
-+		fuzz_flags = 4;
-+	}
-+	if (flags & NDR_IN) {
-+		fuzz_flags |= 1;
-+	} else if (flags & NDR_OUT) {
-+		fuzz_flags |= 2;
-+	}
-+
-+	SSVAL(blob.data, 0, fuzz_flags);
-+	SSVAL(blob.data, 2, opnum);
-+
-+	memcpy(&blob.data[4],
-+	       raw_blob.data,
-+	       raw_blob.length);
-+
-+	/*
-+	 * This matches how oss-fuzz names the corpus input files, due
-+	 * to a preference from libFuzzer
-+	 */
-+	rc = gnutls_hash_fast(GNUTLS_DIG_SHA1,
-+			      blob.data,
-+			      blob.length,
-+			      digest);
-+	if (rc < 0) {
-+		/*
-+		 * This prints a better error message, eg if SHA1 is
-+		 * disabled
-+		 */
-+		NTSTATUS status = gnutls_error_to_ntstatus(rc,
-+						  NT_STATUS_HASH_NOT_SUPPORTED);
-+		DBG_ERR("Failed to generate SHA1 to save fuzz seed: %s",
-+			nt_errstr(status));
-+		talloc_free(temp_ctx);
-+		return;
-+	}
-+
-+	digest_blob.data = digest;
-+	digest_blob.length = sizeof(digest);
-+	digest_hex = data_blob_hex_string_lower(temp_ctx, &digest_blob);
-+
-+	fname = talloc_asprintf(temp_ctx, "%s/%s",
-+				sub_dir,
-+				digest_hex);
-+	if (fname == NULL) {
-+		talloc_free(temp_ctx);
-+		return;
-+	}
-+
-+	/*
-+	 * If this fails, it is most likely because that file already
-+	 * exists.  This is fine, it means we already have this
-+	 * sample
-+	 */
-+	file_save(fname,
-+		  blob.data,
-+		  blob.length);
-+
-+	talloc_free(temp_ctx);
-+}
-+
-+#endif /*if DEVELOPER, enveloping _dcesrv_save_ndr_fuzz_seed() */
-diff --git a/librpc/rpc/dcerpc_pkt_auth.h b/librpc/rpc/dcerpc_pkt_auth.h
-new file mode 100644
-index 00000000000..c0d23b91c05
---- /dev/null
-+++ b/librpc/rpc/dcerpc_pkt_auth.h
-@@ -0,0 +1,58 @@
-+/*
-+   Unix SMB/CIFS implementation.
-+
-+   Copyright (C) Stefan Metzmacher 2010-2011
-+   Copyright (C) Andrew Tridgell 2010-2011
-+   Copyright (C) Simo Sorce 2010
-+
-+   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/>.
-+*/
-+
-+#ifndef __LIBRPC_RPC_DCERPC_PKT_AUTH_H__
-+#define __LIBRPC_RPC_DCERPC_PKT_AUTH_H__
-+
-+#include "replace.h"
-+#include <talloc.h>
-+#include "lib/util/data_blob.h"
-+#include "libcli/util/ntstatus.h"
-+#include "librpc/rpc/rpc_common.h"
-+#include "librpc/gen_ndr/dcerpc.h"
-+
-+NTSTATUS dcerpc_ncacn_pull_pkt_auth(const struct dcerpc_auth *auth_state,
-+				    struct gensec_security *gensec,
-+				    TALLOC_CTX *mem_ctx,
-+				    enum dcerpc_pkt_type ptype,
-+				    uint8_t required_flags,
-+				    uint8_t optional_flags,
-+				    uint8_t payload_offset,
-+				    DATA_BLOB *payload_and_verifier,
-+				    DATA_BLOB *raw_packet,
-+				    const struct ncacn_packet *pkt);
-+NTSTATUS dcerpc_ncacn_push_pkt_auth(const struct dcerpc_auth *auth_state,
-+				    struct gensec_security *gensec,
-+				    TALLOC_CTX *mem_ctx,
-+				    DATA_BLOB *raw_packet,
-+				    size_t sig_size,
-+				    uint8_t payload_offset,
-+				    const DATA_BLOB *payload,
-+				    const struct ncacn_packet *pkt);
-+struct tevent_req *dcerpc_read_ncacn_packet_send(TALLOC_CTX *mem_ctx,
-+						 struct tevent_context *ev,
-+						 struct tstream_context *stream);
-+NTSTATUS dcerpc_read_ncacn_packet_recv(struct tevent_req *req,
-+				       TALLOC_CTX *mem_ctx,
-+				       struct ncacn_packet **pkt,
-+				       DATA_BLOB *buffer);
-+
-+#endif
-diff --git a/librpc/rpc/dcerpc_util.c b/librpc/rpc/dcerpc_util.c
-index 925fb70ad7c..c878a2af094 100644
---- a/librpc/rpc/dcerpc_util.c
-+++ b/librpc/rpc/dcerpc_util.c
-@@ -29,10 +29,6 @@
- #include "librpc/gen_ndr/ndr_dcerpc.h"
- #include "rpc_common.h"
- #include "lib/util/bitmap.h"
--#include "auth/gensec/gensec.h"
--#include "lib/util/mkdir_p.h"
--#include "lib/crypto/gnutls_helpers.h"
--#include <gnutls/crypto.h>
- 
- #undef strncasecmp
- 
-@@ -486,340 +482,6 @@ NTSTATUS dcerpc_verify_ncacn_packet_header(const struct ncacn_packet *pkt,
- 	return NT_STATUS_OK;
- }
- 
--NTSTATUS dcerpc_ncacn_pull_pkt_auth(const struct dcerpc_auth *auth_state,
--				    struct gensec_security *gensec,
--				    TALLOC_CTX *mem_ctx,
--				    enum dcerpc_pkt_type ptype,
--				    uint8_t required_flags,
--				    uint8_t optional_flags,
--				    uint8_t payload_offset,
--				    DATA_BLOB *payload_and_verifier,
--				    DATA_BLOB *raw_packet,
--				    const struct ncacn_packet *pkt)
--{
--	NTSTATUS status;
--	struct dcerpc_auth auth;
--	uint32_t auth_length;
--
--	if (auth_state == NULL) {
--		return NT_STATUS_INTERNAL_ERROR;
--	}
--
--	status = dcerpc_verify_ncacn_packet_header(pkt, ptype,
--					payload_and_verifier->length,
--					required_flags, optional_flags);
--	if (!NT_STATUS_IS_OK(status)) {
--		return status;
--	}
--
--	switch (auth_state->auth_level) {
--	case DCERPC_AUTH_LEVEL_PRIVACY:
--	case DCERPC_AUTH_LEVEL_INTEGRITY:
--	case DCERPC_AUTH_LEVEL_PACKET:
--		break;
--
--	case DCERPC_AUTH_LEVEL_CONNECT:
--		if (pkt->auth_length != 0) {
--			break;
--		}
--		return NT_STATUS_OK;
--	case DCERPC_AUTH_LEVEL_NONE:
--		if (pkt->auth_length != 0) {
--			return NT_STATUS_ACCESS_DENIED;
--		}
--		return NT_STATUS_OK;
--
--	default:
--		return NT_STATUS_RPC_UNSUPPORTED_AUTHN_LEVEL;
--	}
--
--	if (pkt->auth_length == 0) {
--		return NT_STATUS_RPC_PROTOCOL_ERROR;
--	}
--
--	if (gensec == NULL) {
--		return NT_STATUS_INTERNAL_ERROR;
--	}
--
--	status = dcerpc_pull_auth_trailer(pkt, mem_ctx,
--					  payload_and_verifier,
--					  &auth, &auth_length, false);
--	if (!NT_STATUS_IS_OK(status)) {
--		return status;
--	}
--
--	if (payload_and_verifier->length < auth_length) {
--		/*
--		 * should be checked in dcerpc_pull_auth_trailer()
--		 */
--		return NT_STATUS_INTERNAL_ERROR;
--	}
--
--	payload_and_verifier->length -= auth_length;
--
--	if (payload_and_verifier->length < auth.auth_pad_length) {
--		/*
--		 * should be checked in dcerpc_pull_auth_trailer()
--		 */
--		return NT_STATUS_INTERNAL_ERROR;
--	}
--
--	if (auth.auth_type != auth_state->auth_type) {
--		return NT_STATUS_ACCESS_DENIED;
--	}
--
--	if (auth.auth_level != auth_state->auth_level) {
--		return NT_STATUS_ACCESS_DENIED;
--	}
--
--	if (auth.auth_context_id != auth_state->auth_context_id) {
--		return NT_STATUS_ACCESS_DENIED;
--	}
--
--	/* check signature or unseal the packet */
--	switch (auth_state->auth_level) {
--	case DCERPC_AUTH_LEVEL_PRIVACY:
--		status = gensec_unseal_packet(gensec,
--					      raw_packet->data + payload_offset,
--					      payload_and_verifier->length,
--					      raw_packet->data,
--					      raw_packet->length -
--					      auth.credentials.length,
--					      &auth.credentials);
--		if (!NT_STATUS_IS_OK(status)) {
--			return NT_STATUS_RPC_SEC_PKG_ERROR;
--		}
--		memcpy(payload_and_verifier->data,
--		       raw_packet->data + payload_offset,
--		       payload_and_verifier->length);
--		break;
--
--	case DCERPC_AUTH_LEVEL_INTEGRITY:
--	case DCERPC_AUTH_LEVEL_PACKET:
--		status = gensec_check_packet(gensec,
--					     payload_and_verifier->data,
--					     payload_and_verifier->length,
--					     raw_packet->data,
--					     raw_packet->length -
--					     auth.credentials.length,
--					     &auth.credentials);
--		if (!NT_STATUS_IS_OK(status)) {
--			return NT_STATUS_RPC_SEC_PKG_ERROR;
--		}
--		break;
--
--	case DCERPC_AUTH_LEVEL_CONNECT:
--		/* for now we ignore possible signatures here */
--		break;
--
--	default:
--		return NT_STATUS_RPC_UNSUPPORTED_AUTHN_LEVEL;
--	}
--
--	/*
--	 * remove the indicated amount of padding
--	 *
--	 * A possible overflow is checked above.
--	 */
--	payload_and_verifier->length -= auth.auth_pad_length;
--
--	return NT_STATUS_OK;
--}
--
--NTSTATUS dcerpc_ncacn_push_pkt_auth(const struct dcerpc_auth *auth_state,
--				    struct gensec_security *gensec,
--				    TALLOC_CTX *mem_ctx,
--				    DATA_BLOB *raw_packet,
--				    size_t sig_size,
--				    uint8_t payload_offset,
--				    const DATA_BLOB *payload,
--				    const struct ncacn_packet *pkt)
--{
--	TALLOC_CTX *frame = talloc_stackframe();
--	NTSTATUS status;
--	enum ndr_err_code ndr_err;
--	struct ndr_push *ndr = NULL;
--	uint32_t payload_length;
--	uint32_t whole_length;
--	DATA_BLOB blob = data_blob_null;
--	DATA_BLOB sig = data_blob_null;
--	struct dcerpc_auth _out_auth_info;
--	struct dcerpc_auth *out_auth_info = NULL;
--
--	*raw_packet = data_blob_null;
--
--	if (auth_state == NULL) {
--		TALLOC_FREE(frame);
--		return NT_STATUS_INTERNAL_ERROR;
--	}
--
--	switch (auth_state->auth_level) {
--	case DCERPC_AUTH_LEVEL_PRIVACY:
--	case DCERPC_AUTH_LEVEL_INTEGRITY:
--	case DCERPC_AUTH_LEVEL_PACKET:
--		if (sig_size == 0) {
--			TALLOC_FREE(frame);
--			return NT_STATUS_INTERNAL_ERROR;
--		}
--
--		if (gensec == NULL) {
--			TALLOC_FREE(frame);
--			return NT_STATUS_INTERNAL_ERROR;
--		}
--
--		_out_auth_info = (struct dcerpc_auth) {
--			.auth_type = auth_state->auth_type,
--			.auth_level = auth_state->auth_level,
--			.auth_context_id = auth_state->auth_context_id,
--		};
--		out_auth_info = &_out_auth_info;
--		break;
--
--	case DCERPC_AUTH_LEVEL_CONNECT:
--		/*
--		 * TODO: let the gensec mech decide if it wants to generate a
--		 *       signature that might be needed for schannel...
--		 */
--		if (sig_size != 0) {
--			TALLOC_FREE(frame);
--			return NT_STATUS_INTERNAL_ERROR;
--		}
--
--		if (gensec == NULL) {
--			TALLOC_FREE(frame);
--			return NT_STATUS_INTERNAL_ERROR;
--		}
--		break;
--
--	case DCERPC_AUTH_LEVEL_NONE:
--		if (sig_size != 0) {
--			TALLOC_FREE(frame);
--			return NT_STATUS_INTERNAL_ERROR;
--		}
--		break;
--
--	default:
--		TALLOC_FREE(frame);
--		return NT_STATUS_INTERNAL_ERROR;
--	}
--
--	ndr = ndr_push_init_ctx(frame);
--	if (ndr == NULL) {
--		TALLOC_FREE(frame);
--		return NT_STATUS_NO_MEMORY;
--	}
--
--	ndr_err = ndr_push_ncacn_packet(ndr, NDR_SCALARS|NDR_BUFFERS, pkt);
--	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
--		TALLOC_FREE(frame);
--		return ndr_map_error2ntstatus(ndr_err);
--	}
--
--	if (out_auth_info != NULL) {
--		/*
--		 * pad to 16 byte multiple in the payload portion of the
--		 * packet. This matches what w2k3 does. Note that we can't use
--		 * ndr_push_align() as that is relative to the start of the
--		 * whole packet, whereas w2k8 wants it relative to the start
--		 * of the stub.
--		 */
--		out_auth_info->auth_pad_length =
--			DCERPC_AUTH_PAD_LENGTH(payload->length);
--		ndr_err = ndr_push_zero(ndr, out_auth_info->auth_pad_length);
--		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
--			TALLOC_FREE(frame);
--			return ndr_map_error2ntstatus(ndr_err);
--		}
--
--		payload_length = payload->length +
--			out_auth_info->auth_pad_length;
--
--		ndr_err = ndr_push_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS,
--					       out_auth_info);
--		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
--			TALLOC_FREE(frame);
--			return ndr_map_error2ntstatus(ndr_err);
--		}
--
--		whole_length = ndr->offset;
--
--		ndr_err = ndr_push_zero(ndr, sig_size);
--		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
--			TALLOC_FREE(frame);
--			return ndr_map_error2ntstatus(ndr_err);
--		}
--	} else {
--		payload_length = payload->length;
--		whole_length = ndr->offset;
--	}
--
--	/* extract the whole packet as a blob */
--	blob = ndr_push_blob(ndr);
--
--	/*
--	 * Setup the frag and auth length in the packet buffer.
--	 * This is needed if the GENSEC mech does AEAD signing
--	 * of the packet headers. The signature itself will be
--	 * appended later.
--	 */
--	dcerpc_set_frag_length(&blob, blob.length);
--	dcerpc_set_auth_length(&blob, sig_size);
--
--	/* sign or seal the packet */
--	switch (auth_state->auth_level) {
--	case DCERPC_AUTH_LEVEL_PRIVACY:
--		status = gensec_seal_packet(gensec,
--					    frame,
--					    blob.data + payload_offset,
--					    payload_length,
--					    blob.data,
--					    whole_length,
--					    &sig);
--		if (!NT_STATUS_IS_OK(status)) {
--			TALLOC_FREE(frame);
--			return status;
--		}
--		break;
--
--	case DCERPC_AUTH_LEVEL_INTEGRITY:
--	case DCERPC_AUTH_LEVEL_PACKET:
--		status = gensec_sign_packet(gensec,
--					    frame,
--					    blob.data + payload_offset,
--					    payload_length,
--					    blob.data,
--					    whole_length,
--					    &sig);
--		if (!NT_STATUS_IS_OK(status)) {
--			TALLOC_FREE(frame);
--			return status;
--		}
--		break;
--
--	case DCERPC_AUTH_LEVEL_CONNECT:
--	case DCERPC_AUTH_LEVEL_NONE:
--		break;
--
--	default:
--		TALLOC_FREE(frame);
--		return NT_STATUS_INTERNAL_ERROR;
--	}
--
--	if (sig.length != sig_size) {
--		TALLOC_FREE(frame);
--		return NT_STATUS_RPC_SEC_PKG_ERROR;
--	}
--
--	if (sig_size != 0) {
--		memcpy(blob.data + whole_length, sig.data, sig_size);
--	}
--
--	*raw_packet = blob;
--	talloc_steal(mem_ctx, raw_packet->data);
--	TALLOC_FREE(frame);
--	return NT_STATUS_OK;
--}
--
- struct dcerpc_read_ncacn_packet_state {
- #if 0
- 	struct {
-@@ -1474,129 +1136,3 @@ void dcerpc_log_packet(const char *packet_log_dir,
- 		free(name);
- 	}
- }
--
--
--#ifdef DEVELOPER
--
--/*
-- * Save valid, well-formed DCE/RPC stubs to use as a seed for
-- * ndr_fuzz_X
-- */
--void dcerpc_save_ndr_fuzz_seed(TALLOC_CTX *mem_ctx,
--			       DATA_BLOB raw_blob,
--			       const char *dump_dir,
--			       const char *iface_name,
--			       int flags,
--			       int opnum,
--			       bool ndr64)
--{
--	char *fname = NULL;
--	const char *sub_dir = NULL;
--	TALLOC_CTX *temp_ctx = talloc_new(mem_ctx);
--	DATA_BLOB blob;
--	int ret, rc;
--	uint8_t digest[20];
--	DATA_BLOB digest_blob;
--	char *digest_hex;
--	uint16_t fuzz_flags = 0;
--
--	/*
--	 * We want to save the 'stub' in a per-pipe subdirectory, with
--	 * the ndr_fuzz_X header 4 byte header. For the sake of
--	 * convenience (this is a developer only function), we mkdir
--	 * -p the sub-directories when they are needed.
--	 */
--
--	if (dump_dir == NULL) {
--		return;
--	}
--
--	temp_ctx = talloc_stackframe();
--
--	sub_dir = talloc_asprintf(temp_ctx, "%s/%s",
--				  dump_dir,
--				  iface_name);
--	if (sub_dir == NULL) {
--		talloc_free(temp_ctx);
--		return;
--	}
--	ret = mkdir_p(sub_dir, 0755);
--	if (ret && errno != EEXIST) {
--		DBG_ERR("could not create %s\n", sub_dir);
--		talloc_free(temp_ctx);
--		return;
--	}
--
--	blob.length = raw_blob.length + 4;
--	blob.data = talloc_array(sub_dir,
--				 uint8_t,
--				 blob.length);
--	if (blob.data == NULL) {
--		DBG_ERR("could not allocate for fuzz seeds! (%s)\n",
--			iface_name);
--		talloc_free(temp_ctx);
--		return;
--	}
--
--	if (ndr64) {
--		fuzz_flags = 4;
--	}
--	if (flags & NDR_IN) {
--		fuzz_flags |= 1;
--	} else if (flags & NDR_OUT) {
--		fuzz_flags |= 2;
--	}
--
--	SSVAL(blob.data, 0, fuzz_flags);
--	SSVAL(blob.data, 2, opnum);
--
--	memcpy(&blob.data[4],
--	       raw_blob.data,
--	       raw_blob.length);
--
--	/*
--	 * This matches how oss-fuzz names the corpus input files, due
--	 * to a preference from libFuzzer
--	 */
--	rc = gnutls_hash_fast(GNUTLS_DIG_SHA1,
--			      blob.data,
--			      blob.length,
--			      digest);
--	if (rc < 0) {
--		/*
--		 * This prints a better error message, eg if SHA1 is
--		 * disabled
--		 */
--		NTSTATUS status = gnutls_error_to_ntstatus(rc,
--						  NT_STATUS_HASH_NOT_SUPPORTED);
--		DBG_ERR("Failed to generate SHA1 to save fuzz seed: %s",
--			nt_errstr(status));
--		talloc_free(temp_ctx);
--		return;
--	}
--
--	digest_blob.data = digest;
--	digest_blob.length = sizeof(digest);
--	digest_hex = data_blob_hex_string_lower(temp_ctx, &digest_blob);
--
--	fname = talloc_asprintf(temp_ctx, "%s/%s",
--				sub_dir,
--				digest_hex);
--	if (fname == NULL) {
--		talloc_free(temp_ctx);
--		return;
--	}
--
--	/*
--	 * If this fails, it is most likely because that file already
--	 * exists.  This is fine, it means we already have this
--	 * sample
--	 */
--	file_save(fname,
--		  blob.data,
--		  blob.length);
--
--	talloc_free(temp_ctx);
--}
--
--#endif /*if DEVELOPER, enveloping _dcesrv_save_ndr_fuzz_seed() */
-diff --git a/librpc/rpc/dcerpc_util.h b/librpc/rpc/dcerpc_util.h
-index 0ecaf428c3c..a9bc7bd3832 100644
---- a/librpc/rpc/dcerpc_util.h
-+++ b/librpc/rpc/dcerpc_util.h
-@@ -74,24 +74,6 @@ NTSTATUS dcerpc_verify_ncacn_packet_header(const struct ncacn_packet *pkt,
- 					   size_t max_auth_info,
- 					   uint8_t required_flags,
- 					   uint8_t optional_flags);
--NTSTATUS dcerpc_ncacn_pull_pkt_auth(const struct dcerpc_auth *auth_state,
--				    struct gensec_security *gensec,
--				    TALLOC_CTX *mem_ctx,
--				    enum dcerpc_pkt_type ptype,
--				    uint8_t required_flags,
--				    uint8_t optional_flags,
--				    uint8_t payload_offset,
--				    DATA_BLOB *payload_and_verifier,
--				    DATA_BLOB *raw_packet,
--				    const struct ncacn_packet *pkt);
--NTSTATUS dcerpc_ncacn_push_pkt_auth(const struct dcerpc_auth *auth_state,
--				    struct gensec_security *gensec,
--				    TALLOC_CTX *mem_ctx,
--				    DATA_BLOB *raw_packet,
--				    size_t sig_size,
--				    uint8_t payload_offset,
--				    const DATA_BLOB *payload,
--				    const struct ncacn_packet *pkt);
- struct tevent_req *dcerpc_read_ncacn_packet_send(TALLOC_CTX *mem_ctx,
- 						 struct tevent_context *ev,
- 						 struct tstream_context *stream);
-diff --git a/librpc/rpc/dcesrv_auth.c b/librpc/rpc/dcesrv_auth.c
-index f7919ebf575..8dda86d88e2 100644
---- a/librpc/rpc/dcesrv_auth.c
-+++ b/librpc/rpc/dcesrv_auth.c
-@@ -24,6 +24,7 @@
- #include "librpc/rpc/dcesrv_core.h"
- #include "librpc/rpc/dcesrv_core_proto.h"
- #include "librpc/rpc/dcerpc_util.h"
-+#include "librpc/rpc/dcerpc_pkt_auth.h"
- #include "librpc/gen_ndr/ndr_dcerpc.h"
- #include "auth/credentials/credentials.h"
- #include "auth/gensec/gensec.h"
-diff --git a/librpc/wscript_build b/librpc/wscript_build
-index e4632d538a4..59d6c31363d 100644
---- a/librpc/wscript_build
-+++ b/librpc/wscript_build
-@@ -655,12 +655,24 @@ bld.SAMBA_LIBRARY('ndr',
-     )
- 
- bld.SAMBA_LIBRARY('dcerpc-binding',
--    source='rpc/dcerpc_error.c rpc/binding.c rpc/dcerpc_util.c rpc/binding_handle.c',
--    deps='ndr tevent NDR_DCERPC LIBTSOCKET tevent-util gensec',
-+    source='''
-+    rpc/dcerpc_error.c
-+    rpc/binding.c
-+    rpc/dcerpc_util.c
-+    rpc/binding_handle.c
-+    ''',
-+    deps='ndr tevent NDR_DCERPC LIBTSOCKET tevent-util',
-     pc_files=[],
-     public_headers='rpc/rpc_common.h',
-     vnum='0.0.1')
- 
-+bld.SAMBA_LIBRARY('dcerpc-pkt-auth',
-+                  private_library=True,
-+                  source='''
-+                   rpc/dcerpc_pkt_auth.c
-+                   ''',
-+                  deps='dcerpc-binding gensec')
-+
- bld.SAMBA_LIBRARY('dcerpc-server-core',
-     source='''
-            rpc/dcesrv_core.c
-@@ -669,7 +681,14 @@ bld.SAMBA_LIBRARY('dcerpc-server-core',
-            rpc/dcesrv_reply.c
-            rpc/dcesrv_handles.c
-            ''',
--    deps='ndr dcerpc-binding samba-util-core gnutls GNUTLS_HELPERS',
-+    deps='''
-+    ndr
-+    dcerpc-binding
-+    samba-util-core
-+    gnutls
-+    GNUTLS_HELPERS
-+    dcerpc-pkt-auth
-+    ''',
-     pc_files=[],
-     public_headers='rpc/dcesrv_core.h',
-     autoproto='rpc/dcesrv_core_proto.h',
-diff --git a/source3/wscript_build b/source3/wscript_build
-index 5d04fcb41d1..a143477a506 100644
---- a/source3/wscript_build
-+++ b/source3/wscript_build
-@@ -1034,9 +1034,11 @@ bld.SAMBA3_LIBRARY('cli_spoolss',
-                           rpc_client/init_spoolss.c
-                           ''',
-                    deps='''
--                        RPC_NDR_SPOOLSS
--                        smbconf
--                        secrets3''',
-+                   RPC_NDR_SPOOLSS
-+                   smbconf
-+                   secrets3
-+                   gensec
-+                   ''',
-                    private_library=True)
- 
- bld.SAMBA3_SUBSYSTEM('LIBCLI_WINREG',
-diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c
-index f97263dcc5b..4847e8a0200 100644
---- a/source4/librpc/rpc/dcerpc.c
-+++ b/source4/librpc/rpc/dcerpc.c
-@@ -27,6 +27,7 @@
- #include "librpc/rpc/dcerpc.h"
- #include "librpc/rpc/dcerpc_proto.h"
- #include "librpc/rpc/dcerpc_util.h"
-+#include "librpc/rpc/dcerpc_pkt_auth.h"
- #include "librpc/gen_ndr/ndr_misc.h"
- #include "librpc/gen_ndr/ndr_dcerpc.h"
- #include "auth/gensec/gensec.h"
-diff --git a/source4/librpc/wscript_build b/source4/librpc/wscript_build
-index ea9c4853d7a..511008d919d 100644
---- a/source4/librpc/wscript_build
-+++ b/source4/librpc/wscript_build
-@@ -157,7 +157,26 @@ bld.SAMBA_LIBRARY('dcerpc',
- 	rpc/dcerpc_roh_channel_in.c rpc/dcerpc_roh_channel_out.c rpc/dcerpc_roh.c
- 	rpc/dcerpc_connect.c rpc/dcerpc_secondary.c''',
- 	pc_files='dcerpc.pc',
--	deps='samba_socket LIBCLI_RESOLVE LIBCLI_SMB LIBCLI_SMB2 ndr NDR_DCERPC RPC_NDR_EPMAPPER NDR_SCHANNEL RPC_NDR_NETLOGON RPC_NDR_MGMT gensec LIBCLI_AUTH smbclient-raw LP_RESOLVE tevent-util dcerpc-binding param_options http',
-+	deps='''
-+        samba_socket
-+        LIBCLI_RESOLVE
-+        LIBCLI_SMB
-+        LIBCLI_SMB2
-+        ndr
-+        NDR_DCERPC
-+        RPC_NDR_EPMAPPER
-+        NDR_SCHANNEL
-+        RPC_NDR_NETLOGON
-+        RPC_NDR_MGMT
-+        gensec
-+        LIBCLI_AUTH
-+        smbclient-raw
-+        LP_RESOLVE
-+        tevent-util
-+        dcerpc-binding
-+        dcerpc-pkt-auth
-+        param_options
-+        http''',
- 	autoproto='rpc/dcerpc_proto.h',
- 	public_deps='samba-credentials tevent talloc',
- 	public_headers='''rpc/dcerpc.h''',
--- 
-2.25.1
-
-
-From fba123a44e0afd9d2377e3e45b0b2d88aecb2136 Mon Sep 17 00:00:00 2001
-From: Stefan Metzmacher <metze@samba.org>
-Date: Fri, 13 Nov 2020 11:25:41 +0100
-Subject: [PATCH 3/9] CVE-2021-23192: dcesrv_core: add better debugging to
- dcesrv_fault_disconnect()
-
-It's better to see the location that triggered the fault.
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14875
-
-Signed-off-by: Stefan Metzmacher <metze@samba.org>
-Reviewed-by: Samuel Cabrero <scabrero@samba.org>
----
- librpc/rpc/dcesrv_core.c | 29 ++++++++++++++++++++++++-----
- 1 file changed, 24 insertions(+), 5 deletions(-)
-
-diff --git a/librpc/rpc/dcesrv_core.c b/librpc/rpc/dcesrv_core.c
-index 74730f22c7c..0c2d83b4b17 100644
---- a/librpc/rpc/dcesrv_core.c
-+++ b/librpc/rpc/dcesrv_core.c
-@@ -705,19 +705,38 @@ static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason)
- 	return NT_STATUS_OK;
- }
- 
--static NTSTATUS dcesrv_fault_disconnect(struct dcesrv_call_state *call,
--				 uint32_t fault_code)
-+static NTSTATUS _dcesrv_fault_disconnect_flags(struct dcesrv_call_state *call,
-+					       uint32_t fault_code,
-+					       uint8_t extra_flags,
-+					       const char *func,
-+					       const char *location)
- {
-+	const char *reason = NULL;
-+
-+	reason = talloc_asprintf(call, "%s:%s: fault=%u (%s) flags=0x%x",
-+				 func, location,
-+				 fault_code,
-+				 dcerpc_errstr(call, fault_code),
-+				 extra_flags);
-+	if (reason == NULL) {
-+		reason = location;
-+	}
-+
- 	/*
- 	 * We add the call to the pending_call_list
- 	 * in order to defer the termination.
- 	 */
--	dcesrv_call_disconnect_after(call, "dcesrv_fault_disconnect");
- 
--	return dcesrv_fault_with_flags(call, fault_code,
--				       DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
-+	dcesrv_call_disconnect_after(call, reason);
-+
-+	return dcesrv_fault_with_flags(call, fault_code, extra_flags);
- }
- 
-+#define dcesrv_fault_disconnect(call, fault_code) \
-+	_dcesrv_fault_disconnect_flags(call, fault_code, \
-+		DCERPC_PFC_FLAG_DID_NOT_EXECUTE, \
-+		__func__, __location__)
-+
- static int dcesrv_connection_context_destructor(struct dcesrv_connection_context *c)
- {
- 	DLIST_REMOVE(c->conn->contexts, c);
--- 
-2.25.1
-
-
-From 937d9c1b4926aa4b511d1eb4f9b1729fb20ac9fa Mon Sep 17 00:00:00 2001
-From: Stefan Metzmacher <metze@samba.org>
-Date: Fri, 13 Nov 2020 11:27:19 +0100
-Subject: [PATCH 4/9] CVE-2021-23192: dcesrv_core: add
- dcesrv_fault_disconnect0() that skips DCERPC_PFC_FLAG_DID_NOT_EXECUTE
-
-That makes the callers much simpler and allow better debugging.
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14875
-
-Signed-off-by: Stefan Metzmacher <metze@samba.org>
-Reviewed-by: Samuel Cabrero <scabrero@samba.org>
----
- librpc/rpc/dcesrv_core.c | 47 ++++++++++++++--------------------------
- 1 file changed, 16 insertions(+), 31 deletions(-)
-
-diff --git a/librpc/rpc/dcesrv_core.c b/librpc/rpc/dcesrv_core.c
-index 0c2d83b4b17..ffaa9019d4b 100644
---- a/librpc/rpc/dcesrv_core.c
-+++ b/librpc/rpc/dcesrv_core.c
-@@ -736,6 +736,9 @@ static NTSTATUS _dcesrv_fault_disconnect_flags(struct dcesrv_call_state *call,
- 	_dcesrv_fault_disconnect_flags(call, fault_code, \
- 		DCERPC_PFC_FLAG_DID_NOT_EXECUTE, \
- 		__func__, __location__)
-+#define dcesrv_fault_disconnect0(call, fault_code) \
-+	_dcesrv_fault_disconnect_flags(call, fault_code, 0, \
-+		__func__, __location__)
- 
- static int dcesrv_connection_context_destructor(struct dcesrv_connection_context *c)
- {
-@@ -2097,10 +2100,7 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
- 			 * Note that we don't check against the negotiated
- 			 * max_recv_frag, but a hard coded value.
- 			 */
--			dcesrv_call_disconnect_after(call,
--				"dcesrv_auth_request - frag_length too large");
--			return dcesrv_fault(call,
--					DCERPC_NCA_S_PROTO_ERROR);
-+			return dcesrv_fault_disconnect0(call, DCERPC_NCA_S_PROTO_ERROR);
- 		}
- 
- 		if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
-@@ -2110,10 +2110,7 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
- 				 * if DCERPC_PFC_FLAG_CONC_MPX was negotiated.
- 				 */
- 				if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
--					dcesrv_call_disconnect_after(call,
--						"dcesrv_auth_request - "
--						"existing pending call without CONN_MPX");
--					return dcesrv_fault(call,
-+					return dcesrv_fault_disconnect0(call,
- 						DCERPC_NCA_S_PROTO_ERROR);
- 				}
- 			}
-@@ -2131,10 +2128,7 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
- 					TALLOC_FREE(call);
- 					call = dce_conn->incoming_fragmented_call_list;
- 				}
--				dcesrv_call_disconnect_after(call,
--					"dcesrv_auth_request - "
--					"existing fragmented call");
--				return dcesrv_fault(call,
-+				return dcesrv_fault_disconnect0(call,
- 						DCERPC_NCA_S_PROTO_ERROR);
- 			}
- 			if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) {
-@@ -2155,10 +2149,7 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
- 			existing = dcesrv_find_fragmented_call(dce_conn,
- 							call->pkt.call_id);
- 			if (existing == NULL) {
--				dcesrv_call_disconnect_after(call,
--					"dcesrv_auth_request - "
--					"no existing fragmented call");
--				return dcesrv_fault(call,
-+				return dcesrv_fault_disconnect0(call,
- 						DCERPC_NCA_S_PROTO_ERROR);
- 			}
- 			er = &existing->pkt.u.request;
-@@ -2211,12 +2202,10 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
- 			 * here, because we don't want to set
- 			 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
- 			 */
--			dcesrv_call_disconnect_after(call,
--						"dcesrv_auth_request - failed");
- 			if (call->fault_code == 0) {
- 				call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
- 			}
--			return dcesrv_fault(call, call->fault_code);
-+			return dcesrv_fault_disconnect0(call, call->fault_code);
- 		}
- 	}
- 
-@@ -2233,20 +2222,17 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
- 		 */
- 		available = dce_conn->max_total_request_size;
- 		if (er->stub_and_verifier.length > available) {
--			dcesrv_call_disconnect_after(existing,
--				"dcesrv_auth_request - existing payload too large");
--			return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
-+			return dcesrv_fault_disconnect0(existing,
-+					DCERPC_FAULT_ACCESS_DENIED);
- 		}
- 		available -= er->stub_and_verifier.length;
- 		if (nr->alloc_hint > available) {
--			dcesrv_call_disconnect_after(existing,
--				"dcesrv_auth_request - alloc hint too large");
--			return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
-+			return dcesrv_fault_disconnect0(existing,
-+					DCERPC_FAULT_ACCESS_DENIED);
- 		}
- 		if (nr->stub_and_verifier.length > available) {
--			dcesrv_call_disconnect_after(existing,
--				"dcesrv_auth_request - new payload too large");
--			return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
-+			return dcesrv_fault_disconnect0(existing,
-+					DCERPC_FAULT_ACCESS_DENIED);
- 		}
- 		alloc_hint = er->stub_and_verifier.length + nr->alloc_hint;
- 		/* allocate at least 1 byte */
-@@ -2285,9 +2271,8 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
- 		 * Up to 4 MByte are allowed by all fragments
- 		 */
- 		if (call->pkt.u.request.alloc_hint > dce_conn->max_total_request_size) {
--			dcesrv_call_disconnect_after(call,
--				"dcesrv_auth_request - initial alloc hint too large");
--			return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
-+			return dcesrv_fault_disconnect0(call,
-+					DCERPC_FAULT_ACCESS_DENIED);
- 		}
- 		dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
- 		return NT_STATUS_OK;
--- 
-2.25.1
-
-
-From 480bfd0a809705966d782839f02f899fc3f68241 Mon Sep 17 00:00:00 2001
-From: Stefan Metzmacher <metze@samba.org>
-Date: Wed, 11 Nov 2020 16:59:06 +0100
-Subject: [PATCH 5/9] CVE-2021-23192: python/tests/dcerpc: change
- assertNotEquals() into assertNotEqual()
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14875
-
-Signed-off-by: Stefan Metzmacher <metze@samba.org>
-Reviewed-by: Samuel Cabrero <scabrero@samba.org>
----
- python/samba/tests/dcerpc/raw_protocol.py | 288 +++++++++++-----------
- python/samba/tests/dcerpc/raw_testcase.py |  14 +-
- 2 files changed, 151 insertions(+), 151 deletions(-)
-
-diff --git a/python/samba/tests/dcerpc/raw_protocol.py b/python/samba/tests/dcerpc/raw_protocol.py
-index dc13d41c6a2..cbd398d5290 100755
---- a/python/samba/tests/dcerpc/raw_protocol.py
-+++ b/python/samba/tests/dcerpc/raw_protocol.py
-@@ -65,7 +65,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         pfc_flags=rep_pfc_flags, auth_length=0)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 4)
-         self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port)
-         self.assertPadding(rep.u._pad1, 2)
-@@ -86,7 +86,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         rep = self.recv_pdu()
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
-@@ -108,7 +108,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         auth_length=0)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 4)
-         self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port)
-         self.assertPadding(rep.u._pad1, 2)
-@@ -128,7 +128,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         pfc_flags=rep_pfc_flags, auth_length=0)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 0)
-         self.assertEqual(rep.u.secondary_address, "")
-         self.assertPadding(rep.u._pad1, 2)
-@@ -149,7 +149,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         rep = self.recv_pdu()
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
-@@ -396,7 +396,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         auth_length=0)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 4)
-         self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port)
-         self.assertPadding(rep.u._pad1, 2)
-@@ -469,7 +469,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         auth_length=0)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 4)
-         self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port)
-         self.assertPadding(rep.u._pad1, 2)
-@@ -489,7 +489,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         pfc_flags=req.pfc_flags |
-                         dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, 0)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertEqual(rep.u.flags, 0)
-@@ -521,7 +521,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         auth_length=0)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 4)
-         self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port)
-         self.assertPadding(rep.u._pad1, 2)
-@@ -541,7 +541,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         auth_length=0)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 0)
-         self.assertPadding(rep.u._pad1, 2)
-         self.assertEqual(rep.u.num_results, 1)
-@@ -562,7 +562,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         pfc_flags=req.pfc_flags |
-                         dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, ctx1.context_id)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertEqual(rep.u.flags, 0)
-@@ -589,7 +589,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         auth_length=0)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 4)
-         self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port)
-         self.assertPadding(rep.u._pad1, 2)
-@@ -609,7 +609,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         auth_length=0)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 0)
-         self.assertPadding(rep.u._pad1, 2)
-         self.assertEqual(rep.u.num_results, 1)
-@@ -630,7 +630,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         pfc_flags=req.pfc_flags |
-                         dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, 0)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertEqual(rep.u.flags, 0)
-@@ -646,7 +646,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         auth_length=0)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 0)
-         self.assertPadding(rep.u._pad1, 2)
-         self.assertEqual(rep.u.num_results, 1)
-@@ -705,7 +705,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         auth_length=0)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 4)
-         self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port)
-         self.assertPadding(rep.u._pad1, 2)
-@@ -732,7 +732,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         pfc_flags=req.pfc_flags |
-                         dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, 0)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertEqual(rep.u.flags, 0)
-@@ -765,7 +765,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         auth_length=0)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 4)
-         self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port)
-         self.assertPadding(rep.u._pad1, 2)
-@@ -794,7 +794,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         pfc_flags=req.pfc_flags |
-                         dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, 0)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertEqual(rep.u.flags, 0)
-@@ -826,7 +826,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         auth_length=0)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 4)
-         self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port)
-         self.assertPadding(rep.u._pad1, 2)
-@@ -855,7 +855,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         auth_length=0)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 0)
-         self.assertPadding(rep.u._pad1, 2)
-         self.assertEqual(rep.u.num_results, 1)
-@@ -876,7 +876,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         pfc_flags=req.pfc_flags |
-                         dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, ctx1a.context_id)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertEqual(rep.u.flags, 0)
-@@ -902,7 +902,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         auth_length=0)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 4)
-         self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port)
-         self.assertPadding(rep.u._pad1, 2)
-@@ -928,7 +928,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         auth_length=0)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 0)
-         self.assertPadding(rep.u._pad1, 2)
-         self.assertEqual(rep.u.num_results, 1)
-@@ -947,7 +947,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         rep = self.recv_pdu()
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
-@@ -966,7 +966,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         auth_length=0)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 0)
-         self.assertPadding(rep.u._pad1, 2)
-         self.assertEqual(rep.u.num_results, 1)
-@@ -985,7 +985,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         rep = self.recv_pdu()
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
-@@ -1004,7 +1004,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         auth_length=0)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 0)
-         self.assertPadding(rep.u._pad1, 2)
-         self.assertEqual(rep.u.num_results, 1)
-@@ -1023,7 +1023,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         rep = self.recv_pdu()
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
-@@ -1049,7 +1049,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         auth_length=0)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 0)
-         self.assertPadding(rep.u._pad1, 2)
-         self.assertEqual(rep.u.num_results, 2)
-@@ -1073,7 +1073,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         rep = self.recv_pdu()
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
-@@ -1085,7 +1085,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         auth_length=0)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 0)
-         self.assertPadding(rep.u._pad1, 2)
-         self.assertEqual(rep.u.num_results, 2)
-@@ -1109,7 +1109,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         rep = self.recv_pdu()
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
-@@ -1122,7 +1122,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         rep = self.recv_pdu()
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
-@@ -1134,7 +1134,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         auth_length=0)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 0)
-         self.assertPadding(rep.u._pad1, 2)
-         self.assertEqual(rep.u.num_results, 2)
-@@ -1158,7 +1158,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         rep = self.recv_pdu()
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
-@@ -1171,7 +1171,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         rep = self.recv_pdu()
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
-@@ -1197,7 +1197,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         auth_length=0)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 0)
-         self.assertPadding(rep.u._pad1, 2)
-         self.assertEqual(rep.u.num_results, 2)
-@@ -1221,7 +1221,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         rep = self.recv_pdu()
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
-@@ -1233,7 +1233,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         auth_length=0)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 0)
-         self.assertPadding(rep.u._pad1, 2)
-         self.assertEqual(rep.u.num_results, 2)
-@@ -1257,7 +1257,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         rep = self.recv_pdu()
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
-@@ -1282,7 +1282,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         auth_length=0)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 4)
-         self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port)
-         self.assertPadding(rep.u._pad1, 2)
-@@ -1318,7 +1318,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         auth_length=0)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 4)
-         self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port)
-         self.assertPadding(rep.u._pad1, 2)
-@@ -1352,7 +1352,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         auth_length=0)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 4)
-         self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port)
-         self.assertPadding(rep.u._pad1, 2)
-@@ -1424,7 +1424,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         auth_length=0)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 4)
-         self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port)
-         self.assertPadding(rep.u._pad1, 2)
-@@ -1459,7 +1459,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         auth_length=0)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 4)
-         self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port)
-         self.assertPadding(rep.u._pad1, 2)
-@@ -1494,7 +1494,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         auth_length=0)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 4)
-         self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port)
-         self.assertPadding(rep.u._pad1, 2)
-@@ -1617,7 +1617,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 4)
-         self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port)
-         self.assertPadding(rep.u._pad1, 2)
-@@ -1638,7 +1638,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         rep = self.recv_pdu()
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
-@@ -1658,7 +1658,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         # We get a fault back
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertEqual(rep.u.flags, 0)
-@@ -1708,7 +1708,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         auth_length=0)
-         self.assertEqual(rep.u.max_xmit_frag, rep_both)
-         self.assertEqual(rep.u.max_recv_frag, rep_both)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 4)
-         self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port)
-         self.assertPadding(rep.u._pad1, 2)
-@@ -1760,7 +1760,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         rep = self.recv_pdu(ndr_print=True, hexdump=True)
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
-@@ -1775,7 +1775,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         rep = self.recv_pdu()
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
-@@ -1791,7 +1791,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         # We get a fault
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, 0)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertEqual(rep.u.flags, 0)
-@@ -1866,7 +1866,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         auth_length=0)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 4)
-         self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port)
-         self.assertPadding(rep.u._pad1, 2)
-@@ -1888,7 +1888,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         rep = self.recv_pdu()
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
-@@ -1902,7 +1902,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         rep = self.recv_pdu()
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
-@@ -1916,7 +1916,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         rep = self.recv_pdu()
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
-@@ -1994,7 +1994,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                 # We get a fault back
-                 self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id,
-                                 auth_length=0)
--                self.assertNotEquals(rep.u.alloc_hint, 0)
-+                self.assertNotEqual(rep.u.alloc_hint, 0)
-                 self.assertEqual(rep.u.context_id, req.u.context_id)
-                 self.assertEqual(rep.u.cancel_count, 0)
-                 self.assertEqual(rep.u.flags, 0)
-@@ -2014,7 +2014,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                 # We get a fault back
-                 self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id,
-                                 auth_length=0)
--                self.assertNotEquals(rep.u.alloc_hint, 0)
-+                self.assertNotEqual(rep.u.alloc_hint, 0)
-                 self.assertEqual(rep.u.context_id, req.u.context_id)
-                 self.assertEqual(rep.u.cancel_count, 0)
-                 self.assertEqual(rep.u.flags, 0)
-@@ -2036,7 +2036,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-             # We get a fault back
-             self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id,
-                             auth_length=0)
--            self.assertNotEquals(rep.u.alloc_hint, 0)
-+            self.assertNotEqual(rep.u.alloc_hint, 0)
-             self.assertEqual(rep.u.context_id, req.u.context_id)
-             self.assertEqual(rep.u.cancel_count, 0)
-             self.assertEqual(rep.u.flags, 0)
-@@ -2052,7 +2052,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         rep = self.recv_pdu()
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
-@@ -2098,7 +2098,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-             # We get a fault back
-             self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id,
-                             auth_length=0)
--            self.assertNotEquals(rep.u.alloc_hint, 0)
-+            self.assertNotEqual(rep.u.alloc_hint, 0)
-             self.assertEqual(rep.u.context_id, 0)
-             self.assertEqual(rep.u.cancel_count, 0)
-             self.assertEqual(rep.u.flags, 0)
-@@ -2128,7 +2128,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-             # We get a fault back
-             self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id,
-                             auth_length=0)
--            self.assertNotEquals(rep.u.alloc_hint, 0)
-+            self.assertNotEqual(rep.u.alloc_hint, 0)
-             self.assertEqual(rep.u.context_id, req.u.context_id)
-             self.assertEqual(rep.u.cancel_count, 0)
-             self.assertEqual(rep.u.flags, 0)
-@@ -2195,7 +2195,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         dcerpc.DCERPC_PFC_FLAG_LAST |
-                         dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, 0)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertEqual(rep.u.flags, 0)
-@@ -2243,7 +2243,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         rep = self.recv_pdu()
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
-@@ -2277,7 +2277,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         rep = self.recv_pdu()
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
-@@ -2313,7 +2313,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         pfc_flags=dcerpc.DCERPC_PFC_FLAG_FIRST |
-                         dcerpc.DCERPC_PFC_FLAG_LAST,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertEqual(rep.u.flags, 0)
-@@ -2341,7 +2341,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         rep = self.recv_pdu()
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
-@@ -2376,7 +2376,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         rep = self.recv_pdu()
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
-@@ -2390,7 +2390,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         rep = self.recv_pdu()
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
-@@ -2415,7 +2415,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         rep = self.recv_pdu()
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id & 0xff)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
-@@ -2450,7 +2450,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         rep = self.recv_pdu()
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id & 0xff)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
-@@ -2464,7 +2464,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         rep = self.recv_pdu()
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id & 0xff)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
-@@ -2503,7 +2503,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         rep = self.recv_pdu()
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id & 0xff)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
-@@ -2517,7 +2517,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         rep = self.recv_pdu()
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id & 0xff)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
-@@ -2552,7 +2552,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         rep = self.recv_pdu()
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req1.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req1.u.context_id)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertEqual(rep.u.flags, 0)
-@@ -2600,7 +2600,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         rep = self.recv_pdu()
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req2.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, 0)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertEqual(rep.u.flags, 0)
-@@ -2650,7 +2650,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 4)
-         self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port)
-         self.assertPadding(rep.u._pad1, 2)
-@@ -2660,7 +2660,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         self.assertEqual(rep.u.ctx_list[0].reason,
-                           dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
-         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
--        self.assertNotEquals(len(rep.u.auth_info), 0)
-+        self.assertNotEqual(len(rep.u.auth_info), 0)
-         a = self.parse_auth(rep.u.auth_info)
- 
-         from_server = a.credentials
-@@ -2691,7 +2691,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         self.assertEqual(rep.u.ctx_list[0].reason,
-                           dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
-         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
--        self.assertNotEquals(len(rep.u.auth_info), 0)
-+        self.assertNotEqual(len(rep.u.auth_info), 0)
-         a = self.parse_auth(rep.u.auth_info)
- 
-         from_server = a.credentials
-@@ -2707,7 +2707,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         rep = self.recv_pdu()
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id & 0xff)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
-@@ -2727,7 +2727,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         # We don't get an auth_info back
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id & 0xff)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
-@@ -2747,7 +2747,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         # We get a fault back
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertEqual(rep.u.flags, 0)
-@@ -2805,7 +2805,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 4)
-         self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port)
-         self.assertPadding(rep.u._pad1, 2)
-@@ -2815,7 +2815,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         self.assertEqual(rep.u.ctx_list[0].reason,
-                           dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
-         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
--        self.assertNotEquals(len(rep.u.auth_info), 0)
-+        self.assertNotEqual(len(rep.u.auth_info), 0)
-         a = self.parse_auth(rep.u.auth_info)
- 
-         from_server = a.credentials
-@@ -2846,7 +2846,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         self.assertEqual(rep.u.ctx_list[0].reason,
-                           dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
-         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
--        self.assertNotEquals(len(rep.u.auth_info), 0)
-+        self.assertNotEqual(len(rep.u.auth_info), 0)
-         a = self.parse_auth(rep.u.auth_info)
- 
-         from_server = a.credentials
-@@ -2868,7 +2868,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         # We get a fault back
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertEqual(rep.u.flags, 0)
-@@ -2926,7 +2926,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         assoc_group_id = rep.u.assoc_group_id
-         self.assertEqual(rep.u.secondary_address_size, 4)
-         self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port)
-@@ -2937,7 +2937,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         self.assertEqual(rep.u.ctx_list[0].reason,
-                           dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
-         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
--        self.assertNotEquals(len(rep.u.auth_info), 0)
-+        self.assertNotEqual(len(rep.u.auth_info), 0)
-         a = self.parse_auth(rep.u.auth_info)
- 
-         from_server = a.credentials
-@@ -2961,7 +2961,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         pfc_flags=req.pfc_flags |
-                         dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, 0)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertEqual(rep.u.flags, 0)
-@@ -3009,7 +3009,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 4)
-         self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port)
-         self.assertPadding(rep.u._pad1, 2)
-@@ -3019,7 +3019,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         self.assertEqual(rep.u.ctx_list[0].reason,
-                           dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
-         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
--        self.assertNotEquals(len(rep.u.auth_info), 0)
-+        self.assertNotEqual(len(rep.u.auth_info), 0)
-         a = self.parse_auth(rep.u.auth_info)
- 
-         from_server = a.credentials
-@@ -3047,7 +3047,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         # We get a fault back
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertEqual(rep.u.flags, 0)
-@@ -3098,7 +3098,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 4)
-         self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port)
-         self.assertPadding(rep.u._pad1, 2)
-@@ -3108,7 +3108,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         self.assertEqual(rep.u.ctx_list[0].reason,
-                           dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
-         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
--        self.assertNotEquals(len(rep.u.auth_info), 0)
-+        self.assertNotEqual(len(rep.u.auth_info), 0)
-         a = self.parse_auth(rep.u.auth_info)
- 
-         from_server = a.credentials
-@@ -3137,7 +3137,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         self.assertEqual(rep.u.ctx_list[0].reason,
-                           dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
-         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
--        self.assertNotEquals(len(rep.u.auth_info), 0)
-+        self.assertNotEqual(len(rep.u.auth_info), 0)
-         a = self.parse_auth(rep.u.auth_info)
- 
-         from_server = a.credentials
-@@ -3153,7 +3153,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         rep = self.recv_pdu()
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id & 0xff)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
-@@ -3173,7 +3173,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         # We don't get an auth_info back
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
-@@ -3205,7 +3205,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         pfc_flags=req.pfc_flags |
-                         dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, 0)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertEqual(rep.u.flags, 0)
-@@ -3256,7 +3256,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 4)
-         self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port)
-         self.assertPadding(rep.u._pad1, 2)
-@@ -3266,7 +3266,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         self.assertEqual(rep.u.ctx_list[0].reason,
-                           dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
-         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
--        self.assertNotEquals(len(rep.u.auth_info), 0)
-+        self.assertNotEqual(len(rep.u.auth_info), 0)
-         a = self.parse_auth(rep.u.auth_info)
- 
-         from_server = a.credentials
-@@ -3295,7 +3295,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         self.assertEqual(rep.u.ctx_list[0].reason,
-                           dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
-         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
--        self.assertNotEquals(len(rep.u.auth_info), 0)
-+        self.assertNotEqual(len(rep.u.auth_info), 0)
-         a = self.parse_auth(rep.u.auth_info)
- 
-         from_server = a.credentials
-@@ -3311,7 +3311,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         rep = self.recv_pdu()
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
-@@ -3331,7 +3331,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         # We don't get an auth_info back
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
-@@ -3362,7 +3362,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         pfc_flags=req.pfc_flags |
-                         dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, 0)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertEqual(rep.u.flags, 0)
-@@ -3409,7 +3409,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 4)
-         self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port)
-         self.assertPadding(rep.u._pad1, 2)
-@@ -3419,7 +3419,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         self.assertEqual(rep.u.ctx_list[0].reason,
-                           dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
-         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
--        self.assertNotEquals(len(rep.u.auth_info), 0)
-+        self.assertNotEqual(len(rep.u.auth_info), 0)
-         a = self.parse_auth(rep.u.auth_info)
- 
-         from_server = a.credentials
-@@ -3440,7 +3440,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         pfc_flags=req.pfc_flags |
-                         dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, 0)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertEqual(rep.u.flags, 0)
-@@ -3493,7 +3493,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 4)
-         self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port)
-         self.assertPadding(rep.u._pad1, 2)
-@@ -3503,7 +3503,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         self.assertEqual(rep.u.ctx_list[0].reason,
-                           dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
-         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
--        self.assertNotEquals(len(rep.u.auth_info), 0)
-+        self.assertNotEqual(len(rep.u.auth_info), 0)
-         a = self.parse_auth(rep.u.auth_info)
- 
-         from_server = a.credentials
-@@ -3524,7 +3524,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         pfc_flags=req.pfc_flags |
-                         dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, 0)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertEqual(rep.u.flags, 0)
-@@ -3579,7 +3579,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 4)
-         self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port)
-         self.assertPadding(rep.u._pad1, 2)
-@@ -3589,7 +3589,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         self.assertEqual(rep.u.ctx_list[0].reason,
-                           dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
-         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
--        self.assertNotEquals(len(rep.u.auth_info), 0)
-+        self.assertNotEqual(len(rep.u.auth_info), 0)
-         a = self.parse_auth(rep.u.auth_info)
- 
-         from_server = a.credentials
-@@ -3611,7 +3611,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         pfc_flags=req.pfc_flags |
-                         dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, 0)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertEqual(rep.u.flags, 0)
-@@ -3659,7 +3659,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 4)
-         self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port)
-         self.assertPadding(rep.u._pad1, 2)
-@@ -3669,7 +3669,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         self.assertEqual(rep.u.ctx_list[0].reason,
-                           dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
-         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
--        self.assertNotEquals(len(rep.u.auth_info), 0)
-+        self.assertNotEqual(len(rep.u.auth_info), 0)
-         a = self.parse_auth(rep.u.auth_info)
- 
-         from_server = a.credentials
-@@ -3691,7 +3691,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         pfc_flags=req.pfc_flags |
-                         dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, 0)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertEqual(rep.u.flags, 0)
-@@ -3746,7 +3746,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 4)
-         self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port)
-         self.assertPadding(rep.u._pad1, 2)
-@@ -3756,7 +3756,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         self.assertEqual(rep.u.ctx_list[0].reason,
-                           dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
-         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
--        self.assertNotEquals(len(rep.u.auth_info), 0)
-+        self.assertNotEqual(len(rep.u.auth_info), 0)
-         a = self.parse_auth(rep.u.auth_info)
- 
-         from_server = a.credentials
-@@ -3778,7 +3778,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         pfc_flags=req.pfc_flags |
-                         dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, 0)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertEqual(rep.u.flags, 0)
-@@ -3833,7 +3833,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 4)
-         self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port)
-         self.assertPadding(rep.u._pad1, 2)
-@@ -3843,7 +3843,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         self.assertEqual(rep.u.ctx_list[0].reason,
-                           dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
-         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
--        self.assertNotEquals(len(rep.u.auth_info), 0)
-+        self.assertNotEqual(len(rep.u.auth_info), 0)
-         a = self.parse_auth(rep.u.auth_info)
- 
-         from_server = a.credentials
-@@ -3865,7 +3865,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         pfc_flags=req.pfc_flags |
-                         dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, 0)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertEqual(rep.u.flags, 0)
-@@ -3930,7 +3930,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 4)
-         self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port)
-         self.assertPadding(rep.u._pad1, 2)
-@@ -3940,7 +3940,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         self.assertEqual(rep.u.ctx_list[0].reason,
-                           dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
-         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
--        self.assertNotEquals(len(rep.u.auth_info), 0)
-+        self.assertNotEqual(len(rep.u.auth_info), 0)
-         a = self.parse_auth(rep.u.auth_info)
- 
-         from_server = a.credentials
-@@ -3984,7 +3984,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         self.assertEqual(rep.u.ctx_list[0].reason,
-                           dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
-         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
--        self.assertNotEquals(len(rep.u.auth_info), 0)
-+        self.assertNotEqual(len(rep.u.auth_info), 0)
-         a = self.parse_auth(rep.u.auth_info)
- 
-         from_server = a.credentials
-@@ -4000,7 +4000,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         rep = self.recv_pdu()
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
-@@ -4020,7 +4020,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         # We don't get an auth_info back
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
-@@ -4144,7 +4144,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 4)
-         self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port)
-         self.assertPadding(rep.u._pad1, 2)
-@@ -4154,7 +4154,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         self.assertEqual(rep.u.ctx_list[0].reason,
-                           dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
-         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
--        self.assertNotEquals(len(rep.u.auth_info), 0)
-+        self.assertNotEqual(len(rep.u.auth_info), 0)
-         a = self.parse_auth(rep.u.auth_info)
- 
-         from_server = a.credentials
-@@ -4191,7 +4191,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         pfc_flags=req.pfc_flags |
-                         dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, 0)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertEqual(rep.u.flags, 0)
-@@ -4256,7 +4256,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 4)
-         self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port)
-         self.assertPadding(rep.u._pad1, 2)
-@@ -4266,7 +4266,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         self.assertEqual(rep.u.ctx_list[0].reason,
-                           dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
-         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
--        self.assertNotEquals(len(rep.u.auth_info), 0)
-+        self.assertNotEqual(len(rep.u.auth_info), 0)
-         a = self.parse_auth(rep.u.auth_info)
- 
-         from_server = a.credentials
-@@ -4295,7 +4295,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         rep = self.recv_pdu()
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
-@@ -4315,7 +4315,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         # We don't get an auth_info back
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
-@@ -4375,7 +4375,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id)
-         self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
-         self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
--        self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
-+        self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
-         self.assertEqual(rep.u.secondary_address_size, 4)
-         self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port)
-         self.assertPadding(rep.u._pad1, 2)
-@@ -4385,7 +4385,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         self.assertEqual(rep.u.ctx_list[0].reason,
-                           dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
-         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
--        self.assertNotEquals(len(rep.u.auth_info), 0)
-+        self.assertNotEqual(len(rep.u.auth_info), 0)
-         a = self.parse_auth(rep.u.auth_info)
- 
-         from_server = a.credentials
-@@ -4406,7 +4406,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         pfc_flags=req.pfc_flags |
-                         dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, 0)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertEqual(rep.u.flags, 0)
-@@ -4521,7 +4521,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id,
-                         pfc_flags=req.pfc_flags | response_fault_flags,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, ctx1.context_id)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertEqual(rep.u.flags, 0)
-@@ -4688,7 +4688,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         (rep, rep_blob) = self.recv_pdu_raw()
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
-                         auth_length=sig_size)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id & 0xff)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
-@@ -4756,7 +4756,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-                         pfc_flags=req.pfc_flags |
-                         dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
-                         auth_length=0)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, ctx1.context_id)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertEqual(rep.u.flags, 0)
-@@ -4805,7 +4805,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         (rep, rep_blob) = self.recv_pdu_raw()
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
-                         auth_length=sig_size)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id & 0xff)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
-@@ -4870,7 +4870,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
-         (rep, rep_blob) = self.recv_pdu_raw()
-         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
-                         auth_length=sig_size)
--        self.assertNotEquals(rep.u.alloc_hint, 0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-         self.assertEqual(rep.u.context_id, req.u.context_id & 0xff)
-         self.assertEqual(rep.u.cancel_count, 0)
-         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
-diff --git a/python/samba/tests/dcerpc/raw_testcase.py b/python/samba/tests/dcerpc/raw_testcase.py
-index f1c097ebe6d..ed77d329cd5 100644
---- a/python/samba/tests/dcerpc/raw_testcase.py
-+++ b/python/samba/tests/dcerpc/raw_testcase.py
-@@ -321,7 +321,7 @@ class RawDCERPCTest(TestCase):
-                                 pfc_flags=req.pfc_flags |
-                                 samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
-                                 auth_length=0)
--                self.assertNotEquals(rep.u.alloc_hint, 0)
-+                self.assertNotEqual(rep.u.alloc_hint, 0)
-                 self.assertEqual(rep.u.context_id, 0)
-                 self.assertEqual(rep.u.cancel_count, 0)
-                 self.assertEqual(rep.u.flags, 0)
-@@ -361,7 +361,7 @@ class RawDCERPCTest(TestCase):
-             if assoc_group_id != 0:
-                 self.assertEqual(rep.u.assoc_group_id, assoc_group_id)
-             else:
--                self.assertNotEquals(rep.u.assoc_group_id, 0)
-+                self.assertNotEqual(rep.u.assoc_group_id, 0)
-                 assoc_group_id = rep.u.assoc_group_id
-             sda_str = self.secondary_address
-             sda_len = len(sda_str) + 1
-@@ -385,7 +385,7 @@ class RawDCERPCTest(TestCase):
-             self.assertEqual(rep.auth_length, 0)
-             self.assertEqual(len(rep.u.auth_info), 0)
-             return ack
--        self.assertNotEquals(rep.auth_length, 0)
-+        self.assertNotEqual(rep.auth_length, 0)
-         self.assertGreater(len(rep.u.auth_info), samba.dcerpc.dcerpc.DCERPC_AUTH_TRAILER_LENGTH)
-         self.assertEqual(rep.auth_length, len(rep.u.auth_info) - samba.dcerpc.dcerpc.DCERPC_AUTH_TRAILER_LENGTH)
- 
-@@ -426,7 +426,7 @@ class RawDCERPCTest(TestCase):
-                             pfc_flags=req.pfc_flags |
-                             samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
-                             auth_length=0)
--            self.assertNotEquals(rep.u.alloc_hint, 0)
-+            self.assertNotEqual(rep.u.alloc_hint, 0)
-             self.assertEqual(rep.u.context_id, 0)
-             self.assertEqual(rep.u.cancel_count, 0)
-             self.assertEqual(rep.u.flags, 0)
-@@ -451,7 +451,7 @@ class RawDCERPCTest(TestCase):
-         if finished:
-             self.assertEqual(rep.auth_length, 0)
-         else:
--            self.assertNotEquals(rep.auth_length, 0)
-+            self.assertNotEqual(rep.auth_length, 0)
-         self.assertGreaterEqual(len(rep.u.auth_info), samba.dcerpc.dcerpc.DCERPC_AUTH_TRAILER_LENGTH)
-         self.assertEqual(rep.auth_length, len(rep.u.auth_info) - samba.dcerpc.dcerpc.DCERPC_AUTH_TRAILER_LENGTH)
- 
-@@ -547,7 +547,7 @@ class RawDCERPCTest(TestCase):
-             if fault_status:
-                 self.verify_pdu(rep, samba.dcerpc.dcerpc.DCERPC_PKT_FAULT, req.call_id,
-                                 pfc_flags=fault_pfc_flags, auth_length=0)
--                self.assertNotEquals(rep.u.alloc_hint, 0)
-+                self.assertNotEqual(rep.u.alloc_hint, 0)
-                 self.assertEqual(rep.u.context_id, fault_context_id)
-                 self.assertEqual(rep.u.cancel_count, 0)
-                 self.assertEqual(rep.u.flags, 0)
-@@ -563,7 +563,7 @@ class RawDCERPCTest(TestCase):
- 
-             self.verify_pdu(rep, samba.dcerpc.dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
-                             auth_length=expected_auth_length)
--            self.assertNotEquals(rep.u.alloc_hint, 0)
-+            self.assertNotEqual(rep.u.alloc_hint, 0)
-             self.assertEqual(rep.u.context_id, req.u.context_id & 0xff)
-             self.assertEqual(rep.u.cancel_count, 0)
-             self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
--- 
-2.25.1
-
-
-From 4ec27da793964c3c49995ada3da047bae0174d26 Mon Sep 17 00:00:00 2001
-From: Stefan Metzmacher <metze@samba.org>
-Date: Tue, 17 Nov 2020 09:50:58 +0100
-Subject: [PATCH 6/9] CVE-2021-23192: python/tests/dcerpc: let
- generate_request_auth() use g_auth_level in all places
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14875
-
-Signed-off-by: Stefan Metzmacher <metze@samba.org>
-Reviewed-by: Samuel Cabrero <scabrero@samba.org>
----
- python/samba/tests/dcerpc/raw_testcase.py | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/python/samba/tests/dcerpc/raw_testcase.py b/python/samba/tests/dcerpc/raw_testcase.py
-index ed77d329cd5..53f7fa0a2a8 100644
---- a/python/samba/tests/dcerpc/raw_testcase.py
-+++ b/python/samba/tests/dcerpc/raw_testcase.py
-@@ -922,12 +922,12 @@ class RawDCERPCTest(TestCase):
-         req_data = req_blob[ofs_stub:ofs_trailer]
-         req_whole = req_blob[0:ofs_sig]
- 
--        if auth_context["auth_level"] >= dcerpc.DCERPC_AUTH_LEVEL_PRIVACY:
-+        if auth_context["g_auth_level"] >= dcerpc.DCERPC_AUTH_LEVEL_PRIVACY:
-             # TODO: not yet supported here
-             self.assertTrue(False)
--        elif auth_context["auth_level"] >= dcerpc.DCERPC_AUTH_LEVEL_PACKET:
-+        elif auth_context["g_auth_level"] >= dcerpc.DCERPC_AUTH_LEVEL_PACKET:
-             req_sig = auth_context["gensec"].sign_packet(req_data, req_whole)
--        elif auth_context["auth_level"] >= dcerpc.DCERPC_AUTH_LEVEL_CONNECT:
-+        elif auth_context["g_auth_level"] >= dcerpc.DCERPC_AUTH_LEVEL_CONNECT:
-             self.assertEqual(auth_context["auth_type"],
-                               dcerpc.DCERPC_AUTH_TYPE_NTLMSSP)
-             req_sig = b"\x01" +b"\x00" *15
--- 
-2.25.1
-
-
-From 188f01b8ac8b84e9e41a769731cb4426658920cb Mon Sep 17 00:00:00 2001
-From: Stefan Metzmacher <metze@samba.org>
-Date: Tue, 17 Nov 2020 17:43:06 +0100
-Subject: [PATCH 7/9] CVE-2021-23192: python/tests/dcerpc: fix
- do_single_request(send_req=False)
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14875
-
-Signed-off-by: Stefan Metzmacher <metze@samba.org>
-Reviewed-by: Samuel Cabrero <scabrero@samba.org>
----
- python/samba/tests/dcerpc/raw_testcase.py | 37 ++++++++++++-----------
- 1 file changed, 20 insertions(+), 17 deletions(-)
-
-diff --git a/python/samba/tests/dcerpc/raw_testcase.py b/python/samba/tests/dcerpc/raw_testcase.py
-index 53f7fa0a2a8..22b56704fa3 100644
---- a/python/samba/tests/dcerpc/raw_testcase.py
-+++ b/python/samba/tests/dcerpc/raw_testcase.py
-@@ -526,26 +526,25 @@ class RawDCERPCTest(TestCase):
-             if hexdump:
-                 sys.stderr.write("stub_in: %d\n%s" % (len(stub_in), self.hexdump(stub_in)))
- 
--        pfc_flags = samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST
--        pfc_flags |= samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST
--        if object is not None:
--            pfc_flags |= samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_OBJECT_UUID
--
--        req = self.generate_request_auth(call_id=call_id,
--                                         context_id=ctx.context_id,
--                                         pfc_flags=pfc_flags,
--                                         object=object,
--                                         opnum=io.opnum(),
--                                         stub=stub_in,
--                                         auth_context=auth_context)
--        if send_req:
-+            pfc_flags = samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST
-+            pfc_flags |= samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST
-+            if object is not None:
-+                pfc_flags |= samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_OBJECT_UUID
-+
-+            req = self.generate_request_auth(call_id=call_id,
-+                                             context_id=ctx.context_id,
-+                                             pfc_flags=pfc_flags,
-+                                             object=object,
-+                                             opnum=io.opnum(),
-+                                             stub=stub_in,
-+                                             auth_context=auth_context)
-             self.send_pdu(req, ndr_print=ndr_print, hexdump=hexdump)
-         if recv_rep:
-             (rep, rep_blob) = self.recv_pdu_raw(timeout=timeout,
-                                                 ndr_print=ndr_print,
-                                                 hexdump=hexdump)
-             if fault_status:
--                self.verify_pdu(rep, samba.dcerpc.dcerpc.DCERPC_PKT_FAULT, req.call_id,
-+                self.verify_pdu(rep, samba.dcerpc.dcerpc.DCERPC_PKT_FAULT, call_id,
-                                 pfc_flags=fault_pfc_flags, auth_length=0)
-                 self.assertNotEqual(rep.u.alloc_hint, 0)
-                 self.assertEqual(rep.u.context_id, fault_context_id)
-@@ -559,12 +558,16 @@ class RawDCERPCTest(TestCase):
-             expected_auth_length = 0
-             if auth_context is not None and \
-                auth_context["auth_level"] >= dcerpc.DCERPC_AUTH_LEVEL_PACKET:
--                expected_auth_length = req.auth_length
-+                if send_req:
-+                    expected_auth_length = req.auth_length
-+                else:
-+                    expected_auth_length = rep.auth_length
-+
- 
--            self.verify_pdu(rep, samba.dcerpc.dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
-+            self.verify_pdu(rep, samba.dcerpc.dcerpc.DCERPC_PKT_RESPONSE, call_id,
-                             auth_length=expected_auth_length)
-             self.assertNotEqual(rep.u.alloc_hint, 0)
--            self.assertEqual(rep.u.context_id, req.u.context_id & 0xff)
-+            self.assertEqual(rep.u.context_id, ctx.context_id & 0xff)
-             self.assertEqual(rep.u.cancel_count, 0)
-             self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
-             stub_out = self.check_response_auth(rep, rep_blob, auth_context)
--- 
-2.25.1
-
-
-From 7cf3a4a33282ed5b135fcdc47a5cc7cdca370ee7 Mon Sep 17 00:00:00 2001
-From: Stefan Metzmacher <metze@samba.org>
-Date: Tue, 17 Nov 2020 18:14:46 +0100
-Subject: [PATCH 8/9] CVE-2021-23192: python/tests/dcerpc: add tests to check
- how security contexts relate to fragmented requests
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14875
-
-Signed-off-by: Stefan Metzmacher <metze@samba.org>
-Reviewed-by: Samuel Cabrero <scabrero@samba.org>
----
- python/samba/tests/dcerpc/raw_protocol.py | 1273 +++++++++++++++++++++
- selftest/knownfail.d/dcerpc-auth-fraq     |   20 +
- 2 files changed, 1293 insertions(+)
- create mode 100644 selftest/knownfail.d/dcerpc-auth-fraq
-
-diff --git a/python/samba/tests/dcerpc/raw_protocol.py b/python/samba/tests/dcerpc/raw_protocol.py
-index cbd398d5290..3c9d0b136a5 100755
---- a/python/samba/tests/dcerpc/raw_protocol.py
-+++ b/python/samba/tests/dcerpc/raw_protocol.py
-@@ -1683,6 +1683,1279 @@ class TestDCERPC_BIND(RawDCERPCTest):
-     def test_auth_none_packet_request(self):
-         return self._test_auth_none_level_request(dcerpc.DCERPC_AUTH_LEVEL_PACKET)
- 
-+    def test_ntlmssp_multi_auth_first1_lastSame2(self):
-+        auth_type = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP
-+        expected_fault = dcerpc.DCERPC_FAULT_SEC_PKG_ERROR
-+        auth_context_2nd = 2
-+        expected_call_id = None
-+        expected_context_id = None
-+        not_executed = False
-+        conc_mpx = False
-+        forced_call_id = None
-+        forced_context_id = None
-+        forced_opnum = None
-+        forced_auth_context_id = None
-+        forced_auth_type = None
-+        forced_auth_level = None
-+        return self._test_generic_auth_first_last(auth_type,
-+                                                  expected_fault,
-+                                                  auth_context_2nd=auth_context_2nd,
-+                                                  expected_call_id=expected_call_id,
-+                                                  expected_context_id=expected_context_id,
-+                                                  not_executed=not_executed,
-+                                                  conc_mpx=conc_mpx,
-+                                                  forced_call_id=forced_call_id,
-+                                                  forced_context_id=forced_context_id,
-+                                                  forced_opnum=forced_opnum,
-+                                                  forced_auth_context_id=forced_auth_context_id,
-+                                                  forced_auth_type=forced_auth_type,
-+                                                  forced_auth_level=forced_auth_level)
-+
-+    def test_ntlmssp_multi_auth_first1_lastNext2(self):
-+        auth_type = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP
-+        expected_fault = dcerpc.DCERPC_NCA_S_PROTO_ERROR
-+        auth_context_2nd = 2
-+        expected_call_id = None
-+        expected_context_id = None
-+        not_executed = False
-+        conc_mpx = False
-+        forced_call_id = 4
-+        forced_context_id = None
-+        forced_opnum = None
-+        forced_auth_context_id = None
-+        forced_auth_type = None
-+        forced_auth_level = None
-+        return self._test_generic_auth_first_last(auth_type,
-+                                                  expected_fault,
-+                                                  auth_context_2nd=auth_context_2nd,
-+                                                  expected_call_id=expected_call_id,
-+                                                  expected_context_id=expected_context_id,
-+                                                  not_executed=not_executed,
-+                                                  conc_mpx=conc_mpx,
-+                                                  forced_call_id=forced_call_id,
-+                                                  forced_context_id=forced_context_id,
-+                                                  forced_opnum=forced_opnum,
-+                                                  forced_auth_context_id=forced_auth_context_id,
-+                                                  forced_auth_type=forced_auth_type,
-+                                                  forced_auth_level=forced_auth_level)
-+
-+    def test_ntlmssp_multi_auth_first1_lastSame111(self):
-+        auth_type = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP
-+        expected_fault = None
-+        auth_context_2nd = 1
-+        expected_call_id = None
-+        expected_context_id = None
-+        not_executed = False
-+        conc_mpx = False
-+        forced_call_id = None
-+        forced_context_id = 111
-+        forced_opnum = 111
-+        forced_auth_context_id = 111
-+        forced_auth_type = 111
-+        forced_auth_level = 111
-+        return self._test_generic_auth_first_last(auth_type,
-+                                                  expected_fault,
-+                                                  auth_context_2nd=auth_context_2nd,
-+                                                  expected_call_id=expected_call_id,
-+                                                  expected_context_id=expected_context_id,
-+                                                  not_executed=not_executed,
-+                                                  conc_mpx=conc_mpx,
-+                                                  forced_call_id=forced_call_id,
-+                                                  forced_context_id=forced_context_id,
-+                                                  forced_opnum=forced_opnum,
-+                                                  forced_auth_context_id=forced_auth_context_id,
-+                                                  forced_auth_type=forced_auth_type,
-+                                                  forced_auth_level=forced_auth_level)
-+
-+    def test_ntlmssp_multi_auth_first1_lastNext111(self):
-+        auth_type = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP
-+        expected_fault = dcerpc.DCERPC_NCA_S_PROTO_ERROR
-+        auth_context_2nd = 1
-+        expected_call_id = None
-+        expected_context_id = None
-+        not_executed = False
-+        conc_mpx = False
-+        forced_call_id = 4
-+        forced_context_id = 111
-+        forced_opnum = 111
-+        forced_auth_context_id = 111
-+        forced_auth_type = 111
-+        forced_auth_level = 111
-+        return self._test_generic_auth_first_last(auth_type,
-+                                                  expected_fault,
-+                                                  auth_context_2nd=auth_context_2nd,
-+                                                  expected_call_id=expected_call_id,
-+                                                  expected_context_id=expected_context_id,
-+                                                  not_executed=not_executed,
-+                                                  conc_mpx=conc_mpx,
-+                                                  forced_call_id=forced_call_id,
-+                                                  forced_context_id=forced_context_id,
-+                                                  forced_opnum=forced_opnum,
-+                                                  forced_auth_context_id=forced_auth_context_id,
-+                                                  forced_auth_type=forced_auth_type,
-+                                                  forced_auth_level=forced_auth_level)
-+
-+    def test_ntlmssp_multi_auth_MPX_first1_lastNext111(self):
-+        auth_type = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP
-+        expected_fault = dcerpc.DCERPC_NCA_S_PROTO_ERROR
-+        auth_context_2nd = 1
-+        expected_call_id = 4
-+        expected_context_id = 0
-+        not_executed = False
-+        conc_mpx = True
-+        forced_call_id = 4
-+        forced_context_id = 111
-+        forced_opnum = 111
-+        forced_auth_context_id = 111
-+        forced_auth_type = 111
-+        forced_auth_level = 111
-+        return self._test_generic_auth_first_last(auth_type,
-+                                                  expected_fault,
-+                                                  auth_context_2nd=auth_context_2nd,
-+                                                  expected_call_id=expected_call_id,
-+                                                  expected_context_id=expected_context_id,
-+                                                  not_executed=not_executed,
-+                                                  conc_mpx=conc_mpx,
-+                                                  forced_call_id=forced_call_id,
-+                                                  forced_context_id=forced_context_id,
-+                                                  forced_opnum=forced_opnum,
-+                                                  forced_auth_context_id=forced_auth_context_id,
-+                                                  forced_auth_type=forced_auth_type,
-+                                                  forced_auth_level=forced_auth_level)
-+
-+    def test_ntlmssp_multi_auth_first1_lastSameNone(self):
-+        auth_type = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP
-+        expected_fault = dcerpc.DCERPC_NCA_S_PROTO_ERROR
-+        auth_context_2nd = None
-+        expected_call_id = None
-+        expected_context_id = None
-+        not_executed = False
-+        conc_mpx = False
-+        forced_call_id = None
-+        forced_context_id = None
-+        forced_opnum = None
-+        forced_auth_context_id = None
-+        forced_auth_type = None
-+        forced_auth_level = None
-+        return self._test_generic_auth_first_last(auth_type,
-+                                                  expected_fault,
-+                                                  auth_context_2nd=auth_context_2nd,
-+                                                  expected_call_id=expected_call_id,
-+                                                  expected_context_id=expected_context_id,
-+                                                  not_executed=not_executed,
-+                                                  conc_mpx=conc_mpx,
-+                                                  forced_call_id=forced_call_id,
-+                                                  forced_context_id=forced_context_id,
-+                                                  forced_opnum=forced_opnum,
-+                                                  forced_auth_context_id=forced_auth_context_id,
-+                                                  forced_auth_type=forced_auth_type,
-+                                                  forced_auth_level=forced_auth_level)
-+
-+    def test_ntlmssp_multi_auth_MPX_first1_lastSameNone(self):
-+        auth_type = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP
-+        expected_fault = dcerpc.DCERPC_NCA_S_PROTO_ERROR
-+        auth_context_2nd = None
-+        expected_call_id = None
-+        expected_context_id = None
-+        not_executed = False
-+        conc_mpx = True
-+        forced_call_id = None
-+        forced_context_id = None
-+        forced_opnum = None
-+        forced_auth_context_id = None
-+        forced_auth_type = None
-+        forced_auth_level = None
-+        return self._test_generic_auth_first_last(auth_type,
-+                                                  expected_fault,
-+                                                  auth_context_2nd=auth_context_2nd,
-+                                                  expected_call_id=expected_call_id,
-+                                                  expected_context_id=expected_context_id,
-+                                                  not_executed=not_executed,
-+                                                  conc_mpx=conc_mpx,
-+                                                  forced_call_id=forced_call_id,
-+                                                  forced_context_id=forced_context_id,
-+                                                  forced_opnum=forced_opnum,
-+                                                  forced_auth_context_id=forced_auth_context_id,
-+                                                  forced_auth_type=forced_auth_type,
-+                                                  forced_auth_level=forced_auth_level)
-+
-+    def test_ntlmssp_multi_auth_first1_lastNextNone(self):
-+        auth_type = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP
-+        expected_fault = dcerpc.DCERPC_NCA_S_PROTO_ERROR
-+        auth_context_2nd = None
-+        expected_call_id = None
-+        expected_context_id = None
-+        not_executed = False
-+        conc_mpx = False
-+        forced_call_id = 4
-+        forced_context_id = None
-+        forced_opnum = None
-+        forced_auth_context_id = None
-+        forced_auth_type = None
-+        forced_auth_level = None
-+        return self._test_generic_auth_first_last(auth_type,
-+                                                  expected_fault,
-+                                                  auth_context_2nd=auth_context_2nd,
-+                                                  expected_call_id=expected_call_id,
-+                                                  expected_context_id=expected_context_id,
-+                                                  not_executed=not_executed,
-+                                                  conc_mpx=conc_mpx,
-+                                                  forced_call_id=forced_call_id,
-+                                                  forced_context_id=forced_context_id,
-+                                                  forced_opnum=forced_opnum,
-+                                                  forced_auth_context_id=forced_auth_context_id,
-+                                                  forced_auth_type=forced_auth_type,
-+                                                  forced_auth_level=forced_auth_level)
-+
-+    def test_ntlmssp_multi_auth_MPX_first1_lastNextNone(self):
-+        auth_type = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP
-+        expected_fault = dcerpc.DCERPC_NCA_S_PROTO_ERROR
-+        auth_context_2nd = None
-+        expected_call_id = 4
-+        expected_context_id = 0
-+        not_executed = False
-+        conc_mpx = True
-+        forced_call_id = 4
-+        forced_context_id = None
-+        forced_opnum = None
-+        forced_auth_context_id = None
-+        forced_auth_type = None
-+        forced_auth_level = None
-+        return self._test_generic_auth_first_last(auth_type,
-+                                                  expected_fault,
-+                                                  auth_context_2nd=auth_context_2nd,
-+                                                  expected_call_id=expected_call_id,
-+                                                  expected_context_id=expected_context_id,
-+                                                  not_executed=not_executed,
-+                                                  conc_mpx=conc_mpx,
-+                                                  forced_call_id=forced_call_id,
-+                                                  forced_context_id=forced_context_id,
-+                                                  forced_opnum=forced_opnum,
-+                                                  forced_auth_context_id=forced_auth_context_id,
-+                                                  forced_auth_type=forced_auth_type,
-+                                                  forced_auth_level=forced_auth_level)
-+
-+    def test_ntlmssp_multi_auth_first1_lastSameNone111(self):
-+        auth_type = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP
-+        expected_fault = dcerpc.DCERPC_NCA_S_PROTO_ERROR
-+        auth_context_2nd = None
-+        expected_call_id = None
-+        expected_context_id = None
-+        not_executed = False
-+        conc_mpx = False
-+        forced_call_id = None
-+        forced_context_id = 111
-+        forced_opnum = 111
-+        forced_auth_context_id = None
-+        forced_auth_type = None
-+        forced_auth_level = None
-+        return self._test_generic_auth_first_last(auth_type,
-+                                                  expected_fault,
-+                                                  auth_context_2nd=auth_context_2nd,
-+                                                  expected_call_id=expected_call_id,
-+                                                  expected_context_id=expected_context_id,
-+                                                  not_executed=not_executed,
-+                                                  conc_mpx=conc_mpx,
-+                                                  forced_call_id=forced_call_id,
-+                                                  forced_context_id=forced_context_id,
-+                                                  forced_opnum=forced_opnum,
-+                                                  forced_auth_context_id=forced_auth_context_id,
-+                                                  forced_auth_type=forced_auth_type,
-+                                                  forced_auth_level=forced_auth_level)
-+
-+    def test_ntlmssp_multi_auth_MPX_first1_lastSameNone111(self):
-+        auth_type = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP
-+        expected_fault = dcerpc.DCERPC_NCA_S_PROTO_ERROR
-+        auth_context_2nd = None
-+        expected_call_id = None
-+        expected_context_id = None
-+        not_executed = False
-+        conc_mpx = True
-+        forced_call_id = None
-+        forced_context_id = 111
-+        forced_opnum = 111
-+        forced_auth_context_id = None
-+        forced_auth_type = None
-+        forced_auth_level = None
-+        return self._test_generic_auth_first_last(auth_type,
-+                                                  expected_fault,
-+                                                  auth_context_2nd=auth_context_2nd,
-+                                                  expected_call_id=expected_call_id,
-+                                                  expected_context_id=expected_context_id,
-+                                                  not_executed=not_executed,
-+                                                  conc_mpx=conc_mpx,
-+                                                  forced_call_id=forced_call_id,
-+                                                  forced_context_id=forced_context_id,
-+                                                  forced_opnum=forced_opnum,
-+                                                  forced_auth_context_id=forced_auth_context_id,
-+                                                  forced_auth_type=forced_auth_type,
-+                                                  forced_auth_level=forced_auth_level)
-+
-+    def test_ntlmssp_multi_auth_first1_lastNextNone111(self):
-+        auth_type = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP
-+        expected_fault = dcerpc.DCERPC_NCA_S_PROTO_ERROR
-+        auth_context_2nd = None
-+        expected_call_id = None
-+        expected_context_id = None
-+        not_executed = False
-+        conc_mpx = False
-+        forced_call_id = 4
-+        forced_context_id = 111
-+        forced_opnum = 111
-+        forced_auth_context_id = None
-+        forced_auth_type = None
-+        forced_auth_level = None
-+        return self._test_generic_auth_first_last(auth_type,
-+                                                  expected_fault,
-+                                                  auth_context_2nd=auth_context_2nd,
-+                                                  expected_call_id=expected_call_id,
-+                                                  expected_context_id=expected_context_id,
-+                                                  not_executed=not_executed,
-+                                                  conc_mpx=conc_mpx,
-+                                                  forced_call_id=forced_call_id,
-+                                                  forced_context_id=forced_context_id,
-+                                                  forced_opnum=forced_opnum,
-+                                                  forced_auth_context_id=forced_auth_context_id,
-+                                                  forced_auth_type=forced_auth_type,
-+                                                  forced_auth_level=forced_auth_level)
-+
-+    def test_ntlmssp_multi_auth_MPX_first1_lastNextNone111(self):
-+        auth_type = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP
-+        expected_fault = dcerpc.DCERPC_NCA_S_PROTO_ERROR
-+        auth_context_2nd = None
-+        expected_call_id = 4
-+        expected_context_id = 0
-+        not_executed = False
-+        conc_mpx = True
-+        forced_call_id = 4
-+        forced_context_id = 111
-+        forced_opnum = 111
-+        forced_auth_context_id = None
-+        forced_auth_type = None
-+        forced_auth_level = None
-+        return self._test_generic_auth_first_last(auth_type,
-+                                                  expected_fault,
-+                                                  auth_context_2nd=auth_context_2nd,
-+                                                  expected_call_id=expected_call_id,
-+                                                  expected_context_id=expected_context_id,
-+                                                  not_executed=not_executed,
-+                                                  conc_mpx=conc_mpx,
-+                                                  forced_call_id=forced_call_id,
-+                                                  forced_context_id=forced_context_id,
-+                                                  forced_opnum=forced_opnum,
-+                                                  forced_auth_context_id=forced_auth_context_id,
-+                                                  forced_auth_type=forced_auth_type,
-+                                                  forced_auth_level=forced_auth_level)
-+
-+    def _test_generic_auth_first_2nd(self,
-+                                     auth_type,
-+                                     pfc_flags_2nd,
-+                                     expected_fault,
-+                                     auth_context_2nd=2,
-+                                     skip_first=False,
-+                                     expected_call_id=None,
-+                                     expected_context_id=None,
-+                                     conc_mpx=False,
-+                                     not_executed=False,
-+                                     forced_call_id=None,
-+                                     forced_context_id=None,
-+                                     forced_opnum=None,
-+                                     forced_auth_context_id=None,
-+                                     forced_auth_type=None,
-+                                     forced_auth_level=None):
-+        auth_type = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP
-+        auth_level1 = dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY
-+        auth_context_id1=1
-+        auth_level2 = dcerpc.DCERPC_AUTH_LEVEL_PACKET
-+        auth_context_id2=2
-+
-+        creds = self.get_user_creds()
-+
-+        abstract = samba.dcerpc.mgmt.abstract_syntax()
-+        transfer = base.transfer_syntax_ndr()
-+
-+        tsf1_list = [transfer]
-+        ctx = samba.dcerpc.dcerpc.ctx_list()
-+        ctx.context_id = 1
-+        ctx.num_transfer_syntaxes = len(tsf1_list)
-+        ctx.abstract_syntax = abstract
-+        ctx.transfer_syntaxes = tsf1_list
-+
-+        auth_context1 = self.get_auth_context_creds(creds=creds,
-+                                                    auth_type=auth_type,
-+                                                    auth_level=auth_level1,
-+                                                    auth_context_id=auth_context_id1,
-+                                                    hdr_signing=False)
-+        auth_context2 = self.get_auth_context_creds(creds=creds,
-+                                                    auth_type=auth_type,
-+                                                    auth_level=auth_level2,
-+                                                    auth_context_id=auth_context_id2,
-+                                                    hdr_signing=False)
-+
-+        bind_pfc_flags = dcerpc.DCERPC_PFC_FLAG_FIRST | dcerpc.DCERPC_PFC_FLAG_LAST
-+        if conc_mpx:
-+            bind_pfc_flags |= dcerpc.DCERPC_PFC_FLAG_CONC_MPX
-+
-+        ack0 = self.do_generic_bind(call_id=0,
-+                                    ctx=ctx,
-+                                    pfc_flags=bind_pfc_flags)
-+
-+        ack1 = self.do_generic_bind(call_id=1,
-+                                    ctx=ctx,
-+                                    auth_context=auth_context1,
-+                                    assoc_group_id = ack0.u.assoc_group_id,
-+                                    start_with_alter=True)
-+        if auth_context_2nd == 2:
-+            ack2 = self.do_generic_bind(call_id=2,
-+                                        ctx=ctx,
-+                                        auth_context=auth_context2,
-+                                        assoc_group_id = ack0.u.assoc_group_id,
-+                                        start_with_alter=True)
-+
-+        ndr_print = self.do_ndr_print
-+        hexdump = self.do_hexdump
-+        inq_if_ids = samba.dcerpc.mgmt.inq_if_ids()
-+        io = inq_if_ids
-+        if ndr_print:
-+            sys.stderr.write("in: %s" % samba.ndr.ndr_print_in(io))
-+        stub_in = samba.ndr.ndr_pack_in(io)
-+        stub_in += b'\xfe'*45 # add some padding in order to have some payload
-+        if hexdump:
-+            sys.stderr.write("stub_in: %d\n%s" % (len(stub_in), self.hexdump(stub_in)))
-+
-+        call_id = 3
-+        context_id = ctx.context_id
-+        opnum = io.opnum()
-+
-+        if not skip_first:
-+            pfc_flags = samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST
-+            stub_in_tmp = stub_in[0:16]
-+            req = self.generate_request_auth(call_id=call_id,
-+                                             context_id=context_id,
-+                                             pfc_flags=pfc_flags,
-+                                             opnum=opnum,
-+                                             alloc_hint=len(stub_in),
-+                                             stub=stub_in_tmp,
-+                                             auth_context=auth_context1)
-+            self.send_pdu(req, ndr_print=ndr_print, hexdump=hexdump)
-+            rep = self.recv_pdu(timeout=0.01)
-+            self.assertIsNone(rep)
-+            self.assertIsConnected()
-+
-+        # context_id, opnum and auth header values are completely ignored
-+        if auth_context_2nd == 1:
-+            auth_context_copy = auth_context1.copy()
-+        elif auth_context_2nd == 2:
-+            auth_context_copy = auth_context2.copy()
-+        else:
-+            auth_context_copy = None
-+
-+        expected_pfc_flags = dcerpc.DCERPC_PFC_FLAG_FIRST | dcerpc.DCERPC_PFC_FLAG_LAST
-+        if expected_context_id is None:
-+            expected_context_id = context_id
-+        if expected_call_id is None:
-+            expected_call_id = call_id
-+        if not_executed:
-+            expected_pfc_flags |= dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE
-+
-+        if forced_call_id is not None:
-+            call_id = forced_call_id
-+        if forced_context_id is not None:
-+            context_id = forced_context_id
-+        if forced_opnum is not None:
-+            opnum = forced_opnum
-+        if forced_auth_context_id is not None:
-+            auth_context_copy["auth_context_id"] = forced_auth_context_id
-+        if forced_auth_type is not None:
-+            auth_context_copy["auth_type"] = forced_auth_type
-+        if forced_auth_level is not None:
-+            auth_context_copy["auth_level"] = forced_auth_level
-+
-+        pfc_flags = samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST
-+        stub_in_tmp = stub_in[16:-1]
-+        req = self.generate_request_auth(call_id=call_id,
-+                                         context_id=context_id,
-+                                         pfc_flags=pfc_flags_2nd,
-+                                         opnum=opnum,
-+                                         alloc_hint=len(stub_in_tmp),
-+                                         stub=stub_in_tmp,
-+                                         auth_context=auth_context_copy)
-+        self.send_pdu(req, ndr_print=ndr_print, hexdump=hexdump)
-+        if expected_fault is None:
-+            self.do_single_request(call_id=3, ctx=ctx, io=io, send_req=False, auth_context=auth_context1)
-+            return
-+        rep = self.recv_pdu()
-+        self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, expected_call_id,
-+                        pfc_flags=expected_pfc_flags,
-+                        auth_length=0)
-+        self.assertNotEqual(rep.u.alloc_hint, 0)
-+        self.assertEqual(rep.u.context_id, expected_context_id)
-+        self.assertEqual(rep.u.cancel_count, 0)
-+        self.assertEqual(rep.u.flags, 0)
-+        self.assertEqual(rep.u.status, expected_fault)
-+        self.assertEqual(rep.u.reserved, 0)
-+        self.assertEqual(len(rep.u.error_and_verifier), 0)
-+
-+        if not_executed:
-+            # still alive
-+            rep = self.recv_pdu(timeout=0.01)
-+            self.assertIsNone(rep)
-+            self.assertIsConnected()
-+            return
-+
-+        # wait for a disconnect
-+        rep = self.recv_pdu()
-+        self.assertIsNone(rep)
-+        self.assertNotConnected()
-+
-+    def _test_generic_auth_first_last(self,
-+                                      auth_type,
-+                                      expected_fault,
-+                                      auth_context_2nd=2,
-+                                      expected_call_id=None,
-+                                      expected_context_id=None,
-+                                      conc_mpx=False,
-+                                      not_executed=False,
-+                                      forced_call_id=None,
-+                                      forced_context_id=None,
-+                                      forced_opnum=None,
-+                                      forced_auth_context_id=None,
-+                                      forced_auth_type=None,
-+                                      forced_auth_level=None):
-+        pfc_flags_2nd = samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST
-+        return self._test_generic_auth_first_2nd(auth_type,
-+                                                 pfc_flags_2nd,
-+                                                 expected_fault,
-+                                                 auth_context_2nd=auth_context_2nd,
-+                                                 expected_call_id=expected_call_id,
-+                                                 expected_context_id=expected_context_id,
-+                                                 not_executed=not_executed,
-+                                                 conc_mpx=conc_mpx,
-+                                                 forced_call_id=forced_call_id,
-+                                                 forced_context_id=forced_context_id,
-+                                                 forced_opnum=forced_opnum,
-+                                                 forced_auth_context_id=forced_auth_context_id,
-+                                                 forced_auth_type=forced_auth_type,
-+                                                 forced_auth_level=forced_auth_level)
-+
-+    def _test_generic_auth_first_first(self,
-+                                       auth_type,
-+                                       expected_fault,
-+                                       auth_context_2nd=2,
-+                                       expected_call_id=None,
-+                                       expected_context_id=None,
-+                                       conc_mpx=False,
-+                                       not_executed=False,
-+                                       forced_call_id=None,
-+                                       forced_context_id=None,
-+                                       forced_opnum=None,
-+                                       forced_auth_context_id=None,
-+                                       forced_auth_type=None,
-+                                       forced_auth_level=None):
-+        pfc_flags_2nd = samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST
-+        return self._test_generic_auth_first_2nd(auth_type,
-+                                                 pfc_flags_2nd,
-+                                                 expected_fault,
-+                                                 auth_context_2nd=auth_context_2nd,
-+                                                 expected_call_id=expected_call_id,
-+                                                 expected_context_id=expected_context_id,
-+                                                 not_executed=not_executed,
-+                                                 conc_mpx=conc_mpx,
-+                                                 forced_call_id=forced_call_id,
-+                                                 forced_context_id=forced_context_id,
-+                                                 forced_opnum=forced_opnum,
-+                                                 forced_auth_context_id=forced_auth_context_id,
-+                                                 forced_auth_type=forced_auth_type,
-+                                                 forced_auth_level=forced_auth_level)
-+
-+    def test_ntlmssp_multi_auth_first1_firstSame2(self):
-+        auth_type = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP
-+        expected_fault = dcerpc.DCERPC_FAULT_SEC_PKG_ERROR
-+        auth_context_2nd = 2
-+        expected_call_id = None
-+        expected_context_id = None
-+        not_executed = False
-+        conc_mpx = False
-+        forced_call_id = None
-+        forced_context_id = None
-+        forced_opnum = None
-+        forced_auth_context_id = None
-+        forced_auth_type = None
-+        forced_auth_level = None
-+        return self._test_generic_auth_first_first(auth_type,
-+                                                   expected_fault,
-+                                                   auth_context_2nd=auth_context_2nd,
-+                                                   expected_call_id=expected_call_id,
-+                                                   expected_context_id=expected_context_id,
-+                                                   not_executed=not_executed,
-+                                                   conc_mpx=conc_mpx,
-+                                                   forced_call_id=forced_call_id,
-+                                                   forced_context_id=forced_context_id,
-+                                                   forced_opnum=forced_opnum,
-+                                                   forced_auth_context_id=forced_auth_context_id,
-+                                                   forced_auth_type=forced_auth_type,
-+                                                   forced_auth_level=forced_auth_level)
-+
-+    def test_ntlmssp_multi_auth_first1_firstNext2(self):
-+        auth_type = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP
-+        expected_fault = dcerpc.DCERPC_NCA_S_PROTO_ERROR
-+        auth_context_2nd = 2
-+        expected_call_id = 3
-+        expected_context_id = None
-+        not_executed = False
-+        conc_mpx = False
-+        forced_call_id = 4
-+        forced_context_id = None
-+        forced_opnum = None
-+        forced_auth_context_id = None
-+        forced_auth_type = None
-+        forced_auth_level = None
-+        return self._test_generic_auth_first_first(auth_type,
-+                                                   expected_fault,
-+                                                   auth_context_2nd=auth_context_2nd,
-+                                                   expected_call_id=expected_call_id,
-+                                                   expected_context_id=expected_context_id,
-+                                                   not_executed=not_executed,
-+                                                   conc_mpx=conc_mpx,
-+                                                   forced_call_id=forced_call_id,
-+                                                   forced_context_id=forced_context_id,
-+                                                   forced_opnum=forced_opnum,
-+                                                   forced_auth_context_id=forced_auth_context_id,
-+                                                   forced_auth_type=forced_auth_type,
-+                                                   forced_auth_level=forced_auth_level)
-+
-+    def test_ntlmssp_multi_auth_first1_firstSame111(self):
-+        auth_type = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP
-+        expected_fault = dcerpc.DCERPC_NCA_S_PROTO_ERROR
-+        auth_context_2nd = 1
-+        expected_call_id = None
-+        expected_context_id = None
-+        not_executed = False
-+        conc_mpx = False
-+        forced_call_id = None
-+        forced_context_id = 111
-+        forced_opnum = 111
-+        forced_auth_context_id = 111
-+        forced_auth_type = 111
-+        forced_auth_level = 111
-+        return self._test_generic_auth_first_first(auth_type,
-+                                                   expected_fault,
-+                                                   auth_context_2nd=auth_context_2nd,
-+                                                   expected_call_id=expected_call_id,
-+                                                   expected_context_id=expected_context_id,
-+                                                   not_executed=not_executed,
-+                                                   conc_mpx=conc_mpx,
-+                                                   forced_call_id=forced_call_id,
-+                                                   forced_context_id=forced_context_id,
-+                                                   forced_opnum=forced_opnum,
-+                                                   forced_auth_context_id=forced_auth_context_id,
-+                                                   forced_auth_type=forced_auth_type,
-+                                                   forced_auth_level=forced_auth_level)
-+
-+    def test_ntlmssp_multi_auth_MPX_first1_firstSame111(self):
-+        auth_type = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP
-+        expected_fault = dcerpc.DCERPC_NCA_S_PROTO_ERROR
-+        auth_context_2nd = 1
-+        expected_call_id = None
-+        expected_context_id = None
-+        not_executed = False
-+        conc_mpx = True
-+        forced_call_id = None
-+        forced_context_id = 111
-+        forced_opnum = 111
-+        forced_auth_context_id = 111
-+        forced_auth_type = 111
-+        forced_auth_level = 111
-+        return self._test_generic_auth_first_first(auth_type,
-+                                                   expected_fault,
-+                                                   auth_context_2nd=auth_context_2nd,
-+                                                   expected_call_id=expected_call_id,
-+                                                   expected_context_id=expected_context_id,
-+                                                   not_executed=not_executed,
-+                                                   conc_mpx=conc_mpx,
-+                                                   forced_call_id=forced_call_id,
-+                                                   forced_context_id=forced_context_id,
-+                                                   forced_opnum=forced_opnum,
-+                                                   forced_auth_context_id=forced_auth_context_id,
-+                                                   forced_auth_type=forced_auth_type,
-+                                                   forced_auth_level=forced_auth_level)
-+
-+    def test_ntlmssp_multi_auth_first1_firstNext111(self):
-+        auth_type = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP
-+        expected_fault = dcerpc.DCERPC_NCA_S_PROTO_ERROR
-+        auth_context_2nd = 1
-+        expected_call_id = 3
-+        expected_context_id = None
-+        not_executed = False
-+        conc_mpx = False
-+        forced_call_id = 4
-+        forced_context_id = 111
-+        forced_opnum = 111
-+        forced_auth_context_id = 111
-+        forced_auth_type = 111
-+        forced_auth_level = 111
-+        return self._test_generic_auth_first_first(auth_type,
-+                                                   expected_fault,
-+                                                   auth_context_2nd=auth_context_2nd,
-+                                                   expected_call_id=expected_call_id,
-+                                                   expected_context_id=expected_context_id,
-+                                                   not_executed=not_executed,
-+                                                   conc_mpx=conc_mpx,
-+                                                   forced_call_id=forced_call_id,
-+                                                   forced_context_id=forced_context_id,
-+                                                   forced_opnum=forced_opnum,
-+                                                   forced_auth_context_id=forced_auth_context_id,
-+                                                   forced_auth_type=forced_auth_type,
-+                                                   forced_auth_level=forced_auth_level)
-+
-+    def test_ntlmssp_multi_auth_MPX_first1_firstNext111(self):
-+        auth_type = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP
-+        expected_fault = dcerpc.DCERPC_NCA_S_PROTO_ERROR
-+        auth_context_2nd = 1
-+        expected_call_id = 4
-+        expected_context_id = 0
-+        not_executed = False
-+        conc_mpx = True
-+        forced_call_id = 4
-+        forced_context_id = 111
-+        forced_opnum = 111
-+        forced_auth_context_id = 111
-+        forced_auth_type = 111
-+        forced_auth_level = 111
-+        return self._test_generic_auth_first_first(auth_type,
-+                                                   expected_fault,
-+                                                   auth_context_2nd=auth_context_2nd,
-+                                                   expected_call_id=expected_call_id,
-+                                                   expected_context_id=expected_context_id,
-+                                                   not_executed=not_executed,
-+                                                   conc_mpx=conc_mpx,
-+                                                   forced_call_id=forced_call_id,
-+                                                   forced_context_id=forced_context_id,
-+                                                   forced_opnum=forced_opnum,
-+                                                   forced_auth_context_id=forced_auth_context_id,
-+                                                   forced_auth_type=forced_auth_type,
-+                                                   forced_auth_level=forced_auth_level)
-+
-+    def test_ntlmssp_multi_auth_first1_firstSameNone(self):
-+        auth_type = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP
-+        expected_fault = dcerpc.DCERPC_NCA_S_PROTO_ERROR
-+        auth_context_2nd = None
-+        expected_call_id = None
-+        expected_context_id = None
-+        not_executed = False
-+        conc_mpx = False
-+        forced_call_id = None
-+        forced_context_id = None
-+        forced_opnum = None
-+        forced_auth_context_id = None
-+        forced_auth_type = None
-+        forced_auth_level = None
-+        return self._test_generic_auth_first_first(auth_type,
-+                                                   expected_fault,
-+                                                   auth_context_2nd=auth_context_2nd,
-+                                                   expected_call_id=expected_call_id,
-+                                                   expected_context_id=expected_context_id,
-+                                                   not_executed=not_executed,
-+                                                   conc_mpx=conc_mpx,
-+                                                   forced_call_id=forced_call_id,
-+                                                   forced_context_id=forced_context_id,
-+                                                   forced_opnum=forced_opnum,
-+                                                   forced_auth_context_id=forced_auth_context_id,
-+                                                   forced_auth_type=forced_auth_type,
-+                                                   forced_auth_level=forced_auth_level)
-+
-+    def test_ntlmssp_multi_auth_MPX_first1_firstSameNone(self):
-+        auth_type = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP
-+        expected_fault = dcerpc.DCERPC_NCA_S_PROTO_ERROR
-+        auth_context_2nd = None
-+        expected_call_id = None
-+        expected_context_id = None
-+        not_executed = False
-+        conc_mpx = True
-+        forced_call_id = None
-+        forced_context_id = None
-+        forced_opnum = None
-+        forced_auth_context_id = None
-+        forced_auth_type = None
-+        forced_auth_level = None
-+        return self._test_generic_auth_first_first(auth_type,
-+                                                   expected_fault,
-+                                                   auth_context_2nd=auth_context_2nd,
-+                                                   expected_call_id=expected_call_id,
-+                                                   expected_context_id=expected_context_id,
-+                                                   not_executed=not_executed,
-+                                                   conc_mpx=conc_mpx,
-+                                                   forced_call_id=forced_call_id,
-+                                                   forced_context_id=forced_context_id,
-+                                                   forced_opnum=forced_opnum,
-+                                                   forced_auth_context_id=forced_auth_context_id,
-+                                                   forced_auth_type=forced_auth_type,
-+                                                   forced_auth_level=forced_auth_level)
-+
-+    def test_ntlmssp_multi_auth_first1_firstNextNone(self):
-+        auth_type = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP
-+        expected_fault = dcerpc.DCERPC_NCA_S_PROTO_ERROR
-+        auth_context_2nd = None
-+        expected_call_id = None
-+        expected_context_id = None
-+        not_executed = False
-+        conc_mpx = False
-+        forced_call_id = 4
-+        forced_context_id = None
-+        forced_opnum = None
-+        forced_auth_context_id = None
-+        forced_auth_type = None
-+        forced_auth_level = None
-+        return self._test_generic_auth_first_first(auth_type,
-+                                                   expected_fault,
-+                                                   auth_context_2nd=auth_context_2nd,
-+                                                   expected_call_id=expected_call_id,
-+                                                   expected_context_id=expected_context_id,
-+                                                   not_executed=not_executed,
-+                                                   conc_mpx=conc_mpx,
-+                                                   forced_call_id=forced_call_id,
-+                                                   forced_context_id=forced_context_id,
-+                                                   forced_opnum=forced_opnum,
-+                                                   forced_auth_context_id=forced_auth_context_id,
-+                                                   forced_auth_type=forced_auth_type,
-+                                                   forced_auth_level=forced_auth_level)
-+
-+    def test_ntlmssp_multi_auth_MPX_first1_firstNextNone(self):
-+        auth_type = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP
-+        expected_fault = dcerpc.DCERPC_NCA_S_PROTO_ERROR
-+        auth_context_2nd = None
-+        expected_call_id = 4
-+        expected_context_id = 0
-+        not_executed = False
-+        conc_mpx = True
-+        forced_call_id = 4
-+        forced_context_id = None
-+        forced_opnum = None
-+        forced_auth_context_id = None
-+        forced_auth_type = None
-+        forced_auth_level = None
-+        return self._test_generic_auth_first_first(auth_type,
-+                                                   expected_fault,
-+                                                   auth_context_2nd=auth_context_2nd,
-+                                                   expected_call_id=expected_call_id,
-+                                                   expected_context_id=expected_context_id,
-+                                                   not_executed=not_executed,
-+                                                   conc_mpx=conc_mpx,
-+                                                   forced_call_id=forced_call_id,
-+                                                   forced_context_id=forced_context_id,
-+                                                   forced_opnum=forced_opnum,
-+                                                   forced_auth_context_id=forced_auth_context_id,
-+                                                   forced_auth_type=forced_auth_type,
-+                                                   forced_auth_level=forced_auth_level)
-+
-+    def test_ntlmssp_multi_auth_first1_firstSameNone111(self):
-+        auth_type = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP
-+        expected_fault = dcerpc.DCERPC_NCA_S_PROTO_ERROR
-+        auth_context_2nd = None
-+        expected_call_id = None
-+        expected_context_id = None
-+        not_executed = False
-+        conc_mpx = False
-+        forced_call_id = None
-+        forced_context_id = 111
-+        forced_opnum = 111
-+        forced_auth_context_id = None
-+        forced_auth_type = None
-+        forced_auth_level = None
-+        return self._test_generic_auth_first_first(auth_type,
-+                                                   expected_fault,
-+                                                   auth_context_2nd=auth_context_2nd,
-+                                                   expected_call_id=expected_call_id,
-+                                                   expected_context_id=expected_context_id,
-+                                                   not_executed=not_executed,
-+                                                   conc_mpx=conc_mpx,
-+                                                   forced_call_id=forced_call_id,
-+                                                   forced_context_id=forced_context_id,
-+                                                   forced_opnum=forced_opnum,
-+                                                   forced_auth_context_id=forced_auth_context_id,
-+                                                   forced_auth_type=forced_auth_type,
-+                                                   forced_auth_level=forced_auth_level)
-+
-+    def test_ntlmssp_multi_auth_MPX_first1_firstSameNone111(self):
-+        auth_type = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP
-+        expected_fault = dcerpc.DCERPC_NCA_S_PROTO_ERROR
-+        auth_context_2nd = None
-+        expected_call_id = None
-+        expected_context_id = None
-+        not_executed = False
-+        conc_mpx = True
-+        forced_call_id = None
-+        forced_context_id = 111
-+        forced_opnum = 111
-+        forced_auth_context_id = None
-+        forced_auth_type = None
-+        forced_auth_level = None
-+        return self._test_generic_auth_first_first(auth_type,
-+                                                   expected_fault,
-+                                                   auth_context_2nd=auth_context_2nd,
-+                                                   expected_call_id=expected_call_id,
-+                                                   expected_context_id=expected_context_id,
-+                                                   not_executed=not_executed,
-+                                                   conc_mpx=conc_mpx,
-+                                                   forced_call_id=forced_call_id,
-+                                                   forced_context_id=forced_context_id,
-+                                                   forced_opnum=forced_opnum,
-+                                                   forced_auth_context_id=forced_auth_context_id,
-+                                                   forced_auth_type=forced_auth_type,
-+                                                   forced_auth_level=forced_auth_level)
-+
-+    def test_ntlmssp_multi_auth_first1_firstNextNone111(self):
-+        auth_type = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP
-+        expected_fault = dcerpc.DCERPC_NCA_S_PROTO_ERROR
-+        auth_context_2nd = None
-+        expected_call_id = None
-+        expected_context_id = None
-+        not_executed = False
-+        conc_mpx = False
-+        forced_call_id = 4
-+        forced_context_id = 111
-+        forced_opnum = 111
-+        forced_auth_context_id = None
-+        forced_auth_type = None
-+        forced_auth_level = None
-+        return self._test_generic_auth_first_first(auth_type,
-+                                                   expected_fault,
-+                                                   auth_context_2nd=auth_context_2nd,
-+                                                   expected_call_id=expected_call_id,
-+                                                   expected_context_id=expected_context_id,
-+                                                   not_executed=not_executed,
-+                                                   conc_mpx=conc_mpx,
-+                                                   forced_call_id=forced_call_id,
-+                                                   forced_context_id=forced_context_id,
-+                                                   forced_opnum=forced_opnum,
-+                                                   forced_auth_context_id=forced_auth_context_id,
-+                                                   forced_auth_type=forced_auth_type,
-+                                                   forced_auth_level=forced_auth_level)
-+
-+    def test_ntlmssp_multi_auth_MPX_first1_firstNextNone111(self):
-+        auth_type = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP
-+        expected_fault = dcerpc.DCERPC_NCA_S_PROTO_ERROR
-+        auth_context_2nd = None
-+        expected_call_id = 4
-+        expected_context_id = 0
-+        not_executed = False
-+        conc_mpx = True
-+        forced_call_id = 4
-+        forced_context_id = 111
-+        forced_opnum = 111
-+        forced_auth_context_id = None
-+        forced_auth_type = None
-+        forced_auth_level = None
-+        return self._test_generic_auth_first_first(auth_type,
-+                                                   expected_fault,
-+                                                   auth_context_2nd=auth_context_2nd,
-+                                                   expected_call_id=expected_call_id,
-+                                                   expected_context_id=expected_context_id,
-+                                                   not_executed=not_executed,
-+                                                   conc_mpx=conc_mpx,
-+                                                   forced_call_id=forced_call_id,
-+                                                   forced_context_id=forced_context_id,
-+                                                   forced_opnum=forced_opnum,
-+                                                   forced_auth_context_id=forced_auth_context_id,
-+                                                   forced_auth_type=forced_auth_type,
-+                                                   forced_auth_level=forced_auth_level)
-+
-+    def _test_generic_auth_middle(self,
-+                                  auth_type,
-+                                  expected_fault,
-+                                  expected_context_id=None,
-+                                  not_executed=False,
-+                                  conc_mpx=False,
-+                                  forced_context_id=None,
-+                                  forced_opnum=None,
-+                                  forced_auth_context_id=None,
-+                                  forced_auth_type=None,
-+                                  forced_auth_level=None):
-+        auth_context_2nd = 1
-+        skip_first = True
-+        pfc_flags_2nd = 0
-+        expected_call_id = None
-+        forced_call_id = None
-+        return self._test_generic_auth_first_2nd(auth_type,
-+                                                 pfc_flags_2nd,
-+                                                 expected_fault,
-+                                                 auth_context_2nd=auth_context_2nd,
-+                                                 skip_first=skip_first,
-+                                                 expected_call_id=expected_call_id,
-+                                                 expected_context_id=expected_context_id,
-+                                                 not_executed=not_executed,
-+                                                 conc_mpx=conc_mpx,
-+                                                 forced_call_id=forced_call_id,
-+                                                 forced_context_id=forced_context_id,
-+                                                 forced_opnum=forced_opnum,
-+                                                 forced_auth_context_id=forced_auth_context_id,
-+                                                 forced_auth_type=forced_auth_type,
-+                                                 forced_auth_level=forced_auth_level)
-+
-+    def test_ntlmssp_auth_middle_alone(self):
-+        auth_type = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP
-+        expected_fault = dcerpc.DCERPC_NCA_S_PROTO_ERROR
-+        expected_context_id = 0
-+        not_executed = False
-+        conc_mpx = False
-+        forced_context_id = None
-+        forced_opnum = None
-+        forced_auth_context_id = None
-+        forced_auth_type = None
-+        forced_auth_level = None
-+        return self._test_generic_auth_middle(auth_type,
-+                                              expected_fault,
-+                                              expected_context_id=expected_context_id,
-+                                              not_executed=not_executed,
-+                                              conc_mpx=conc_mpx,
-+                                              forced_context_id=forced_context_id,
-+                                              forced_opnum=forced_opnum,
-+                                              forced_auth_context_id=forced_auth_context_id,
-+                                              forced_auth_type=forced_auth_type,
-+                                              forced_auth_level=forced_auth_level)
-+
-+    def test_ntlmssp_auth_MPX_middle_alone(self):
-+        auth_type = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP
-+        expected_fault = dcerpc.DCERPC_NCA_S_PROTO_ERROR
-+        expected_context_id = None
-+        not_executed = False
-+        conc_mpx = True
-+        forced_context_id = None
-+        forced_opnum = None
-+        forced_auth_context_id = None
-+        forced_auth_type = None
-+        forced_auth_level = None
-+        return self._test_generic_auth_middle(auth_type,
-+                                              expected_fault,
-+                                              expected_context_id=expected_context_id,
-+                                              not_executed=not_executed,
-+                                              conc_mpx=conc_mpx,
-+                                              forced_context_id=forced_context_id,
-+                                              forced_opnum=forced_opnum,
-+                                              forced_auth_context_id=forced_auth_context_id,
-+                                              forced_auth_type=forced_auth_type,
-+                                              forced_auth_level=forced_auth_level)
-+
-+    def test_ntlmssp_auth_middle_all_111(self):
-+        auth_type = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP
-+        expected_fault = dcerpc.DCERPC_NCA_S_PROTO_ERROR
-+        expected_context_id = 0
-+        not_executed = False
-+        conc_mpx = False
-+        forced_context_id = 111
-+        forced_opnum = 111
-+        forced_auth_context_id = 111
-+        forced_auth_type = 111
-+        forced_auth_level = 111
-+        return self._test_generic_auth_middle(auth_type,
-+                                              expected_fault,
-+                                              expected_context_id=expected_context_id,
-+                                              not_executed=not_executed,
-+                                              conc_mpx=conc_mpx,
-+                                              forced_context_id=forced_context_id,
-+                                              forced_opnum=forced_opnum,
-+                                              forced_auth_context_id=forced_auth_context_id,
-+                                              forced_auth_type=forced_auth_type,
-+                                              forced_auth_level=forced_auth_level)
-+
-+    def test_ntlmssp_auth_MPX_middle_all_111(self):
-+        auth_type = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP
-+        expected_fault = dcerpc.DCERPC_NCA_S_UNKNOWN_IF
-+        expected_context_id = 0
-+        not_executed = True
-+        conc_mpx = True
-+        forced_context_id = 111
-+        forced_opnum = 111
-+        forced_auth_context_id = 111
-+        forced_auth_type = 111
-+        forced_auth_level = 111
-+        return self._test_generic_auth_middle(auth_type,
-+                                              expected_fault,
-+                                              expected_context_id=expected_context_id,
-+                                              not_executed=not_executed,
-+                                              conc_mpx=conc_mpx,
-+                                              forced_context_id=forced_context_id,
-+                                              forced_opnum=forced_opnum,
-+                                              forced_auth_context_id=forced_auth_context_id,
-+                                              forced_auth_type=forced_auth_type,
-+                                              forced_auth_level=forced_auth_level)
-+
-+    def test_ntlmssp_auth_middle_auth_all_111(self):
-+        auth_type = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP
-+        expected_fault = dcerpc.DCERPC_NCA_S_PROTO_ERROR
-+        expected_context_id = 0
-+        not_executed = False
-+        conc_mpx = False
-+        forced_context_id = None
-+        forced_opnum = 111
-+        forced_auth_context_id = 111
-+        forced_auth_type = 111
-+        forced_auth_level = 111
-+        return self._test_generic_auth_middle(auth_type,
-+                                              expected_fault,
-+                                              expected_context_id=expected_context_id,
-+                                              not_executed=not_executed,
-+                                              conc_mpx=conc_mpx,
-+                                              forced_context_id=forced_context_id,
-+                                              forced_opnum=forced_opnum,
-+                                              forced_auth_context_id=forced_auth_context_id,
-+                                              forced_auth_type=forced_auth_type,
-+                                              forced_auth_level=forced_auth_level)
-+
-+    def test_ntlmssp_auth_MPX_middle_auth_all_111(self):
-+        auth_type = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP
-+        expected_fault = dcerpc.DCERPC_FAULT_ACCESS_DENIED
-+        expected_context_id = None
-+        not_executed = False
-+        conc_mpx = True
-+        forced_context_id = None
-+        forced_opnum = 111
-+        forced_auth_context_id = 111
-+        forced_auth_type = 111
-+        forced_auth_level = 111
-+        return self._test_generic_auth_middle(auth_type,
-+                                              expected_fault,
-+                                              expected_context_id=expected_context_id,
-+                                              not_executed=not_executed,
-+                                              conc_mpx=conc_mpx,
-+                                              forced_context_id=forced_context_id,
-+                                              forced_opnum=forced_opnum,
-+                                              forced_auth_context_id=forced_auth_context_id,
-+                                              forced_auth_type=forced_auth_type,
-+                                              forced_auth_level=forced_auth_level)
-+
-+    def test_ntlmssp_auth_middle_auth_context_111(self):
-+        auth_type = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP
-+        expected_fault = dcerpc.DCERPC_NCA_S_PROTO_ERROR
-+        expected_context_id = 0
-+        not_executed = False
-+        conc_mpx = False
-+        forced_context_id = None
-+        forced_opnum = None
-+        forced_auth_context_id = 111
-+        forced_auth_type = None
-+        forced_auth_level = None
-+        return self._test_generic_auth_middle(auth_type,
-+                                              expected_fault,
-+                                              expected_context_id=expected_context_id,
-+                                              not_executed=not_executed,
-+                                              conc_mpx=conc_mpx,
-+                                              forced_context_id=forced_context_id,
-+                                              forced_opnum=forced_opnum,
-+                                              forced_auth_context_id=forced_auth_context_id,
-+                                              forced_auth_type=forced_auth_type,
-+                                              forced_auth_level=forced_auth_level)
-+
-+    def test_ntlmssp_auth_MPX_middle_auth_context_111(self):
-+        auth_type = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP
-+        expected_fault = dcerpc.DCERPC_FAULT_ACCESS_DENIED
-+        expected_context_id = None
-+        not_executed = False
-+        conc_mpx = True
-+        forced_context_id = None
-+        forced_opnum = None
-+        forced_auth_context_id = 111
-+        forced_auth_type = None
-+        forced_auth_level = None
-+        return self._test_generic_auth_middle(auth_type,
-+                                              expected_fault,
-+                                              expected_context_id=expected_context_id,
-+                                              not_executed=not_executed,
-+                                              conc_mpx=conc_mpx,
-+                                              forced_context_id=forced_context_id,
-+                                              forced_opnum=forced_opnum,
-+                                              forced_auth_context_id=forced_auth_context_id,
-+                                              forced_auth_type=forced_auth_type,
-+                                              forced_auth_level=forced_auth_level)
-+
-+    def test_ntlmssp_auth_middle_auth_type_111(self):
-+        auth_type = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP
-+        expected_fault = dcerpc.DCERPC_NCA_S_PROTO_ERROR
-+        expected_context_id = 0
-+        not_executed = False
-+        conc_mpx = False
-+        forced_context_id = None
-+        forced_opnum = None
-+        forced_auth_context_id = None
-+        forced_auth_type = 111
-+        forced_auth_level = None
-+        return self._test_generic_auth_middle(auth_type,
-+                                              expected_fault,
-+                                              expected_context_id=expected_context_id,
-+                                              not_executed=not_executed,
-+                                              conc_mpx=conc_mpx,
-+                                              forced_context_id=forced_context_id,
-+                                              forced_opnum=forced_opnum,
-+                                              forced_auth_context_id=forced_auth_context_id,
-+                                              forced_auth_type=forced_auth_type,
-+                                              forced_auth_level=forced_auth_level)
-+
-+    def test_ntlmssp_auth_MPX_middle_auth_type_111(self):
-+        auth_type = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP
-+        expected_fault = dcerpc.DCERPC_FAULT_ACCESS_DENIED
-+        expected_context_id = None
-+        not_executed = False
-+        conc_mpx = True
-+        forced_context_id = None
-+        forced_opnum = None
-+        forced_auth_context_id = None
-+        forced_auth_type = 111
-+        forced_auth_level = None
-+        return self._test_generic_auth_middle(auth_type,
-+                                              expected_fault,
-+                                              expected_context_id=expected_context_id,
-+                                              not_executed=not_executed,
-+                                              conc_mpx=conc_mpx,
-+                                              forced_context_id=forced_context_id,
-+                                              forced_opnum=forced_opnum,
-+                                              forced_auth_context_id=forced_auth_context_id,
-+                                              forced_auth_type=forced_auth_type,
-+                                              forced_auth_level=forced_auth_level)
-+
-+    def test_ntlmssp_auth_middle_auth_level_111(self):
-+        auth_type = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP
-+        expected_fault = dcerpc.DCERPC_NCA_S_PROTO_ERROR
-+        expected_context_id = 0
-+        not_executed = False
-+        conc_mpx = False
-+        forced_context_id = None
-+        forced_opnum = None
-+        forced_auth_context_id = None
-+        forced_auth_type = None
-+        forced_auth_level = 111
-+        return self._test_generic_auth_middle(auth_type,
-+                                              expected_fault,
-+                                              expected_context_id=expected_context_id,
-+                                              not_executed=not_executed,
-+                                              conc_mpx=conc_mpx,
-+                                              forced_context_id=forced_context_id,
-+                                              forced_opnum=forced_opnum,
-+                                              forced_auth_context_id=forced_auth_context_id,
-+                                              forced_auth_type=forced_auth_type,
-+                                              forced_auth_level=forced_auth_level)
-+
-+    def test_ntlmssp_auth_MPX_middle_auth_level_111(self):
-+        auth_type = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP
-+        expected_fault = dcerpc.DCERPC_FAULT_ACCESS_DENIED
-+        expected_context_id = None
-+        not_executed = False
-+        conc_mpx = True
-+        forced_context_id = None
-+        forced_opnum = None
-+        forced_auth_context_id = None
-+        forced_auth_type = None
-+        forced_auth_level = 111
-+        return self._test_generic_auth_middle(auth_type,
-+                                              expected_fault,
-+                                              expected_context_id=expected_context_id,
-+                                              not_executed=not_executed,
-+                                              conc_mpx=conc_mpx,
-+                                              forced_context_id=forced_context_id,
-+                                              forced_opnum=forced_opnum,
-+                                              forced_auth_context_id=forced_auth_context_id,
-+                                              forced_auth_type=forced_auth_type,
-+                                              forced_auth_level=forced_auth_level)
-+
-     def _test_neg_xmit_check_values(self,
-                                     req_xmit=None,
-                                     req_recv=None,
-diff --git a/selftest/knownfail.d/dcerpc-auth-fraq b/selftest/knownfail.d/dcerpc-auth-fraq
-new file mode 100644
-index 00000000000..f3c62b65e9e
---- /dev/null
-+++ b/selftest/knownfail.d/dcerpc-auth-fraq
-@@ -0,0 +1,20 @@
-+^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_ntlmssp_auth_MPX_middle_all_111
-+^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_ntlmssp_auth_MPX_middle_alone
-+^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_ntlmssp_auth_MPX_middle_auth_all_111
-+^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_ntlmssp_auth_MPX_middle_auth_context_111
-+^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_ntlmssp_auth_MPX_middle_auth_level_111
-+^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_ntlmssp_auth_MPX_middle_auth_type_111
-+^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_ntlmssp_multi_auth_MPX_first1_firstSame111
-+^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_ntlmssp_multi_auth_MPX_first1_firstSameNone
-+^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_ntlmssp_multi_auth_MPX_first1_firstSameNone111
-+^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_ntlmssp_multi_auth_MPX_first1_lastSameNone
-+^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_ntlmssp_multi_auth_MPX_first1_lastSameNone111
-+^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_ntlmssp_multi_auth_first1_firstSame2
-+^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_ntlmssp_multi_auth_first1_lastNext111
-+^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_ntlmssp_multi_auth_first1_lastNext2
-+^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_ntlmssp_multi_auth_first1_lastNextNone
-+^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_ntlmssp_multi_auth_first1_lastNextNone111
-+^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_ntlmssp_multi_auth_first1_lastSame111
-+^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_ntlmssp_multi_auth_first1_lastSame2
-+^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_ntlmssp_multi_auth_first1_lastSameNone
-+^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_ntlmssp_multi_auth_first1_lastSameNone111
--- 
-2.25.1
-
-
-From 43b09da3138606e2d0fbc033e8bc50fa82687946 Mon Sep 17 00:00:00 2001
-From: Stefan Metzmacher <metze@samba.org>
-Date: Mon, 16 Nov 2020 14:15:06 +0100
-Subject: [PATCH 9/9] CVE-2021-23192: dcesrv_core: only the first fragment
- specifies the auth_contexts
-
-All other fragments blindly inherit it.
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14875
-
-Signed-off-by: Stefan Metzmacher <metze@samba.org>
-Reviewed-by: Samuel Cabrero <scabrero@samba.org>
----
- librpc/rpc/dcerpc_pkt_auth.c          | 19 +++---
- librpc/rpc/dcerpc_pkt_auth.h          |  1 +
- librpc/rpc/dcesrv_auth.c              | 28 +++++++++
- librpc/rpc/dcesrv_core.c              | 86 +++++++++++++++++++++------
- selftest/knownfail.d/dcerpc-auth-fraq | 20 -------
- source4/librpc/rpc/dcerpc.c           |  1 +
- 6 files changed, 109 insertions(+), 46 deletions(-)
- delete mode 100644 selftest/knownfail.d/dcerpc-auth-fraq
-
-diff --git a/librpc/rpc/dcerpc_pkt_auth.c b/librpc/rpc/dcerpc_pkt_auth.c
-index 322d7497893..1cb191468b5 100644
---- a/librpc/rpc/dcerpc_pkt_auth.c
-+++ b/librpc/rpc/dcerpc_pkt_auth.c
-@@ -39,6 +39,7 @@
- 
- NTSTATUS dcerpc_ncacn_pull_pkt_auth(const struct dcerpc_auth *auth_state,
- 				    struct gensec_security *gensec,
-+				    bool check_pkt_auth_fields,
- 				    TALLOC_CTX *mem_ctx,
- 				    enum dcerpc_pkt_type ptype,
- 				    uint8_t required_flags,
-@@ -115,16 +116,18 @@ NTSTATUS dcerpc_ncacn_pull_pkt_auth(const struct dcerpc_auth *auth_state,
- 		return NT_STATUS_INTERNAL_ERROR;
- 	}
- 
--	if (auth.auth_type != auth_state->auth_type) {
--		return NT_STATUS_ACCESS_DENIED;
--	}
-+	if (check_pkt_auth_fields) {
-+		if (auth.auth_type != auth_state->auth_type) {
-+			return NT_STATUS_ACCESS_DENIED;
-+		}
- 
--	if (auth.auth_level != auth_state->auth_level) {
--		return NT_STATUS_ACCESS_DENIED;
--	}
-+		if (auth.auth_level != auth_state->auth_level) {
-+			return NT_STATUS_ACCESS_DENIED;
-+		}
- 
--	if (auth.auth_context_id != auth_state->auth_context_id) {
--		return NT_STATUS_ACCESS_DENIED;
-+		if (auth.auth_context_id != auth_state->auth_context_id) {
-+			return NT_STATUS_ACCESS_DENIED;
-+		}
- 	}
- 
- 	/* check signature or unseal the packet */
-diff --git a/librpc/rpc/dcerpc_pkt_auth.h b/librpc/rpc/dcerpc_pkt_auth.h
-index c0d23b91c05..1dcee12f53c 100644
---- a/librpc/rpc/dcerpc_pkt_auth.h
-+++ b/librpc/rpc/dcerpc_pkt_auth.h
-@@ -31,6 +31,7 @@
- 
- NTSTATUS dcerpc_ncacn_pull_pkt_auth(const struct dcerpc_auth *auth_state,
- 				    struct gensec_security *gensec,
-+				    bool check_pkt_auth_fields,
- 				    TALLOC_CTX *mem_ctx,
- 				    enum dcerpc_pkt_type ptype,
- 				    uint8_t required_flags,
-diff --git a/librpc/rpc/dcesrv_auth.c b/librpc/rpc/dcesrv_auth.c
-index 8dda86d88e2..9d8df6c42e2 100644
---- a/librpc/rpc/dcesrv_auth.c
-+++ b/librpc/rpc/dcesrv_auth.c
-@@ -438,6 +438,10 @@ bool dcesrv_auth_prepare_auth3(struct dcesrv_call_state *call)
- 		return false;
- 	}
- 
-+	if (auth->auth_invalid) {
-+		return false;
-+	}
-+
- 	/* We can't work without an existing gensec state */
- 	if (auth->gensec_security == NULL) {
- 		return false;
-@@ -524,6 +528,10 @@ bool dcesrv_auth_alter(struct dcesrv_call_state *call)
- 		return false;
- 	}
- 
-+	if (auth->auth_invalid) {
-+		return false;
-+	}
-+
- 	if (call->in_auth_info.auth_type != auth->auth_type) {
- 		return false;
- 	}
-@@ -590,6 +598,7 @@ bool dcesrv_auth_pkt_pull(struct dcesrv_call_state *call,
- 		.auth_level = auth->auth_level,
- 		.auth_context_id = auth->auth_context_id,
- 	};
-+	bool check_pkt_auth_fields;
- 	NTSTATUS status;
- 
- 	if (!auth->auth_started) {
-@@ -605,8 +614,27 @@ bool dcesrv_auth_pkt_pull(struct dcesrv_call_state *call,
- 		return false;
- 	}
- 
-+	if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
-+		/*
-+		 * The caller most likely checked this
-+		 * already, but we better double check.
-+		 */
-+		check_pkt_auth_fields = true;
-+	} else {
-+		/*
-+		 * The caller already found first fragment
-+		 * and is passing the auth_state of it.
-+		 * A server is supposed to use the
-+		 * setting of the first fragment and
-+		 * completely ignore the values
-+		 * on the remaining fragments
-+		 */
-+		check_pkt_auth_fields = false;
-+	}
-+
- 	status = dcerpc_ncacn_pull_pkt_auth(&tmp_auth,
- 					    auth->gensec_security,
-+					    check_pkt_auth_fields,
- 					    call,
- 					    pkt->ptype,
- 					    required_flags,
-diff --git a/librpc/rpc/dcesrv_core.c b/librpc/rpc/dcesrv_core.c
-index ffaa9019d4b..0bab4c10641 100644
---- a/librpc/rpc/dcesrv_core.c
-+++ b/librpc/rpc/dcesrv_core.c
-@@ -1805,6 +1805,10 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
- 	struct ndr_pull *pull;
- 	NTSTATUS status;
- 
-+	if (auth->auth_invalid) {
-+		return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
-+	}
-+
- 	if (!auth->auth_finished) {
- 		return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
- 	}
-@@ -1968,6 +1972,7 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
- 	enum dcerpc_AuthType auth_type = 0;
- 	enum dcerpc_AuthLevel auth_level = 0;
- 	uint32_t auth_context_id = 0;
-+	bool auth_invalid = false;
- 
- 	call = talloc_zero(dce_conn, struct dcesrv_call_state);
- 	if (!call) {
-@@ -1999,12 +2004,16 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
- 
- 	if (call->auth_state == NULL) {
- 		struct dcesrv_auth *a = NULL;
-+		bool check_type_level = true;
- 
- 		auth_type = dcerpc_get_auth_type(&blob);
- 		auth_level = dcerpc_get_auth_level(&blob);
- 		auth_context_id = dcerpc_get_auth_context_id(&blob);
- 
- 		if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
-+			if (!(call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST)) {
-+				check_type_level = false;
-+			}
- 			dce_conn->default_auth_level_connect = NULL;
- 			if (auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
- 				dce_conn->got_explicit_auth_level_connect = true;
-@@ -2014,14 +2023,19 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
- 		for (a = dce_conn->auth_states; a != NULL; a = a->next) {
- 			num_auth_ctx++;
- 
--			if (a->auth_type != auth_type) {
-+			if (a->auth_context_id != auth_context_id) {
- 				continue;
- 			}
--			if (a->auth_finished && a->auth_level != auth_level) {
--				continue;
-+
-+			if (a->auth_type != auth_type) {
-+				auth_invalid = true;
- 			}
--			if (a->auth_context_id != auth_context_id) {
--				continue;
-+			if (a->auth_level != auth_level) {
-+				auth_invalid = true;
-+			}
-+
-+			if (check_type_level && auth_invalid) {
-+				a->auth_invalid = true;
- 			}
- 
- 			DLIST_PROMOTE(dce_conn->auth_states, a);
-@@ -2048,6 +2062,7 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
- 			/*
- 			 * This can never be valid.
- 			 */
-+			auth_invalid = true;
- 			a->auth_invalid = true;
- 		}
- 		call->auth_state = a;
-@@ -2116,6 +2131,18 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
- 			}
- 			/* only one request is possible in the fragmented list */
- 			if (dce_conn->incoming_fragmented_call_list != NULL) {
-+				call->fault_code = DCERPC_NCA_S_PROTO_ERROR;
-+
-+				existing = dcesrv_find_fragmented_call(dce_conn,
-+								       call->pkt.call_id);
-+				if (existing != NULL && call->auth_state != existing->auth_state) {
-+					call->context = dcesrv_find_context(call->conn,
-+								call->pkt.u.request.context_id);
-+
-+					if (call->pkt.auth_length != 0 && existing->context == call->context) {
-+						call->fault_code = DCERPC_FAULT_SEC_PKG_ERROR;
-+					}
-+				}
- 				if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
- 					/*
- 					 * Without DCERPC_PFC_FLAG_CONC_MPX
-@@ -2125,11 +2152,14 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
- 					 * This is important to get the
- 					 * call_id and context_id right.
- 					 */
-+					dce_conn->incoming_fragmented_call_list->fault_code = call->fault_code;
- 					TALLOC_FREE(call);
- 					call = dce_conn->incoming_fragmented_call_list;
- 				}
--				return dcesrv_fault_disconnect0(call,
--						DCERPC_NCA_S_PROTO_ERROR);
-+				if (existing != NULL) {
-+					call->context = existing->context;
-+				}
-+				return dcesrv_fault_disconnect0(call, call->fault_code);
- 			}
- 			if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) {
- 				return dcesrv_fault_disconnect(call,
-@@ -2142,17 +2172,43 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
- 					DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
- 			}
- 		} else {
--			const struct dcerpc_request *nr = &call->pkt.u.request;
--			const struct dcerpc_request *er = NULL;
- 			int cmp;
- 
- 			existing = dcesrv_find_fragmented_call(dce_conn,
- 							call->pkt.call_id);
- 			if (existing == NULL) {
-+				if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
-+					/*
-+					 * Without DCERPC_PFC_FLAG_CONC_MPX
-+					 * we need to return the FAULT on the
-+					 * already existing call.
-+					 *
-+					 * This is important to get the
-+					 * call_id and context_id right.
-+					 */
-+					if (dce_conn->incoming_fragmented_call_list != NULL) {
-+						TALLOC_FREE(call);
-+						call = dce_conn->incoming_fragmented_call_list;
-+					}
-+					return dcesrv_fault_disconnect0(call,
-+							DCERPC_NCA_S_PROTO_ERROR);
-+				}
-+				if (dce_conn->incoming_fragmented_call_list != NULL) {
-+					return dcesrv_fault_disconnect0(call, DCERPC_NCA_S_PROTO_ERROR);
-+				}
-+				call->context = dcesrv_find_context(call->conn,
-+							call->pkt.u.request.context_id);
-+				if (call->context == NULL) {
-+					return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
-+						DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
-+				}
-+				if (auth_invalid) {
-+					return dcesrv_fault_disconnect0(call,
-+									DCERPC_FAULT_ACCESS_DENIED);
-+				}
- 				return dcesrv_fault_disconnect0(call,
- 						DCERPC_NCA_S_PROTO_ERROR);
- 			}
--			er = &existing->pkt.u.request;
- 
- 			if (call->pkt.ptype != existing->pkt.ptype) {
- 				/* trying to play silly buggers are we? */
-@@ -2165,14 +2221,8 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
- 				return dcesrv_fault_disconnect(existing,
- 						DCERPC_NCA_S_PROTO_ERROR);
- 			}
--			if (nr->context_id != er->context_id)  {
--				return dcesrv_fault_disconnect(existing,
--						DCERPC_NCA_S_PROTO_ERROR);
--			}
--			if (nr->opnum != er->opnum)  {
--				return dcesrv_fault_disconnect(existing,
--						DCERPC_NCA_S_PROTO_ERROR);
--			}
-+			call->auth_state = existing->auth_state;
-+			call->context = existing->context;
- 		}
- 	}
- 
-diff --git a/selftest/knownfail.d/dcerpc-auth-fraq b/selftest/knownfail.d/dcerpc-auth-fraq
-deleted file mode 100644
-index f3c62b65e9e..00000000000
---- a/selftest/knownfail.d/dcerpc-auth-fraq
-+++ /dev/null
-@@ -1,20 +0,0 @@
--^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_ntlmssp_auth_MPX_middle_all_111
--^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_ntlmssp_auth_MPX_middle_alone
--^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_ntlmssp_auth_MPX_middle_auth_all_111
--^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_ntlmssp_auth_MPX_middle_auth_context_111
--^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_ntlmssp_auth_MPX_middle_auth_level_111
--^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_ntlmssp_auth_MPX_middle_auth_type_111
--^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_ntlmssp_multi_auth_MPX_first1_firstSame111
--^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_ntlmssp_multi_auth_MPX_first1_firstSameNone
--^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_ntlmssp_multi_auth_MPX_first1_firstSameNone111
--^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_ntlmssp_multi_auth_MPX_first1_lastSameNone
--^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_ntlmssp_multi_auth_MPX_first1_lastSameNone111
--^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_ntlmssp_multi_auth_first1_firstSame2
--^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_ntlmssp_multi_auth_first1_lastNext111
--^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_ntlmssp_multi_auth_first1_lastNext2
--^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_ntlmssp_multi_auth_first1_lastNextNone
--^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_ntlmssp_multi_auth_first1_lastNextNone111
--^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_ntlmssp_multi_auth_first1_lastSame111
--^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_ntlmssp_multi_auth_first1_lastSame2
--^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_ntlmssp_multi_auth_first1_lastSameNone
--^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_ntlmssp_multi_auth_first1_lastSameNone111
-diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c
-index 4847e8a0200..baf6df6e498 100644
---- a/source4/librpc/rpc/dcerpc.c
-+++ b/source4/librpc/rpc/dcerpc.c
-@@ -726,6 +726,7 @@ static NTSTATUS ncacn_pull_pkt_auth(struct dcecli_connection *c,
- 
- 	status = dcerpc_ncacn_pull_pkt_auth(&tmp_auth,
- 					    c->security_state.generic_state,
-+					    true, /* check_pkt_auth_fields */
- 					    mem_ctx,
- 					    ptype,
- 					    required_flags,
--- 
-2.25.1
-
diff --git a/SOURCES/CVE-2021-44142-v4.14.patch b/SOURCES/CVE-2021-44142-v4.14.patch
deleted file mode 100644
index 1f76f7c..0000000
--- a/SOURCES/CVE-2021-44142-v4.14.patch
+++ /dev/null
@@ -1,759 +0,0 @@
-From 2f7332f6c283fbedbd859c79a3f74ca6e07aad46 Mon Sep 17 00:00:00 2001
-From: Ralph Boehme <slow@samba.org>
-Date: Thu, 13 Jan 2022 16:48:01 +0100
-Subject: [PATCH 1/5] CVE-2021-44142: libadouble: add defines for icon lengths
-
-From https://www.ietf.org/rfc/rfc1740.txt
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14914
-
-Signed-off-by: Ralph Boehme <slow@samba.org>
----
- source3/lib/adouble.h | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/source3/lib/adouble.h b/source3/lib/adouble.h
-index 90a825c502e0..e3b9263a1f9a 100644
---- a/source3/lib/adouble.h
-+++ b/source3/lib/adouble.h
-@@ -101,6 +101,8 @@ typedef enum {ADOUBLE_META, ADOUBLE_RSRC} adouble_type_t;
- #define ADEDLEN_MACFILEI        4
- #define ADEDLEN_PRODOSFILEI     8
- #define ADEDLEN_MSDOSFILEI      2
-+#define ADEDLEN_ICONBW          128
-+#define ADEDLEN_ICONCOL         1024
- #define ADEDLEN_DID             4
- #define ADEDLEN_PRIVDEV         8
- #define ADEDLEN_PRIVINO         8
--- 
-2.34.1
-
-
-From fc20cb8268af1203a331ba142b630d4dfb613478 Mon Sep 17 00:00:00 2001
-From: Ralph Boehme <slow@samba.org>
-Date: Sat, 20 Nov 2021 16:36:42 +0100
-Subject: [PATCH 2/5] CVE-2021-44142: smbd: add Netatalk xattr used by
- vfs_fruit to the list of private Samba xattrs
-
-This is an internal xattr that should not be user visible.
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14914
-
-Signed-off-by: Ralph Boehme <slow@samba.org>
-[slow@samba.org: conflict due to changed includes in source3/smbd/trans2.c]
----
- source3/smbd/trans2.c | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
-index 70a492a96a8a..a200656b76cf 100644
---- a/source3/smbd/trans2.c
-+++ b/source3/smbd/trans2.c
-@@ -45,6 +45,7 @@
- #include "smb1_utils.h"
- #include "libcli/smb/smb2_posix.h"
- #include "lib/util/string_wrappers.h"
-+#include "source3/lib/adouble.h"
- 
- #define DIR_ENTRY_SAFETY_MARGIN 4096
- 
-@@ -218,6 +219,7 @@ bool samba_private_attr_name(const char *unix_ea_name)
- 		SAMBA_XATTR_DOS_ATTRIB,
- 		SAMBA_XATTR_MARKER,
- 		XATTR_NTACL_NAME,
-+		AFPINFO_EA_NETATALK,
- 		NULL
- 	};
- 
--- 
-2.34.1
-
-
-From 73302708170a71afce09ff42640ea4fceff4d08a Mon Sep 17 00:00:00 2001
-From: Ralph Boehme <slow@samba.org>
-Date: Fri, 26 Nov 2021 07:19:32 +0100
-Subject: [PATCH 3/5] CVE-2021-44142: libadouble: harden ad_unpack_xattrs()
-
-This ensures ad_unpack_xattrs() is only called for an ad_type of ADOUBLE_RSRC,
-which is used for parsing ._ AppleDouble sidecar files, and the buffer
-ad->ad_data is AD_XATTR_MAX_HDR_SIZE bytes large which is a prerequisite for all
-buffer out-of-bounds access checks in ad_unpack_xattrs().
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14914
-
-Signed-off-by: Ralph Boehme <slow@samba.org>
----
- source3/lib/adouble.c | 21 ++++++++++++++++++---
- 1 file changed, 18 insertions(+), 3 deletions(-)
-
-diff --git a/source3/lib/adouble.c b/source3/lib/adouble.c
-index 0ab9019cfb59..7875dd6f0df8 100644
---- a/source3/lib/adouble.c
-+++ b/source3/lib/adouble.c
-@@ -707,14 +707,27 @@ static bool ad_pack(struct vfs_handle_struct *handle,
- static bool ad_unpack_xattrs(struct adouble *ad)
- {
- 	struct ad_xattr_header *h = &ad->adx_header;
-+	size_t bufsize = talloc_get_size(ad->ad_data);
- 	const char *p = ad->ad_data;
- 	uint32_t hoff;
- 	uint32_t i;
- 
-+	if (ad->ad_type != ADOUBLE_RSRC) {
-+		return false;
-+	}
-+
- 	if (ad_getentrylen(ad, ADEID_FINDERI) <= ADEDLEN_FINDERI) {
- 		return true;
- 	}
- 
-+	/*
-+	 * Ensure the buffer ad->ad_data was allocated by ad_alloc() for an
-+	 * ADOUBLE_RSRC type (._ AppleDouble file on-disk).
-+	 */
-+	if (bufsize != AD_XATTR_MAX_HDR_SIZE) {
-+		return false;
-+	}
-+
- 	/* 2 bytes padding */
- 	hoff = ad_getentryoff(ad, ADEID_FINDERI) + ADEDLEN_FINDERI + 2;
- 
-@@ -964,9 +977,11 @@ static bool ad_unpack(struct adouble *ad, const size_t nentries,
- 		ad->ad_eid[eid].ade_len = len;
- 	}
- 
--	ok = ad_unpack_xattrs(ad);
--	if (!ok) {
--		return false;
-+	if (ad->ad_type == ADOUBLE_RSRC) {
-+		ok = ad_unpack_xattrs(ad);
-+		if (!ok) {
-+			return false;
-+		}
- 	}
- 
- 	return true;
--- 
-2.34.1
-
-
-From 0cfe02ac7ad197ea9fb4b19f296b73e5e7baf0af Mon Sep 17 00:00:00 2001
-From: Ralph Boehme <slow@samba.org>
-Date: Thu, 25 Nov 2021 15:04:03 +0100
-Subject: [PATCH 4/5] CVE-2021-44142: libadouble: add basic cmocka tests
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14914
-
-Signed-off-by: Ralph Boehme <slow@samba.org>
-[slow@samba.org: conflict due to missing test in selftest/tests.py]
----
- selftest/knownfail.d/samba.unittests.adouble |   3 +
- selftest/tests.py                            |   2 +
- source3/lib/test_adouble.c                   | 389 +++++++++++++++++++
- source3/wscript_build                        |   5 +
- 4 files changed, 399 insertions(+)
- create mode 100644 selftest/knownfail.d/samba.unittests.adouble
- create mode 100644 source3/lib/test_adouble.c
-
-diff --git a/selftest/knownfail.d/samba.unittests.adouble b/selftest/knownfail.d/samba.unittests.adouble
-new file mode 100644
-index 000000000000..8b0314f2faec
---- /dev/null
-+++ b/selftest/knownfail.d/samba.unittests.adouble
-@@ -0,0 +1,3 @@
-+^samba.unittests.adouble.parse_abouble_finderinfo2\(none\)
-+^samba.unittests.adouble.parse_abouble_finderinfo3\(none\)
-+^samba.unittests.adouble.parse_abouble_date2\(none\)
-diff --git a/selftest/tests.py b/selftest/tests.py
-index af1e46061852..f4a1056f1dc8 100644
---- a/selftest/tests.py
-+++ b/selftest/tests.py
-@@ -427,3 +427,5 @@ plantestsuite("samba.unittests.test_oLschema2ldif", "none",
-                   [os.path.join(bindir(), "default/source3/test_mdsparser_es")] + [configuration])
- plantestsuite("samba.unittests.credentials", "none",
-               [os.path.join(bindir(), "default/auth/credentials/test_creds")])
-+plantestsuite("samba.unittests.adouble", "none",
-+              [os.path.join(bindir(), "test_adouble")])
-diff --git a/source3/lib/test_adouble.c b/source3/lib/test_adouble.c
-new file mode 100644
-index 000000000000..615c22469c91
---- /dev/null
-+++ b/source3/lib/test_adouble.c
-@@ -0,0 +1,389 @@
-+/*
-+ * Unix SMB/CIFS implementation.
-+ *
-+ * Copyright (C) 2021 Ralph Boehme <slow@samba.org>
-+ *
-+ * 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 "adouble.c"
-+#include <cmocka.h>
-+
-+static int setup_talloc_context(void **state)
-+{
-+	TALLOC_CTX *frame = talloc_stackframe();
-+
-+	*state = frame;
-+	return 0;
-+}
-+
-+static int teardown_talloc_context(void **state)
-+{
-+	TALLOC_CTX *frame = *state;
-+
-+	TALLOC_FREE(frame);
-+	return 0;
-+}
-+
-+/*
-+ * Basic and sane buffer.
-+ */
-+static uint8_t ad_basic[] = {
-+	0x00, 0x05, 0x16, 0x07, /* Magic */
-+	0x00, 0x02, 0x00, 0x00, /* Version */
-+	0x00, 0x00, 0x00, 0x00, /* Filler */
-+	0x00, 0x00, 0x00, 0x00, /* Filler */
-+	0x00, 0x00, 0x00, 0x00, /* Filler */
-+	0x00, 0x00, 0x00, 0x00, /* Filler */
-+	0x00, 0x02,             /* Count */
-+	/* adentry 1: FinderInfo */
-+	0x00, 0x00, 0x00, 0x09,	/* eid: FinderInfo */
-+	0x00, 0x00, 0x00, 0x32,	/* offset */
-+	0x00, 0x00, 0x00, 0x20,	/* length */
-+	/* adentry 2: Resourcefork */
-+	0x00, 0x00, 0x00, 0x02,	/* eid: Resourcefork */
-+	0x00, 0x00, 0x00, 0x52,	/* offset */
-+	0xff, 0xff, 0xff, 0x00,	/* length */
-+	/* FinderInfo data: 32 bytes */
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+};
-+
-+/*
-+ * An empty FinderInfo entry.
-+ */
-+static uint8_t ad_finderinfo1[] = {
-+	0x00, 0x05, 0x16, 0x07, /* Magic */
-+	0x00, 0x02, 0x00, 0x00, /* Version */
-+	0x00, 0x00, 0x00, 0x00, /* Filler */
-+	0x00, 0x00, 0x00, 0x00, /* Filler */
-+	0x00, 0x00, 0x00, 0x00, /* Filler */
-+	0x00, 0x00, 0x00, 0x00, /* Filler */
-+	0x00, 0x02,             /* Count */
-+	/* adentry 1: FinderInfo */
-+	0x00, 0x00, 0x00, 0x09,	/* eid: FinderInfo */
-+	0x00, 0x00, 0x00, 0x52,	/* off: points at end of buffer */
-+	0x00, 0x00, 0x00, 0x00,	/* len: 0, so off+len don't exceed bufferlen */
-+	/* adentry 2: Resourcefork */
-+	0x00, 0x00, 0x00, 0x02,	/* eid: Resourcefork */
-+	0x00, 0x00, 0x00, 0x52,	/* offset */
-+	0xff, 0xff, 0xff, 0x00,	/* length */
-+	/* FinderInfo data: 32 bytes */
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+};
-+
-+/*
-+ * A dangerous FinderInfo with correct length exceeding buffer by one byte.
-+ */
-+static uint8_t ad_finderinfo2[] = {
-+	0x00, 0x05, 0x16, 0x07, /* Magic */
-+	0x00, 0x02, 0x00, 0x00, /* Version */
-+	0x00, 0x00, 0x00, 0x00, /* Filler */
-+	0x00, 0x00, 0x00, 0x00, /* Filler */
-+	0x00, 0x00, 0x00, 0x00, /* Filler */
-+	0x00, 0x00, 0x00, 0x00, /* Filler */
-+	0x00, 0x02,             /* Count */
-+	/* adentry 1: FinderInfo */
-+	0x00, 0x00, 0x00, 0x09,	/* eid: FinderInfo */
-+	0x00, 0x00, 0x00, 0x33,	/* off: points at beginng of data + 1 */
-+	0x00, 0x00, 0x00, 0x20,	/* len: 32, so off+len exceeds bufferlen by 1 */
-+	/* adentry 2: Resourcefork */
-+	0x00, 0x00, 0x00, 0x02,	/* eid: Resourcefork */
-+	0x00, 0x00, 0x00, 0x52,	/* offset */
-+	0xff, 0xff, 0xff, 0x00,	/* length */
-+	/* FinderInfo data: 32 bytes */
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+};
-+
-+static uint8_t ad_finderinfo3[] = {
-+	0x00, 0x05, 0x16, 0x07, /* Magic */
-+	0x00, 0x02, 0x00, 0x00, /* Version */
-+	0x00, 0x00, 0x00, 0x00, /* Filler */
-+	0x00, 0x00, 0x00, 0x00, /* Filler */
-+	0x00, 0x00, 0x00, 0x00, /* Filler */
-+	0x00, 0x00, 0x00, 0x00, /* Filler */
-+	0x00, 0x02,             /* Count */
-+	/* adentry 1: FinderInfo */
-+	0x00, 0x00, 0x00, 0x09,	/* eid: FinderInfo */
-+	0x00, 0x00, 0x00, 0x33,	/* off: points at beginng of data + 1 */
-+	0x00, 0x00, 0x00, 0x1f,	/* len: 31, so off+len don't exceed buf */
-+	/* adentry 2: Resourcefork */
-+	0x00, 0x00, 0x00, 0x02,	/* eid: Resourcefork */
-+	0x00, 0x00, 0x00, 0x52,	/* offset */
-+	0xff, 0xff, 0xff, 0x00,	/* length */
-+	/* FinderInfo data: 32 bytes */
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+};
-+
-+/*
-+ * A dangerous name entry.
-+ */
-+static uint8_t ad_name[] = {
-+	0x00, 0x05, 0x16, 0x07, /* Magic */
-+	0x00, 0x02, 0x00, 0x00, /* Version */
-+	0x00, 0x00, 0x00, 0x00, /* Filler */
-+	0x00, 0x00, 0x00, 0x00, /* Filler */
-+	0x00, 0x00, 0x00, 0x00, /* Filler */
-+	0x00, 0x00, 0x00, 0x00, /* Filler */
-+	0x00, 0x02,             /* Count */
-+	/* adentry 1: FinderInfo */
-+	0x00, 0x00, 0x00, 0x09,	/* eid: FinderInfo */
-+	0x00, 0x00, 0x00, 0x32,	/* offset */
-+	0x00, 0x00, 0x00, 0x20,	/* length */
-+	/* adentry 2: Name */
-+	0x00, 0x00, 0x00, 0x03,	/* eid: Name */
-+	0x00, 0x00, 0x00, 0x52,	/* off: points at end of buffer */
-+	0x00, 0x00, 0x00, 0x01,	/* len: 1, so off+len exceeds bufferlen */
-+	/* FinderInfo data: 32 bytes */
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+};
-+
-+/*
-+ * A empty ADEID_FILEDATESI entry.
-+ */
-+static uint8_t ad_date1[] = {
-+	0x00, 0x05, 0x16, 0x07, /* Magic */
-+	0x00, 0x02, 0x00, 0x00, /* Version */
-+	0x00, 0x00, 0x00, 0x00, /* Filler */
-+	0x00, 0x00, 0x00, 0x00, /* Filler */
-+	0x00, 0x00, 0x00, 0x00, /* Filler */
-+	0x00, 0x00, 0x00, 0x00, /* Filler */
-+	0x00, 0x02,             /* Count */
-+	/* adentry 1: FinderInfo */
-+	0x00, 0x00, 0x00, 0x09,	/* eid: FinderInfo */
-+	0x00, 0x00, 0x00, 0x32,	/* offset */
-+	0x00, 0x00, 0x00, 0x20,	/* length */
-+	/* adentry 2: Dates */
-+	0x00, 0x00, 0x00, 0x08,	/* eid: dates */
-+	0x00, 0x00, 0x00, 0x52,	/* off: end of buffer */
-+	0x00, 0x00, 0x00, 0x00,	/* len: 0, empty entry, valid */
-+	/* FinderInfo data: 32 bytes */
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+};
-+
-+/*
-+ * A dangerous ADEID_FILEDATESI entry, invalid length.
-+ */
-+static uint8_t ad_date2[] = {
-+	0x00, 0x05, 0x16, 0x07, /* Magic */
-+	0x00, 0x02, 0x00, 0x00, /* Version */
-+	0x00, 0x00, 0x00, 0x00, /* Filler */
-+	0x00, 0x00, 0x00, 0x00, /* Filler */
-+	0x00, 0x00, 0x00, 0x00, /* Filler */
-+	0x00, 0x00, 0x00, 0x00, /* Filler */
-+	0x00, 0x02,             /* Count */
-+	/* adentry 1: FinderInfo */
-+	0x00, 0x00, 0x00, 0x09,	/* eid: FinderInfo */
-+	0x00, 0x00, 0x00, 0x32,	/* offset */
-+	0x00, 0x00, 0x00, 0x20,	/* length */
-+	/* adentry 2: Dates */
-+	0x00, 0x00, 0x00, 0x08,	/* eid: dates */
-+	0x00, 0x00, 0x00, 0x43,	/* off: FinderInfo buf but one byte short */
-+	0x00, 0x00, 0x00, 0x0f,	/* len: 15, so off+len don't exceed bufferlen */
-+	/* FinderInfo data: 32 bytes */
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+	0x00, 0x00, 0x00, 0x00,
-+};
-+
-+static struct adouble *parse_adouble(TALLOC_CTX *mem_ctx,
-+				     uint8_t *adbuf,
-+				     size_t adsize,
-+				     off_t filesize)
-+{
-+	struct adouble *ad = NULL;
-+	bool ok;
-+
-+	ad = talloc_zero(mem_ctx, struct adouble);
-+	ad->ad_data = talloc_zero_size(ad, adsize);
-+	assert_non_null(ad);
-+
-+	memcpy(ad->ad_data, adbuf, adsize);
-+
-+	ok = ad_unpack(ad, 2, filesize);
-+	if (!ok) {
-+		return NULL;
-+	}
-+
-+	return ad;
-+}
-+
-+static void parse_abouble_basic(void **state)
-+{
-+	TALLOC_CTX *frame = *state;
-+	struct adouble *ad = NULL;
-+	char *p = NULL;
-+
-+	ad = parse_adouble(frame, ad_basic, sizeof(ad_basic), 0xffffff52);
-+	assert_non_null(ad);
-+
-+	p = ad_get_entry(ad, ADEID_FINDERI);
-+	assert_non_null(p);
-+
-+	return;
-+}
-+
-+static void parse_abouble_finderinfo1(void **state)
-+{
-+	TALLOC_CTX *frame = *state;
-+	struct adouble *ad = NULL;
-+	char *p = NULL;
-+
-+	ad = parse_adouble(frame,
-+			   ad_finderinfo1,
-+			   sizeof(ad_finderinfo1),
-+			   0xffffff52);
-+	assert_non_null(ad);
-+
-+	p = ad_get_entry(ad, ADEID_FINDERI);
-+	assert_null(p);
-+
-+	return;
-+}
-+
-+static void parse_abouble_finderinfo2(void **state)
-+{
-+	TALLOC_CTX *frame = *state;
-+	struct adouble *ad = NULL;
-+
-+	ad = parse_adouble(frame,
-+			   ad_finderinfo2,
-+			   sizeof(ad_finderinfo2),
-+			   0xffffff52);
-+	assert_null(ad);
-+
-+	return;
-+}
-+
-+static void parse_abouble_finderinfo3(void **state)
-+{
-+	TALLOC_CTX *frame = *state;
-+	struct adouble *ad = NULL;
-+
-+	ad = parse_adouble(frame,
-+			   ad_finderinfo3,
-+			   sizeof(ad_finderinfo3),
-+			   0xffffff52);
-+	assert_null(ad);
-+
-+	return;
-+}
-+
-+static void parse_abouble_name(void **state)
-+{
-+	TALLOC_CTX *frame = *state;
-+	struct adouble *ad = NULL;
-+
-+	ad = parse_adouble(frame, ad_name, sizeof(ad_name), 0x52);
-+	assert_null(ad);
-+
-+	return;
-+}
-+
-+static void parse_abouble_date1(void **state)
-+{
-+	TALLOC_CTX *frame = *state;
-+	struct adouble *ad = NULL;
-+	char *p = NULL;
-+
-+	ad = parse_adouble(frame, ad_date1, sizeof(ad_date1), 0x52);
-+	assert_non_null(ad);
-+
-+	p = ad_get_entry(ad, ADEID_FILEDATESI);
-+	assert_null(p);
-+
-+	return;
-+}
-+
-+static void parse_abouble_date2(void **state)
-+{
-+	TALLOC_CTX *frame = *state;
-+	struct adouble *ad = NULL;
-+
-+	ad = parse_adouble(frame, ad_date2, sizeof(ad_date2), 0x52);
-+	assert_null(ad);
-+
-+	return;
-+}
-+
-+int main(int argc, char *argv[])
-+{
-+	int rc;
-+	const struct CMUnitTest tests[] = {
-+		cmocka_unit_test(parse_abouble_basic),
-+		cmocka_unit_test(parse_abouble_finderinfo1),
-+		cmocka_unit_test(parse_abouble_finderinfo2),
-+		cmocka_unit_test(parse_abouble_finderinfo3),
-+		cmocka_unit_test(parse_abouble_name),
-+		cmocka_unit_test(parse_abouble_date1),
-+		cmocka_unit_test(parse_abouble_date2),
-+	};
-+
-+	if (argc == 2) {
-+		cmocka_set_test_filter(argv[1]);
-+	}
-+	cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
-+
-+	rc = cmocka_run_group_tests(tests,
-+				    setup_talloc_context,
-+				    teardown_talloc_context);
-+
-+	return rc;
-+}
-diff --git a/source3/wscript_build b/source3/wscript_build
-index a143477a5064..95e589cfc734 100644
---- a/source3/wscript_build
-+++ b/source3/wscript_build
-@@ -1088,6 +1088,11 @@ bld.SAMBA3_SUBSYSTEM('ADOUBLE',
-                     source='lib/adouble.c',
-                     deps='STRING_REPLACE')
- 
-+bld.SAMBA3_BINARY('test_adouble',
-+                 source='lib/test_adouble.c',
-+                 deps='smbd_base STRING_REPLACE cmocka',
-+                 for_selftest=True)
-+
- bld.SAMBA3_SUBSYSTEM('STRING_REPLACE',
-                     source='lib/string_replace.c')
- 
--- 
-2.34.1
-
-
-From 793ca8c474a74f82745a266f4a4bf9e20443ad53 Mon Sep 17 00:00:00 2001
-From: Ralph Boehme <slow@samba.org>
-Date: Thu, 13 Jan 2022 17:03:02 +0100
-Subject: [PATCH 5/5] CVE-2021-44142: libadouble: harden parsing code
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14914
-
-Signed-off-by: Ralph Boehme <slow@samba.org>
----
- selftest/knownfail.d/samba.unittests.adouble |   3 -
- source3/lib/adouble.c                        | 115 ++++++++++++++++---
- 2 files changed, 101 insertions(+), 17 deletions(-)
- delete mode 100644 selftest/knownfail.d/samba.unittests.adouble
-
-diff --git a/selftest/knownfail.d/samba.unittests.adouble b/selftest/knownfail.d/samba.unittests.adouble
-deleted file mode 100644
-index 8b0314f2faec..000000000000
---- a/selftest/knownfail.d/samba.unittests.adouble
-+++ /dev/null
-@@ -1,3 +0,0 @@
--^samba.unittests.adouble.parse_abouble_finderinfo2\(none\)
--^samba.unittests.adouble.parse_abouble_finderinfo3\(none\)
--^samba.unittests.adouble.parse_abouble_date2\(none\)
-diff --git a/source3/lib/adouble.c b/source3/lib/adouble.c
-index 7875dd6f0df8..48cc0007c23c 100644
---- a/source3/lib/adouble.c
-+++ b/source3/lib/adouble.c
-@@ -269,6 +269,95 @@ size_t ad_setentryoff(struct adouble *ad, int eid, size_t off)
- 	return ad->ad_eid[eid].ade_off = off;
- }
- 
-+/*
-+ * All entries besides FinderInfo and resource fork must fit into the
-+ * buffer. FinderInfo is special as it may be larger then the default 32 bytes
-+ * if it contains marshalled xattrs, which we will fixup that in
-+ * ad_convert(). The first 32 bytes however must also be part of the buffer.
-+ *
-+ * The resource fork is never accessed directly by the ad_data buf.
-+ */
-+static bool ad_entry_check_size(uint32_t eid,
-+				size_t bufsize,
-+				uint32_t off,
-+				uint32_t got_len)
-+{
-+	struct {
-+		off_t expected_len;
-+		bool fixed_size;
-+		bool minimum_size;
-+	} ad_checks[] = {
-+		[ADEID_DFORK] = {-1, false, false}, /* not applicable */
-+		[ADEID_RFORK] = {-1, false, false}, /* no limit */
-+		[ADEID_NAME] = {ADEDLEN_NAME, false, false},
-+		[ADEID_COMMENT] = {ADEDLEN_COMMENT, false, false},
-+		[ADEID_ICONBW] = {ADEDLEN_ICONBW, true, false},
-+		[ADEID_ICONCOL] = {ADEDLEN_ICONCOL, false, false},
-+		[ADEID_FILEI] = {ADEDLEN_FILEI, true, false},
-+		[ADEID_FILEDATESI] = {ADEDLEN_FILEDATESI, true, false},
-+		[ADEID_FINDERI] = {ADEDLEN_FINDERI, false, true},
-+		[ADEID_MACFILEI] = {ADEDLEN_MACFILEI, true, false},
-+		[ADEID_PRODOSFILEI] = {ADEDLEN_PRODOSFILEI, true, false},
-+		[ADEID_MSDOSFILEI] = {ADEDLEN_MSDOSFILEI, true, false},
-+		[ADEID_SHORTNAME] = {ADEDLEN_SHORTNAME, false, false},
-+		[ADEID_AFPFILEI] = {ADEDLEN_AFPFILEI, true, false},
-+		[ADEID_DID] = {ADEDLEN_DID, true, false},
-+		[ADEID_PRIVDEV] = {ADEDLEN_PRIVDEV, true, false},
-+		[ADEID_PRIVINO] = {ADEDLEN_PRIVINO, true, false},
-+		[ADEID_PRIVSYN] = {ADEDLEN_PRIVSYN, true, false},
-+		[ADEID_PRIVID] = {ADEDLEN_PRIVID, true, false},
-+	};
-+
-+	if (eid >= ADEID_MAX) {
-+		return false;
-+	}
-+	if (got_len == 0) {
-+		/* Entry present, but empty, allow */
-+		return true;
-+	}
-+	if (ad_checks[eid].expected_len == 0) {
-+		/*
-+		 * Shouldn't happen: implicitly initialized to zero because
-+		 * explicit initializer missing.
-+		 */
-+		return false;
-+	}
-+	if (ad_checks[eid].expected_len == -1) {
-+		/* Unused or no limit */
-+		return true;
-+	}
-+	if (ad_checks[eid].fixed_size) {
-+		if (ad_checks[eid].expected_len != got_len) {
-+			/* Wrong size fo fixed size entry. */
-+			return false;
-+		}
-+	} else {
-+		if (ad_checks[eid].minimum_size) {
-+			if (got_len < ad_checks[eid].expected_len) {
-+				/*
-+				 * Too small for variable sized entry with
-+				 * minimum size.
-+				 */
-+				return false;
-+			}
-+		} else {
-+			if (got_len > ad_checks[eid].expected_len) {
-+				/* Too big for variable sized entry. */
-+				return false;
-+			}
-+		}
-+	}
-+	if (off + got_len < off) {
-+		/* wrap around */
-+		return false;
-+	}
-+	if (off + got_len > bufsize) {
-+		/* overflow */
-+		return false;
-+	}
-+	return true;
-+}
-+
- /**
-  * Return a pointer to an AppleDouble entry
-  *
-@@ -276,8 +365,15 @@ size_t ad_setentryoff(struct adouble *ad, int eid, size_t off)
-  **/
- char *ad_get_entry(const struct adouble *ad, int eid)
- {
-+	size_t bufsize = talloc_get_size(ad->ad_data);
- 	off_t off = ad_getentryoff(ad, eid);
- 	size_t len = ad_getentrylen(ad, eid);
-+	bool valid;
-+
-+	valid = ad_entry_check_size(eid, bufsize, off, len);
-+	if (!valid) {
-+		return NULL;
-+	}
- 
- 	if (off == 0 || len == 0) {
- 		return NULL;
-@@ -914,20 +1010,11 @@ static bool ad_unpack(struct adouble *ad, const size_t nentries,
- 			return false;
- 		}
- 
--		/*
--		 * All entries besides FinderInfo and resource fork
--		 * must fit into the buffer. FinderInfo is special as
--		 * it may be larger then the default 32 bytes (if it
--		 * contains marshalled xattrs), but we will fixup that
--		 * in ad_convert(). And the resource fork is never
--		 * accessed directly by the ad_data buf (also see
--		 * comment above) anyway.
--		 */
--		if ((eid != ADEID_RFORK) &&
--		    (eid != ADEID_FINDERI) &&
--		    ((off + len) > bufsize)) {
--			DEBUG(1, ("bogus eid %d: off: %" PRIu32 ", len: %" PRIu32 "\n",
--				  eid, off, len));
-+		ok = ad_entry_check_size(eid, bufsize, off, len);
-+		if (!ok) {
-+			DBG_ERR("bogus eid [%"PRIu32"] bufsize [%zu] "
-+				"off [%"PRIu32"] len [%"PRIu32"]\n",
-+				eid, bufsize, off, len);
- 			return false;
- 		}
- 
--- 
-2.34.1
-
diff --git a/SOURCES/samba-4-15-fix-autorid.patch b/SOURCES/samba-4-15-fix-autorid.patch
new file mode 100644
index 0000000..f63464c
--- /dev/null
+++ b/SOURCES/samba-4-15-fix-autorid.patch
@@ -0,0 +1,231 @@
+From 89f7b7790dd7f3a300718de2d811104dc0637bbd Mon Sep 17 00:00:00 2001
+From: Andreas Schneider <asn@samba.org>
+Date: Tue, 1 Feb 2022 10:06:30 +0100
+Subject: [PATCH 1/3] s3:winbindd: Add a sanity check for the range
+
+What we want to avoid:
+
+$ ./bin/testparm -s | grep "idmap config"
+        idmap config * : rangesize = 10000
+        idmap config * : range = 10000-19999
+        idmap config * : backend = autorid
+
+$ ./bin/wbinfo --name-to-sid BUILTIN/Administrators
+S-1-5-32-544 SID_ALIAS (4)
+
+$ ./bin/wbinfo --sid-to-gid S-1-5-32-544
+10000
+
+$ ./bin/wbinfo --name-to-sid ADDOMAIN/alice
+S-1-5-21-4058748110-895691256-3682847423-1107 SID_USER (1)
+
+$ ./bin/wbinfo --sid-to-gid S-1-5-21-984165912-589366285-3903095728-1107
+failed to call wbcSidToGid: WBC_ERR_DOMAIN_NOT_FOUND
+Could not convert sid S-1-5-21-984165912-589366285-3903095728-1107 to gid
+
+If only one range is configured we are either not able to map users/groups
+from our primary *and* the BUILTIN domain. We need at least two ranges to also
+cover the BUILTIN domain!
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=14967
+
+Signed-off-by: Andreas Schneider <asn@samba.org>
+Reviewed-by: Guenther Deschner <gd@samba.org>
+(cherry picked from commit fe84ae5547313e482ea0eba8ddca5b38a033dc8f)
+---
+ source3/winbindd/idmap_autorid.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/source3/winbindd/idmap_autorid.c b/source3/winbindd/idmap_autorid.c
+index ad53b5810ee..c7d56a37684 100644
+--- a/source3/winbindd/idmap_autorid.c
++++ b/source3/winbindd/idmap_autorid.c
+@@ -856,9 +856,10 @@ static NTSTATUS idmap_autorid_initialize(struct idmap_domain *dom)
+ 	config->maxranges = (dom->high_id - dom->low_id + 1) /
+ 	    config->rangesize;
+ 
+-	if (config->maxranges == 0) {
+-		DEBUG(1, ("Allowed uid range is smaller than rangesize. "
+-			  "Increase uid range or decrease rangesize.\n"));
++	if (config->maxranges < 2) {
++		DBG_WARNING("Allowed idmap range is not a least double the "
++			    "size of the rangesize. Please increase idmap "
++			    "range.\n");
+ 		status = NT_STATUS_INVALID_PARAMETER;
+ 		goto error;
+ 	}
+-- 
+2.35.1
+
+
+From 70a0069038948a22b1e7dfd8917a3487206ec770 Mon Sep 17 00:00:00 2001
+From: Andreas Schneider <asn@samba.org>
+Date: Tue, 1 Feb 2022 10:07:50 +0100
+Subject: [PATCH 2/3] s3:utils: Add a testparm check for idmap autorid
+
+What we want to avoid:
+
+$ ./bin/testparm -s | grep "idmap config"
+        idmap config * : rangesize = 10000
+        idmap config * : range = 10000-19999
+        idmap config * : backend = autorid
+
+$ ./bin/wbinfo --name-to-sid BUILTIN/Administrators
+S-1-5-32-544 SID_ALIAS (4)
+
+$ ./bin/wbinfo --sid-to-gid S-1-5-32-544
+10000
+
+$ ./bin/wbinfo --name-to-sid ADDOMAIN/alice
+S-1-5-21-4058748110-895691256-3682847423-1107 SID_USER (1)
+
+$ ./bin/wbinfo --sid-to-gid S-1-5-21-984165912-589366285-3903095728-1107
+failed to call wbcSidToGid: WBC_ERR_DOMAIN_NOT_FOUND
+Could not convert sid S-1-5-21-984165912-589366285-3903095728-1107 to gid
+
+If only one range is configured we are either not able to map users/groups
+from our primary *and* the BUILTIN domain. We need at least two ranges to also
+cover the BUILTIN domain!
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=14967
+
+Signed-off-by: Andreas Schneider <asn@samba.org>
+Reviewed-by: Guenther Deschner <gd@samba.org>
+(cherry picked from commit db6d4da3411a910e7ce45fe1fecfabf2864eb9f4)
+---
+ source3/utils/testparm.c | 51 ++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 51 insertions(+)
+
+diff --git a/source3/utils/testparm.c b/source3/utils/testparm.c
+index 98bcc219b1e..58ba46bc15f 100644
+--- a/source3/utils/testparm.c
++++ b/source3/utils/testparm.c
+@@ -128,6 +128,21 @@ static bool lp_scan_idmap_found_domain(const char *string,
+ 	return false; /* Keep scanning */
+ }
+ 
++static int idmap_config_int(const char *domname, const char *option, int def)
++{
++	int len = snprintf(NULL, 0, "idmap config %s", domname);
++
++	if (len == -1) {
++		return def;
++	}
++	{
++		char config_option[len+1];
++		snprintf(config_option, sizeof(config_option),
++			 "idmap config %s", domname);
++		return lp_parm_int(-1, config_option, option, def);
++	}
++}
++
+ static bool do_idmap_check(void)
+ {
+ 	struct idmap_domains *d;
+@@ -157,6 +172,42 @@ static bool do_idmap_check(void)
+ 			rc);
+ 	}
+ 
++	/* Check autorid backend */
++	if (strequal(lp_idmap_default_backend(), "autorid")) {
++		struct idmap_config *c = NULL;
++		bool found = false;
++
++		for (i = 0; i < d->count; i++) {
++			c = &d->c[i];
++
++			if (strequal(c->backend, "autorid")) {
++				found = true;
++				break;
++			}
++		}
++
++		if (found) {
++			uint32_t rangesize =
++				idmap_config_int("*", "rangesize", 100000);
++			uint32_t maxranges =
++				(c->high - c->low  + 1) / rangesize;
++
++			if (maxranges < 2) {
++				fprintf(stderr,
++					"ERROR: The idmap autorid range "
++					"[%u-%u] needs to be at least twice as "
++					"big as the rangesize [%u]!"
++					"\n\n",
++					c->low,
++					c->high,
++					rangesize);
++				ok = false;
++				goto done;
++			}
++		}
++	}
++
++	/* Check for overlapping idmap ranges */
+ 	for (i = 0; i < d->count; i++) {
+ 		struct idmap_config *c = &d->c[i];
+ 		uint32_t j;
+-- 
+2.35.1
+
+
+From 9cc90a306bc31ca9fb0b82556ae28c173b77724e Mon Sep 17 00:00:00 2001
+From: Andreas Schneider <asn@samba.org>
+Date: Tue, 1 Feb 2022 10:05:19 +0100
+Subject: [PATCH 3/3] docs-xml: Fix idmap_autorid documentation
+
+What we want to avoid:
+
+$ ./bin/testparm -s | grep "idmap config"
+        idmap config * : rangesize = 10000
+        idmap config * : range = 10000-19999
+        idmap config * : backend = autorid
+
+$ ./bin/wbinfo --name-to-sid BUILTIN/Administrators
+S-1-5-32-544 SID_ALIAS (4)
+
+$ ./bin/wbinfo --sid-to-gid S-1-5-32-544
+10000
+
+$ ./bin/wbinfo --name-to-sid ADDOMAIN/alice
+S-1-5-21-4058748110-895691256-3682847423-1107 SID_USER (1)
+
+$ ./bin/wbinfo --sid-to-gid S-1-5-21-984165912-589366285-3903095728-1107
+failed to call wbcSidToGid: WBC_ERR_DOMAIN_NOT_FOUND
+Could not convert sid S-1-5-21-984165912-589366285-3903095728-1107 to gid
+
+If only one range is configured we are either not able to map users/groups
+from our primary *and* the BUILTIN domain. We need at least two ranges to also
+cover the BUILTIN domain!
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=14967
+
+Signed-off-by: Andreas Schneider <asn@samba.org>
+Reviewed-by: Guenther Deschner <gd@samba.org>
+(cherry picked from commit 7e5afd8f1f7e5cfab1a8ef7f4293ac465b7cd8de)
+---
+ docs-xml/manpages/idmap_autorid.8.xml | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/docs-xml/manpages/idmap_autorid.8.xml b/docs-xml/manpages/idmap_autorid.8.xml
+index 6c4da1cad8a..980718f0bd4 100644
+--- a/docs-xml/manpages/idmap_autorid.8.xml
++++ b/docs-xml/manpages/idmap_autorid.8.xml
+@@ -48,7 +48,13 @@
+ 			and the corresponding map is discarded.  It is
+ 			intended as a way to avoid accidental UID/GID
+ 			overlaps between local and remotely defined
+-			IDs.
++			IDs. Note that the range should be a multiple
++			of the rangesize and needs to be at least twice
++			as large in order to have sufficient id range
++			space for the mandatory BUILTIN domain.
++			With a default rangesize of 100000 the range
++			needs to span at least 200000.
++			This would be: range = 100000 - 299999.
+ 		</para></listitem>
+ 		</varlistentry>
+ 
+-- 
+2.35.1
+
diff --git a/SOURCES/samba-4-15-fix-create-local-krb5-conf.patch b/SOURCES/samba-4-15-fix-create-local-krb5-conf.patch
new file mode 100644
index 0000000..2d7ad44
--- /dev/null
+++ b/SOURCES/samba-4-15-fix-create-local-krb5-conf.patch
@@ -0,0 +1,477 @@
+From 73368f962136398d79c22e7df6fe4f6d7ce3932f Mon Sep 17 00:00:00 2001
+From: Andreas Schneider <asn@samba.org>
+Date: Tue, 15 Mar 2022 16:53:02 +0100
+Subject: [PATCH 1/9] testprogs: Add test that local krb5.conf has been created
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=15016
+
+Signed-off-by: Andreas Schneider <asn@samba.org>
+---
+ testprogs/blackbox/test_net_ads.sh | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/testprogs/blackbox/test_net_ads.sh b/testprogs/blackbox/test_net_ads.sh
+index 76b394b10a9..cfafb945b62 100755
+--- a/testprogs/blackbox/test_net_ads.sh
++++ b/testprogs/blackbox/test_net_ads.sh
+@@ -51,6 +51,12 @@ fi
+ 
+ testit "join" $VALGRIND $net_tool ads join -U$DC_USERNAME%$DC_PASSWORD || failed=`expr $failed + 1`
+ 
++workgroup=$(awk '/workgroup =/ { print $NR }' "${BASEDIR}/${WORKDIR}/client.conf")
++testit "local krb5.conf created" \
++	test -r \
++	"${BASEDIR}/${WORKDIR}/lockdir/smb_krb5/krb5.conf.${workgroup}" ||
++	failed=$((failed + 1))
++
+ testit "testjoin" $VALGRIND $net_tool ads testjoin -P --use-kerberos=required || failed=`expr $failed + 1`
+ 
+ netbios=$(grep "netbios name" $BASEDIR/$WORKDIR/client.conf | cut -f2 -d= | awk '{$1=$1};1')
+-- 
+2.35.1
+
+
+From d50e4298d6d713128cc3a7687cb7d5c8f4c213e4 Mon Sep 17 00:00:00 2001
+From: Andreas Schneider <asn@samba.org>
+Date: Tue, 15 Mar 2022 12:03:40 +0100
+Subject: [PATCH 2/9] s3:libads: Remove trailing spaces in kerberos.c
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=15016
+
+Signed-off-by: Andreas Schneider <asn@samba.org>
+---
+ source3/libads/kerberos.c | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c
+index 75beeef4a44..60fe03fd5d7 100644
+--- a/source3/libads/kerberos.c
++++ b/source3/libads/kerberos.c
+@@ -1,4 +1,4 @@
+-/* 
++/*
+    Unix SMB/CIFS implementation.
+    kerberos utility library
+    Copyright (C) Andrew Tridgell 2001
+@@ -37,11 +37,11 @@
+ #define LIBADS_CCACHE_NAME "MEMORY:libads"
+ 
+ /*
+-  we use a prompter to avoid a crash bug in the kerberos libs when 
++  we use a prompter to avoid a crash bug in the kerberos libs when
+   dealing with empty passwords
+   this prompter is just a string copy ...
+ */
+-static krb5_error_code 
++static krb5_error_code
+ kerb_prompter(krb5_context ctx, void *data,
+ 	       const char *name,
+ 	       const char *banner,
+@@ -192,7 +192,7 @@ int kerberos_kinit_password_ext(const char *given_principal,
+ 		krb5_get_init_creds_opt_set_address_list(opt, addr->addrs);
+ 	}
+ 
+-	if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, discard_const_p(char,password), 
++	if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, discard_const_p(char,password),
+ 						 kerb_prompter, discard_const_p(char, password),
+ 						 0, NULL, opt))) {
+ 		goto out;
+@@ -299,7 +299,7 @@ int ads_kdestroy(const char *cc_name)
+ 	}
+ 
+ 	if ((code = krb5_cc_destroy (ctx, cc))) {
+-		DEBUG(3, ("ads_kdestroy: krb5_cc_destroy failed: %s\n", 
++		DEBUG(3, ("ads_kdestroy: krb5_cc_destroy failed: %s\n",
+ 			error_message(code)));
+ 	}
+ 
+@@ -348,10 +348,10 @@ int kerberos_kinit_password(const char *principal,
+ 			    int time_offset,
+ 			    const char *cache_name)
+ {
+-	return kerberos_kinit_password_ext(principal, 
+-					   password, 
+-					   time_offset, 
+-					   0, 
++	return kerberos_kinit_password_ext(principal,
++					   password,
++					   time_offset,
++					   0,
+ 					   0,
+ 					   cache_name,
+ 					   False,
+-- 
+2.35.1
+
+
+From 85f140daa2779dec38255a997ec77540365959ca Mon Sep 17 00:00:00 2001
+From: Andreas Schneider <asn@samba.org>
+Date: Tue, 15 Mar 2022 12:04:34 +0100
+Subject: [PATCH 3/9] s3:libads: Leave early on error in get_kdc_ip_string()
+
+This avoids useless allocations.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=15016
+
+Signed-off-by: Andreas Schneider <asn@samba.org>
+---
+ source3/libads/kerberos.c | 17 +++++++++++------
+ 1 file changed, 11 insertions(+), 6 deletions(-)
+
+diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c
+index 60fe03fd5d7..1bf149ef09b 100644
+--- a/source3/libads/kerberos.c
++++ b/source3/libads/kerberos.c
+@@ -434,9 +434,14 @@ static char *get_kdc_ip_string(char *mem_ctx,
+ 	struct netlogon_samlogon_response **responses = NULL;
+ 	NTSTATUS status;
+ 	bool ok;
+-	char *kdc_str = talloc_asprintf(mem_ctx, "%s\t\tkdc = %s\n", "",
+-					print_canonical_sockaddr_with_port(mem_ctx, pss));
++	char *kdc_str = NULL;
+ 
++	SMB_ASSERT(pss != NULL);
++
++	kdc_str = talloc_asprintf(mem_ctx,
++				  "\t\tkdc = %s\n",
++				  print_canonical_sockaddr_with_port(mem_ctx,
++								     pss));
+ 	if (kdc_str == NULL) {
+ 		TALLOC_FREE(frame);
+ 		return NULL;
+@@ -516,15 +521,15 @@ static char *get_kdc_ip_string(char *mem_ctx,
+ 		}
+ 	}
+ 
+-	dc_addrs2 = talloc_zero_array(talloc_tos(),
+-				      struct tsocket_address *,
+-				      num_dcs);
+-
+ 	DBG_DEBUG("%zu additional KDCs to test\n", num_dcs);
+ 	if (num_dcs == 0) {
+ 		TALLOC_FREE(kdc_str);
+ 		goto out;
+ 	}
++
++	dc_addrs2 = talloc_zero_array(talloc_tos(),
++				      struct tsocket_address *,
++				      num_dcs);
+ 	if (dc_addrs2 == NULL) {
+ 		TALLOC_FREE(kdc_str);
+ 		goto out;
+-- 
+2.35.1
+
+
+From 010cb49995f00b6bb5058b8b1a69e684c0bb1050 Mon Sep 17 00:00:00 2001
+From: Andreas Schneider <asn@samba.org>
+Date: Tue, 15 Mar 2022 12:10:47 +0100
+Subject: [PATCH 4/9] s3:libads: Improve debug messages for get_kdc_ip_string()
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=15016
+
+Signed-off-by: Andreas Schneider <asn@samba.org>
+---
+ source3/libads/kerberos.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c
+index 1bf149ef09b..6a46d72a156 100644
+--- a/source3/libads/kerberos.c
++++ b/source3/libads/kerberos.c
+@@ -590,7 +590,11 @@ static char *get_kdc_ip_string(char *mem_ctx,
+ 
+ 	result = kdc_str;
+ out:
+-	DBG_DEBUG("Returning\n%s\n", kdc_str);
++	if (result != NULL) {
++		DBG_DEBUG("Returning\n%s\n", kdc_str);
++	} else {
++		DBG_NOTICE("Failed to get KDC ip address\n");
++	}
+ 
+ 	TALLOC_FREE(ip_sa_site);
+ 	TALLOC_FREE(ip_sa_nonsite);
+-- 
+2.35.1
+
+
+From c0640d8ea59ef57a1d61151f790431bcf7fddeba Mon Sep 17 00:00:00 2001
+From: Andreas Schneider <asn@samba.org>
+Date: Tue, 15 Mar 2022 12:48:23 +0100
+Subject: [PATCH 5/9] s3:libads: Use talloc_asprintf_append() in
+ get_kdc_ip_string()
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=15016
+
+Signed-off-by: Andreas Schneider <asn@samba.org>
+---
+ source3/libads/kerberos.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c
+index 6a46d72a156..d1c410ffa4b 100644
+--- a/source3/libads/kerberos.c
++++ b/source3/libads/kerberos.c
+@@ -578,10 +578,11 @@ static char *get_kdc_ip_string(char *mem_ctx,
+ 		}
+ 
+ 		/* Append to the string - inefficient but not done often. */
+-		new_kdc_str = talloc_asprintf(mem_ctx, "%s\t\tkdc = %s\n",
+-					      kdc_str,
+-					      print_canonical_sockaddr_with_port(mem_ctx, &dc_addrs[i]));
+-		TALLOC_FREE(kdc_str);
++		new_kdc_str = talloc_asprintf_append(
++				kdc_str,
++				"\t\tkdc = %s\n",
++				print_canonical_sockaddr_with_port(
++					mem_ctx, &dc_addrs[i]));
+ 		if (new_kdc_str == NULL) {
+ 			goto out;
+ 		}
+-- 
+2.35.1
+
+
+From b8e73356ff44f0717ed413a4e8af51f043434a7f Mon Sep 17 00:00:00 2001
+From: Andreas Schneider <asn@samba.org>
+Date: Tue, 15 Mar 2022 12:56:58 +0100
+Subject: [PATCH 6/9] s3:libads: Allocate all memory on the talloc stackframe
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=15016
+
+Signed-off-by: Andreas Schneider <asn@samba.org>
+---
+ source3/libads/kerberos.c | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c
+index d1c410ffa4b..aadc65a3edc 100644
+--- a/source3/libads/kerberos.c
++++ b/source3/libads/kerberos.c
+@@ -438,7 +438,7 @@ static char *get_kdc_ip_string(char *mem_ctx,
+ 
+ 	SMB_ASSERT(pss != NULL);
+ 
+-	kdc_str = talloc_asprintf(mem_ctx,
++	kdc_str = talloc_asprintf(frame,
+ 				  "\t\tkdc = %s\n",
+ 				  print_canonical_sockaddr_with_port(mem_ctx,
+ 								     pss));
+@@ -459,7 +459,7 @@ static char *get_kdc_ip_string(char *mem_ctx,
+ 	 */
+ 
+ 	if (sitename) {
+-		status = get_kdc_list(talloc_tos(),
++		status = get_kdc_list(frame,
+ 					realm,
+ 					sitename,
+ 					&ip_sa_site,
+@@ -477,7 +477,7 @@ static char *get_kdc_ip_string(char *mem_ctx,
+ 
+ 	/* Get all KDC's. */
+ 
+-	status = get_kdc_list(talloc_tos(),
++	status = get_kdc_list(frame,
+ 					realm,
+ 					NULL,
+ 					&ip_sa_nonsite,
+@@ -589,7 +589,7 @@ static char *get_kdc_ip_string(char *mem_ctx,
+ 		kdc_str = new_kdc_str;
+ 	}
+ 
+-	result = kdc_str;
++	result = talloc_move(mem_ctx, &kdc_str);
+ out:
+ 	if (result != NULL) {
+ 		DBG_DEBUG("Returning\n%s\n", kdc_str);
+@@ -597,8 +597,6 @@ out:
+ 		DBG_NOTICE("Failed to get KDC ip address\n");
+ 	}
+ 
+-	TALLOC_FREE(ip_sa_site);
+-	TALLOC_FREE(ip_sa_nonsite);
+ 	TALLOC_FREE(frame);
+ 	return result;
+ }
+-- 
+2.35.1
+
+
+From e2ea1de6128195af937474b41a57756013c8249e Mon Sep 17 00:00:00 2001
+From: Andreas Schneider <asn@samba.org>
+Date: Tue, 15 Mar 2022 12:57:18 +0100
+Subject: [PATCH 7/9] s3:libads: Remove obsolete free's of kdc_str
+
+This is allocated on the stackframe now!
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=15016
+
+Signed-off-by: Andreas Schneider <asn@samba.org>
+---
+ source3/libads/kerberos.c | 12 +-----------
+ 1 file changed, 1 insertion(+), 11 deletions(-)
+
+diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c
+index aadc65a3edc..2087dc1e6f9 100644
+--- a/source3/libads/kerberos.c
++++ b/source3/libads/kerberos.c
+@@ -443,13 +443,11 @@ static char *get_kdc_ip_string(char *mem_ctx,
+ 				  print_canonical_sockaddr_with_port(mem_ctx,
+ 								     pss));
+ 	if (kdc_str == NULL) {
+-		TALLOC_FREE(frame);
+-		return NULL;
++		goto out;
+ 	}
+ 
+ 	ok = sockaddr_storage_to_samba_sockaddr(&sa, pss);
+ 	if (!ok) {
+-		TALLOC_FREE(kdc_str);
+ 		goto out;
+ 	}
+ 
+@@ -467,7 +465,6 @@ static char *get_kdc_ip_string(char *mem_ctx,
+ 		if (!NT_STATUS_IS_OK(status)) {
+ 			DBG_ERR("get_kdc_list fail %s\n",
+ 				nt_errstr(status));
+-			TALLOC_FREE(kdc_str);
+ 			goto out;
+ 		}
+ 		DBG_DEBUG("got %zu addresses from site %s search\n",
+@@ -485,7 +482,6 @@ static char *get_kdc_ip_string(char *mem_ctx,
+ 	if (!NT_STATUS_IS_OK(status)) {
+ 		DBG_ERR("get_kdc_list (site-less) fail %s\n",
+ 			nt_errstr(status));
+-		TALLOC_FREE(kdc_str);
+ 		goto out;
+ 	}
+ 	DBG_DEBUG("got %zu addresses from site-less search\n", count_nonsite);
+@@ -493,7 +489,6 @@ static char *get_kdc_ip_string(char *mem_ctx,
+ 	if (count_site + count_nonsite < count_site) {
+ 		/* Wrap check. */
+ 		DBG_ERR("get_kdc_list_talloc (site-less) fail wrap error\n");
+-		TALLOC_FREE(kdc_str);
+ 		goto out;
+ 	}
+ 
+@@ -501,7 +496,6 @@ static char *get_kdc_ip_string(char *mem_ctx,
+ 	dc_addrs = talloc_array(talloc_tos(), struct sockaddr_storage,
+ 				count_site + count_nonsite);
+ 	if (dc_addrs == NULL) {
+-		TALLOC_FREE(kdc_str);
+ 		goto out;
+ 	}
+ 
+@@ -523,7 +517,6 @@ static char *get_kdc_ip_string(char *mem_ctx,
+ 
+ 	DBG_DEBUG("%zu additional KDCs to test\n", num_dcs);
+ 	if (num_dcs == 0) {
+-		TALLOC_FREE(kdc_str);
+ 		goto out;
+ 	}
+ 
+@@ -531,7 +524,6 @@ static char *get_kdc_ip_string(char *mem_ctx,
+ 				      struct tsocket_address *,
+ 				      num_dcs);
+ 	if (dc_addrs2 == NULL) {
+-		TALLOC_FREE(kdc_str);
+ 		goto out;
+ 	}
+ 
+@@ -548,7 +540,6 @@ static char *get_kdc_ip_string(char *mem_ctx,
+ 			status = map_nt_error_from_unix(errno);
+ 			DEBUG(2,("Failed to create tsocket_address for %s - %s\n",
+ 				 addr, nt_errstr(status)));
+-			TALLOC_FREE(kdc_str);
+ 			goto out;
+ 		}
+ 	}
+@@ -566,7 +557,6 @@ static char *get_kdc_ip_string(char *mem_ctx,
+ 	if (!NT_STATUS_IS_OK(status)) {
+ 		DEBUG(10,("get_kdc_ip_string: cldap_multi_netlogon failed: "
+ 			  "%s\n", nt_errstr(status)));
+-		TALLOC_FREE(kdc_str);
+ 		goto out;
+ 	}
+ 
+-- 
+2.35.1
+
+
+From 8242cb20ed3149acb83a140c140bdbb90de58b65 Mon Sep 17 00:00:00 2001
+From: Andreas Schneider <asn@samba.org>
+Date: Tue, 15 Mar 2022 13:02:05 +0100
+Subject: [PATCH 8/9] s3:libads: Check print_canonical_sockaddr_with_port() for
+ NULL in get_kdc_ip_string()
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=15016
+
+Signed-off-by: Andreas Schneider <asn@samba.org>
+---
+ source3/libads/kerberos.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c
+index 2087dc1e6f9..20dceeefb22 100644
+--- a/source3/libads/kerberos.c
++++ b/source3/libads/kerberos.c
+@@ -435,13 +435,18 @@ static char *get_kdc_ip_string(char *mem_ctx,
+ 	NTSTATUS status;
+ 	bool ok;
+ 	char *kdc_str = NULL;
++	char *canon_sockaddr = NULL;
+ 
+ 	SMB_ASSERT(pss != NULL);
+ 
++	canon_sockaddr = print_canonical_sockaddr_with_port(frame, pss);
++	if (canon_sockaddr == NULL) {
++		goto out;
++	}
++
+ 	kdc_str = talloc_asprintf(frame,
+ 				  "\t\tkdc = %s\n",
+-				  print_canonical_sockaddr_with_port(mem_ctx,
+-								     pss));
++				  canon_sockaddr);
+ 	if (kdc_str == NULL) {
+ 		goto out;
+ 	}
+-- 
+2.35.1
+
+
+From fbd0843fdd257bc0e4ebef53c7afa29f171e86e5 Mon Sep 17 00:00:00 2001
+From: Andreas Schneider <asn@samba.org>
+Date: Tue, 15 Mar 2022 13:10:06 +0100
+Subject: [PATCH 9/9] s3:libads: Fix creating local krb5.conf
+
+We create an KDC ip string entry directly at the beginning, use it if we
+don't have any additional DCs.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=15016
+
+Signed-off-by: Andreas Schneider <asn@samba.org>
+---
+ source3/libads/kerberos.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c
+index 20dceeefb22..3fd86e87064 100644
+--- a/source3/libads/kerberos.c
++++ b/source3/libads/kerberos.c
+@@ -522,6 +522,11 @@ static char *get_kdc_ip_string(char *mem_ctx,
+ 
+ 	DBG_DEBUG("%zu additional KDCs to test\n", num_dcs);
+ 	if (num_dcs == 0) {
++		/*
++		 * We do not have additional KDCs, but we have the one passed
++		 * in via `pss`. So just use that one and leave.
++		 */
++		result = talloc_move(mem_ctx, &kdc_str);
+ 		goto out;
+ 	}
+ 
+-- 
+2.35.1
+
diff --git a/SOURCES/samba-4-15-fix-winbind-refresh-tickets.patch b/SOURCES/samba-4-15-fix-winbind-refresh-tickets.patch
new file mode 100644
index 0000000..93c2caa
--- /dev/null
+++ b/SOURCES/samba-4-15-fix-winbind-refresh-tickets.patch
@@ -0,0 +1,411 @@
+From a32bef9d1193e2bc253b7af8f4d0adb6476937f5 Mon Sep 17 00:00:00 2001
+From: Samuel Cabrero <scabrero@suse.de>
+Date: Tue, 22 Feb 2022 12:59:44 +0100
+Subject: [PATCH 1/6] s3:libads: Fix memory leak in kerberos_return_pac() error
+ path
+
+Signed-off-by: Samuel Cabrero <scabrero@samba.org>
+Reviewed-by: Stefan Metzmacher <metze@samba.org>
+Reviewed-by: Andreas Schneider <asn@samba.org>
+(cherry picked from commit 3dbcd20de98cd28683a9c248368e5082b6388111)
+---
+ source3/libads/authdata.c | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c
+index dd21d895fc2..c048510d480 100644
+--- a/source3/libads/authdata.c
++++ b/source3/libads/authdata.c
+@@ -61,7 +61,10 @@ NTSTATUS kerberos_return_pac(TALLOC_CTX *mem_ctx,
+ {
+ 	krb5_error_code ret;
+ 	NTSTATUS status = NT_STATUS_INVALID_PARAMETER;
+-	DATA_BLOB tkt, tkt_wrapped, ap_rep, sesskey1;
++	DATA_BLOB tkt = data_blob_null;
++	DATA_BLOB tkt_wrapped = data_blob_null;
++	DATA_BLOB ap_rep = data_blob_null;
++	DATA_BLOB sesskey1 = data_blob_null;
+ 	const char *auth_princ = NULL;
+ 	const char *cc = "MEMORY:kerberos_return_pac";
+ 	struct auth_session_info *session_info;
+@@ -81,7 +84,8 @@ NTSTATUS kerberos_return_pac(TALLOC_CTX *mem_ctx,
+ 	ZERO_STRUCT(sesskey1);
+ 
+ 	if (!name || !pass) {
+-		return NT_STATUS_INVALID_PARAMETER;
++		status = NT_STATUS_INVALID_PARAMETER;
++		goto out;
+ 	}
+ 
+ 	if (cache_name) {
+@@ -131,7 +135,8 @@ NTSTATUS kerberos_return_pac(TALLOC_CTX *mem_ctx,
+ 
+ 	if (expire_time && renew_till_time &&
+ 	    (*expire_time == 0) && (*renew_till_time == 0)) {
+-		return NT_STATUS_INVALID_LOGON_TYPE;
++		status = NT_STATUS_INVALID_LOGON_TYPE;
++		goto out;
+ 	}
+ 
+ 	ret = ads_krb5_cli_get_ticket(mem_ctx,
+-- 
+2.35.1
+
+
+From d5a800beb60ee0b9310fa073c2e06a7dcbe65d5e Mon Sep 17 00:00:00 2001
+From: Samuel Cabrero <scabrero@suse.de>
+Date: Tue, 22 Feb 2022 13:00:05 +0100
+Subject: [PATCH 2/6] lib:krb5_wrap: Improve debug message and use newer debug
+ macro
+
+Signed-off-by: Samuel Cabrero <scabrero@samba.org>
+Reviewed-by: Stefan Metzmacher <metze@samba.org>
+Reviewed-by: Andreas Schneider <asn@samba.org>
+(cherry picked from commit ed14513be055cc56eb39785323df2c538a813865)
+---
+ lib/krb5_wrap/krb5_samba.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/krb5_wrap/krb5_samba.c b/lib/krb5_wrap/krb5_samba.c
+index fff5b4e2a22..42d4b950f80 100644
+--- a/lib/krb5_wrap/krb5_samba.c
++++ b/lib/krb5_wrap/krb5_samba.c
+@@ -1079,7 +1079,7 @@ krb5_error_code smb_krb5_renew_ticket(const char *ccache_string,
+ 		goto done;
+ 	}
+ 
+-	DEBUG(10,("smb_krb5_renew_ticket: using %s as ccache\n", ccache_string));
++	DBG_DEBUG("Using %s as ccache for '%s'\n", ccache_string, client_string);
+ 
+ 	/* FIXME: we should not fall back to defaults */
+ 	ret = krb5_cc_resolve(context, discard_const_p(char, ccache_string), &ccache);
+-- 
+2.35.1
+
+
+From 79d08465f66df67b69fdafed8eec48290acf24b9 Mon Sep 17 00:00:00 2001
+From: Samuel Cabrero <scabrero@suse.de>
+Date: Tue, 22 Feb 2022 14:28:28 +0100
+Subject: [PATCH 3/6] lib:krb5_wrap: Fix wrong debug message and use newer
+ debug macro
+
+Signed-off-by: Samuel Cabrero <scabrero@samba.org>
+Reviewed-by: Stefan Metzmacher <metze@samba.org>
+Reviewed-by: Andreas Schneider <asn@samba.org>
+(cherry picked from commit 1b5b4107a5081f15ba215f3025056d509fcfcf2a)
+---
+ lib/krb5_wrap/krb5_samba.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/lib/krb5_wrap/krb5_samba.c b/lib/krb5_wrap/krb5_samba.c
+index 42d4b950f80..76c2dcd2126 100644
+--- a/lib/krb5_wrap/krb5_samba.c
++++ b/lib/krb5_wrap/krb5_samba.c
+@@ -1101,7 +1101,10 @@ krb5_error_code smb_krb5_renew_ticket(const char *ccache_string,
+ 
+ 	ret = krb5_get_renewed_creds(context, &creds, client, ccache, discard_const_p(char, service_string));
+ 	if (ret) {
+-		DEBUG(10,("smb_krb5_renew_ticket: krb5_get_kdc_cred failed: %s\n", error_message(ret)));
++		DBG_DEBUG("krb5_get_renewed_creds using ccache '%s' "
++			  "for client '%s' and service '%s' failed: %s\n",
++			  ccache_string, client_string, service_string,
++			  error_message(ret));
+ 		goto done;
+ 	}
+ 
+-- 
+2.35.1
+
+
+From 00418e5b78fa4361c0386c13374154d310426f77 Mon Sep 17 00:00:00 2001
+From: Samuel Cabrero <scabrero@suse.de>
+Date: Tue, 22 Feb 2022 13:08:56 +0100
+Subject: [PATCH 4/6] s3:libads: Return canonical principal and realm from
+ kerberos_return_pac()
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=14979
+
+Signed-off-by: Samuel Cabrero <scabrero@samba.org>
+Reviewed-by: Stefan Metzmacher <metze@samba.org>
+Reviewed-by: Andreas Schneider <asn@samba.org>
+(cherry picked from commit 00b1f44a7e8f66976757535bcbc6bea97fb1c29f)
+---
+ source3/libads/authdata.c       | 22 +++++++++++++++++++++-
+ source3/libads/kerberos_proto.h |  2 ++
+ source3/utils/net_ads.c         |  2 ++
+ source3/winbindd/winbindd_pam.c |  2 ++
+ 4 files changed, 27 insertions(+), 1 deletion(-)
+
+diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c
+index c048510d480..bf9a2335445 100644
+--- a/source3/libads/authdata.c
++++ b/source3/libads/authdata.c
+@@ -57,6 +57,8 @@ NTSTATUS kerberos_return_pac(TALLOC_CTX *mem_ctx,
+ 			     time_t renewable_time,
+ 			     const char *impersonate_princ_s,
+ 			     const char *local_service,
++			     char **_canon_principal,
++			     char **_canon_realm,
+ 			     struct PAC_DATA_CTR **_pac_data_ctr)
+ {
+ 	krb5_error_code ret;
+@@ -75,6 +77,8 @@ NTSTATUS kerberos_return_pac(TALLOC_CTX *mem_ctx,
+ 	struct auth4_context *auth_context;
+ 	struct loadparm_context *lp_ctx;
+ 	struct PAC_DATA_CTR *pac_data_ctr = NULL;
++	char *canon_principal = NULL;
++	char *canon_realm = NULL;
+ 
+ 	TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+ 	NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
+@@ -88,6 +92,14 @@ NTSTATUS kerberos_return_pac(TALLOC_CTX *mem_ctx,
+ 		goto out;
+ 	}
+ 
++	if (_canon_principal != NULL) {
++		*_canon_principal = NULL;
++	}
++
++	if (_canon_realm != NULL) {
++		*_canon_realm = NULL;
++	}
++
+ 	if (cache_name) {
+ 		cc = cache_name;
+ 	}
+@@ -109,7 +121,9 @@ NTSTATUS kerberos_return_pac(TALLOC_CTX *mem_ctx,
+ 					  request_pac,
+ 					  add_netbios_addr,
+ 					  renewable_time,
+-					  NULL, NULL, NULL,
++					  tmp_ctx,
++					  &canon_principal,
++					  &canon_realm,
+ 					  &status);
+ 	if (ret) {
+ 		DEBUG(1,("kinit failed for '%s' with: %s (%d)\n",
+@@ -243,6 +257,12 @@ NTSTATUS kerberos_return_pac(TALLOC_CTX *mem_ctx,
+ 	}
+ 
+ 	*_pac_data_ctr = talloc_move(mem_ctx, &pac_data_ctr);
++	if (_canon_principal != NULL) {
++		*_canon_principal = talloc_move(mem_ctx, &canon_principal);
++	}
++	if (_canon_realm != NULL) {
++		*_canon_realm = talloc_move(mem_ctx, &canon_realm);
++	}
+ 
+ out:
+ 	talloc_free(tmp_ctx);
+diff --git a/source3/libads/kerberos_proto.h b/source3/libads/kerberos_proto.h
+index 3d7b5bc074b..807381248c8 100644
+--- a/source3/libads/kerberos_proto.h
++++ b/source3/libads/kerberos_proto.h
+@@ -78,6 +78,8 @@ NTSTATUS kerberos_return_pac(TALLOC_CTX *mem_ctx,
+ 			     time_t renewable_time,
+ 			     const char *impersonate_princ_s,
+ 			     const char *local_service,
++			     char **_canon_principal,
++			     char **_canon_realm,
+ 			     struct PAC_DATA_CTR **pac_data_ctr);
+ 
+ /* The following definitions come from libads/krb5_setpw.c  */
+diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c
+index 8f993f9ba4c..c41fb0afe9c 100644
+--- a/source3/utils/net_ads.c
++++ b/source3/utils/net_ads.c
+@@ -3273,6 +3273,8 @@ static int net_ads_kerberos_pac_common(struct net_context *c, int argc, const ch
+ 				     2592000, /* one month */
+ 				     impersonate_princ_s,
+ 				     local_service,
++				     NULL,
++				     NULL,
+ 				     pac_data_ctr);
+ 	if (!NT_STATUS_IS_OK(status)) {
+ 		d_printf(_("failed to query kerberos PAC: %s\n"),
+diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c
+index 7606bfb4ecd..025a5cbc111 100644
+--- a/source3/winbindd/winbindd_pam.c
++++ b/source3/winbindd/winbindd_pam.c
+@@ -789,6 +789,8 @@ static NTSTATUS winbindd_raw_kerberos_login(TALLOC_CTX *mem_ctx,
+ 				     WINBINDD_PAM_AUTH_KRB5_RENEW_TIME,
+ 				     NULL,
+ 				     local_service,
++				     NULL,
++				     NULL,
+ 				     &pac_data_ctr);
+ 	if (user_ccache_file != NULL) {
+ 		gain_root_privilege();
+-- 
+2.35.1
+
+
+From d754753ab8edf6dde241d91442fe6afba8993de5 Mon Sep 17 00:00:00 2001
+From: Samuel Cabrero <scabrero@suse.de>
+Date: Tue, 22 Feb 2022 13:19:02 +0100
+Subject: [PATCH 5/6] s3:winbind: Store canonical principal and realm in ccache
+ entry
+
+They will be used later to refresh the tickets.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=14979
+
+Signed-off-by: Samuel Cabrero <scabrero@samba.org>
+Reviewed-by: Stefan Metzmacher <metze@samba.org>
+Reviewed-by: Andreas Schneider <asn@samba.org>
+(cherry picked from commit 0f4f330773d272b4d28ff3ba5a41bdd4ba569c8b)
+---
+ source3/winbindd/winbindd.h            |  2 ++
+ source3/winbindd/winbindd_cred_cache.c | 16 +++++++++++++++-
+ source3/winbindd/winbindd_pam.c        | 14 ++++++++++----
+ source3/winbindd/winbindd_proto.h      |  4 +++-
+ 4 files changed, 30 insertions(+), 6 deletions(-)
+
+diff --git a/source3/winbindd/winbindd.h b/source3/winbindd/winbindd.h
+index a6b2238cec1..dac4a1fa927 100644
+--- a/source3/winbindd/winbindd.h
++++ b/source3/winbindd/winbindd.h
+@@ -344,6 +344,8 @@ struct WINBINDD_CCACHE_ENTRY {
+ 	const char *service;
+ 	const char *username;
+ 	const char *realm;
++	const char *canon_principal;
++	const char *canon_realm;
+ 	struct WINBINDD_MEMORY_CREDS *cred_ptr;
+ 	int ref_count;
+ 	uid_t uid;
+diff --git a/source3/winbindd/winbindd_cred_cache.c b/source3/winbindd/winbindd_cred_cache.c
+index c3077e21989..88847b1ab97 100644
+--- a/source3/winbindd/winbindd_cred_cache.c
++++ b/source3/winbindd/winbindd_cred_cache.c
+@@ -501,7 +501,9 @@ NTSTATUS add_ccache_to_list(const char *princ_name,
+ 			    time_t create_time,
+ 			    time_t ticket_end,
+ 			    time_t renew_until,
+-			    bool postponed_request)
++			    bool postponed_request,
++			    const char *canon_principal,
++			    const char *canon_realm)
+ {
+ 	struct WINBINDD_CCACHE_ENTRY *entry = NULL;
+ 	struct timeval t;
+@@ -617,6 +619,18 @@ NTSTATUS add_ccache_to_list(const char *princ_name,
+ 			goto no_mem;
+ 		}
+ 	}
++	if (canon_principal != NULL) {
++		entry->canon_principal = talloc_strdup(entry, canon_principal);
++		if (entry->canon_principal == NULL) {
++			goto no_mem;
++		}
++	}
++	if (canon_realm != NULL) {
++		entry->canon_realm = talloc_strdup(entry, canon_realm);
++		if (entry->canon_realm == NULL) {
++			goto no_mem;
++		}
++	}
+ 
+ 	entry->ccname = talloc_strdup(entry, ccname);
+ 	if (!entry->ccname) {
+diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c
+index 025a5cbc111..a24cef78440 100644
+--- a/source3/winbindd/winbindd_pam.c
++++ b/source3/winbindd/winbindd_pam.c
+@@ -687,6 +687,8 @@ static NTSTATUS winbindd_raw_kerberos_login(TALLOC_CTX *mem_ctx,
+ 	const char *local_service;
+ 	uint32_t i;
+ 	struct netr_SamInfo6 *info6_copy = NULL;
++	char *canon_principal = NULL;
++	char *canon_realm = NULL;
+ 	bool ok;
+ 
+ 	*info6 = NULL;
+@@ -789,8 +791,8 @@ static NTSTATUS winbindd_raw_kerberos_login(TALLOC_CTX *mem_ctx,
+ 				     WINBINDD_PAM_AUTH_KRB5_RENEW_TIME,
+ 				     NULL,
+ 				     local_service,
+-				     NULL,
+-				     NULL,
++				     &canon_principal,
++				     &canon_realm,
+ 				     &pac_data_ctr);
+ 	if (user_ccache_file != NULL) {
+ 		gain_root_privilege();
+@@ -856,7 +858,9 @@ static NTSTATUS winbindd_raw_kerberos_login(TALLOC_CTX *mem_ctx,
+ 					    time(NULL),
+ 					    ticket_lifetime,
+ 					    renewal_until,
+-					    false);
++					    false,
++					    canon_principal,
++					    canon_realm);
+ 
+ 		if (!NT_STATUS_IS_OK(result)) {
+ 			DEBUG(10,("winbindd_raw_kerberos_login: failed to add ccache to list: %s\n",
+@@ -1233,7 +1237,9 @@ static NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain,
+ 							    time(NULL),
+ 							    time(NULL) + lp_winbind_cache_time(),
+ 							    time(NULL) + WINBINDD_PAM_AUTH_KRB5_RENEW_TIME,
+-							    true);
++							    true,
++							    principal_s,
++							    realm);
+ 
+ 				if (!NT_STATUS_IS_OK(result)) {
+ 					DEBUG(10,("winbindd_dual_pam_auth_cached: failed "
+diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h
+index c0d653a6d77..16c23f3de40 100644
+--- a/source3/winbindd/winbindd_proto.h
++++ b/source3/winbindd/winbindd_proto.h
+@@ -236,7 +236,9 @@ NTSTATUS add_ccache_to_list(const char *princ_name,
+ 			    time_t create_time,
+ 			    time_t ticket_end,
+ 			    time_t renew_until,
+-			    bool postponed_request);
++			    bool postponed_request,
++			    const char *canon_principal,
++			    const char *canon_realm);
+ NTSTATUS remove_ccache(const char *username);
+ struct WINBINDD_MEMORY_CREDS *find_memory_creds_by_name(const char *username);
+ NTSTATUS winbindd_add_memory_creds(const char *username,
+-- 
+2.35.1
+
+
+From 82452eb54758de50700776fb92b7e7af892fdaea Mon Sep 17 00:00:00 2001
+From: Samuel Cabrero <scabrero@suse.de>
+Date: Tue, 22 Feb 2022 14:28:44 +0100
+Subject: [PATCH 6/6] s3:winbind: Use the canonical principal name to renew the
+ credentials
+
+The principal name stored in the winbindd ccache entry might be an
+enterprise principal name if enterprise principals are enabled. Use
+the canonical name to renew the credentials.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=14979
+
+Signed-off-by: Samuel Cabrero <scabrero@samba.org>
+Reviewed-by: Stefan Metzmacher <metze@samba.org>
+Reviewed-by: Andreas Schneider <asn@samba.org>
+(cherry picked from commit 8246ccc23d064147412bb3475e6431a9fffc0d27)
+---
+ source3/winbindd/winbindd_cred_cache.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/source3/winbindd/winbindd_cred_cache.c b/source3/winbindd/winbindd_cred_cache.c
+index 88847b1ab97..6c65db6a73f 100644
+--- a/source3/winbindd/winbindd_cred_cache.c
++++ b/source3/winbindd/winbindd_cred_cache.c
+@@ -209,7 +209,7 @@ rekinit:
+ 	set_effective_uid(entry->uid);
+ 
+ 	ret = smb_krb5_renew_ticket(entry->ccname,
+-				    entry->principal_name,
++				    entry->canon_principal,
+ 				    entry->service,
+ 				    &new_start);
+ #if defined(DEBUG_KRB5_TKT_RENEWAL)
+-- 
+2.35.1
+
diff --git a/SOURCES/samba-4.14-IPA-DC-add-missing-checks.patch b/SOURCES/samba-4.14-IPA-DC-add-missing-checks.patch
deleted file mode 100644
index 7e33d59..0000000
--- a/SOURCES/samba-4.14-IPA-DC-add-missing-checks.patch
+++ /dev/null
@@ -1,51 +0,0 @@
-From c11dab13dd30af3e0beb69e8d47c3bfd85e18a91 Mon Sep 17 00:00:00 2001
-From: Alexander Bokovoy <ab@samba.org>
-Date: Fri, 12 Nov 2021 19:06:01 +0200
-Subject: [PATCH] IPA DC: add missing checks
-
-When introducing FreeIPA support, two places were forgotten:
-
- - schannel gensec module needs to be aware of IPA DC
- - _lsa_QueryInfoPolicy should treat IPA DC as PDC
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14903
-
-Signed-off-by: Alexander Bokovoy <ab@samba.org>
-Reviewed-by: Guenther Deschner <gd@samba.org>
-
-Autobuild-User(master): Alexander Bokovoy <ab@samba.org>
-Autobuild-Date(master): Sat Nov 13 07:01:26 UTC 2021 on sn-devel-184
-
-(cherry picked from commit c69b66f649c1d47a7367f7efe25b8df32369a3a5)
----
- auth/gensec/schannel.c              | 1 +
- source3/rpc_server/lsa/srv_lsa_nt.c | 1 +
- 2 files changed, 2 insertions(+)
-
-diff --git a/auth/gensec/schannel.c b/auth/gensec/schannel.c
-index 0cdae141ead..6ebbe8f3179 100644
---- a/auth/gensec/schannel.c
-+++ b/auth/gensec/schannel.c
-@@ -1080,6 +1080,7 @@ static NTSTATUS schannel_server_start(struct gensec_security *gensec_security)
- 	case ROLE_DOMAIN_BDC:
- 	case ROLE_DOMAIN_PDC:
- 	case ROLE_ACTIVE_DIRECTORY_DC:
-+	case ROLE_IPA_DC:
- 		return NT_STATUS_OK;
- 	default:
- 		return NT_STATUS_NOT_IMPLEMENTED;
-diff --git a/source3/rpc_server/lsa/srv_lsa_nt.c b/source3/rpc_server/lsa/srv_lsa_nt.c
-index d6d606ddeca..36774be3e32 100644
---- a/source3/rpc_server/lsa/srv_lsa_nt.c
-+++ b/source3/rpc_server/lsa/srv_lsa_nt.c
-@@ -683,6 +683,7 @@ NTSTATUS _lsa_QueryInfoPolicy(struct pipes_struct *p,
- 		switch (lp_server_role()) {
- 			case ROLE_DOMAIN_PDC:
- 			case ROLE_DOMAIN_BDC:
-+			case ROLE_IPA_DC:
- 				name = get_global_sam_name();
- 				sid = dom_sid_dup(p->mem_ctx, get_global_sam_sid());
- 				if (!sid) {
--- 
-2.33.1
-
diff --git a/SOURCES/samba-4.14-del-dir-with-dangling-symlinks.patch b/SOURCES/samba-4.14-del-dir-with-dangling-symlinks.patch
deleted file mode 100644
index ca9dd8e..0000000
--- a/SOURCES/samba-4.14-del-dir-with-dangling-symlinks.patch
+++ /dev/null
@@ -1,1023 +0,0 @@
-From a0618e0eda69d31d090f776a9217a6a3cf76e5da Mon Sep 17 00:00:00 2001
-From: Jeremy Allison <jra@samba.org>
-Date: Thu, 21 Oct 2021 16:37:27 -0700
-Subject: [PATCH 1/7] s3: smbd: Add two tests showing the ability to delete a
- directory containing a dangling symlink over SMB2 depends on "delete veto
- files" setting.
-
-Add knownfail.
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14879
-
-Signed-off-by: Jeremy Allison <jra@samba.org>
-Reviewed-by: Ralph Boehme <slow@samba.org>
-(cherry picked from commit 942123b95923f35a32df4196a072a3ed3468396a)
-(cherry picked from commit 359517877d6462ff4398401748f921c8b79357a6)
----
- selftest/knownfail.d/rmdir_dangle_symlink     |   1 +
- selftest/target/Samba3.pm                     |   4 +
- .../test_delete_veto_files_only_rmdir.sh      | 183 ++++++++++++++++++
- source3/selftest/tests.py                     |   3 +
- 4 files changed, 191 insertions(+)
- create mode 100644 selftest/knownfail.d/rmdir_dangle_symlink
- create mode 100755 source3/script/tests/test_delete_veto_files_only_rmdir.sh
-
-diff --git a/selftest/knownfail.d/rmdir_dangle_symlink b/selftest/knownfail.d/rmdir_dangle_symlink
-new file mode 100644
-index 00000000000..c775dc5fe15
---- /dev/null
-+++ b/selftest/knownfail.d/rmdir_dangle_symlink
-@@ -0,0 +1 @@
-+^samba3.blackbox.test_dangle_rmdir.rmdir can delete directory containing dangling symlink\(fileserver\)
-diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
-index bbff9d74817..588d7779dd4 100755
---- a/selftest/target/Samba3.pm
-+++ b/selftest/target/Samba3.pm
-@@ -1584,6 +1584,10 @@ sub setup_fileserver
- 	veto files = /veto_name*/
- 	delete veto files = yes
- 
-+[delete_veto_files_only]
-+	path = $veto_sharedir
-+	delete veto files = yes
-+
- [homes]
- 	comment = Home directories
- 	browseable = No
-diff --git a/source3/script/tests/test_delete_veto_files_only_rmdir.sh b/source3/script/tests/test_delete_veto_files_only_rmdir.sh
-new file mode 100755
-index 00000000000..d2c3b2198f7
---- /dev/null
-+++ b/source3/script/tests/test_delete_veto_files_only_rmdir.sh
-@@ -0,0 +1,183 @@
-+#!/bin/sh
-+#
-+# Check smbclient can (or cannot) delete a directory containing dangling symlinks.
-+# BUG: https://bugzilla.samba.org/show_bug.cgi?id=14879
-+#
-+
-+if [ $# -lt 6 ]; then
-+cat <<EOF
-+Usage: $0 SERVER SERVER_IP USERNAME PASSWORD SHAREPATH SMBCLIENT
-+EOF
-+exit 1;
-+fi
-+
-+SERVER=${1}
-+SERVER_IP=${2}
-+USERNAME=${3}
-+PASSWORD=${4}
-+SHAREPATH=${5}
-+SMBCLIENT=${6}
-+shift 6
-+SMBCLIENT="$VALGRIND ${SMBCLIENT}"
-+ADDARGS="$@"
-+
-+incdir=$(dirname "$0")/../../../testprogs/blackbox
-+. $incdir/subunit.sh
-+
-+failed=0
-+
-+rmdir_path="$SHAREPATH/dir"
-+
-+#
-+# Using the share "[delete_veto_files_only]" we CAN delete
-+# a directory containing only a dangling symlink.
-+#
-+test_dangle_symlink_delete_veto_rmdir()
-+{
-+    local dangle_symlink_path="$rmdir_path/bad_link"
-+    local tmpfile=$PREFIX/smbclient.in.$$
-+
-+    # Create rmdir directory.
-+    mkdir -p "$rmdir_path"
-+    # Create dangling symlink underneath.
-+    ln -s "nowhere-foo" "$dangle_symlink_path"
-+
-+    cat > "$tmpfile" <<EOF
-+cd dir
-+ls
-+quit
-+EOF
-+
-+    local cmd='CLI_FORCE_INTERACTIVE=yes $SMBCLIENT //$SERVER/delete_veto_files_only -U$USERNAME%$PASSWORD $ADDARGS < $tmpfile 2>&1'
-+    eval echo "$cmd"
-+    out=$(eval "$cmd")
-+    ret=$?
-+
-+    # Check for smbclient error.
-+    if [ $ret != 0 ] ; then
-+        echo "Failed accessing share delete_veto_files_only - $ret"
-+        echo "$out"
-+        return 1
-+    fi
-+
-+    # We should NOT see the dangling symlink file.
-+    echo "$out" | grep bad_link
-+    ret=$?
-+    if [ $ret -eq 0 ] ; then
-+       echo "Saw dangling symlink bad_link in share delete_veto_files_only"
-+       echo "$out"
-+       return 1
-+    fi
-+
-+    # Try and remove the directory, should succeed.
-+    cat > "$tmpfile" <<EOF
-+rd dir
-+quit
-+EOF
-+
-+    local cmd='CLI_FORCE_INTERACTIVE=yes $SMBCLIENT //$SERVER/delete_veto_files_only -U$USERNAME%$PASSWORD $ADDARGS < $tmpfile 2>&1'
-+    eval echo "$cmd"
-+    out=$(eval "$cmd")
-+    ret=$?
-+
-+    # Check for smbclient error.
-+    if [ $ret != 0 ] ; then
-+        echo "Failed accessing share delete_veto_files_only - $ret"
-+        echo "$out"
-+        return 1
-+    fi
-+
-+    # We should get no NT_STATUS_ errors.
-+    echo "$out" | grep NT_STATUS_
-+    ret=$?
-+    if [ $ret -eq 0 ] ; then
-+       echo "Got error NT_STATUS_ in share delete_veto_files_only"
-+       echo "$out"
-+       return 1
-+    fi
-+
-+    return 0
-+}
-+
-+#
-+# Using the share "[veto_files_nodelete]" we CANNOT delete
-+# a directory containing only a dangling symlink.
-+#
-+test_dangle_symlink_veto_files_nodelete()
-+{
-+    local dangle_symlink_path="$rmdir_path/bad_link"
-+    local tmpfile=$PREFIX/smbclient.in.$$
-+
-+    # Create rmdir directory.
-+    mkdir -p "$rmdir_path"
-+    # Create dangling symlink underneath.
-+    ln -s "nowhere-foo" "$dangle_symlink_path"
-+
-+    cat > "$tmpfile" <<EOF
-+cd dir
-+ls
-+quit
-+EOF
-+
-+    local cmd='CLI_FORCE_INTERACTIVE=yes $SMBCLIENT //$SERVER/veto_files_nodelete -U$USERNAME%$PASSWORD $ADDARGS < $tmpfile 2>&1'
-+    eval echo "$cmd"
-+    out=$(eval "$cmd")
-+    ret=$?
-+
-+    # Check for smbclient error.
-+    if [ $ret != 0 ] ; then
-+        echo "Failed accessing share veto_files_nodelete - $ret"
-+        echo "$out"
-+        return 1
-+    fi
-+
-+    # We should NOT see the dangling symlink file.
-+    echo "$out" | grep bad_link
-+    ret=$?
-+    if [ $ret -eq 0 ] ; then
-+       echo "Saw dangling symlink bad_link in share veto_files_nodelete"
-+       echo "$out"
-+       return 1
-+    fi
-+
-+    # Try and remove the directory, should fail with DIRECTORY_NOT_EMPTY.
-+    cat > "$tmpfile" <<EOF
-+rd dir
-+quit
-+EOF
-+
-+    local cmd='CLI_FORCE_INTERACTIVE=yes $SMBCLIENT //$SERVER/veto_files_nodelete -U$USERNAME%$PASSWORD $ADDARGS < $tmpfile 2>&1'
-+    eval echo "$cmd"
-+    out=$(eval "$cmd")
-+    ret=$?
-+
-+    # Check for smbclient error.
-+    if [ $ret != 0 ] ; then
-+        echo "Failed accessing share veto_files_nodelete - $ret"
-+        echo "$out"
-+        return 1
-+    fi
-+
-+    # We should get NT_STATUS_DIRECTORY_NOT_EMPTY errors.
-+    echo "$out" | grep NT_STATUS_DIRECTORY_NOT_EMPTY
-+    ret=$?
-+    if [ $ret -ne 0 ] ; then
-+       echo "Should get NT_STATUS_DIRECTORY_NOT_EMPTY in share veto_files_nodelete"
-+       echo "$out"
-+       return 1
-+    fi
-+
-+    return 0
-+}
-+
-+
-+testit "rmdir can delete directory containing dangling symlink" \
-+   test_dangle_symlink_delete_veto_rmdir || failed=$(expr "$failed" + 1)
-+
-+rm -rf "$rmdir_path"
-+
-+testit "rmdir cannot delete directory delete_veto_files_no containing dangling symlink" \
-+   test_dangle_symlink_veto_files_nodelete || failed=$(expr "$failed" + 1)
-+
-+rm -rf "$rmdir_path"
-+exit "$failed"
-diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
-index 82f32ec4232..330024cf77c 100755
---- a/source3/selftest/tests.py
-+++ b/source3/selftest/tests.py
-@@ -501,6 +501,9 @@ for env in ["fileserver"]:
-     plantestsuite("samba3.blackbox.test_veto_rmdir", env,
-                   [os.path.join(samba3srcdir, "script/tests/test_veto_rmdir.sh"),
-                   '$SERVER', '$SERVER_IP', '$USERNAME', '$PASSWORD', '$LOCAL_PATH/veto', smbclient3])
-+    plantestsuite("samba3.blackbox.test_dangle_rmdir", env,
-+                  [os.path.join(samba3srcdir, "script/tests/test_delete_veto_files_only_rmdir.sh"),
-+                  '$SERVER', '$SERVER_IP', '$USERNAME', '$PASSWORD', '$LOCAL_PATH/veto', smbclient3])
- 
-     #
-     # tar command tests
--- 
-2.33.1
-
-
-From 47c98fe40101b60d5b5a34eb8ef02106c1da66c9 Mon Sep 17 00:00:00 2001
-From: Jeremy Allison <jra@samba.org>
-Date: Mon, 25 Oct 2021 12:01:58 -0700
-Subject: [PATCH 2/7] s3: VFS: streams_depot. Allow unlinkat to cope with
- dangling symlinks.
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14879
-
-Signed-off-by: Jeremy Allison <jra@samba.org>
-Reviewed-by: Ralph Boehme <slow@samba.org>
-(cherry picked from commit 295d7d026babe3cd5123d0f53adcb16868907f05)
-(backported from commit 7a4173809a87350bc3580240232978042ec2ceca)
-[pfilipen@redhat.com: code in 4.15 uses different variable name]
----
- source3/modules/vfs_streams_depot.c | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
-diff --git a/source3/modules/vfs_streams_depot.c b/source3/modules/vfs_streams_depot.c
-index a5e02d5a069..dd6376e5fd0 100644
---- a/source3/modules/vfs_streams_depot.c
-+++ b/source3/modules/vfs_streams_depot.c
-@@ -739,6 +739,16 @@ static int streams_depot_unlink_internal(vfs_handle_struct *handle,
- 		ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname_base);
- 	} else {
- 		ret = SMB_VFS_NEXT_STAT(handle, smb_fname_base);
-+		if (ret == -1 && (errno == ENOENT || errno == ELOOP)) {
-+			if (VALID_STAT(smb_fname->st) &&
-+					S_ISLNK(smb_fname->st.st_ex_mode)) {
-+				/*
-+				 * Original name was a link - Could be
-+				 * trying to remove a dangling symlink.
-+				 */
-+				ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname_base);
-+			}
-+		}
- 	}
- 
- 	if (ret == -1) {
--- 
-2.33.1
-
-
-From 474a91d03527a15f7655be3866a9e5eaa405118f Mon Sep 17 00:00:00 2001
-From: Jeremy Allison <jra@samba.org>
-Date: Mon, 25 Oct 2021 12:02:43 -0700
-Subject: [PATCH 3/7] s3: VFS: xattr_tdb. Allow unlinkat to cope with dangling
- symlinks.
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14879
-
-Signed-off-by: Jeremy Allison <jra@samba.org>
-Reviewed-by: Ralph Boehme <slow@samba.org>
-(cherry picked from commit f254be19d6501a4f573843af97963e350a9ee2ed)
-(backported from commit 0dba0917fd97e975d1daab5b0828644d026c2bc5)
-[pfilipen@redhat.com: code in 4.15 uses different variable name]
----
- source3/modules/vfs_xattr_tdb.c | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
-diff --git a/source3/modules/vfs_xattr_tdb.c b/source3/modules/vfs_xattr_tdb.c
-index d89a1dd0d7d..e06ff9639f1 100644
---- a/source3/modules/vfs_xattr_tdb.c
-+++ b/source3/modules/vfs_xattr_tdb.c
-@@ -639,6 +639,16 @@ static int xattr_tdb_unlinkat(vfs_handle_struct *handle,
- 		ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname_tmp);
- 	} else {
- 		ret = SMB_VFS_NEXT_STAT(handle, smb_fname_tmp);
-+		if (ret == -1 && (errno == ENOENT || errno == ELOOP)) {
-+			if (VALID_STAT(smb_fname->st) &&
-+					S_ISLNK(smb_fname->st.st_ex_mode)) {
-+				/*
-+				 * Original name was a link - Could be
-+				 * trying to remove a dangling symlink.
-+				 */
-+				ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname_tmp);
-+			}
-+		}
- 	}
- 	if (ret == -1) {
- 		goto out;
--- 
-2.33.1
-
-
-From 298a8dac1160ebba56cd84b7e25908e160b88f85 Mon Sep 17 00:00:00 2001
-From: Jeremy Allison <jra@samba.org>
-Date: Mon, 25 Oct 2021 12:21:37 -0700
-Subject: [PATCH 4/7] s3: smbd: Fix rmdir_internals() to do an early return if
- lp_delete_veto_files() is not set.
-
-Fix the comments to match what the code actually does. The
-exit at the end of the scan directory loop if we find a client
-visible filename is a change in behavior, but the previous
-behavior (not exist on visible filename, but delete it) was
-a bug and in non-tested code. Now it's testd.
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14879
-
-Signed-off-by: Jeremy Allison <jra@samba.org>
-Reviewed-by: Ralph Boehme <slow@samba.org>
-(cherry picked from commit a37d16e7c55f85e3f2c9c8614755ea6307092d5f)
-(backported from commit e00fe095e8cf7ab54bc82870b913762d2fdddbad)
-[pfilipen@redhat.com: rmdir_internals() got refactored in 4.15]
----
- source3/smbd/close.c | 247 ++++++++++++++++++++++---------------------
- 1 file changed, 128 insertions(+), 119 deletions(-)
-
-diff --git a/source3/smbd/close.c b/source3/smbd/close.c
-index f05619d1886..0c102b9533b 100644
---- a/source3/smbd/close.c
-+++ b/source3/smbd/close.c
-@@ -938,8 +938,11 @@ static NTSTATUS rmdir_internals(TALLOC_CTX *ctx, files_struct *fsp)
- {
- 	connection_struct *conn = fsp->conn;
- 	struct smb_filename *smb_dname = fsp->fsp_name;
--	const struct loadparm_substitution *lp_sub =
--		loadparm_s3_global_substitution();
-+	SMB_STRUCT_STAT st;
-+	const char *dname = NULL;
-+	char *talloced = NULL;
-+	long dirpos = 0;
-+	struct smb_Dir *dir_hnd = NULL;
- 	int ret;
- 
- 	SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
-@@ -974,143 +977,149 @@ static NTSTATUS rmdir_internals(TALLOC_CTX *ctx, files_struct *fsp)
- 		return NT_STATUS_OK;
- 	}
- 
--	if(((errno == ENOTEMPTY)||(errno == EEXIST)) && *lp_veto_files(talloc_tos(), lp_sub, SNUM(conn))) {
--		/*
--		 * Check to see if the only thing in this directory are
--		 * vetoed files/directories. If so then delete them and
--		 * retry. If we fail to delete any of them (and we *don't*
--		 * do a recursive delete) then fail the rmdir.
--		 */
--		SMB_STRUCT_STAT st;
--		const char *dname = NULL;
--		char *talloced = NULL;
--		long dirpos = 0;
--		struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn,
--						  smb_dname, NULL,
--						  0);
--
--		if(dir_hnd == NULL) {
-+	if (!((errno == ENOTEMPTY) || (errno == EEXIST))) {
-+		DEBUG(3,("rmdir_internals: couldn't remove directory %s : "
-+			 "%s\n", smb_fname_str_dbg(smb_dname),
-+			 strerror(errno)));
-+		return map_nt_error_from_unix(errno);
-+	}
-+
-+	/*
-+	 * Here we know the initial directory unlink failed with
-+	 * ENOTEMPTY or EEXIST so we know there are objects within.
-+	 * If we don't have permission to delete files non
-+	 * visible to the client just fail the directory delete.
-+	 */
-+
-+	if (!lp_delete_veto_files(SNUM(conn))) {
-+		errno = ENOTEMPTY;
-+		goto err;
-+	}
-+
-+	/*
-+	 * Check to see if the only thing in this directory are
-+	 * files non-visible to the client. If not, fail the delete.
-+	 */
-+
-+	dir_hnd = OpenDir(talloc_tos(), conn, smb_dname, NULL, 0);
-+	if (dir_hnd == NULL) {
-+		errno = ENOTEMPTY;
-+		goto err;
-+	}
-+
-+	while ((dname = ReadDirName(dir_hnd, &dirpos, &st, &talloced)) != NULL) {
-+		if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0)) {
-+			TALLOC_FREE(talloced);
-+			continue;
-+		}
-+		if (!is_visible_file(conn,
-+					dir_hnd,
-+					dname,
-+					&st,
-+					false)) {
-+			TALLOC_FREE(talloced);
-+			continue;
-+		}
-+		if(!IS_VETO_PATH(conn, dname)) {
-+			/*
-+			 * We found a client visible name.
-+			 * We cannot delete this directory.
-+			 */
-+			DBG_DEBUG("got name %s - "
-+				"can't delete directory %s\n",
-+				dname,
-+				fsp_str_dbg(fsp));
-+			TALLOC_FREE(dir_hnd);
-+			TALLOC_FREE(talloced);
- 			errno = ENOTEMPTY;
- 			goto err;
- 		}
-+		TALLOC_FREE(talloced);
-+	}
- 
--		while ((dname = ReadDirName(dir_hnd, &dirpos, &st,
--					    &talloced)) != NULL) {
--			if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0)) {
--				TALLOC_FREE(talloced);
--				continue;
--			}
--			if (!is_visible_file(conn,
--						dir_hnd,
--						dname,
--						&st,
--						false)) {
--				TALLOC_FREE(talloced);
--				continue;
--			}
--			if(!IS_VETO_PATH(conn, dname)) {
--				TALLOC_FREE(dir_hnd);
--				TALLOC_FREE(talloced);
--				errno = ENOTEMPTY;
--				goto err;
--			}
-+	/* Do a recursive delete. */
-+	RewindDir(dir_hnd,&dirpos);
-+	while ((dname = ReadDirName(dir_hnd, &dirpos, &st, &talloced)) != NULL) {
-+		struct smb_filename *smb_dname_full = NULL;
-+		char *fullname = NULL;
-+		bool do_break = true;
-+
-+		if (ISDOT(dname) || ISDOTDOT(dname)) {
-+			TALLOC_FREE(talloced);
-+			continue;
-+		}
-+		if (!is_visible_file(conn,
-+					dir_hnd,
-+					dname,
-+					&st,
-+					false)) {
- 			TALLOC_FREE(talloced);
-+			continue;
- 		}
- 
--		/* We only have veto files/directories.
--		 * Are we allowed to delete them ? */
-+		fullname = talloc_asprintf(ctx,
-+				"%s/%s",
-+				smb_dname->base_name,
-+				dname);
- 
--		if(!lp_delete_veto_files(SNUM(conn))) {
--			TALLOC_FREE(dir_hnd);
--			errno = ENOTEMPTY;
--			goto err;
-+		if (fullname == NULL) {
-+			errno = ENOMEM;
-+			goto err_break;
- 		}
- 
--		/* Do a recursive delete. */
--		RewindDir(dir_hnd,&dirpos);
--		while ((dname = ReadDirName(dir_hnd, &dirpos, &st,
--					    &talloced)) != NULL) {
--			struct smb_filename *smb_dname_full = NULL;
--			char *fullname = NULL;
--			bool do_break = true;
--
--			if (ISDOT(dname) || ISDOTDOT(dname)) {
--				TALLOC_FREE(talloced);
--				continue;
--			}
--			if (!is_visible_file(conn,
--						dir_hnd,
--						dname,
--						&st,
--						false)) {
--				TALLOC_FREE(talloced);
--				continue;
--			}
--
--			fullname = talloc_asprintf(ctx,
--					"%s/%s",
--					smb_dname->base_name,
--					dname);
-+		smb_dname_full = synthetic_smb_fname(talloc_tos(),
-+						fullname,
-+						NULL,
-+						NULL,
-+						smb_dname->twrp,
-+						smb_dname->flags);
-+		if (smb_dname_full == NULL) {
-+			errno = ENOMEM;
-+			goto err_break;
-+		}
- 
--			if(!fullname) {
--				errno = ENOMEM;
-+		if(SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
-+			goto err_break;
-+		}
-+		if(smb_dname_full->st.st_ex_mode & S_IFDIR) {
-+			int retval;
-+			if(!recursive_rmdir(ctx, conn,
-+					    smb_dname_full)) {
- 				goto err_break;
- 			}
--
--			smb_dname_full = synthetic_smb_fname(talloc_tos(),
--							fullname,
--							NULL,
--							NULL,
--							smb_dname->twrp,
--							smb_dname->flags);
--			if (smb_dname_full == NULL) {
--				errno = ENOMEM;
-+			retval = SMB_VFS_UNLINKAT(conn,
-+					conn->cwd_fsp,
-+					smb_dname_full,
-+					AT_REMOVEDIR);
-+			if(retval != 0) {
- 				goto err_break;
- 			}
--
--			if(SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
-+		} else {
-+			int retval = SMB_VFS_UNLINKAT(conn,
-+					conn->cwd_fsp,
-+					smb_dname_full,
-+					0);
-+			if(retval != 0) {
- 				goto err_break;
- 			}
--			if(smb_dname_full->st.st_ex_mode & S_IFDIR) {
--				int retval;
--				if(!recursive_rmdir(ctx, conn,
--						    smb_dname_full)) {
--					goto err_break;
--				}
--				retval = SMB_VFS_UNLINKAT(conn,
--						conn->cwd_fsp,
--						smb_dname_full,
--						AT_REMOVEDIR);
--				if(retval != 0) {
--					goto err_break;
--				}
--			} else {
--				int retval = SMB_VFS_UNLINKAT(conn,
--						conn->cwd_fsp,
--						smb_dname_full,
--						0);
--				if(retval != 0) {
--					goto err_break;
--				}
--			}
-+		}
- 
--			/* Successful iteration. */
--			do_break = false;
-+		/* Successful iteration. */
-+		do_break = false;
- 
--		 err_break:
--			TALLOC_FREE(fullname);
--			TALLOC_FREE(smb_dname_full);
--			TALLOC_FREE(talloced);
--			if (do_break)
--				break;
--		}
--		TALLOC_FREE(dir_hnd);
--		/* Retry the rmdir */
--		ret = SMB_VFS_UNLINKAT(conn,
--				conn->cwd_fsp,
--				smb_dname,
--				AT_REMOVEDIR);
-+	err_break:
-+		TALLOC_FREE(fullname);
-+		TALLOC_FREE(smb_dname_full);
-+		TALLOC_FREE(talloced);
-+		if (do_break)
-+			break;
- 	}
-+	TALLOC_FREE(dir_hnd);
-+	/* Retry the rmdir */
-+	ret = SMB_VFS_UNLINKAT(conn,
-+			conn->cwd_fsp,
-+			smb_dname,
-+			AT_REMOVEDIR);
- 
-   err:
- 
--- 
-2.33.1
-
-
-From a7075aeedd078c68b57556678fa40907cd66cd08 Mon Sep 17 00:00:00 2001
-From: Jeremy Allison <jra@samba.org>
-Date: Mon, 25 Oct 2021 12:32:29 -0700
-Subject: [PATCH 5/7] s3: smbd: Fix logic in rmdir_internals() to cope with
- dangling symlinks.
-
-Still need to add the same logic in can_delete_directory_fsp()
-before we can delete the knownfail.
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14879
-
-Signed-off-by: Jeremy Allison <jra@samba.org>
-Reviewed-by: Ralph Boehme <slow@samba.org>
-(cherry picked from commit 26fecad2e66e91a3913d88ee2e0889f266e91d89)
-(backported from commit 4793c4d5307472f0eb72f70f7dbf7324744e3f91)
-[pfilipen@redhat.com: rmdir_internals() got refactored in 4.15]
----
- source3/smbd/close.c | 103 ++++++++++++++++++++++++++++++++++++++++++-
- 1 file changed, 101 insertions(+), 2 deletions(-)
-
-diff --git a/source3/smbd/close.c b/source3/smbd/close.c
-index 0c102b9533b..81811f703b0 100644
---- a/source3/smbd/close.c
-+++ b/source3/smbd/close.c
-@@ -1008,10 +1008,14 @@ static NTSTATUS rmdir_internals(TALLOC_CTX *ctx, files_struct *fsp)
- 	}
- 
- 	while ((dname = ReadDirName(dir_hnd, &dirpos, &st, &talloced)) != NULL) {
-+		struct smb_filename *smb_dname_full = NULL;
-+		char *fullname = NULL;
-+
- 		if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0)) {
- 			TALLOC_FREE(talloced);
- 			continue;
- 		}
-+
- 		if (!is_visible_file(conn,
- 					dir_hnd,
- 					dname,
-@@ -1020,6 +1024,98 @@ static NTSTATUS rmdir_internals(TALLOC_CTX *ctx, files_struct *fsp)
- 			TALLOC_FREE(talloced);
- 			continue;
- 		}
-+
-+		fullname = talloc_asprintf(talloc_tos(),
-+					   "%s/%s",
-+					   smb_dname->base_name,
-+					   dname);
-+
-+		if (fullname == NULL) {
-+			TALLOC_FREE(talloced);
-+			errno = ENOMEM;
-+			goto err;
-+		}
-+
-+		smb_dname_full = synthetic_smb_fname(talloc_tos(),
-+						     fullname,
-+						     NULL,
-+						     NULL,
-+						     smb_dname->twrp,
-+						     smb_dname->flags);
-+		if (smb_dname_full == NULL) {
-+			TALLOC_FREE(talloced);
-+			TALLOC_FREE(fullname);
-+			errno = ENOMEM;
-+			goto err;
-+		}
-+
-+		ret = SMB_VFS_LSTAT(conn, smb_dname_full);
-+		if (ret != 0) {
-+			int saved_errno = errno;
-+			TALLOC_FREE(talloced);
-+			TALLOC_FREE(fullname);
-+			TALLOC_FREE(smb_dname_full);
-+			errno = saved_errno;
-+			goto err;
-+		}
-+
-+		if (S_ISLNK(smb_dname_full->st.st_ex_mode)) {
-+			/* Could it be an msdfs link ? */
-+			if (lp_host_msdfs() &&
-+				lp_msdfs_root(SNUM(conn))) {
-+				struct smb_filename *smb_atname;
-+				smb_atname = synthetic_smb_fname(talloc_tos(),
-+							dname,
-+							NULL,
-+							&smb_dname_full->st,
-+							fsp->fsp_name->twrp,
-+							fsp->fsp_name->flags);
-+				if (smb_atname == NULL) {
-+					TALLOC_FREE(talloced);
-+					TALLOC_FREE(fullname);
-+					TALLOC_FREE(smb_dname_full);
-+					errno = ENOMEM;
-+					goto err;
-+				}
-+				if (is_msdfs_link(conn, smb_atname)) {
-+					TALLOC_FREE(talloced);
-+					TALLOC_FREE(fullname);
-+					TALLOC_FREE(smb_dname_full);
-+					TALLOC_FREE(smb_atname);
-+					DBG_DEBUG("got msdfs link name %s "
-+						"- can't delete directory %s\n",
-+						dname,
-+						fsp_str_dbg(fsp));
-+					errno = ENOTEMPTY;
-+					goto err;
-+				}
-+				TALLOC_FREE(smb_atname);
-+			}
-+
-+			/* Not a DFS link - could it be a dangling symlink ? */
-+			ret = SMB_VFS_STAT(conn, smb_dname_full);
-+			if (ret == -1 && (errno == ENOENT || errno == ELOOP)) {
-+				/*
-+				 * Dangling symlink.
-+				 * Allow delete as "delete veto files = yes"
-+				 */
-+				TALLOC_FREE(talloced);
-+				TALLOC_FREE(fullname);
-+				TALLOC_FREE(smb_dname_full);
-+				continue;
-+			}
-+
-+			DBG_DEBUG("got symlink name %s - "
-+				"can't delete directory %s\n",
-+				dname,
-+				fsp_str_dbg(fsp));
-+			TALLOC_FREE(talloced);
-+			TALLOC_FREE(fullname);
-+			TALLOC_FREE(smb_dname_full);
-+			errno = ENOTEMPTY;
-+			goto err;
-+		}
-+
- 		if(!IS_VETO_PATH(conn, dname)) {
- 			/*
- 			 * We found a client visible name.
-@@ -1029,12 +1125,15 @@ static NTSTATUS rmdir_internals(TALLOC_CTX *ctx, files_struct *fsp)
- 				"can't delete directory %s\n",
- 				dname,
- 				fsp_str_dbg(fsp));
--			TALLOC_FREE(dir_hnd);
- 			TALLOC_FREE(talloced);
-+			TALLOC_FREE(fullname);
-+			TALLOC_FREE(smb_dname_full);
- 			errno = ENOTEMPTY;
- 			goto err;
- 		}
- 		TALLOC_FREE(talloced);
-+		TALLOC_FREE(fullname);
-+		TALLOC_FREE(smb_dname_full);
- 	}
- 
- 	/* Do a recursive delete. */
-@@ -1114,7 +1213,6 @@ static NTSTATUS rmdir_internals(TALLOC_CTX *ctx, files_struct *fsp)
- 		if (do_break)
- 			break;
- 	}
--	TALLOC_FREE(dir_hnd);
- 	/* Retry the rmdir */
- 	ret = SMB_VFS_UNLINKAT(conn,
- 			conn->cwd_fsp,
-@@ -1123,6 +1221,7 @@ static NTSTATUS rmdir_internals(TALLOC_CTX *ctx, files_struct *fsp)
- 
-   err:
- 
-+	TALLOC_FREE(dir_hnd);
- 	if (ret != 0) {
- 		DEBUG(3,("rmdir_internals: couldn't remove directory %s : "
- 			 "%s\n", smb_fname_str_dbg(smb_dname),
--- 
-2.33.1
-
-
-From 843fc3b857cdfd6c7e902acef933d17690815e7e Mon Sep 17 00:00:00 2001
-From: Jeremy Allison <jra@samba.org>
-Date: Mon, 25 Oct 2021 12:36:57 -0700
-Subject: [PATCH 6/7] s3: smbd: Fix logic in can_delete_directory_fsp() to cope
- with dangling symlinks.
-
-Remove knownfail.
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14879
-
-Signed-off-by: Jeremy Allison <jra@samba.org>
-Reviewed-by: Ralph Boehme <slow@samba.org>
-(cherry picked from commit e9ef970eee5eca8ab3720279c54098e91d2dfda9)
-(backported from commit 5023dbc04bfad7cc39e8c4de96f40c82e7a0288e)
-[pfilipen@redhat.com: can_delete_directory_fsp() got refactored in 4.15]
----
- selftest/knownfail.d/rmdir_dangle_symlink |  1 -
- source3/smbd/dir.c                        | 97 +++++++++++++++++++++++
- 2 files changed, 97 insertions(+), 1 deletion(-)
- delete mode 100644 selftest/knownfail.d/rmdir_dangle_symlink
-
-diff --git a/selftest/knownfail.d/rmdir_dangle_symlink b/selftest/knownfail.d/rmdir_dangle_symlink
-deleted file mode 100644
-index c775dc5fe15..00000000000
---- a/selftest/knownfail.d/rmdir_dangle_symlink
-+++ /dev/null
-@@ -1 +0,0 @@
--^samba3.blackbox.test_dangle_rmdir.rmdir can delete directory containing dangling symlink\(fileserver\)
-diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c
-index 545c7499f28..96edc8678e5 100644
---- a/source3/smbd/dir.c
-+++ b/source3/smbd/dir.c
-@@ -1876,6 +1876,8 @@ NTSTATUS can_delete_directory_fsp(files_struct *fsp)
- 	char *talloced = NULL;
- 	SMB_STRUCT_STAT st;
- 	struct connection_struct *conn = fsp->conn;
-+	struct smb_filename *smb_dname = fsp->fsp_name;
-+	int ret;
- 	struct smb_Dir *dir_hnd = OpenDir(talloc_tos(),
- 					conn,
- 					fsp->fsp_name,
-@@ -1887,6 +1889,9 @@ NTSTATUS can_delete_directory_fsp(files_struct *fsp)
- 	}
- 
- 	while ((dname = ReadDirName(dir_hnd, &dirpos, &st, &talloced))) {
-+		struct smb_filename *smb_dname_full = NULL;
-+		char *fullname = NULL;
-+
- 		if (ISDOT(dname) || (ISDOTDOT(dname))) {
- 			TALLOC_FREE(talloced);
- 			continue;
-@@ -1901,6 +1906,98 @@ NTSTATUS can_delete_directory_fsp(files_struct *fsp)
- 			continue;
- 		}
- 
-+		fullname = talloc_asprintf(talloc_tos(),
-+					   "%s/%s",
-+					   smb_dname->base_name,
-+					   dname);
-+
-+		if (fullname == NULL) {
-+			TALLOC_FREE(dir_hnd);
-+			TALLOC_FREE(talloced);
-+			return NT_STATUS_NO_MEMORY;
-+		}
-+
-+		smb_dname_full = synthetic_smb_fname(talloc_tos(),
-+						     fullname,
-+						     NULL,
-+						     NULL,
-+						     smb_dname->twrp,
-+						     smb_dname->flags);
-+		if (smb_dname_full == NULL) {
-+			TALLOC_FREE(dir_hnd);
-+			TALLOC_FREE(talloced);
-+			TALLOC_FREE(fullname);
-+			return NT_STATUS_NO_MEMORY;
-+		}
-+
-+		ret = SMB_VFS_LSTAT(conn, smb_dname_full);
-+		if (ret != 0) {
-+			TALLOC_FREE(dir_hnd);
-+			TALLOC_FREE(talloced);
-+			TALLOC_FREE(fullname);
-+			TALLOC_FREE(smb_dname_full);
-+			return map_nt_error_from_unix(errno);
-+		}
-+
-+		if (S_ISLNK(smb_dname_full->st.st_ex_mode)) {
-+			/* Could it be an msdfs link ? */
-+			if (lp_host_msdfs() &&
-+			    lp_msdfs_root(SNUM(conn))) {
-+				struct smb_filename *smb_atname;
-+				smb_atname = synthetic_smb_fname(talloc_tos(),
-+							dname,
-+							NULL,
-+							&smb_dname_full->st,
-+							fsp->fsp_name->twrp,
-+							fsp->fsp_name->flags);
-+				if (smb_atname == NULL) {
-+					TALLOC_FREE(dir_hnd);
-+					TALLOC_FREE(talloced);
-+					TALLOC_FREE(fullname);
-+					TALLOC_FREE(smb_dname_full);
-+					return NT_STATUS_NO_MEMORY;
-+				}
-+				if (is_msdfs_link(conn, smb_atname)) {
-+					TALLOC_FREE(dir_hnd);
-+					TALLOC_FREE(talloced);
-+					TALLOC_FREE(fullname);
-+					TALLOC_FREE(smb_dname_full);
-+					TALLOC_FREE(smb_atname);
-+					DBG_DEBUG("got msdfs link name %s "
-+						"- can't delete directory %s\n",
-+						dname,
-+						fsp_str_dbg(fsp));
-+					return NT_STATUS_DIRECTORY_NOT_EMPTY;
-+				}
-+				TALLOC_FREE(smb_atname);
-+			}
-+
-+			/* Not a DFS link - could it be a dangling symlink ? */
-+			ret = SMB_VFS_STAT(conn, smb_dname_full);
-+			if (ret == -1 && (errno == ENOENT || errno == ELOOP)) {
-+				/*
-+				 * Dangling symlink.
-+				 * Allow if "delete veto files = yes"
-+				 */
-+				if (lp_delete_veto_files(SNUM(conn))) {
-+					TALLOC_FREE(talloced);
-+					TALLOC_FREE(fullname);
-+					TALLOC_FREE(smb_dname_full);
-+					continue;
-+				}
-+			}
-+
-+			DBG_DEBUG("got symlink name %s - "
-+				"can't delete directory %s\n",
-+				dname,
-+				fsp_str_dbg(fsp));
-+			TALLOC_FREE(dir_hnd);
-+			TALLOC_FREE(talloced);
-+			TALLOC_FREE(fullname);
-+			TALLOC_FREE(smb_dname_full);
-+			return NT_STATUS_DIRECTORY_NOT_EMPTY;
-+		}
-+
- 		DEBUG(10,("got name %s - can't delete\n",
- 			 dname ));
- 		status = NT_STATUS_DIRECTORY_NOT_EMPTY;
--- 
-2.33.1
-
-
-From 7189ea825d8c9e4777dba737227ead602ad9b651 Mon Sep 17 00:00:00 2001
-From: Jeremy Allison <jra@samba.org>
-Date: Mon, 25 Oct 2021 12:42:02 -0700
-Subject: [PATCH 7/7] s3: docs-xml: Clarify the "delete veto files" paramter.
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14879
-
-Signed-off-by: Jeremy Allison <jra@samba.org>
-Reviewed-by: Ralph Boehme <slow@samba.org>
-
-Autobuild-User(master): Ralph Böhme <slow@samba.org>
-Autobuild-Date(master): Fri Oct 29 14:57:14 UTC 2021 on sn-devel-184
-
-(cherry picked from commit 0b818c6b77e972626d0b071bebcf4ce55619fb84)
-(cherry picked from commit a549dc219cba5bd61969e4919ae4142f52c133ea)
----
- docs-xml/smbdotconf/filename/deletevetofiles.xml | 9 ++++++---
- 1 file changed, 6 insertions(+), 3 deletions(-)
-
-diff --git a/docs-xml/smbdotconf/filename/deletevetofiles.xml b/docs-xml/smbdotconf/filename/deletevetofiles.xml
-index 581dc05396d..570d4ac60a0 100644
---- a/docs-xml/smbdotconf/filename/deletevetofiles.xml
-+++ b/docs-xml/smbdotconf/filename/deletevetofiles.xml
-@@ -4,9 +4,12 @@
-                  xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
- <description>
- 	<para>This option is used when Samba is attempting to 
--	delete a directory that contains one or more vetoed directories 
--	(see the <smbconfoption name="veto files"/>
--	option).  If this option is set to <constant>no</constant> (the default) then if a vetoed 
-+	delete a directory that contains one or more vetoed files
-+	or directories or non-visible files or directories (such
-+	as dangling symlinks that point nowhere).
-+	(see the <smbconfoption name="veto files"/>, <smbconfoption name="hide special files"/>,
-+	<smbconfoption name="hide unreadable"/>, <smbconfoption name="hide unwriteable files"/>
-+	options).  If this option is set to <constant>no</constant> (the default) then if a vetoed
- 	directory contains any non-vetoed files or directories then the 
- 	directory delete will fail. This is usually what you want.</para>
- 
--- 
-2.33.1
-
diff --git a/SOURCES/samba-4.14-fix-domain-join-segfault.patch b/SOURCES/samba-4.14-fix-domain-join-segfault.patch
deleted file mode 100644
index 0521c27..0000000
--- a/SOURCES/samba-4.14-fix-domain-join-segfault.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From 0ef9fe22f56ef3ff202f88426c3ee48c15e4a71e Mon Sep 17 00:00:00 2001
-From: Ralph Boehme <slow@samba.org>
-Date: Fri, 26 Nov 2021 11:59:45 +0100
-Subject: [PATCH] smbd: s3-dsgetdcname: handle num_ips == 0
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14923
-
-Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>
-Signed-off-by: Ralph Boehme <slow@samba.org>
-Signed-off-by: Stefan Metzmacher <metze@samba.org>
-Reviewed-by: Guenther Deschner <gd@samba.org>
-Reviewed-by: Jeremy Allison <jra@samba.org>
-
-Autobuild-User(master): Stefan Metzmacher <metze@samba.org>
-Autobuild-Date(master): Fri Dec  3 12:54:04 UTC 2021 on sn-devel-184
-
-(cherry picked from commit 5e3df5f9ee64a80898f73585b19113354f463c44)
----
- source3/libsmb/dsgetdcname.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
-diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c
-index f8ae96109b71..5954e48d747b 100644
---- a/source3/libsmb/dsgetdcname.c
-+++ b/source3/libsmb/dsgetdcname.c
-@@ -572,6 +572,10 @@ static NTSTATUS discover_dc_dns(TALLOC_CTX *mem_ctx,
- 	for (i = 0; i < numdcs; i++) {
- 		size_t j;
- 
-+		if (dcs[i].num_ips == 0) {
-+			continue;
-+		}
-+
- 		dclist[ret_count].hostname =
- 			talloc_move(dclist, &dcs[i].hostname);
- 
--- 
-2.33.1
-
diff --git a/SOURCES/samba-4.14-fix-username-map-script.patch b/SOURCES/samba-4.14-fix-username-map-script.patch
deleted file mode 100644
index 8d7dcc8..0000000
--- a/SOURCES/samba-4.14-fix-username-map-script.patch
+++ /dev/null
@@ -1,227 +0,0 @@
-From 0e179b5f06988c576a1fff505c06920d51fe8ed4 Mon Sep 17 00:00:00 2001
-From: Stefan Metzmacher <metze@samba.org>
-Date: Fri, 12 Nov 2021 15:27:58 +0100
-Subject: [PATCH 1/3] CVE-2020-25727: idmap_nss: verify that the name of the
- sid belongs to the configured domain
-
-We already check the sid belongs to the domain, but checking the name
-too feels better and make it easier to understand.
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14901
-
-Signed-off-by: Stefan Metzmacher <metze@samba.org>
-Reviewed-by: Ralph Boehme <slow@samba.org>
-(cherry picked from commit bfd093648b4af51d104096c0cb3535e8706671e5)
----
- source3/winbindd/idmap_nss.c | 26 +++++++++++++++++++++-----
- 1 file changed, 21 insertions(+), 5 deletions(-)
-
-diff --git a/source3/winbindd/idmap_nss.c b/source3/winbindd/idmap_nss.c
-index da50e2b4aa7..2729a0de3f3 100644
---- a/source3/winbindd/idmap_nss.c
-+++ b/source3/winbindd/idmap_nss.c
-@@ -139,18 +139,21 @@ static NTSTATUS idmap_nss_sids_to_unixids(struct idmap_domain *dom, struct id_ma
- 	for (i = 0; ids[i]; i++) {
- 		struct group *gr;
- 		enum lsa_SidType type;
--		const char *p = NULL;
-+		const char *_domain = NULL;
-+		const char *_name = NULL;
-+		char *domain = NULL;
- 		char *name = NULL;
- 		bool ret;
- 
- 		/* by default calls to winbindd are disabled
- 		   the following call will not recurse so this is safe */
- 		(void)winbind_on();
--		ret = winbind_lookup_sid(talloc_tos(), ids[i]->sid, NULL,
--					 &p, &type);
-+		ret = winbind_lookup_sid(talloc_tos(),
-+					 ids[i]->sid,
-+					 &_domain,
-+					 &_name,
-+					 &type);
- 		(void)winbind_off();
--		name = discard_const_p(char, p);
--
- 		if (!ret) {
- 			/* TODO: how do we know if the name is really not mapped,
- 			 * or something just failed ? */
-@@ -158,6 +161,18 @@ static NTSTATUS idmap_nss_sids_to_unixids(struct idmap_domain *dom, struct id_ma
- 			continue;
- 		}
- 
-+		domain = discard_const_p(char, _domain);
-+		name = discard_const_p(char, _name);
-+
-+		if (!strequal(domain, dom->name)) {
-+			struct dom_sid_buf buf;
-+			DBG_ERR("DOMAIN[%s] ignoring SID[%s] belongs to %s [%s\\%s]\n",
-+			        dom->name, dom_sid_str_buf(ids[i]->sid, &buf),
-+				sid_type_lookup(type), domain, name);
-+			ids[i]->status = ID_UNMAPPED;
-+			continue;
-+		}
-+
- 		switch (type) {
- 		case SID_NAME_USER: {
- 			struct passwd *pw;
-@@ -190,6 +205,7 @@ static NTSTATUS idmap_nss_sids_to_unixids(struct idmap_domain *dom, struct id_ma
- 			ids[i]->status = ID_UNKNOWN;
- 			break;
- 		}
-+		TALLOC_FREE(domain);
- 		TALLOC_FREE(name);
- 	}
- 	return NT_STATUS_OK;
--- 
-2.34.1
-
-
-From 704ae4b8308e9ae6c50e3548f98de65e97ab6aa6 Mon Sep 17 00:00:00 2001
-From: Joseph Sutton <josephsutton@catalyst.net.nz>
-Date: Fri, 12 Nov 2021 20:53:30 +1300
-Subject: [PATCH 2/3] CVE-2020-25717: nsswitch/nsstest.c: Lower 'non existent
- uid' to make room for new accounts
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14901
-
-Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
-Reviewed-by: Stefan Metzmacher <metze@samba.org>
-Reviewed-by: Ralph Boehme <slow@samba.org>
-(cherry picked from commit fdbee5e074ebd76d659613b8b7114d70f938c38a)
----
- nsswitch/nsstest.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/nsswitch/nsstest.c b/nsswitch/nsstest.c
-index e2ee9fbf3af..45270cdc459 100644
---- a/nsswitch/nsstest.c
-+++ b/nsswitch/nsstest.c
-@@ -466,7 +466,7 @@ static void nss_test_errors(void)
- 		printf("ERROR Non existent user gave error %d\n", last_error);
- 	}
- 
--	pwd = getpwuid(0xFFF0);
-+	pwd = getpwuid(0xFF00);
- 	if (pwd || last_error != NSS_STATUS_NOTFOUND) {
- 		total_errors++;
- 		printf("ERROR Non existent uid gave error %d\n", last_error);
--- 
-2.34.1
-
-
-From 844723aa82cec67fd863fc327bde9fb04eab438d Mon Sep 17 00:00:00 2001
-From: Andrew Bartlett <abartlet@samba.org>
-Date: Fri, 12 Nov 2021 16:10:31 +1300
-Subject: [PATCH 3/3] CVE-2020-25717: s3:auth: Fallback to a SID/UID based
- mapping if the named based lookup fails
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Before the CVE-2020-25717 fixes we had a fallback from
-getpwnam('DOMAIN\user') to getpwnam('user') which was very dangerous and
-unpredictable.
-
-Now we do the fallback based on sid_to_uid() followed by
-getpwuid() on the returned uid.
-
-This obsoletes 'username map [script]' based workaround adviced
-for CVE-2020-25717, when nss_winbindd is not used or
-idmap_nss is actually used.
-
-In future we may decide to prefer or only do the SID/UID based
-lookup, but for now we want to keep this unchanged as much as possible.
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14901
-
-Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>
-
-Signed-off-by: Andrew Bartlett <abartlet@samba.org>
-Signed-off-by: Stefan Metzmacher <metze@samba.org>
-
-[metze@samba.org moved the new logic into the fallback codepath only
- in order to avoid behavior changes as much as possible]
-Reviewed-by: Ralph Boehme <slow@samba.org>
-
-Autobuild-User(master): Ralph Böhme <slow@samba.org>
-Autobuild-Date(master): Mon Nov 15 19:01:56 UTC 2021 on sn-devel-184
-
-(cherry picked from commit 0a546be05295a7e4a552f9f4f0c74aeb2e9a0d6e)
----
- source3/auth/auth_util.c | 34 +++++++++++++++++++++++++++++++++-
- 1 file changed, 33 insertions(+), 1 deletion(-)
-
-diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
-index 065b525500f..7a97dd45f11 100644
---- a/source3/auth/auth_util.c
-+++ b/source3/auth/auth_util.c
-@@ -1862,7 +1862,9 @@ const struct auth_session_info *get_session_info_system(void)
- ***************************************************************************/
- 
- static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain,
--			      const char *username, char **found_username,
-+			      const char *username,
-+			      const struct dom_sid *sid,
-+			      char **found_username,
- 			      struct passwd **pwd,
- 			      bool *username_was_mapped)
- {
-@@ -1897,6 +1899,31 @@ static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain,
- 	}
- 
- 	passwd = smb_getpwnam(mem_ctx, dom_user, &real_username, false);
-+	if (!passwd && !*username_was_mapped) {
-+		struct dom_sid_buf buf;
-+		uid_t uid;
-+		bool ok;
-+
-+		DBG_DEBUG("Failed to find authenticated user %s via "
-+			  "getpwnam(), fallback to sid_to_uid(%s).\n",
-+			  dom_user, dom_sid_str_buf(sid, &buf));
-+
-+		ok = sid_to_uid(sid, &uid);
-+		if (!ok) {
-+			DBG_ERR("Failed to convert SID %s to a UID (dom_user[%s])\n",
-+				dom_sid_str_buf(sid, &buf), dom_user);
-+			return NT_STATUS_NO_SUCH_USER;
-+		}
-+		passwd = getpwuid_alloc(mem_ctx, uid);
-+		if (!passwd) {
-+			DBG_ERR("Failed to find local account with UID %lld for SID %s (dom_user[%s])\n",
-+				(long long)uid,
-+				dom_sid_str_buf(sid, &buf),
-+				dom_user);
-+			return NT_STATUS_NO_SUCH_USER;
-+		}
-+		real_username = talloc_strdup(mem_ctx, passwd->pw_name);
-+	}
- 	if (!passwd) {
- 		DEBUG(3, ("Failed to find authenticated user %s via "
- 			  "getpwnam(), denying access.\n", dom_user));
-@@ -2042,6 +2069,7 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
- 	bool username_was_mapped;
- 	struct passwd *pwd;
- 	struct auth_serversupplied_info *result;
-+	struct dom_sid sid;
- 	TALLOC_CTX *tmp_ctx = talloc_stackframe();
- 
- 	/* 
-@@ -2088,9 +2116,13 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
- 
- 	/* this call will try to create the user if necessary */
- 
-+	sid_copy(&sid, info3->base.domain_sid);
-+	sid_append_rid(&sid, info3->base.rid);
-+
- 	nt_status = check_account(tmp_ctx,
- 				  nt_domain,
- 				  nt_username,
-+				  &sid,
- 				  &found_username,
- 				  &pwd,
- 				  &username_was_mapped);
--- 
-2.34.1
-
diff --git a/SOURCES/samba-4.14-fix-virus-scanner.patch b/SOURCES/samba-4.14-fix-virus-scanner.patch
deleted file mode 100644
index 515c642..0000000
--- a/SOURCES/samba-4.14-fix-virus-scanner.patch
+++ /dev/null
@@ -1,563 +0,0 @@
-From e4baa05c6f73b364843f0ddd5394bf4298aca0d7 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Pavel=20Filipensk=C3=BD?= <pfilipen@redhat.com>
-Date: Tue, 8 Feb 2022 12:07:03 +0100
-Subject: [PATCH 1/5] s3:modules: Implement dummy virus scanner that uses
- filename matching
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Bug: https://bugzilla.samba.org/show_bug.cgi?id=14971
-
-Signed-off-by: Pavel Filipenský <pfilipen@redhat.com>
-Reviewed-by: Jeremy Allison <jra@samba.org>
-Reviewed-by: Andreas Schneider <asn@samba.org>
-(cherry picked from commit 9f34babec7c6aca3d91f226705d3b3996792e5f1)
----
- source3/modules/vfs_virusfilter.c        | 12 +++++
- source3/modules/vfs_virusfilter_common.h |  4 ++
- source3/modules/vfs_virusfilter_dummy.c  | 58 ++++++++++++++++++++++++
- source3/modules/wscript_build            |  1 +
- 4 files changed, 75 insertions(+)
- create mode 100644 source3/modules/vfs_virusfilter_dummy.c
-
-diff --git a/source3/modules/vfs_virusfilter.c b/source3/modules/vfs_virusfilter.c
-index 524e7dfbad9..5ae8a02a369 100644
---- a/source3/modules/vfs_virusfilter.c
-+++ b/source3/modules/vfs_virusfilter.c
-@@ -35,12 +35,14 @@
- 
- enum virusfilter_scanner_enum {
- 	VIRUSFILTER_SCANNER_CLAMAV,
-+	VIRUSFILTER_SCANNER_DUMMY,
- 	VIRUSFILTER_SCANNER_FSAV,
- 	VIRUSFILTER_SCANNER_SOPHOS
- };
- 
- static const struct enum_list scanner_list[] = {
- 	{ VIRUSFILTER_SCANNER_CLAMAV,	"clamav" },
-+	{ VIRUSFILTER_SCANNER_DUMMY,	"dummy" },
- 	{ VIRUSFILTER_SCANNER_FSAV,	"fsav" },
- 	{ VIRUSFILTER_SCANNER_SOPHOS,	"sophos" },
- 	{ -1,				NULL }
-@@ -199,6 +201,7 @@ static int virusfilter_vfs_connect(
- 	int snum = SNUM(handle->conn);
- 	struct virusfilter_config *config = NULL;
- 	const char *exclude_files = NULL;
-+	const char *infected_files = NULL;
- 	const char *temp_quarantine_dir_mode = NULL;
- 	const char *infected_file_command = NULL;
- 	const char *scan_error_command = NULL;
-@@ -255,6 +258,12 @@ static int virusfilter_vfs_connect(
- 		set_namearray(&config->exclude_files, exclude_files);
- 	}
- 
-+	infected_files = lp_parm_const_string(
-+		snum, "virusfilter", "infected files", NULL);
-+	if (infected_files != NULL) {
-+		set_namearray(&config->infected_files, infected_files);
-+	}
-+
- 	config->cache_entry_limit = lp_parm_int(
- 		snum, "virusfilter", "cache entry limit", 100);
- 
-@@ -532,6 +541,9 @@ static int virusfilter_vfs_connect(
- 	case VIRUSFILTER_SCANNER_CLAMAV:
- 		ret = virusfilter_clamav_init(config);
- 		break;
-+	case VIRUSFILTER_SCANNER_DUMMY:
-+		ret = virusfilter_dummy_init(config);
-+		break;
- 	default:
- 		DBG_ERR("Unhandled scanner %d\n", backend);
- 		return -1;
-diff --git a/source3/modules/vfs_virusfilter_common.h b/source3/modules/vfs_virusfilter_common.h
-index f71b0b949a7..463a9d74e9c 100644
---- a/source3/modules/vfs_virusfilter_common.h
-+++ b/source3/modules/vfs_virusfilter_common.h
-@@ -83,6 +83,9 @@ struct virusfilter_config {
- 	/* Exclude files */
- 	name_compare_entry		*exclude_files;
- 
-+	/* Infected files */
-+	name_compare_entry		*infected_files;
-+
- 	/* Scan result cache */
- 	struct virusfilter_cache	*cache;
- 	int				cache_entry_limit;
-@@ -149,5 +152,6 @@ struct virusfilter_backend {
- int virusfilter_sophos_init(struct virusfilter_config *config);
- int virusfilter_fsav_init(struct virusfilter_config *config);
- int virusfilter_clamav_init(struct virusfilter_config *config);
-+int virusfilter_dummy_init(struct virusfilter_config *config);
- 
- #endif /* _VIRUSFILTER_COMMON_H */
-diff --git a/source3/modules/vfs_virusfilter_dummy.c b/source3/modules/vfs_virusfilter_dummy.c
-new file mode 100644
-index 00000000000..03405cd6629
---- /dev/null
-+++ b/source3/modules/vfs_virusfilter_dummy.c
-@@ -0,0 +1,58 @@
-+/*
-+   Samba-VirusFilter VFS modules
-+   Dummy scanner with infected files support.
-+   Copyright (C) 2022 Pavel Filipenský <pfilipen@redhat.com>
-+
-+   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 "modules/vfs_virusfilter_utils.h"
-+
-+static virusfilter_result virusfilter_dummy_scan(
-+	struct vfs_handle_struct *handle,
-+	struct virusfilter_config *config,
-+	const struct files_struct *fsp,
-+	char **reportp)
-+{
-+	bool ok;
-+
-+	DBG_INFO("Scanning file: %s\n", fsp_str_dbg(fsp));
-+	ok = is_in_path(fsp->fsp_name->base_name,
-+			config->infected_files,
-+			false);
-+	return ok ? VIRUSFILTER_RESULT_INFECTED : VIRUSFILTER_RESULT_CLEAN;
-+}
-+
-+static struct virusfilter_backend_fns virusfilter_backend_dummy = {
-+	.connect = NULL,
-+	.disconnect = NULL,
-+	.scan_init = NULL,
-+	.scan = virusfilter_dummy_scan,
-+	.scan_end = NULL,
-+};
-+
-+int virusfilter_dummy_init(struct virusfilter_config *config)
-+{
-+	struct virusfilter_backend *backend = NULL;
-+
-+	backend = talloc_zero(config, struct virusfilter_backend);
-+	if (backend == NULL) {
-+		return -1;
-+	}
-+
-+	backend->fns = &virusfilter_backend_dummy;
-+	backend->name = "dummy";
-+	config->backend = backend;
-+	return 0;
-+}
-diff --git a/source3/modules/wscript_build b/source3/modules/wscript_build
-index 36b047ef79b..444a16f2cc0 100644
---- a/source3/modules/wscript_build
-+++ b/source3/modules/wscript_build
-@@ -598,6 +598,7 @@ bld.SAMBA3_MODULE('vfs_virusfilter',
-                  vfs_virusfilter_sophos.c
-                  vfs_virusfilter_fsav.c
-                  vfs_virusfilter_clamav.c
-+                 vfs_virusfilter_dummy.c
-                  ''',
-                  deps='samba-util VFS_VIRUSFILTER_UTILS',
-                  init_function='',
--- 
-2.34.1
-
-
-From f3c9a2e7c524b25558550ed7fb1b7778975a3f2b Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Pavel=20Filipensk=C3=BD?= <pfilipen@redhat.com>
-Date: Tue, 8 Feb 2022 22:35:29 +0100
-Subject: [PATCH 2/5] docs-xml:manpages: Document 'dummy' virusfilter and
- 'virusfilter:infected files'
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Bug: https://bugzilla.samba.org/show_bug.cgi?id=14971
-
-Signed-off-by: Pavel Filipenský <pfilipen@redhat.com>
-Reviewed-by: Jeremy Allison <jra@samba.org>
-Reviewed-by: Andreas Schneider <asn@samba.org>
-(cherry picked from commit 2fd518e5cc63221c162c9b3f8526b9b7c9e34969)
----
- docs-xml/manpages/vfs_virusfilter.8.xml | 12 ++++++++++++
- 1 file changed, 12 insertions(+)
-
-diff --git a/docs-xml/manpages/vfs_virusfilter.8.xml b/docs-xml/manpages/vfs_virusfilter.8.xml
-index 329a35af68a..88f91d73a42 100644
---- a/docs-xml/manpages/vfs_virusfilter.8.xml
-+++ b/docs-xml/manpages/vfs_virusfilter.8.xml
-@@ -48,6 +48,10 @@
- 		  scanner</para></listitem>
- 		  <listitem><para><emphasis>clamav</emphasis>, the ClamAV
- 		  scanner</para></listitem>
-+		  <listitem><para><emphasis>dummy</emphasis>, dummy scanner used in
-+		  tests. Checks against the <emphasis>infected files</emphasis>
-+		  parameter and flags any name that matches as infected.
-+		  </para></listitem>
- 		</itemizedlist>
- 		</listitem>
- 		</varlistentry>
-@@ -264,6 +268,14 @@
- 		</listitem>
- 		</varlistentry>
- 
-+		<varlistentry>
-+		<term>virusfilter:infected files = empty</term>
-+		<listitem>
-+		<para>Files that virusfilter <emphasis>dummy</emphasis> flags as infected.</para>
-+		<para>If this option is not set, the default is empty.</para>
-+		</listitem>
-+		</varlistentry>
-+
- 		<varlistentry>
- 		<term>virusfilter:block access on error = false</term>
- 		<listitem>
--- 
-2.34.1
-
-
-From 3758a9612862c88a17ed20787b60346859c03eea Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Pavel=20Filipensk=C3=BD?= <pfilipen@redhat.com>
-Date: Tue, 8 Feb 2022 15:34:56 +0100
-Subject: [PATCH 3/5] selftest: Fix trailing whitespace in Samba3.pm
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Bug: https://bugzilla.samba.org/show_bug.cgi?id=14971
-
-Signed-off-by: Pavel Filipenský <pfilipen@redhat.com>
-Reviewed-by: Jeremy Allison <jra@samba.org>
-Reviewed-by: Andreas Schneider <asn@samba.org>
-(cherry picked from commit 547b4c595a8513a4be99177edbaa39ce43840f7a)
----
- selftest/target/Samba3.pm | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
-index 9a8c9ee2604..306783931e0 100755
---- a/selftest/target/Samba3.pm
-+++ b/selftest/target/Samba3.pm
-@@ -188,7 +188,7 @@ sub getlog_env_app($$$)
- 	close(LOG);
- 
- 	return "" if $out eq $title;
-- 
-+
- 	return $out;
- }
- 
-@@ -2205,7 +2205,7 @@ sub provision($$)
- 	my $nmbdsockdir="$prefix_abs/nmbd";
- 	unlink($nmbdsockdir);
- 
--	## 
-+	##
- 	## create the test directory layout
- 	##
- 	die ("prefix_abs = ''") if $prefix_abs eq "";
-@@ -3057,7 +3057,7 @@ sub provision($$)
- 	unless (open(PASSWD, ">$nss_wrapper_passwd")) {
-            warn("Unable to open $nss_wrapper_passwd");
-            return undef;
--        } 
-+        }
- 	print PASSWD "nobody:x:$uid_nobody:$gid_nobody:nobody gecos:$prefix_abs:/bin/false
- $unix_name:x:$unix_uid:$unix_gids[0]:$unix_name gecos:$prefix_abs:/bin/false
- pdbtest:x:$uid_pdbtest:$gid_nogroup:pdbtest gecos:$prefix_abs:/bin/false
--- 
-2.34.1
-
-
-From e92fbd282c584cadcd0ed513c414b5377282ed64 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Pavel=20Filipensk=C3=BD?= <pfilipen@redhat.com>
-Date: Tue, 8 Feb 2022 15:35:48 +0100
-Subject: [PATCH 4/5] s3:selftest: Add test for virus scanner
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Bug: https://bugzilla.samba.org/show_bug.cgi?id=14971
-
-Signed-off-by: Pavel Filipenský <pfilipen@redhat.com>
-
-Pair-Programmed-With: Andreas Schneider <asn@samba.org>
-Reviewed-by: Jeremy Allison <jra@samba.org>
-Reviewed-by: Andreas Schneider <asn@samba.org>
-(cherry picked from commit a25c714c34d3e00e0f3c29d2acfa98cf9cdbc544)
----
- selftest/knownfail.d/virus_scanner         |   2 +
- selftest/target/Samba3.pm                  |  12 ++
- source3/script/tests/test_virus_scanner.sh | 124 +++++++++++++++++++++
- source3/selftest/tests.py                  |   9 ++
- 4 files changed, 147 insertions(+)
- create mode 100644 selftest/knownfail.d/virus_scanner
- create mode 100755 source3/script/tests/test_virus_scanner.sh
-
-diff --git a/selftest/knownfail.d/virus_scanner b/selftest/knownfail.d/virus_scanner
-new file mode 100644
-index 00000000000..6df3fd20627
---- /dev/null
-+++ b/selftest/knownfail.d/virus_scanner
-@@ -0,0 +1,2 @@
-+^samba3.blackbox.virus_scanner.check_infected_read  # test download infected file ('vfs objects = virusfilter')
-+^samba3.blackbox.virus_scanner.check_infected_write # test upload infected file ('vfs objects = virusfilter')
-diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
-index 306783931e0..baec3347c7d 100755
---- a/selftest/target/Samba3.pm
-+++ b/selftest/target/Samba3.pm
-@@ -1463,6 +1463,9 @@ sub setup_fileserver
- 	my $veto_sharedir="$share_dir/veto";
- 	push(@dirs,$veto_sharedir);
- 
-+	my $virusfilter_sharedir="$share_dir/virusfilter";
-+	push(@dirs,$virusfilter_sharedir);
-+
- 	my $ip4 = Samba::get_ipv4_addr("FILESERVER");
- 	my $fileserver_options = "
- 	kernel change notify = yes
-@@ -1588,6 +1591,15 @@ sub setup_fileserver
- 	path = $veto_sharedir
- 	delete veto files = yes
- 
-+[virusfilter]
-+	path = $virusfilter_sharedir
-+	vfs objects = acl_xattr virusfilter
-+	virusfilter:scanner = dummy
-+	virusfilter:min file size = 0
-+	virusfilter:infected files = *infected*
-+	virusfilter:infected file action = rename
-+	virusfilter:scan on close = yes
-+
- [homes]
- 	comment = Home directories
- 	browseable = No
-diff --git a/source3/script/tests/test_virus_scanner.sh b/source3/script/tests/test_virus_scanner.sh
-new file mode 100755
-index 00000000000..2234ea6ca89
---- /dev/null
-+++ b/source3/script/tests/test_virus_scanner.sh
-@@ -0,0 +1,124 @@
-+#!/bin/sh
-+# Copyright (c) 2022      Pavel Filipenský <pfilipen@redhat.com>
-+# shellcheck disable=1091
-+
-+if [ $# -lt 4 ]; then
-+cat <<EOF
-+Usage: $0 SERVER_IP SHARE LOCAL_PATH SMBCLIENT
-+EOF
-+exit 1;
-+fi
-+
-+SERVER_IP=${1}
-+SHARE=${2}
-+LOCAL_PATH=${3}
-+SMBCLIENT=${4}
-+
-+SMBCLIENT="${VALGRIND} ${SMBCLIENT}"
-+
-+failed=0
-+sharedir="${LOCAL_PATH}/${SHARE}"
-+
-+incdir="$(dirname "$0")/../../../testprogs/blackbox"
-+. "${incdir}/subunit.sh"
-+
-+check_infected_read()
-+{
-+    rm -rf "${sharedir:?}"/*
-+
-+    if ! touch "${sharedir}/infected.txt"; then
-+        echo "ERROR: Cannot create ${sharedir}/infected.txt"
-+        return 1
-+    fi
-+
-+    ${SMBCLIENT} "//${SERVER_IP}/${SHARE}" -U"${USER}"%"${PASSWORD}" -c "get infected.txt ${sharedir}/infected.download.txt"
-+
-+    # check that virusfilter:rename prefix/suffix was added
-+    if [ ! -f "${sharedir}/virusfilter.infected.txt.infected" ]; then
-+        echo "ERROR: ${sharedir}/virusfilter.infected.txt.infected is missing."
-+        return 1
-+    fi
-+
-+    # check that file was not downloaded
-+    if [ -f "${sharedir}/infected.download.txt" ]; then
-+        echo "ERROR: {sharedir}/infected.download.txt should not exist."
-+        return 1
-+    fi
-+
-+    return 0
-+}
-+
-+check_infected_write()
-+{
-+    rm -rf "${sharedir:?}"/*
-+    smbfile=infected.upload.txt
-+    smbfilerenamed="virusfilter.${smbfile}.infected"
-+
-+    # non empty file is needed
-+    # vsf_virusfilter performs a scan only if fsp->fsp_flags.modified
-+    if ! echo "Hello Virus!" > "${sharedir}/infected.txt"; then
-+        echo "ERROR: Cannot create ${sharedir}/infected.txt"
-+        return 1
-+    fi
-+
-+    ${SMBCLIENT} "//${SERVER_IP}/${SHARE}" -U"${USER}"%"${PASSWORD}" -c "put ${sharedir}/infected.txt ${smbfile}"
-+
-+    # check that virusfilter:rename prefix/suffix was added
-+    if [ ! -f "${sharedir}/${smbfilerenamed}" ]; then
-+        echo "ERROR: ${sharedir}/${smbfilerenamed} is missing."
-+        return 1
-+    fi
-+
-+    # check that file was not uploaded
-+    if [ -f "${sharedir}/infected.upload.txt" ]; then
-+        echo "ERROR: {sharedir}/${smbfile} should not exist."
-+        return 1
-+    fi
-+
-+    return 0
-+}
-+
-+check_healthy_read()
-+{
-+    rm -rf "${sharedir:?}"/*
-+
-+    if ! echo "Hello Samba!" > "${sharedir}/healthy.txt"; then
-+        echo "ERROR: Cannot create ${sharedir}/healthy.txt"
-+        return 1
-+    fi
-+
-+    ${SMBCLIENT} //"${SERVER_IP}"/"${SHARE}" -U"${USER}"%"${PASSWORD}" -c "get healthy.txt ${sharedir}/healthy.download.txt"
-+
-+    if ! cmp "${sharedir}/healthy.txt" "${sharedir}/healthy.download.txt"; then
-+        echo "ERROR: cmp ${sharedir}/healthy.txt ${sharedir}/healthy.download.txt FAILED"
-+        return 1
-+    fi
-+
-+    return 0
-+}
-+
-+check_healthy_write()
-+{
-+    rm -rf "${sharedir:?}"/*
-+
-+    if ! echo "Hello Samba!" > "${sharedir}/healthy.txt"; then
-+        echo "ERROR: Cannot create ${sharedir}/healthy.txt"
-+        return 1
-+    fi
-+
-+    ${SMBCLIENT} //"${SERVER_IP}"/"${SHARE}" -U"${USER}"%"${PASSWORD}" -c "put ${sharedir}/healthy.txt healthy.upload.txt"
-+
-+    if ! cmp "${sharedir}/healthy.txt" "${sharedir}/healthy.upload.txt"; then
-+        echo "ERROR: cmp ${sharedir}/healthy.txt ${sharedir}/healthy.upload.txt FAILED"
-+        return 1
-+    fi
-+
-+    return 0
-+}
-+
-+testit "check_infected_read"  check_infected_read  || failed=$((failed + 1))
-+testit "check_infected_write" check_infected_write || failed=$((failed + 1))
-+testit "check_healthy_read"   check_healthy_read   || failed=$((failed + 1))
-+testit "check_healthy_write"  check_healthy_write  || failed=$((failed + 1))
-+
-+testok "$0" "$failed"
-diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
-index c78c9ea4ab8..3c8976874e6 100755
---- a/source3/selftest/tests.py
-+++ b/source3/selftest/tests.py
-@@ -1113,6 +1113,15 @@ plantestsuite("samba3.blackbox.smbclient.encryption_off", "simpleserver",
-                "$USERNAME", "$PASSWORD", "$SERVER",
-                smbclient3])
- 
-+env = 'fileserver'
-+plantestsuite("samba3.blackbox.virus_scanner", "%s:local" % (env),
-+              [os.path.join(samba3srcdir,
-+                            "script/tests/test_virus_scanner.sh"),
-+               '$SERVER_IP',
-+               "virusfilter",
-+               '$LOCAL_PATH',
-+               smbclient3])
-+
- for env in ['fileserver', 'simpleserver']:
-     plantestsuite("samba3.blackbox.smbclient.encryption", env,
-                   [os.path.join(samba3srcdir, "script/tests/test_smbclient_encryption.sh"),
--- 
-2.34.1
-
-
-From 3e1a57b6d8528d7aa4c46b8ac76bff034523b273 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Pavel=20Filipensk=C3=BD?= <pfilipen@redhat.com>
-Date: Mon, 7 Feb 2022 23:06:10 +0100
-Subject: [PATCH 5/5] s3:modules: Fix virusfilter_vfs_openat
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Bug: https://bugzilla.samba.org/show_bug.cgi?id=14971
-
-Signed-off-by: Pavel Filipenský <pfilipen@redhat.com>
-
-Pair-Programmed-With: Andreas Schneider <asn@samba.org>
-Reviewed-by: Jeremy Allison <jra@samba.org>
-Reviewed-by: Andreas Schneider <asn@samba.org>
-
-Autobuild-User(master): Jeremy Allison <jra@samba.org>
-Autobuild-Date(master): Thu Feb 10 22:09:06 UTC 2022 on sn-devel-184
-
-(cherry picked from commit 3f1c958f6fa9d2991185f4e281a377a295d09f9c)
----
- selftest/knownfail.d/virus_scanner | 2 --
- source3/modules/vfs_virusfilter.c  | 6 +++---
- 2 files changed, 3 insertions(+), 5 deletions(-)
- delete mode 100644 selftest/knownfail.d/virus_scanner
-
-diff --git a/selftest/knownfail.d/virus_scanner b/selftest/knownfail.d/virus_scanner
-deleted file mode 100644
-index 6df3fd20627..00000000000
---- a/selftest/knownfail.d/virus_scanner
-+++ /dev/null
-@@ -1,2 +0,0 @@
--^samba3.blackbox.virus_scanner.check_infected_read  # test download infected file ('vfs objects = virusfilter')
--^samba3.blackbox.virus_scanner.check_infected_write # test upload infected file ('vfs objects = virusfilter')
-diff --git a/source3/modules/vfs_virusfilter.c b/source3/modules/vfs_virusfilter.c
-index 5ae8a02a369..8c7e5323341 100644
---- a/source3/modules/vfs_virusfilter.c
-+++ b/source3/modules/vfs_virusfilter.c
-@@ -1304,21 +1304,21 @@ static int virusfilter_vfs_openat(struct vfs_handle_struct *handle,
- 		 */
- 		goto virusfilter_vfs_open_next;
- 	}
--	ret = S_ISREG(smb_fname->st.st_ex_mode);
-+	ret = S_ISREG(sbuf.st_ex_mode);
- 	if (ret == 0) {
- 		DBG_INFO("Not scanned: Directory or special file: %s/%s\n",
- 			 cwd_fname, fname);
- 		goto virusfilter_vfs_open_next;
- 	}
- 	if (config->max_file_size > 0 &&
--	    smb_fname->st.st_ex_size > config->max_file_size)
-+	    sbuf.st_ex_size > config->max_file_size)
- 	{
- 		DBG_INFO("Not scanned: file size > max file size: %s/%s\n",
- 			 cwd_fname, fname);
- 		goto virusfilter_vfs_open_next;
- 	}
- 	if (config->min_file_size > 0 &&
--	    smb_fname->st.st_ex_size < config->min_file_size)
-+	    sbuf.st_ex_size < config->min_file_size)
- 	{
- 		DBG_INFO("Not scanned: file size < min file size: %s/%s\n",
- 		      cwd_fname, fname);
--- 
-2.34.1
-
diff --git a/SOURCES/samba-4.14-fix-winbind-no-trusted-domain.patch b/SOURCES/samba-4.14-fix-winbind-no-trusted-domain.patch
deleted file mode 100644
index 4924872..0000000
--- a/SOURCES/samba-4.14-fix-winbind-no-trusted-domain.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From 2edaf32b4204b9fe363c441c25b6989fe76911a4 Mon Sep 17 00:00:00 2001
-From: Stefan Metzmacher <metze@samba.org>
-Date: Tue, 9 Nov 2021 20:50:20 +0100
-Subject: [PATCH] s3:winbindd: fix "allow trusted domains = no" regression
-
-add_trusted_domain() should only reject domains
-based on is_allowed_domain(), which now also
-checks "allow trusted domains = no", if we don't
-have an explicit trust to the domain (SEC_CHAN_NULL).
-
-We use at least SEC_CHAN_LOCAL for local domains like
-BUILTIN.
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14899
-
-Signed-off-by: Stefan Metzmacher <metze@samba.org>
-
-Autobuild-User(master): Stefan Metzmacher <metze@samba.org>
-Autobuild-Date(master): Wed Nov 10 11:21:31 UTC 2021 on sn-devel-184
-
-(cherry picked from commit a7f6c60cb037b4bc9eee276236539b8282213935)
----
- source3/winbindd/winbindd_util.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c
-index 42ddbfd2f44..9d54e462c42 100644
---- a/source3/winbindd/winbindd_util.c
-+++ b/source3/winbindd/winbindd_util.c
-@@ -134,7 +134,7 @@ static NTSTATUS add_trusted_domain(const char *domain_name,
- 		return NT_STATUS_INVALID_PARAMETER;
- 	}
- 
--	if (!is_allowed_domain(domain_name)) {
-+	if (secure_channel_type == SEC_CHAN_NULL && !is_allowed_domain(domain_name)) {
- 		return NT_STATUS_NO_SUCH_DOMAIN;
- 	}
- 
--- 
-2.33.1
-
diff --git a/SOURCES/samba-4.14-krb5pac.patch b/SOURCES/samba-4.14-krb5pac.patch
deleted file mode 100644
index ff3e1ca..0000000
--- a/SOURCES/samba-4.14-krb5pac.patch
+++ /dev/null
@@ -1,298 +0,0 @@
-From 97829843013e2f0d81b6ed61d155a04217e40205 Mon Sep 17 00:00:00 2001
-From: Joseph Sutton <josephsutton@catalyst.net.nz>
-Date: Wed, 1 Sep 2021 15:39:19 +1200
-Subject: [PATCH 1/6] krb5pac.idl: Add ticket checksum PAC buffer type
-
-Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
-Reviewed-by: Andrew Bartlett <abartlet@samba.org>
-Reviewed-by: Isaac Boukris <iboukris@samba.org>
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881
-(cherry picked from commit ff2f38fae79220e16765e17671972f9a55eb7cce)
----
- librpc/idl/krb5pac.idl | 4 +++-
- 1 file changed, 3 insertions(+), 1 deletion(-)
-
-diff --git a/librpc/idl/krb5pac.idl b/librpc/idl/krb5pac.idl
-index fb360c1257f..3239d7656b6 100644
---- a/librpc/idl/krb5pac.idl
-+++ b/librpc/idl/krb5pac.idl
-@@ -112,7 +112,8 @@ interface krb5pac
- 		PAC_TYPE_KDC_CHECKSUM = 7,
- 		PAC_TYPE_LOGON_NAME = 10,
- 		PAC_TYPE_CONSTRAINED_DELEGATION = 11,
--		PAC_TYPE_UPN_DNS_INFO = 12
-+		PAC_TYPE_UPN_DNS_INFO = 12,
-+		PAC_TYPE_TICKET_CHECKSUM = 16
- 	} PAC_TYPE;
- 
- 	typedef struct {
-@@ -128,6 +129,7 @@ interface krb5pac
- 		[case(PAC_TYPE_CONSTRAINED_DELEGATION)][subcontext(0xFFFFFC01)]
- 			PAC_CONSTRAINED_DELEGATION_CTR constrained_delegation;
- 		[case(PAC_TYPE_UPN_DNS_INFO)]	PAC_UPN_DNS_INFO upn_dns_info;
-+		[case(PAC_TYPE_TICKET_CHECKSUM)]	PAC_SIGNATURE_DATA ticket_checksum;
- 		/* when new PAC info types are added they are supposed to be done
- 		   in such a way that they are backwards compatible with existing
- 		   servers. This makes it safe to just use a [default] for
--- 
-2.33.1
-
-
-From 99cc0e06e5fe2776371b808432af39de00f76cdf Mon Sep 17 00:00:00 2001
-From: Joseph Sutton <josephsutton@catalyst.net.nz>
-Date: Wed, 1 Sep 2021 15:40:59 +1200
-Subject: [PATCH 2/6] security.idl: Add well-known SIDs for FAST
-
-Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
-Reviewed-by: Andrew Bartlett <abartlet@samba.org>
-Reviewed-by: Isaac Boukris <iboukris@samba.org>
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881
-(cherry picked from commit 0092b4a3ed58b2c256d4dd9117cce927a3edde12)
----
- librpc/idl/security.idl | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/librpc/idl/security.idl b/librpc/idl/security.idl
-index 06bf7449a70..3df96dedbdd 100644
---- a/librpc/idl/security.idl
-+++ b/librpc/idl/security.idl
-@@ -295,6 +295,9 @@ interface security
- 	const string SID_AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY = "S-1-18-1";
- 	const string SID_SERVICE_ASSERTED_IDENTITY = "S-1-18-2";
- 
-+	const string SID_COMPOUNDED_AUTHENTICATION = "S-1-5-21-0-0-0-496";
-+	const string SID_CLAIMS_VALID = "S-1-5-21-0-0-0-497";
-+
- 	/*
- 	 * http://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
- 	 */
--- 
-2.33.1
-
-
-From 693bcdb2f9b64af390d619c9b39293c581900151 Mon Sep 17 00:00:00 2001
-From: Joseph Sutton <josephsutton@catalyst.net.nz>
-Date: Wed, 29 Sep 2021 16:15:26 +1300
-Subject: [PATCH 3/6] krb5pac.idl: Add missing buffer type values
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642
-
-Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
-Reviewed-by: Andrew Bartlett <abartlet@samba.org>
-Backported-by: Andreas Schneider <asn@samba.org>
----
- librpc/idl/krb5pac.idl | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/librpc/idl/krb5pac.idl b/librpc/idl/krb5pac.idl
-index 3239d7656b6..515150ab9cd 100644
---- a/librpc/idl/krb5pac.idl
-+++ b/librpc/idl/krb5pac.idl
-@@ -113,6 +113,9 @@ interface krb5pac
- 		PAC_TYPE_LOGON_NAME = 10,
- 		PAC_TYPE_CONSTRAINED_DELEGATION = 11,
- 		PAC_TYPE_UPN_DNS_INFO = 12,
-+		PAC_TYPE_CLIENT_CLAIMS_INFO = 13,
-+		PAC_TYPE_DEVICE_INFO = 14,
-+		PAC_TYPE_DEVICE_CLAIMS_INFO = 15,
- 		PAC_TYPE_TICKET_CHECKSUM = 16
- 	} PAC_TYPE;
- 
--- 
-2.33.1
-
-
-From 97323751c1b6b97e72eb80b8b99485d94696b30b Mon Sep 17 00:00:00 2001
-From: Joseph Sutton <josephsutton@catalyst.net.nz>
-Date: Tue, 26 Oct 2021 20:33:38 +1300
-Subject: [PATCH 4/6] CVE-2020-25719 krb5pac.idl: Add PAC_ATTRIBUTES_INFO PAC
- buffer type
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561
-
-Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
-Reviewed-by: Andrew Bartlett <abartlet@samba.org>
----
- librpc/idl/krb5pac.idl | 14 +++++++++++++-
- 1 file changed, 13 insertions(+), 1 deletion(-)
-
-diff --git a/librpc/idl/krb5pac.idl b/librpc/idl/krb5pac.idl
-index 515150ab9cd..7a8d16464eb 100644
---- a/librpc/idl/krb5pac.idl
-+++ b/librpc/idl/krb5pac.idl
-@@ -97,6 +97,16 @@ interface krb5pac
- 		PAC_UPN_DNS_FLAGS flags;
- 	} PAC_UPN_DNS_INFO;
- 
-+	typedef [bitmap32bit] bitmap {
-+		PAC_ATTRIBUTE_FLAG_PAC_WAS_REQUESTED = 0x00000001,
-+		PAC_ATTRIBUTE_FLAG_PAC_WAS_GIVEN_IMPLICITLY = 0x00000002
-+	} PAC_ATTRIBUTE_INFO_FLAGS;
-+
-+	typedef struct {
-+		uint32 flags_length; /* length in bits */
-+		PAC_ATTRIBUTE_INFO_FLAGS flags;
-+	} PAC_ATTRIBUTES_INFO;
-+
- 	typedef [public] struct {
- 		PAC_LOGON_INFO *info;
- 	} PAC_LOGON_INFO_CTR;
-@@ -116,7 +126,8 @@ interface krb5pac
- 		PAC_TYPE_CLIENT_CLAIMS_INFO = 13,
- 		PAC_TYPE_DEVICE_INFO = 14,
- 		PAC_TYPE_DEVICE_CLAIMS_INFO = 15,
--		PAC_TYPE_TICKET_CHECKSUM = 16
-+		PAC_TYPE_TICKET_CHECKSUM = 16,
-+		PAC_TYPE_ATTRIBUTES_INFO = 17
- 	} PAC_TYPE;
- 
- 	typedef struct {
-@@ -133,6 +144,7 @@ interface krb5pac
- 			PAC_CONSTRAINED_DELEGATION_CTR constrained_delegation;
- 		[case(PAC_TYPE_UPN_DNS_INFO)]	PAC_UPN_DNS_INFO upn_dns_info;
- 		[case(PAC_TYPE_TICKET_CHECKSUM)]	PAC_SIGNATURE_DATA ticket_checksum;
-+		[case(PAC_TYPE_ATTRIBUTES_INFO)]	PAC_ATTRIBUTES_INFO attributes_info;
- 		/* when new PAC info types are added they are supposed to be done
- 		   in such a way that they are backwards compatible with existing
- 		   servers. This makes it safe to just use a [default] for
--- 
-2.33.1
-
-
-From 9867beabf3b0be026d900e26ac91af655fb50cfe Mon Sep 17 00:00:00 2001
-From: Joseph Sutton <josephsutton@catalyst.net.nz>
-Date: Tue, 26 Oct 2021 20:33:49 +1300
-Subject: [PATCH 5/6] CVE-2020-25719 krb5pac.idl: Add PAC_REQUESTER_SID PAC
- buffer type
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561
-
-Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
-Reviewed-by: Andrew Bartlett <abartlet@samba.org>
----
- librpc/idl/krb5pac.idl | 8 +++++++-
- 1 file changed, 7 insertions(+), 1 deletion(-)
-
-diff --git a/librpc/idl/krb5pac.idl b/librpc/idl/krb5pac.idl
-index 7a8d16464eb..52fb40c4bbb 100644
---- a/librpc/idl/krb5pac.idl
-+++ b/librpc/idl/krb5pac.idl
-@@ -107,6 +107,10 @@ interface krb5pac
- 		PAC_ATTRIBUTE_INFO_FLAGS flags;
- 	} PAC_ATTRIBUTES_INFO;
- 
-+	typedef struct {
-+		dom_sid sid;
-+	} PAC_REQUESTER_SID;
-+
- 	typedef [public] struct {
- 		PAC_LOGON_INFO *info;
- 	} PAC_LOGON_INFO_CTR;
-@@ -127,7 +131,8 @@ interface krb5pac
- 		PAC_TYPE_DEVICE_INFO = 14,
- 		PAC_TYPE_DEVICE_CLAIMS_INFO = 15,
- 		PAC_TYPE_TICKET_CHECKSUM = 16,
--		PAC_TYPE_ATTRIBUTES_INFO = 17
-+		PAC_TYPE_ATTRIBUTES_INFO = 17,
-+		PAC_TYPE_REQUESTER_SID = 18
- 	} PAC_TYPE;
- 
- 	typedef struct {
-@@ -145,6 +150,7 @@ interface krb5pac
- 		[case(PAC_TYPE_UPN_DNS_INFO)]	PAC_UPN_DNS_INFO upn_dns_info;
- 		[case(PAC_TYPE_TICKET_CHECKSUM)]	PAC_SIGNATURE_DATA ticket_checksum;
- 		[case(PAC_TYPE_ATTRIBUTES_INFO)]	PAC_ATTRIBUTES_INFO attributes_info;
-+		[case(PAC_TYPE_REQUESTER_SID)]	PAC_REQUESTER_SID requester_sid;
- 		/* when new PAC info types are added they are supposed to be done
- 		   in such a way that they are backwards compatible with existing
- 		   servers. This makes it safe to just use a [default] for
--- 
-2.33.1
-
-
-From fb92457cfd11745be73660eb90519b625f6a5d97 Mon Sep 17 00:00:00 2001
-From: Andrew Bartlett <abartlet@samba.org>
-Date: Mon, 27 Sep 2021 11:20:19 +1300
-Subject: [PATCH 6/6] CVE-2020-25721 krb5pac: Add new buffers for
- samAccountName and objectSID
-
-These appear when PAC_UPN_DNS_FLAG_HAS_SAM_NAME_AND_SID is set.
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14835
-
-Signed-off-by: Andrew Bartlett <abartlet@samba.org>
-Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz>
----
- librpc/idl/krb5pac.idl   | 18 ++++++++++++++++--
- librpc/ndr/ndr_krb5pac.c |  4 ++--
- 2 files changed, 18 insertions(+), 4 deletions(-)
-
-diff --git a/librpc/idl/krb5pac.idl b/librpc/idl/krb5pac.idl
-index 52fb40c4bbb..bbe4a253e3a 100644
---- a/librpc/idl/krb5pac.idl
-+++ b/librpc/idl/krb5pac.idl
-@@ -86,15 +86,29 @@ interface krb5pac
- 	} PAC_CONSTRAINED_DELEGATION;
- 
- 	typedef [bitmap32bit] bitmap {
--		PAC_UPN_DNS_FLAG_CONSTRUCTED = 0x00000001
-+		PAC_UPN_DNS_FLAG_CONSTRUCTED = 0x00000001,
-+		PAC_UPN_DNS_FLAG_HAS_SAM_NAME_AND_SID = 0x00000002
- 	} PAC_UPN_DNS_FLAGS;
- 
-+	typedef struct {
-+		[value(2*strlen_m(samaccountname))] uint16 samaccountname_size;
-+		[relative_short,subcontext(0),subcontext_size(samaccountname_size),flag(NDR_ALIGN8|STR_NOTERM|NDR_REMAINING)] string *samaccountname;
-+		[value(ndr_size_dom_sid(objectsid, ndr->flags))] uint16 objectsid_size;
-+		[relative_short,subcontext(0),subcontext_size(objectsid_size)] dom_sid *objectsid;
-+	} PAC_UPN_DNS_INFO_SAM_NAME_AND_SID;
-+
-+	typedef [nodiscriminant] union {
-+		[case(PAC_UPN_DNS_FLAG_HAS_SAM_NAME_AND_SID)] PAC_UPN_DNS_INFO_SAM_NAME_AND_SID sam_name_and_sid;
-+		[default];
-+	} PAC_UPN_DNS_INFO_EX;
-+
- 	typedef struct {
- 		[value(2*strlen_m(upn_name))] uint16 upn_name_size;
- 		[relative_short,subcontext(0),subcontext_size(upn_name_size),flag(NDR_ALIGN8|STR_NOTERM|NDR_REMAINING)] string *upn_name;
- 		[value(2*strlen_m(dns_domain_name))] uint16 dns_domain_name_size;
- 		[relative_short,subcontext(0),subcontext_size(dns_domain_name_size),flag(NDR_ALIGN8|STR_NOTERM|NDR_REMAINING)] string *dns_domain_name;
- 		PAC_UPN_DNS_FLAGS flags;
-+		[switch_is(flags & PAC_UPN_DNS_FLAG_HAS_SAM_NAME_AND_SID)] PAC_UPN_DNS_INFO_EX ex;
- 	} PAC_UPN_DNS_INFO;
- 
- 	typedef [bitmap32bit] bitmap {
-@@ -160,7 +174,7 @@ interface krb5pac
- 
- 	typedef [public,nopush,nopull] struct {
- 		PAC_TYPE type;
--		[value(_ndr_size_PAC_INFO(info, type, 0))] uint32 _ndr_size;
-+		[value(_ndr_size_PAC_INFO(info, type, LIBNDR_FLAG_ALIGN8))] uint32 _ndr_size;
- 		/*
- 		 * We need to have two subcontexts to get the padding right,
- 		 * the outer subcontext uses NDR_ROUND(_ndr_size, 8), while
-diff --git a/librpc/ndr/ndr_krb5pac.c b/librpc/ndr/ndr_krb5pac.c
-index a9ae2c4a789..57b28df9e52 100644
---- a/librpc/ndr/ndr_krb5pac.c
-+++ b/librpc/ndr/ndr_krb5pac.c
-@@ -41,7 +41,7 @@ enum ndr_err_code ndr_push_PAC_BUFFER(struct ndr_push *ndr, int ndr_flags, const
- 	if (ndr_flags & NDR_SCALARS) {
- 		NDR_CHECK(ndr_push_align(ndr, 4));
- 		NDR_CHECK(ndr_push_PAC_TYPE(ndr, NDR_SCALARS, r->type));
--		NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, _ndr_size_PAC_INFO(r->info,r->type,0)));
-+		NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, _ndr_size_PAC_INFO(r->info,r->type,LIBNDR_FLAG_ALIGN8)));
- 		{
- 			uint32_t _flags_save_PAC_INFO = ndr->flags;
- 			ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN8);
-@@ -59,7 +59,7 @@ enum ndr_err_code ndr_push_PAC_BUFFER(struct ndr_push *ndr, int ndr_flags, const
- 				{
- 					struct ndr_push *_ndr_info_pad;
- 					struct ndr_push *_ndr_info;
--					size_t _ndr_size = _ndr_size_PAC_INFO(r->info, r->type, 0);
-+					size_t _ndr_size = _ndr_size_PAC_INFO(r->info, r->type, LIBNDR_FLAG_ALIGN8);
- 					NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_info_pad, 0, NDR_ROUND(_ndr_size, 8)));
- 					NDR_CHECK(ndr_push_subcontext_start(_ndr_info_pad, &_ndr_info, 0, _ndr_size));
- 					NDR_CHECK(ndr_push_set_switch_value(_ndr_info, r->info, r->type));
--- 
-2.33.1
-
diff --git a/SOURCES/samba-4.14-raise-dfs-enoent-debug-level.patch b/SOURCES/samba-4.14-raise-dfs-enoent-debug-level.patch
deleted file mode 100644
index de8d813..0000000
--- a/SOURCES/samba-4.14-raise-dfs-enoent-debug-level.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From 4b192aaf503ea7f5eba27b6e43edcfe54ac6c5a6 Mon Sep 17 00:00:00 2001
-From: Andreas Schneider <asn@samba.org>
-Date: Wed, 26 May 2021 15:04:08 +0200
-Subject: [PATCH] s3:modules: Reduce debug level if file doesn't exists on dfs
- share
-
-There is software out there trying to open desktop.ini in every
-directory. Avoid spamming the logs with error messages.
-
-Signed-off-by: Andreas Schneider <asn@samba.org>
-Reviewed-by: Jeremy Allison <jra@samba.org>
-
-Autobuild-User(master): Jeremy Allison <jra@samba.org>
-Autobuild-Date(master): Fri Jun 18 18:14:11 UTC 2021 on sn-devel-184
-
-(cherry picked from commit 4079efae76718a84a4cf24b6613cdc53cdb2dd39)
----
- source3/modules/vfs_default.c | 15 +++++++++++----
- 1 file changed, 11 insertions(+), 4 deletions(-)
-
-diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
-index 8d592bbad64..ea036b24ddf 100644
---- a/source3/modules/vfs_default.c
-+++ b/source3/modules/vfs_default.c
-@@ -476,10 +476,17 @@ static NTSTATUS vfswrap_read_dfs_pathat(struct vfs_handle_struct *handle,
- 			status = NT_STATUS_OBJECT_TYPE_MISMATCH;
- 		} else {
- 			status = map_nt_error_from_unix(errno);
--			DBG_ERR("Error reading "
--				"msdfs link %s: %s\n",
--				smb_fname->base_name,
--				strerror(errno));
-+			if (errno == ENOENT) {
-+				DBG_NOTICE("Error reading "
-+					 "msdfs link %s: %s\n",
-+					 smb_fname->base_name,
-+					 strerror(errno));
-+			} else {
-+				DBG_ERR("Error reading "
-+					"msdfs link %s: %s\n",
-+					smb_fname->base_name,
-+					strerror(errno));
-+			}
- 		}
-                 goto err;
-         }
--- 
-2.31.1
-
diff --git a/SOURCES/samba-4.14-recursive-delete-of-veto-files.patch b/SOURCES/samba-4.14-recursive-delete-of-veto-files.patch
deleted file mode 100644
index 62525e7..0000000
--- a/SOURCES/samba-4.14-recursive-delete-of-veto-files.patch
+++ /dev/null
@@ -1,295 +0,0 @@
-From 505e48439364c4027aa11aeda467bbd2060b89f4 Mon Sep 17 00:00:00 2001
-From: Jeremy Allison <jra@samba.org>
-Date: Thu, 21 Oct 2021 15:06:20 -0700
-Subject: [PATCH] s3: smbd: Add two tests showing recursive directory delete of
- a directory containing veto file and msdfs links over SMB2.
-
-Add knownfail.
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=14878
-
-Signed-off-by: Jeremy Allison <jra@samba.org>
-Reviewed-by: Ralph Boehme <slow@samba.org>
-(cherry picked from commit ad0082d79a681b981154747dcde5713e1933b88f)
-(cherry picked from commit dab3fa1d8c27e696afa15e071331f646e06d9706)
----
- selftest/target/Samba3.pm               |  16 ++
- source3/script/tests/test_veto_rmdir.sh | 217 ++++++++++++++++++++++++
- source3/selftest/tests.py               |   3 +
- 3 files changed, 236 insertions(+)
- create mode 100755 source3/script/tests/test_veto_rmdir.sh
-
-diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
-index 14a1f1223b1..bbff9d74817 100755
---- a/selftest/target/Samba3.pm
-+++ b/selftest/target/Samba3.pm
-@@ -1460,6 +1460,9 @@ sub setup_fileserver
- 	my $bad_iconv_sharedir="$share_dir/bad_iconv";
- 	push(@dirs, $bad_iconv_sharedir);
- 
-+	my $veto_sharedir="$share_dir/veto";
-+	push(@dirs,$veto_sharedir);
-+
- 	my $ip4 = Samba::get_ipv4_addr("FILESERVER");
- 	my $fileserver_options = "
- 	kernel change notify = yes
-@@ -1568,6 +1571,19 @@ sub setup_fileserver
- 	comment = smb username is [%U]
- 	vfs objects =
- 
-+[veto_files_nodelete]
-+	path = $veto_sharedir
-+	read only = no
-+	msdfs root = yes
-+	veto files = /veto_name*/
-+	delete veto files = no
-+
-+[veto_files_delete]
-+	path = $veto_sharedir
-+	msdfs root = yes
-+	veto files = /veto_name*/
-+	delete veto files = yes
-+
- [homes]
- 	comment = Home directories
- 	browseable = No
-diff --git a/source3/script/tests/test_veto_rmdir.sh b/source3/script/tests/test_veto_rmdir.sh
-new file mode 100755
-index 00000000000..d3df8f1bba0
---- /dev/null
-+++ b/source3/script/tests/test_veto_rmdir.sh
-@@ -0,0 +1,217 @@
-+#!/bin/sh
-+#
-+# Check smbclient can (or cannot) delete a directory containing veto files.
-+# BUG: https://bugzilla.samba.org/show_bug.cgi?id=14878
-+#
-+
-+if [ $# -lt 6 ]; then
-+cat <<EOF
-+Usage: $0 SERVER SERVER_IP USERNAME PASSWORD SHAREPATH SMBCLIENT
-+EOF
-+exit 1;
-+fi
-+
-+SERVER=${1}
-+SERVER_IP=${2}
-+USERNAME=${3}
-+PASSWORD=${4}
-+SHAREPATH=${5}
-+SMBCLIENT=${6}
-+shift 6
-+SMBCLIENT="$VALGRIND ${SMBCLIENT}"
-+ADDARGS="$@"
-+
-+incdir=$(dirname "$0")/../../../testprogs/blackbox
-+. "$incdir"/subunit.sh
-+
-+failed=0
-+
-+rmdir_path="$SHAREPATH/dir"
-+
-+test_veto_nodelete_rmdir()
-+{
-+    local veto_path="$rmdir_path/veto_name1"
-+    local msdfs_link_path="$rmdir_path/dfs_link"
-+    local tmpfile=$PREFIX/smbclient.in.$$
-+
-+    # Create rmdir directory.
-+    mkdir -p "$rmdir_path"
-+    # Create veto file underneath.
-+    touch "$veto_path"
-+    # Create msdfs link underneath.
-+    ln -s "msdfs:$SERVER_IP\\ro-tmp" "$msdfs_link_path"
-+
-+    cat > "$tmpfile" <<EOF
-+cd dir
-+ls
-+quit
-+EOF
-+
-+    local cmd='CLI_FORCE_INTERACTIVE=yes $SMBCLIENT //$SERVER/veto_files_nodelete -U$USERNAME%$PASSWORD $ADDARGS < $tmpfile 2>&1'
-+    eval echo "$cmd"
-+    out=$(eval "$cmd")
-+    ret=$?
-+
-+    # Check for smbclient error.
-+    if [ $ret != 0 ] ; then
-+        echo "Failed accessing share veto_files_nodelete - $ret"
-+        echo "$out"
-+        return 1
-+    fi
-+
-+    # We should only see the dfs_link file.
-+    echo "$out" | grep dfs_link
-+    ret=$?
-+    if [ $ret -ne 0 ] ; then
-+       echo "Failed to see dfs_link in share veto_files_nodelete"
-+       echo "$out"
-+       return 1
-+    fi
-+
-+    # Now remove the dfs_link file.
-+    rm -rf "$msdfs_link_path"
-+
-+    # Try and remove the directory, should fail with NT_STATUS_DIRECTORY_NOT_EMPTY.
-+    cat > "$tmpfile" <<EOF
-+rd dir
-+quit
-+EOF
-+
-+    local cmd='CLI_FORCE_INTERACTIVE=yes $SMBCLIENT //$SERVER/veto_files_nodelete -U$USERNAME%$PASSWORD $ADDARGS < $tmpfile 2>&1'
-+    eval echo "$cmd"
-+    out=$(eval "$cmd")
-+    ret=$?
-+
-+    # Check for smbclient error.
-+    if [ $ret != 0 ] ; then
-+        echo "Failed accessing share veto_files_nodelete - $ret"
-+        echo "$out"
-+        return 1
-+    fi
-+
-+    # We should get NT_STATUS_DIRECTORY_NOT_EMPTY.
-+    echo "$out" | grep NT_STATUS_DIRECTORY_NOT_EMPTY
-+    ret=$?
-+    if [ $ret -ne 0 ] ; then
-+       echo "Failed to get error NT_STATUS_DIRECTORY_NOT_EMPTY in share veto_files_nodelete"
-+       echo "$out"
-+       return 1
-+    fi
-+
-+    # remove the veto file - directory should now be empty.
-+    rm -rf "$veto_path"
-+
-+    # Try and remove the directory, should now succeed.
-+    cat > "$tmpfile" <<EOF
-+rd dir
-+quit
-+EOF
-+
-+    local cmd='CLI_FORCE_INTERACTIVE=yes $SMBCLIENT //$SERVER/veto_files_nodelete -U$USERNAME%$PASSWORD $ADDARGS < $tmpfile 2>&1'
-+    eval echo "$cmd"
-+    out=$(eval "$cmd")
-+    ret=$?
-+
-+    # Check for smbclient error.
-+    if [ $ret != 0 ] ; then
-+        echo "Failed accessing share veto_files_nodelete - $ret"
-+        echo "$out"
-+        return 1
-+    fi
-+
-+    # We should get no NT_STATUS_ errors.
-+    echo "$out" | grep NT_STATUS_
-+    ret=$?
-+    if [ $ret -eq 0 ] ; then
-+       echo "Got error NT_STATUS_ in share veto_files_nodelete"
-+       echo "$out"
-+       return 1
-+    fi
-+
-+    return 0
-+}
-+
-+test_veto_delete_rmdir()
-+{
-+    local veto_path="$rmdir_path/veto_name1"
-+    local msdfs_link_path="$rmdir_path/dfs_link"
-+    local tmpfile=$PREFIX/smbclient.in.$$
-+
-+    # Create rmdir directory.
-+    mkdir -p "$rmdir_path"
-+    # Create veto file underneath.
-+    touch "$veto_path"
-+    # Create msdfs link underneath.
-+    ln -s "msdfs:$SERVER_IP\\ro-tmp" "$msdfs_link_path"
-+
-+    cat > "$tmpfile" <<EOF
-+cd dir
-+ls
-+quit
-+EOF
-+
-+    local cmd='CLI_FORCE_INTERACTIVE=yes $SMBCLIENT //$SERVER/veto_files_delete -U$USERNAME%$PASSWORD $ADDARGS < $tmpfile 2>&1'
-+    eval echo "$cmd"
-+    out=$(eval "$cmd")
-+    ret=$?
-+
-+    # Check for smbclient error.
-+    if [ $ret != 0 ] ; then
-+        echo "Failed accessing share veto_files_delete - $ret"
-+        echo "$out"
-+        return 1
-+    fi
-+
-+    # We should only see the dfs_link file.
-+    echo "$out" | grep dfs_link
-+    ret=$?
-+    if [ $ret -ne 0 ] ; then
-+       echo "Failed to see dfs_link in share veto_files_delete"
-+       echo "$out"
-+       return 1
-+    fi
-+
-+    # Now remove the dfs_link file.
-+    rm -rf "$msdfs_link_path"
-+
-+    # Try and remove the directory, should now succeed.
-+    cat > "$tmpfile" <<EOF
-+rd dir
-+quit
-+EOF
-+
-+    local cmd='CLI_FORCE_INTERACTIVE=yes $SMBCLIENT //$SERVER/veto_files_delete -U$USERNAME%$PASSWORD $ADDARGS < $tmpfile 2>&1'
-+    eval echo "$cmd"
-+    out=$(eval "$cmd")
-+    ret=$?
-+
-+    # Check for smbclient error.
-+    if [ $ret != 0 ] ; then
-+        echo "Failed accessing share veto_files_delete - $ret"
-+        echo "$out"
-+        return 1
-+    fi
-+
-+    # We should get no NT_STATUS_ errors.
-+    echo "$out" | grep NT_STATUS_
-+    ret=$?
-+    if [ $ret -eq 0 ] ; then
-+       echo "Got error NT_STATUS_ in share veto_files_delete"
-+       echo "$out"
-+       return 1
-+    fi
-+
-+    return 0
-+}
-+
-+testit "rmdir cannot delete directory containing a veto file" \
-+   test_veto_nodelete_rmdir || failed=$(expr "$failed" + 1)
-+
-+rm -rf "$rmdir_path"
-+
-+testit "rmdir can delete directory containing a veto file" \
-+   test_veto_delete_rmdir || failed=$(expr "$failed" + 1)
-+
-+rm -rf "$rmdir_path"
-+
-+exit "$failed"
-diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
-index 651be239825..82f32ec4232 100755
---- a/source3/selftest/tests.py
-+++ b/source3/selftest/tests.py
-@@ -498,6 +498,9 @@ for env in ["fileserver"]:
-     plantestsuite("samba3.blackbox.smbclient_iconv.CORE", env + "_smb1_done",
-                   [os.path.join(samba3srcdir, "script/tests/test_smbclient_iconv.sh"),
-                    '$SERVER', '$SERVER_IP', 'bad_iconv', '$USERNAME', '$PASSWORD', smbclient3, '-mCORE'])
-+    plantestsuite("samba3.blackbox.test_veto_rmdir", env,
-+                  [os.path.join(samba3srcdir, "script/tests/test_veto_rmdir.sh"),
-+                  '$SERVER', '$SERVER_IP', '$USERNAME', '$PASSWORD', '$LOCAL_PATH/veto', smbclient3])
- 
-     #
-     # tar command tests
--- 
-2.33.1
-
diff --git a/SOURCES/samba-4.14.5.tar.asc b/SOURCES/samba-4.14.5.tar.asc
deleted file mode 100644
index 24e5294..0000000
--- a/SOURCES/samba-4.14.5.tar.asc
+++ /dev/null
@@ -1,16 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQIzBAABCgAdFiEEgfXigyvSVFoYl7cTqplEL7aAtiAFAmC14EsACgkQqplEL7aA
-tiDWUA//b0Dj/dJozZY/Q6OI9UjPNL9nvPGqpKF0Sl2sW5jO1KWdcq1OZk+H6eO5
-gaX9nuH8Qo/IMxVRIPZVW6lXwsLzSdAOhwPAV02D/feSNfuld078v5yN1My2x6gH
-tmfEVXZJjNkObhLDz0Wgq3mxxKvwxSM4+q2SI9p2/Yk32+oT1l/EWT3WZRNa/I1x
-MF8nr8p5BktPw7tQoITG/JhkWudfkPpvVA3LJYl+F0rjubMA3C3btvDNquPaNXQ0
-Jr0nOt8+OKpsrtBb6ED0su7CWqbHHjc7lTKLepruqnHzllk5/Tcsu6APVRb8qjim
-B2ElieWYJKQ7vBchjuSw/3ufqOsJdvckO4znGM1bUFDnCV0DDOXPE/U5QmjcoQqE
-kJ36m53WnGCHR3JbL+rSjrB1m0ip8tViNraV+Ch2sXNlNvKYPNNo3cgX62nnDWJz
-aLlncx0W1LpZ8mhYVv0AvdoVKBDygzxheye8Fssz3Wz5RDzZ6Vm0AoJwBm+G8v1k
-u0MXMyvBv1KLpBLL27PJm2m7r6KIDB0v9PuLK5iF107omkSWfY/lMLQR2UFph8oH
-uCwV5PiEy/ecBhBfo3KzUG5yJLBBayYB2vGcXJh4yRpAByppFbpo3csr6UZSEsU8
-iImmN97Tg3QVd/FTn9qRiQ15NxzWC0XCE1glY87KqqC5kl5Lk9Y=
-=i6jp
------END PGP SIGNATURE-----
diff --git a/SOURCES/samba-4.15.5.tar.asc b/SOURCES/samba-4.15.5.tar.asc
new file mode 100644
index 0000000..4e31e62
--- /dev/null
+++ b/SOURCES/samba-4.15.5.tar.asc
@@ -0,0 +1,16 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQIzBAABCgAdFiEEgfXigyvSVFoYl7cTqplEL7aAtiAFAmH3yN4ACgkQqplEL7aA
+tiBh5Q/+Pz0ROFJ5gGKdpjH0ZS7ES38wutEgnIyy0y25VHxes+ByByUSpd4WHKMX
+KYSmpQlvQBqSUhD5Jg5GxFT5iVsRiVMcHxc0QVAbdqLuypyoztTE0nGj4RrkWa/9
+j7kPtdojQ3Z6rZ1W6bPzzgb6JRLdvTnoc/IKi/ICXaN50bb8qNGarE35JDbKWcIt
+b72pKe8Z3ainkxNM2/ozFgZeTDSpVZG0b9z8fulsMZ47HDY4pXYWaTG4Q0avrzdY
+0o/p17FFO8YLpSBIIsbHCjIVLz5diZYwuT/23zYAzFZGNIIVYyQlrorBB4krIB6v
+/2q1kescibqc0FMcbWEtSp+QnLqKCCV9JAWgTkyJaUNBZkRQKTF1KwA1/tDtbEoj
++rM8m/luKl0HlwbcQTRk5m3fWTIbZNAKyVoLmv9Aj38wsoEqKyvhjB2xqiTxVwu9
+g2/z7lGTx/qzou0TMbVwCjX1yahR1qmKD0GlffvIPRNPtCOfUlYvX36yM8v8yP/y
+5Pv7SdJ2G3GNkWpzWSSteWDzPvI5IY3PXX+AINuknNgjT54+SiaTY1uKEHj8aYMJ
+f1YkvKhBiBL87+CGZkOEaIDAKsZUAwmfVo8ebID7Ebmtd/VfLYHR8BEeMOU70cxB
+OlAsSQcQm9Nwv51h/AB3n4oK1RykD2FMaH8XNmY0pw+Nd7mKoBo=
+=oc6g
+-----END PGP SIGNATURE-----
diff --git a/SOURCES/samba-ctdb-etcd-reclock.patch b/SOURCES/samba-ctdb-etcd-reclock.patch
new file mode 100644
index 0000000..2a55408
--- /dev/null
+++ b/SOURCES/samba-ctdb-etcd-reclock.patch
@@ -0,0 +1,30 @@
+From 939aed0498269df3c1e012f3b68c314b583f25bd Mon Sep 17 00:00:00 2001
+From: Martin Schwenke <martin@meltin.net>
+Date: Tue, 27 Apr 2021 15:46:14 +1000
+Subject: [PATCH] utils: Use Python 3
+
+Due to the number of flake8 and pylint warnings it is unclear if the
+source has Python 3 incompatibilities.  These will be cleaned up in
+subsequent commits.
+
+Signed-off-by: "L.P.H. van Belle" <belle@bazuin.nl>
+Reviewed-by: Martin Schwenke <martin@meltin.net>
+Reviewed-by: David Disseldorp <ddiss@samba.org>
+Reviewed-by: Jose A. Rivera <jarrpa@samba.org>
+---
+ ctdb/utils/etcd/ctdb_etcd_lock | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/ctdb/utils/etcd/ctdb_etcd_lock b/ctdb/utils/etcd/ctdb_etcd_lock
+index 000c6bb7208..7f5194eff0a 100755
+--- a/ctdb/utils/etcd/ctdb_etcd_lock
++++ b/ctdb/utils/etcd/ctdb_etcd_lock
+@@ -1,4 +1,4 @@
+-#!/usr/bin/python
++#!/usr/bin/env python3
+ #
+ #    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
+-- 
+2.31.1
+
diff --git a/SOURCES/samba-disable-ntlmssp.patch b/SOURCES/samba-disable-ntlmssp.patch
new file mode 100644
index 0000000..d80e85b
--- /dev/null
+++ b/SOURCES/samba-disable-ntlmssp.patch
@@ -0,0 +1,764 @@
+From 1d5dc35b3c5d793f75cd6572bdda2a1ab0df99cc Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Pavel=20Filipensk=C3=BD?= <pfilipen@redhat.com>
+Date: Fri, 10 Dec 2021 16:08:04 +0100
+Subject: [PATCH 01/10] s3:utils: set ads->auth.flags using krb5_state
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=14955
+
+Pair-Programmed-With: Andreas Schneider <asn@samba.org>
+
+Signed-off-by: Pavel Filipenský <pfilipen@redhat.com>
+Signed-off-by: Andreas Schneider <asn@samba.org>
+Reviewed-by: Stefan Metzmacher <metze@samba.org>
+(cherry picked from commit afcdb090769f6f0f66428cd29f88b0283c6bd527)
+---
+ source3/utils/net_ads.c | 22 +++++++++++++++++++++-
+ 1 file changed, 21 insertions(+), 1 deletion(-)
+
+diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c
+index 6ab4a0096b1..8f993f9ba4c 100644
+--- a/source3/utils/net_ads.c
++++ b/source3/utils/net_ads.c
+@@ -607,6 +607,8 @@ static ADS_STATUS ads_startup_int(struct net_context *c, bool only_own_domain,
+ 	char *cp;
+ 	const char *realm = NULL;
+ 	bool tried_closest_dc = false;
++	enum credentials_use_kerberos krb5_state =
++		CRED_USE_KERBEROS_DISABLED;
+ 
+ 	/* lp_realm() should be handled by a command line param,
+ 	   However, the join requires that realm be set in smb.conf
+@@ -650,10 +652,28 @@ retry:
+ 		ads->auth.password = smb_xstrdup(c->opt_password);
+ 	}
+ 
+-	ads->auth.flags |= auth_flags;
+ 	SAFE_FREE(ads->auth.user_name);
+ 	ads->auth.user_name = smb_xstrdup(c->opt_user_name);
+ 
++	ads->auth.flags |= auth_flags;
++
++	/* The ADS code will handle FIPS mode */
++	krb5_state = cli_credentials_get_kerberos_state(c->creds);
++	switch (krb5_state) {
++	case CRED_USE_KERBEROS_REQUIRED:
++		ads->auth.flags &= ~ADS_AUTH_DISABLE_KERBEROS;
++		ads->auth.flags &= ~ADS_AUTH_ALLOW_NTLMSSP;
++		break;
++	case CRED_USE_KERBEROS_DESIRED:
++		ads->auth.flags &= ~ADS_AUTH_DISABLE_KERBEROS;
++		ads->auth.flags |= ADS_AUTH_ALLOW_NTLMSSP;
++		break;
++	case CRED_USE_KERBEROS_DISABLED:
++		ads->auth.flags |= ADS_AUTH_DISABLE_KERBEROS;
++		ads->auth.flags |= ADS_AUTH_ALLOW_NTLMSSP;
++		break;
++	}
++
+        /*
+         * If the username is of the form "name@realm",
+         * extract the realm and convert to upper case.
+-- 
+2.33.1
+
+
+From 8f5c1246fdf03ae4d4abba50ef41e2a5cded61d3 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Pavel=20Filipensk=C3=BD?= <pfilipen@redhat.com>
+Date: Wed, 8 Dec 2021 16:05:17 +0100
+Subject: [PATCH 02/10] s3:libads: Remove trailing spaces from sasl.c
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=14955
+
+Signed-off-by: Pavel Filipenský <pfilipen@redhat.com>
+Signed-off-by: Andreas Schneider <asn@samba.org>
+Reviewed-by: Stefan Metzmacher <metze@samba.org>
+(cherry picked from commit 49d18f2d6e8872c2b0cbe2bf3324e7057c8438f4)
+---
+ source3/libads/sasl.c | 22 +++++++++++-----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
+diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c
+index 60fa2bf80cb..b91e2d15bcf 100644
+--- a/source3/libads/sasl.c
++++ b/source3/libads/sasl.c
+@@ -1,18 +1,18 @@
+-/* 
++/*
+    Unix SMB/CIFS implementation.
+    ads sasl code
+    Copyright (C) Andrew Tridgell 2001
+-   
++
+    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/>.
+ */
+@@ -117,7 +117,7 @@ static const struct ads_saslwrap_ops ads_sasl_gensec_ops = {
+ 	.disconnect	= ads_sasl_gensec_disconnect
+ };
+ 
+-/* 
++/*
+    perform a LDAP/SASL/SPNEGO/{NTLMSSP,KRB5} bind (just how many layers can
+    we fit on one socket??)
+ */
+@@ -496,7 +496,7 @@ static ADS_STATUS ads_generate_service_principal(ADS_STRUCT *ads,
+ 
+ #endif /* HAVE_KRB5 */
+ 
+-/* 
++/*
+    this performs a SASL/SPNEGO bind
+ */
+ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads)
+@@ -529,7 +529,7 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads)
+ 	file_save("sasl_spnego.dat", blob.data, blob.length);
+ #endif
+ 
+-	/* the server sent us the first part of the SPNEGO exchange in the negprot 
++	/* the server sent us the first part of the SPNEGO exchange in the negprot
+ 	   reply */
+ 	if (!spnego_parse_negTokenInit(talloc_tos(), blob, OIDs, &given_principal, NULL) ||
+ 			OIDs[0] == NULL) {
+@@ -557,7 +557,7 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads)
+ 
+ #ifdef HAVE_KRB5
+ 	if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) &&
+-	    got_kerberos_mechanism) 
++	    got_kerberos_mechanism)
+ 	{
+ 		mech = "KRB5";
+ 
+@@ -578,7 +578,7 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads)
+ 				  "calling kinit\n", ads_errstr(status)));
+ 		}
+ 
+-		status = ADS_ERROR_KRB5(ads_kinit_password(ads)); 
++		status = ADS_ERROR_KRB5(ads_kinit_password(ads));
+ 
+ 		if (ADS_ERR_OK(status)) {
+ 			status = ads_sasl_spnego_gensec_bind(ads, "GSS-SPNEGO",
+@@ -597,7 +597,7 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads)
+ 		}
+ 
+ 		/* only fallback to NTLMSSP if allowed */
+-		if (ADS_ERR_OK(status) || 
++		if (ADS_ERR_OK(status) ||
+ 		    !(ads->auth.flags & ADS_AUTH_ALLOW_NTLMSSP)) {
+ 			goto done;
+ 		}
+@@ -613,7 +613,7 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads)
+ #endif
+ 
+ 	/* lets do NTLMSSP ... this has the big advantage that we don't need
+-	   to sync clocks, and we don't rely on special versions of the krb5 
++	   to sync clocks, and we don't rely on special versions of the krb5
+ 	   library for HMAC_MD4 encryption */
+ 	mech = "NTLMSSP";
+ 	status = ads_sasl_spnego_gensec_bind(ads, "GSS-SPNEGO",
+-- 
+2.33.1
+
+
+From 2885c2186fd2d1d8e2fc5f90e58f54b0c72a72df Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Pavel=20Filipensk=C3=BD?= <pfilipen@redhat.com>
+Date: Thu, 9 Dec 2021 13:43:08 +0100
+Subject: [PATCH 03/10] s3:libads: Disable NTLMSSP for FIPS
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=14955
+
+Pair-Programmed-With: Andreas Schneider <asn@samba.org>
+
+Signed-off-by: Pavel Filipenský <pfilipen@redhat.com>
+Signed-off-by: Andreas Schneider <asn@samba.org>
+Reviewed-by: Stefan Metzmacher <metze@samba.org>
+(cherry picked from commit 7785eb9b78066f6f7ee2541cf72d80fcf7411329)
+---
+ source3/libads/sasl.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c
+index b91e2d15bcf..992f7022a69 100644
+--- a/source3/libads/sasl.c
++++ b/source3/libads/sasl.c
+@@ -604,7 +604,7 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads)
+ 
+ 		DEBUG(1,("ads_sasl_spnego_gensec_bind(KRB5) failed "
+ 			 "for %s/%s with user[%s] realm[%s]: %s, "
+-			 "fallback to NTLMSSP\n",
++			 "try to fallback to NTLMSSP\n",
+ 			 p.service, p.hostname,
+ 			 ads->auth.user_name,
+ 			 ads->auth.realm,
+@@ -616,6 +616,14 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads)
+ 	   to sync clocks, and we don't rely on special versions of the krb5
+ 	   library for HMAC_MD4 encryption */
+ 	mech = "NTLMSSP";
++
++	if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED) {
++		DBG_WARNING("We can't fallback to NTLMSSP, weak crypto is"
++			    " disallowed.\n");
++		status = ADS_ERROR_NT(NT_STATUS_NETWORK_CREDENTIAL_CONFLICT);
++		goto done;
++	}
++
+ 	status = ads_sasl_spnego_gensec_bind(ads, "GSS-SPNEGO",
+ 					     CRED_USE_KERBEROS_DISABLED,
+ 					     p.service, p.hostname,
+-- 
+2.33.1
+
+
+From 636281a0b09f20e4c91f649a950a8c9ca53d1e3c Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Pavel=20Filipensk=C3=BD?= <pfilipen@redhat.com>
+Date: Fri, 7 Jan 2022 10:31:19 +0100
+Subject: [PATCH 04/10] s3:libads: Improve debug messages for SASL bind
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=14955
+
+Pair-Programmed-With: Andreas Schneider <asn@samba.org>
+
+Signed-off-by: Pavel Filipenský <pfilipen@redhat.com>
+Signed-off-by: Andreas Schneider <asn@samba.org>
+Reviewed-by: Stefan Metzmacher <metze@samba.org>
+(cherry picked from commit 5f6251abf2f468b3744a96376b0e1c3bc317c738)
+---
+ source3/libads/sasl.c | 22 +++++++++++-----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
+diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c
+index 992f7022a69..ea98aa47ecd 100644
+--- a/source3/libads/sasl.c
++++ b/source3/libads/sasl.c
+@@ -586,13 +586,13 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads)
+ 							p.service, p.hostname,
+ 							blob);
+ 			if (!ADS_ERR_OK(status)) {
+-				DEBUG(0,("kinit succeeded but "
+-					"ads_sasl_spnego_gensec_bind(KRB5) failed "
+-					"for %s/%s with user[%s] realm[%s]: %s\n",
++				DBG_ERR("kinit succeeded but "
++					"SPNEGO bind with Kerberos failed "
++					"for %s/%s - user[%s], realm[%s]: %s\n",
+ 					p.service, p.hostname,
+ 					ads->auth.user_name,
+ 					ads->auth.realm,
+-					ads_errstr(status)));
++					ads_errstr(status));
+ 			}
+ 		}
+ 
+@@ -602,13 +602,13 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads)
+ 			goto done;
+ 		}
+ 
+-		DEBUG(1,("ads_sasl_spnego_gensec_bind(KRB5) failed "
+-			 "for %s/%s with user[%s] realm[%s]: %s, "
+-			 "try to fallback to NTLMSSP\n",
+-			 p.service, p.hostname,
+-			 ads->auth.user_name,
+-			 ads->auth.realm,
+-			 ads_errstr(status)));
++		DBG_WARNING("SASL bind with Kerberos failed "
++			    "for %s/%s - user[%s], realm[%s]: %s, "
++			    "try to fallback to NTLMSSP\n",
++			    p.service, p.hostname,
++			    ads->auth.user_name,
++			    ads->auth.realm,
++			    ads_errstr(status));
+ 	}
+ #endif
+ 
+-- 
+2.33.1
+
+
+From db4df8c4ebc9a10d14174878c3303c5f7a9e3d2f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Pavel=20Filipensk=C3=BD?= <pfilipen@redhat.com>
+Date: Mon, 3 Jan 2022 11:13:06 +0100
+Subject: [PATCH 05/10] s3:libads: Disable NTLMSSP if not allowed (for builds
+ without kerberos)
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=14955
+
+Pair-Programmed-With: Andreas Schneider <asn@samba.org>
+
+Signed-off-by: Pavel Filipenský <pfilipen@redhat.com>
+Signed-off-by: Andreas Schneider <asn@samba.org>
+Reviewed-by: Stefan Metzmacher <metze@samba.org>
+(cherry picked from commit 17ea2ccdabbe935ef571e1227908d51b755707bc)
+---
+ source3/libads/sasl.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c
+index ea98aa47ecd..1bcfe0490a8 100644
+--- a/source3/libads/sasl.c
++++ b/source3/libads/sasl.c
+@@ -617,6 +617,12 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads)
+ 	   library for HMAC_MD4 encryption */
+ 	mech = "NTLMSSP";
+ 
++	if (!(ads->auth.flags & ADS_AUTH_ALLOW_NTLMSSP)) {
++		DBG_WARNING("We can't use NTLMSSP, it is not allowed.\n");
++		status = ADS_ERROR_NT(NT_STATUS_NETWORK_CREDENTIAL_CONFLICT);
++		goto done;
++	}
++
+ 	if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED) {
+ 		DBG_WARNING("We can't fallback to NTLMSSP, weak crypto is"
+ 			    " disallowed.\n");
+-- 
+2.33.1
+
+
+From 86e4b3649f001e162328b1b89ea2d068056514e7 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Pavel=20Filipensk=C3=BD?= <pfilipen@redhat.com>
+Date: Mon, 3 Jan 2022 15:33:46 +0100
+Subject: [PATCH 06/10] tests: Add test for disabling NTLMSSP for ldap client
+ connections
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=14955
+
+Signed-off-by: Pavel Filipenský <pfilipen@redhat.com>
+Signed-off-by: Andreas Schneider <asn@samba.org>
+Reviewed-by: Stefan Metzmacher <metze@samba.org>
+(cherry picked from commit eb0fa26dce77829995505f542af02e32df088cd6)
+---
+ .../test_weak_disable_ntlmssp_ldap.sh         | 41 +++++++++++++++++++
+ 1 file changed, 41 insertions(+)
+ create mode 100755 testprogs/blackbox/test_weak_disable_ntlmssp_ldap.sh
+
+diff --git a/testprogs/blackbox/test_weak_disable_ntlmssp_ldap.sh b/testprogs/blackbox/test_weak_disable_ntlmssp_ldap.sh
+new file mode 100755
+index 00000000000..2822ab29d14
+--- /dev/null
++++ b/testprogs/blackbox/test_weak_disable_ntlmssp_ldap.sh
+@@ -0,0 +1,41 @@
++#!/bin/sh
++# Blackbox tests for diabing NTLMSSP for ldap clinet connections
++# Copyright (c) 2022      Pavel Filipenský <pfilipen@redhat.com>
++
++if [ $# -lt 2 ]; then
++cat <<EOF
++Usage: $0 USERNAME PASSWORD
++EOF
++exit 1;
++fi
++
++USERNAME=$1
++PASSWORD=$2
++shift 2
++
++failed=0
++. `dirname $0`/subunit.sh
++
++samba_testparm="$BINDIR/testparm"
++samba_net="$BINDIR/net"
++
++unset GNUTLS_FORCE_FIPS_MODE
++
++# Checks that testparm reports: Weak crypto is allowed
++testit_grep "testparm" "Weak crypto is allowed" $samba_testparm --suppress-prompt $SMB_CONF_PATH 2>&1 || failed=`expr $failed + 1`
++
++# We should be allowed to use NTLM for connecting
++testit "net_ads_search.ntlm" $samba_net ads search --use-kerberos=off '(objectCategory=group)' sAMAccountName -U${USERNAME}%${PASSWORD} || failed=`expr $failed + 1`
++
++GNUTLS_FORCE_FIPS_MODE=1
++export GNUTLS_FORCE_FIPS_MODE
++
++# Checks that testparm reports: Weak crypto is disallowed
++testit_grep "testparm" "Weak crypto is disallowed" $samba_testparm --suppress-prompt $SMB_CONF_PATH 2>&1 || failed=`expr $failed + 1`
++
++# We should not be allowed to use NTLM for connecting
++testit_expect_failure_grep "net_ads_search.ntlm" "We can't fallback to NTLMSSP, weak crypto is disallowed." $samba_net ads search --use-kerberos=off -d10 '(objectCategory=group)' sAMAccountName -U${USERNAME}%${PASSWORD} || failed=`expr $failed + 1`
++
++unset GNUTLS_FORCE_FIPS_MODE
++
++exit $failed
+-- 
+2.33.1
+
+
+From bd39e9418da9dee81d5872037aa5834deba2b40b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Pavel=20Filipensk=C3=BD?= <pfilipen@redhat.com>
+Date: Tue, 4 Jan 2022 12:00:20 +0100
+Subject: [PATCH 07/10] s4:selftest: plan test suite
+ samba4.blackbox.test_weak_disable_ntlmssp_ldap
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=14955
+
+Signed-off-by: Pavel Filipenský <pfilipen@redhat.com>
+Signed-off-by: Andreas Schneider <asn@samba.org>
+Reviewed-by: Stefan Metzmacher <metze@samba.org>
+(cherry picked from commit 9624e60e8c32de695661ae8f0fb5f8f9d836ab95)
+---
+ source4/selftest/tests.py | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py
+index 1e4b2ae6dd3..3a6a716f061 100755
+--- a/source4/selftest/tests.py
++++ b/source4/selftest/tests.py
+@@ -636,6 +636,7 @@ plantestsuite("samba4.blackbox.samba-tool_ntacl(ad_member:local)", "ad_member:lo
+ 
+ if have_gnutls_fips_mode_support:
+     plantestsuite("samba4.blackbox.weak_crypto.client", "ad_dc", [os.path.join(bbdir, "test_weak_crypto.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$REALM', '$DOMAIN', "$PREFIX/ad_dc"])
++    plantestsuite("samba4.blackbox.test_weak_disable_ntlmssp_ldap", "ad_member:local", [os.path.join(bbdir, "test_weak_disable_ntlmssp_ldap.sh"),'$DC_USERNAME', '$DC_PASSWORD'])
+ 
+     for env in ["ad_dc_fips", "ad_member_fips"]:
+         plantestsuite("samba4.blackbox.weak_crypto.server", env, [os.path.join(bbdir, "test_weak_crypto_server.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$REALM', '$DOMAIN', "$PREFIX/ad_dc_fips", configuration])
+-- 
+2.33.1
+
+
+From bde5c51a9eef39a165dad7aadf23ecaa5921f520 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Pavel=20Filipensk=C3=BD?= <pfilipen@redhat.com>
+Date: Tue, 18 Jan 2022 19:47:38 +0100
+Subject: [PATCH 08/10] s3:winbindd: Remove trailing spaces from winbindd_ads.c
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=14955
+
+Signed-off-by: Pavel Filipenský <pfilipen@redhat.com>
+Signed-off-by: Andreas Schneider <asn@samba.org>
+Reviewed-by: Stefan Metzmacher <metze@samba.org>
+(cherry picked from commit fcf225a356abb06d1205f66eb79f707c85803cb5)
+---
+ source3/winbindd/winbindd_ads.c | 38 ++++++++++++++++-----------------
+ 1 file changed, 19 insertions(+), 19 deletions(-)
+
+diff --git a/source3/winbindd/winbindd_ads.c b/source3/winbindd/winbindd_ads.c
+index 948c903f165..e415df347e6 100644
+--- a/source3/winbindd/winbindd_ads.c
++++ b/source3/winbindd/winbindd_ads.c
+@@ -326,7 +326,7 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain,
+ 
+ 	if ( !winbindd_can_contact_domain( domain ) ) {
+ 		DEBUG(10,("query_user_list: No incoming trust for domain %s\n",
+-			  domain->name));		
++			  domain->name));
+ 		return NT_STATUS_OK;
+ 	}
+ 
+@@ -432,7 +432,7 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
+ 
+ 	if ( !winbindd_can_contact_domain( domain ) ) {
+ 		DEBUG(10,("enum_dom_groups: No incoming trust for domain %s\n",
+-			  domain->name));		
++			  domain->name));
+ 		return NT_STATUS_OK;
+ 	}
+ 
+@@ -447,7 +447,7 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
+ 	 * According to Section 5.1(4) of RFC 2251 if a value of a type is it's
+ 	 * default value, it MUST be absent. In case of extensible matching the
+ 	 * "dnattr" boolean defaults to FALSE and so it must be only be present
+-	 * when set to TRUE. 
++	 * when set to TRUE.
+ 	 *
+ 	 * When it is set to FALSE and the OpenLDAP lib (correctly) encodes a
+ 	 * filter using bitwise matching rule then the buggy AD fails to decode
+@@ -458,9 +458,9 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
+ 	 *
+ 	 * Thanks to Ralf Haferkamp for input and testing - Guenther */
+ 
+-	filter = talloc_asprintf(mem_ctx, "(&(objectCategory=group)(&(groupType:dn:%s:=%d)(!(groupType:dn:%s:=%d))))", 
++	filter = talloc_asprintf(mem_ctx, "(&(objectCategory=group)(&(groupType:dn:%s:=%d)(!(groupType:dn:%s:=%d))))",
+ 				 ADS_LDAP_MATCHING_RULE_BIT_AND, GROUP_TYPE_SECURITY_ENABLED,
+-				 ADS_LDAP_MATCHING_RULE_BIT_AND, 
++				 ADS_LDAP_MATCHING_RULE_BIT_AND,
+ 				 enum_dom_local_groups ? GROUP_TYPE_BUILTIN_LOCAL_GROUP : GROUP_TYPE_RESOURCE_GROUP);
+ 
+ 	if (filter == NULL) {
+@@ -529,7 +529,7 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
+ 	DEBUG(3,("ads enum_dom_groups gave %d entries\n", (*num_entries)));
+ 
+ done:
+-	if (res) 
++	if (res)
+ 		ads_msgfree(ads, res);
+ 
+ 	return status;
+@@ -542,12 +542,12 @@ static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
+ 				struct wb_acct_info **info)
+ {
+ 	/*
+-	 * This is a stub function only as we returned the domain 
++	 * This is a stub function only as we returned the domain
+ 	 * local groups in enum_dom_groups() if the domain->native field
+ 	 * was true.  This is a simple performance optimization when
+ 	 * using LDAP.
+ 	 *
+-	 * if we ever need to enumerate domain local groups separately, 
++	 * if we ever need to enumerate domain local groups separately,
+ 	 * then this optimization in enum_dom_groups() will need
+ 	 * to be split out
+ 	 */
+@@ -601,7 +601,7 @@ static NTSTATUS rids_to_names(struct winbindd_domain *domain,
+    tokenGroups are not available. */
+ static NTSTATUS lookup_usergroups_member(struct winbindd_domain *domain,
+ 					 TALLOC_CTX *mem_ctx,
+-					 const char *user_dn, 
++					 const char *user_dn,
+ 					 struct dom_sid *primary_group,
+ 					 uint32_t *p_num_groups, struct dom_sid **user_sids)
+ {
+@@ -620,7 +620,7 @@ static NTSTATUS lookup_usergroups_member(struct winbindd_domain *domain,
+ 
+ 	if ( !winbindd_can_contact_domain( domain ) ) {
+ 		DEBUG(10,("lookup_usergroups_members: No incoming trust for domain %s\n",
+-			  domain->name));		
++			  domain->name));
+ 		return NT_STATUS_OK;
+ 	}
+ 
+@@ -702,7 +702,7 @@ static NTSTATUS lookup_usergroups_member(struct winbindd_domain *domain,
+ 
+ 	DEBUG(3,("ads lookup_usergroups (member) succeeded for dn=%s\n", user_dn));
+ done:
+-	if (res) 
++	if (res)
+ 		ads_msgfree(ads, res);
+ 
+ 	return status;
+@@ -883,14 +883,14 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
+ 	if (count != 1) {
+ 		status = NT_STATUS_UNSUCCESSFUL;
+ 		DEBUG(1,("lookup_usergroups(sid=%s) ads_search tokenGroups: "
+-			 "invalid number of results (count=%d)\n", 
++			 "invalid number of results (count=%d)\n",
+ 			 dom_sid_str_buf(sid, &buf),
+ 			 count));
+ 		goto done;
+ 	}
+ 
+ 	if (!msg) {
+-		DEBUG(1,("lookup_usergroups(sid=%s) ads_search tokenGroups: NULL msg\n", 
++		DEBUG(1,("lookup_usergroups(sid=%s) ads_search tokenGroups: NULL msg\n",
+ 			 dom_sid_str_buf(sid, &buf)));
+ 		status = NT_STATUS_UNSUCCESSFUL;
+ 		goto done;
+@@ -903,7 +903,7 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
+ 	}
+ 
+ 	if (!ads_pull_uint32(ads, msg, "primaryGroupID", &primary_group_rid)) {
+-		DEBUG(1,("%s: No primary group for sid=%s !?\n", 
++		DEBUG(1,("%s: No primary group for sid=%s !?\n",
+ 			 domain->name,
+ 			 dom_sid_str_buf(sid, &buf)));
+ 		goto done;
+@@ -913,7 +913,7 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
+ 
+ 	count = ads_pull_sids(ads, mem_ctx, msg, "tokenGroups", &sids);
+ 
+-	/* there must always be at least one group in the token, 
++	/* there must always be at least one group in the token,
+ 	   unless we are talking to a buggy Win2k server */
+ 
+ 	/* actually this only happens when the machine account has no read
+@@ -937,7 +937,7 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
+ 		/* lookup what groups this user is a member of by DN search on
+ 		 * "member" */
+ 
+-		status = lookup_usergroups_member(domain, mem_ctx, user_dn, 
++		status = lookup_usergroups_member(domain, mem_ctx, user_dn,
+ 						  &primary_group,
+ 						  &num_groups, user_sids);
+ 		*p_num_groups = num_groups;
+@@ -1302,7 +1302,7 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
+ 			DEBUG(10, ("lookup_groupmem: lsa_lookup_sids could "
+ 				   "not map any SIDs at all.\n"));
+ 			/* Don't handle this as an error here.
+-			 * There is nothing left to do with respect to the 
++			 * There is nothing left to do with respect to the
+ 			 * overall result... */
+ 		}
+ 		else if (!NT_STATUS_IS_OK(status)) {
+@@ -1367,13 +1367,13 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
+ 			NETR_TRUST_FLAG_IN_FOREST;
+ 	} else {
+ 		flags = NETR_TRUST_FLAG_IN_FOREST;
+-	}	
++	}
+ 
+ 	result = cm_connect_netlogon(domain, &cli);
+ 
+ 	if (!NT_STATUS_IS_OK(result)) {
+ 		DEBUG(5, ("trusted_domains: Could not open a connection to %s "
+-			  "for PIPE_NETLOGON (%s)\n", 
++			  "for PIPE_NETLOGON (%s)\n",
+ 			  domain->name, nt_errstr(result)));
+ 		return NT_STATUS_UNSUCCESSFUL;
+ 	}
+-- 
+2.33.1
+
+
+From db840cc208542a52a8e8a226b452c4df921fe9e6 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Pavel=20Filipensk=C3=BD?= <pfilipen@redhat.com>
+Date: Tue, 18 Jan 2022 19:44:54 +0100
+Subject: [PATCH 09/10] s3:winbindd: Do not set ADS_AUTH_ALLOW_NTLMSSP in FIPS
+ mode
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=14955
+
+Pair-Programmed-With: Andreas Schneider <asn@samba.org>
+
+Signed-off-by: Pavel Filipenský <pfilipen@redhat.com>
+Signed-off-by: Andreas Schneider <asn@samba.org>
+Reviewed-by: Stefan Metzmacher <metze@samba.org>
+(cherry picked from commit f03abaec2abbd22b9dc83ce4a103b1b3a2912d96)
+---
+ source3/winbindd/winbindd_ads.c | 19 ++++++++++++++++++-
+ 1 file changed, 18 insertions(+), 1 deletion(-)
+
+diff --git a/source3/winbindd/winbindd_ads.c b/source3/winbindd/winbindd_ads.c
+index e415df347e6..6f01ef6e334 100644
+--- a/source3/winbindd/winbindd_ads.c
++++ b/source3/winbindd/winbindd_ads.c
+@@ -34,6 +34,7 @@
+ #include "../libds/common/flag_mapping.h"
+ #include "libsmb/samlogon_cache.h"
+ #include "passdb.h"
++#include "auth/credentials/credentials.h"
+ 
+ #ifdef HAVE_ADS
+ 
+@@ -102,6 +103,7 @@ static ADS_STATUS ads_cached_connection_connect(ADS_STRUCT **adsp,
+ 	ADS_STATUS status;
+ 	struct sockaddr_storage dc_ss;
+ 	fstring dc_name;
++	enum credentials_use_kerberos krb5_state;
+ 
+ 	if (auth_realm == NULL) {
+ 		return ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL);
+@@ -125,7 +127,22 @@ static ADS_STATUS ads_cached_connection_connect(ADS_STRUCT **adsp,
+ 	ads->auth.renewable = renewable;
+ 	ads->auth.password = password;
+ 
+-	ads->auth.flags |= ADS_AUTH_ALLOW_NTLMSSP;
++	/* In FIPS mode, client use kerberos is forced to required. */
++	krb5_state = lp_client_use_kerberos();
++	switch (krb5_state) {
++	case CRED_USE_KERBEROS_REQUIRED:
++		ads->auth.flags &= ~ADS_AUTH_DISABLE_KERBEROS;
++		ads->auth.flags &= ~ADS_AUTH_ALLOW_NTLMSSP;
++		break;
++	case CRED_USE_KERBEROS_DESIRED:
++		ads->auth.flags &= ~ADS_AUTH_DISABLE_KERBEROS;
++		ads->auth.flags |= ADS_AUTH_ALLOW_NTLMSSP;
++		break;
++	case CRED_USE_KERBEROS_DISABLED:
++		ads->auth.flags |= ADS_AUTH_DISABLE_KERBEROS;
++		ads->auth.flags |= ADS_AUTH_ALLOW_NTLMSSP;
++		break;
++	}
+ 
+ 	ads->auth.realm = SMB_STRDUP(auth_realm);
+ 	if (!strupper_m(ads->auth.realm)) {
+-- 
+2.33.1
+
+
+From ead4f4c0a908f22ee2edf7510033345700e2efd9 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Pavel=20Filipensk=C3=BD?= <pfilipen@redhat.com>
+Date: Fri, 21 Jan 2022 12:01:33 +0100
+Subject: [PATCH 10/10] s3:libnet: Do not set ADS_AUTH_ALLOW_NTLMSSP in FIPS
+ mode
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=14955
+
+Pair-Programmed-With: Andreas Schneider <asn@samba.org>
+
+Signed-off-by: Pavel Filipenský <pfilipen@redhat.com>
+Signed-off-by: Andreas Schneider <asn@samba.org>
+Reviewed-by: Stefan Metzmacher <metze@samba.org>
+
+Autobuild-User(master): Stefan Metzmacher <metze@samba.org>
+Autobuild-Date(master): Sat Jan 22 00:27:52 UTC 2022 on sn-devel-184
+
+(cherry picked from commit fa5413b63c8f4a20ab5b803f5cc523e0658eefc9)
+---
+ source3/libnet/libnet_join.c | 18 +++++++++++++++++-
+ 1 file changed, 17 insertions(+), 1 deletion(-)
+
+diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c
+index 02705f1c70c..4c67e9af5c4 100644
+--- a/source3/libnet/libnet_join.c
++++ b/source3/libnet/libnet_join.c
+@@ -139,6 +139,7 @@ static ADS_STATUS libnet_connect_ads(const char *dns_domain_name,
+ 	ADS_STATUS status;
+ 	ADS_STRUCT *my_ads = NULL;
+ 	char *cp;
++	enum credentials_use_kerberos krb5_state;
+ 
+ 	my_ads = ads_init(dns_domain_name,
+ 			  netbios_domain_name,
+@@ -148,7 +149,22 @@ static ADS_STATUS libnet_connect_ads(const char *dns_domain_name,
+ 		return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
+ 	}
+ 
+-	my_ads->auth.flags |= ADS_AUTH_ALLOW_NTLMSSP;
++	/* In FIPS mode, client use kerberos is forced to required. */
++	krb5_state = lp_client_use_kerberos();
++	switch (krb5_state) {
++	case CRED_USE_KERBEROS_REQUIRED:
++		my_ads->auth.flags &= ~ADS_AUTH_DISABLE_KERBEROS;
++		my_ads->auth.flags &= ~ADS_AUTH_ALLOW_NTLMSSP;
++		break;
++	case CRED_USE_KERBEROS_DESIRED:
++		my_ads->auth.flags &= ~ADS_AUTH_DISABLE_KERBEROS;
++		my_ads->auth.flags |= ADS_AUTH_ALLOW_NTLMSSP;
++		break;
++	case CRED_USE_KERBEROS_DISABLED:
++		my_ads->auth.flags |= ADS_AUTH_DISABLE_KERBEROS;
++		my_ads->auth.flags |= ADS_AUTH_ALLOW_NTLMSSP;
++		break;
++	}
+ 
+ 	if (user_name) {
+ 		SAFE_FREE(my_ads->auth.user_name);
+-- 
+2.33.1
+
diff --git a/SOURCES/samba-disable-systemd-notifications.patch b/SOURCES/samba-disable-systemd-notifications.patch
new file mode 100644
index 0000000..9e57630
--- /dev/null
+++ b/SOURCES/samba-disable-systemd-notifications.patch
@@ -0,0 +1,36 @@
+From 752de46cc57215b14b55f2c68334178454d7444f Mon Sep 17 00:00:00 2001
+From: "FeRD (Frank Dana)" <ferdnyc@gmail.com>
+Date: Mon, 24 Jan 2022 22:14:31 -0500
+Subject: [PATCH] printing/bgqd: Disable systemd notifications
+
+samba-bgqd daemon is started by existing Samba daemons. When running
+under systemd, those daemons control systemd notifications and
+samba-bgqd messages need to be silenced.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=14947
+
+Signed-off-by: FeRD (Frank Dana) <ferdnyc@gmail.com>
+Reviewed-by: Alexander Bokovoy <ab@samba.org>
+Reviewed-by: Andreas Schneider <asn@samba.org>
+(cherry picked from commit 36c861e25b1d9c5ce44bfcb46247e7e4747930c5)
+---
+ source3/printing/samba-bgqd.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/source3/printing/samba-bgqd.c b/source3/printing/samba-bgqd.c
+index f21327fc622..59ed0cc40db 100644
+--- a/source3/printing/samba-bgqd.c
++++ b/source3/printing/samba-bgqd.c
+@@ -252,6 +252,9 @@ int main(int argc, const char *argv[])
+ 
+ 	log_stdout = (debug_get_log_type() == DEBUG_STDOUT);
+ 
++	/* main process will notify systemd */
++	daemon_sd_notifications(false);
++
+ 	if (!cmdline_daemon_cfg->fork) {
+ 		daemon_status(progname, "Starting process ... ");
+ 	} else {
+-- 
+2.34.1
+
diff --git a/SOURCES/samba-glibc-dns.patch b/SOURCES/samba-glibc-dns.patch
new file mode 100644
index 0000000..c01d481
--- /dev/null
+++ b/SOURCES/samba-glibc-dns.patch
@@ -0,0 +1,64 @@
+From e556b4067e0c4036e20fc26523e3b4d6d5c6be42 Mon Sep 17 00:00:00 2001
+From: Andreas Schneider <asn@samba.org>
+Date: Thu, 7 Oct 2021 15:55:37 +0200
+Subject: [PATCH] waf: Fix resolv_wrapper with glibc 2.34
+
+With glibc 2.34 we are not able to talk to the DNS server via socket_wrapper
+anymore. The res_* symbols have been moved from libresolv to libc. We are not
+able to intercept any traffic inside of libc.
+
+Signed-off-by: Andreas Schneider <asn@samba.org>
+Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
+Reviewed-by: Alexander Bokovoy <ab@samba.org>
+---
+ selftest/wscript                   |  2 +-
+ third_party/resolv_wrapper/wscript | 13 +++++++++++++
+ 2 files changed, 14 insertions(+), 1 deletion(-)
+
+diff --git a/selftest/wscript b/selftest/wscript
+index a6be06c2ae9..85d9338489a 100644
+--- a/selftest/wscript
++++ b/selftest/wscript
+@@ -252,7 +252,7 @@ def cmd_testonly(opt):
+     if os.environ.get('USE_NAMESPACES') is None:
+         env.OPTIONS += " --socket_wrapper_so_path=" + CONFIG_GET(opt, 'LIBSOCKET_WRAPPER_SO_PATH')
+ 
+-    if Utils.unversioned_sys_platform() in ('netbsd', 'openbsd', 'sunos'):
++    if not CONFIG_SET(opt, 'HAVE_RESOLV_CONF_SUPPORT'):
+         env.OPTIONS += " --use-dns-faking"
+ 
+     if CONFIG_GET(opt, 'USING_SYSTEM_KRB5') and CONFIG_GET(opt, 'MIT_KDC_PATH'):
+diff --git a/third_party/resolv_wrapper/wscript b/third_party/resolv_wrapper/wscript
+index a7f18389b0f..7e369bd90b5 100644
+--- a/third_party/resolv_wrapper/wscript
++++ b/third_party/resolv_wrapper/wscript
+@@ -1,6 +1,7 @@
+ #!/usr/bin/env python
+ 
+ import os
++from waflib import Logs
+ 
+ VERSION="1.1.7"
+ 
+@@ -49,6 +50,18 @@ def configure(conf):
+         if conf.CONFIG_SET('HAVE_RES_NCLOSE'):
+             conf.DEFINE('HAVE_RES_NCLOSE_IN_LIBRESOLV', 1)
+ 
++        # If we find res_nquery in libc, we can't do resolv.conf redirect
++        conf.CHECK_FUNCS('res_nquery __res_nquery')
++        if (conf.CONFIG_SET('HAVE_RES_NQUERY')
++                or conf.CONFIG_SET('HAVE___RES_NQUERY')):
++            Logs.warn("Detection for resolv_wrapper: "
++                      "Only dns faking will be available")
++        else:
++            if conf.CHECK_FUNCS('res_nquery', lib='resolv'):
++                conf.DEFINE('HAVE_RESOLV_CONF_SUPPORT', 1)
++            if conf.CHECK_FUNCS('__res_nquery', lib='resolv'):
++                conf.DEFINE('HAVE_RESOLV_CONF_SUPPORT', 1)
++
+         conf.CHECK_FUNCS_IN('res_init __res_init', 'resolv', checklibc=True)
+         conf.CHECK_FUNCS_IN('res_ninit __res_ninit', 'resolv', checklibc=True)
+         conf.CHECK_FUNCS_IN('res_close __res_close', 'resolv', checklibc=True)
+-- 
+2.33.1
+
diff --git a/SOURCES/samba-password-change-prompt.patch b/SOURCES/samba-password-change-prompt.patch
new file mode 100644
index 0000000..5dee86c
--- /dev/null
+++ b/SOURCES/samba-password-change-prompt.patch
@@ -0,0 +1,100 @@
+From 513946aec6ddf4cb61d5d460e0478fd7ffd7be21 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org>
+Date: Wed, 17 Nov 2021 09:56:09 +0100
+Subject: [PATCH] pam_winbind: add new pwd_change_prompt option (defaults to
+ off).
+
+This change disables the prompt for the change of an expired password by
+default (using the PAM_RADIO_TYPE mechanism if present).
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=8691
+
+Guenther
+
+Signed-off-by: Guenther Deschner <gd@samba.org>
+Reviewed-by: Alexander Bokovoy <ab@samba.org>
+Reviewed-by: Andreas Schneider <asn@samba.org>
+(cherry picked from commit 20c85cc1da8d8c7f1932fbdd92128bb6dafad472)
+---
+ docs-xml/manpages/pam_winbind.conf.5.xml |  7 +++++++
+ nsswitch/pam_winbind.c                   | 12 ++++++++++--
+ nsswitch/pam_winbind.h                   |  1 +
+ 3 files changed, 18 insertions(+), 2 deletions(-)
+
+diff --git a/docs-xml/manpages/pam_winbind.conf.5.xml b/docs-xml/manpages/pam_winbind.conf.5.xml
+index 0bc288f91a1..bae9298fc32 100644
+--- a/docs-xml/manpages/pam_winbind.conf.5.xml
++++ b/docs-xml/manpages/pam_winbind.conf.5.xml
+@@ -194,6 +194,13 @@
+ 		</para></listitem>
+ 		</varlistentry>
+ 
++		<varlistentry>
++		<term>pwd_change_prompt = yes|no</term>
++		<listitem><para>
++			Generate prompt for changing an expired password. Defaults to "no".
++		</para></listitem>
++		</varlistentry>
++
+ 		</variablelist>
+ 
+ 	</para>
+diff --git a/nsswitch/pam_winbind.c b/nsswitch/pam_winbind.c
+index 720a4b90d85..06098dd07d8 100644
+--- a/nsswitch/pam_winbind.c
++++ b/nsswitch/pam_winbind.c
+@@ -479,6 +479,10 @@ static int _pam_parse(const pam_handle_t *pamh,
+ 		ctrl |= WINBIND_MKHOMEDIR;
+ 	}
+ 
++	if (tiniparser_getboolean(d, "global:pwd_change_prompt", false)) {
++		ctrl |= WINBIND_PWD_CHANGE_PROMPT;
++	}
++
+ config_from_pam:
+ 	/* step through arguments */
+ 	for (i=argc,v=argv; i-- > 0; ++v) {
+@@ -522,6 +526,8 @@ config_from_pam:
+ 		else if (!strncasecmp(*v, "warn_pwd_expire",
+ 			strlen("warn_pwd_expire")))
+ 			ctrl |= WINBIND_WARN_PWD_EXPIRE;
++		else if (!strcasecmp(*v, "pwd_change_prompt"))
++			ctrl |= WINBIND_PWD_CHANGE_PROMPT;
+ 		else if (type != PAM_WINBIND_CLEANUP) {
+ 			__pam_log(pamh, ctrl, LOG_ERR,
+ 				 "pam_parse: unknown option: %s", *v);
+@@ -976,7 +982,8 @@ static bool _pam_send_password_expiry_message(struct pwb_context *ctx,
+ 		 * successfully sent the warning message.
+ 		 * Give the user a chance to change pwd.
+ 		 */
+-		if (ret == PAM_SUCCESS) {
++		if (ret == PAM_SUCCESS &&
++		    (ctx->ctrl & WINBIND_PWD_CHANGE_PROMPT)) {
+ 			if (change_pwd) {
+ 				retval = _pam_winbind_change_pwd(ctx);
+ 				if (retval) {
+@@ -1006,7 +1013,8 @@ static bool _pam_send_password_expiry_message(struct pwb_context *ctx,
+ 		 * successfully sent the warning message.
+ 		 * Give the user a chance to change pwd.
+ 		 */
+-		if (ret == PAM_SUCCESS) {
++		if (ret == PAM_SUCCESS &&
++		    (ctx->ctrl & WINBIND_PWD_CHANGE_PROMPT)) {
+ 			if (change_pwd) {
+ 				retval = _pam_winbind_change_pwd(ctx);
+ 				if (retval) {
+diff --git a/nsswitch/pam_winbind.h b/nsswitch/pam_winbind.h
+index c6786d65a4d..2f4a25729bd 100644
+--- a/nsswitch/pam_winbind.h
++++ b/nsswitch/pam_winbind.h
+@@ -157,6 +157,7 @@ do {                             \
+ #define WINBIND_WARN_PWD_EXPIRE		0x00002000
+ #define WINBIND_MKHOMEDIR		0x00004000
+ #define WINBIND_TRY_AUTHTOK_ARG		0x00008000
++#define WINBIND_PWD_CHANGE_PROMPT	0x00010000
+ 
+ #if defined(HAVE_GETTEXT) && !defined(__LCLINT__)
+ #define _(string) dgettext(MODULE_NAME, string)
+-- 
+2.35.1
+
diff --git a/SOURCES/samba-printing-win7.patch b/SOURCES/samba-printing-win7.patch
new file mode 100644
index 0000000..d1a6b6a
--- /dev/null
+++ b/SOURCES/samba-printing-win7.patch
@@ -0,0 +1,229 @@
+From 10f485b3a27e10906aa6ee40833fca8bf81b5511 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze@samba.org>
+Date: Sat, 22 Jan 2022 01:08:26 +0100
+Subject: [PATCH] dcesrv_core: wrap gensec_*() calls in [un]become_root() calls
+
+This is important for the source3/rpc_server code as it might
+be called embedded in smbd and may not run as root with access
+to our private tdb/ldb files.
+
+Note this is only really needed for 4.15 and older, as
+we no longer run the rpc_server embedded in smbd,
+but we better be consistent for now.
+
+This should be able to fix the problem the printing no longer works
+on Windows 7 with 2021-10 monthly rollup patch (KB5006743).
+
+Windows uses NTLMSSP with privacy at the DCERPC layer on top
+of NCACN_NP (smb).
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=14867
+
+Signed-off-by: Stefan Metzmacher <metze@samba.org>
+Reviewed-by: Andreas Schneider <asn@samba.org>
+(cherry picked from commit 0651fa474cd68b18d8eb9bdc7c4ba5b847ba9ad9)
+---
+ librpc/rpc/dcesrv_auth.c         |  5 +++++
+ librpc/rpc/dcesrv_core.c         | 18 ++++++++++++++++++
+ librpc/rpc/dcesrv_core.h         |  2 ++
+ source3/rpc_server/rpc_config.c  |  2 ++
+ source4/rpc_server/service_rpc.c | 10 ++++++++++
+ 5 files changed, 37 insertions(+)
+
+diff --git a/librpc/rpc/dcesrv_auth.c b/librpc/rpc/dcesrv_auth.c
+index fec8df513a83..99d8e0162160 100644
+--- a/librpc/rpc/dcesrv_auth.c
++++ b/librpc/rpc/dcesrv_auth.c
+@@ -130,11 +130,13 @@ static bool dcesrv_auth_prepare_gensec(struct dcesrv_call_state *call)
+ 	auth->auth_level = call->in_auth_info.auth_level;
+ 	auth->auth_context_id = call->in_auth_info.auth_context_id;
+ 
++	cb->auth.become_root();
+ 	status = cb->auth.gensec_prepare(
+ 		auth,
+ 		call,
+ 		&auth->gensec_security,
+ 		cb->auth.private_data);
++	cb->auth.unbecome_root();
+ 	if (!NT_STATUS_IS_OK(status)) {
+ 		DEBUG(1, ("Failed to call samba_server_gensec_start %s\n",
+ 			  nt_errstr(status)));
+@@ -329,6 +331,7 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call)
+ NTSTATUS dcesrv_auth_complete(struct dcesrv_call_state *call, NTSTATUS status)
+ {
+ 	struct dcesrv_auth *auth = call->auth_state;
++	struct dcesrv_context_callbacks *cb = call->conn->dce_ctx->callbacks;
+ 	const char *pdu = "<unknown>";
+ 
+ 	switch (call->pkt.ptype) {
+@@ -359,9 +362,11 @@ NTSTATUS dcesrv_auth_complete(struct dcesrv_call_state *call, NTSTATUS status)
+ 		return status;
+ 	}
+ 
++	cb->auth.become_root();
+ 	status = gensec_session_info(auth->gensec_security,
+ 				     auth,
+ 				     &auth->session_info);
++	cb->auth.unbecome_root();
+ 	if (!NT_STATUS_IS_OK(status)) {
+ 		DEBUG(1, ("Failed to establish session_info: %s\n",
+ 			  nt_errstr(status)));
+diff --git a/librpc/rpc/dcesrv_core.c b/librpc/rpc/dcesrv_core.c
+index d16159b0b6cd..ea91fc689b4a 100644
+--- a/librpc/rpc/dcesrv_core.c
++++ b/librpc/rpc/dcesrv_core.c
+@@ -938,6 +938,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
+ 	struct dcerpc_binding *ep_2nd_description = NULL;
+ 	const char *endpoint = NULL;
+ 	struct dcesrv_auth *auth = call->auth_state;
++	struct dcesrv_context_callbacks *cb = call->conn->dce_ctx->callbacks;
+ 	struct dcerpc_ack_ctx *ack_ctx_list = NULL;
+ 	struct dcerpc_ack_ctx *ack_features = NULL;
+ 	struct tevent_req *subreq = NULL;
+@@ -1143,9 +1144,11 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
+ 		return dcesrv_auth_reply(call);
+ 	}
+ 
++	cb->auth.become_root();
+ 	subreq = gensec_update_send(call, call->event_ctx,
+ 				    auth->gensec_security,
+ 				    call->in_auth_info.credentials);
++	cb->auth.unbecome_root();
+ 	if (subreq == NULL) {
+ 		return NT_STATUS_NO_MEMORY;
+ 	}
+@@ -1160,10 +1163,13 @@ static void dcesrv_bind_done(struct tevent_req *subreq)
+ 		tevent_req_callback_data(subreq,
+ 		struct dcesrv_call_state);
+ 	struct dcesrv_connection *conn = call->conn;
++	struct dcesrv_context_callbacks *cb = call->conn->dce_ctx->callbacks;
+ 	NTSTATUS status;
+ 
++	cb->auth.become_root();
+ 	status = gensec_update_recv(subreq, call,
+ 				    &call->out_auth_info->credentials);
++	cb->auth.unbecome_root();
+ 	TALLOC_FREE(subreq);
+ 
+ 	status = dcesrv_auth_complete(call, status);
+@@ -1221,6 +1227,7 @@ static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
+ {
+ 	struct dcesrv_connection *conn = call->conn;
+ 	struct dcesrv_auth *auth = call->auth_state;
++	struct dcesrv_context_callbacks *cb = call->conn->dce_ctx->callbacks;
+ 	struct tevent_req *subreq = NULL;
+ 	NTSTATUS status;
+ 
+@@ -1265,9 +1272,11 @@ static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
+ 		return NT_STATUS_OK;
+ 	}
+ 
++	cb->auth.become_root();
+ 	subreq = gensec_update_send(call, call->event_ctx,
+ 				    auth->gensec_security,
+ 				    call->in_auth_info.credentials);
++	cb->auth.unbecome_root();
+ 	if (subreq == NULL) {
+ 		return NT_STATUS_NO_MEMORY;
+ 	}
+@@ -1283,10 +1292,13 @@ static void dcesrv_auth3_done(struct tevent_req *subreq)
+ 		struct dcesrv_call_state);
+ 	struct dcesrv_connection *conn = call->conn;
+ 	struct dcesrv_auth *auth = call->auth_state;
++	struct dcesrv_context_callbacks *cb = call->conn->dce_ctx->callbacks;
+ 	NTSTATUS status;
+ 
++	cb->auth.become_root();
+ 	status = gensec_update_recv(subreq, call,
+ 				    &call->out_auth_info->credentials);
++	cb->auth.unbecome_root();
+ 	TALLOC_FREE(subreq);
+ 
+ 	status = dcesrv_auth_complete(call, status);
+@@ -1555,6 +1567,7 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
+ 	struct ncacn_packet *pkt = &call->ack_pkt;
+ 	uint32_t extra_flags = 0;
+ 	struct dcesrv_auth *auth = call->auth_state;
++	struct dcesrv_context_callbacks *cb = call->conn->dce_ctx->callbacks;
+ 	struct dcerpc_ack_ctx *ack_ctx_list = NULL;
+ 	struct tevent_req *subreq = NULL;
+ 	size_t i;
+@@ -1666,9 +1679,11 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
+ 		return dcesrv_auth_reply(call);
+ 	}
+ 
++	cb->auth.become_root();
+ 	subreq = gensec_update_send(call, call->event_ctx,
+ 				    auth->gensec_security,
+ 				    call->in_auth_info.credentials);
++	cb->auth.unbecome_root();
+ 	if (subreq == NULL) {
+ 		return NT_STATUS_NO_MEMORY;
+ 	}
+@@ -1683,10 +1698,13 @@ static void dcesrv_alter_done(struct tevent_req *subreq)
+ 		tevent_req_callback_data(subreq,
+ 		struct dcesrv_call_state);
+ 	struct dcesrv_connection *conn = call->conn;
++	struct dcesrv_context_callbacks *cb = call->conn->dce_ctx->callbacks;
+ 	NTSTATUS status;
+ 
++	cb->auth.become_root();
+ 	status = gensec_update_recv(subreq, call,
+ 				    &call->out_auth_info->credentials);
++	cb->auth.unbecome_root();
+ 	TALLOC_FREE(subreq);
+ 
+ 	status = dcesrv_auth_complete(call, status);
+diff --git a/librpc/rpc/dcesrv_core.h b/librpc/rpc/dcesrv_core.h
+index d8d5f9030959..0538442e0ce6 100644
+--- a/librpc/rpc/dcesrv_core.h
++++ b/librpc/rpc/dcesrv_core.h
+@@ -392,6 +392,8 @@ struct dcesrv_context_callbacks {
+ 			struct gensec_security **out,
+ 			void *private_data);
+ 		void *private_data;
++		void (*become_root)(void);
++		void (*unbecome_root)(void);
+ 	} auth;
+ 	struct {
+ 		NTSTATUS (*find)(
+diff --git a/source3/rpc_server/rpc_config.c b/source3/rpc_server/rpc_config.c
+index 2f1a01da1c0b..289c4f398409 100644
+--- a/source3/rpc_server/rpc_config.c
++++ b/source3/rpc_server/rpc_config.c
+@@ -31,6 +31,8 @@
+ static struct dcesrv_context_callbacks srv_callbacks = {
+ 	.log.successful_authz = dcesrv_log_successful_authz,
+ 	.auth.gensec_prepare = dcesrv_auth_gensec_prepare,
++	.auth.become_root = become_root,
++	.auth.unbecome_root = unbecome_root,
+ 	.assoc_group.find = dcesrv_assoc_group_find,
+ };
+ 
+diff --git a/source4/rpc_server/service_rpc.c b/source4/rpc_server/service_rpc.c
+index d8c6746d7815..ebb50f8a7ef3 100644
+--- a/source4/rpc_server/service_rpc.c
++++ b/source4/rpc_server/service_rpc.c
+@@ -40,9 +40,19 @@
+ #include "../libcli/named_pipe_auth/npa_tstream.h"
+ #include "samba/process_model.h"
+ 
++static void skip_become_root(void)
++{
++}
++
++static void skip_unbecome_root(void)
++{
++}
++
+ static struct dcesrv_context_callbacks srv_callbacks = {
+ 	.log.successful_authz = log_successful_dcesrv_authz_event,
+ 	.auth.gensec_prepare = dcesrv_gensec_prepare,
++	.auth.become_root = skip_become_root,
++	.auth.unbecome_root = skip_unbecome_root,
+ 	.assoc_group.find = dcesrv_assoc_group_find,
+ };
+ 
+-- 
+2.25.1
+
diff --git a/SOURCES/samba-s4u.patch b/SOURCES/samba-s4u.patch
new file mode 100644
index 0000000..8e84d96
--- /dev/null
+++ b/SOURCES/samba-s4u.patch
@@ -0,0 +1,697 @@
+From 0b196043f08ea4c025f19c4519175a3a73e1d185 Mon Sep 17 00:00:00 2001
+From: Isaac Boukris <iboukris@gmail.com>
+Date: Fri, 27 Sep 2019 18:25:03 +0300
+Subject: [PATCH 1/3] mit-kdc: add basic loacl realm S4U support
+
+Signed-off-by: Isaac Boukris <iboukris@gmail.com>
+Pair-Programmed-With: Andreas Schneider <asn@samba.org>
+---
+ source4/kdc/mit-kdb/kdb_samba_policies.c | 124 +++++++++++------------
+ source4/kdc/mit_samba.c                  |  47 ++-------
+ source4/kdc/mit_samba.h                  |   6 +-
+ 3 files changed, 71 insertions(+), 106 deletions(-)
+
+diff --git a/source4/kdc/mit-kdb/kdb_samba_policies.c b/source4/kdc/mit-kdb/kdb_samba_policies.c
+index f35210669c2..b1c7c5dcc5e 100644
+--- a/source4/kdc/mit-kdb/kdb_samba_policies.c
++++ b/source4/kdc/mit-kdb/kdb_samba_policies.c
+@@ -195,13 +195,17 @@ static krb5_error_code ks_verify_pac(krb5_context context,
+ 				     krb5_keyblock *krbtgt_key,
+ 				     krb5_timestamp authtime,
+ 				     krb5_authdata **tgt_auth_data,
+-				     krb5_pac *pac)
++				     krb5_pac *out_pac)
+ {
+ 	struct mit_samba_context *mit_ctx;
+ 	krb5_authdata **authdata = NULL;
+-	krb5_pac ipac = NULL;
+-	DATA_BLOB logon_data = { NULL, 0 };
++	krb5_keyblock *header_server_key = NULL;
++	krb5_key_data *impersonator_kd = NULL;
++	krb5_keyblock impersonator_key = {0};
+ 	krb5_error_code code;
++	krb5_pac pac;
++
++	*out_pac = NULL;
+ 
+ 	mit_ctx = ks_get_context(context);
+ 	if (mit_ctx == NULL) {
+@@ -233,41 +237,43 @@ static krb5_error_code ks_verify_pac(krb5_context context,
+ 	code = krb5_pac_parse(context,
+ 			      authdata[0]->contents,
+ 			      authdata[0]->length,
+-			      &ipac);
++			      &pac);
+ 	if (code != 0) {
+ 		goto done;
+ 	}
+ 
+-	/* TODO: verify this is correct
+-	 *
+-	 * In the constrained delegation case, the PAC is from a service
+-	 * ticket rather than a TGT; we must verify the server and KDC
+-	 * signatures to assert that the server did not forge the PAC.
++	/*
++	 * For constrained delegation in MIT version < 1.18 we aren't provided
++	 * with the 2nd ticket server key to verify the PAC.
++	 * We can workaround that by fetching the key from the client db entry,
++	 * which is the impersonator account in that version.
++	 * TODO: use the provided entry in the new 1.18 version.
+ 	 */
+ 	if (flags & KRB5_KDB_FLAG_CONSTRAINED_DELEGATION) {
+-		code = krb5_pac_verify(context,
+-				       ipac,
+-				       authtime,
+-				       client_princ,
+-				       server_key,
+-				       krbtgt_key);
++		/* The impersonator must be local. */
++		if (client == NULL) {
++			code = KRB5KDC_ERR_BADOPTION;
++			goto done;
++		}
++		/* Fetch and decrypt 2nd ticket server's current key. */
++		code = krb5_dbe_find_enctype(context, client, -1, -1, 0,
++					     &impersonator_kd);
++		if (code != 0) {
++			goto done;
++		}
++		code = krb5_dbe_decrypt_key_data(context, NULL,
++						 impersonator_kd,
++						 &impersonator_key, NULL);
++		if (code != 0) {
++			goto done;
++		}
++		header_server_key = &impersonator_key;
+ 	} else {
+-		code = krb5_pac_verify(context,
+-				       ipac,
+-				       authtime,
+-				       client_princ,
+-				       krbtgt_key,
+-				       NULL);
+-	}
+-	if (code != 0) {
+-		goto done;
++		header_server_key = krbtgt_key;
+ 	}
+ 
+-	/* check and update PAC */
+-	code = krb5_pac_parse(context,
+-			      authdata[0]->contents,
+-			      authdata[0]->length,
+-			      pac);
++	code = krb5_pac_verify(context, pac, authtime, client_princ,
++			       header_server_key, NULL);
+ 	if (code != 0) {
+ 		goto done;
+ 	}
+@@ -275,17 +281,22 @@ static krb5_error_code ks_verify_pac(krb5_context context,
+ 	code = mit_samba_reget_pac(mit_ctx,
+ 				   context,
+ 				   flags,
+-				   client_princ,
+ 				   client,
+ 				   server,
+ 				   krbtgt,
+ 				   krbtgt_key,
+-				   pac);
++				   &pac);
++	if (code != 0) {
++		goto done;
++	}
++
++	*out_pac = pac;
++	pac = NULL;
+ 
+ done:
++	krb5_free_keyblock_contents(context, &impersonator_key);
+ 	krb5_free_authdata(context, authdata);
+-	krb5_pac_free(context, ipac);
+-	free(logon_data.data);
++	krb5_pac_free(context, pac);
+ 
+ 	return code;
+ }
+@@ -314,6 +325,7 @@ krb5_error_code kdb_samba_db_sign_auth_data(krb5_context context,
+ 	krb5_authdata **pac_auth_data = NULL;
+ 	krb5_authdata **authdata = NULL;
+ 	krb5_boolean is_as_req;
++	krb5_const_principal pac_client;
+ 	krb5_error_code code;
+ 	krb5_pac pac = NULL;
+ 	krb5_data pac_data;
+@@ -325,11 +337,6 @@ krb5_error_code kdb_samba_db_sign_auth_data(krb5_context context,
+ 	krbtgt = krbtgt == NULL ? local_krbtgt : krbtgt;
+ 	krbtgt_key = krbtgt_key == NULL ? local_krbtgt_key : krbtgt_key;
+ 
+-	/* FIXME: We don't support S4U yet */
+-	if (flags & KRB5_KDB_FLAGS_S4U) {
+-		return KRB5_KDB_DBTYPE_NOSUP;
+-	}
+-
+ 	is_as_req = ((flags & KRB5_KDB_FLAG_CLIENT_REFERRALS_ONLY) != 0);
+ 
+ 	/*
+@@ -390,6 +397,16 @@ krb5_error_code kdb_samba_db_sign_auth_data(krb5_context context,
+ 		ks_client_princ = client->princ;
+ 	}
+ 
++	/* In protocol transition, we are currently not provided with the tgt
++	 * client name to verify the PAC, we could probably skip the name
++	 * verification and just verify the signatures, but since we don't
++	 * support cross-realm nor aliases, we can just use server->princ */
++	if (flags & KRB5_KDB_FLAG_PROTOCOL_TRANSITION) {
++		pac_client = server->princ;
++	} else {
++		pac_client = ks_client_princ;
++	}
++
+ 	if (client_entry == NULL) {
+ 		client_entry = client;
+ 	}
+@@ -454,7 +471,7 @@ krb5_error_code kdb_samba_db_sign_auth_data(krb5_context context,
+ 
+ 			code = ks_verify_pac(context,
+ 					     flags,
+-					     ks_client_princ,
++					     pac_client,
+ 					     client_entry,
+ 					     server,
+ 					     krbtgt,
+@@ -494,7 +511,7 @@ krb5_error_code kdb_samba_db_sign_auth_data(krb5_context context,
+ 		  is_as_req ? "AS-REQ" : "TGS-REQ",
+ 		  client_name);
+ 	code = krb5_pac_sign(context, pac, authtime, ks_client_princ,
+-			server_key, krbtgt_key, &pac_data);
++			     server_key, krbtgt_key, &pac_data);
+ 	if (code != 0) {
+ 		DBG_ERR("krb5_pac_sign failed: %d\n", code);
+ 		goto done;
+@@ -520,12 +537,6 @@ krb5_error_code kdb_samba_db_sign_auth_data(krb5_context context,
+ 					      KRB5_AUTHDATA_IF_RELEVANT,
+ 					      authdata,
+ 					      signed_auth_data);
+-	if (code != 0) {
+-		goto done;
+-	}
+-
+-	code = 0;
+-
+ done:
+ 	if (client_entry != NULL && client_entry != client) {
+ 		ks_free_principal(context, client_entry);
+@@ -551,32 +562,13 @@ krb5_error_code kdb_samba_db_check_allowed_to_delegate(krb5_context context,
+ 	 * server; -> delegating service
+ 	 * proxy; -> target principal
+ 	 */
+-	krb5_db_entry *delegating_service = discard_const_p(krb5_db_entry, server);
+-
+-	char *target_name = NULL;
+-	bool is_enterprise;
+-	krb5_error_code code;
+ 
+ 	mit_ctx = ks_get_context(context);
+ 	if (mit_ctx == NULL) {
+ 		return KRB5_KDB_DBNOTINITED;
+ 	}
+ 
+-	code = krb5_unparse_name(context, proxy, &target_name);
+-	if (code) {
+-		goto done;
+-	}
+-
+-	is_enterprise = (proxy->type == KRB5_NT_ENTERPRISE_PRINCIPAL);
+-
+-	code = mit_samba_check_s4u2proxy(mit_ctx,
+-					 delegating_service,
+-					 target_name,
+-					 is_enterprise);
+-
+-done:
+-	free(target_name);
+-	return code;
++	return mit_samba_check_s4u2proxy(mit_ctx, server, proxy);
+ }
+ 
+ 
+diff --git a/source4/kdc/mit_samba.c b/source4/kdc/mit_samba.c
+index 4239332f0d9..acc3cba6254 100644
+--- a/source4/kdc/mit_samba.c
++++ b/source4/kdc/mit_samba.c
+@@ -501,7 +501,6 @@ int mit_samba_get_pac(struct mit_samba_context *smb_ctx,
+ krb5_error_code mit_samba_reget_pac(struct mit_samba_context *ctx,
+ 				    krb5_context context,
+ 				    int flags,
+-				    krb5_const_principal client_principal,
+ 				    krb5_db_entry *client,
+ 				    krb5_db_entry *server,
+ 				    krb5_db_entry *krbtgt,
+@@ -665,7 +664,7 @@ krb5_error_code mit_samba_reget_pac(struct mit_samba_context *ctx,
+ 								  context,
+ 								  *pac,
+ 								  server->princ,
+-								  discard_const(client_principal),
++								  client->princ,
+ 								  deleg_blob);
+ 		if (!NT_STATUS_IS_OK(nt_status)) {
+ 			DEBUG(0, ("Update delegation info failed: %s\n",
+@@ -987,41 +986,17 @@ int mit_samba_check_client_access(struct mit_samba_context *ctx,
+ }
+ 
+ int mit_samba_check_s4u2proxy(struct mit_samba_context *ctx,
+-			      krb5_db_entry *kentry,
+-			      const char *target_name,
+-			      bool is_nt_enterprise_name)
++			      const krb5_db_entry *server,
++			      krb5_const_principal target_principal)
+ {
+-#if 1
+-	/*
+-	 * This is disabled because mit_samba_update_pac_data() does not handle
+-	 * S4U_DELEGATION_INFO
+-	 */
+-
+-	return KRB5KDC_ERR_BADOPTION;
+-#else
+-	krb5_principal target_principal;
+-	int flags = 0;
+-	int ret;
+-
+-	if (is_nt_enterprise_name) {
+-		flags = KRB5_PRINCIPAL_PARSE_ENTERPRISE;
+-	}
+-
+-	ret = krb5_parse_name_flags(ctx->context, target_name,
+-				    flags, &target_principal);
+-	if (ret) {
+-		return ret;
+-	}
+-
+-	ret = samba_kdc_check_s4u2proxy(ctx->context,
+-					ctx->db_ctx,
+-					skdc_entry,
+-					target_principal);
+-
+-	krb5_free_principal(ctx->context, target_principal);
+-
+-	return ret;
+-#endif
++	struct samba_kdc_entry *server_skdc_entry =
++		 talloc_get_type_abort(server->e_data,
++				       struct samba_kdc_entry);
++
++	return samba_kdc_check_s4u2proxy(ctx->context,
++					 ctx->db_ctx,
++					 server_skdc_entry,
++					 target_principal);
+ }
+ 
+ static krb5_error_code mit_samba_change_pwd_error(krb5_context context,
+diff --git a/source4/kdc/mit_samba.h b/source4/kdc/mit_samba.h
+index 636c77ec97c..9cb00c9610e 100644
+--- a/source4/kdc/mit_samba.h
++++ b/source4/kdc/mit_samba.h
+@@ -56,7 +56,6 @@ int mit_samba_get_pac(struct mit_samba_context *smb_ctx,
+ krb5_error_code mit_samba_reget_pac(struct mit_samba_context *ctx,
+ 				    krb5_context context,
+ 				    int flags,
+-				    krb5_const_principal client_principal,
+ 				    krb5_db_entry *client,
+ 				    krb5_db_entry *server,
+ 				    krb5_db_entry *krbtgt,
+@@ -73,9 +72,8 @@ int mit_samba_check_client_access(struct mit_samba_context *ctx,
+ 				  DATA_BLOB *e_data);
+ 
+ int mit_samba_check_s4u2proxy(struct mit_samba_context *ctx,
+-			      krb5_db_entry *kentry,
+-			      const char *target_name,
+-			      bool is_nt_enterprise_name);
++			      const krb5_db_entry *server,
++			      krb5_const_principal target_principal);
+ 
+ int mit_samba_kpasswd_change_password(struct mit_samba_context *ctx,
+ 				      char *pwd,
+-- 
+2.33.1
+
+
+From 992d38fa35c01f2f0bdb39d387fa29e8eb8d3d37 Mon Sep 17 00:00:00 2001
+From: Isaac Boukris <iboukris@gmail.com>
+Date: Fri, 27 Sep 2019 18:35:30 +0300
+Subject: [PATCH 2/3] krb5-mit: enable S4U client support for MIT build
+
+Signed-off-by: Isaac Boukris <iboukris@gmail.com>
+Pair-Programmed-With: Andreas Schneider <asn@samba.org>
+---
+ lib/krb5_wrap/krb5_samba.c            | 185 ++++++++++++++++++++++++++
+ lib/krb5_wrap/krb5_samba.h            |   2 -
+ source4/auth/kerberos/kerberos_util.c |  11 --
+ 3 files changed, 185 insertions(+), 13 deletions(-)
+
+diff --git a/lib/krb5_wrap/krb5_samba.c b/lib/krb5_wrap/krb5_samba.c
+index fff5b4e2a22..791b417d5ba 100644
+--- a/lib/krb5_wrap/krb5_samba.c
++++ b/lib/krb5_wrap/krb5_samba.c
+@@ -2694,6 +2694,191 @@ krb5_error_code smb_krb5_kinit_s4u2_ccache(krb5_context ctx,
+ 
+ 	return 0;
+ }
++
++#else /* MIT */
++
++static bool princ_compare_no_dollar(krb5_context ctx,
++				    krb5_principal a,
++				    krb5_principal b)
++{
++	bool cmp;
++	krb5_principal mod = NULL;
++
++	if (a->length == 1 && b->length == 1 &&
++	    a->data[0].length != 0 && b->data[0].length != 0 &&
++	    a->data[0].data[a->data[0].length -1] !=
++	    b->data[0].data[b->data[0].length -1]) {
++		if (a->data[0].data[a->data[0].length -1] == '$') {
++			mod = a;
++			mod->data[0].length--;
++		} else if (b->data[0].data[b->data[0].length -1] == '$') {
++			mod = b;
++			mod->data[0].length--;
++		}
++	}
++
++	cmp = krb5_principal_compare_flags(ctx, a, b,
++					   KRB5_PRINCIPAL_COMPARE_CASEFOLD);
++
++	if (mod != NULL) {
++		mod->data[0].length++;
++	}
++
++	return cmp;
++}
++
++krb5_error_code smb_krb5_kinit_s4u2_ccache(krb5_context ctx,
++					   krb5_ccache store_cc,
++					   krb5_principal init_principal,
++					   const char *init_password,
++					   krb5_principal impersonate_principal,
++					   const char *self_service,
++					   const char *target_service,
++					   krb5_get_init_creds_opt *krb_options,
++					   time_t *expire_time,
++					   time_t *kdc_time)
++{
++	krb5_error_code code;
++	krb5_principal self_princ = NULL;
++	krb5_principal target_princ = NULL;
++	krb5_creds *store_creds;
++	krb5_creds *s4u2self_creds = NULL;
++	krb5_creds *s4u2proxy_creds = NULL;
++	krb5_creds init_creds = {0};
++	krb5_creds mcreds = {0};
++	krb5_flags options = KRB5_GC_NO_STORE;
++	krb5_ccache tmp_cc;
++	bool s4u2proxy;
++
++	code = krb5_cc_new_unique(ctx, "MEMORY", NULL, &tmp_cc);
++	if (code != 0) {
++		return code;
++	}
++
++	code = krb5_get_init_creds_password(ctx, &init_creds,
++					    init_principal,
++					    init_password,
++					    NULL, NULL,
++					    0,
++					    NULL,
++					    krb_options);
++	if (code != 0) {
++		goto done;
++	}
++
++	code = krb5_cc_initialize(ctx, tmp_cc, init_creds.client);
++	if (code != 0) {
++		goto done;
++	}
++
++	code = krb5_cc_store_cred(ctx, tmp_cc, &init_creds);
++	if (code != 0) {
++		goto done;
++	}
++
++	/*
++	 * Check if we also need S4U2Proxy or if S4U2Self is
++	 * enough in order to get a ticket for the target.
++	 */
++	if (target_service == NULL) {
++		s4u2proxy = false;
++	} else if (strcmp(target_service, self_service) == 0) {
++		s4u2proxy = false;
++	} else {
++		s4u2proxy = true;
++	}
++
++	code = krb5_parse_name(ctx, self_service, &self_princ);
++	if (code != 0) {
++		goto done;
++	}
++
++	/* MIT lacks aliases support in S4U, for S4U2Self we require the tgt
++	 * client and the request server to be the same principal name. */
++	if (!princ_compare_no_dollar(ctx, init_creds.client, self_princ)) {
++		code = KRB5KDC_ERR_PADATA_TYPE_NOSUPP;
++		goto done;
++	}
++
++	mcreds.client = impersonate_principal;
++	mcreds.server = init_creds.client;
++
++	code = krb5_get_credentials_for_user(ctx, options, tmp_cc, &mcreds,
++					     NULL, &s4u2self_creds);
++	if (code != 0) {
++		goto done;
++	}
++
++	if (s4u2proxy) {
++		code = krb5_parse_name(ctx, target_service, &target_princ);
++		if (code != 0) {
++			goto done;
++		}
++
++		mcreds.client = init_creds.client;
++		mcreds.server = target_princ;
++		mcreds.second_ticket = s4u2self_creds->ticket;
++
++		code = krb5_get_credentials(ctx, options |
++					    KRB5_GC_CONSTRAINED_DELEGATION,
++					    tmp_cc, &mcreds, &s4u2proxy_creds);
++		if (code != 0) {
++			goto done;
++		}
++
++		/* Check KDC support of S4U2Proxy extension */
++		if (!krb5_principal_compare(ctx, s4u2self_creds->client,
++					    s4u2proxy_creds->client)) {
++			code = KRB5KDC_ERR_PADATA_TYPE_NOSUPP;
++			goto done;
++		}
++
++		store_creds = s4u2proxy_creds;
++	} else {
++		store_creds = s4u2self_creds;;
++
++		/* We need to save the ticket with the requested server name
++		 * or the caller won't be able to find it in cache. */
++		if (!krb5_principal_compare(ctx, self_princ,
++			store_creds->server)) {
++			krb5_free_principal(ctx, store_creds->server);
++			store_creds->server = NULL;
++			code = krb5_copy_principal(ctx, self_princ,
++						   &store_creds->server);
++			if (code != 0) {
++				goto done;
++			}
++		}
++	}
++
++	code = krb5_cc_initialize(ctx, store_cc, store_creds->client);
++	if (code != 0) {
++		goto done;
++	}
++
++	code = krb5_cc_store_cred(ctx, store_cc, store_creds);
++	if (code != 0) {
++		goto done;
++	}
++
++	if (expire_time) {
++		*expire_time = (time_t) store_creds->times.endtime;
++	}
++
++	if (kdc_time) {
++		*kdc_time = (time_t) store_creds->times.starttime;
++	}
++
++done:
++	krb5_cc_destroy(ctx, tmp_cc);
++	krb5_free_cred_contents(ctx, &init_creds);
++	krb5_free_creds(ctx, s4u2self_creds);
++	krb5_free_creds(ctx, s4u2proxy_creds);
++	krb5_free_principal(ctx, self_princ);
++	krb5_free_principal(ctx, target_princ);
++
++	return code;
++}
+ #endif
+ 
+ #if !defined(HAVE_KRB5_MAKE_PRINCIPAL) && defined(HAVE_KRB5_BUILD_PRINCIPAL_ALLOC_VA)
+diff --git a/lib/krb5_wrap/krb5_samba.h b/lib/krb5_wrap/krb5_samba.h
+index eab67f6d969..b5385c69a33 100644
+--- a/lib/krb5_wrap/krb5_samba.h
++++ b/lib/krb5_wrap/krb5_samba.h
+@@ -252,7 +252,6 @@ krb5_error_code smb_krb5_kinit_password_ccache(krb5_context ctx,
+ 					       krb5_get_init_creds_opt *krb_options,
+ 					       time_t *expire_time,
+ 					       time_t *kdc_time);
+-#ifdef SAMBA4_USES_HEIMDAL
+ krb5_error_code smb_krb5_kinit_s4u2_ccache(krb5_context ctx,
+ 					   krb5_ccache store_cc,
+ 					   krb5_principal init_principal,
+@@ -263,7 +262,6 @@ krb5_error_code smb_krb5_kinit_s4u2_ccache(krb5_context ctx,
+ 					   krb5_get_init_creds_opt *krb_options,
+ 					   time_t *expire_time,
+ 					   time_t *kdc_time);
+-#endif
+ 
+ #if defined(HAVE_KRB5_MAKE_PRINCIPAL)
+ #define smb_krb5_make_principal krb5_make_principal
+diff --git a/source4/auth/kerberos/kerberos_util.c b/source4/auth/kerberos/kerberos_util.c
+index 544d9d853cc..c14d8c72d8c 100644
+--- a/source4/auth/kerberos/kerberos_util.c
++++ b/source4/auth/kerberos/kerberos_util.c
+@@ -234,9 +234,7 @@ done:
+ {
+ 	krb5_error_code ret;
+ 	const char *password;
+-#ifdef SAMBA4_USES_HEIMDAL
+ 	const char *self_service;
+-#endif
+ 	const char *target_service;
+ 	time_t kdc_time = 0;
+ 	krb5_principal princ;
+@@ -268,9 +266,7 @@ done:
+ 		return ret;
+ 	}
+ 
+-#ifdef SAMBA4_USES_HEIMDAL
+ 	self_service = cli_credentials_get_self_service(credentials);
+-#endif
+ 	target_service = cli_credentials_get_target_service(credentials);
+ 
+ 	password = cli_credentials_get_password(credentials);
+@@ -331,7 +327,6 @@ done:
+ #endif
+ 		if (password) {
+ 			if (impersonate_principal) {
+-#ifdef SAMBA4_USES_HEIMDAL
+ 				ret = smb_krb5_kinit_s4u2_ccache(smb_krb5_context->krb5_context,
+ 								 ccache,
+ 								 princ,
+@@ -342,12 +337,6 @@ done:
+ 								 krb_options,
+ 								 NULL,
+ 								 &kdc_time);
+-#else
+-				talloc_free(mem_ctx);
+-				(*error_string) = "INTERNAL error: s4u2 ops "
+-					"are not supported with MIT build yet";
+-				return EINVAL;
+-#endif
+ 			} else {
+ 				ret = smb_krb5_kinit_password_ccache(smb_krb5_context->krb5_context,
+ 								     ccache,
+-- 
+2.33.1
+
+
+From f1951b501ca0fb3e613f04437c99dc1bbf204609 Mon Sep 17 00:00:00 2001
+From: Isaac Boukris <iboukris@gmail.com>
+Date: Sat, 19 Sep 2020 14:16:20 +0200
+Subject: [PATCH 3/3] wip: for canonicalization with new MIT kdc code
+
+---
+ source4/heimdal/lib/hdb/hdb.h | 1 +
+ source4/kdc/db-glue.c         | 8 ++++++--
+ source4/kdc/mit_samba.c       | 3 +++
+ source4/kdc/sdb.h             | 1 +
+ 4 files changed, 11 insertions(+), 2 deletions(-)
+
+diff --git a/source4/heimdal/lib/hdb/hdb.h b/source4/heimdal/lib/hdb/hdb.h
+index 5ef9d9565f3..dafaffc6c2d 100644
+--- a/source4/heimdal/lib/hdb/hdb.h
++++ b/source4/heimdal/lib/hdb/hdb.h
+@@ -63,6 +63,7 @@ enum hdb_lockop{ HDB_RLOCK, HDB_WLOCK };
+ #define HDB_F_ALL_KVNOS		2048	/* we want all the keys, live or not */
+ #define HDB_F_FOR_AS_REQ	4096	/* fetch is for a AS REQ */
+ #define HDB_F_FOR_TGS_REQ	8192	/* fetch is for a TGS REQ */
++#define HDB_F_FORCE_CANON	16384	/* force canonicalition */
+ 
+ /* hdb_capability_flags */
+ #define HDB_CAP_F_HANDLE_ENTERPRISE_PRINCIPAL 1
+diff --git a/source4/kdc/db-glue.c b/source4/kdc/db-glue.c
+index aff74f2ee71..d16b4c3329a 100644
+--- a/source4/kdc/db-glue.c
++++ b/source4/kdc/db-glue.c
+@@ -916,17 +916,21 @@ static krb5_error_code samba_kdc_message2entry(krb5_context context,
+ 			}
+ 		}
+ 
+-	} else if (ent_type == SAMBA_KDC_ENT_TYPE_ANY && principal == NULL) {
++	} else if (ent_type == SAMBA_KDC_ENT_TYPE_ANY && principal == NULL) { // was this supposed to be || ?
+ 		ret = smb_krb5_make_principal(context, &entry_ex->entry.principal, lpcfg_realm(lp_ctx), samAccountName, NULL);
+ 		if (ret) {
+ 			krb5_clear_error_message(context);
+ 			goto out;
+ 		}
+-	} else if ((flags & SDB_F_CANON) && (flags & SDB_F_FOR_AS_REQ)) {
++	} else if (((flags & SDB_F_CANON) && (flags & SDB_F_FOR_AS_REQ)) || (flags & SDB_F_FORCE_CANON)){
+ 		/*
+ 		 * SDB_F_CANON maps from the canonicalize flag in the
+ 		 * packet, and has a different meaning between AS-REQ
+ 		 * and TGS-REQ.  We only change the principal in the AS-REQ case
++		 *
++		 * The SDB_F_FORCE_CANON if for the new MIT kdc code that wants
++		 * the canonical name in all lookups, and takes care to canonicalize
++		 * only when appropriate.
+ 		 */
+ 		ret = smb_krb5_make_principal(context, &entry_ex->entry.principal, lpcfg_realm(lp_ctx), samAccountName, NULL);
+ 		if (ret) {
+diff --git a/source4/kdc/mit_samba.c b/source4/kdc/mit_samba.c
+index acc3cba6254..f0b9df8b613 100644
+--- a/source4/kdc/mit_samba.c
++++ b/source4/kdc/mit_samba.c
+@@ -224,6 +224,9 @@ int mit_samba_get_principal(struct mit_samba_context *ctx,
+ 	if (kflags & KRB5_KDB_FLAG_CANONICALIZE) {
+ 		sflags |= SDB_F_CANON;
+ 	}
++#if KRB5_KDB_API_VERSION >= 10
++	sflags |= SDB_F_FORCE_CANON;
++#endif
+ 	if (kflags & (KRB5_KDB_FLAG_CLIENT_REFERRALS_ONLY |
+ 		      KRB5_KDB_FLAG_INCLUDE_PAC)) {
+ 		/*
+diff --git a/source4/kdc/sdb.h b/source4/kdc/sdb.h
+index c929acccce6..a9115ec23d7 100644
+--- a/source4/kdc/sdb.h
++++ b/source4/kdc/sdb.h
+@@ -116,6 +116,7 @@ struct sdb_entry_ex {
+ #define SDB_F_KVNO_SPECIFIED	128	/* we want a particular KVNO */
+ #define SDB_F_FOR_AS_REQ	4096	/* fetch is for a AS REQ */
+ #define SDB_F_FOR_TGS_REQ	8192	/* fetch is for a TGS REQ */
++#define SDB_F_FORCE_CANON	16384	/* force canonicalition */
+ 
+ void sdb_free_entry(struct sdb_entry_ex *e);
+ void free_sdb_entry(struct sdb_entry *s);
+-- 
+2.33.1
+
diff --git a/SOURCES/samba-virus_scanner.patch b/SOURCES/samba-virus_scanner.patch
new file mode 100644
index 0000000..6e243da
--- /dev/null
+++ b/SOURCES/samba-virus_scanner.patch
@@ -0,0 +1,597 @@
+From 1b14752bebbdecbb7c89c7fe03853bdf4dff6f64 Mon Sep 17 00:00:00 2001
+From: Andreas Schneider <asn@samba.org>
+Date: Wed, 9 Feb 2022 16:33:10 +0100
+Subject: [PATCH 1/6] selftest: Do not force -d0 for smbd/nmbd/winbindd
+
+We have the env variable SERVER_LOG_LEVEL which allows you to change
+the log level on the command line. If we force -d0 this will not work.
+
+make test TESTS="samba" SERVER_LOG_LEVEL=10
+
+Signed-off-by: Andreas Schneider <asn@samba.org>
+Reviewed-by: Jeremy Allison <jra@samba.org>
+(cherry picked from commit 9693f7ea7383c6a51ab58b7c8255b30206f18a3b)
+---
+ selftest/target/Samba3.pm | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
+index b901fd2677a..64a9a791a61 100755
+--- a/selftest/target/Samba3.pm
++++ b/selftest/target/Samba3.pm
+@@ -2153,7 +2153,7 @@ sub make_bin_cmd
+ {
+ 	my ($self, $binary, $env_vars, $options, $valgrind, $dont_log_stdout) = @_;
+ 
+-	my @optargs = ("-d0");
++	my @optargs = ();
+ 	if (defined($options)) {
+ 		@optargs = split(/ /, $options);
+ 	}
+-- 
+2.34.1
+
+
+From 22c2899dfc787736c19857997291c151886b7ac0 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Pavel=20Filipensk=C3=BD?= <pfilipen@redhat.com>
+Date: Tue, 8 Feb 2022 12:07:03 +0100
+Subject: [PATCH 2/6] s3:modules: Implement dummy virus scanner that uses
+ filename matching
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Bug: https://bugzilla.samba.org/show_bug.cgi?id=14971
+
+Signed-off-by: Pavel Filipenský <pfilipen@redhat.com>
+Reviewed-by: Jeremy Allison <jra@samba.org>
+Reviewed-by: Andreas Schneider <asn@samba.org>
+(cherry picked from commit 9f34babec7c6aca3d91f226705d3b3996792e5f1)
+---
+ source3/modules/vfs_virusfilter.c        | 12 +++++
+ source3/modules/vfs_virusfilter_common.h |  4 ++
+ source3/modules/vfs_virusfilter_dummy.c  | 58 ++++++++++++++++++++++++
+ source3/modules/wscript_build            |  1 +
+ 4 files changed, 75 insertions(+)
+ create mode 100644 source3/modules/vfs_virusfilter_dummy.c
+
+diff --git a/source3/modules/vfs_virusfilter.c b/source3/modules/vfs_virusfilter.c
+index 9fafe4e5d41..e6cbee7cd45 100644
+--- a/source3/modules/vfs_virusfilter.c
++++ b/source3/modules/vfs_virusfilter.c
+@@ -35,12 +35,14 @@
+ 
+ enum virusfilter_scanner_enum {
+ 	VIRUSFILTER_SCANNER_CLAMAV,
++	VIRUSFILTER_SCANNER_DUMMY,
+ 	VIRUSFILTER_SCANNER_FSAV,
+ 	VIRUSFILTER_SCANNER_SOPHOS
+ };
+ 
+ static const struct enum_list scanner_list[] = {
+ 	{ VIRUSFILTER_SCANNER_CLAMAV,	"clamav" },
++	{ VIRUSFILTER_SCANNER_DUMMY,	"dummy" },
+ 	{ VIRUSFILTER_SCANNER_FSAV,	"fsav" },
+ 	{ VIRUSFILTER_SCANNER_SOPHOS,	"sophos" },
+ 	{ -1,				NULL }
+@@ -199,6 +201,7 @@ static int virusfilter_vfs_connect(
+ 	int snum = SNUM(handle->conn);
+ 	struct virusfilter_config *config = NULL;
+ 	const char *exclude_files = NULL;
++	const char *infected_files = NULL;
+ 	const char *temp_quarantine_dir_mode = NULL;
+ 	const char *infected_file_command = NULL;
+ 	const char *scan_error_command = NULL;
+@@ -255,6 +258,12 @@ static int virusfilter_vfs_connect(
+ 		set_namearray(&config->exclude_files, exclude_files);
+ 	}
+ 
++	infected_files = lp_parm_const_string(
++		snum, "virusfilter", "infected files", NULL);
++	if (infected_files != NULL) {
++		set_namearray(&config->infected_files, infected_files);
++	}
++
+ 	config->cache_entry_limit = lp_parm_int(
+ 		snum, "virusfilter", "cache entry limit", 100);
+ 
+@@ -537,6 +546,9 @@ static int virusfilter_vfs_connect(
+ 	case VIRUSFILTER_SCANNER_CLAMAV:
+ 		ret = virusfilter_clamav_init(config);
+ 		break;
++	case VIRUSFILTER_SCANNER_DUMMY:
++		ret = virusfilter_dummy_init(config);
++		break;
+ 	default:
+ 		DBG_ERR("Unhandled scanner %d\n", backend);
+ 		return -1;
+diff --git a/source3/modules/vfs_virusfilter_common.h b/source3/modules/vfs_virusfilter_common.h
+index f71b0b949a7..463a9d74e9c 100644
+--- a/source3/modules/vfs_virusfilter_common.h
++++ b/source3/modules/vfs_virusfilter_common.h
+@@ -83,6 +83,9 @@ struct virusfilter_config {
+ 	/* Exclude files */
+ 	name_compare_entry		*exclude_files;
+ 
++	/* Infected files */
++	name_compare_entry		*infected_files;
++
+ 	/* Scan result cache */
+ 	struct virusfilter_cache	*cache;
+ 	int				cache_entry_limit;
+@@ -149,5 +152,6 @@ struct virusfilter_backend {
+ int virusfilter_sophos_init(struct virusfilter_config *config);
+ int virusfilter_fsav_init(struct virusfilter_config *config);
+ int virusfilter_clamav_init(struct virusfilter_config *config);
++int virusfilter_dummy_init(struct virusfilter_config *config);
+ 
+ #endif /* _VIRUSFILTER_COMMON_H */
+diff --git a/source3/modules/vfs_virusfilter_dummy.c b/source3/modules/vfs_virusfilter_dummy.c
+new file mode 100644
+index 00000000000..03405cd6629
+--- /dev/null
++++ b/source3/modules/vfs_virusfilter_dummy.c
+@@ -0,0 +1,58 @@
++/*
++   Samba-VirusFilter VFS modules
++   Dummy scanner with infected files support.
++   Copyright (C) 2022 Pavel Filipenský <pfilipen@redhat.com>
++
++   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 "modules/vfs_virusfilter_utils.h"
++
++static virusfilter_result virusfilter_dummy_scan(
++	struct vfs_handle_struct *handle,
++	struct virusfilter_config *config,
++	const struct files_struct *fsp,
++	char **reportp)
++{
++	bool ok;
++
++	DBG_INFO("Scanning file: %s\n", fsp_str_dbg(fsp));
++	ok = is_in_path(fsp->fsp_name->base_name,
++			config->infected_files,
++			false);
++	return ok ? VIRUSFILTER_RESULT_INFECTED : VIRUSFILTER_RESULT_CLEAN;
++}
++
++static struct virusfilter_backend_fns virusfilter_backend_dummy = {
++	.connect = NULL,
++	.disconnect = NULL,
++	.scan_init = NULL,
++	.scan = virusfilter_dummy_scan,
++	.scan_end = NULL,
++};
++
++int virusfilter_dummy_init(struct virusfilter_config *config)
++{
++	struct virusfilter_backend *backend = NULL;
++
++	backend = talloc_zero(config, struct virusfilter_backend);
++	if (backend == NULL) {
++		return -1;
++	}
++
++	backend->fns = &virusfilter_backend_dummy;
++	backend->name = "dummy";
++	config->backend = backend;
++	return 0;
++}
+diff --git a/source3/modules/wscript_build b/source3/modules/wscript_build
+index 40df4539392..ff318c3fa06 100644
+--- a/source3/modules/wscript_build
++++ b/source3/modules/wscript_build
+@@ -591,6 +591,7 @@ bld.SAMBA3_MODULE('vfs_virusfilter',
+                  vfs_virusfilter_sophos.c
+                  vfs_virusfilter_fsav.c
+                  vfs_virusfilter_clamav.c
++                 vfs_virusfilter_dummy.c
+                  ''',
+                  deps='samba-util VFS_VIRUSFILTER_UTILS',
+                  init_function='',
+-- 
+2.34.1
+
+
+From a813dc2adec352a85ec526ac9a3ec67139b730d3 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Pavel=20Filipensk=C3=BD?= <pfilipen@redhat.com>
+Date: Tue, 8 Feb 2022 22:35:29 +0100
+Subject: [PATCH 3/6] docs-xml:manpages: Document 'dummy' virusfilter and
+ 'virusfilter:infected files'
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Bug: https://bugzilla.samba.org/show_bug.cgi?id=14971
+
+Signed-off-by: Pavel Filipenský <pfilipen@redhat.com>
+Reviewed-by: Jeremy Allison <jra@samba.org>
+Reviewed-by: Andreas Schneider <asn@samba.org>
+(cherry picked from commit 2fd518e5cc63221c162c9b3f8526b9b7c9e34969)
+---
+ docs-xml/manpages/vfs_virusfilter.8.xml | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/docs-xml/manpages/vfs_virusfilter.8.xml b/docs-xml/manpages/vfs_virusfilter.8.xml
+index 329a35af68a..88f91d73a42 100644
+--- a/docs-xml/manpages/vfs_virusfilter.8.xml
++++ b/docs-xml/manpages/vfs_virusfilter.8.xml
+@@ -48,6 +48,10 @@
+ 		  scanner</para></listitem>
+ 		  <listitem><para><emphasis>clamav</emphasis>, the ClamAV
+ 		  scanner</para></listitem>
++		  <listitem><para><emphasis>dummy</emphasis>, dummy scanner used in
++		  tests. Checks against the <emphasis>infected files</emphasis>
++		  parameter and flags any name that matches as infected.
++		  </para></listitem>
+ 		</itemizedlist>
+ 		</listitem>
+ 		</varlistentry>
+@@ -264,6 +268,14 @@
+ 		</listitem>
+ 		</varlistentry>
+ 
++		<varlistentry>
++		<term>virusfilter:infected files = empty</term>
++		<listitem>
++		<para>Files that virusfilter <emphasis>dummy</emphasis> flags as infected.</para>
++		<para>If this option is not set, the default is empty.</para>
++		</listitem>
++		</varlistentry>
++
+ 		<varlistentry>
+ 		<term>virusfilter:block access on error = false</term>
+ 		<listitem>
+-- 
+2.34.1
+
+
+From b67c6fe07a506627439c6ffd07e687befbc122ba Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Pavel=20Filipensk=C3=BD?= <pfilipen@redhat.com>
+Date: Tue, 8 Feb 2022 15:34:56 +0100
+Subject: [PATCH 4/6] selftest: Fix trailing whitespace in Samba3.pm
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Bug: https://bugzilla.samba.org/show_bug.cgi?id=14971
+
+Signed-off-by: Pavel Filipenský <pfilipen@redhat.com>
+Reviewed-by: Jeremy Allison <jra@samba.org>
+Reviewed-by: Andreas Schneider <asn@samba.org>
+(cherry picked from commit 547b4c595a8513a4be99177edbaa39ce43840f7a)
+---
+ selftest/target/Samba3.pm | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
+index 64a9a791a61..7584a0e7ba9 100755
+--- a/selftest/target/Samba3.pm
++++ b/selftest/target/Samba3.pm
+@@ -188,7 +188,7 @@ sub getlog_env_app($$$)
+ 	close(LOG);
+ 
+ 	return "" if $out eq $title;
+- 
++
+ 	return $out;
+ }
+ 
+@@ -2426,7 +2426,7 @@ sub provision($$)
+ 	my $nmbdsockdir="$prefix_abs/nmbd";
+ 	unlink($nmbdsockdir);
+ 
+-	## 
++	##
+ 	## create the test directory layout
+ 	##
+ 	die ("prefix_abs = ''") if $prefix_abs eq "";
+@@ -3290,7 +3290,7 @@ sub provision($$)
+ 	unless (open(PASSWD, ">$nss_wrapper_passwd")) {
+            warn("Unable to open $nss_wrapper_passwd");
+            return undef;
+-        } 
++        }
+ 	print PASSWD "nobody:x:$uid_nobody:$gid_nobody:nobody gecos:$prefix_abs:/bin/false
+ $unix_name:x:$unix_uid:$unix_gids[0]:$unix_name gecos:$prefix_abs:/bin/false
+ pdbtest:x:$uid_pdbtest:$gid_nogroup:pdbtest gecos:$prefix_abs:/bin/false
+-- 
+2.34.1
+
+
+From b558d8f8be4459fa9e588486984c4cadf65ede12 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Pavel=20Filipensk=C3=BD?= <pfilipen@redhat.com>
+Date: Tue, 8 Feb 2022 15:35:48 +0100
+Subject: [PATCH 5/6] s3:selftest: Add test for virus scanner
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Bug: https://bugzilla.samba.org/show_bug.cgi?id=14971
+
+Signed-off-by: Pavel Filipenský <pfilipen@redhat.com>
+
+Pair-Programmed-With: Andreas Schneider <asn@samba.org>
+Reviewed-by: Jeremy Allison <jra@samba.org>
+Reviewed-by: Andreas Schneider <asn@samba.org>
+(cherry picked from commit a25c714c34d3e00e0f3c29d2acfa98cf9cdbc544)
+---
+ selftest/knownfail.d/virus_scanner         |   2 +
+ selftest/target/Samba3.pm                  |  12 ++
+ source3/script/tests/test_virus_scanner.sh | 124 +++++++++++++++++++++
+ source3/selftest/tests.py                  |   9 ++
+ 4 files changed, 147 insertions(+)
+ create mode 100644 selftest/knownfail.d/virus_scanner
+ create mode 100755 source3/script/tests/test_virus_scanner.sh
+
+diff --git a/selftest/knownfail.d/virus_scanner b/selftest/knownfail.d/virus_scanner
+new file mode 100644
+index 00000000000..6df3fd20627
+--- /dev/null
++++ b/selftest/knownfail.d/virus_scanner
+@@ -0,0 +1,2 @@
++^samba3.blackbox.virus_scanner.check_infected_read  # test download infected file ('vfs objects = virusfilter')
++^samba3.blackbox.virus_scanner.check_infected_write # test upload infected file ('vfs objects = virusfilter')
+diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
+index 7584a0e7ba9..c1d0c60d96a 100755
+--- a/selftest/target/Samba3.pm
++++ b/selftest/target/Samba3.pm
+@@ -1688,6 +1688,9 @@ sub setup_fileserver
+ 	my $veto_sharedir="$share_dir/veto";
+ 	push(@dirs,$veto_sharedir);
+ 
++	my $virusfilter_sharedir="$share_dir/virusfilter";
++	push(@dirs,$virusfilter_sharedir);
++
+ 	my $ip4 = Samba::get_ipv4_addr("FILESERVER");
+ 	my $fileserver_options = "
+ 	kernel change notify = yes
+@@ -1813,6 +1816,15 @@ sub setup_fileserver
+ 	path = $veto_sharedir
+ 	delete veto files = yes
+ 
++[virusfilter]
++	path = $virusfilter_sharedir
++	vfs objects = acl_xattr virusfilter
++	virusfilter:scanner = dummy
++	virusfilter:min file size = 0
++	virusfilter:infected files = *infected*
++	virusfilter:infected file action = rename
++	virusfilter:scan on close = yes
++
+ [homes]
+ 	comment = Home directories
+ 	browseable = No
+diff --git a/source3/script/tests/test_virus_scanner.sh b/source3/script/tests/test_virus_scanner.sh
+new file mode 100755
+index 00000000000..2234ea6ca89
+--- /dev/null
++++ b/source3/script/tests/test_virus_scanner.sh
+@@ -0,0 +1,124 @@
++#!/bin/sh
++# Copyright (c) 2022      Pavel Filipenský <pfilipen@redhat.com>
++# shellcheck disable=1091
++
++if [ $# -lt 4 ]; then
++cat <<EOF
++Usage: $0 SERVER_IP SHARE LOCAL_PATH SMBCLIENT
++EOF
++exit 1;
++fi
++
++SERVER_IP=${1}
++SHARE=${2}
++LOCAL_PATH=${3}
++SMBCLIENT=${4}
++
++SMBCLIENT="${VALGRIND} ${SMBCLIENT}"
++
++failed=0
++sharedir="${LOCAL_PATH}/${SHARE}"
++
++incdir="$(dirname "$0")/../../../testprogs/blackbox"
++. "${incdir}/subunit.sh"
++
++check_infected_read()
++{
++    rm -rf "${sharedir:?}"/*
++
++    if ! touch "${sharedir}/infected.txt"; then
++        echo "ERROR: Cannot create ${sharedir}/infected.txt"
++        return 1
++    fi
++
++    ${SMBCLIENT} "//${SERVER_IP}/${SHARE}" -U"${USER}"%"${PASSWORD}" -c "get infected.txt ${sharedir}/infected.download.txt"
++
++    # check that virusfilter:rename prefix/suffix was added
++    if [ ! -f "${sharedir}/virusfilter.infected.txt.infected" ]; then
++        echo "ERROR: ${sharedir}/virusfilter.infected.txt.infected is missing."
++        return 1
++    fi
++
++    # check that file was not downloaded
++    if [ -f "${sharedir}/infected.download.txt" ]; then
++        echo "ERROR: {sharedir}/infected.download.txt should not exist."
++        return 1
++    fi
++
++    return 0
++}
++
++check_infected_write()
++{
++    rm -rf "${sharedir:?}"/*
++    smbfile=infected.upload.txt
++    smbfilerenamed="virusfilter.${smbfile}.infected"
++
++    # non empty file is needed
++    # vsf_virusfilter performs a scan only if fsp->fsp_flags.modified
++    if ! echo "Hello Virus!" > "${sharedir}/infected.txt"; then
++        echo "ERROR: Cannot create ${sharedir}/infected.txt"
++        return 1
++    fi
++
++    ${SMBCLIENT} "//${SERVER_IP}/${SHARE}" -U"${USER}"%"${PASSWORD}" -c "put ${sharedir}/infected.txt ${smbfile}"
++
++    # check that virusfilter:rename prefix/suffix was added
++    if [ ! -f "${sharedir}/${smbfilerenamed}" ]; then
++        echo "ERROR: ${sharedir}/${smbfilerenamed} is missing."
++        return 1
++    fi
++
++    # check that file was not uploaded
++    if [ -f "${sharedir}/infected.upload.txt" ]; then
++        echo "ERROR: {sharedir}/${smbfile} should not exist."
++        return 1
++    fi
++
++    return 0
++}
++
++check_healthy_read()
++{
++    rm -rf "${sharedir:?}"/*
++
++    if ! echo "Hello Samba!" > "${sharedir}/healthy.txt"; then
++        echo "ERROR: Cannot create ${sharedir}/healthy.txt"
++        return 1
++    fi
++
++    ${SMBCLIENT} //"${SERVER_IP}"/"${SHARE}" -U"${USER}"%"${PASSWORD}" -c "get healthy.txt ${sharedir}/healthy.download.txt"
++
++    if ! cmp "${sharedir}/healthy.txt" "${sharedir}/healthy.download.txt"; then
++        echo "ERROR: cmp ${sharedir}/healthy.txt ${sharedir}/healthy.download.txt FAILED"
++        return 1
++    fi
++
++    return 0
++}
++
++check_healthy_write()
++{
++    rm -rf "${sharedir:?}"/*
++
++    if ! echo "Hello Samba!" > "${sharedir}/healthy.txt"; then
++        echo "ERROR: Cannot create ${sharedir}/healthy.txt"
++        return 1
++    fi
++
++    ${SMBCLIENT} //"${SERVER_IP}"/"${SHARE}" -U"${USER}"%"${PASSWORD}" -c "put ${sharedir}/healthy.txt healthy.upload.txt"
++
++    if ! cmp "${sharedir}/healthy.txt" "${sharedir}/healthy.upload.txt"; then
++        echo "ERROR: cmp ${sharedir}/healthy.txt ${sharedir}/healthy.upload.txt FAILED"
++        return 1
++    fi
++
++    return 0
++}
++
++testit "check_infected_read"  check_infected_read  || failed=$((failed + 1))
++testit "check_infected_write" check_infected_write || failed=$((failed + 1))
++testit "check_healthy_read"   check_healthy_read   || failed=$((failed + 1))
++testit "check_healthy_write"  check_healthy_write  || failed=$((failed + 1))
++
++testok "$0" "$failed"
+diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
+index 701be011f70..6b146c76381 100755
+--- a/source3/selftest/tests.py
++++ b/source3/selftest/tests.py
+@@ -1240,6 +1240,15 @@ plantestsuite("samba3.blackbox.smbXsrv_client_dead_rec", "fileserver:local",
+                '$SERVER_IP',
+                "tmp"])
+ 
++env = 'fileserver'
++plantestsuite("samba3.blackbox.virus_scanner", "%s:local" % (env),
++              [os.path.join(samba3srcdir,
++                            "script/tests/test_virus_scanner.sh"),
++               '$SERVER_IP',
++               "virusfilter",
++               '$LOCAL_PATH',
++               smbclient3])
++
+ for env in ['fileserver', 'simpleserver']:
+     plantestsuite("samba3.blackbox.smbclient.encryption", env,
+                   [os.path.join(samba3srcdir, "script/tests/test_smbclient_encryption.sh"),
+-- 
+2.34.1
+
+
+From 275139352e854c7b01a53014b16673c8c7254fa9 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Pavel=20Filipensk=C3=BD?= <pfilipen@redhat.com>
+Date: Mon, 7 Feb 2022 23:06:10 +0100
+Subject: [PATCH 6/6] s3:modules: Fix virusfilter_vfs_openat
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Bug: https://bugzilla.samba.org/show_bug.cgi?id=14971
+
+Signed-off-by: Pavel Filipenský <pfilipen@redhat.com>
+
+Pair-Programmed-With: Andreas Schneider <asn@samba.org>
+Reviewed-by: Jeremy Allison <jra@samba.org>
+Reviewed-by: Andreas Schneider <asn@samba.org>
+
+Autobuild-User(master): Jeremy Allison <jra@samba.org>
+Autobuild-Date(master): Thu Feb 10 22:09:06 UTC 2022 on sn-devel-184
+
+(cherry picked from commit 3f1c958f6fa9d2991185f4e281a377a295d09f9c)
+---
+ selftest/knownfail.d/virus_scanner | 2 --
+ source3/modules/vfs_virusfilter.c  | 6 +++---
+ 2 files changed, 3 insertions(+), 5 deletions(-)
+ delete mode 100644 selftest/knownfail.d/virus_scanner
+
+diff --git a/selftest/knownfail.d/virus_scanner b/selftest/knownfail.d/virus_scanner
+deleted file mode 100644
+index 6df3fd20627..00000000000
+--- a/selftest/knownfail.d/virus_scanner
++++ /dev/null
+@@ -1,2 +0,0 @@
+-^samba3.blackbox.virus_scanner.check_infected_read  # test download infected file ('vfs objects = virusfilter')
+-^samba3.blackbox.virus_scanner.check_infected_write # test upload infected file ('vfs objects = virusfilter')
+diff --git a/source3/modules/vfs_virusfilter.c b/source3/modules/vfs_virusfilter.c
+index e6cbee7cd45..d1554967ad1 100644
+--- a/source3/modules/vfs_virusfilter.c
++++ b/source3/modules/vfs_virusfilter.c
+@@ -1309,21 +1309,21 @@ static int virusfilter_vfs_openat(struct vfs_handle_struct *handle,
+ 		 */
+ 		goto virusfilter_vfs_open_next;
+ 	}
+-	ret = S_ISREG(smb_fname->st.st_ex_mode);
++	ret = S_ISREG(sbuf.st_ex_mode);
+ 	if (ret == 0) {
+ 		DBG_INFO("Not scanned: Directory or special file: %s/%s\n",
+ 			 cwd_fname, fname);
+ 		goto virusfilter_vfs_open_next;
+ 	}
+ 	if (config->max_file_size > 0 &&
+-	    smb_fname->st.st_ex_size > config->max_file_size)
++	    sbuf.st_ex_size > config->max_file_size)
+ 	{
+ 		DBG_INFO("Not scanned: file size > max file size: %s/%s\n",
+ 			 cwd_fname, fname);
+ 		goto virusfilter_vfs_open_next;
+ 	}
+ 	if (config->min_file_size > 0 &&
+-	    smb_fname->st.st_ex_size < config->min_file_size)
++	    sbuf.st_ex_size < config->min_file_size)
+ 	{
+ 		DBG_INFO("Not scanned: file size < min file size: %s/%s\n",
+ 		      cwd_fname, fname);
+-- 
+2.34.1
+
diff --git a/SPECS/samba.spec b/SPECS/samba.spec
index 2d49425..c6c58a6 100644
--- a/SPECS/samba.spec
+++ b/SPECS/samba.spec
@@ -2,12 +2,16 @@
 #
 # To build and run the tests use:
 #
+# fedpkg local --with testsuite
+# or
 # rpmbuild --rebuild --with testsuite samba.src.rpm
 #
 %bcond_with testsuite
 
 # Build with internal talloc, tevent, tdb and ldb.
 #
+# fedpkg local --with=testsuite --with=includelibs
+# or
 # rpmbuild --rebuild --with=testsuite --with=includelibs samba.src.rpm
 #
 %bcond_with includelibs
@@ -15,6 +19,9 @@
 # ctdb is enabled by default, you can disable it with: --without clustering
 %bcond_without clustering
 
+# Define _make_verbose if it doesn't exist (RHEL8)
+%{!?_make_verbose:%define _make_verbose V=1 VERBOSE=1}
+
 # Build with Active Directory Domain Controller support by default on Fedora
 %if 0%{?fedora}
 %bcond_without dc
@@ -42,18 +49,21 @@
 %bcond_without winexe
 %endif
 
-# Build vfs_ceph module by default on 64bit Fedora
+# Build vfs_ceph module and ctdb cepth mutex helper by default on 64bit Fedora
 %if 0%{?fedora}
 
 %ifarch aarch64 ppc64le s390x x86_64
 %bcond_without vfs_cephfs
+%bcond_without ceph_mutex
 %else
 %bcond_with vfs_cephfs
+%bcond_with ceph_mutex
 #endifarch
 %endif
 
 %else
 %bcond_with vfs_cephfs
+%bcond_with ceph_mutex
 #endif fedora
 %endif
 
@@ -106,15 +116,29 @@
 #endif fedora || rhel >= 8
 %endif
 
+# Build the ctdb-pcp-pmda package by default on Fedora
+%if 0%{?fedora}
+%bcond_without pcp_pmda
+%else
+%bcond_with pcp_pmda
+%endif
+
+# Build the etcd helpers by default on Fedora
+%if 0%{?fedora}
+%bcond_without etcd_mutex
+%else
+%bcond_with etcd_mutex
+%endif
+
 %define samba_requires_eq()  %(LC_ALL="C" echo '%*' | xargs -r rpm -q --qf 'Requires: %%{name} = %%{epoch}:%%{version}\\n' | sed -e 's/ (none):/ /' -e 's/ 0:/ /' | grep -v "is not")
 
-%global baserelease 10
+%global baserelease 5
 
-%global samba_version 4.14.5
-%global talloc_version 2.3.2
-%global tdb_version 1.4.3
-%global tevent_version 0.10.2
-%global ldb_version 2.3.0
+%global samba_version 4.15.5
+%global talloc_version 2.3.3
+%global tdb_version 1.4.4
+%global tevent_version 0.11.0
+%global ldb_version 2.4.1
 # This should be rc1 or nil
 %global pre_release %nil
 
@@ -177,19 +201,17 @@ Source14:       samba.pamd
 
 Source201:      README.downgrade
 
-Patch0:         samba-4.14-raise-dfs-enoent-debug-level.patch
-Patch1:         CVE-2016-2124.patch
-Patch2:         CVE-2021-23192.patch
-Patch3:         CVE-2020-25717.patch
-Patch4:         samba-4.14-krb5pac.patch
-Patch5:         samba-4.14-fix-winbind-no-trusted-domain.patch
-Patch6:         samba-4.14-IPA-DC-add-missing-checks.patch
-Patch7:         samba-4.14-recursive-delete-of-veto-files.patch
-Patch8:         samba-4.14-del-dir-with-dangling-symlinks.patch
-Patch9:         samba-4.14-fix-username-map-script.patch
-Patch10:        samba-4.14-fix-domain-join-segfault.patch
-Patch11:        CVE-2021-44142-v4.14.patch
-Patch12:        samba-4.14-fix-virus-scanner.patch
+Patch0:         samba-s4u.patch
+Patch1:         samba-ctdb-etcd-reclock.patch
+Patch2:         samba-glibc-dns.patch
+Patch3:         samba-printing-win7.patch
+Patch4:         samba-disable-systemd-notifications.patch
+Patch5:         samba-disable-ntlmssp.patch
+Patch6:         samba-password-change-prompt.patch
+Patch7:         samba-virus_scanner.patch
+Patch8:         samba-4-15-fix-autorid.patch
+Patch9:         samba-4-15-fix-winbind-refresh-tickets.patch
+Patch10:        samba-4-15-fix-create-local-krb5-conf.patch
 
 Requires(pre): /usr/sbin/groupadd
 Requires(post): systemd
@@ -297,6 +319,16 @@ BuildRequires: libcephfs-devel
 BuildRequires: liburing-devel >= 0.4
 %endif
 
+%if %{with pcp_pmda}
+BuildRequires: pcp-libs-devel
+%endif
+%if %{with ceph_mutex}
+BuildRequires: librados-devel
+%endif
+%if %{with etcd_mutex}
+BuildRequires: python3-etcd
+%endif
+
 %if %{with dc} || %{with testsuite}
 # Add python3-iso8601 to avoid that the
 # version in Samba is being packaged
@@ -326,9 +358,13 @@ BuildRequires: python3-tdb >= %{tdb_version}
 BuildRequires: libldb-devel >= %{ldb_version}
 BuildRequires: python3-ldb >= %{ldb_version}
 BuildRequires: python3-ldb-devel >= %{ldb_version}
-%else
+%endif
+
+%if %{with includelibs} || %{with testsuite}
+# lmdb-devel is required for the mdb ldb module, if samba is configured
+# to build includelibs we need lmdb-devel for building that module on our own
 BuildRequires: lmdb-devel
-#endif without testsuite
+#endif without includelibs
 %endif
 
 %if %{with dc} || %{with testsuite}
@@ -338,6 +374,7 @@ BuildRequires: ldb-tools
 BuildRequires: python3-gpg
 BuildRequires: python3-markdown
 BuildRequires: python3-setproctitle
+BuildRequires: python3-cryptography
 BuildRequires: tdb-tools
 %endif
 
@@ -435,7 +472,7 @@ Obsoletes: ctdb-tests-debuginfo < %{samba_depver}
 # endif with clustering
 %endif
 
-# If only build glusterfs for RHGS and Fedora, so obsolete it on other version
+# We only build glusterfs for RHGS and Fedora, so obsolete it on other versions
 # of the distro
 %if %{without vfs_glusterfs}
 Obsoletes: samba-vfs-glusterfs < %{samba_depver}
@@ -456,6 +493,15 @@ Requires: samba-libs = %{samba_depver}
 Requires: libwbclient = %{samba_depver}
 %endif
 
+# samba-tool needs python3-samba
+Requires: python3-%{name} = %{samba_depver}
+# samba-tool needs tdbbackup
+Requires: tdb-tools
+%if %{with dc}
+# samba-tool needs mdb_copy for domain backup or upgrade provision
+Requires: lmdb
+%endif
+
 Provides: bundled(libreplace)
 
 %description common-tools
@@ -477,10 +523,6 @@ Requires(post): libwbclient = %{samba_depver}
 Requires: libwbclient = %{samba_depver}
 %endif
 
-# samba-tool needs tdbbackup
-Requires: tdb-tools
-# samba-tool needs mdb_copy
-Requires: lmdb
 Requires: ldb-tools
 Requires: python3-setproctitle
 # Force using libldb version to be the same as build version
@@ -573,6 +615,7 @@ Samba VFS module for Ceph distributed storage system integration.
 Summary: Samba VFS module for io_uring
 Requires: %{name} = %{samba_depver}
 Requires: %{name}-libs = %{samba_depver}
+Requires: %{name}-client-libs = %{samba_depver}
 
 Provides: bundled(libreplace)
 
@@ -716,7 +759,7 @@ Summary: Samba python devel files
 Requires: python3-%{name} = %{samba_depver}
 
 %description -n python3-%{name}-devel
-The python3-%{name}-devel package contains the Python 3 defel files.
+The python3-%{name}-devel package contains the Python 3 devel files.
 
 %package -n python3-samba-test
 Summary: Samba Python libraries
@@ -811,9 +854,12 @@ Summary: Samba winbind
 Requires(pre): %{name}-common = %{samba_depver}
 Requires: %{name}-common = %{samba_depver}
 Requires: %{name}-common-libs = %{samba_depver}
+Requires(post): %{name}-common-libs = %{samba_depver}
 Requires: %{name}-common-tools = %{samba_depver}
 Requires: %{name}-client-libs = %{samba_depver}
+Requires(post): %{name}-client-libs = %{samba_depver}
 Requires: %{name}-libs = %{samba_depver}
+Requires(post): %{name}-libs = %{samba_depver}
 Requires: %{name}-winbind-modules = %{samba_depver}
 
 %if %{with libwbclient}
@@ -906,6 +952,7 @@ necessary to communicate to the Winbind Daemon
 Summary: Samba Winexe Windows Binary
 License: GPLv3
 Requires: %{name}-client-libs = %{samba_depver}
+Requires: %{name}-common-libs = %{samba_depver}
 
 Provides: bundled(libreplace)
 
@@ -973,6 +1020,45 @@ and use CTDB instead.
 
 #endif with testsuite
 %endif
+
+%if %{with pcp_pmda}
+
+%package -n ctdb-pcp-pmda
+Summary: CTDB PCP pmda support
+Requires: ctdb = %{samba_depver}
+Requires: pcp-libs
+
+%description -n ctdb-pcp-pmda
+Performance Co-Pilot (PCP) support for CTDB
+
+#endif with pcp_pmda
+%endif
+
+%if %{with etcd_mutex}
+
+%package -n ctdb-etcd-mutex
+Summary: CTDB ETCD mutex helper
+Requires: ctdb = %{samba_depver}
+Requires: python3-etcd
+
+%description -n ctdb-etcd-mutex
+Support for using an existing ETCD cluster as a mutex helper for CTDB
+
+#endif with etcd_mutex
+%endif
+
+%if %{with ceph_mutex}
+
+%package -n ctdb-ceph-mutex
+Summary: CTDB ceph mutex helper
+Requires: ctdb = %{samba_depver}
+
+%description -n ctdb-ceph-mutex
+Support for using an existing CEPH cluster as a mutex helper for CTDB
+
+#endif with ceph_mutex
+%endif
+
 #endif with clustering
 %endif
 
@@ -1063,8 +1149,18 @@ export LDFLAGS="%{__global_ldflags} -fuse-ld=gold"
 %if %{with testsuite}
         --enable-selftest \
 %endif
+%if %{with pcp_pmda}
+        --enable-pmda \
+%endif
+%if %{with ceph_mutex}
+        --enable-ceph-reclock \
+%endif
+%if %{with etcd_mutex}
+        --enable-etcd-reclock \
+%endif
         --with-profiling-data \
         --with-systemd \
+        --with-quotas \
         --systemd-install-services \
         --with-systemddir=/usr/lib/systemd/system \
         --systemd-smb-extra=%{_systemd_extra} \
@@ -1073,7 +1169,7 @@ export LDFLAGS="%{__global_ldflags} -fuse-ld=gold"
         --systemd-samba-extra=%{_systemd_extra}
 
 # Do not use %%make_build, make is just a wrapper around waf in Samba!
-%{__make} %{?_smp_mflags} V=1
+%{__make} %{?_smp_mflags} %{_make_verbose}
 
 pushd pidl
 %__perl Makefile.PL PREFIX=%{_prefix}
@@ -1082,7 +1178,8 @@ pushd pidl
 popd
 
 %install
-%make_install
+# Do not use %%make_install, make is just a wrapper around waf in Samba!
+%{__make} %{?_smp_mflags} %{_make_verbose} install DESTDIR=%{buildroot}
 
 install -d -m 0755 %{buildroot}/usr/{sbin,bin}
 install -d -m 0755 %{buildroot}%{_libdir}/security
@@ -1170,12 +1267,10 @@ touch %{buildroot}%{_libdir}/krb5/plugins/libkrb5/winbind_krb5_locator.so
 %if %{without dc} && %{without testsuite}
 for i in \
     %{_libdir}/samba/libdfs-server-ad-samba4.so \
-    %{_libdir}/samba/libdnsserver-common-samba4.so \
     %{_libdir}/samba/libdsdb-garbage-collect-tombstones-samba4.so \
     %{_libdir}/samba/libscavenge-dns-records-samba4.so \
     %{_mandir}/man8/samba.8 \
     %{_mandir}/man8/samba_downgrade_db.8 \
-    %{_mandir}/man8/samba-tool.8 \
     %{_mandir}/man8/samba-gpupdate.8 \
     %{_libdir}/samba/ldb/ildap.so \
     %{_libdir}/samba/ldb/ldbsamba_extensions.so \
@@ -1526,6 +1621,8 @@ fi
 %{_libdir}/samba/vfs/nfs4acl_xattr.so
 %endif
 
+%{_libexecdir}/samba/samba-bgqd
+
 %dir %{_datadir}/samba
 %dir %{_datadir}/samba/mdssvc
 %{_datadir}/samba/mdssvc/elasticsearch_mappings.json
@@ -1537,6 +1634,7 @@ fi
 %config(noreplace) %{_sysconfdir}/pam.d/samba
 %{_mandir}/man1/smbstatus.1*
 %{_mandir}/man8/eventlogadm.8*
+%{_mandir}/man8/samba-bgqd.8*
 %{_mandir}/man8/smbd.8*
 %{_mandir}/man8/nmbd.8*
 %{_mandir}/man8/vfs_acl_tdb.8*
@@ -1587,9 +1685,8 @@ fi
 %{_bindir}/cifsdd
 %{_bindir}/dbwrap_tool
 %{_bindir}/dumpmscat
-%exclude %{_bindir}/findsmb
 %{_bindir}/mvxattr
-%{_bindir}/mdfind
+%{_bindir}/mdsearch
 %{_bindir}/nmblookup
 %{_bindir}/oLschema2ldif
 %{_bindir}/regdiff
@@ -1616,9 +1713,8 @@ fi
 %{_mandir}/man1/regpatch.1*
 %{_mandir}/man1/regshell.1*
 %{_mandir}/man1/regtree.1*
-%exclude %{_mandir}/man1/findsmb.1*
 %{_mandir}/man1/log2pcap.1*
-%{_mandir}/man1/mdfind.1*
+%{_mandir}/man1/mdsearch.1*
 %{_mandir}/man1/mvxattr.1*
 %{_mandir}/man1/rpcclient.1*
 %{_mandir}/man1/sharesec.1*
@@ -1699,12 +1795,11 @@ fi
 %{_libdir}/samba/libclidns-samba4.so
 %{_libdir}/samba/libcluster-samba4.so
 %{_libdir}/samba/libcmdline-contexts-samba4.so
-%{_libdir}/samba/libcmdline-credentials-samba4.so
 %{_libdir}/samba/libcommon-auth-samba4.so
 %{_libdir}/samba/libctdb-event-client-samba4.so
 %{_libdir}/samba/libdbwrap-samba4.so
-%{_libdir}/samba/libdcerpc-samba-samba4.so
 %{_libdir}/samba/libdcerpc-pkt-auth-samba4.so
+%{_libdir}/samba/libdcerpc-samba-samba4.so
 %{_libdir}/samba/libevents-samba4.so
 %{_libdir}/samba/libflag-mapping-samba4.so
 %{_libdir}/samba/libgenrand-samba4.so
@@ -1758,7 +1853,6 @@ fi
 %{_libdir}/samba/libtime-basic-samba4.so
 %{_libdir}/samba/libtorture-samba4.so
 %{_libdir}/samba/libtrusts-util-samba4.so
-%{_libdir}/samba/libutil-cmdline-samba4.so
 %{_libdir}/samba/libutil-reg-samba4.so
 %{_libdir}/samba/libutil-setid-samba4.so
 %{_libdir}/samba/libutil-tdb-samba4.so
@@ -1784,7 +1878,7 @@ fi
 
 %{_libdir}/samba/ldb/asq.so
 %{_libdir}/samba/ldb/ldb.so
-#%%{_libdir}/samba/ldb/mdb.so
+%{_libdir}/samba/ldb/mdb.so
 %{_libdir}/samba/ldb/paged_searches.so
 %{_libdir}/samba/ldb/rdn_name.so
 %{_libdir}/samba/ldb/sample.so
@@ -1822,8 +1916,7 @@ fi
 ### COMMON-libs
 %files common-libs
 # common libraries
-%{_libdir}/samba/libpopt-samba3-cmdline-samba4.so
-%{_libdir}/samba/libpopt-samba3-samba4.so
+%{_libdir}/samba/libcmdline-samba4.so
 
 %dir %{_libdir}/samba/ldb
 
@@ -1836,6 +1929,7 @@ fi
 %{_bindir}/net
 %{_bindir}/pdbedit
 %{_bindir}/profiles
+%{_bindir}/samba-tool
 %{_bindir}/smbcontrol
 %{_bindir}/smbpasswd
 %{_bindir}/testparm
@@ -1844,13 +1938,13 @@ fi
 %{_mandir}/man1/testparm.1*
 %{_mandir}/man8/net.8*
 %{_mandir}/man8/pdbedit.8*
+%{_mandir}/man8/samba-tool.8*
 %{_mandir}/man8/smbpasswd.8*
 
 ### DC
 %if %{with dc} || %{with testsuite}
 %files dc
 %{_unitdir}/samba.service
-%{_bindir}/samba-tool
 %{_sbindir}/samba
 %{_sbindir}/samba_dnsupdate
 %{_sbindir}/samba_downgrade_db
@@ -1918,7 +2012,6 @@ fi
 %{_mandir}/man8/samba.8*
 %{_mandir}/man8/samba_downgrade_db.8*
 %{_mandir}/man8/samba-gpupdate.8*
-%{_mandir}/man8/samba-tool.8*
 %dir %{_datadir}/samba/admx
 %{_datadir}/samba/admx/samba.admx
 %dir %{_datadir}/samba/admx/en-US
@@ -1961,7 +2054,6 @@ fi
 %endif
 
 %{_libdir}/libdcerpc-server.so.*
-%{_libdir}/samba/libdnsserver-common-samba4.so
 %{_libdir}/samba/libdsdb-module-samba4.so
 %{_libdir}/samba/libdsdb-garbage-collect-tombstones-samba4.so
 %{_libdir}/samba/libscavenge-dns-records-samba4.so
@@ -1970,8 +2062,6 @@ fi
 %files dc-bind-dlz
 %attr(770,root,named) %dir /var/lib/samba/bind-dns
 %dir %{_libdir}/samba/bind9
-%{_libdir}/samba/bind9/dlz_bind9.so
-%{_libdir}/samba/bind9/dlz_bind9_9.so
 %{_libdir}/samba/bind9/dlz_bind9_10.so
 %{_libdir}/samba/bind9/dlz_bind9_11.so
 %{_libdir}/samba/bind9/dlz_bind9_12.so
@@ -2145,6 +2235,7 @@ fi
 %{_libdir}/samba/libauth4-samba4.so
 %{_libdir}/samba/libauth-unix-token-samba4.so
 %{_libdir}/samba/libdcerpc-samba4.so
+%{_libdir}/samba/libdnsserver-common-samba4.so
 %{_libdir}/samba/libshares-samba4.so
 %{_libdir}/samba/libsmbpasswdparser-samba4.so
 %{_libdir}/samba/libxattr-tdb-samba4.so
@@ -2239,6 +2330,7 @@ fi
 %{python3_sitearch}/samba/__pycache__/getopt.*.pyc
 %{python3_sitearch}/samba/__pycache__/gpclass.*.pyc
 %{python3_sitearch}/samba/__pycache__/gp_ext_loader.*.pyc
+%{python3_sitearch}/samba/__pycache__/gp_gnome_settings_ext.*.pyc
 %{python3_sitearch}/samba/__pycache__/gp_msgs_ext.*.pyc
 %{python3_sitearch}/samba/__pycache__/gp_scripts_ext.*.pyc
 %{python3_sitearch}/samba/__pycache__/gp_sec_ext.*.pyc
@@ -2261,7 +2353,14 @@ fi
 %{python3_sitearch}/samba/__pycache__/trust_utils.*.pyc
 %{python3_sitearch}/samba/__pycache__/upgrade.*.pyc
 %{python3_sitearch}/samba/__pycache__/upgradehelpers.*.pyc
+%{python3_sitearch}/samba/__pycache__/vgp_access_ext.*.pyc
+%{python3_sitearch}/samba/__pycache__/vgp_files_ext.*.pyc
+%{python3_sitearch}/samba/__pycache__/vgp_issue_ext.*.pyc
+%{python3_sitearch}/samba/__pycache__/vgp_motd_ext.*.pyc
+%{python3_sitearch}/samba/__pycache__/vgp_openssh_ext.*.pyc
+%{python3_sitearch}/samba/__pycache__/vgp_startup_scripts_ext.*.pyc
 %{python3_sitearch}/samba/__pycache__/vgp_sudoers_ext.*.pyc
+%{python3_sitearch}/samba/__pycache__/vgp_symlink_ext.*.pyc
 %{python3_sitearch}/samba/__pycache__/xattr.*.pyc
 %{python3_sitearch}/samba/_glue.*.so
 %{python3_sitearch}/samba/_ldb.*.so
@@ -2290,6 +2389,7 @@ fi
 %{python3_sitearch}/samba/dcerpc/idmap.*.so
 %{python3_sitearch}/samba/dcerpc/initshutdown.*.so
 %{python3_sitearch}/samba/dcerpc/irpc.*.so
+%{python3_sitearch}/samba/dcerpc/krb5ccache.*.so
 %{python3_sitearch}/samba/dcerpc/krb5pac.*.so
 %{python3_sitearch}/samba/dcerpc/lsa.*.so
 %{python3_sitearch}/samba/dcerpc/messaging.*.so
@@ -2318,9 +2418,12 @@ fi
 %{python3_sitearch}/samba/descriptor.py
 %{python3_sitearch}/samba/dnsresolver.py
 %{python3_sitearch}/samba/drs_utils.py
+%{python3_sitearch}/samba/dsdb.*.so
+%{python3_sitearch}/samba/dsdb_dns.*.so
 %{python3_sitearch}/samba/gensec.*.so
 %{python3_sitearch}/samba/getopt.py
 %{python3_sitearch}/samba/gpclass.py
+%{python3_sitearch}/samba/gp_gnome_settings_ext.py
 %{python3_sitearch}/samba/gp_scripts_ext.py
 %{python3_sitearch}/samba/gp_sec_ext.py
 %{python3_sitearch}/samba/gpo.*.so
@@ -2331,6 +2434,7 @@ fi
 %{python3_sitearch}/samba/messaging.*.so
 %{python3_sitearch}/samba/ndr.py
 %{python3_sitearch}/samba/net.*.so
+%{python3_sitearch}/samba/net_s3.*.so
 %{python3_sitearch}/samba/ntstatus.*.so
 %{python3_sitearch}/samba/posix_eadb.*.so
 %dir %{python3_sitearch}/samba/emulate
@@ -2453,7 +2557,14 @@ fi
 %{python3_sitearch}/samba/trust_utils.py
 %{python3_sitearch}/samba/upgrade.py
 %{python3_sitearch}/samba/upgradehelpers.py
+%{python3_sitearch}/samba/vgp_access_ext.py
+%{python3_sitearch}/samba/vgp_files_ext.py
+%{python3_sitearch}/samba/vgp_issue_ext.py
+%{python3_sitearch}/samba/vgp_motd_ext.py
+%{python3_sitearch}/samba/vgp_openssh_ext.py
+%{python3_sitearch}/samba/vgp_startup_scripts_ext.py
 %{python3_sitearch}/samba/vgp_sudoers_ext.py
+%{python3_sitearch}/samba/vgp_symlink_ext.py
 %{python3_sitearch}/samba/werror.*.so
 %{python3_sitearch}/samba/xattr.py
 %{python3_sitearch}/samba/xattr_native.*.so
@@ -2500,8 +2611,6 @@ fi
 
 %{python3_sitearch}/samba/dcerpc/dnsserver.*.so
 %{python3_sitearch}/samba/dckeytab.*.so
-%{python3_sitearch}/samba/dsdb.*.so
-%{python3_sitearch}/samba/dsdb_dns.*.so
 %{python3_sitearch}/samba/domain_update.py
 %{python3_sitearch}/samba/forest_update.py
 %{python3_sitearch}/samba/ms_forest_updates_markdown.py
@@ -2568,6 +2677,7 @@ fi
 %{python3_sitearch}/samba/tests/__pycache__/cred_opt.*.pyc
 %{python3_sitearch}/samba/tests/__pycache__/dckeytab.*.pyc
 %{python3_sitearch}/samba/tests/__pycache__/dns.*.pyc
+%{python3_sitearch}/samba/tests/__pycache__/dns_aging.*.pyc
 %{python3_sitearch}/samba/tests/__pycache__/dns_base.*.pyc
 %{python3_sitearch}/samba/tests/__pycache__/dns_forwarder.*.pyc
 %{python3_sitearch}/samba/tests/__pycache__/dns_invalid.*.pyc
@@ -2575,6 +2685,8 @@ fi
 %{python3_sitearch}/samba/tests/__pycache__/dns_tkey.*.pyc
 %{python3_sitearch}/samba/tests/__pycache__/dns_wildcard.*.pyc
 %{python3_sitearch}/samba/tests/__pycache__/dsdb.*.pyc
+%{python3_sitearch}/samba/tests/__pycache__/dsdb_api.*.pyc
+%{python3_sitearch}/samba/tests/__pycache__/dsdb_dns.*.pyc
 %{python3_sitearch}/samba/tests/__pycache__/dsdb_lock.*.pyc
 %{python3_sitearch}/samba/tests/__pycache__/dsdb_schema_attributes.*.pyc
 %{python3_sitearch}/samba/tests/__pycache__/docs.*.pyc
@@ -2586,17 +2698,22 @@ fi
 %{python3_sitearch}/samba/tests/__pycache__/getdcname.*.pyc
 %{python3_sitearch}/samba/tests/__pycache__/glue.*.pyc
 %{python3_sitearch}/samba/tests/__pycache__/gpo.*.pyc
+%{python3_sitearch}/samba/tests/__pycache__/gpo_member.*.pyc
 %{python3_sitearch}/samba/tests/__pycache__/graph.*.pyc
 %{python3_sitearch}/samba/tests/__pycache__/group_audit.*.pyc
 %{python3_sitearch}/samba/tests/__pycache__/hostconfig.*.pyc
+%{python3_sitearch}/samba/tests/__pycache__/imports.*.pyc
 %{python3_sitearch}/samba/tests/__pycache__/join.*.pyc
 %{python3_sitearch}/samba/tests/__pycache__/krb5_credentials.*.pyc
 %{python3_sitearch}/samba/tests/__pycache__/ldap_raw.*.pyc
 %{python3_sitearch}/samba/tests/__pycache__/ldap_referrals.*.pyc
+%{python3_sitearch}/samba/tests/__pycache__/ldap_spn.*.pyc
+%{python3_sitearch}/samba/tests/__pycache__/ldap_upn_sam_account.*.pyc
 %{python3_sitearch}/samba/tests/__pycache__/loadparm.*.pyc
 %{python3_sitearch}/samba/tests/__pycache__/libsmb.*.pyc
 %{python3_sitearch}/samba/tests/__pycache__/lsa_string.*.pyc
 %{python3_sitearch}/samba/tests/__pycache__/messaging.*.pyc
+%{python3_sitearch}/samba/tests/__pycache__/ndr.*.pyc
 %{python3_sitearch}/samba/tests/__pycache__/netbios.*.pyc
 %{python3_sitearch}/samba/tests/__pycache__/netcmd.*.pyc
 %{python3_sitearch}/samba/tests/__pycache__/net_join_no_spnego.*.pyc
@@ -2632,10 +2749,12 @@ fi
 %{python3_sitearch}/samba/tests/__pycache__/s3passdb.*.pyc
 %{python3_sitearch}/samba/tests/__pycache__/s3registry.*.pyc
 %{python3_sitearch}/samba/tests/__pycache__/s3windb.*.pyc
+%{python3_sitearch}/samba/tests/__pycache__/s3_net_join.*.pyc
 %{python3_sitearch}/samba/tests/__pycache__/samba_upgradedns_lmdb.*.pyc
 %{python3_sitearch}/samba/tests/__pycache__/samba3sam.*.pyc
 %{python3_sitearch}/samba/tests/__pycache__/samdb.*.pyc
 %{python3_sitearch}/samba/tests/__pycache__/samdb_api.*.pyc
+%{python3_sitearch}/samba/tests/__pycache__/sddl.*.pyc
 %{python3_sitearch}/samba/tests/__pycache__/security.*.pyc
 %{python3_sitearch}/samba/tests/__pycache__/segfault.*.pyc
 %{python3_sitearch}/samba/tests/__pycache__/smb.*.pyc
@@ -2670,7 +2789,7 @@ fi
 %{python3_sitearch}/samba/tests/blackbox/__pycache__/bug13653.*.pyc
 %{python3_sitearch}/samba/tests/blackbox/__pycache__/check_output.*.pyc
 %{python3_sitearch}/samba/tests/blackbox/__pycache__/downgradedatabase.*.pyc
-%{python3_sitearch}/samba/tests/blackbox/__pycache__/mdfind.*.pyc
+%{python3_sitearch}/samba/tests/blackbox/__pycache__/mdsearch.*.pyc
 %{python3_sitearch}/samba/tests/blackbox/__pycache__/ndrdump.*.pyc
 %{python3_sitearch}/samba/tests/blackbox/__pycache__/netads_json.*.pyc
 %{python3_sitearch}/samba/tests/blackbox/__pycache__/samba_dnsupdate.*.pyc
@@ -2686,7 +2805,7 @@ fi
 %{python3_sitearch}/samba/tests/blackbox/bug13653.py
 %{python3_sitearch}/samba/tests/blackbox/check_output.py
 %{python3_sitearch}/samba/tests/blackbox/downgradedatabase.py
-%{python3_sitearch}/samba/tests/blackbox/mdfind.py
+%{python3_sitearch}/samba/tests/blackbox/mdsearch.py
 %{python3_sitearch}/samba/tests/blackbox/ndrdump.py
 %{python3_sitearch}/samba/tests/blackbox/netads_json.py
 %{python3_sitearch}/samba/tests/blackbox/samba_dnsupdate.py
@@ -2714,6 +2833,7 @@ fi
 %{python3_sitearch}/samba/tests/dcerpc/__pycache__/binding.*.pyc
 %{python3_sitearch}/samba/tests/dcerpc/__pycache__/dnsserver.*.pyc
 %{python3_sitearch}/samba/tests/dcerpc/__pycache__/integer.*.pyc
+%{python3_sitearch}/samba/tests/dcerpc/__pycache__/lsa.*.pyc
 %{python3_sitearch}/samba/tests/dcerpc/__pycache__/mdssvc.*.pyc
 %{python3_sitearch}/samba/tests/dcerpc/__pycache__/misc.*.pyc
 %{python3_sitearch}/samba/tests/dcerpc/__pycache__/raw_protocol.*.pyc
@@ -2733,6 +2853,7 @@ fi
 %{python3_sitearch}/samba/tests/dcerpc/createtrustrelax.py
 %{python3_sitearch}/samba/tests/dcerpc/dnsserver.py
 %{python3_sitearch}/samba/tests/dcerpc/integer.py
+%{python3_sitearch}/samba/tests/dcerpc/lsa.py
 %{python3_sitearch}/samba/tests/dcerpc/mdssvc.py
 %{python3_sitearch}/samba/tests/dcerpc/misc.py
 %{python3_sitearch}/samba/tests/dcerpc/raw_protocol.py
@@ -2748,6 +2869,7 @@ fi
 %{python3_sitearch}/samba/tests/dcerpc/unix.py
 %{python3_sitearch}/samba/tests/dckeytab.py
 %{python3_sitearch}/samba/tests/dns.py
+%{python3_sitearch}/samba/tests/dns_aging.py
 %{python3_sitearch}/samba/tests/dns_base.py
 %{python3_sitearch}/samba/tests/dns_forwarder.py
 %dir %{python3_sitearch}/samba/tests/dns_forwarder_helpers
@@ -2758,6 +2880,8 @@ fi
 %{python3_sitearch}/samba/tests/dns_tkey.py
 %{python3_sitearch}/samba/tests/dns_wildcard.py
 %{python3_sitearch}/samba/tests/dsdb.py
+%{python3_sitearch}/samba/tests/dsdb_api.py
+%{python3_sitearch}/samba/tests/dsdb_dns.py
 %{python3_sitearch}/samba/tests/dsdb_lock.py
 %{python3_sitearch}/samba/tests/dsdb_schema_attributes.py
 %{python3_sitearch}/samba/tests/docs.py
@@ -2777,9 +2901,11 @@ fi
 %{python3_sitearch}/samba/tests/get_opt.py
 %{python3_sitearch}/samba/tests/glue.py
 %{python3_sitearch}/samba/tests/gpo.py
+%{python3_sitearch}/samba/tests/gpo_member.py
 %{python3_sitearch}/samba/tests/graph.py
 %{python3_sitearch}/samba/tests/group_audit.py
 %{python3_sitearch}/samba/tests/hostconfig.py
+%{python3_sitearch}/samba/tests/imports.py
 %{python3_sitearch}/samba/tests/join.py
 %dir %{python3_sitearch}/samba/tests/kcc
 %{python3_sitearch}/samba/tests/kcc/__init__.py
@@ -2795,37 +2921,66 @@ fi
 %{python3_sitearch}/samba/tests/kcc/ldif_import_export.py
 %dir %{python3_sitearch}/samba/tests/krb5
 %dir %{python3_sitearch}/samba/tests/krb5/__pycache__
+%{python3_sitearch}/samba/tests/krb5/__pycache__/alias_tests.*.pyc
 %{python3_sitearch}/samba/tests/krb5/__pycache__/as_canonicalization_tests.*.pyc
+%{python3_sitearch}/samba/tests/krb5/__pycache__/as_req_tests.*.pyc
 %{python3_sitearch}/samba/tests/krb5/__pycache__/compatability_tests.*.pyc
+%{python3_sitearch}/samba/tests/krb5/__pycache__/fast_tests.*.pyc
 %{python3_sitearch}/samba/tests/krb5/__pycache__/kcrypto.*.pyc
 %{python3_sitearch}/samba/tests/krb5/__pycache__/kdc_base_test.*.pyc
 %{python3_sitearch}/samba/tests/krb5/__pycache__/kdc_tests.*.pyc
 %{python3_sitearch}/samba/tests/krb5/__pycache__/kdc_tgs_tests.*.pyc
+%{python3_sitearch}/samba/tests/krb5/__pycache__/ms_kile_client_principal_lookup_tests.*.pyc
 %{python3_sitearch}/samba/tests/krb5/__pycache__/raw_testcase.*.pyc
 %{python3_sitearch}/samba/tests/krb5/__pycache__/rfc4120_constants.*.pyc
 %{python3_sitearch}/samba/tests/krb5/__pycache__/rfc4120_pyasn1.*.pyc
+%{python3_sitearch}/samba/tests/krb5/__pycache__/rodc_tests*.pyc
+%{python3_sitearch}/samba/tests/krb5/__pycache__/salt_tests.*.pyc
 %{python3_sitearch}/samba/tests/krb5/__pycache__/simple_tests.*.pyc
+%{python3_sitearch}/samba/tests/krb5/__pycache__/spn_tests.*.pyc
 %{python3_sitearch}/samba/tests/krb5/__pycache__/s4u_tests.*.pyc
+%{python3_sitearch}/samba/tests/krb5/__pycache__/test_ccache.*.pyc
+%{python3_sitearch}/samba/tests/krb5/__pycache__/test_idmap_nss.*.pyc
+%{python3_sitearch}/samba/tests/krb5/__pycache__/test_ldap.*.pyc
+%{python3_sitearch}/samba/tests/krb5/__pycache__/test_min_domain_uid.*.pyc
+%{python3_sitearch}/samba/tests/krb5/__pycache__/test_rpc.*.pyc
+%{python3_sitearch}/samba/tests/krb5/__pycache__/test_smb.*.pyc
 %{python3_sitearch}/samba/tests/krb5/__pycache__/xrealm_tests.*.pyc
+%{python3_sitearch}/samba/tests/krb5/alias_tests.py
 %{python3_sitearch}/samba/tests/krb5/as_canonicalization_tests.py
+%{python3_sitearch}/samba/tests/krb5/as_req_tests.py
 %{python3_sitearch}/samba/tests/krb5/compatability_tests.py
+%{python3_sitearch}/samba/tests/krb5/fast_tests.py
 %{python3_sitearch}/samba/tests/krb5/kcrypto.py
 %{python3_sitearch}/samba/tests/krb5/kdc_base_test.py
 %{python3_sitearch}/samba/tests/krb5/kdc_tests.py
 %{python3_sitearch}/samba/tests/krb5/kdc_tgs_tests.py
+%{python3_sitearch}/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py
 %{python3_sitearch}/samba/tests/krb5/raw_testcase.py
 %{python3_sitearch}/samba/tests/krb5/rfc4120_constants.py
 %{python3_sitearch}/samba/tests/krb5/rfc4120_pyasn1.py
+%{python3_sitearch}/samba/tests/krb5/rodc_tests.py
+%{python3_sitearch}/samba/tests/krb5/salt_tests.py
 %{python3_sitearch}/samba/tests/krb5/simple_tests.py
+%{python3_sitearch}/samba/tests/krb5/spn_tests.py
+%{python3_sitearch}/samba/tests/krb5/test_ccache.py
+%{python3_sitearch}/samba/tests/krb5/test_idmap_nss.py
+%{python3_sitearch}/samba/tests/krb5/test_ldap.py
+%{python3_sitearch}/samba/tests/krb5/test_min_domain_uid.py
+%{python3_sitearch}/samba/tests/krb5/test_rpc.py
+%{python3_sitearch}/samba/tests/krb5/test_smb.py
 %{python3_sitearch}/samba/tests/krb5/s4u_tests.py
 %{python3_sitearch}/samba/tests/krb5/xrealm_tests.py
 %{python3_sitearch}/samba/tests/krb5_credentials.py
 %{python3_sitearch}/samba/tests/ldap_raw.py
 %{python3_sitearch}/samba/tests/ldap_referrals.py
+%{python3_sitearch}/samba/tests/ldap_spn.py
+%{python3_sitearch}/samba/tests/ldap_upn_sam_account.py
 %{python3_sitearch}/samba/tests/libsmb.py
 %{python3_sitearch}/samba/tests/loadparm.py
 %{python3_sitearch}/samba/tests/lsa_string.py
 %{python3_sitearch}/samba/tests/messaging.py
+%{python3_sitearch}/samba/tests/ndr.py
 %{python3_sitearch}/samba/tests/netbios.py
 %{python3_sitearch}/samba/tests/netcmd.py
 %{python3_sitearch}/samba/tests/net_join_no_spnego.py
@@ -2861,6 +3016,7 @@ fi
 %{python3_sitearch}/samba/tests/s3passdb.py
 %{python3_sitearch}/samba/tests/s3registry.py
 %{python3_sitearch}/samba/tests/s3windb.py
+%{python3_sitearch}/samba/tests/s3_net_join.py
 %{python3_sitearch}/samba/tests/samba3sam.py
 %{python3_sitearch}/samba/tests/samba_upgradedns_lmdb.py
 %dir %{python3_sitearch}/samba/tests/samba_tool
@@ -2877,6 +3033,7 @@ fi
 %{python3_sitearch}/samba/tests/samba_tool/__pycache__/forest.*.pyc
 %{python3_sitearch}/samba/tests/samba_tool/__pycache__/fsmo.*.pyc
 %{python3_sitearch}/samba/tests/samba_tool/__pycache__/gpo.*.pyc
+%{python3_sitearch}/samba/tests/samba_tool/__pycache__/gpo_exts.*.pyc
 %{python3_sitearch}/samba/tests/samba_tool/__pycache__/group.*.pyc
 %{python3_sitearch}/samba/tests/samba_tool/__pycache__/help.*.pyc
 %{python3_sitearch}/samba/tests/samba_tool/__pycache__/join.*.pyc
@@ -2888,6 +3045,7 @@ fi
 %{python3_sitearch}/samba/tests/samba_tool/__pycache__/promote_dc_lmdb_size.*.pyc
 %{python3_sitearch}/samba/tests/samba_tool/__pycache__/provision_lmdb_size.*.pyc
 %{python3_sitearch}/samba/tests/samba_tool/__pycache__/provision_password_check.*.pyc
+%{python3_sitearch}/samba/tests/samba_tool/__pycache__/provision_userPassword_crypt.*.pyc
 %{python3_sitearch}/samba/tests/samba_tool/__pycache__/rodc.*.pyc
 %{python3_sitearch}/samba/tests/samba_tool/__pycache__/schema.*.pyc
 %{python3_sitearch}/samba/tests/samba_tool/__pycache__/sites.*.pyc
@@ -2911,6 +3069,7 @@ fi
 %{python3_sitearch}/samba/tests/samba_tool/forest.py
 %{python3_sitearch}/samba/tests/samba_tool/fsmo.py
 %{python3_sitearch}/samba/tests/samba_tool/gpo.py
+%{python3_sitearch}/samba/tests/samba_tool/gpo_exts.py
 %{python3_sitearch}/samba/tests/samba_tool/group.py
 %{python3_sitearch}/samba/tests/samba_tool/help.py
 %{python3_sitearch}/samba/tests/samba_tool/join.py
@@ -2922,6 +3081,7 @@ fi
 %{python3_sitearch}/samba/tests/samba_tool/promote_dc_lmdb_size.py
 %{python3_sitearch}/samba/tests/samba_tool/provision_lmdb_size.py
 %{python3_sitearch}/samba/tests/samba_tool/provision_password_check.py
+%{python3_sitearch}/samba/tests/samba_tool/provision_userPassword_crypt.py
 %{python3_sitearch}/samba/tests/samba_tool/rodc.py
 %{python3_sitearch}/samba/tests/samba_tool/schema.py
 %{python3_sitearch}/samba/tests/samba_tool/sites.py
@@ -2937,6 +3097,7 @@ fi
 %{python3_sitearch}/samba/tests/samba_tool/visualize_drs.py
 %{python3_sitearch}/samba/tests/samdb.py
 %{python3_sitearch}/samba/tests/samdb_api.py
+%{python3_sitearch}/samba/tests/sddl.py
 %{python3_sitearch}/samba/tests/security.py
 %{python3_sitearch}/samba/tests/segfault.py
 %{python3_sitearch}/samba/tests/smb.py
@@ -3080,6 +3241,7 @@ fi
 %{_libexecdir}/ctdb/ctdb_recovery_helper
 %{_libexecdir}/ctdb/ctdb_takeover_helper
 %{_libexecdir}/ctdb/smnotify
+%{_libexecdir}/ctdb/tdb_mutex_check
 
 %dir %{_localstatedir}/lib/ctdb/
 %dir %{_localstatedir}/lib/ctdb/persistent
@@ -3910,6 +4072,33 @@ fi
 #endif with selftest
 %endif
 
+%if %{with pcp_pmda}
+%files -n ctdb-pcp-pmda
+%dir %{_localstatedir}/lib/pcp/pmdas/ctdb
+%{_localstatedir}/lib/pcp/pmdas/ctdb/Install
+%{_localstatedir}/lib/pcp/pmdas/ctdb/README
+%{_localstatedir}/lib/pcp/pmdas/ctdb/Remove
+%{_localstatedir}/lib/pcp/pmdas/ctdb/domain.h
+%{_localstatedir}/lib/pcp/pmdas/ctdb/help
+%{_localstatedir}/lib/pcp/pmdas/ctdb/pmdactdb
+%{_localstatedir}/lib/pcp/pmdas/ctdb/pmns
+#endif with pcp_pmda
+%endif
+
+%if %{with etcd_mutex}
+%files -n ctdb-etcd-mutex
+%{_libexecdir}/ctdb/ctdb_etcd_lock
+%{_mandir}/man7/ctdb-etcd.7.gz
+#endif with etcd_mutex
+%endif
+
+%if %{with ceph_mutex}
+%files -n ctdb-ceph-mutex
+%{_libexecdir}/ctdb/ctdb_mutex_ceph_rados_helper
+%{_mandir}/man7/ctdb_mutex_ceph_rados_helper.7.gz
+#endif with ceph_mutex
+%endif
+
 #endif with clustering
 %endif
 
@@ -3921,36 +4110,75 @@ fi
 %endif
 
 %changelog
-* Tue Feb 22 2022 Pavel Filipenský <pfilipen@redhat.com> - 4.14.5-10
-- resolves: rhbz#2029417 - Fix virusfilter_vfs_openat: Not scanned: Directory or special file
-
-* Thu Jan 27 2022 Andreas Schneider <asn@redhat.com> - 4.14.5-9
-- resolves: rhbz#2046174 - Fix username map script regression of CVE-2020-25717
-- resolves: rhbz#2046160 - Fix possible segfault while joining a domain
-- resolves: rhbz#2046152 - Fix CVE-2021-44142
-
-* Thu Dec 02 2021 Pavel Filipenský <pfilipen@redhat.com> - 4.14.5-8
-- resolves: rhbz#2026717 - Dir containing dangling symlinks cannot be deleted
-
-* Mon Nov 22 2021 Andreas Schneider <asn@redhat.com> - 4.14.5-7
-- related: rhbz#2021171 - Fix CVE-2020-25717
+* Wed Mar 16 2022 Andreas Schneider <asn@redhat.com> - 4.15.5-5
+- resolves: rhbz#2064325 - Fix 'create krb5 conf = yes` when a KDC has a
+                           single IP address.
+
+* Thu Feb 24 2022 Andreas Schneider <asn@redhat.com> - 4.15.5-4
+- resolves: rhbz#2057503 - Fix winbind kerberos ticket refresh
+
+* Mon Feb 21 2022 Andreas Schneider <asn@redhat.com> - 4.15.5-3
+- related: rhbz#1979959 - Fix typo in testparm output
+
+* Thu Feb 17 2022 Andreas Schneider <asn@redhat.com> - 4.15.5-2
+- resolves: rhbz#1979959 - Improve idmap autorid sanity checks and documentation
+
+* Mon Feb 14 2022 Pavel Filipenský <pfilipen@redhat.com> - 4.15.5-1
+- resolves: #1995849 - [RFE] Change change password change prompt phrasing
+- resolves: #2029417 - virusfilter_vfs_openat: Not scanned: Directory or special file 
+
+* Wed Feb 02 2022 Pavel Filipenský <pfilipen@redhat.com> - 4.15.5-0
+- Update to Samba 4.15.5
+- related: rhbz#2013596 - Rebase Samba to the the latest 4.15.x release
+- resolves: rhbz#2046127 - Fix CVE-2021-44141
+- resolves: rhbz#2046153 - Fix CVE-2021-44142
+- resolves: rhbz#2044404 - Printing no longer works on Windows 7
+- resolves: rhbz#2043154 - Fix systemd notifications
+- resolves: rhbz#2049602 - Disable NTLMSSP for ldap client connections (e.g. libads)
+
+* Fri Jan 21 2022 Pavel Filipenský <pfilipen@redhat.com> - 4.15.4-0
+- Update to Samba 4.15.4
+- related: rhbz#2013596 - Rebase Samba to the the latest 4.15.x release
+- resolves: rhbz#2039153 - Fix CVE-2021-20316
+- resolves: rhbz#1912549 - Winexe: Kerberos flag not invoking Kerberos Auth
+- resolves: rhbz#2039157 - Fix CVE-2021-43566
+- resolves: rhbz#2038148 - Failed to authenticate users after upgrade samba package to release samba-4.14.5-7
+- resolves: rhbz#2035528 - [smb] Segmentation fault when joining the domain
+- resolves: rhbz#2038796 - filename_convert_internal: open_pathref_fsp [xxx] failed: NT_STATUS_ACCESS_DENIED 
+
+* Thu Dec 16 2021 Pavel Filipenský <pfilipen@redhat.com> - 4.15.3-1
+- related: rhbz#2013596 - Rebase to version 4.15.3
+- resolves: rhbz#2028029 - Fix possible null pointer dereference in winbind
+- resolves: rhbz#1912549 - Winexe: Kerberos Auth is respected via --use-kerberos=desired
+
+* Fri Dec 03 2021 Andreas Schneider <asn@redhat.com> - 4.15.2-2
+- related: rhbz#2013596 - Remove unneeded lmdb dependency
+
+* Thu Nov 25 2021 Pavel Filipenský <pfilipen@redhat.com> - 4.15.2-1
+- resolves: rhbz#2013596 - Rebase to version 4.15.2
+- resolves: rhbz#1999294 - Remove noisy error message in winbindd
+- resolves: rhbz#1958881 - Don't require winbind being online for krb5 auth
+                           with one-way trusts
+- resolves: rhbz#2019461 - Fix deleting directories with dangling symlinks
+
+* Mon Nov 22 2021 Andreas Schneider <asn@redhat.com> - 4.14.5-14
+- related: rbhz#2019674 - Fix CVE-2020-25717
 - Fix running ktest (selftest)
 
-* Sat Nov 13 2021 Alexander Bokovoy <abokovoy@redhat.com> - 4.14.5-6
-- related: rhbz#2021171 - Fix CVE-2020-25717
+* Sat Nov 13 2021 Alexander Bokovoy <abokovoy@redhat.com> - 4.14.5-13
+- related: rbhz#2019674 - Fix CVE-2020-25717
 - Add missing checks for IPA DC server role
 
-* Tue Nov 09 2021 Andreas Schneider <asn@redhat.com> - 4.14.5-5
-- resolves: rhbz#2021493 - Add missing PAC buffer types to krb5pac.idl
-- related: rbhz#2021171 - Fix regression with 'allow trusted domains = no'
-
-* Fri Nov 05 2021 Andreas Schneider <asn@redhat.com> - 4.14.4-4
-- resolves: rhbz#2021163
-  Fix CVE-2016-2124
-- resolves: rhbz#2021167
-  Fix CVE-2021-23192
-- resolves: rhbz#2021171
-  Fix CVE-2020-25717
+* Wed Nov 10 2021 Andreas Schneider <asn@redhat.com> - 4.14.5-12
+- related: rbhz#2019674 - Fix regression with 'allow trusted domains = no'
+
+* Tue Nov 09 2021 Andreas Schneider <asn@redhat.com> - 4.14.5-11
+- resolves: rhbz#2021425 - Add missing PAC buffer types to krb5pac.idl
+
+* Fri Nov 05 2021 Andreas Schneider <asn@redhat.com> - 4.14.4-3
+- resolves: rhbz#2019662 - Fix CVE-2016-2124
+- resolves: rhbz#2019668 - Fix CVE-2021-23192
+- resolves: rbhz#2019674 - Fix CVE-2020-25717
 
 * Tue Jul 13 2021 Andreas Schneider <asn@redhat.com> -  4.14.4-2
 - related: rhbz#1980346 - Rebuild for libtalloc 0.11.0