200 lines
5.4 KiB
Diff
200 lines
5.4 KiB
Diff
From f99cff8c0515d5f29aba9d605415744b1d1c3b08 Mon Sep 17 00:00:00 2001
|
|
From: Andreas Schneider <asn@samba.org>
|
|
Date: Mon, 12 Jul 2021 14:00:19 +0200
|
|
Subject: [PATCH 205/266] CVE-2020-25719 mit-samba: Rework PAC handling in
|
|
|
|
Conflict: NA
|
|
Reference: https://git.samba.org/samba.git/?p=samba.git;a=patch;h=f99cff8c0515d5f29aba9d605415744b1d1c3b08
|
|
|
|
kdb_samba_db_sign_auth_data()
|
|
|
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561
|
|
|
|
Signed-off-by: Andreas Schneider <asn@samba.org>
|
|
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
|
---
|
|
selftest/knownfail_mit_kdc | 6 +-
|
|
source4/kdc/mit-kdb/kdb_samba_policies.c | 116 ++++++++++++++++++-----
|
|
2 files changed, 93 insertions(+), 29 deletions(-)
|
|
|
|
diff --git a/source4/kdc/mit-kdb/kdb_samba_policies.c b/source4/kdc/mit-kdb/kdb_samba_policies.c
|
|
index dce87c50049..7bc9a7b3347 100644
|
|
--- a/source4/kdc/mit-kdb/kdb_samba_policies.c
|
|
+++ b/source4/kdc/mit-kdb/kdb_samba_policies.c
|
|
@@ -4,7 +4,7 @@
|
|
Samba KDB plugin for MIT Kerberos
|
|
|
|
Copyright (c) 2010 Simo Sorce <idra@samba.org>.
|
|
- Copyright (c) 2014 Andreas Schneider <asn@samba.org>
|
|
+ Copyright (c) 2014-2021 Andreas Schneider <asn@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
|
|
@@ -325,11 +325,16 @@ krb5_error_code kdb_samba_db_sign_auth_data(krb5_context context,
|
|
{
|
|
krb5_const_principal ks_client_princ = NULL;
|
|
krb5_db_entry *client_entry = NULL;
|
|
+ krb5_authdata **pac_auth_data = NULL;
|
|
krb5_authdata **authdata = NULL;
|
|
krb5_boolean is_as_req;
|
|
krb5_error_code code;
|
|
krb5_pac pac = NULL;
|
|
krb5_data pac_data;
|
|
+ bool with_pac = false;
|
|
+ bool generate_pac = false;
|
|
+ char *client_name = NULL;
|
|
+
|
|
|
|
is_as_req = ((flags & KRB5_KDB_FLAG_CLIENT_REFERRALS_ONLY) != 0);
|
|
|
|
@@ -374,8 +379,6 @@ krb5_error_code kdb_samba_db_sign_auth_data(krb5_context context,
|
|
0,
|
|
&client_entry);
|
|
if (code != 0) {
|
|
- char *client_name = NULL;
|
|
-
|
|
(void)krb5_unparse_name(context,
|
|
ks_client_princ,
|
|
&client_name);
|
|
@@ -407,43 +410,105 @@ krb5_error_code kdb_samba_db_sign_auth_data(krb5_context context,
|
|
client_entry = client;
|
|
}
|
|
|
|
- if (is_as_req && (flags & KRB5_KDB_FLAG_INCLUDE_PAC)) {
|
|
+ if (is_as_req) {
|
|
+ with_pac = mit_samba_princ_needs_pac(client_entry);
|
|
+ } else {
|
|
+ with_pac = mit_samba_princ_needs_pac(server);
|
|
+ }
|
|
+
|
|
+ code = krb5_unparse_name(context,
|
|
+ client_princ,
|
|
+ &client_name);
|
|
+ if (code != 0) {
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
+ if (is_as_req && (flags & KRB5_KDB_FLAG_INCLUDE_PAC) != 0) {
|
|
+ generate_pac = true;
|
|
+ }
|
|
+
|
|
+ DBG_DEBUG("*** Sign data for client principal: %s [%s %s%s]\n",
|
|
+ client_name,
|
|
+ is_as_req ? "AS-REQ" : "TGS_REQ",
|
|
+ with_pac ? is_as_req ? "WITH_PAC" : "FIND_PAC" : "NO_PAC",
|
|
+ generate_pac ? " GENERATE_PAC" : "");
|
|
+
|
|
+ /*
|
|
+ * Generate PAC for the AS-REQ or check or generate one for the TGS if
|
|
+ * needed.
|
|
+ */
|
|
+ if (with_pac && generate_pac) {
|
|
+ DBG_DEBUG("Generate PAC for AS-REQ [%s]\n", client_name);
|
|
code = ks_get_pac(context, client_entry, client_key, &pac);
|
|
if (code != 0) {
|
|
goto done;
|
|
}
|
|
- }
|
|
-
|
|
- if (!is_as_req) {
|
|
- code = ks_verify_pac(context,
|
|
- flags,
|
|
- ks_client_princ,
|
|
- client_entry,
|
|
- server,
|
|
- krbtgt,
|
|
- server_key,
|
|
- krbtgt_key,
|
|
- authtime,
|
|
- tgt_auth_data,
|
|
- &pac);
|
|
+ } else if (with_pac && !is_as_req) {
|
|
+ /*
|
|
+ * Find the PAC in the TGS, if one exists.
|
|
+ */
|
|
+ code = krb5_find_authdata(context,
|
|
+ tgt_auth_data,
|
|
+ NULL,
|
|
+ KRB5_AUTHDATA_WIN2K_PAC,
|
|
+ &pac_auth_data);
|
|
if (code != 0) {
|
|
+ DBG_ERR("krb5_find_authdata failed: %d\n", code);
|
|
goto done;
|
|
}
|
|
- }
|
|
+ DBG_DEBUG("Found PAC data for TGS-REQ [%s]\n", client_name);
|
|
|
|
- if (pac == NULL) {
|
|
+ if (pac_auth_data != NULL && pac_auth_data[0] != NULL) {
|
|
+ if (pac_auth_data[1] != NULL) {
|
|
+ DBG_ERR("Invalid PAC data!\n");
|
|
+ code = KRB5KDC_ERR_BADOPTION;
|
|
+ goto done;
|
|
+ }
|
|
|
|
- code = ks_get_pac(context, client_entry, client_key, &pac);
|
|
- if (code != 0) {
|
|
- goto done;
|
|
+ DBG_DEBUG("Verify PAC for TGS [%s]\n",
|
|
+ client_name);
|
|
+
|
|
+ code = ks_verify_pac(context,
|
|
+ flags,
|
|
+ ks_client_princ,
|
|
+ client_entry,
|
|
+ server,
|
|
+ krbtgt,
|
|
+ server_key,
|
|
+ krbtgt_key,
|
|
+ authtime,
|
|
+ tgt_auth_data,
|
|
+ &pac);
|
|
+ if (code != 0) {
|
|
+ goto done;
|
|
+ }
|
|
+ } else {
|
|
+ if (flags & KRB5_KDB_FLAG_CONSTRAINED_DELEGATION) {
|
|
+ DBG_DEBUG("Generate PAC for constrained"
|
|
+ "delegation TGS [%s]\n",
|
|
+ client_name);
|
|
+
|
|
+ code = ks_get_pac(context,
|
|
+ client_entry,
|
|
+ client_key,
|
|
+ &pac);
|
|
+ if (code != 0 && code != ENOENT) {
|
|
+ goto done;
|
|
+ }
|
|
+ }
|
|
}
|
|
}
|
|
|
|
if (pac == NULL) {
|
|
- code = KRB5_KDB_DBTYPE_NOSUP;
|
|
+ DBG_DEBUG("No PAC data - we're done [%s]\n", client_name);
|
|
+ *signed_auth_data = NULL;
|
|
+ code = 0;
|
|
goto done;
|
|
}
|
|
|
|
+ DBG_DEBUG("Signing PAC for %s [%s]\n",
|
|
+ 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);
|
|
if (code != 0) {
|
|
@@ -481,8 +546,9 @@ done:
|
|
if (client_entry != NULL && client_entry != client) {
|
|
ks_free_principal(context, client_entry);
|
|
}
|
|
- krb5_pac_free(context, pac);
|
|
+ SAFE_FREE(client_name);
|
|
krb5_free_authdata(context, authdata);
|
|
+ krb5_pac_free(context, pac);
|
|
|
|
return code;
|
|
}
|
|
--
|
|
2.23.0
|
|
|