[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Thu Jan 12 01:44:02 MST 2012


The branch, master has been updated
       via  bd164ac Revert "make paranoia check less paranoid" - check that key types strictly match
       via  3628f34 make hmac-md5 the keyed checksum type for arcfour-hmac-md5
       via  1787efa use ETYPE_DES3_CBC_SHA1 for the verify step in verify_mic_des3
       via  d087e71 heimdal: remove checking of KDC PAC signature, delegate to wdc plugin
       via  b69c40f auth/kerberos: Remove unused TALLOC_CTX argument to check_pac_checksum
       via  49f8113 s4-kdc Do the KDC PAC checksum validation in the Samba plugin
       via  d0bb8b8 s4-kdc: use IDL constant NETLOGON_GENERIC_KRB5_PAC_VALIDATE
      from  6764e4f samba-tool:dns: DNS names are case insensitive

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit bd164acb8237b4913f01c4c690b65a65e69ac551
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Thu Dec 15 12:29:01 2011 +1100

    Revert "make paranoia check less paranoid" - check that key types strictly match
    
    This reverts commit c25af51232616061bb08eea86aae595b4f029490 because
    otherwise we could attempt to check a CKSUMTYPE_HMAC_SHA1_96_AES_256 key with a
    KRB5_ENCTYPE_ARCFOUR_HMAC_MD5 key.
    
    Andrew Bartlett
    
    Autobuild-User: Andrew Bartlett <abartlet at samba.org>
    Autobuild-Date: Thu Jan 12 09:43:07 CET 2012 on sn-devel-104

commit 3628f34aa3b6036a267a0bc586a3f9433b58b9b9
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Thu Dec 15 16:36:03 2011 +1100

    make hmac-md5 the keyed checksum type for arcfour-hmac-md5

commit 1787efaa006b73cd682f6c27f2b5d367495e7e02
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Thu Dec 15 16:17:09 2011 +1100

    use ETYPE_DES3_CBC_SHA1 for the verify step in verify_mic_des3
    
    This allows a strict link between checksum types and key types to be
    enforced.
    
    Andrew Bartlett

commit d087e715fc803eae735636b4ebbb4c0f131f9bb4
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Jan 11 18:19:14 2012 +1100

    heimdal: remove checking of KDC PAC signature, delegate to wdc plugin
    
    The checking of the KDC signature is more complex than it looks, it may be of a different
    enc type to that which the ticket is encrypted with, and may even be prefixed
    with the RODC number.
    
    This is better handled in the plugin which can easily look up the DB for the
    correct key to verify this with, and can also quickly determine if this is
    an interdomain trust, which we cannot verify the PAC for.
    
    Andrew Bartlett

commit b69c40ffce7d1ab8828ec6a1df1d46f7e8c51278
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Jan 11 18:07:41 2012 +1100

    auth/kerberos: Remove unused TALLOC_CTX argument to check_pac_checksum

commit 49f8113fabd2603b45439404c91d350b4d6eaeac
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Jan 11 18:06:55 2012 +1100

    s4-kdc Do the KDC PAC checksum validation in the Samba plugin
    
    Here we can fetch the right key, and check if the PAC is likely to be signed by a key that
    we know.  We cannot check the KDC signature on incoming trusts.
    
    Andrew Bartlett

commit d0bb8b8a15c76c739062e7a78c013b54729dc5ab
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Jan 11 16:13:37 2012 +1100

    s4-kdc: use IDL constant NETLOGON_GENERIC_KRB5_PAC_VALIDATE

-----------------------------------------------------------------------

Summary of changes:
 auth/kerberos/kerberos_pac.c                 |    9 +--
 libcli/auth/krb5_wrap.h                      |    3 +-
 source4/heimdal/kdc/krb5tgs.c                |   14 +---
 source4/heimdal/lib/gssapi/krb5/verify_mic.c |    8 ++
 source4/heimdal/lib/krb5/crypto-arcfour.c    |    2 +-
 source4/heimdal/lib/krb5/crypto.c            |    2 +-
 source4/kdc/kdc.c                            |   31 +------
 source4/kdc/mit_samba.c                      |    5 +-
 source4/kdc/pac-glue.c                       |  114 +++++++++++++++++++++++---
 source4/kdc/pac-glue.h                       |   10 ++-
 source4/kdc/wdc-samba4.c                     |   36 ++++++++-
 source4/kdc/wscript_build                    |    2 +-
 12 files changed, 169 insertions(+), 67 deletions(-)


Changeset truncated at 500 lines:

diff --git a/auth/kerberos/kerberos_pac.c b/auth/kerberos/kerberos_pac.c
index 97fce73..5155c9f 100644
--- a/auth/kerberos/kerberos_pac.c
+++ b/auth/kerberos/kerberos_pac.c
@@ -28,8 +28,7 @@
 #include "librpc/gen_ndr/ndr_krb5pac.h"
 #include "libcli/auth/krb5_wrap.h"
 
-krb5_error_code check_pac_checksum(TALLOC_CTX *mem_ctx,
-					  DATA_BLOB pac_data,
+krb5_error_code check_pac_checksum(DATA_BLOB pac_data,
 					  struct PAC_SIGNATURE_DATA *sig,
 					  krb5_context context,
 					  const krb5_keyblock *keyblock)
@@ -304,8 +303,7 @@ NTSTATUS kerberos_decode_pac(TALLOC_CTX *mem_ctx,
 
 	if (service_keyblock) {
 		/* verify by service_key */
-		ret = check_pac_checksum(tmp_ctx,
-					 modified_pac_blob, srv_sig_ptr,
+		ret = check_pac_checksum(modified_pac_blob, srv_sig_ptr,
 					 context,
 					 service_keyblock);
 		if (ret) {
@@ -316,8 +314,7 @@ NTSTATUS kerberos_decode_pac(TALLOC_CTX *mem_ctx,
 
 		if (krbtgt_keyblock) {
 			/* verify the service key checksum by krbtgt_key */
-			ret = check_pac_checksum(tmp_ctx,
-						 srv_sig_ptr->signature, kdc_sig_ptr,
+			ret = check_pac_checksum(srv_sig_ptr->signature, kdc_sig_ptr,
 						 context, krbtgt_keyblock);
 			if (ret) {
 				DEBUG(1, ("PAC Decode: Failed to verify the KDC signature: %s\n",
diff --git a/libcli/auth/krb5_wrap.h b/libcli/auth/krb5_wrap.h
index affb892..814c427 100644
--- a/libcli/auth/krb5_wrap.h
+++ b/libcli/auth/krb5_wrap.h
@@ -58,8 +58,7 @@ char *gssapi_error_string(TALLOC_CTX *mem_ctx,
 			  const gss_OID mech);
 char *smb_get_krb5_error_message(krb5_context context, krb5_error_code code, TALLOC_CTX *mem_ctx);
 
-krb5_error_code check_pac_checksum(TALLOC_CTX *mem_ctx,
-				   DATA_BLOB pac_data,
+krb5_error_code check_pac_checksum(DATA_BLOB pac_data,
 				   struct PAC_SIGNATURE_DATA *sig,
 				   krb5_context context,
 				   const krb5_keyblock *keyblock);
diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c
index 96ee9cc..4568177 100644
--- a/source4/heimdal/kdc/krb5tgs.c
+++ b/source4/heimdal/kdc/krb5tgs.c
@@ -284,7 +284,6 @@ check_PAC(krb5_context context,
 	  hdb_entry_ex *server,
 	  hdb_entry_ex *krbtgt,
 	  const EncryptionKey *server_check_key,
-	  const EncryptionKey *krbtgt_check_key,
 	  const EncryptionKey *server_sign_key,
 	  const EncryptionKey *krbtgt_sign_key,
 	  EncTicketPart *tkt,
@@ -330,7 +329,7 @@ check_PAC(krb5_context context,
 
 		ret = krb5_pac_verify(context, pac, tkt->authtime,
 				      client_principal,
-				      server_check_key, krbtgt_check_key);
+				      server_check_key, NULL);
 		if (ret) {
 		    krb5_pac_free(context, pac);
 		    return ret;
@@ -1525,7 +1524,6 @@ tgs_build_reply(krb5_context context,
 
     Key *tkey_check;
     Key *tkey_sign;
-    Key *tkey_krbtgt_check = NULL;
     int flags = HDB_F_FOR_TGS_REQ;
 
     memset(&sessionkey, 0, sizeof(sessionkey));
@@ -1799,13 +1797,6 @@ server_lookup:
 	goto out;
     }
 
-    /* Check if we would know the krbtgt key for the PAC.  We would
-     * only know this if the krbtgt principal was the same (ie, in our
-     * realm, regardless of KVNO) */
-    if (krb5_principal_compare(context, krbtgt_out->entry.principal, krbtgt->entry.principal)) {
-	tkey_krbtgt_check = tkey_check;
-    }
-
     ret = _kdc_db_fetch(context, config, cp, HDB_F_GET_CLIENT | flags,
 			NULL, &clientdb, &client);
     if(ret == HDB_ERR_NOT_FOUND_HERE) {
@@ -1839,7 +1830,6 @@ server_lookup:
     ret = check_PAC(context, config, cp, NULL,
 		    client, server, krbtgt,
 		    &tkey_check->key,
-		    tkey_krbtgt_check ? &tkey_krbtgt_check->key : NULL,
 		    ekey, &tkey_sign->key,
 		    tgt, &rspac, &signedpath);
     if (ret) {
@@ -2109,7 +2099,7 @@ server_lookup:
 	 */
 	ret = check_PAC(context, config, tp, dp,
 			client, server, krbtgt,
-			&clientkey->key, &tkey_check->key,
+			&clientkey->key,
 			ekey, &tkey_sign->key,
 			&adtkt, &rspac, &ad_signedpath);
 	if (ret) {
diff --git a/source4/heimdal/lib/gssapi/krb5/verify_mic.c b/source4/heimdal/lib/gssapi/krb5/verify_mic.c
index af06e0a..0f56124 100644
--- a/source4/heimdal/lib/gssapi/krb5/verify_mic.c
+++ b/source4/heimdal/lib/gssapi/krb5/verify_mic.c
@@ -251,6 +251,14 @@ retry:
   csum.checksum.length = 20;
   csum.checksum.data   = p + 8;
 
+  krb5_crypto_destroy (context, crypto);
+  ret = krb5_crypto_init(context, key,
+			 ETYPE_DES3_CBC_SHA1, &crypto);
+  if (ret){
+      *minor_status = ret;
+      return GSS_S_FAILURE;
+  }
+
   ret = krb5_verify_checksum (context, crypto,
 			      KRB5_KU_USAGE_SIGN,
 			      tmp, message_buffer->length + 8,
diff --git a/source4/heimdal/lib/krb5/crypto-arcfour.c b/source4/heimdal/lib/krb5/crypto-arcfour.c
index 0a51316..e16b70c 100644
--- a/source4/heimdal/lib/krb5/crypto-arcfour.c
+++ b/source4/heimdal/lib/krb5/crypto-arcfour.c
@@ -317,7 +317,7 @@ struct _krb5_encryption_type _krb5_enctype_arcfour_hmac_md5 = {
     8,
     &keytype_arcfour,
     &_krb5_checksum_hmac_md5,
-    NULL,
+    &_krb5_checksum_hmac_md5,
     F_SPECIAL,
     ARCFOUR_encrypt,
     0,
diff --git a/source4/heimdal/lib/krb5/crypto.c b/source4/heimdal/lib/krb5/crypto.c
index 732311b..75d0a09 100644
--- a/source4/heimdal/lib/krb5/crypto.c
+++ b/source4/heimdal/lib/krb5/crypto.c
@@ -454,7 +454,7 @@ verify_checksum(krb5_context context,
 	    return KRB5_PROG_SUMTYPE_NOSUPP; /* XXX */
 	}
 	kct = crypto->et->keyed_checksum;
-	if (kct != NULL && kct->type != ct->type) {
+	if (kct == NULL || kct->type != ct->type) {
 	    krb5_set_error_message(context, KRB5_PROG_SUMTYPE_NOSUPP,
 				   N_("Checksum type %s is keyed, but "
 				      "the key type %s passed didnt have that checksum "
diff --git a/source4/kdc/kdc.c b/source4/kdc/kdc.c
index 9679144..d1ce527 100644
--- a/source4/kdc/kdc.c
+++ b/source4/kdc/kdc.c
@@ -32,6 +32,7 @@
 #include "lib/socket/netif.h"
 #include "param/param.h"
 #include "kdc/kdc-glue.h"
+#include "kdc/pac-glue.h"
 #include "dsdb/samdb/samdb.h"
 #include "auth/session.h"
 
@@ -777,7 +778,6 @@ static NTSTATUS kdc_startup_interfaces(struct kdc_server *kdc, struct loadparm_c
 	return NT_STATUS_OK;
 }
 
-
 static NTSTATUS kdc_check_generic_kerberos(struct irpc_message *msg,
 				 struct kdc_check_generic_kerberos *r)
 {
@@ -786,12 +786,9 @@ static NTSTATUS kdc_check_generic_kerberos(struct irpc_message *msg,
 	struct PAC_SIGNATURE_DATA kdc_sig;
 	struct kdc_server *kdc = talloc_get_type(msg->private_data, struct kdc_server);
 	enum ndr_err_code ndr_err;
-	krb5_enctype etype;
 	int ret;
 	hdb_entry_ex ent;
 	krb5_principal principal;
-	krb5_keyblock keyblock;
-	Key *key;
 
 	/* There is no reply to this request */
 	r->out.generic_reply = data_blob(NULL, 0);
@@ -802,7 +799,7 @@ static NTSTATUS kdc_check_generic_kerberos(struct irpc_message *msg,
 		return NT_STATUS_INVALID_PARAMETER;
 	}
 
-	if (pac_validate.MessageType != 3) {
+	if (pac_validate.MessageType != NETLOGON_GENERIC_KRB5_PAC_VALIDATE) {
 		/* We don't implement any other message types - such as certificate validation - yet */
 		return NT_STATUS_INVALID_PARAMETER;
 	}
@@ -816,16 +813,6 @@ static NTSTATUS kdc_check_generic_kerberos(struct irpc_message *msg,
 	srv_sig = data_blob_const(pac_validate.ChecksumAndSignature.data,
 				  pac_validate.ChecksumLength);
 
-	if (pac_validate.SignatureType == CKSUMTYPE_HMAC_MD5) {
-		etype = ETYPE_ARCFOUR_HMAC_MD5;
-	} else {
-		ret = krb5_cksumtype_to_enctype(kdc->smb_krb5_context->krb5_context, pac_validate.SignatureType,
-						&etype);
-		if (ret != 0) {
-			return NT_STATUS_LOGON_FAILURE;
-		}
-	}
-
 	ret = krb5_make_principal(kdc->smb_krb5_context->krb5_context, &principal,
 				  lpcfg_realm(kdc->task->lp_ctx),
 				  "krbtgt", lpcfg_realm(kdc->task->lp_ctx),
@@ -849,21 +836,11 @@ static NTSTATUS kdc_check_generic_kerberos(struct irpc_message *msg,
 		return NT_STATUS_LOGON_FAILURE;
 	}
 
-	ret = hdb_enctype2key(kdc->smb_krb5_context->krb5_context, &ent.entry, etype, &key);
-
-	if (ret != 0) {
-		hdb_free_entry(kdc->smb_krb5_context->krb5_context, &ent);
-		krb5_free_principal(kdc->smb_krb5_context->krb5_context, principal);
-		return NT_STATUS_LOGON_FAILURE;
-	}
-
-	keyblock = key->key;
-
 	kdc_sig.type = pac_validate.SignatureType;
 	kdc_sig.signature = data_blob_const(&pac_validate.ChecksumAndSignature.data[pac_validate.ChecksumLength],
 					    pac_validate.SignatureLength);
-	ret = check_pac_checksum(msg, srv_sig, &kdc_sig,
-			   kdc->smb_krb5_context->krb5_context, &keyblock);
+
+	ret = kdc_check_pac(kdc->smb_krb5_context->krb5_context, srv_sig, &kdc_sig, &ent);
 
 	hdb_free_entry(kdc->smb_krb5_context->krb5_context, &ent);
 	krb5_free_principal(kdc->smb_krb5_context->krb5_context, principal);
diff --git a/source4/kdc/mit_samba.c b/source4/kdc/mit_samba.c
index 06ee46e..f56e679 100644
--- a/source4/kdc/mit_samba.c
+++ b/source4/kdc/mit_samba.c
@@ -254,8 +254,11 @@ static int mit_samba_update_pac_data(struct mit_samba_context *ctx,
 		goto done;
 	}
 
+	/* TODO: An implementation-specific decision will need to be
+	 * made as to when to check the KDC pac signature, and how to
+	 * untrust untrusted RODCs */
 	nt_status = samba_kdc_update_pac_blob(tmp_ctx, ctx->context,
-					      pac, logon_blob);
+					      pac, logon_blob, NULL, NULL);
 	if (!NT_STATUS_IS_OK(nt_status)) {
 		DEBUG(0, ("Building PAC failed: %s\n",
 			  nt_errstr(nt_status)));
diff --git a/source4/kdc/pac-glue.c b/source4/kdc/pac-glue.c
index 5718452..3b0f00f 100644
--- a/source4/kdc/pac-glue.c
+++ b/source4/kdc/pac-glue.c
@@ -30,6 +30,8 @@
 #include "kdc/pac-glue.h"
 #include "param/param.h"
 #include "librpc/gen_ndr/ndr_krb5pac.h"
+#include "libcli/security/security.h"
+#include "dsdb/samdb/samdb.h"
 
 static
 NTSTATUS samba_get_logon_info_pac_blob(TALLOC_CTX *mem_ctx,
@@ -143,22 +145,74 @@ bool samba_princ_needs_pac(struct hdb_entry_ex *princ)
 	return true;
 }
 
-/* Was the krbtgt an RODC (and we are not) */
-bool samba_krbtgt_was_untrusted_rodc(struct hdb_entry_ex *princ)
+/* Was the krbtgt in this DB (ie, should we check the incoming signature) and was it an RODC */
+int samba_krbtgt_is_in_db(struct hdb_entry_ex *princ, bool *is_in_db, bool *is_untrusted)
 {
-
+	NTSTATUS status;
 	struct samba_kdc_entry *p = talloc_get_type(princ->ctx, struct samba_kdc_entry);
-	int rodc_krbtgt_number;
+	int rodc_krbtgt_number, trust_direction;
+	uint32_t rid;
+
+	TALLOC_CTX *mem_ctx = talloc_new(NULL);
+	if (!mem_ctx) {
+		return ENOMEM;
+	}
+	
+	trust_direction = ldb_msg_find_attr_as_int(p->msg, "trustDirection", 0);
+
+	if (trust_direction != 0) {
+		/* Domain trust - we cannot check the sig, but we trust it for a correct PAC
+		   
+		   This is exactly where we should flag for SID
+		   validation when we do inter-foreest trusts
+		 */
+		talloc_free(mem_ctx);
+		*is_untrusted = false;
+		*is_in_db = false;
+		return 0;
+	}
+
+	/* The lack of password controls etc applies to krbtgt by
+	 * virtue of being that particular RID */
+	status = dom_sid_split_rid(NULL, samdb_result_dom_sid(mem_ctx, p->msg, "objectSid"), NULL, &rid);
+
+	if (!NT_STATUS_IS_OK(status)) {
+		talloc_free(mem_ctx);
+		return EINVAL;
+	}
 
-	/* Determine if this was printed by an RODC */
 	rodc_krbtgt_number = ldb_msg_find_attr_as_int(p->msg, "msDS-SecondaryKrbTgtNumber", -1);
-	if (rodc_krbtgt_number == -1) {
-		return false;
-	} else if (rodc_krbtgt_number != p->kdc_db_ctx->my_krbtgt_number) {
-		return true;
+
+	if (p->kdc_db_ctx->my_krbtgt_number == 0) {
+		if (rid == DOMAIN_RID_KRBTGT) {
+			*is_untrusted = false;
+			*is_in_db = true;
+			talloc_free(mem_ctx);
+			return 0;
+		} else if (rodc_krbtgt_number != -1) {
+			*is_in_db = true;
+			*is_untrusted = true;
+			talloc_free(mem_ctx);
+			return 0;
+		}
+	} else if ((rid != DOMAIN_RID_KRBTGT) && (rodc_krbtgt_number == p->kdc_db_ctx->my_krbtgt_number)) {
+		talloc_free(mem_ctx);
+		*is_untrusted = false;
+		*is_in_db = true;
+		return 0;
+	} else if (rid == DOMAIN_RID_KRBTGT) {
+		/* krbtgt viewed from an RODC */
+		talloc_free(mem_ctx);
+		*is_untrusted = false;
+		*is_in_db = false;
+		return 0;
 	}
 
-	return false;
+	/* Another RODC */
+	talloc_free(mem_ctx);
+	*is_untrusted = true;
+	*is_in_db = false;
+	return 0;
 }
 
 NTSTATUS samba_kdc_get_pac_blob(TALLOC_CTX *mem_ctx,
@@ -208,14 +262,16 @@ NTSTATUS samba_kdc_get_pac_blob(TALLOC_CTX *mem_ctx,
 
 NTSTATUS samba_kdc_update_pac_blob(TALLOC_CTX *mem_ctx,
 				   krb5_context context,
-				   const krb5_pac pac, DATA_BLOB *pac_blob)
+				   const krb5_pac pac, DATA_BLOB *pac_blob,
+				   struct PAC_SIGNATURE_DATA *pac_srv_sig,
+				   struct PAC_SIGNATURE_DATA *pac_kdc_sig)
 {
 	struct auth_user_info_dc *user_info_dc;
 	krb5_error_code ret;
 	NTSTATUS nt_status;
 
 	ret = kerberos_pac_to_user_info_dc(mem_ctx, pac,
-					   context, &user_info_dc, NULL, NULL);
+					   context, &user_info_dc, pac_srv_sig, pac_kdc_sig);
 	if (ret) {
 		return NT_STATUS_UNSUCCESSFUL;
 	}
@@ -405,3 +461,37 @@ NTSTATUS samba_kdc_check_client_access(struct samba_kdc_entry *kdc_entry,
 	return nt_status;
 }
 
+int kdc_check_pac(krb5_context context,
+		  DATA_BLOB srv_sig,
+		  struct PAC_SIGNATURE_DATA *kdc_sig,
+		  hdb_entry_ex *ent)
+{
+	krb5_enctype etype;
+	int ret;
+	krb5_keyblock keyblock;
+	Key *key;
+	if (kdc_sig->type == CKSUMTYPE_HMAC_MD5) {
+		etype = ETYPE_ARCFOUR_HMAC_MD5;
+	} else {
+		ret = krb5_cksumtype_to_enctype(context, 
+						kdc_sig->type,
+						&etype);
+		if (ret != 0) {
+			return ret;
+		}
+	}
+
+	ret = hdb_enctype2key(context, &ent->entry, etype, &key);
+
+	if (ret != 0) {
+		return ret;
+	}
+
+	keyblock = key->key;
+
+	return check_pac_checksum(srv_sig, kdc_sig,
+				 context, &keyblock);
+}
+
+
+
diff --git a/source4/kdc/pac-glue.h b/source4/kdc/pac-glue.h
index 66c20cd..0e1cdcd 100644
--- a/source4/kdc/pac-glue.h
+++ b/source4/kdc/pac-glue.h
@@ -28,7 +28,7 @@ krb5_error_code samba_make_krb5_pac(krb5_context context,
 
 bool samba_princ_needs_pac(struct hdb_entry_ex *princ);
 
-bool samba_krbtgt_was_untrusted_rodc(struct hdb_entry_ex *princ);
+int samba_krbtgt_is_in_db(struct hdb_entry_ex *princ, bool *is_in_db, bool *is_untrusted);
 
 NTSTATUS samba_kdc_get_pac_blob(TALLOC_CTX *mem_ctx,
 				struct hdb_entry_ex *client,
@@ -36,7 +36,9 @@ NTSTATUS samba_kdc_get_pac_blob(TALLOC_CTX *mem_ctx,
 
 NTSTATUS samba_kdc_update_pac_blob(TALLOC_CTX *mem_ctx,
 				   krb5_context context,
-				   const krb5_pac pac, DATA_BLOB *pac_blob);
+				   const krb5_pac pac, DATA_BLOB *pac_blob,
+				   struct PAC_SIGNATURE_DATA *pac_srv_sig,
+				   struct PAC_SIGNATURE_DATA *pac_kdc_sig);
 
 NTSTATUS samba_kdc_update_delegation_info_blob(TALLOC_CTX *mem_ctx,
 				krb5_context context,
@@ -53,3 +55,7 @@ NTSTATUS samba_kdc_check_client_access(struct samba_kdc_entry *kdc_entry,
 				       const char *client_name,
 				       const char *workstation,
 				       bool password_change);
+int kdc_check_pac(krb5_context krb5_context,
+		  DATA_BLOB server_sig,
+		  struct PAC_SIGNATURE_DATA *kdc_sig,
+		  hdb_entry_ex *ent);
diff --git a/source4/kdc/wdc-samba4.c b/source4/kdc/wdc-samba4.c
index 99ad96a..70e849c 100644
--- a/source4/kdc/wdc-samba4.c
+++ b/source4/kdc/wdc-samba4.c
@@ -68,6 +68,9 @@ static krb5_error_code samba_wdc_reget_pac(void *priv, krb5_context context,
 	DATA_BLOB *deleg_blob = NULL;
 	krb5_error_code ret;
 	NTSTATUS nt_status;
+	struct PAC_SIGNATURE_DATA *pac_srv_sig;
+	struct PAC_SIGNATURE_DATA *pac_kdc_sig;
+	bool is_in_db, is_untrusted;
 
 	if (!mem_ctx) {
 		return ENOMEM;
@@ -82,7 +85,13 @@ static krb5_error_code samba_wdc_reget_pac(void *priv, krb5_context context,
 	/* 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 */
-	if (samba_krbtgt_was_untrusted_rodc(krbtgt)) {
+	ret = samba_krbtgt_is_in_db(krbtgt, &is_in_db, &is_untrusted);
+	if (ret != 0) {
+		talloc_free(mem_ctx);
+		return ret;
+	}
+
+	if (is_untrusted) {
 		if (client == NULL) {
 			return KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
 		}
@@ -98,14 +107,37 @@ static krb5_error_code samba_wdc_reget_pac(void *priv, krb5_context context,
 			return ENOMEM;
 		}
 
+		pac_srv_sig = talloc_zero(mem_ctx, struct PAC_SIGNATURE_DATA);
+		if (!pac_srv_sig) {
+			talloc_free(mem_ctx);
+			return ENOMEM;
+		}
+
+		pac_kdc_sig = talloc_zero(mem_ctx, struct PAC_SIGNATURE_DATA);
+		if (!pac_kdc_sig) {
+			talloc_free(mem_ctx);
+			return ENOMEM;
+		}
+
 		nt_status = samba_kdc_update_pac_blob(mem_ctx, context,
-						      *pac, pac_blob);
+						      *pac, pac_blob,
+						      pac_srv_sig, pac_kdc_sig);
 		if (!NT_STATUS_IS_OK(nt_status)) {
 			DEBUG(0, ("Building PAC failed: %s\n",
 				  nt_errstr(nt_status)));
 			talloc_free(mem_ctx);
 			return EINVAL;
 		}
+		
+		if (is_in_db) {
+			/* Now check the KDC signature, fetching the correct key based on the enc type */
+			ret = kdc_check_pac(context, pac_srv_sig->signature, pac_kdc_sig, krbtgt);
+			if (ret != 0) {


-- 
Samba Shared Repository


More information about the samba-cvs mailing list