Path: blob/main/crypto/krb5/src/lib/kdb/kdb_convert.c
39566 views
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */1/*2* Copyright 2005 Sun Microsystems, Inc. All rights reserved.3* Use is subject to license terms.4*/56/* #pragma ident "@(#)kdb_convert.c 1.3 05/01/05 SMI" */78/*9* This file contains api's for conversion of the kdb_incr_update_t10* struct(s) into krb5_db_entry struct(s) and vice-versa.11*/12#include <k5-int.h>13#include <sys/types.h>14#include <com_err.h>15#include <locale.h>16#include <iprop_hdr.h>17#include "iprop.h"18#include <kdb.h>19#include <kdb_log.h>2021/* BEGIN CSTYLED */22#define ULOG_ENTRY_TYPE(upd, i) ((kdb_incr_update_t *)upd)->kdb_update.kdbe_t_val[i]2324#define ULOG_ENTRY(upd, i) ((kdb_incr_update_t *)upd)->kdb_update.kdbe_t_val[i].kdbe_val_t_u2526#define ULOG_ENTRY_KEYVAL(upd, i, j) ((kdb_incr_update_t *)upd)->kdb_update.kdbe_t_val[i].kdbe_val_t_u.av_keydata.av_keydata_val[j]2728#define ULOG_ENTRY_PRINC(upd, i, j) ((kdb_incr_update_t *)upd)->kdb_update.kdbe_t_val[i].kdbe_val_t_u.av_princ.k_components.k_components_val[j]2930#define ULOG_ENTRY_MOD_PRINC(upd, i, j) ((kdb_incr_update_t *)upd)->kdb_update.kdbe_t_val[i].kdbe_val_t_u.av_mod_princ.k_components.k_components_val[j]31/* END CSTYLED */3233typedef enum {34REG_PRINC = 0,35MOD_PRINC = 136} princ_type;373839/*40* This routine tracks the krb5_db_entry fields that have been modified41* (by comparing it to the db_entry currently present in principal.db)42* in the update.43*/44static void45find_changed_attrs(krb5_db_entry *current, krb5_db_entry *new,46krb5_boolean exclude_nra,47kdbe_attr_type_t *attrs, int *nattrs)48{49int i = 0, j = 0;5051krb5_tl_data *first, *second;5253if (current->attributes != new->attributes)54attrs[i++] = AT_ATTRFLAGS;5556if (current->max_life != new->max_life)57attrs[i++] = AT_MAX_LIFE;5859if (current->max_renewable_life != new->max_renewable_life)60attrs[i++] = AT_MAX_RENEW_LIFE;6162if (current->expiration != new->expiration)63attrs[i++] = AT_EXP;6465if (current->pw_expiration != new->pw_expiration)66attrs[i++] = AT_PW_EXP;6768if (!exclude_nra) {69if (current->last_success != new->last_success)70attrs[i++] = AT_LAST_SUCCESS;7172if (current->last_failed != new->last_failed)73attrs[i++] = AT_LAST_FAILED;7475if (current->fail_auth_count != new->fail_auth_count)76attrs[i++] = AT_FAIL_AUTH_COUNT;77}7879if ((current->princ->type == new->princ->type) &&80(current->princ->length == new->princ->length)) {81if ((current->princ->realm.length ==82new->princ->realm.length) &&83strncmp(current->princ->realm.data,84new->princ->realm.data,85current->princ->realm.length)) {86for (j = 0; j < current->princ->length; j++) {87if ((current->princ->data[j].data != NULL) &&88(strncmp(current->princ->data[j].data,89new->princ->data[j].data,90current->princ->data[j].length))) {91attrs[i++] = AT_PRINC;92break;93}94}95} else {96attrs[i++] = AT_PRINC;97}98} else {99attrs[i++] = AT_PRINC;100}101102if (current->n_key_data == new->n_key_data) {103/* Assuming key ordering is the same in new & current */104for (j = 0; j < new->n_key_data; j++) {105if (current->key_data[j].key_data_kvno !=106new->key_data[j].key_data_kvno) {107attrs[i++] = AT_KEYDATA;108break;109}110}111} else {112attrs[i++] = AT_KEYDATA;113}114115if (current->n_tl_data == new->n_tl_data) {116/* Assuming we preserve the TL_DATA ordering between updates */117for (first = current->tl_data, second = new->tl_data;118first; first = first->tl_data_next,119second = second->tl_data_next) {120if ((first->tl_data_length == second->tl_data_length) &&121(first->tl_data_type == second->tl_data_type)) {122if ((memcmp((char *)first->tl_data_contents,123(char *)second->tl_data_contents,124first->tl_data_length)) != 0) {125attrs[i++] = AT_TL_DATA;126break;127}128} else {129attrs[i++] = AT_TL_DATA;130break;131}132}133} else {134attrs[i++] = AT_TL_DATA;135}136137if (current->len != new->len)138attrs[i++] = AT_LEN;139/*140* Store the no. of (possibly :)) changed attributes141*/142*nattrs = i;143}144145146/* Initialize *u with a copy of d. Return 0 on success, -1 on failure. */147static int148data_to_utf8str(utf8str_t *u, krb5_data d)149{150u->utf8str_t_len = d.length;151if (d.data) {152u->utf8str_t_val = malloc(d.length);153if (u->utf8str_t_val == NULL)154return -1;155memcpy(u->utf8str_t_val, d.data, d.length);156} else157u->utf8str_t_val = NULL;158return 0;159}160161/*162* Converts the krb5_principal struct from db2 to ulog format.163*/164static krb5_error_code165conv_princ_2ulog(krb5_principal princ, kdb_incr_update_t *upd,166int cnt, princ_type tp)167{168int i = 0;169kdbe_princ_t *p;170kdbe_data_t *components;171172if ((upd == NULL) || !princ)173return (KRB5KRB_ERR_GENERIC);174175switch (tp) {176case REG_PRINC:177case MOD_PRINC:178p = &ULOG_ENTRY(upd, cnt).av_princ; /* or av_mod_princ */179p->k_nametype = (int32_t)princ->type;180181if (data_to_utf8str(&p->k_realm, princ->realm) < 0) {182return ENOMEM;183}184185p->k_components.k_components_len = princ->length;186187p->k_components.k_components_val = components188= malloc(princ->length * sizeof (kdbe_data_t));189if (p->k_components.k_components_val == NULL) {190free(p->k_realm.utf8str_t_val);191p->k_realm.utf8str_t_val = NULL;192return (ENOMEM);193}194195memset(components, 0, princ->length * sizeof(kdbe_data_t));196for (i = 0; i < princ->length; i++)197components[i].k_data.utf8str_t_val = NULL;198for (i = 0; i < princ->length; i++) {199components[i].k_magic = princ->data[i].magic;200if (data_to_utf8str(&components[i].k_data, princ->data[i]) < 0) {201int j;202for (j = 0; j < i; j++) {203free(components[j].k_data.utf8str_t_val);204components[j].k_data.utf8str_t_val = NULL;205}206free(components);207p->k_components.k_components_val = NULL;208free(p->k_realm.utf8str_t_val);209p->k_realm.utf8str_t_val = NULL;210return ENOMEM;211}212}213break;214215default:216break;217}218return (0);219}220221/*222* Copies a UTF-8 string from ulog to a krb5_data object, which may223* already have allocated storage associated with it.224*225* Maybe a return value should indicate success/failure?226*/227static void228set_from_utf8str(krb5_data *d, utf8str_t u)229{230if (u.utf8str_t_len > INT_MAX - 1) {231d->data = NULL;232return;233}234d->length = u.utf8str_t_len;235d->data = malloc(d->length + 1);236if (d->data == NULL)237return;238if (d->length) /* Pointer may be null if length = 0. */239strncpy(d->data, u.utf8str_t_val, d->length);240d->data[d->length] = 0;241}242243/*244* Converts the krb5_principal struct from ulog to db2 format.245*/246static krb5_principal247conv_princ_2db(krb5_context context, kdbe_princ_t *kdbe_princ)248{249unsigned int i;250int j;251krb5_principal princ;252kdbe_data_t *components;253254princ = calloc(1, sizeof (krb5_principal_data));255if (princ == NULL) {256return NULL;257}258princ->length = 0;259princ->data = NULL;260261components = kdbe_princ->k_components.k_components_val;262263princ->type = (krb5_int32) kdbe_princ->k_nametype;264princ->realm.data = NULL;265set_from_utf8str(&princ->realm, kdbe_princ->k_realm);266if (princ->realm.data == NULL)267goto error;268269princ->data = calloc(kdbe_princ->k_components.k_components_len,270sizeof (krb5_data));271if (princ->data == NULL)272goto error;273for (i = 0; i < kdbe_princ->k_components.k_components_len; i++)274princ->data[i].data = NULL;275princ->length = (krb5_int32)kdbe_princ->k_components.k_components_len;276277for (j = 0; j < princ->length; j++) {278princ->data[j].magic = components[j].k_magic;279set_from_utf8str(&princ->data[j], components[j].k_data);280if (princ->data[j].data == NULL)281goto error;282}283284return princ;285error:286krb5_free_principal(context, princ);287return NULL;288}289290291/*292* This routine converts a krb5 DB record into update log (ulog) entry format.293* Space for the update log entry should be allocated prior to invocation of294* this routine.295*/296krb5_error_code297ulog_conv_2logentry(krb5_context context, krb5_db_entry *entry,298kdb_incr_update_t *update)299{300int i, j, cnt, final, nattrs, tmpint;301krb5_principal tmpprinc;302krb5_tl_data *newtl;303krb5_db_entry *curr;304krb5_error_code ret;305kdbe_attr_type_t *attr_types;306int kadm_data_yes;307308nattrs = tmpint = 0;309final = -1;310kadm_data_yes = 0;311attr_types = NULL;312313/*314* XXX we rely on the good behaviour of the database not to315* exceed this limit.316*/317if ((update->kdb_update.kdbe_t_val = (kdbe_val_t *)318malloc(MAXENTRY_SIZE)) == NULL) {319return (ENOMEM);320}321322/*323* Find out which attrs have been modified324*/325if ((attr_types = (kdbe_attr_type_t *)malloc(326sizeof (kdbe_attr_type_t) * MAXATTRS_SIZE))327== NULL) {328return (ENOMEM);329}330331ret = krb5_db_get_principal(context, entry->princ, 0, &curr);332if (ret && ret != KRB5_KDB_NOENTRY) {333free(attr_types);334return (ret);335}336337if (ret == KRB5_KDB_NOENTRY) {338/*339* This is a new entry to the database, hence will340* include all the attribute-value pairs341*342* We leave out the TL_DATA types which we model as343* attrs in kdbe_attr_type_t, since listing AT_TL_DATA344* encompasses these other types-turned-attributes345*346* So, we do *NOT* consider AT_MOD_PRINC, AT_MOD_TIME,347* AT_MOD_WHERE, AT_PW_LAST_CHANGE, AT_PW_POLICY,348* AT_PW_POLICY_SWITCH, AT_PW_HIST_KVNO and AT_PW_HIST,349* totalling 8 attrs.350*/351while (nattrs < MAXATTRS_SIZE - 8) {352attr_types[nattrs] = nattrs;353nattrs++;354}355} else {356/* Always exclude non-replicated attributes for now. */357find_changed_attrs(curr, entry, TRUE, attr_types, &nattrs);358krb5_db_free_principal(context, curr);359}360361for (i = 0; i < nattrs; i++) {362switch (attr_types[i]) {363case AT_ATTRFLAGS:364if (entry->attributes >= 0) {365ULOG_ENTRY_TYPE(update, ++final).av_type =366AT_ATTRFLAGS;367ULOG_ENTRY(update, final).av_attrflags =368(uint32_t)entry->attributes;369}370break;371372case AT_MAX_LIFE:373if (entry->max_life >= 0) {374ULOG_ENTRY_TYPE(update, ++final).av_type = AT_MAX_LIFE;375ULOG_ENTRY(update, final).av_max_life =376(uint32_t)entry->max_life;377}378break;379380case AT_MAX_RENEW_LIFE:381if (entry->max_renewable_life >= 0) {382ULOG_ENTRY_TYPE(update, ++final).av_type = AT_MAX_RENEW_LIFE;383ULOG_ENTRY(update, final).av_max_renew_life =384(uint32_t)entry->max_renewable_life;385}386break;387388case AT_EXP:389if (entry->expiration >= 0) {390ULOG_ENTRY_TYPE(update, ++final).av_type = AT_EXP;391ULOG_ENTRY(update, final).av_exp = (uint32_t)entry->expiration;392}393break;394395case AT_PW_EXP:396if (entry->pw_expiration >= 0) {397ULOG_ENTRY_TYPE(update, ++final).av_type = AT_PW_EXP;398ULOG_ENTRY(update, final).av_pw_exp =399(uint32_t)entry->pw_expiration;400}401break;402403case AT_PRINC:404if (entry->princ->length > 0) {405ULOG_ENTRY_TYPE(update, ++final).av_type = AT_PRINC;406if ((ret = conv_princ_2ulog(entry->princ,407update, final, REG_PRINC))) {408free(attr_types);409return (ret);410}411}412break;413414case AT_KEYDATA:415/* BEGIN CSTYLED */416if (entry->n_key_data >= 0) {417ULOG_ENTRY_TYPE(update, ++final).av_type = AT_KEYDATA;418ULOG_ENTRY(update, final).av_keydata.av_keydata_len =419entry->n_key_data;420ULOG_ENTRY(update, final).av_keydata.av_keydata_val =421malloc(entry->n_key_data * sizeof (kdbe_key_t));422if (ULOG_ENTRY(update, final).av_keydata.av_keydata_val ==423NULL) {424free(attr_types);425return (ENOMEM);426}427428for (j = 0; j < entry->n_key_data; j++) {429ULOG_ENTRY_KEYVAL(update, final, j).k_ver =430entry->key_data[j].key_data_ver;431ULOG_ENTRY_KEYVAL(update, final, j).k_kvno =432entry->key_data[j].key_data_kvno;433ULOG_ENTRY_KEYVAL(update, final, j).k_enctype.k_enctype_len = entry->key_data[j].key_data_ver;434ULOG_ENTRY_KEYVAL(update, final, j).k_contents.k_contents_len = entry->key_data[j].key_data_ver;435436ULOG_ENTRY_KEYVAL(update, final, j).k_enctype.k_enctype_val = malloc(entry->key_data[j].key_data_ver * sizeof(int32_t));437if (ULOG_ENTRY_KEYVAL(update, final, j).k_enctype.k_enctype_val == NULL) {438free(attr_types);439return (ENOMEM);440}441442ULOG_ENTRY_KEYVAL(update, final, j).k_contents.k_contents_val = malloc(entry->key_data[j].key_data_ver * sizeof(utf8str_t));443if (ULOG_ENTRY_KEYVAL(update, final, j).k_contents.k_contents_val == NULL) {444free(attr_types);445return (ENOMEM);446}447448for (cnt = 0; cnt < entry->key_data[j].key_data_ver;449cnt++) {450ULOG_ENTRY_KEYVAL(update, final, j).k_enctype.k_enctype_val[cnt] = entry->key_data[j].key_data_type[cnt];451ULOG_ENTRY_KEYVAL(update, final, j).k_contents.k_contents_val[cnt].utf8str_t_len = entry->key_data[j].key_data_length[cnt];452ULOG_ENTRY_KEYVAL(update, final, j).k_contents.k_contents_val[cnt].utf8str_t_val = malloc(entry->key_data[j].key_data_length[cnt] * sizeof (char));453if (ULOG_ENTRY_KEYVAL(update, final, j).k_contents.k_contents_val[cnt].utf8str_t_val == NULL) {454free(attr_types);455return (ENOMEM);456}457(void) memcpy(ULOG_ENTRY_KEYVAL(update, final, j).k_contents.k_contents_val[cnt].utf8str_t_val, entry->key_data[j].key_data_contents[cnt], entry->key_data[j].key_data_length[cnt]);458}459}460}461break;462463case AT_TL_DATA:464ret = krb5_dbe_lookup_last_pwd_change(context, entry, &tmpint);465if (ret == 0) {466ULOG_ENTRY_TYPE(update, ++final).av_type = AT_PW_LAST_CHANGE;467ULOG_ENTRY(update, final).av_pw_last_change = tmpint;468}469tmpint = 0;470471if(!(ret = krb5_dbe_lookup_mod_princ_data(context, entry, &tmpint,472&tmpprinc))) {473474ULOG_ENTRY_TYPE(update, ++final).av_type = AT_MOD_PRINC;475476ret = conv_princ_2ulog(tmpprinc, update, final, MOD_PRINC);477krb5_free_principal(context, tmpprinc);478if (ret) {479free(attr_types);480return (ret);481}482ULOG_ENTRY_TYPE(update, ++final).av_type = AT_MOD_TIME;483ULOG_ENTRY(update, final).av_mod_time =484tmpint;485}486487newtl = entry->tl_data;488while (newtl) {489switch (newtl->tl_data_type) {490case KRB5_TL_LAST_PWD_CHANGE:491case KRB5_TL_MOD_PRINC:492break;493494case KRB5_TL_KADM_DATA:495default:496if (kadm_data_yes == 0) {497ULOG_ENTRY_TYPE(update, ++final).av_type = AT_TL_DATA;498ULOG_ENTRY(update, final).av_tldata.av_tldata_len = 0;499ULOG_ENTRY(update, final).av_tldata.av_tldata_val =500malloc(entry->n_tl_data * sizeof(kdbe_tl_t));501502if (ULOG_ENTRY(update, final).av_tldata.av_tldata_val503== NULL) {504free(attr_types);505return (ENOMEM);506}507kadm_data_yes = 1;508}509510tmpint = ULOG_ENTRY(update, final).av_tldata.av_tldata_len;511ULOG_ENTRY(update, final).av_tldata.av_tldata_len++;512ULOG_ENTRY(update, final).av_tldata.av_tldata_val[tmpint].tl_type = newtl->tl_data_type;513ULOG_ENTRY(update, final).av_tldata.av_tldata_val[tmpint].tl_data.tl_data_len = newtl->tl_data_length;514ULOG_ENTRY(update, final).av_tldata.av_tldata_val[tmpint].tl_data.tl_data_val = malloc(newtl->tl_data_length * sizeof (char));515if (ULOG_ENTRY(update, final).av_tldata.av_tldata_val[tmpint].tl_data.tl_data_val == NULL) {516free(attr_types);517return (ENOMEM);518}519(void) memcpy(ULOG_ENTRY(update, final).av_tldata.av_tldata_val[tmpint].tl_data.tl_data_val, newtl->tl_data_contents, newtl->tl_data_length);520break;521}522newtl = newtl->tl_data_next;523}524break;525/* END CSTYLED */526527case AT_LEN:528ULOG_ENTRY_TYPE(update, ++final).av_type = AT_LEN;529ULOG_ENTRY(update, final).av_len = (int16_t)entry->len;530break;531532default:533break;534}535536}537538free(attr_types);539540/*541* Update len field in kdb_update542*/543update->kdb_update.kdbe_t_len = ++final;544return (0);545}546547/* Convert an update log (ulog) entry into a kerberos record. */548krb5_error_code549ulog_conv_2dbentry(krb5_context context, krb5_db_entry **entry,550kdb_incr_update_t *update)551{552krb5_db_entry *ent = NULL;553int replica;554krb5_principal mod_princ = NULL;555int i, j, cnt = 0, mod_time = 0, nattrs;556krb5_principal dbprinc;557char *dbprincstr = NULL;558krb5_tl_data newtl;559krb5_error_code ret;560unsigned int prev_n_keys = 0;561krb5_boolean is_add;562void *newptr;563564*entry = NULL;565566replica = (context->kdblog_context != NULL) &&567(context->kdblog_context->iproprole == IPROP_REPLICA);568569/*570* Store the no. of changed attributes in nattrs571*/572nattrs = update->kdb_update.kdbe_t_len;573574dbprincstr = k5memdup0(update->kdb_princ_name.utf8str_t_val,575update->kdb_princ_name.utf8str_t_len, &ret);576if (dbprincstr == NULL)577goto cleanup;578579ret = krb5_parse_name(context, dbprincstr, &dbprinc);580free(dbprincstr);581if (ret)582goto cleanup;583584ret = krb5_db_get_principal(context, dbprinc, 0, &ent);585krb5_free_principal(context, dbprinc);586if (ret && ret != KRB5_KDB_NOENTRY)587goto cleanup;588is_add = (ret == KRB5_KDB_NOENTRY);589590/*591* Set ent->n_tl_data = 0 initially, if this is an ADD update592*/593if (is_add) {594ent = calloc(1, sizeof(*ent));595if (ent == NULL)596return (ENOMEM);597ent->n_tl_data = 0;598}599600for (i = 0; i < nattrs; i++) {601krb5_principal tmpprinc = NULL;602603#define u (ULOG_ENTRY(update, i))604switch (ULOG_ENTRY_TYPE(update, i).av_type) {605case AT_ATTRFLAGS:606ent->attributes = (krb5_flags) u.av_attrflags;607break;608609case AT_MAX_LIFE:610ent->max_life = (krb5_deltat) u.av_max_life;611break;612613case AT_MAX_RENEW_LIFE:614ent->max_renewable_life = (krb5_deltat) u.av_max_renew_life;615break;616617case AT_EXP:618ent->expiration = (krb5_timestamp) u.av_exp;619break;620621case AT_PW_EXP:622ent->pw_expiration = (krb5_timestamp) u.av_pw_exp;623break;624625case AT_LAST_SUCCESS:626if (!replica)627ent->last_success = (krb5_timestamp) u.av_last_success;628break;629630case AT_LAST_FAILED:631if (!replica)632ent->last_failed = (krb5_timestamp) u.av_last_failed;633break;634635case AT_FAIL_AUTH_COUNT:636if (!replica)637ent->fail_auth_count = (krb5_kvno) u.av_fail_auth_count;638break;639640case AT_PRINC:641tmpprinc = conv_princ_2db(context, &u.av_princ);642if (tmpprinc == NULL) {643ret = ENOMEM;644goto cleanup;645}646krb5_free_principal(context, ent->princ);647ent->princ = tmpprinc;648break;649650case AT_KEYDATA:651if (!is_add)652prev_n_keys = ent->n_key_data;653else654prev_n_keys = 0;655ent->n_key_data = (krb5_int16)u.av_keydata.av_keydata_len;656if (is_add)657ent->key_data = NULL;658659/* Allocate one extra key data to avoid allocating zero bytes. */660newptr = realloc(ent->key_data, (ent->n_key_data + 1) *661sizeof(krb5_key_data));662if (newptr == NULL) {663ret = ENOMEM;664goto cleanup;665}666ent->key_data = newptr;667668/* BEGIN CSTYLED */669for (j = prev_n_keys; j < ent->n_key_data; j++) {670for (cnt = 0; cnt < 2; cnt++) {671ent->key_data[j].key_data_contents[cnt] = NULL;672}673}674for (j = 0; j < ent->n_key_data; j++) {675krb5_key_data *kp = &ent->key_data[j];676kdbe_key_t *kv = &ULOG_ENTRY_KEYVAL(update, i, j);677kp->key_data_ver = (krb5_int16)kv->k_ver;678kp->key_data_kvno = (krb5_ui_2)kv->k_kvno;679if (kp->key_data_ver > 2) {680ret = EINVAL; /* XXX ? */681goto cleanup;682}683684for (cnt = 0; cnt < kp->key_data_ver; cnt++) {685kp->key_data_type[cnt] = (krb5_int16)kv->k_enctype.k_enctype_val[cnt];686kp->key_data_length[cnt] = (krb5_int16)kv->k_contents.k_contents_val[cnt].utf8str_t_len;687newptr = realloc(kp->key_data_contents[cnt],688kp->key_data_length[cnt]);689if (newptr == NULL) {690ret = ENOMEM;691goto cleanup;692}693kp->key_data_contents[cnt] = newptr;694695(void) memset(kp->key_data_contents[cnt], 0,696kp->key_data_length[cnt]);697(void) memcpy(kp->key_data_contents[cnt],698kv->k_contents.k_contents_val[cnt].utf8str_t_val,699kp->key_data_length[cnt]);700}701}702break;703704case AT_TL_DATA: {705for (j = 0; j < (int)u.av_tldata.av_tldata_len; j++) {706newtl.tl_data_type = (krb5_int16)u.av_tldata.av_tldata_val[j].tl_type;707newtl.tl_data_length = (krb5_int16)u.av_tldata.av_tldata_val[j].tl_data.tl_data_len;708newtl.tl_data_contents = (krb5_octet *)u.av_tldata.av_tldata_val[j].tl_data.tl_data_val;709newtl.tl_data_next = NULL;710ret = krb5_dbe_update_tl_data(context, ent, &newtl);711if (ret)712goto cleanup;713}714break;715/* END CSTYLED */716}717case AT_PW_LAST_CHANGE:718ret = krb5_dbe_update_last_pwd_change(context, ent,719u.av_pw_last_change);720if (ret)721goto cleanup;722break;723724case AT_MOD_PRINC:725tmpprinc = conv_princ_2db(context, &u.av_mod_princ);726if (tmpprinc == NULL) {727ret = ENOMEM;728goto cleanup;729}730mod_princ = tmpprinc;731break;732733case AT_MOD_TIME:734mod_time = u.av_mod_time;735break;736737case AT_LEN:738ent->len = (krb5_int16) u.av_len;739break;740741default:742break;743}744#undef u745}746747/*748* process mod_princ_data request749*/750if (mod_time && mod_princ) {751ret = krb5_dbe_update_mod_princ_data(context, ent,752mod_time, mod_princ);753if (ret)754goto cleanup;755}756757*entry = ent;758ent = NULL;759ret = 0;760cleanup:761krb5_db_free_principal(context, ent);762krb5_free_principal(context, mod_princ);763return ret;764}765766767768/*769* This routine frees up memory associated with the bunched ulog entries.770*/771void772ulog_free_entries(kdb_incr_update_t *updates, int no_of_updates)773{774775kdb_incr_update_t *upd;776unsigned int i, j;777int k, cnt;778779if (updates == NULL)780return;781782upd = updates;783784/*785* Loop thru each ulog entry786*/787for (cnt = 0; cnt < no_of_updates; cnt++) {788789/*790* ulog entry - kdb_princ_name791*/792free(upd->kdb_princ_name.utf8str_t_val);793794/* BEGIN CSTYLED */795796/*797* ulog entry - kdb_kdcs_seen_by798*/799if (upd->kdb_kdcs_seen_by.kdb_kdcs_seen_by_val) {800for (i = 0; i < upd->kdb_kdcs_seen_by.kdb_kdcs_seen_by_len; i++)801free(upd->kdb_kdcs_seen_by.kdb_kdcs_seen_by_val[i].utf8str_t_val);802free(upd->kdb_kdcs_seen_by.kdb_kdcs_seen_by_val);803}804805/*806* ulog entry - kdb_futures807*/808free(upd->kdb_futures.kdb_futures_val);809810/*811* ulog entry - kdb_update812*/813if (upd->kdb_update.kdbe_t_val) {814/*815* Loop thru all the attributes and free up stuff816*/817for (i = 0; i < upd->kdb_update.kdbe_t_len; i++) {818819/*820* Free av_key_data821*/822if ((ULOG_ENTRY_TYPE(upd, i).av_type == AT_KEYDATA) && ULOG_ENTRY(upd, i).av_keydata.av_keydata_val) {823824for (j = 0; j < ULOG_ENTRY(upd, i).av_keydata.av_keydata_len; j++) {825free(ULOG_ENTRY_KEYVAL(upd, i, j).k_enctype.k_enctype_val);826if (ULOG_ENTRY_KEYVAL(upd, i, j).k_contents.k_contents_val) {827for (k = 0; k < ULOG_ENTRY_KEYVAL(upd, i, j).k_ver; k++) {828free(ULOG_ENTRY_KEYVAL(upd, i, j).k_contents.k_contents_val[k].utf8str_t_val);829}830free(ULOG_ENTRY_KEYVAL(upd, i, j).k_contents.k_contents_val);831}832}833free(ULOG_ENTRY(upd, i).av_keydata.av_keydata_val);834}835836837/*838* Free av_tl_data839*/840if ((ULOG_ENTRY_TYPE(upd, i).av_type == AT_TL_DATA) && ULOG_ENTRY(upd, i).av_tldata.av_tldata_val) {841for (j = 0; j < ULOG_ENTRY(upd, i).av_tldata.av_tldata_len; j++) {842free(ULOG_ENTRY(upd, i).av_tldata.av_tldata_val[j].tl_data.tl_data_val);843}844free(ULOG_ENTRY(upd, i).av_tldata.av_tldata_val);845}846847/*848* Free av_princ849*/850if (ULOG_ENTRY_TYPE(upd, i).av_type == AT_PRINC) {851free(ULOG_ENTRY(upd, i).av_princ.k_realm.utf8str_t_val);852if (ULOG_ENTRY(upd, i).av_princ.k_components.k_components_val) {853for (j = 0; j < ULOG_ENTRY(upd, i).av_princ.k_components.k_components_len; j++) {854free(ULOG_ENTRY_PRINC(upd, i, j).k_data.utf8str_t_val);855}856free(ULOG_ENTRY(upd, i).av_princ.k_components.k_components_val);857}858}859860/*861* Free av_mod_princ862*/863if (ULOG_ENTRY_TYPE(upd, i).av_type == AT_MOD_PRINC) {864free(ULOG_ENTRY(upd, i).av_mod_princ.k_realm.utf8str_t_val);865if (ULOG_ENTRY(upd, i).av_mod_princ.k_components.k_components_val) {866for (j = 0; j < ULOG_ENTRY(upd, i).av_mod_princ.k_components.k_components_len; j++) {867free(ULOG_ENTRY_MOD_PRINC(upd, i, j).k_data.utf8str_t_val);868}869free(ULOG_ENTRY(upd, i).av_mod_princ.k_components.k_components_val);870}871}872873/*874* Free av_mod_where875*/876if ((ULOG_ENTRY_TYPE(upd, i).av_type == AT_MOD_WHERE) && ULOG_ENTRY(upd, i).av_mod_where.utf8str_t_val)877free(ULOG_ENTRY(upd, i).av_mod_where.utf8str_t_val);878879/*880* Free av_pw_policy881*/882if ((ULOG_ENTRY_TYPE(upd, i).av_type == AT_PW_POLICY) && ULOG_ENTRY(upd, i).av_pw_policy.utf8str_t_val)883free(ULOG_ENTRY(upd, i).av_pw_policy.utf8str_t_val);884885/*886* XXX: Free av_pw_hist887*888* For now, we just free the pointer889* to av_pw_hist_val, since we aren't890* populating this union member in891* the conv api function(s) anyways.892*/893if ((ULOG_ENTRY_TYPE(upd, i).av_type == AT_PW_HIST) && ULOG_ENTRY(upd, i).av_pw_hist.av_pw_hist_val)894free(ULOG_ENTRY(upd, i).av_pw_hist.av_pw_hist_val);895896}897898/*899* Free up the pointer to kdbe_t_val900*/901free(upd->kdb_update.kdbe_t_val);902}903904/* END CSTYLED */905906/*907* Bump up to next struct908*/909upd++;910}911912913/*914* Finally, free up the pointer to the bunched ulog entries915*/916free(updates);917}918919920