Mercurial > illumos > illumos-gate
changeset 10025:9214f62864a1
6787354 kpropd cored when converting incremental update to kdb entry for a particular principal
author | Peter Shoults <Peter.Shoults@Sun.COM> |
---|---|
date | Thu, 02 Jul 2009 16:15:22 -0400 |
parents | 2213a466547f |
children | 2659dc230676 |
files | usr/src/lib/krb5/kdb/kdb_convert.c |
diffstat | 1 files changed, 246 insertions(+), 300 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/lib/krb5/kdb/kdb_convert.c Thu Jul 02 10:30:52 2009 -0700 +++ b/usr/src/lib/krb5/kdb/kdb_convert.c Thu Jul 02 16:15:22 2009 -0400 @@ -1,10 +1,8 @@ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * This file contains api's for conversion of the kdb_incr_update_t * struct(s) into krb5_db_entry struct(s) and vice-versa. @@ -16,7 +14,8 @@ #include <iprop_hdr.h> #include "iprop.h" #include <k5-int.h> -#include <krb5/kdb.h> +#include <kdb.h> +#include <kdb_log.h> /* BEGIN CSTYLED */ #define ULOG_ENTRY_TYPE(upd, i) ((kdb_incr_update_t *)upd)->kdb_update.kdbe_t_val[i] @@ -41,9 +40,10 @@ * (by comparing it to the db_entry currently present in principal.db) * in the update. */ -void +static void find_changed_attrs(krb5_db_entry *current, krb5_db_entry *new, - kdbe_attr_type_t *attrs, int *nattrs) { + kdbe_attr_type_t *attrs, int *nattrs) +{ int i = 0, j = 0; krb5_tl_data *first, *second; @@ -139,77 +139,71 @@ *nattrs = i; } +static int +data_to_utf8str(utf8str_t *u, krb5_data d) +{ + u->utf8str_t_len = d.length; + if (d.data) { + u->utf8str_t_val = malloc(d.length); + if (u->utf8str_t_val == NULL) + return -1; + memcpy(u->utf8str_t_val, d.data, d.length); + } else + u->utf8str_t_val = NULL; + return 0; +} /* * Converts the krb5_principal struct from db2 to ulog format. */ -krb5_error_code +static krb5_error_code conv_princ_2ulog(krb5_principal princ, kdb_incr_update_t *upd, - int cnt, princ_type tp) { + int cnt, princ_type tp) { int i = 0; + kdbe_princ_t *p; + kdbe_data_t *components; if ((upd == NULL) || !princ) return (KRB5KRB_ERR_GENERIC); switch (tp) { case REG_PRINC: - ULOG_ENTRY(upd, cnt).av_princ.k_nametype = - (int32_t)princ->type; + case MOD_PRINC: + p = &ULOG_ENTRY(upd, cnt).av_princ; /* or av_mod_princ */ + p->k_nametype = (int32_t)princ->type; - ULOG_ENTRY(upd, cnt).av_princ.k_realm.utf8str_t_len = - princ->realm.length; - ULOG_ENTRY(upd, cnt).av_princ.k_realm.utf8str_t_val = - (princ->realm.data != NULL) ? - strdup(princ->realm.data) : NULL; - - ULOG_ENTRY(upd, cnt).av_princ.k_components.k_components_len = - (uint_t)princ->length; + if (data_to_utf8str(&p->k_realm, princ->realm) < 0) { + return ENOMEM; + } - ULOG_ENTRY(upd, cnt).av_princ.k_components.k_components_val = - malloc(princ->length * sizeof (kdbe_data_t)); - if (ULOG_ENTRY(upd, cnt).av_princ.k_components.k_components_val - == NULL) - return (ENOMEM); + p->k_components.k_components_len = princ->length; - for (i = 0; i < princ->length; i++) { - ULOG_ENTRY_PRINC(upd, cnt, i).k_magic = - princ->data[i].magic; - ULOG_ENTRY_PRINC(upd, cnt, i).k_data.utf8str_t_len = - princ->data[i].length; - ULOG_ENTRY_PRINC(upd, cnt, i).k_data.utf8str_t_val = - (princ->data[i].data != NULL) ? - strdup(princ->data[i].data) : NULL; + p->k_components.k_components_val = components + = malloc(princ->length * sizeof (kdbe_data_t)); + if (p->k_components.k_components_val == NULL) { + free(p->k_realm.utf8str_t_val); + p->k_realm.utf8str_t_val = NULL; + return (ENOMEM); } - break; - case MOD_PRINC: - ULOG_ENTRY(upd, cnt).av_mod_princ.k_nametype = - (int32_t)princ->type; - - ULOG_ENTRY(upd, cnt).av_mod_princ.k_realm.utf8str_t_len = - princ->realm.length; - - ULOG_ENTRY(upd, cnt).av_mod_princ.k_realm.utf8str_t_val = - (princ->realm.data != NULL) ? - strdup(princ->realm.data) : NULL; - - ULOG_ENTRY(upd, cnt).av_mod_princ.k_components.k_components_len - = (uint_t)princ->length; - - ULOG_ENTRY(upd, cnt).av_mod_princ.k_components.k_components_val - = malloc(princ->length * sizeof (kdbe_data_t)); - if (ULOG_ENTRY(upd, - cnt).av_mod_princ.k_components.k_components_val == NULL) - return (ENOMEM); - + memset(components, 0, princ->length * sizeof(kdbe_data_t)); + for (i = 0; i < princ->length; i++) + components[i].k_data.utf8str_t_val = NULL; for (i = 0; i < princ->length; i++) { - ULOG_ENTRY_MOD_PRINC(upd, cnt, i).k_magic = - princ->data[i].magic; - ULOG_ENTRY_MOD_PRINC(upd, cnt, i).k_data.utf8str_t_len - = princ->data[i].length; - ULOG_ENTRY_MOD_PRINC(upd, cnt, i).k_data.utf8str_t_val - = (princ->data[i].data != NULL) ? - strdup(princ->data[i].data) : NULL; + components[i].k_magic = princ->data[i].magic; + if (data_to_utf8str(&components[i].k_data, + princ->data[i]) < 0) { + int j; + for (j = 0; j < i; j++) { + free(components[j].k_data.utf8str_t_val); + components[j].k_data.utf8str_t_val = NULL; + } + free(components); + p->k_components.k_components_val = NULL; + free(p->k_realm.utf8str_t_val); + p->k_realm.utf8str_t_val = NULL; + return ENOMEM; + } } break; @@ -220,135 +214,73 @@ } /* + * Copies a UTF-8 string from ulog to a krb5_data object, which may + * already have allocated storage associated with it. + * + * Maybe a return value should indicate success/failure? + */ +static void +set_from_utf8str(krb5_data *d, utf8str_t u) +{ + if (u.utf8str_t_len > INT_MAX-1 || u.utf8str_t_len >= SIZE_MAX-1) { + d->data = NULL; + return; + } + d->length = u.utf8str_t_len; + d->data = malloc(d->length + 1); + if (d->data == NULL) + return; + if (d->length) /* Pointer may be null if length = 0. */ + strncpy(d->data, u.utf8str_t_val, d->length); + d->data[d->length] = 0; +} + +/* * Converts the krb5_principal struct from ulog to db2 format. */ -krb5_error_code -conv_princ_2db(krb5_context context, krb5_principal *dbprinc, - kdb_incr_update_t *upd, - int cnt, princ_type tp, - int princ_exists) { - +static krb5_principal +conv_princ_2db(krb5_context context, kdbe_princ_t *kdbe_princ) +{ int i; krb5_principal princ; + kdbe_data_t *components; - if (upd == NULL) - return (KRB5KRB_ERR_GENERIC); + princ = calloc(1, sizeof (krb5_principal_data)); + if (princ == NULL) { + return NULL; + } + princ->length = 0; + princ->data = NULL; + + components = kdbe_princ->k_components.k_components_val; - if (princ_exists == 0) { - princ = NULL; - princ = (krb5_principal)malloc(sizeof (krb5_principal_data)); - if (princ == NULL) { - return (ENOMEM); - } - } else { - princ = *dbprinc; + princ->type = (krb5_int32) kdbe_princ->k_nametype; + princ->realm.data = NULL; + set_from_utf8str(&princ->realm, kdbe_princ->k_realm); + if (princ->realm.data == NULL) + goto error; + + princ->data = calloc(kdbe_princ->k_components.k_components_len, + sizeof (krb5_data)); + if (princ->data == NULL) + goto error; + for (i = 0; i < kdbe_princ->k_components.k_components_len; i++) + princ->data[i].data = NULL; + princ->length = (krb5_int32)kdbe_princ->k_components.k_components_len; + + for (i = 0; i < princ->length; i++) { + princ->data[i].magic = components[i].k_magic; + set_from_utf8str(&princ->data[i], components[i].k_data); + if (princ->data[i].data == NULL) + goto error; } - switch (tp) { - case REG_PRINC: - princ->type = (krb5_int32) - ULOG_ENTRY(upd, cnt).av_princ.k_nametype; - princ->realm.length = (int) - ULOG_ENTRY(upd, cnt).av_princ.k_realm.utf8str_t_len; - - if (princ_exists == 0) - princ->realm.data = NULL; - princ->realm.data = (char *)realloc(princ->realm.data, - (princ->realm.length + 1)); - if (princ->realm.data == NULL) - goto error; - strlcpy(princ->realm.data, - (char *)ULOG_ENTRY(upd, cnt).av_princ.k_realm.utf8str_t_val, - (princ->realm.length + 1)); - - princ->length = (krb5_int32)ULOG_ENTRY(upd, - cnt).av_princ.k_components.k_components_len; - - if (princ_exists == 0) - princ->data = NULL; - princ->data = (krb5_data *)realloc(princ->data, - (princ->length * sizeof (krb5_data))); - if (princ->data == NULL) - goto error; - - for (i = 0; i < princ->length; i++) { - princ->data[i].magic = - ULOG_ENTRY_PRINC(upd, cnt, i).k_magic; - princ->data[i].length = (int) - ULOG_ENTRY_PRINC(upd, cnt, i).k_data.utf8str_t_len; - - if (princ_exists == 0) - princ->data[i].data = NULL; - princ->data[i].data = (char *)realloc( - princ->data[i].data, - (princ->data[i].length + 1)); - if (princ->data[i].data == NULL) - goto error; - - strlcpy(princ->data[i].data, (char *)ULOG_ENTRY_PRINC( - upd, cnt, i).k_data.utf8str_t_val, - (princ->data[i].length + 1)); - } - break; - - case MOD_PRINC: - princ->type = (krb5_int32) - ULOG_ENTRY(upd, cnt).av_mod_princ.k_nametype; - princ->realm.length = (int) - ULOG_ENTRY(upd, cnt).av_mod_princ.k_realm.utf8str_t_len; - - if (princ_exists == 0) - princ->realm.data = NULL; - princ->realm.data = (char *)realloc(princ->realm.data, - (princ->realm.length + 1)); - if (princ->realm.data == NULL) - goto error; - strlcpy(princ->realm.data, (char *)ULOG_ENTRY(upd, - cnt).av_mod_princ.k_realm.utf8str_t_val, - (princ->realm.length + 1)); - - princ->length = (krb5_int32)ULOG_ENTRY(upd, - cnt).av_mod_princ.k_components.k_components_len; - - if (princ_exists == 0) - princ->data = NULL; - princ->data = (krb5_data *)realloc(princ->data, - (princ->length * sizeof (krb5_data))); - if (princ->data == NULL) - goto error; - - for (i = 0; i < princ->length; i++) { - princ->data[i].magic = - ULOG_ENTRY_MOD_PRINC(upd, cnt, i).k_magic; - princ->data[i].length = (int) - ULOG_ENTRY_MOD_PRINC(upd, cnt, i).k_data.utf8str_t_len; - - if (princ_exists == 0) - princ->data[i].data = NULL; - princ->data[i].data = (char *)realloc( - princ->data[i].data, - (princ->data[i].length + 1)); - if (princ->data[i].data == NULL) - goto error; - strlcpy(princ->data[i].data, - (char *)ULOG_ENTRY_MOD_PRINC(upd, - cnt, i).k_data.utf8str_t_val, - (princ->data[i].length + 1)); - } - break; - - default: - break; - } - - *dbprinc = princ; - return (0); + return princ; error: krb5_free_principal(context, princ); - return (ENOMEM); + return NULL; } - /* * This routine converts one or more krb5 db2 records into update * log (ulog) entry format. Space for the update log entries should @@ -357,7 +289,8 @@ krb5_error_code ulog_conv_2logentry(krb5_context context, krb5_db_entry *entries, kdb_incr_update_t *updates, - int nentries) { + int nentries) +{ int i, j, k, cnt, final, nattrs, tmpint, nprincs; unsigned int more; krb5_principal tmpprinc; @@ -367,7 +300,7 @@ kdbe_attr_type_t *attr_types; kdb_incr_update_t *upd; krb5_db_entry *ent; - boolean_t kadm_data_yes; + int kadm_data_yes; if ((updates == NULL) || (entries == NULL)) return (KRB5KRB_ERR_GENERIC); @@ -378,7 +311,7 @@ for (k = 0; k < nentries; k++) { nprincs = nattrs = tmpint = 0; final = -1; - kadm_data_yes = B_FALSE; + kadm_data_yes = 0; attr_types = NULL; if ((upd->kdb_update.kdbe_t_val = (kdbe_val_t *) @@ -395,12 +328,9 @@ return (ENOMEM); } - /* - * Solaris Kerberos: avoid a deadlock since ulog_conv_2logentry - * is called by krb5_db2_db_put_principal which holds a lock. - */ - if ((ret = krb5_db_get_principal_nolock(context, ent->princ, - &curr, &nprincs, &more))) { + if ((ret = krb5_db_get_principal_nolock(context, ent->princ, &curr, + &nprincs, &more))) { + free(attr_types); return (ret); } @@ -511,8 +441,10 @@ ULOG_ENTRY_TYPE(upd, ++final).av_type = AT_PRINC; if ((ret = conv_princ_2ulog(ent->princ, - upd, final, REG_PRINC))) + upd, final, REG_PRINC))) { + free(attr_types); return (ret); + } } break; @@ -524,8 +456,10 @@ ULOG_ENTRY(upd, final).av_keydata.av_keydata_len = ent->n_key_data; ULOG_ENTRY(upd, final).av_keydata.av_keydata_val = malloc(ent->n_key_data * sizeof (kdbe_key_t)); - if (ULOG_ENTRY(upd, final).av_keydata.av_keydata_val == NULL) + if (ULOG_ENTRY(upd, final).av_keydata.av_keydata_val == NULL) { + free(attr_types); return (ENOMEM); + } for (j = 0; j < ent->n_key_data; j++) { ULOG_ENTRY_KEYVAL(upd, final, j).k_ver = ent->key_data[j].key_data_ver; @@ -534,19 +468,25 @@ ULOG_ENTRY_KEYVAL(upd, final, j).k_contents.k_contents_len = ent->key_data[j].key_data_ver; ULOG_ENTRY_KEYVAL(upd, final, j).k_enctype.k_enctype_val = malloc(ent->key_data[j].key_data_ver * sizeof(int32_t)); - if (ULOG_ENTRY_KEYVAL(upd, final, j).k_enctype.k_enctype_val == NULL) + if (ULOG_ENTRY_KEYVAL(upd, final, j).k_enctype.k_enctype_val == NULL) { + free(attr_types); return (ENOMEM); + } ULOG_ENTRY_KEYVAL(upd, final, j).k_contents.k_contents_val = malloc(ent->key_data[j].key_data_ver * sizeof(utf8str_t)); - if (ULOG_ENTRY_KEYVAL(upd, final, j).k_contents.k_contents_val == NULL) + if (ULOG_ENTRY_KEYVAL(upd, final, j).k_contents.k_contents_val == NULL) { + free(attr_types); return (ENOMEM); + } for (cnt = 0; cnt < ent->key_data[j].key_data_ver; cnt++) { ULOG_ENTRY_KEYVAL(upd, final, j).k_enctype.k_enctype_val[cnt] = ent->key_data[j].key_data_type[cnt]; ULOG_ENTRY_KEYVAL(upd, final, j).k_contents.k_contents_val[cnt].utf8str_t_len = ent->key_data[j].key_data_length[cnt]; ULOG_ENTRY_KEYVAL(upd, final, j).k_contents.k_contents_val[cnt].utf8str_t_val = malloc(ent->key_data[j].key_data_length[cnt] * sizeof (char)); - if (ULOG_ENTRY_KEYVAL(upd, final, j).k_contents.k_contents_val[cnt].utf8str_t_val == NULL) + if (ULOG_ENTRY_KEYVAL(upd, final, j).k_contents.k_contents_val[cnt].utf8str_t_val == NULL) { + free(attr_types); return (ENOMEM); + } (void) memcpy(ULOG_ENTRY_KEYVAL(upd, final, j).k_contents.k_contents_val[cnt].utf8str_t_val, ent->key_data[j].key_data_contents[cnt], ent->key_data[j].key_data_length[cnt]); } } @@ -572,8 +512,10 @@ ret = conv_princ_2ulog(tmpprinc, upd, final, MOD_PRINC); krb5_free_principal(context, tmpprinc); - if (ret) + if (ret) { + free(attr_types); return (ret); + } ULOG_ENTRY_TYPE(upd, ++final).av_type = AT_MOD_TIME; ULOG_ENTRY(upd, final).av_mod_time = @@ -589,14 +531,16 @@ case KRB5_TL_KADM_DATA: default: - if (kadm_data_yes == B_FALSE) { + if (kadm_data_yes == 0) { ULOG_ENTRY_TYPE(upd, ++final).av_type = AT_TL_DATA; ULOG_ENTRY(upd, final).av_tldata.av_tldata_len = 0; ULOG_ENTRY(upd, final).av_tldata.av_tldata_val = malloc(ent->n_tl_data * sizeof(kdbe_tl_t)); - if (ULOG_ENTRY(upd, final).av_tldata.av_tldata_val == NULL) + if (ULOG_ENTRY(upd, final).av_tldata.av_tldata_val == NULL) { + free(attr_types); return (ENOMEM); - kadm_data_yes = B_TRUE; + } + kadm_data_yes = 1; } tmpint = ULOG_ENTRY(upd, final).av_tldata.av_tldata_len; @@ -604,8 +548,10 @@ ULOG_ENTRY(upd, final).av_tldata.av_tldata_val[tmpint].tl_type = newtl->tl_data_type; ULOG_ENTRY(upd, final).av_tldata.av_tldata_val[tmpint].tl_data.tl_data_len = newtl->tl_data_length; ULOG_ENTRY(upd, final).av_tldata.av_tldata_val[tmpint].tl_data.tl_data_val = malloc(newtl->tl_data_length * sizeof (char)); - if (ULOG_ENTRY(upd, final).av_tldata.av_tldata_val[tmpint].tl_data.tl_data_val == NULL) + if (ULOG_ENTRY(upd, final).av_tldata.av_tldata_val[tmpint].tl_data.tl_data_val == NULL) { + free(attr_types); return (ENOMEM); + } (void) memcpy(ULOG_ENTRY(upd, final).av_tldata.av_tldata_val[tmpint].tl_data.tl_data_val, newtl->tl_data_contents, newtl->tl_data_length); break; } @@ -653,20 +599,12 @@ krb5_error_code ulog_conv_2dbentry(krb5_context context, krb5_db_entry *entries, kdb_incr_update_t *updates, - int nentries) { - int i, j, k, cnt, mod_time, nattrs, nprincs; - krb5_principal mod_princ = NULL; - krb5_principal dbprinc; - char *dbprincstr = NULL; - + int nentries) +{ + int k; krb5_db_entry *ent; kdb_incr_update_t *upd; - krb5_tl_data *newtl = NULL; - krb5_error_code ret; - unsigned int more; - unsigned int prev_n_keys = 0; - if ((updates == NULL) || (entries == NULL)) return (KRB5KRB_ERR_GENERIC); @@ -674,7 +612,15 @@ upd = updates; for (k = 0; k < nentries; k++) { - cnt = nprincs = 0; + krb5_principal mod_princ = NULL; + int i, j, cnt = 0, mod_time = 0, nattrs, nprincs = 0; + krb5_principal dbprinc; + char *dbprincstr = NULL; + + krb5_tl_data *newtl = NULL; + krb5_error_code ret; + unsigned int more; + unsigned int prev_n_keys = 0; /* * If the ulog entry represents a DELETE update, @@ -692,9 +638,9 @@ * sizeof (char)); if (dbprincstr == NULL) return (ENOMEM); - strlcpy(dbprincstr, (char *)upd->kdb_princ_name.utf8str_t_val, - (upd->kdb_princ_name.utf8str_t_len + 1)); - + strncpy(dbprincstr, (char *)upd->kdb_princ_name.utf8str_t_val, + upd->kdb_princ_name.utf8str_t_len); + dbprincstr[upd->kdb_princ_name.utf8str_t_len] = 0; ret = krb5_parse_name(context, dbprincstr, &dbprinc); free(dbprincstr); if (ret) @@ -713,117 +659,131 @@ ent->n_tl_data = 0; for (i = 0; i < nattrs; i++) { + krb5_principal tmpprinc = NULL; + +#define u (ULOG_ENTRY(upd, i)) switch (ULOG_ENTRY_TYPE(upd, i).av_type) { case AT_ATTRFLAGS: - ent->attributes = (krb5_flags) - ULOG_ENTRY(upd, i).av_attrflags; + ent->attributes = (krb5_flags) u.av_attrflags; break; case AT_MAX_LIFE: - ent->max_life = (krb5_deltat) - ULOG_ENTRY(upd, i).av_max_life; + ent->max_life = (krb5_deltat) u.av_max_life; break; case AT_MAX_RENEW_LIFE: - ent->max_renewable_life = (krb5_deltat) - ULOG_ENTRY(upd, i).av_max_renew_life; + ent->max_renewable_life = (krb5_deltat) u.av_max_renew_life; break; case AT_EXP: - ent->expiration = (krb5_timestamp) - ULOG_ENTRY(upd, i).av_exp; + ent->expiration = (krb5_timestamp) u.av_exp; break; case AT_PW_EXP: - ent->pw_expiration = (krb5_timestamp) - ULOG_ENTRY(upd, i).av_pw_exp; + ent->pw_expiration = (krb5_timestamp) u.av_pw_exp; break; case AT_LAST_SUCCESS: - ent->last_success = (krb5_timestamp) - ULOG_ENTRY(upd, i).av_last_success; + ent->last_success = (krb5_timestamp) u.av_last_success; break; case AT_LAST_FAILED: - ent->last_failed = (krb5_timestamp) - ULOG_ENTRY(upd, i).av_last_failed; + ent->last_failed = (krb5_timestamp) u.av_last_failed; break; case AT_FAIL_AUTH_COUNT: - ent->fail_auth_count = (krb5_kvno) - ULOG_ENTRY(upd, i).av_fail_auth_count; + ent->fail_auth_count = (krb5_kvno) u.av_fail_auth_count; break; case AT_PRINC: - if ((ret = conv_princ_2db(context, - &(ent->princ), upd, - i, REG_PRINC, nprincs))) - return (ret); + tmpprinc = conv_princ_2db(context, &u.av_princ); + if (tmpprinc == NULL) + return ENOMEM; + if (nprincs) + krb5_free_principal(context, ent->princ); + ent->princ = tmpprinc; break; case AT_KEYDATA: if (nprincs != 0) prev_n_keys = ent->n_key_data; - - ent->n_key_data = (krb5_int16)ULOG_ENTRY(upd, - i).av_keydata.av_keydata_len; + else + prev_n_keys = 0; + ent->n_key_data = (krb5_int16)u.av_keydata.av_keydata_len; if (nprincs == 0) ent->key_data = NULL; - ent->key_data = (krb5_key_data *)realloc( - ent->key_data, - (ent->n_key_data * + ent->key_data = (krb5_key_data *)realloc(ent->key_data, + (ent->n_key_data * sizeof (krb5_key_data))); + /* XXX Memory leak: Old key data in + records eliminated by resizing to + smaller size. */ if (ent->key_data == NULL) + /* XXX Memory leak: old storage. */ return (ENOMEM); /* BEGIN CSTYLED */ + for (j = prev_n_keys; j < ent->n_key_data; j++) { + for (cnt = 0; cnt < 2; cnt++) { + ent->key_data[j].key_data_contents[cnt] = NULL; + } + } for (j = 0; j < ent->n_key_data; j++) { - ent->key_data[j].key_data_ver = (krb5_int16)ULOG_ENTRY_KEYVAL(upd, i, j).k_ver; - ent->key_data[j].key_data_kvno = (krb5_int16)ULOG_ENTRY_KEYVAL(upd, i, j).k_kvno; + krb5_key_data *kp = &ent->key_data[j]; + kdbe_key_t *kv = &ULOG_ENTRY_KEYVAL(upd, i, j); + kp->key_data_ver = (krb5_int16)kv->k_ver; + kp->key_data_kvno = (krb5_int16)kv->k_kvno; + if (kp->key_data_ver > 2) { + return EINVAL; /* XXX ? */ + } - for (cnt = 0; cnt < ent->key_data[j].key_data_ver; cnt++) { - ent->key_data[j].key_data_type[cnt] = (krb5_int16)ULOG_ENTRY_KEYVAL(upd, i, j).k_enctype.k_enctype_val[cnt]; - ent->key_data[j].key_data_length[cnt] = (krb5_int16)ULOG_ENTRY_KEYVAL(upd, i, j).k_contents.k_contents_val[cnt].utf8str_t_len; - if ((nprincs == 0) || (j >= prev_n_keys)) - ent->key_data[j].key_data_contents[cnt] = NULL; + for (cnt = 0; cnt < kp->key_data_ver; cnt++) { + void *newptr; + kp->key_data_type[cnt] = (krb5_int16)kv->k_enctype.k_enctype_val[cnt]; + kp->key_data_length[cnt] = (krb5_int16)kv->k_contents.k_contents_val[cnt].utf8str_t_len; + newptr = realloc(kp->key_data_contents[cnt], + kp->key_data_length[cnt]); + if (newptr == NULL) + return ENOMEM; + kp->key_data_contents[cnt] = newptr; - ent->key_data[j].key_data_contents[cnt] = (krb5_octet *)realloc(ent->key_data[j].key_data_contents[cnt], ent->key_data[j].key_data_length[cnt]); - if (ent->key_data[j].key_data_contents[cnt] == NULL) - return (ENOMEM); - - (void) memset(ent->key_data[j].key_data_contents[cnt], 0, (ent->key_data[j].key_data_length[cnt] * sizeof (krb5_octet))); - (void) memcpy(ent->key_data[j].key_data_contents[cnt], ULOG_ENTRY_KEYVAL(upd, i, j).k_contents.k_contents_val[cnt].utf8str_t_val, ent->key_data[j].key_data_length[cnt]); + (void) memset(kp->key_data_contents[cnt], 0, + kp->key_data_length[cnt]); + (void) memcpy(kp->key_data_contents[cnt], + kv->k_contents.k_contents_val[cnt].utf8str_t_val, + kp->key_data_length[cnt]); } } break; case AT_TL_DATA: - cnt = ULOG_ENTRY(upd, i).av_tldata.av_tldata_len; + cnt = u.av_tldata.av_tldata_len; newtl = malloc(cnt * sizeof (krb5_tl_data)); (void) memset(newtl, 0, (cnt * sizeof (krb5_tl_data))); if (newtl == NULL) return (ENOMEM); - for (j = 0; j < cnt; j++){ - newtl[j].tl_data_type = (krb5_int16)ULOG_ENTRY(upd, i).av_tldata.av_tldata_val[j].tl_type; - newtl[j].tl_data_length = (krb5_int16)ULOG_ENTRY(upd, i).av_tldata.av_tldata_val[j].tl_data.tl_data_len; + for (j = 0; j < cnt; j++) { + newtl[j].tl_data_type = (krb5_int16)u.av_tldata.av_tldata_val[j].tl_type; + newtl[j].tl_data_length = (krb5_int16)u.av_tldata.av_tldata_val[j].tl_data.tl_data_len; newtl[j].tl_data_contents = NULL; newtl[j].tl_data_contents = malloc(newtl[j].tl_data_length * sizeof (krb5_octet)); if (newtl[j].tl_data_contents == NULL) + /* XXX Memory leak: newtl + and previously + allocated elements. */ return (ENOMEM); (void) memset(newtl[j].tl_data_contents, 0, (newtl[j].tl_data_length * sizeof (krb5_octet))); - (void) memcpy(newtl[j].tl_data_contents, ULOG_ENTRY(upd, i).av_tldata.av_tldata_val[j].tl_data.tl_data_val, newtl[j].tl_data_length); + (void) memcpy(newtl[j].tl_data_contents, u.av_tldata.av_tldata_val[j].tl_data.tl_data_val, newtl[j].tl_data_length); newtl[j].tl_data_next = NULL; if (j > 0) - newtl[j - 1].tl_data_next = - &newtl[j]; + newtl[j - 1].tl_data_next = &newtl[j]; } - if ((ret = krb5_dbe_update_tl_data(context, - ent, newtl))) + if ((ret = krb5_dbe_update_tl_data(context, ent, newtl))) return (ret); for (j = 0; j < cnt; j++) if (newtl[j].tl_data_contents) { @@ -838,32 +798,30 @@ /* END CSTYLED */ case AT_PW_LAST_CHANGE: - if ((ret = krb5_dbe_update_last_pwd_change( - context, ent, - ULOG_ENTRY(upd, i).av_pw_last_change))) + if ((ret = krb5_dbe_update_last_pwd_change(context, ent, + u.av_pw_last_change))) return (ret); break; case AT_MOD_PRINC: - if ((ret = conv_princ_2db(context, - &mod_princ, upd, - i, MOD_PRINC, 0))) - return (ret); + tmpprinc = conv_princ_2db(context, &u.av_mod_princ); + if (tmpprinc == NULL) + return ENOMEM; + mod_princ = tmpprinc; break; case AT_MOD_TIME: - mod_time = ULOG_ENTRY(upd, i).av_mod_time; + mod_time = u.av_mod_time; break; case AT_LEN: - ent->len = (krb5_int16) - ULOG_ENTRY(upd, i).av_len; + ent->len = (krb5_int16) u.av_len; break; default: break; } - +#undef u } /* @@ -873,6 +831,7 @@ ret = krb5_dbe_update_mod_princ_data(context, ent, mod_time, mod_princ); krb5_free_principal(context, mod_princ); + mod_princ = NULL; if (ret) return (ret); } @@ -893,7 +852,8 @@ * This routine frees up memory associated with the bunched ulog entries. */ void -ulog_free_entries(kdb_incr_update_t *updates, int no_of_updates) { +ulog_free_entries(kdb_incr_update_t *updates, int no_of_updates) +{ kdb_incr_update_t *upd; int i, j, k, cnt; @@ -911,8 +871,7 @@ /* * ulog entry - kdb_princ_name */ - if (upd->kdb_princ_name.utf8str_t_val) - free(upd->kdb_princ_name.utf8str_t_val); + free(upd->kdb_princ_name.utf8str_t_val); /* BEGIN CSTYLED */ @@ -920,24 +879,20 @@ * ulog entry - kdb_kdcs_seen_by */ if (upd->kdb_kdcs_seen_by.kdb_kdcs_seen_by_val) { - for (i = 0; i < upd->kdb_kdcs_seen_by.kdb_kdcs_seen_by_len; i++) { - if (upd->kdb_kdcs_seen_by.kdb_kdcs_seen_by_val[i].utf8str_t_val) - free(upd->kdb_kdcs_seen_by.kdb_kdcs_seen_by_val[i].utf8str_t_val); - } - if (upd->kdb_kdcs_seen_by.kdb_kdcs_seen_by_val) - free(upd->kdb_kdcs_seen_by.kdb_kdcs_seen_by_val); + for (i = 0; i < upd->kdb_kdcs_seen_by.kdb_kdcs_seen_by_len; i++) + free(upd->kdb_kdcs_seen_by.kdb_kdcs_seen_by_val[i].utf8str_t_val); + free(upd->kdb_kdcs_seen_by.kdb_kdcs_seen_by_val); } /* * ulog entry - kdb_futures */ - if (upd->kdb_futures.kdb_futures_val) - free(upd->kdb_futures.kdb_futures_val); + free(upd->kdb_futures.kdb_futures_val); /* * ulog entry - kdb_update */ - if(upd->kdb_update.kdbe_t_val) { + if (upd->kdb_update.kdbe_t_val) { /* * Loop thru all the attributes and free up stuff */ @@ -949,12 +904,10 @@ if ((ULOG_ENTRY_TYPE(upd, i).av_type == AT_KEYDATA) && ULOG_ENTRY(upd, i).av_keydata.av_keydata_val) { for (j = 0; j < ULOG_ENTRY(upd, i).av_keydata.av_keydata_len; j++) { - if (ULOG_ENTRY_KEYVAL(upd, i, j).k_enctype.k_enctype_val) - free(ULOG_ENTRY_KEYVAL(upd, i, j).k_enctype.k_enctype_val); + free(ULOG_ENTRY_KEYVAL(upd, i, j).k_enctype.k_enctype_val); if (ULOG_ENTRY_KEYVAL(upd, i, j).k_contents.k_contents_val) { for (k = 0; k < ULOG_ENTRY_KEYVAL(upd, i, j).k_ver; k++) { - if (ULOG_ENTRY_KEYVAL(upd, i, j).k_contents.k_contents_val[k].utf8str_t_val) - free(ULOG_ENTRY_KEYVAL(upd, i, j).k_contents.k_contents_val[k].utf8str_t_val); + free(ULOG_ENTRY_KEYVAL(upd, i, j).k_contents.k_contents_val[k].utf8str_t_val); } free(ULOG_ENTRY_KEYVAL(upd, i, j).k_contents.k_contents_val); } @@ -968,8 +921,7 @@ */ if ((ULOG_ENTRY_TYPE(upd, i).av_type == AT_TL_DATA) && ULOG_ENTRY(upd, i).av_tldata.av_tldata_val) { for (j = 0; j < ULOG_ENTRY(upd, i).av_tldata.av_tldata_len; j++) { - if (ULOG_ENTRY(upd, i).av_tldata.av_tldata_val[j].tl_data.tl_data_val) - free(ULOG_ENTRY(upd, i).av_tldata.av_tldata_val[j].tl_data.tl_data_val); + free(ULOG_ENTRY(upd, i).av_tldata.av_tldata_val[j].tl_data.tl_data_val); } free(ULOG_ENTRY(upd, i).av_tldata.av_tldata_val); } @@ -978,12 +930,10 @@ * Free av_princ */ if (ULOG_ENTRY_TYPE(upd, i).av_type == AT_PRINC) { - if (ULOG_ENTRY(upd, i).av_princ.k_realm.utf8str_t_val) - free(ULOG_ENTRY(upd, i).av_princ.k_realm.utf8str_t_val); + free(ULOG_ENTRY(upd, i).av_princ.k_realm.utf8str_t_val); if (ULOG_ENTRY(upd, i).av_princ.k_components.k_components_val) { for (j = 0; j < ULOG_ENTRY(upd, i).av_princ.k_components.k_components_len; j++) { - if (ULOG_ENTRY_PRINC(upd, i, j).k_data.utf8str_t_val) - free(ULOG_ENTRY_PRINC(upd, i, j).k_data.utf8str_t_val); + free(ULOG_ENTRY_PRINC(upd, i, j).k_data.utf8str_t_val); } free(ULOG_ENTRY(upd, i).av_princ.k_components.k_components_val); } @@ -993,12 +943,10 @@ * Free av_mod_princ */ if (ULOG_ENTRY_TYPE(upd, i).av_type == AT_MOD_PRINC) { - if (ULOG_ENTRY(upd, i).av_mod_princ.k_realm.utf8str_t_val) - free(ULOG_ENTRY(upd, i).av_mod_princ.k_realm.utf8str_t_val); + free(ULOG_ENTRY(upd, i).av_mod_princ.k_realm.utf8str_t_val); if (ULOG_ENTRY(upd, i).av_mod_princ.k_components.k_components_val) { for (j = 0; j < ULOG_ENTRY(upd, i).av_mod_princ.k_components.k_components_len; j++) { - if (ULOG_ENTRY_MOD_PRINC(upd, i, j).k_data.utf8str_t_val) - free(ULOG_ENTRY_MOD_PRINC(upd, i, j).k_data.utf8str_t_val); + free(ULOG_ENTRY_MOD_PRINC(upd, i, j).k_data.utf8str_t_val); } free(ULOG_ENTRY(upd, i).av_mod_princ.k_components.k_components_val); } @@ -1020,7 +968,7 @@ * XXX: Free av_pw_hist * * For now, we just free the pointer - * to av_pw_hist_val, since we arent + * to av_pw_hist_val, since we aren't * populating this union member in * the conv api function(s) anyways. */ @@ -1032,8 +980,7 @@ /* * Free up the pointer to kdbe_t_val */ - if (upd->kdb_update.kdbe_t_val) - free(upd->kdb_update.kdbe_t_val); + free(upd->kdb_update.kdbe_t_val); } /* END CSTYLED */ @@ -1048,6 +995,5 @@ /* * Finally, free up the pointer to the bunched ulog entries */ - if (updates) - free(updates); + free(updates); }