krb5/Refactor-KDC-authdata-list-management-helpers.patch
DistroBaker 2c0634c50d Merged update from upstream sources
This is an automated DistroBaker update from upstream sources.
If you do not know what this is about or would like to opt out,
contact the OSCI team.

Source: https://src.fedoraproject.org/rpms/krb5.git#bfdc7c0b7be1f33f451a173fb1155450fbe25690
2020-10-27 21:13:14 +01:00

336 lines
12 KiB
Diff

From 9335481c00cd15170adec244ccff0a00a014bbab Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Wed, 5 Feb 2020 18:46:11 -0500
Subject: [PATCH] Refactor KDC authdata list management helpers
Remove the unused concat_authorization_data(). Split merge_authdata()
into two helpers, one to destructively merge without filtering and one
to add copied elements while filtering out KDC-only authdata types.
Remove context parameters where they aren't needed (taking advantage
of knowledge that some libkrb5 functions don't use their context
parameters).
(cherry picked from commit b2190fdc253de6024001e0f1ff9fe56c31042bb7)
---
src/kdc/kdc_authdata.c | 138 +++++++++++++++++++----------------------
src/kdc/kdc_util.c | 50 ---------------
src/kdc/kdc_util.h | 5 --
3 files changed, 64 insertions(+), 129 deletions(-)
diff --git a/src/kdc/kdc_authdata.c b/src/kdc/kdc_authdata.c
index 1ebe87246..010922c27 100644
--- a/src/kdc/kdc_authdata.c
+++ b/src/kdc/kdc_authdata.c
@@ -108,7 +108,7 @@ unload_authdata_plugins(krb5_context context)
/* Return true if authdata should be filtered when copying from untrusted
* authdata. If desired_type is non-zero, look only for that type. */
static krb5_boolean
-is_kdc_issued_authdatum(krb5_context context, krb5_authdata *authdata,
+is_kdc_issued_authdatum(krb5_authdata *authdata,
krb5_authdatatype desired_type)
{
krb5_boolean result = FALSE;
@@ -117,7 +117,7 @@ is_kdc_issued_authdatum(krb5_context context, krb5_authdata *authdata,
krb5_authdatatype *ad_types, *containee_types = NULL;
if (authdata->ad_type == KRB5_AUTHDATA_IF_RELEVANT) {
- if (krb5int_get_authdata_containee_types(context, authdata, &count,
+ if (krb5int_get_authdata_containee_types(NULL, authdata, &count,
&containee_types) != 0)
goto cleanup;
ad_types = containee_types;
@@ -152,7 +152,7 @@ cleanup:
/* Return true if authdata contains any elements which should only come from
* the KDC. If desired_type is non-zero, look only for that type. */
static krb5_boolean
-has_kdc_issued_authdata(krb5_context context, krb5_authdata **authdata,
+has_kdc_issued_authdata(krb5_authdata **authdata,
krb5_authdatatype desired_type)
{
int i;
@@ -160,7 +160,7 @@ has_kdc_issued_authdata(krb5_context context, krb5_authdata **authdata,
if (authdata == NULL)
return FALSE;
for (i = 0; authdata[i] != NULL; i++) {
- if (is_kdc_issued_authdatum(context, authdata[i], desired_type))
+ if (is_kdc_issued_authdatum(authdata[i], desired_type))
return TRUE;
}
return FALSE;
@@ -181,66 +181,71 @@ has_mandatory_for_kdc_authdata(krb5_context context, krb5_authdata **authdata)
return FALSE;
}
-/*
- * Add the elements of in_authdata to out_authdata. If copy is false,
- * in_authdata is invalid on successful return. If ignore_kdc_issued is true,
- * KDC-issued authdata is not copied.
- */
+/* Add elements from *new_elements to *existing_list, reallocating as
+ * necessary. On success, release *new_elements and set it to NULL. */
static krb5_error_code
-merge_authdata(krb5_context context, krb5_authdata **in_authdata,
- krb5_authdata ***out_authdata, krb5_boolean copy,
- krb5_boolean ignore_kdc_issued)
+merge_authdata(krb5_authdata ***existing_list, krb5_authdata ***new_elements)
{
- krb5_error_code ret;
- size_t i, j, nadata = 0;
- krb5_authdata **in_copy = NULL, **authdata = *out_authdata;
+ size_t count = 0, ncount = 0;
+ krb5_authdata **list = *existing_list, **nlist = *new_elements;
- if (in_authdata == NULL || in_authdata[0] == NULL)
+ if (nlist == NULL)
return 0;
- if (authdata != NULL) {
- for (nadata = 0; authdata[nadata] != NULL; nadata++)
- ;
- }
+ for (count = 0; list != NULL && list[count] != NULL; count++);
+ for (ncount = 0; nlist[ncount] != NULL; ncount++);
- for (i = 0; in_authdata[i] != NULL; i++)
- ;
-
- if (copy) {
- ret = krb5_copy_authdata(context, in_authdata, &in_copy);
- if (ret)
- return ret;
- in_authdata = in_copy;
- }
-
- authdata = realloc(authdata, (nadata + i + 1) * sizeof(krb5_authdata *));
- if (authdata == NULL) {
- krb5_free_authdata(context, in_copy);
+ list = realloc(list, (count + ncount + 1) * sizeof(*list));
+ if (list == NULL)
return ENOMEM;
+
+ memcpy(list + count, nlist, ncount * sizeof(*nlist));
+ list[count + ncount] = NULL;
+ free(nlist);
+
+ if (list[0] == NULL) {
+ free(list);
+ list = NULL;
}
- for (i = 0, j = 0; in_authdata[i] != NULL; i++) {
- if (ignore_kdc_issued &&
- is_kdc_issued_authdatum(context, in_authdata[i], 0)) {
- free(in_authdata[i]->contents);
- free(in_authdata[i]);
+ *new_elements = NULL;
+ *existing_list = list;
+ return 0;
+}
+
+/* Add a copy of new_elements to *existing_list, omitting KDC-issued
+ * authdata. */
+static krb5_error_code
+add_filtered_authdata(krb5_authdata ***existing_list,
+ krb5_authdata **new_elements)
+{
+ krb5_error_code ret;
+ krb5_authdata **copy;
+ size_t i, j;
+
+ if (new_elements == NULL)
+ return 0;
+
+ ret = krb5_copy_authdata(NULL, new_elements, &copy);
+ if (ret)
+ return ret;
+
+ /* Remove KDC-issued elements from copy. */
+ j = 0;
+ for (i = 0; copy[i] != NULL; i++) {
+ if (is_kdc_issued_authdatum(copy[i], 0)) {
+ free(copy[i]->contents);
+ free(copy[i]);
} else {
- authdata[nadata + j++] = in_authdata[i];
+ copy[j++] = copy[i];
}
}
+ copy[j] = NULL;
- authdata[nadata + j] = NULL;
-
- free(in_authdata);
-
- if (authdata[0] == NULL) {
- free(authdata);
- authdata = NULL;
- }
-
- *out_authdata = authdata;
-
- return 0;
+ /* Destructively merge the filtered copy into existing_list. */
+ ret = merge_authdata(existing_list, &copy);
+ krb5_free_authdata(NULL, copy);
+ return ret;
}
/* Copy TGS-REQ authorization data into the ticket authdata. */
@@ -289,10 +294,7 @@ copy_request_authdata(krb5_context context, krb5_keyblock *client_key,
goto cleanup;
}
- /* Add a copy of the requested authdata to the ticket, ignoring KDC-issued
- * types. */
- ret = merge_authdata(context, req->unenc_authdata, tkt_authdata, TRUE,
- TRUE);
+ ret = add_filtered_authdata(tkt_authdata, req->unenc_authdata);
cleanup:
free(plaintext.data);
@@ -307,9 +309,7 @@ copy_tgt_authdata(krb5_context context, krb5_kdc_req *request,
if (has_mandatory_for_kdc_authdata(context, tgt_authdata))
return KRB5KDC_ERR_POLICY;
- /* Add a copy of the TGT authdata to the ticket, ignoring KDC-issued
- * types. */
- return merge_authdata(context, tgt_authdata, tkt_authdata, TRUE, TRUE);
+ return add_filtered_authdata(tkt_authdata, tgt_authdata);
}
/* Fetch authorization data from KDB module. */
@@ -374,8 +374,7 @@ fetch_kdb_authdata(krb5_context context, unsigned int flags,
/* Put the KDB authdata first in the ticket. A successful merge places the
* combined list in db_authdata and releases the old ticket authdata. */
- ret = merge_authdata(context, enc_tkt_reply->authorization_data,
- &db_authdata, FALSE, FALSE);
+ ret = merge_authdata(&db_authdata, &enc_tkt_reply->authorization_data);
if (ret)
krb5_free_authdata(context, db_authdata);
else
@@ -404,8 +403,7 @@ make_signedpath_data(krb5_context context, krb5_const_principal client,
return ret;
for (i = 0, j = 0; authdata[i] != NULL; i++) {
- if (is_kdc_issued_authdatum(context, authdata[i],
- KRB5_AUTHDATA_SIGNTICKET))
+ if (is_kdc_issued_authdatum(authdata[i], KRB5_AUTHDATA_SIGNTICKET))
continue;
sign_authdata[j++] = authdata[i];
@@ -635,12 +633,8 @@ make_signedpath(krb5_context context, krb5_const_principal for_user_princ,
if (ret)
goto cleanup;
- /* Add the authdata to the ticket, without copying or filtering. */
- ret = merge_authdata(context, if_relevant,
- &enc_tkt_reply->authorization_data, FALSE, FALSE);
- if (ret)
- goto cleanup;
- if_relevant = NULL; /* merge_authdata() freed */
+ /* Add the signedpath authdata to the ticket. */
+ ret = merge_authdata(&enc_tkt_reply->authorization_data, &if_relevant);
cleanup:
free(sp.delegated);
@@ -665,7 +659,7 @@ free_deleg_path(krb5_context context, krb5_principal *deleg_path)
static krb5_boolean
has_pac(krb5_context context, krb5_authdata **authdata)
{
- return has_kdc_issued_authdata(context, authdata, KRB5_AUTHDATA_WIN2K_PAC);
+ return has_kdc_issued_authdata(authdata, KRB5_AUTHDATA_WIN2K_PAC);
}
/* Verify AD-SIGNTICKET authdata if we need to, and insert an AD-SIGNEDPATH
@@ -746,11 +740,7 @@ add_auth_indicators(krb5_context context, krb5_data *const *auth_indicators,
goto cleanup;
/* Add the wrapped authdata to the ticket, without copying or filtering. */
- ret = merge_authdata(context, cammac, &enc_tkt_reply->authorization_data,
- FALSE, FALSE);
- if (ret)
- goto cleanup;
- cammac = NULL; /* merge_authdata() freed */
+ ret = merge_authdata(&enc_tkt_reply->authorization_data, &cammac);
cleanup:
krb5_free_data(context, der_indicators);
diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c
index 6330387d0..a4a05b9fa 100644
--- a/src/kdc/kdc_util.c
+++ b/src/kdc/kdc_util.c
@@ -78,56 +78,6 @@ static krb5_error_code find_server_key(krb5_context,
krb5_kvno, krb5_keyblock **,
krb5_kvno *);
-/*
- * concatenate first two authdata arrays, returning an allocated replacement.
- * The replacement should be freed with krb5_free_authdata().
- */
-krb5_error_code
-concat_authorization_data(krb5_context context,
- krb5_authdata **first, krb5_authdata **second,
- krb5_authdata ***output)
-{
- int i, j;
- krb5_authdata **ptr, **retdata;
-
- /* count up the entries */
- i = 0;
- if (first)
- for (ptr = first; *ptr; ptr++)
- i++;
- if (second)
- for (ptr = second; *ptr; ptr++)
- i++;
-
- retdata = (krb5_authdata **)malloc((i+1)*sizeof(*retdata));
- if (!retdata)
- return ENOMEM;
- retdata[i] = 0; /* null-terminated array */
- for (i = 0, j = 0, ptr = first; j < 2 ; ptr = second, j++)
- while (ptr && *ptr) {
- /* now walk & copy */
- retdata[i] = (krb5_authdata *)malloc(sizeof(*retdata[i]));
- if (!retdata[i]) {
- krb5_free_authdata(context, retdata);
- return ENOMEM;
- }
- *retdata[i] = **ptr;
- if (!(retdata[i]->contents =
- (krb5_octet *)malloc(retdata[i]->length))) {
- free(retdata[i]);
- retdata[i] = 0;
- krb5_free_authdata(context, retdata);
- return ENOMEM;
- }
- memcpy(retdata[i]->contents, (*ptr)->contents, retdata[i]->length);
-
- ptr++;
- i++;
- }
- *output = retdata;
- return 0;
-}
-
krb5_boolean
is_local_principal(kdc_realm_t *kdc_active_realm, krb5_const_principal princ1)
{
diff --git a/src/kdc/kdc_util.h b/src/kdc/kdc_util.h
index 2c9d8cf69..42b7ee208 100644
--- a/src/kdc/kdc_util.h
+++ b/src/kdc/kdc_util.h
@@ -52,11 +52,6 @@ compress_transited (krb5_data *,
krb5_principal,
krb5_data *);
krb5_error_code
-concat_authorization_data (krb5_context,
- krb5_authdata **,
- krb5_authdata **,
- krb5_authdata ***);
-krb5_error_code
fetch_last_req_info (krb5_db_entry *, krb5_last_req_entry ***);
krb5_error_code