154 lines
4.4 KiB
Diff
154 lines
4.4 KiB
Diff
From 940ddac4572b3caa419579c3bf60f6af0e019d18 Mon Sep 17 00:00:00 2001
|
|
From: Andreas Schneider <asn@samba.org>
|
|
Date: Mon, 12 Jul 2021 11:20:29 +0200
|
|
Subject: [PATCH 202/266] CVE-2020-25719 mit-samba: If we use client_princ,
|
|
|
|
Conflict: NA
|
|
Reference: https://git.samba.org/samba.git/?p=samba.git;a=patch;h=940ddac4572b3caa419579c3bf60f6af0e019d18
|
|
|
|
always lookup the db entry
|
|
|
|
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>
|
|
|
|
[abartlet@samba.org backported due to support for MIT KDB < 10
|
|
in Samba 4.14]
|
|
---
|
|
source4/kdc/mit-kdb/kdb_samba_policies.c | 81 ++++++++++++++++++++++--
|
|
1 file changed, 75 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/source4/kdc/mit-kdb/kdb_samba_policies.c b/source4/kdc/mit-kdb/kdb_samba_policies.c
|
|
index 9197551ed61..dce87c50049 100644
|
|
--- a/source4/kdc/mit-kdb/kdb_samba_policies.c
|
|
+++ b/source4/kdc/mit-kdb/kdb_samba_policies.c
|
|
@@ -323,6 +323,8 @@ krb5_error_code kdb_samba_db_sign_auth_data(krb5_context context,
|
|
krb5_authdata **tgt_auth_data,
|
|
krb5_authdata ***signed_auth_data)
|
|
{
|
|
+ krb5_const_principal ks_client_princ = NULL;
|
|
+ krb5_db_entry *client_entry = NULL;
|
|
krb5_authdata **authdata = NULL;
|
|
krb5_boolean is_as_req;
|
|
krb5_error_code code;
|
|
@@ -341,8 +343,72 @@ krb5_error_code kdb_samba_db_sign_auth_data(krb5_context context,
|
|
|
|
is_as_req = ((flags & KRB5_KDB_FLAG_CLIENT_REFERRALS_ONLY) != 0);
|
|
|
|
+ /*
|
|
+ * When using s4u2proxy client_princ actually refers to the proxied user
|
|
+ * while client->princ to the proxy service asking for the TGS on behalf
|
|
+ * of the proxied user. So always use client_princ in preference.
|
|
+ *
|
|
+ * Note that when client principal is not NULL, client entry might be
|
|
+ * NULL for cross-realm case, so we need to make sure to not
|
|
+ * dereference NULL pointer here.
|
|
+ */
|
|
+ if (client_princ != NULL) {
|
|
+ ks_client_princ = client_princ;
|
|
+ if (!is_as_req) {
|
|
+ krb5_boolean is_equal = false;
|
|
+
|
|
+ if (client != NULL && client->princ != NULL) {
|
|
+ is_equal =
|
|
+ krb5_principal_compare(context,
|
|
+ client_princ,
|
|
+ client->princ);
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * When client principal is the same as supplied client
|
|
+ * entry, don't fetch it.
|
|
+ */
|
|
+ if (!is_equal) {
|
|
+ code = ks_get_principal(context,
|
|
+ ks_client_princ,
|
|
+ 0,
|
|
+ &client_entry);
|
|
+ if (code != 0) {
|
|
+ char *client_name = NULL;
|
|
+
|
|
+ (void)krb5_unparse_name(context,
|
|
+ ks_client_princ,
|
|
+ &client_name);
|
|
+
|
|
+ DBG_DEBUG("We didn't find the client "
|
|
+ "principal [%s] in our "
|
|
+ "database.\n",
|
|
+ client_name);
|
|
+ SAFE_FREE(client_name);
|
|
+
|
|
+ /*
|
|
+ * If we didn't find client_princ in our
|
|
+ * database it might be from another
|
|
+ * realm.
|
|
+ */
|
|
+ client_entry = NULL;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ } else {
|
|
+ if (client == NULL) {
|
|
+ *signed_auth_data = NULL;
|
|
+ return 0;
|
|
+ }
|
|
+ ks_client_princ = client->princ;
|
|
+ }
|
|
+
|
|
+ if (client_entry == NULL) {
|
|
+ client_entry = client;
|
|
+ }
|
|
+
|
|
if (is_as_req && (flags & KRB5_KDB_FLAG_INCLUDE_PAC)) {
|
|
- code = ks_get_pac(context, client, client_key, &pac);
|
|
+ code = ks_get_pac(context, client_entry, client_key, &pac);
|
|
if (code != 0) {
|
|
goto done;
|
|
}
|
|
@@ -351,8 +417,8 @@ krb5_error_code kdb_samba_db_sign_auth_data(krb5_context context,
|
|
if (!is_as_req) {
|
|
code = ks_verify_pac(context,
|
|
flags,
|
|
- client_princ,
|
|
- client,
|
|
+ ks_client_princ,
|
|
+ client_entry,
|
|
server,
|
|
krbtgt,
|
|
server_key,
|
|
@@ -365,9 +431,9 @@ krb5_error_code kdb_samba_db_sign_auth_data(krb5_context context,
|
|
}
|
|
}
|
|
|
|
- if (pac == NULL && client != NULL) {
|
|
+ if (pac == NULL) {
|
|
|
|
- code = ks_get_pac(context, client, client_key, &pac);
|
|
+ code = ks_get_pac(context, client_entry, client_key, &pac);
|
|
if (code != 0) {
|
|
goto done;
|
|
}
|
|
@@ -378,7 +444,7 @@ krb5_error_code kdb_samba_db_sign_auth_data(krb5_context context,
|
|
goto done;
|
|
}
|
|
|
|
- code = krb5_pac_sign(context, pac, authtime, client_princ,
|
|
+ code = krb5_pac_sign(context, pac, authtime, ks_client_princ,
|
|
server_key, krbtgt_key, &pac_data);
|
|
if (code != 0) {
|
|
DBG_ERR("krb5_pac_sign failed: %d\n", code);
|
|
@@ -412,6 +478,9 @@ krb5_error_code kdb_samba_db_sign_auth_data(krb5_context context,
|
|
code = 0;
|
|
|
|
done:
|
|
+ if (client_entry != NULL && client_entry != client) {
|
|
+ ks_free_principal(context, client_entry);
|
|
+ }
|
|
krb5_pac_free(context, pac);
|
|
krb5_free_authdata(context, authdata);
|
|
|
|
--
|
|
2.23.0
|
|
|