krb5 commit: Simplify kdc_preauth.c systems table

Greg Hudson <[email protected]>
Newsgroups gmane.comp.encryption.kerberos.cvs
Message-ID <[email protected]>
https://github.com/krb5/krb5/commit/fea1a488924faa3938ef723feaa1ff12d22a91ff
commit fea1a488924faa3938ef723feaa1ff12d22a91ff
Author: Greg Hudson <[email protected]>
Date:   Sun Feb 11 15:23:35 2018 -0500

    Simplify kdc_preauth.c systems table
    
    Get rid of static_preauth_systems, and replace it with explicit calls
    to helper functions in get_preauth_hint_list() and return_padata().
    Stop preallocating pa-data lists, instead reallocating on each
    addition using add_pa_data_element().  Also simplify
    maybe_add_etype_info2() using add_pa_data_element().
    
    The KRB5_PADATA_PAC_REQUEST table entry did nothing, and was probably
    originally added back when the KDC would error out on unrecognized
    padata types.  The KRB5_PADATA_SERVER_REFERRAL entry has been disabled
    since it was first added.

 src/kdc/kdc_preauth.c |  522 +++++++++++++++++--------------------------------
 1 files changed, 182 insertions(+), 340 deletions(-)

diff --git a/src/kdc/kdc_preauth.c b/src/kdc/kdc_preauth.c
index edc30bd..6f34dc2 100644
--- a/src/kdc/kdc_preauth.c
+++ b/src/kdc/kdc_preauth.c
@@ -101,108 +101,14 @@ typedef struct preauth_system_st {
     krb5_kdcpreauth_loop_fn loop;
 } preauth_system;
 
+static preauth_system *preauth_systems;
+static size_t n_preauth_systems;
+
 static krb5_error_code
 make_etype_info(krb5_context context, krb5_preauthtype pa_type,
                 krb5_principal client, krb5_key_data *client_key,
                 krb5_enctype enctype, krb5_pa_data **pa_out);
 
-static void
-get_etype_info(krb5_context context, krb5_kdc_req *request,
-               krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock,
-               krb5_kdcpreauth_moddata moddata, krb5_preauthtype pa_type,
-               krb5_kdcpreauth_edata_respond_fn respond, void *arg);
-
-static krb5_error_code
-return_etype_info(krb5_context, krb5_pa_data *padata,
-                  krb5_data *req_pkt, krb5_kdc_req *request,
-                  krb5_kdc_rep *reply, krb5_keyblock *encrypting_key,
-                  krb5_pa_data **send_pa, krb5_kdcpreauth_callbacks cb,
-                  krb5_kdcpreauth_rock rock, krb5_kdcpreauth_moddata moddata,
-                  krb5_kdcpreauth_modreq modreq);
-
-static krb5_error_code
-return_pw_salt(krb5_context, krb5_pa_data *padata,
-               krb5_data *req_pkt, krb5_kdc_req *request, krb5_kdc_rep *reply,
-               krb5_keyblock *encrypting_key, krb5_pa_data **send_pa,
-               krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock,
-               krb5_kdcpreauth_moddata moddata, krb5_kdcpreauth_modreq modreq);
-
-
-
-static preauth_system static_preauth_systems[] = {
-    {
-        "FAST",
-        KRB5_PADATA_FX_FAST,
-        PA_HARDWARE,
-        NULL,
-        NULL,
-        NULL,
-        NULL,
-        NULL,
-        0
-    },
-    {
-        "etype-info",
-        KRB5_PADATA_ETYPE_INFO,
-        PA_HARDWARE,
-        NULL,
-        NULL,
-        NULL,
-        get_etype_info,
-        0,
-        return_etype_info
-    },
-    {
-        "etype-info2",
-        KRB5_PADATA_ETYPE_INFO2,
-        PA_HARDWARE,
-        NULL,
-        NULL,
-        NULL,
-        get_etype_info,
-        0,
-        return_etype_info
-    },
-    {
-        "pw-salt",
-        KRB5_PADATA_PW_SALT,
-        PA_PSEUDO,              /* Don't include this in the error list */
-        NULL,
-        NULL,
-        NULL,
-        0,
-        0,
-        return_pw_salt
-    },
-    {
-        "pac-request",
-        KRB5_PADATA_PAC_REQUEST,
-        PA_PSEUDO,
-        NULL,
-        NULL,
-        NULL,
-        NULL,
-        NULL,
-        NULL
-    },
-#if 0
-    {
-        "server-referral",
-        KRB5_PADATA_SERVER_REFERRAL,
-        PA_PSEUDO,
-        0,
-        0,
-        return_server_referral
-    },
-#endif
-};
-
-#define NUM_STATIC_PREAUTH_SYSTEMS (sizeof(static_preauth_systems) /    \
-                                    sizeof(*static_preauth_systems))
-
-static preauth_system *preauth_systems;
-static size_t n_preauth_systems;
-
 /* Get all available kdcpreauth vtables and a count of preauth types they
  * support.  Return an empty list on failure. */
 static void
