From 2149108966f4159a218a901c19bea3921d68fa1e Mon Sep 17 00:00:00 2001
From: Andrew Bartlett <abartlet@samba.org>
Date: Mon, 18 Oct 2021 16:00:45 +1300
Subject: [PATCH] kdc: Correctly strip PAC, rather than error on
 UF_NO_AUTH_DATA_REQUIRED for servers

UF_NO_AUTH_DATA_REQUIRED on a server/service account should cause
the PAC to be stripped not to given an error if the PAC was still
present.

Tested against Windows 2019

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14871
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14881

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
(cherry picked from commit 031a8287642e3c4b9d0b7c6b51f3b1d79b227542)
Conflict: remove selftest/knownfail_heimdal_kdc
---
 source4/kdc/wdc-samba4.c       | 38 +++++++++++++++++++++++-----------
 2 files changed, 26 insertions(+), 16 deletions(-)

diff --git a/source4/kdc/wdc-samba4.c b/source4/kdc/wdc-samba4.c
index 589df8a651d..ac9d7d51733 100644
--- a/source4/kdc/wdc-samba4.c
+++ b/source4/kdc/wdc-samba4.c
@@ -105,13 +105,15 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context,
 					    krb5_pac *pac,
 					    krb5_cksumtype ctype)
 {
-	struct samba_kdc_entry *p =
+	struct samba_kdc_entry *server_skdc_entry =
 		talloc_get_type_abort(server->ctx,
 		struct samba_kdc_entry);
 	struct samba_kdc_entry *krbtgt_skdc_entry =
 		talloc_get_type_abort(krbtgt->ctx,
 		struct samba_kdc_entry);
-	TALLOC_CTX *mem_ctx = talloc_named(p, 0, "samba_kdc_reget_pac2 context");
+	TALLOC_CTX *mem_ctx = talloc_named(server_skdc_entry,
+					   0,
+					   "samba_kdc_reget_pac2 context");
 	krb5_pac new_pac = NULL;
 	DATA_BLOB *pac_blob = NULL;
 	DATA_BLOB *upn_blob = NULL;
@@ -135,12 +137,6 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context,
 		return ENOMEM;
 	}
 
-	/* The user account may be set not to want the PAC */
-	if (!samba_princ_needs_pac(p)) {
-		talloc_free(mem_ctx);
-		return EINVAL;
-	}
-
 	/* If the krbtgt was generated by an RODC, and we are not that
 	 * RODC, then we need to regenerate the PAC - we can't trust
 	 * it */
@@ -373,12 +369,28 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context,
 		return EINVAL;
 	}
 
-	/* Build an updated PAC */
+	/*
+	 * The server account may be set not to want the PAC.
+	 *
+	 * While this is wasteful if the above cacluations were done
+	 * and now thrown away, this is cleaner as we do any ticket
+	 * signature checking etc always.
+	 *
+	 * UF_NO_AUTH_DATA_REQUIRED is the rare case and most of the
+	 * time (eg not accepting a ticket from the RODC) we do not
+	 * need to re-generate anything anyway.
+	 */
+	if (!samba_princ_needs_pac(server_skdc_entry)) {
+		ret = 0;
+		new_pac = NULL;
+		goto out;
+	}
+
+	/* Otherwise build an updated PAC */
 	ret = krb5_pac_init(context, &new_pac);
 	if (ret != 0) {
-		SAFE_FREE(types);
-		talloc_free(mem_ctx);
-		return ret;
+		new_pac = NULL;
+		goto out;
 	}
 
 	for (i = 0;;) {
@@ -496,6 +508,8 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context,
 		}
 	}
 
+out:
+
 	SAFE_FREE(types);
 
 	/* We now replace the pac */
-- 
2.33.0