@@ -284,7 +190,6 @@ load_preauth_plugins(struct server_handle *handle, krb5_context context,
     get_plugin_vtables(context, &vtables, &n_tables, &n_systems);
 
     /* Allocate the list of static and plugin preauth systems. */
-    n_systems += NUM_STATIC_PREAUTH_SYSTEMS;
     preauth_systems = calloc(n_systems + 1, sizeof(preauth_system));
     if (preauth_systems == NULL)
         goto cleanup;
@@ -292,13 +197,8 @@ load_preauth_plugins(struct server_handle *handle, krb5_context context,
     if (get_realm_names(handle, &realm_names))
         goto cleanup;
 
-    /* Add the static system to the list first.  No static systems require
-     * initialization, so just make a direct copy. */
-    memcpy(preauth_systems, static_preauth_systems,
-           sizeof(static_preauth_systems));
-
     /* Add the dynamically-loaded mechanisms to the list. */
-    n_systems = NUM_STATIC_PREAUTH_SYSTEMS;
+    n_systems = 0;
     for (i = 0; i < n_tables; i++) {
         /* Try to initialize this module. */
         vt = &vtables[i];
@@ -622,7 +522,9 @@ find_pa_system(int type, preauth_system **preauth)
 {
     preauth_system *ap;
 
-    ap = preauth_systems ? preauth_systems : static_preauth_systems;
+    if (preauth_systems == NULL)
+        return KRB5_PREAUTH_BAD_TYPE;
+    ap = preauth_systems;
     while ((ap->type != -1) && (ap->type != type))
         ap++;
     if (ap->type == -1)
@@ -776,6 +678,98 @@ const char *missing_required_preauth(krb5_db_entry *client,
     return 0;
 }
 
+/* Return true if request's enctypes indicate support for etype-info2. */
+static krb5_boolean
+requires_info2(const krb5_kdc_req *request)
+{
+    int i;
+
+    for (i = 0; i < request->nktypes; i++) {
+        if (enctype_requires_etype_info_2(request->ktype[i]))
+            return TRUE;
+    }
+    return FALSE;
+}
+
+/* Add PA-ETYPE-INFO2 and possibly PA-ETYPE-INFO entries to pa_list as
+ * appropriate for the request and client principal. */
+static krb5_error_code
+add_etype_info(krb5_context context, krb5_kdcpreauth_rock rock,
+               krb5_pa_data ***pa_list)
+{
+    krb5_error_code ret;
+    krb5_pa_data *pa;
+
+    if (rock->client_key == NULL)
+        return 0;
+
+    if (!requires_info2(rock->request)) {
+        /* Include PA-ETYPE-INFO only for old clients. */
+        ret = make_etype_info(context, KRB5_PADATA_ETYPE_INFO,
+                              rock->client->princ, rock->client_key,
+                              rock->client_keyblock->enctype, &pa);
+        if (ret)
+            return ret;
+        /* add_pa_data_element() claims pa on success or failure. */
+        ret = add_pa_data_element(pa_list, pa);
+        if (ret)
+            return ret;
+    }
+
+    /* Always include PA-ETYPE-INFO2. */
+    ret = make_etype_info(context, KRB5_PADATA_ETYPE_INFO2,
+                          rock->client->princ, rock->client_key,
+                          rock->client_keyblock->enctype, &pa);
+    if (ret)
+        return ret;
+    /* add_pa_data_element() claims pa on success or failure. */
+    return add_pa_data_element(pa_list, pa);
+}
+
+/* Add PW-SALT or AFS3-SALT entries to pa_list as appropriate for the request
+ * and client principal. */
+static krb5_error_code
+add_pw_salt(krb5_context context, krb5_kdcpreauth_rock rock,
+            krb5_pa_data ***pa_list)
+{
+    krb5_error_code ret;
+    krb5_pa_data *pa;
+    krb5_data *salt = NULL;
+    krb5_int16 salttype;
+
+    /* Only include this pa-data for old clients. */
+    if (rock->client_key == NULL || requires_info2(rock->request))
+        return 0;
+
+    ret = krb5_dbe_compute_salt(context, rock->client_key,
+                                rock->request->client, &salttype, &salt);
+    if (ret)
+        return 0;
+
+    if (salttype == KRB5_KDB_SALTTYPE_AFS3) {
+        ret = alloc_pa_data(KRB5_PADATA_AFS3_SALT, salt->length + 1, &pa);
+        if (ret)
+            goto cleanup;
+        memcpy(pa->contents, salt->data, salt->length);
+        pa->contents[salt->length] = '\0';
+    } else {
+        /* Steal memory from salt to make the pa-data entry. */
+        ret = alloc_pa_data(KRB5_PADATA_PW_SALT, 0, &pa);
+        if (ret)
+            goto cleanup;
+        pa->length = salt->length;
+        pa->contents = (uint8_t *)salt->data;
+        salt->data = NULL;
+    }
+
+    /* add_pa_data_element() claims pa on success or failure. */
+    ret = add_pa_data_element(pa_list, pa);
+
+cleanup:
+    krb5_free_data(context, salt);
+    return ret;
+}
+
 struct hint_state {
     kdc_hint_respond_fn respond;
     void *arg;
@@ -787,7 +781,7 @@ struct hint_state {
 
     int hw_only;
     preauth_system *ap;
-    krb5_pa_data **pa_data, **pa_cur;
+    krb5_pa_data **pa_data;
     krb5_preauthtype pa_type;
 };
 
@@ -799,7 +793,7 @@ hint_list_finish(struct hint_state *state, krb5_error_code code)
     kdc_realm_t *kdc_active_realm = state->realm;
 
     if (!code) {
-        if (state->pa_data[0] == 0) {
+        if (state->pa_data == NULL) {
             krb5_klog_syslog(LOG_INFO,
                              _("%spreauth required but hint list is empty"),
                              state->hw_only ? "hw" : "");
@@ -820,20 +814,27 @@ hint_list_next(struct hint_state *arg);
 static void
 finish_get_edata(void *arg, krb5_error_code code, krb5_pa_data *pa)
 {
+    krb5_error_code ret;
     struct hint_state *state = arg;
 
     if (code == 0) {
         if (pa == NULL) {
-            /* Include an empty value of the current type. */
-            pa = calloc(1, sizeof(*pa));
-            pa->magic = KV5M_PA_DATA;
-            pa->pa_type = state->pa_type;
+            ret = alloc_pa_data(state->pa_type, 0, &pa);
+            if (ret)
+                goto error;
         }
-        *state->pa_cur++ = pa;
+        /* add_pa_data_element() claims pa on success or failure. */
+        ret = add_pa_data_element(&state->pa_data, pa);
+        if (ret)
+            goto error;
     }
 
     state->ap++;
     hint_list_next(state);
+    return;
+
+error:
+    hint_list_finish(state, ret);
 }
 
 static void
@@ -870,16 +871,16 @@ get_preauth_hint_list(krb5_kdc_req *request, krb5_kdcpreauth_rock rock,
                       krb5_pa_data ***e_data_out, kdc_hint_respond_fn respond,
                       void *arg)
 {
+    kdc_realm_t *kdc_active_realm = rock->rstate->realm_data;
     struct hint_state *state;
+    krb5_pa_data *pa;
 
     *e_data_out = NULL;
 
     /* Allocate our state. */
     state = calloc(1, sizeof(*state));
-    if (state == NULL) {
-        (*respond)(arg);
-        return;
-    }
+    if (state == NULL)
+        goto error;
     state->hw_only = isflagset(rock->client->attributes,
                                KRB5_KDB_REQUIRES_HW_AUTH);
     state->respond = respond;
@@ -888,17 +889,27 @@ get_preauth_hint_list(krb5_kdc_req *request, krb5_kdcpreauth_rock rock,
     state->rock = rock;
     state->realm = rock->rstate->realm_data;
     state->e_data_out = e_data_out;
+    state->pa_data = NULL;
+    state->ap = preauth_systems;
 
-    state->pa_data = calloc(n_preauth_systems + 1, sizeof(krb5_pa_data *));
-    if (!state->pa_data) {
-        free(state);
-        (*respond)(arg);
-        return;
-    }
+    /* Add an empty PA-FX-FAST element to advertise FAST support. */
+    if (alloc_pa_data(KRB5_PADATA_FX_FAST, 0, &pa) != 0)
+        goto error;
+    /* add_pa_data_element() claims pa on success or failure. */
+    if (add_pa_data_element(&state->pa_data, pa) != 0)
+        goto error;
+
+    if (add_etype_info(kdc_context, rock, &state->pa_data) != 0)
+        goto error;
 
-    state->pa_cur = state->pa_data;
-    state->ap = preauth_systems;
     hint_list_next(state);
+    return;
+
+error:
+    if (state != NULL)
+        krb5_free_pa_data(kdc_context, state->pa_data);
+    free(state);
+    (*respond)(arg);
 }
 
 /*
@@ -1029,10 +1040,10 @@ filter_preauth_error(krb5_error_code code)
 static krb5_error_code
 maybe_add_etype_info2(struct padata_state *state, krb5_error_code code)
 {
+    krb5_error_code ret;
     krb5_context context = state->context;
     krb5_kdcpreauth_rock rock = state->rock;
-    krb5_pa_data **list = state->pa_e_data;
-    size_t count;
+    krb5_pa_data *pa;
 
     /* Only add key information when requesting another preauth round trip. */
     if (code != KRB5KDC_ERR_MORE_PREAUTH_DATA_REQUIRED)
@@ -1048,18 +1059,14 @@ maybe_add_etype_info2(struct padata_state *state, krb5_error_code code)
                              KRB5_PADATA_FX_COOKIE) != NULL)
         return 0;
 
-    /* Reallocate state->pa_e_data to make room for the etype-info2 element. */
-    for (count = 0; list != NULL && list[count] != NULL; count++);
-    list = realloc(list, (count + 2) * sizeof(*list));
-    if (list == NULL)
-        return ENOMEM;
-    list[count] = list[count + 1] = NULL;
-    state->pa_e_data = list;
+    ret = make_etype_info(context, KRB5_PADATA_ETYPE_INFO2,
+                          rock->client->princ, rock->client_key,
+                          rock->client_keyblock->enctype, &pa);
+    if (ret)
+        return ret;
 
-    /* Generate an etype-info2 element in the new slot. */
-    return make_etype_info(context, KRB5_PADATA_ETYPE_INFO2,
-                           rock->client->princ, rock->client_key,
-                           rock->client_keyblock->enctype, &list[count]);
+    /* add_pa_data_element() claims pa on success or failure. */
+    return add_pa_data_element(&state->pa_e_data, pa);
 }
 
 /* Release state and respond to the AS-REQ processing code with the result of
@@ -1279,17 +1286,20 @@ return_padata(krb5_context context, krb5_kdcpreauth_rock rock,
 {
     krb5_error_code             retval;
     krb5_pa_data **             padata;
-    krb5_pa_data **             send_pa_list;
-    krb5_pa_data **             send_pa;
+    krb5_pa_data **             send_pa_list = NULL;
+    krb5_pa_data *              send_pa;
     krb5_pa_data *              pa = 0;
     krb5_pa_data null_item;
     preauth_system *            ap;
-    int *                       pa_order;
+    int *                       pa_order = NULL;
     int *                       pa_type;
     int                         size = 0;
     krb5_kdcpreauth_modreq      *modreq_ptr;
     krb5_boolean                key_modified;
     krb5_keyblock               original_key;
+
+    memset(&original_key, 0, sizeof(original_key));
+
     if ((!*padata_context) &&
         (make_padata_context(context, padata_context) != 0)) {
         return KRB5KRB_ERR_GENERIC;
@@ -1300,26 +1310,18 @@ return_padata(krb5_context context, krb5_kdcpreauth_rock rock,
             size++;
     }
 
-    if ((send_pa_list = malloc((size+1) * sizeof(krb5_pa_data *))) == NULL)
-        return ENOMEM;
-    if ((pa_order = malloc((size+1) * sizeof(int))) == NULL) {
-        free(send_pa_list);
-        return ENOMEM;
-    }
+    pa_order = k5calloc(size + 1, sizeof(int), &retval);
+    if (pa_order == NULL)
+        goto cleanup;
     sort_pa_order(context, request, pa_order);
 
     retval = krb5_copy_keyblock_contents(context, encrypting_key,
                                          &original_key);
-    if (retval) {
-        free(send_pa_list);
-        free(pa_order);
-        return retval;
-    }
+    if (retval)
+        goto cleanup;
     key_modified = FALSE;
     null_item.contents = NULL;
     null_item.length = 0;
-    send_pa = send_pa_list;
-    *send_pa = 0;
 
     for (pa_type = pa_order; *pa_type != -1; pa_type++) {
         ap = &preauth_systems[*pa_type];
@@ -1349,20 +1351,30 @@ return_padata(krb5_context context, krb5_kdcpreauth_rock rock,
                 }
             }
         }
+        send_pa = NULL;
         retval = ap->return_padata(context, pa, req_pkt, request, reply,
-                                   encrypting_key, send_pa, &callbacks, rock,
+                                   encrypting_key, &send_pa, &callbacks, rock,
                                    ap->moddata, *modreq_ptr);
         if (retval)
             goto cleanup;
 
-        if (*send_pa)
-            send_pa++;
-        *send_pa = 0;
+        if (send_pa != NULL) {
+            /* add_pa_data_element() claims send_pa on success or failure. */
+            retval = add_pa_data_element(&send_pa_list, send_pa);
+            if (retval)
+                goto cleanup;
+        }
     }
 
-    retval = 0;
+    /* Add etype-info and pw-salt pa-data as needed. */
+    retval = add_etype_info(context, rock, &send_pa_list);
+    if (retval)
+        goto cleanup;
+    retval = add_pw_salt(context, rock, &send_pa_list);
+    if (retval)
+        goto cleanup;
 
-    if (send_pa_list[0]) {
+    if (send_pa_list != NULL) {
         reply->padata = send_pa_list;
         send_pa_list = 0;
     }
@@ -1370,8 +1382,7 @@ return_padata(krb5_context context, krb5_kdcpreauth_rock rock,
 cleanup:
     krb5_free_keyblock_contents(context, &original_key);
     free(pa_order);
-    if (send_pa_list)
-        krb5_free_pa_data(context, send_pa_list);
+    krb5_free_pa_data(context, send_pa_list);
 
     return (retval);
 }
@@ -1438,9 +1449,8 @@ make_etype_info(krb5_context context, krb5_preauthtype pa_type,
                 krb5_enctype enctype, krb5_pa_data **pa_out)
 {
     krb5_error_code retval;
-    krb5_pa_data *pa = NULL;
     krb5_etype_info_entry **entry = NULL;
-    krb5_data *scratch = NULL;
+    krb5_data *der_etype_info = NULL;
     int etype_info2 = (pa_type == KRB5_PADATA_ETYPE_INFO2);
 
     *pa_out = NULL;
@@ -1454,125 +1464,23 @@ make_etype_info(krb5_context context, krb5_preauthtype pa_type,
         goto cleanup;
 
     if (etype_info2)
-        retval = encode_krb5_etype_info2(entry, &scratch);
+        retval = encode_krb5_etype_info2(entry, &der_etype_info);
     else
-        retval = encode_krb5_etype_info(entry, &scratch);
+        retval = encode_krb5_etype_info(entry, &der_etype_info);
     if (retval)
         goto cleanup;
-    pa = k5alloc(sizeof(*pa), &retval);
-    if (pa == NULL)
-        goto cleanup;
-    pa->magic = KV5M_PA_DATA;
-    pa->pa_type = pa_type;
-    pa->contents = (unsigned char *)scratch->data;
-    pa->length = scratch->length;
-    scratch->data = NULL;
-    *pa_out = pa;
-
-cleanup:
-    krb5_free_etype_info(context, entry);
-    krb5_free_data(context, scratch);
-    return retval;
-}
-
-/* Return true if request's enctypes indicate support for etype-info2. */
-static krb5_boolean
-requires_info2(const krb5_kdc_req *request)
-{
-    int i;
-
-    for (i = 0; i < request->nktypes; i++) {
-        if (enctype_requires_etype_info_2(request->ktype[i]))
-            return TRUE;
-    }
-    return FALSE;
-}
 
-/* Generate hint list padata for PA-ETYPE-INFO or PA-ETYPE-INFO2. */
-static void
-get_etype_info(krb5_context context, krb5_kdc_req *request,
-               krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock,
-               krb5_kdcpreauth_moddata moddata, krb5_preauthtype pa_type,
-               krb5_kdcpreauth_edata_respond_fn respond, void *arg)
-{
-    krb5_error_code ret;
-    krb5_pa_data *pa = NULL;
-
-    if (rock->client_key == NULL) {
-        ret = KRB5KDC_ERR_PADATA_TYPE_NOSUPP;
-    } else if (pa_type == KRB5_PADATA_ETYPE_INFO && requires_info2(request)) {
-        ret = KRB5KDC_ERR_PADATA_TYPE_NOSUPP;
-    } else {
-        ret = make_etype_info(context, pa_type, rock->client->princ,
-                              rock->client_key, rock->client_keyblock->enctype,
-                              &pa);
-    }
-    (*respond)(arg, ret, pa);
-}
-
-/* Generate AS-REP padata for PA-ETYPE-INFO or PA-ETYPE-INFO2. */
-static krb5_error_code
-return_etype_info(krb5_context context, krb5_pa_data *padata,
-                  krb5_data *req_pkt, krb5_kdc_req *request,
-                  krb5_kdc_rep *reply, krb5_keyblock *encrypting_key,
-                  krb5_pa_data **send_pa, krb5_kdcpreauth_callbacks cb,
-                  krb5_kdcpreauth_rock rock, krb5_kdcpreauth_moddata moddata,
-                  krb5_kdcpreauth_modreq modreq)
-{
-    *send_pa = NULL;
-    if (rock->client_key == NULL)
-        return 0;
-    if (padata->pa_type == KRB5_PADATA_ETYPE_INFO && requires_info2(request))
-        return 0;
-    return make_etype_info(context, padata->pa_type, rock->client->princ,
-                           rock->client_key, encrypting_key->enctype, send_pa);
-}
-
-static krb5_error_code
-return_pw_salt(krb5_context context, krb5_pa_data *in_padata,
-               krb5_data *req_pkt, krb5_kdc_req *request, krb5_kdc_rep *reply,
-               krb5_keyblock *encrypting_key, krb5_pa_data **send_pa,
-               krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock,
-               krb5_kdcpreauth_moddata moddata, krb5_kdcpreauth_modreq modreq)
-{
-    krb5_error_code     retval;
-    krb5_pa_data *      padata;
-    krb5_data *         salt = NULL;
-    krb5_int16          salttype;
-    krb5_key_data *     client_key = rock->client_key;
-
-    if (client_key == NULL || requires_info2(request))
-        return 0;
-
-    retval = krb5_dbe_compute_salt(context, client_key, request->client,
-                                   &salttype, &salt);
+    /* Steal the data from der_etype_info to create a pa-data element. */
+    retval = alloc_pa_data(pa_type, 0, pa_out);
     if (retval)
-        return 0;
-
-    padata = k5alloc(sizeof(*padata), &retval);
-    if (padata == NULL)
         goto cleanup;
-    padata->magic = KV5M_PA_DATA;
-
-    if (salttype == KRB5_KDB_SALTTYPE_AFS3) {
-        padata->contents = k5memdup0(salt->data, salt->length, &retval);
-        if (padata->contents == NULL)
-            goto cleanup;
-        padata->pa_type = KRB5_PADATA_AFS3_SALT;
-        padata->length = salt->length + 1;
-    } else {
-        padata->pa_type = KRB5_PADATA_PW_SALT;
-        padata->length = salt->length;
-        padata->contents = (krb5_octet *)salt->data;
-        salt->data = NULL;
-    }
-
-    *send_pa = padata;
-    padata = NULL;
+    (*pa_out)->contents = (uint8_t *)der_etype_info->data;
+    (*pa_out)->length = der_etype_info->length;
+    der_etype_info->data = NULL;
 
 cleanup:
-    free(padata);
-    krb5_free_data(context, salt);
+    krb5_free_etype_info(context, entry);
+    krb5_free_data(context, der_etype_info);
     return retval;
 }
 
@@ -1656,69 +1564,3 @@ return_enc_padata(krb5_context context, krb5_data *req_pkt,
 cleanup:
     return code;
 }
-
-
-#if 0
-static krb5_error_code return_server_referral(krb5_context context,
-                                              krb5_pa_data * padata,
-                                              krb5_db_entry *client,
-                                              krb5_db_entry *server,
-                                              krb5_kdc_req *request,
-                                              krb5_kdc_rep *reply,
-                                              krb5_key_data *client_key,
-                                              krb5_keyblock *encrypting_key,
-                                              krb5_pa_data **send_pa)
-{
-    krb5_error_code             code;
-    krb5_tl_data                tl_data;
-    krb5_pa_data                *pa_data;
-    krb5_enc_data               enc_data;
-    krb5_data                   plain;
-    krb5_data                   *enc_pa_data;
-
-    *send_pa = NULL;
-
-    tl_data.tl_data_type = KRB5_TL_SERVER_REFERRAL;
-
-    code = krb5_dbe_lookup_tl_data(context, server, &tl_data);
-    if (code || tl_data.tl_data_length == 0)
-        return 0; /* no server referrals to return */
-
-    plain.length = tl_data.tl_data_length;
-    plain.data = tl_data.tl_data_contents;
-
-    /* Encrypt ServerReferralData */
-    code = krb5_encrypt_helper(context, encrypting_key,
-                               KRB5_KEYUSAGE_PA_SERVER_REFERRAL_DATA,
-                               &plain, &enc_data);
-    if (code)
-        return code;
-
-    /* Encode ServerReferralData into PA-SERVER-REFERRAL-DATA */
-    code = encode_krb5_enc_data(&enc_data, &enc_pa_data);
-    if (code) {
-        krb5_free_data_contents(context, &enc_data.ciphertext);
-        return code;
-    }
-
-    krb5_free_data_contents(context, &enc_data.ciphertext);
-
-    /* Return PA-SERVER-REFERRAL-DATA */
-    pa_data = (krb5_pa_data *)malloc(sizeof(*pa_data));
-    if (pa_data == NULL) {
-        krb5_free_data(context, enc_pa_data);
-        return ENOMEM;
-    }
-
-    pa_data->magic = KV5M_PA_DATA;
-    pa_data->pa_type = KRB5_PADATA_SVR_REFERRAL_INFO;
-    pa_data->length = enc_pa_data->length;
-    pa_data->contents = enc_pa_data->data;
-
-    free(enc_pa_data); /* don't free contents */
-
-    *send_pa = pa_data;
-
-    return 0;
-}
-#endif
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.