xref: /illumos-gate/usr/src/lib/krb5/kdb/kdb_convert.c (revision 75e21072)
17c478bd9Sstevel@tonic-gate /*
2*75e21072SPeter Shoults  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
37c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate  */
57c478bd9Sstevel@tonic-gate 
67c478bd9Sstevel@tonic-gate /*
77c478bd9Sstevel@tonic-gate  * This file contains api's for conversion of the kdb_incr_update_t
87c478bd9Sstevel@tonic-gate  * struct(s) into krb5_db_entry struct(s) and vice-versa.
97c478bd9Sstevel@tonic-gate  */
107c478bd9Sstevel@tonic-gate #include <sys/types.h>
117c478bd9Sstevel@tonic-gate #include <com_err.h>
127c478bd9Sstevel@tonic-gate #include <locale.h>
137c478bd9Sstevel@tonic-gate #include <errno.h>
147c478bd9Sstevel@tonic-gate #include <iprop_hdr.h>
157c478bd9Sstevel@tonic-gate #include "iprop.h"
167c478bd9Sstevel@tonic-gate #include <k5-int.h>
17*75e21072SPeter Shoults #include <kdb.h>
18*75e21072SPeter Shoults #include <kdb_log.h>
197c478bd9Sstevel@tonic-gate 
207c478bd9Sstevel@tonic-gate /* BEGIN CSTYLED */
217c478bd9Sstevel@tonic-gate #define	ULOG_ENTRY_TYPE(upd, i)	((kdb_incr_update_t *)upd)->kdb_update.kdbe_t_val[i]
227c478bd9Sstevel@tonic-gate 
237c478bd9Sstevel@tonic-gate #define	ULOG_ENTRY(upd, i) ((kdb_incr_update_t *)upd)->kdb_update.kdbe_t_val[i].kdbe_val_t_u
247c478bd9Sstevel@tonic-gate 
257c478bd9Sstevel@tonic-gate #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]
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate #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]
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate #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]
307c478bd9Sstevel@tonic-gate /* END CSTYLED */
317c478bd9Sstevel@tonic-gate 
327c478bd9Sstevel@tonic-gate typedef enum {
337c478bd9Sstevel@tonic-gate 	REG_PRINC = 0,
347c478bd9Sstevel@tonic-gate 	MOD_PRINC = 1
357c478bd9Sstevel@tonic-gate } princ_type;
367c478bd9Sstevel@tonic-gate 
377c478bd9Sstevel@tonic-gate 
387c478bd9Sstevel@tonic-gate /*
397c478bd9Sstevel@tonic-gate  * This routine tracks the krb5_db_entry fields that have been modified
407c478bd9Sstevel@tonic-gate  * (by comparing it to the db_entry currently present in principal.db)
417c478bd9Sstevel@tonic-gate  * in the update.
427c478bd9Sstevel@tonic-gate  */
43*75e21072SPeter Shoults static void
find_changed_attrs(krb5_db_entry * current,krb5_db_entry * new,kdbe_attr_type_t * attrs,int * nattrs)447c478bd9Sstevel@tonic-gate find_changed_attrs(krb5_db_entry *current, krb5_db_entry *new,
45*75e21072SPeter Shoults 		   kdbe_attr_type_t *attrs, int *nattrs)
46*75e21072SPeter Shoults {
477c478bd9Sstevel@tonic-gate 	int i = 0, j = 0;
487c478bd9Sstevel@tonic-gate 
497c478bd9Sstevel@tonic-gate 	krb5_tl_data *first, *second;
507c478bd9Sstevel@tonic-gate 
517c478bd9Sstevel@tonic-gate 	if (current->attributes != new->attributes)
527c478bd9Sstevel@tonic-gate 		attrs[i++] = AT_ATTRFLAGS;
537c478bd9Sstevel@tonic-gate 
547c478bd9Sstevel@tonic-gate 	if (current->max_life != new->max_life)
557c478bd9Sstevel@tonic-gate 		attrs[i++] = AT_MAX_LIFE;
567c478bd9Sstevel@tonic-gate 
577c478bd9Sstevel@tonic-gate 	if (current->max_renewable_life != new->max_renewable_life)
587c478bd9Sstevel@tonic-gate 		attrs[i++] = AT_MAX_RENEW_LIFE;
597c478bd9Sstevel@tonic-gate 
607c478bd9Sstevel@tonic-gate 	if (current->expiration != new->expiration)
617c478bd9Sstevel@tonic-gate 		attrs[i++] = AT_EXP;
627c478bd9Sstevel@tonic-gate 
637c478bd9Sstevel@tonic-gate 	if (current->pw_expiration != new->pw_expiration)
647c478bd9Sstevel@tonic-gate 		attrs[i++] = AT_PW_EXP;
657c478bd9Sstevel@tonic-gate 
667c478bd9Sstevel@tonic-gate 	if (current->last_success != new->last_success)
677c478bd9Sstevel@tonic-gate 		attrs[i++] = AT_LAST_SUCCESS;
687c478bd9Sstevel@tonic-gate 
697c478bd9Sstevel@tonic-gate 	if (current->last_failed != new->last_failed)
707c478bd9Sstevel@tonic-gate 		attrs[i++] = AT_LAST_FAILED;
717c478bd9Sstevel@tonic-gate 
727c478bd9Sstevel@tonic-gate 	if (current->fail_auth_count != new->fail_auth_count)
737c478bd9Sstevel@tonic-gate 		attrs[i++] = AT_FAIL_AUTH_COUNT;
747c478bd9Sstevel@tonic-gate 
757c478bd9Sstevel@tonic-gate 	if ((current->princ->type == new->princ->type) &&
767c478bd9Sstevel@tonic-gate 	    (current->princ->length == new->princ->length)) {
777c478bd9Sstevel@tonic-gate 		if ((current->princ->realm.length ==
787c478bd9Sstevel@tonic-gate 			new->princ->realm.length) &&
797c478bd9Sstevel@tonic-gate 				strncmp(current->princ->realm.data,
807c478bd9Sstevel@tonic-gate 					new->princ->realm.data,
817c478bd9Sstevel@tonic-gate 					current->princ->realm.length)) {
827c478bd9Sstevel@tonic-gate 			for (j = 0; j < current->princ->length; j++) {
837c478bd9Sstevel@tonic-gate 				if ((current->princ->data[j].data != NULL) &&
847c478bd9Sstevel@tonic-gate 					(strncmp(current->princ->data[j].data,
857c478bd9Sstevel@tonic-gate 					    new->princ->data[j].data,
867c478bd9Sstevel@tonic-gate 					    current->princ->data[j].length))) {
877c478bd9Sstevel@tonic-gate 					attrs[i++] = AT_PRINC;
887c478bd9Sstevel@tonic-gate 					break;
897c478bd9Sstevel@tonic-gate 				}
907c478bd9Sstevel@tonic-gate 			}
917c478bd9Sstevel@tonic-gate 		} else {
927c478bd9Sstevel@tonic-gate 			attrs[i++] = AT_PRINC;
937c478bd9Sstevel@tonic-gate 		}
947c478bd9Sstevel@tonic-gate 	} else {
957c478bd9Sstevel@tonic-gate 		attrs[i++] = AT_PRINC;
967c478bd9Sstevel@tonic-gate 	}
977c478bd9Sstevel@tonic-gate 
987c478bd9Sstevel@tonic-gate 	if (current->n_key_data == new->n_key_data) {
997c478bd9Sstevel@tonic-gate 		/* Assuming key ordering is the same in new & current */
1007c478bd9Sstevel@tonic-gate 		for (j = 0; j < new->n_key_data; j++) {
1017c478bd9Sstevel@tonic-gate 			if (current->key_data[j].key_data_kvno !=
1027c478bd9Sstevel@tonic-gate 			    new->key_data[j].key_data_kvno) {
1037c478bd9Sstevel@tonic-gate 				attrs[i++] = AT_KEYDATA;
1047c478bd9Sstevel@tonic-gate 				break;
1057c478bd9Sstevel@tonic-gate 			}
1067c478bd9Sstevel@tonic-gate 		}
1077c478bd9Sstevel@tonic-gate 	} else {
1087c478bd9Sstevel@tonic-gate 		attrs[i++] = AT_KEYDATA;
1097c478bd9Sstevel@tonic-gate 	}
1107c478bd9Sstevel@tonic-gate 
1117c478bd9Sstevel@tonic-gate 	if (current->n_tl_data == new->n_tl_data) {
1127c478bd9Sstevel@tonic-gate 		/* Assuming we preserve the TL_DATA ordering between updates */
1137c478bd9Sstevel@tonic-gate 		for (first = current->tl_data, second = new->tl_data;
1147c478bd9Sstevel@tonic-gate 				first; first = first->tl_data_next,
1157c478bd9Sstevel@tonic-gate 					second = second->tl_data_next) {
1167c478bd9Sstevel@tonic-gate 			if ((first->tl_data_length == second->tl_data_length) &&
1177c478bd9Sstevel@tonic-gate 				(first->tl_data_type == second->tl_data_type)) {
1187c478bd9Sstevel@tonic-gate 				if ((memcmp((char *)first->tl_data_contents,
1197c478bd9Sstevel@tonic-gate 					(char *)second->tl_data_contents,
1207c478bd9Sstevel@tonic-gate 					first->tl_data_length)) != 0) {
1217c478bd9Sstevel@tonic-gate 					attrs[i++] = AT_TL_DATA;
1227c478bd9Sstevel@tonic-gate 					break;
1237c478bd9Sstevel@tonic-gate 				}
1247c478bd9Sstevel@tonic-gate 			} else {
1257c478bd9Sstevel@tonic-gate 				attrs[i++] = AT_TL_DATA;
1267c478bd9Sstevel@tonic-gate 				break;
1277c478bd9Sstevel@tonic-gate 			}
1287c478bd9Sstevel@tonic-gate 		}
1297c478bd9Sstevel@tonic-gate 
1307c478bd9Sstevel@tonic-gate 	} else {
1317c478bd9Sstevel@tonic-gate 		attrs[i++] = AT_TL_DATA;
1327c478bd9Sstevel@tonic-gate 	}
1337c478bd9Sstevel@tonic-gate 
1347c478bd9Sstevel@tonic-gate 	if (current->len != new->len)
1357c478bd9Sstevel@tonic-gate 		attrs[i++] = AT_LEN;
1367c478bd9Sstevel@tonic-gate 	/*
1377c478bd9Sstevel@tonic-gate 	 * Store the no. of (possibly :)) changed attributes
1387c478bd9Sstevel@tonic-gate 	 */
1397c478bd9Sstevel@tonic-gate 	*nattrs = i;
1407c478bd9Sstevel@tonic-gate }
1417c478bd9Sstevel@tonic-gate 
142*75e21072SPeter Shoults static int
data_to_utf8str(utf8str_t * u,krb5_data d)143*75e21072SPeter Shoults data_to_utf8str(utf8str_t *u, krb5_data d)
144*75e21072SPeter Shoults {
145*75e21072SPeter Shoults 	u->utf8str_t_len = d.length;
146*75e21072SPeter Shoults 	if (d.data) {
147*75e21072SPeter Shoults 		u->utf8str_t_val = malloc(d.length);
148*75e21072SPeter Shoults 		if (u->utf8str_t_val == NULL)
149*75e21072SPeter Shoults 			return -1;
150*75e21072SPeter Shoults 		memcpy(u->utf8str_t_val, d.data, d.length);
151*75e21072SPeter Shoults 	} else
152*75e21072SPeter Shoults 		u->utf8str_t_val = NULL;
153*75e21072SPeter Shoults 	return 0;
154*75e21072SPeter Shoults }
1557c478bd9Sstevel@tonic-gate 
1567c478bd9Sstevel@tonic-gate /*
1577c478bd9Sstevel@tonic-gate  * Converts the krb5_principal struct from db2 to ulog format.
1587c478bd9Sstevel@tonic-gate  */
159*75e21072SPeter Shoults static krb5_error_code
conv_princ_2ulog(krb5_principal princ,kdb_incr_update_t * upd,int cnt,princ_type tp)1607c478bd9Sstevel@tonic-gate conv_princ_2ulog(krb5_principal princ, kdb_incr_update_t *upd,
161*75e21072SPeter Shoults 		 int cnt, princ_type tp) {
1627c478bd9Sstevel@tonic-gate 	int i = 0;
163*75e21072SPeter Shoults 	kdbe_princ_t *p;
164*75e21072SPeter Shoults 	kdbe_data_t *components;
1657c478bd9Sstevel@tonic-gate 
1667c478bd9Sstevel@tonic-gate 	if ((upd == NULL) || !princ)
1677c478bd9Sstevel@tonic-gate 		return (KRB5KRB_ERR_GENERIC);
1687c478bd9Sstevel@tonic-gate 
1697c478bd9Sstevel@tonic-gate 	switch (tp) {
1707c478bd9Sstevel@tonic-gate 	case REG_PRINC:
1717c478bd9Sstevel@tonic-gate 	case MOD_PRINC:
172*75e21072SPeter Shoults 		p = &ULOG_ENTRY(upd, cnt).av_princ; /* or av_mod_princ */
173*75e21072SPeter Shoults 		p->k_nametype = (int32_t)princ->type;
1747c478bd9Sstevel@tonic-gate 
175*75e21072SPeter Shoults 		if (data_to_utf8str(&p->k_realm, princ->realm) < 0) {
176*75e21072SPeter Shoults 			return ENOMEM;
177*75e21072SPeter Shoults 		}
1787c478bd9Sstevel@tonic-gate 
179*75e21072SPeter Shoults 		p->k_components.k_components_len = princ->length;
1807c478bd9Sstevel@tonic-gate 
181*75e21072SPeter Shoults 		p->k_components.k_components_val = components
182*75e21072SPeter Shoults 		    = malloc(princ->length * sizeof (kdbe_data_t));
183*75e21072SPeter Shoults 		if (p->k_components.k_components_val == NULL) {
184*75e21072SPeter Shoults 			free(p->k_realm.utf8str_t_val);
185*75e21072SPeter Shoults 			p->k_realm.utf8str_t_val = NULL;
1867c478bd9Sstevel@tonic-gate 			return (ENOMEM);
187*75e21072SPeter Shoults 		}
1887c478bd9Sstevel@tonic-gate 
189*75e21072SPeter Shoults 		memset(components, 0, princ->length * sizeof(kdbe_data_t));
190*75e21072SPeter Shoults 		for (i = 0; i < princ->length; i++)
191*75e21072SPeter Shoults 			components[i].k_data.utf8str_t_val = NULL;
1927c478bd9Sstevel@tonic-gate 		for (i = 0; i < princ->length; i++) {
193*75e21072SPeter Shoults 			components[i].k_magic = princ->data[i].magic;
194*75e21072SPeter Shoults 			if (data_to_utf8str(&components[i].k_data,
195*75e21072SPeter Shoults 			    princ->data[i]) < 0) {
196*75e21072SPeter Shoults 				int j;
197*75e21072SPeter Shoults 				for (j = 0; j < i; j++) {
198*75e21072SPeter Shoults 					free(components[j].k_data.utf8str_t_val);
199*75e21072SPeter Shoults 					components[j].k_data.utf8str_t_val = NULL;
200*75e21072SPeter Shoults 				}
201*75e21072SPeter Shoults 			free(components);
202*75e21072SPeter Shoults 			p->k_components.k_components_val = NULL;
203*75e21072SPeter Shoults 			free(p->k_realm.utf8str_t_val);
204*75e21072SPeter Shoults 			p->k_realm.utf8str_t_val = NULL;
205*75e21072SPeter Shoults 			return ENOMEM;
206*75e21072SPeter Shoults 			}
2077c478bd9Sstevel@tonic-gate 		}
2087c478bd9Sstevel@tonic-gate 		break;
2097c478bd9Sstevel@tonic-gate 
2107c478bd9Sstevel@tonic-gate 	default:
2117c478bd9Sstevel@tonic-gate 		break;
2127c478bd9Sstevel@tonic-gate 	}
2137c478bd9Sstevel@tonic-gate 	return (0);
2147c478bd9Sstevel@tonic-gate }
2157c478bd9Sstevel@tonic-gate 
2167c478bd9Sstevel@tonic-gate /*
217*75e21072SPeter Shoults  * Copies a UTF-8 string from ulog to a krb5_data object, which may
218*75e21072SPeter Shoults  * already have allocated storage associated with it.
219*75e21072SPeter Shoults  *
220*75e21072SPeter Shoults  * Maybe a return value should indicate success/failure?
2217c478bd9Sstevel@tonic-gate  */
222*75e21072SPeter Shoults static void
set_from_utf8str(krb5_data * d,utf8str_t u)223*75e21072SPeter Shoults set_from_utf8str(krb5_data *d, utf8str_t u)
224*75e21072SPeter Shoults {
225*75e21072SPeter Shoults 	if (u.utf8str_t_len > INT_MAX-1 || u.utf8str_t_len >= SIZE_MAX-1) {
226*75e21072SPeter Shoults 		d->data = NULL;
227*75e21072SPeter Shoults 		return;
228*75e21072SPeter Shoults 	}
229*75e21072SPeter Shoults 	d->length = u.utf8str_t_len;
230*75e21072SPeter Shoults 	d->data = malloc(d->length + 1);
231*75e21072SPeter Shoults 	if (d->data == NULL)
232*75e21072SPeter Shoults 		return;
233*75e21072SPeter Shoults 	if (d->length)   /* Pointer may be null if length = 0.  */
234*75e21072SPeter Shoults 		strncpy(d->data, u.utf8str_t_val, d->length);
235*75e21072SPeter Shoults 	d->data[d->length] = 0;
236*75e21072SPeter Shoults }
2377c478bd9Sstevel@tonic-gate 
238*75e21072SPeter Shoults /*
239*75e21072SPeter Shoults  * Converts the krb5_principal struct from ulog to db2 format.
240*75e21072SPeter Shoults  */
241*75e21072SPeter Shoults static krb5_principal
conv_princ_2db(krb5_context context,kdbe_princ_t * kdbe_princ)242*75e21072SPeter Shoults conv_princ_2db(krb5_context context, kdbe_princ_t *kdbe_princ)
243*75e21072SPeter Shoults {
2447c478bd9Sstevel@tonic-gate 	int i;
2457c478bd9Sstevel@tonic-gate 	krb5_principal princ;
246*75e21072SPeter Shoults 	kdbe_data_t *components;
2477c478bd9Sstevel@tonic-gate 
248*75e21072SPeter Shoults 	princ = calloc(1, sizeof (krb5_principal_data));
249*75e21072SPeter Shoults 	if (princ == NULL) {
250*75e21072SPeter Shoults 		return NULL;
2517c478bd9Sstevel@tonic-gate 	}
252*75e21072SPeter Shoults 	princ->length = 0;
253*75e21072SPeter Shoults 	princ->data = NULL;
254*75e21072SPeter Shoults 
255*75e21072SPeter Shoults 	components = kdbe_princ->k_components.k_components_val;
256*75e21072SPeter Shoults 
257*75e21072SPeter Shoults 	princ->type = (krb5_int32) kdbe_princ->k_nametype;
258*75e21072SPeter Shoults 	princ->realm.data = NULL;
259*75e21072SPeter Shoults 	set_from_utf8str(&princ->realm, kdbe_princ->k_realm);
260*75e21072SPeter Shoults 	if (princ->realm.data == NULL)
261*75e21072SPeter Shoults 		goto error;
262*75e21072SPeter Shoults 
263*75e21072SPeter Shoults 	princ->data = calloc(kdbe_princ->k_components.k_components_len,
264*75e21072SPeter Shoults 			     sizeof (krb5_data));
265*75e21072SPeter Shoults 	if (princ->data == NULL)
266*75e21072SPeter Shoults 		goto error;
267*75e21072SPeter Shoults 	for (i = 0; i < kdbe_princ->k_components.k_components_len; i++)
268*75e21072SPeter Shoults 		princ->data[i].data = NULL;
269*75e21072SPeter Shoults 	princ->length = (krb5_int32)kdbe_princ->k_components.k_components_len;
270*75e21072SPeter Shoults 
271*75e21072SPeter Shoults 	for (i = 0; i < princ->length; i++) {
272*75e21072SPeter Shoults 		princ->data[i].magic = components[i].k_magic;
273*75e21072SPeter Shoults 		set_from_utf8str(&princ->data[i], components[i].k_data);
274*75e21072SPeter Shoults 		if (princ->data[i].data == NULL)
2757c478bd9Sstevel@tonic-gate 			goto error;
2767c478bd9Sstevel@tonic-gate 	}
2777c478bd9Sstevel@tonic-gate 
278*75e21072SPeter Shoults 	return princ;
2797c478bd9Sstevel@tonic-gate error:
2807c478bd9Sstevel@tonic-gate 	krb5_free_principal(context, princ);
281*75e21072SPeter Shoults 	return NULL;
2827c478bd9Sstevel@tonic-gate }
2837c478bd9Sstevel@tonic-gate 
2847c478bd9Sstevel@tonic-gate /*
2857c478bd9Sstevel@tonic-gate  * This routine converts one or more krb5 db2 records into update
2867c478bd9Sstevel@tonic-gate  * log (ulog) entry format. Space for the update log entries should
2877c478bd9Sstevel@tonic-gate  * be allocated prior to invocation of this routine.
2887c478bd9Sstevel@tonic-gate  */
2897c478bd9Sstevel@tonic-gate krb5_error_code
ulog_conv_2logentry(krb5_context context,krb5_db_entry * entries,kdb_incr_update_t * updates,int nentries)2907c478bd9Sstevel@tonic-gate ulog_conv_2logentry(krb5_context context, krb5_db_entry *entries,
2917c478bd9Sstevel@tonic-gate 				kdb_incr_update_t *updates,
292*75e21072SPeter Shoults 				int nentries)
293*75e21072SPeter Shoults {
2947c478bd9Sstevel@tonic-gate 	int i, j, k, cnt, final, nattrs, tmpint, nprincs;
2957c478bd9Sstevel@tonic-gate 	unsigned int more;
2967c478bd9Sstevel@tonic-gate 	krb5_principal tmpprinc;
2977c478bd9Sstevel@tonic-gate 	krb5_tl_data *newtl;
2987c478bd9Sstevel@tonic-gate 	krb5_db_entry curr;
2997c478bd9Sstevel@tonic-gate 	krb5_error_code ret;
3007c478bd9Sstevel@tonic-gate 	kdbe_attr_type_t *attr_types;
3017c478bd9Sstevel@tonic-gate 	kdb_incr_update_t *upd;
3027c478bd9Sstevel@tonic-gate 	krb5_db_entry *ent;
303*75e21072SPeter Shoults 	int kadm_data_yes;
3047c478bd9Sstevel@tonic-gate 
3057c478bd9Sstevel@tonic-gate 	if ((updates == NULL) || (entries == NULL))
3067c478bd9Sstevel@tonic-gate 		return (KRB5KRB_ERR_GENERIC);
3077c478bd9Sstevel@tonic-gate 
3087c478bd9Sstevel@tonic-gate 	upd = updates;
3097c478bd9Sstevel@tonic-gate 	ent = entries;
3107c478bd9Sstevel@tonic-gate 
3117c478bd9Sstevel@tonic-gate 	for (k = 0; k < nentries; k++) {
3127c478bd9Sstevel@tonic-gate 		nprincs = nattrs = tmpint = 0;
3137c478bd9Sstevel@tonic-gate 		final = -1;
314*75e21072SPeter Shoults 		kadm_data_yes = 0;
3157c478bd9Sstevel@tonic-gate 		attr_types = NULL;
3167c478bd9Sstevel@tonic-gate 
3177c478bd9Sstevel@tonic-gate 		if ((upd->kdb_update.kdbe_t_val = (kdbe_val_t *)
3187c478bd9Sstevel@tonic-gate 				malloc(MAXENTRY_SIZE)) == NULL) {
3197c478bd9Sstevel@tonic-gate 			return (ENOMEM);
3207c478bd9Sstevel@tonic-gate 		}
3217c478bd9Sstevel@tonic-gate 
3227c478bd9Sstevel@tonic-gate 		/*
3237c478bd9Sstevel@tonic-gate 		 * Find out which attrs have been modified
3247c478bd9Sstevel@tonic-gate 		 */
3257c478bd9Sstevel@tonic-gate 		if ((attr_types = (kdbe_attr_type_t *)malloc(
3267c478bd9Sstevel@tonic-gate 			    sizeof (kdbe_attr_type_t) * MAXATTRS_SIZE))
3277c478bd9Sstevel@tonic-gate 					== NULL) {
3287c478bd9Sstevel@tonic-gate 			return (ENOMEM);
3297c478bd9Sstevel@tonic-gate 		}
3307c478bd9Sstevel@tonic-gate 
331*75e21072SPeter Shoults 		if ((ret = krb5_db_get_principal_nolock(context, ent->princ, &curr,
332*75e21072SPeter Shoults 						 &nprincs, &more))) {
333*75e21072SPeter Shoults 			free(attr_types);
3347c478bd9Sstevel@tonic-gate 			return (ret);
33554925bf6Swillf 		}
3367c478bd9Sstevel@tonic-gate 
3377c478bd9Sstevel@tonic-gate 		if (nprincs == 0) {
3387c478bd9Sstevel@tonic-gate 			/*
3397c478bd9Sstevel@tonic-gate 			 * This is a new entry to the database, hence will
3407c478bd9Sstevel@tonic-gate 			 * include all the attribute-value pairs
3417c478bd9Sstevel@tonic-gate 			 *
3427c478bd9Sstevel@tonic-gate 			 * We leave out the TL_DATA types which we model as
3437c478bd9Sstevel@tonic-gate 			 * attrs in kdbe_attr_type_t, since listing AT_TL_DATA
3447c478bd9Sstevel@tonic-gate 			 * encompasses these other types-turned-attributes
3457c478bd9Sstevel@tonic-gate 			 *
3467c478bd9Sstevel@tonic-gate 			 * So, we do *NOT* consider AT_MOD_PRINC, AT_MOD_TIME,
3477c478bd9Sstevel@tonic-gate 			 * AT_MOD_WHERE, AT_PW_LAST_CHANGE, AT_PW_POLICY,
3487c478bd9Sstevel@tonic-gate 			 * AT_PW_POLICY_SWITCH, AT_PW_HIST_KVNO and AT_PW_HIST,
3497c478bd9Sstevel@tonic-gate 			 * totalling 8 attrs.
3507c478bd9Sstevel@tonic-gate 			 */
3517c478bd9Sstevel@tonic-gate 			while (nattrs < MAXATTRS_SIZE - 8) {
3527c478bd9Sstevel@tonic-gate 				attr_types[nattrs] = nattrs;
3537c478bd9Sstevel@tonic-gate 				nattrs++;
3547c478bd9Sstevel@tonic-gate 			}
3557c478bd9Sstevel@tonic-gate 		} else {
3567c478bd9Sstevel@tonic-gate 			find_changed_attrs(&curr, ent, attr_types, &nattrs);
3577c478bd9Sstevel@tonic-gate 
3587c478bd9Sstevel@tonic-gate 			krb5_db_free_principal(context, &curr, nprincs);
3597c478bd9Sstevel@tonic-gate 		}
3607c478bd9Sstevel@tonic-gate 
3617c478bd9Sstevel@tonic-gate 		for (i = 0; i < nattrs; i++) {
3627c478bd9Sstevel@tonic-gate 			switch (attr_types[i]) {
3637c478bd9Sstevel@tonic-gate 			case AT_ATTRFLAGS:
3647c478bd9Sstevel@tonic-gate 				if (ent->attributes >= 0) {
3657c478bd9Sstevel@tonic-gate 					ULOG_ENTRY_TYPE(upd, ++final).av_type =
3667c478bd9Sstevel@tonic-gate 						AT_ATTRFLAGS;
3677c478bd9Sstevel@tonic-gate 					ULOG_ENTRY(upd, final).av_attrflags =
3687c478bd9Sstevel@tonic-gate 						(uint32_t)ent->attributes;
3697c478bd9Sstevel@tonic-gate 				}
3707c478bd9Sstevel@tonic-gate 				break;
3717c478bd9Sstevel@tonic-gate 
3727c478bd9Sstevel@tonic-gate 			case AT_MAX_LIFE:
3737c478bd9Sstevel@tonic-gate 				if (ent->max_life >= 0) {
3747c478bd9Sstevel@tonic-gate 					ULOG_ENTRY_TYPE(upd, ++final).av_type =
3757c478bd9Sstevel@tonic-gate 						AT_MAX_LIFE;
3767c478bd9Sstevel@tonic-gate 					ULOG_ENTRY(upd, final).av_max_life =
3777c478bd9Sstevel@tonic-gate 						(uint32_t)ent->max_life;
3787c478bd9Sstevel@tonic-gate 				}
3797c478bd9Sstevel@tonic-gate 				break;
3807c478bd9Sstevel@tonic-gate 
3817c478bd9Sstevel@tonic-gate 			case AT_MAX_RENEW_LIFE:
3827c478bd9Sstevel@tonic-gate 				if (ent->max_renewable_life >= 0) {
3837c478bd9Sstevel@tonic-gate 					ULOG_ENTRY_TYPE(upd, ++final).av_type =
3847c478bd9Sstevel@tonic-gate 						AT_MAX_RENEW_LIFE;
3857c478bd9Sstevel@tonic-gate 					ULOG_ENTRY(upd,
3867c478bd9Sstevel@tonic-gate 					    final).av_max_renew_life =
3877c478bd9Sstevel@tonic-gate 					    (uint32_t)ent->max_renewable_life;
3887c478bd9Sstevel@tonic-gate 				}
3897c478bd9Sstevel@tonic-gate 				break;
3907c478bd9Sstevel@tonic-gate 
3917c478bd9Sstevel@tonic-gate 			case AT_EXP:
3927c478bd9Sstevel@tonic-gate 				if (ent->expiration >= 0) {
3937c478bd9Sstevel@tonic-gate 					ULOG_ENTRY_TYPE(upd, ++final).av_type =
3947c478bd9Sstevel@tonic-gate 						AT_EXP;
3957c478bd9Sstevel@tonic-gate 					ULOG_ENTRY(upd, final).av_exp =
3967c478bd9Sstevel@tonic-gate 						(uint32_t)ent->expiration;
3977c478bd9Sstevel@tonic-gate 				}
3987c478bd9Sstevel@tonic-gate 				break;
3997c478bd9Sstevel@tonic-gate 
4007c478bd9Sstevel@tonic-gate 			case AT_PW_EXP:
4017c478bd9Sstevel@tonic-gate 				if (ent->pw_expiration >= 0) {
4027c478bd9Sstevel@tonic-gate 					ULOG_ENTRY_TYPE(upd, ++final).av_type =
4037c478bd9Sstevel@tonic-gate 						AT_PW_EXP;
4047c478bd9Sstevel@tonic-gate 					ULOG_ENTRY(upd, final).av_pw_exp =
4057c478bd9Sstevel@tonic-gate 						(uint32_t)ent->pw_expiration;
4067c478bd9Sstevel@tonic-gate 				}
4077c478bd9Sstevel@tonic-gate 				break;
4087c478bd9Sstevel@tonic-gate 
4097c478bd9Sstevel@tonic-gate 			case AT_LAST_SUCCESS:
4107c478bd9Sstevel@tonic-gate 				if (ent->last_success >= 0) {
4117c478bd9Sstevel@tonic-gate 					ULOG_ENTRY_TYPE(upd, ++final).av_type =
4127c478bd9Sstevel@tonic-gate 						AT_LAST_SUCCESS;
4137c478bd9Sstevel@tonic-gate 					ULOG_ENTRY(upd,
4147c478bd9Sstevel@tonic-gate 						final).av_last_success =
4157c478bd9Sstevel@tonic-gate 						    (uint32_t)ent->last_success;
4167c478bd9Sstevel@tonic-gate 				}
4177c478bd9Sstevel@tonic-gate 				break;
4187c478bd9Sstevel@tonic-gate 
4197c478bd9Sstevel@tonic-gate 			case AT_LAST_FAILED:
4207c478bd9Sstevel@tonic-gate 				if (ent->last_failed >= 0) {
4217c478bd9Sstevel@tonic-gate 					ULOG_ENTRY_TYPE(upd, ++final).av_type =
4227c478bd9Sstevel@tonic-gate 						AT_LAST_FAILED;
4237c478bd9Sstevel@tonic-gate 					ULOG_ENTRY(upd,
4247c478bd9Sstevel@tonic-gate 						final).av_last_failed =
4257c478bd9Sstevel@tonic-gate 						(uint32_t)ent->last_failed;
4267c478bd9Sstevel@tonic-gate 				}
4277c478bd9Sstevel@tonic-gate 				break;
4287c478bd9Sstevel@tonic-gate 
4297c478bd9Sstevel@tonic-gate 			case AT_FAIL_AUTH_COUNT:
4307c478bd9Sstevel@tonic-gate 				if (ent->fail_auth_count >= (krb5_kvno)0) {
4317c478bd9Sstevel@tonic-gate 					ULOG_ENTRY_TYPE(upd, ++final).av_type =
4327c478bd9Sstevel@tonic-gate 						AT_FAIL_AUTH_COUNT;
4337c478bd9Sstevel@tonic-gate 					ULOG_ENTRY(upd,
4347c478bd9Sstevel@tonic-gate 						final).av_fail_auth_count =
4357c478bd9Sstevel@tonic-gate 						(uint32_t)ent->fail_auth_count;
4367c478bd9Sstevel@tonic-gate 				}
4377c478bd9Sstevel@tonic-gate 				break;
4387c478bd9Sstevel@tonic-gate 
4397c478bd9Sstevel@tonic-gate 			case AT_PRINC:
4407c478bd9Sstevel@tonic-gate 				if (ent->princ->length > 0) {
4417c478bd9Sstevel@tonic-gate 					ULOG_ENTRY_TYPE(upd, ++final).av_type =
4427c478bd9Sstevel@tonic-gate 						AT_PRINC;
4437c478bd9Sstevel@tonic-gate 					if ((ret = conv_princ_2ulog(ent->princ,
444*75e21072SPeter Shoults 						upd, final, REG_PRINC))) {
445*75e21072SPeter Shoults 						free(attr_types);
4467c478bd9Sstevel@tonic-gate 						return (ret);
447*75e21072SPeter Shoults 					}
4487c478bd9Sstevel@tonic-gate 				}
4497c478bd9Sstevel@tonic-gate 				break;
4507c478bd9Sstevel@tonic-gate 
4517c478bd9Sstevel@tonic-gate 			case AT_KEYDATA:
4527c478bd9Sstevel@tonic-gate /* BEGIN CSTYLED */
4537c478bd9Sstevel@tonic-gate 				if (ent->n_key_data >= 0) {
4547c478bd9Sstevel@tonic-gate 					ULOG_ENTRY_TYPE(upd, ++final).av_type =
4557c478bd9Sstevel@tonic-gate 						AT_KEYDATA;
4567c478bd9Sstevel@tonic-gate 					ULOG_ENTRY(upd, final).av_keydata.av_keydata_len = ent->n_key_data;
4577c478bd9Sstevel@tonic-gate 
4587c478bd9Sstevel@tonic-gate 					ULOG_ENTRY(upd, final).av_keydata.av_keydata_val = malloc(ent->n_key_data * sizeof (kdbe_key_t));
459*75e21072SPeter Shoults 					if (ULOG_ENTRY(upd, final).av_keydata.av_keydata_val == NULL) {
460*75e21072SPeter Shoults 						free(attr_types);
4617c478bd9Sstevel@tonic-gate 						return (ENOMEM);
462*75e21072SPeter Shoults 					}
4637c478bd9Sstevel@tonic-gate 
4647c478bd9Sstevel@tonic-gate 					for (j = 0; j < ent->n_key_data; j++) {
4657c478bd9Sstevel@tonic-gate 						ULOG_ENTRY_KEYVAL(upd, final, j).k_ver = ent->key_data[j].key_data_ver;
4667c478bd9Sstevel@tonic-gate 						ULOG_ENTRY_KEYVAL(upd, final, j).k_kvno = ent->key_data[j].key_data_kvno;
4677c478bd9Sstevel@tonic-gate 						ULOG_ENTRY_KEYVAL(upd, final, j).k_enctype.k_enctype_len = ent->key_data[j].key_data_ver;
4687c478bd9Sstevel@tonic-gate 						ULOG_ENTRY_KEYVAL(upd, final, j).k_contents.k_contents_len = ent->key_data[j].key_data_ver;
4697c478bd9Sstevel@tonic-gate 
4707c478bd9Sstevel@tonic-gate 						ULOG_ENTRY_KEYVAL(upd, final, j).k_enctype.k_enctype_val = malloc(ent->key_data[j].key_data_ver * sizeof(int32_t));
471*75e21072SPeter Shoults 						if (ULOG_ENTRY_KEYVAL(upd, final, j).k_enctype.k_enctype_val == NULL) {
472*75e21072SPeter Shoults 							free(attr_types);
4737c478bd9Sstevel@tonic-gate 							return (ENOMEM);
474*75e21072SPeter Shoults 						}
4757c478bd9Sstevel@tonic-gate 
4767c478bd9Sstevel@tonic-gate 						ULOG_ENTRY_KEYVAL(upd, final, j).k_contents.k_contents_val = malloc(ent->key_data[j].key_data_ver * sizeof(utf8str_t));
477*75e21072SPeter Shoults 						if (ULOG_ENTRY_KEYVAL(upd, final, j).k_contents.k_contents_val == NULL) {
478*75e21072SPeter Shoults 							free(attr_types);
4797c478bd9Sstevel@tonic-gate 							return (ENOMEM);
480*75e21072SPeter Shoults 						}
4817c478bd9Sstevel@tonic-gate 
4827c478bd9Sstevel@tonic-gate 						for (cnt = 0; cnt < ent->key_data[j].key_data_ver; cnt++) {
4837c478bd9Sstevel@tonic-gate 							ULOG_ENTRY_KEYVAL(upd, final, j).k_enctype.k_enctype_val[cnt] = ent->key_data[j].key_data_type[cnt];
4847c478bd9Sstevel@tonic-gate 							ULOG_ENTRY_KEYVAL(upd, final, j).k_contents.k_contents_val[cnt].utf8str_t_len = ent->key_data[j].key_data_length[cnt];
4857c478bd9Sstevel@tonic-gate 							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));
486*75e21072SPeter Shoults 							if (ULOG_ENTRY_KEYVAL(upd, final, j).k_contents.k_contents_val[cnt].utf8str_t_val == NULL) {
487*75e21072SPeter Shoults 								free(attr_types);
4887c478bd9Sstevel@tonic-gate 								return (ENOMEM);
489*75e21072SPeter Shoults 							}
4907c478bd9Sstevel@tonic-gate 							(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]);
4917c478bd9Sstevel@tonic-gate 						}
4927c478bd9Sstevel@tonic-gate 					}
4937c478bd9Sstevel@tonic-gate 				}
4947c478bd9Sstevel@tonic-gate 				break;
4957c478bd9Sstevel@tonic-gate 
4967c478bd9Sstevel@tonic-gate 			case AT_TL_DATA:
4977c478bd9Sstevel@tonic-gate 				ret = krb5_dbe_lookup_last_pwd_change(context,
4987c478bd9Sstevel@tonic-gate 								ent, &tmpint);
4997c478bd9Sstevel@tonic-gate 				if (ret == 0) {
5007c478bd9Sstevel@tonic-gate 					ULOG_ENTRY_TYPE(upd, ++final).av_type =
5017c478bd9Sstevel@tonic-gate 						AT_PW_LAST_CHANGE;
5027c478bd9Sstevel@tonic-gate 					ULOG_ENTRY(upd, final).av_pw_last_change = tmpint;
5037c478bd9Sstevel@tonic-gate 				}
5047c478bd9Sstevel@tonic-gate 				tmpint = 0;
5057c478bd9Sstevel@tonic-gate 
5067c478bd9Sstevel@tonic-gate 				if(!(ret = krb5_dbe_lookup_mod_princ_data(
5077c478bd9Sstevel@tonic-gate 					context, ent, &tmpint, &tmpprinc))) {
5087c478bd9Sstevel@tonic-gate 
5097c478bd9Sstevel@tonic-gate 					ULOG_ENTRY_TYPE(upd, ++final).av_type =
5107c478bd9Sstevel@tonic-gate 						AT_MOD_PRINC;
5117c478bd9Sstevel@tonic-gate 
5127c478bd9Sstevel@tonic-gate 					ret = conv_princ_2ulog(tmpprinc,
5137c478bd9Sstevel@tonic-gate 					    upd, final, MOD_PRINC);
5147c478bd9Sstevel@tonic-gate 					krb5_free_principal(context, tmpprinc);
515*75e21072SPeter Shoults 					if (ret) {
516*75e21072SPeter Shoults 						free(attr_types);
5177c478bd9Sstevel@tonic-gate 						return (ret);
518*75e21072SPeter Shoults 					}
5197c478bd9Sstevel@tonic-gate 					ULOG_ENTRY_TYPE(upd, ++final).av_type =
5207c478bd9Sstevel@tonic-gate 						AT_MOD_TIME;
5217c478bd9Sstevel@tonic-gate 					ULOG_ENTRY(upd, final).av_mod_time =
5227c478bd9Sstevel@tonic-gate 						tmpint;
5237c478bd9Sstevel@tonic-gate 				}
5247c478bd9Sstevel@tonic-gate 
5257c478bd9Sstevel@tonic-gate 				newtl = ent->tl_data;
5267c478bd9Sstevel@tonic-gate 				while (newtl) {
5277c478bd9Sstevel@tonic-gate 					switch (newtl->tl_data_type) {
5287c478bd9Sstevel@tonic-gate 					case KRB5_TL_LAST_PWD_CHANGE:
5297c478bd9Sstevel@tonic-gate 					case KRB5_TL_MOD_PRINC:
5307c478bd9Sstevel@tonic-gate 						break;
5317c478bd9Sstevel@tonic-gate 
5327c478bd9Sstevel@tonic-gate 					case KRB5_TL_KADM_DATA:
5337c478bd9Sstevel@tonic-gate 					default:
534*75e21072SPeter Shoults 						if (kadm_data_yes == 0) {
5357c478bd9Sstevel@tonic-gate 							ULOG_ENTRY_TYPE(upd, ++final).av_type = AT_TL_DATA;
5367c478bd9Sstevel@tonic-gate 							ULOG_ENTRY(upd, final).av_tldata.av_tldata_len = 0;
5377c478bd9Sstevel@tonic-gate 							ULOG_ENTRY(upd, final).av_tldata.av_tldata_val = malloc(ent->n_tl_data * sizeof(kdbe_tl_t));
5387c478bd9Sstevel@tonic-gate 
539*75e21072SPeter Shoults 							if (ULOG_ENTRY(upd, final).av_tldata.av_tldata_val == NULL) {
540*75e21072SPeter Shoults 								free(attr_types);
5417c478bd9Sstevel@tonic-gate 								return (ENOMEM);
542*75e21072SPeter Shoults 							}
543*75e21072SPeter Shoults 							kadm_data_yes = 1;
5447c478bd9Sstevel@tonic-gate 						}
5457c478bd9Sstevel@tonic-gate 
5467c478bd9Sstevel@tonic-gate 						tmpint = ULOG_ENTRY(upd, final).av_tldata.av_tldata_len;
5477c478bd9Sstevel@tonic-gate 						ULOG_ENTRY(upd, final).av_tldata.av_tldata_len++;
5487c478bd9Sstevel@tonic-gate 						ULOG_ENTRY(upd, final).av_tldata.av_tldata_val[tmpint].tl_type = newtl->tl_data_type;
5497c478bd9Sstevel@tonic-gate 						ULOG_ENTRY(upd, final).av_tldata.av_tldata_val[tmpint].tl_data.tl_data_len = newtl->tl_data_length;
5507c478bd9Sstevel@tonic-gate 						ULOG_ENTRY(upd, final).av_tldata.av_tldata_val[tmpint].tl_data.tl_data_val = malloc(newtl->tl_data_length * sizeof (char));
551*75e21072SPeter Shoults 						if (ULOG_ENTRY(upd, final).av_tldata.av_tldata_val[tmpint].tl_data.tl_data_val == NULL) {
552*75e21072SPeter Shoults 							free(attr_types);
5537c478bd9Sstevel@tonic-gate 							return (ENOMEM);
554*75e21072SPeter Shoults 						}
5557c478bd9Sstevel@tonic-gate 						(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);
5567c478bd9Sstevel@tonic-gate 						break;
5577c478bd9Sstevel@tonic-gate 					}
5587c478bd9Sstevel@tonic-gate 					newtl = newtl->tl_data_next;
5597c478bd9Sstevel@tonic-gate 				}
5607c478bd9Sstevel@tonic-gate 				break;
5617c478bd9Sstevel@tonic-gate /* END CSTYLED */
5627c478bd9Sstevel@tonic-gate 
5637c478bd9Sstevel@tonic-gate 			case AT_LEN:
564ebd1706eSgtb 				ULOG_ENTRY_TYPE(upd, ++final).av_type =
565ebd1706eSgtb 					AT_LEN;
566ebd1706eSgtb 				ULOG_ENTRY(upd, final).av_len =
567ebd1706eSgtb 					(int16_t)ent->len;
5687c478bd9Sstevel@tonic-gate 				break;
5697c478bd9Sstevel@tonic-gate 
5707c478bd9Sstevel@tonic-gate 			default:
5717c478bd9Sstevel@tonic-gate 				break;
5727c478bd9Sstevel@tonic-gate 			}
5737c478bd9Sstevel@tonic-gate 
5747c478bd9Sstevel@tonic-gate 		}
5757c478bd9Sstevel@tonic-gate 
5767c478bd9Sstevel@tonic-gate 		if (attr_types)
5777c478bd9Sstevel@tonic-gate 			free(attr_types);
5787c478bd9Sstevel@tonic-gate 
5797c478bd9Sstevel@tonic-gate 		/*
5807c478bd9Sstevel@tonic-gate 		 * Update len field in kdb_update
5817c478bd9Sstevel@tonic-gate 		 */
5827c478bd9Sstevel@tonic-gate 		upd->kdb_update.kdbe_t_len = ++final;
5837c478bd9Sstevel@tonic-gate 
5847c478bd9Sstevel@tonic-gate 		/*
5857c478bd9Sstevel@tonic-gate 		 * Bump up to next struct
5867c478bd9Sstevel@tonic-gate 		 */
5877c478bd9Sstevel@tonic-gate 		upd++;
5887c478bd9Sstevel@tonic-gate 		ent++;
5897c478bd9Sstevel@tonic-gate 	}
5907c478bd9Sstevel@tonic-gate 	return (0);
5917c478bd9Sstevel@tonic-gate }
5927c478bd9Sstevel@tonic-gate 
5937c478bd9Sstevel@tonic-gate /*
5947c478bd9Sstevel@tonic-gate  * This routine converts one or more update log (ulog) entries into
5957c478bd9Sstevel@tonic-gate  * kerberos db2 records. Required memory should be allocated
5967c478bd9Sstevel@tonic-gate  * for the db2 records (pointed to by krb5_db_entry *ent), prior
5977c478bd9Sstevel@tonic-gate  * to calling this routine.
5987c478bd9Sstevel@tonic-gate  */
5997c478bd9Sstevel@tonic-gate krb5_error_code
ulog_conv_2dbentry(krb5_context context,krb5_db_entry * entries,kdb_incr_update_t * updates,int nentries)6007c478bd9Sstevel@tonic-gate ulog_conv_2dbentry(krb5_context context, krb5_db_entry *entries,
6017c478bd9Sstevel@tonic-gate 				kdb_incr_update_t *updates,
602*75e21072SPeter Shoults 				int nentries)
603*75e21072SPeter Shoults {
604*75e21072SPeter Shoults 	int k;
6057c478bd9Sstevel@tonic-gate 	krb5_db_entry *ent;
6067c478bd9Sstevel@tonic-gate 	kdb_incr_update_t *upd;
6077c478bd9Sstevel@tonic-gate 
6087c478bd9Sstevel@tonic-gate 	if ((updates == NULL) || (entries == NULL))
6097c478bd9Sstevel@tonic-gate 		return (KRB5KRB_ERR_GENERIC);
6107c478bd9Sstevel@tonic-gate 
6117c478bd9Sstevel@tonic-gate 	ent = entries;
6127c478bd9Sstevel@tonic-gate 	upd = updates;
6137c478bd9Sstevel@tonic-gate 
6147c478bd9Sstevel@tonic-gate 	for (k = 0; k < nentries; k++) {
615*75e21072SPeter Shoults 		krb5_principal mod_princ = NULL;
616*75e21072SPeter Shoults 		int i, j, cnt = 0, mod_time = 0, nattrs, nprincs = 0;
617*75e21072SPeter Shoults 		krb5_principal dbprinc;
618*75e21072SPeter Shoults 		char *dbprincstr = NULL;
619*75e21072SPeter Shoults 
620*75e21072SPeter Shoults 		krb5_tl_data *newtl = NULL;
621*75e21072SPeter Shoults 		krb5_error_code ret;
622*75e21072SPeter Shoults 		unsigned int more;
623*75e21072SPeter Shoults 		unsigned int prev_n_keys = 0;
6247c478bd9Sstevel@tonic-gate 
6257c478bd9Sstevel@tonic-gate 		/*
6267c478bd9Sstevel@tonic-gate 		 * If the ulog entry represents a DELETE update,
6277c478bd9Sstevel@tonic-gate 		 * just skip to the next entry.
6287c478bd9Sstevel@tonic-gate 		 */
6297c478bd9Sstevel@tonic-gate 		if (upd->kdb_deleted == TRUE)
6307c478bd9Sstevel@tonic-gate 			goto next;
6317c478bd9Sstevel@tonic-gate 
6327c478bd9Sstevel@tonic-gate 		/*
6337c478bd9Sstevel@tonic-gate 		 * Store the no. of changed attributes in nattrs
6347c478bd9Sstevel@tonic-gate 		 */
6357c478bd9Sstevel@tonic-gate 		nattrs = upd->kdb_update.kdbe_t_len;
6367c478bd9Sstevel@tonic-gate 
6377c478bd9Sstevel@tonic-gate 		dbprincstr = malloc((upd->kdb_princ_name.utf8str_t_len + 1)
6387c478bd9Sstevel@tonic-gate 					* sizeof (char));
6397c478bd9Sstevel@tonic-gate 		if (dbprincstr == NULL)
6407c478bd9Sstevel@tonic-gate 			return (ENOMEM);
641*75e21072SPeter Shoults 		strncpy(dbprincstr, (char *)upd->kdb_princ_name.utf8str_t_val,
642*75e21072SPeter Shoults 		    upd->kdb_princ_name.utf8str_t_len);
643*75e21072SPeter Shoults 		dbprincstr[upd->kdb_princ_name.utf8str_t_len] = 0;
6447c478bd9Sstevel@tonic-gate 		ret = krb5_parse_name(context, dbprincstr, &dbprinc);
6457c478bd9Sstevel@tonic-gate 		free(dbprincstr);
6467c478bd9Sstevel@tonic-gate 		if (ret)
6477c478bd9Sstevel@tonic-gate 			return (ret);
6487c478bd9Sstevel@tonic-gate 
6497c478bd9Sstevel@tonic-gate 		ret = krb5_db_get_principal(context, dbprinc, ent, &nprincs,
6507c478bd9Sstevel@tonic-gate 		    &more);
6517c478bd9Sstevel@tonic-gate 		krb5_free_principal(context, dbprinc);
6527c478bd9Sstevel@tonic-gate 		if (ret)
6537c478bd9Sstevel@tonic-gate 			return (ret);
6547c478bd9Sstevel@tonic-gate 
6557c478bd9Sstevel@tonic-gate 		/*
6567c478bd9Sstevel@tonic-gate 		 * Set ent->n_tl_data = 0 initially, if this is an ADD update
6577c478bd9Sstevel@tonic-gate 		 */
6587c478bd9Sstevel@tonic-gate 		if (nprincs == 0)
6597c478bd9Sstevel@tonic-gate 			ent->n_tl_data = 0;
6607c478bd9Sstevel@tonic-gate 
6617c478bd9Sstevel@tonic-gate 		for (i = 0; i < nattrs; i++) {
662*75e21072SPeter Shoults 			krb5_principal tmpprinc = NULL;
663*75e21072SPeter Shoults 
664*75e21072SPeter Shoults #define u (ULOG_ENTRY(upd, i))
6657c478bd9Sstevel@tonic-gate 			switch (ULOG_ENTRY_TYPE(upd, i).av_type) {
6667c478bd9Sstevel@tonic-gate 			case AT_ATTRFLAGS:
667*75e21072SPeter Shoults 				ent->attributes = (krb5_flags) u.av_attrflags;
6687c478bd9Sstevel@tonic-gate 				break;
6697c478bd9Sstevel@tonic-gate 
6707c478bd9Sstevel@tonic-gate 			case AT_MAX_LIFE:
671*75e21072SPeter Shoults 				ent->max_life = (krb5_deltat) u.av_max_life;
6727c478bd9Sstevel@tonic-gate 				break;
6737c478bd9Sstevel@tonic-gate 
6747c478bd9Sstevel@tonic-gate 			case AT_MAX_RENEW_LIFE:
675*75e21072SPeter Shoults 				ent->max_renewable_life = (krb5_deltat) u.av_max_renew_life;
6767c478bd9Sstevel@tonic-gate 				break;
6777c478bd9Sstevel@tonic-gate 
6787c478bd9Sstevel@tonic-gate 			case AT_EXP:
679*75e21072SPeter Shoults 				ent->expiration = (krb5_timestamp) u.av_exp;
6807c478bd9Sstevel@tonic-gate 				break;
6817c478bd9Sstevel@tonic-gate 
6827c478bd9Sstevel@tonic-gate 			case AT_PW_EXP:
683*75e21072SPeter Shoults 				ent->pw_expiration = (krb5_timestamp) u.av_pw_exp;
6847c478bd9Sstevel@tonic-gate 				break;
6857c478bd9Sstevel@tonic-gate 
6867c478bd9Sstevel@tonic-gate 			case AT_LAST_SUCCESS:
687*75e21072SPeter Shoults 				ent->last_success = (krb5_timestamp) u.av_last_success;
6887c478bd9Sstevel@tonic-gate 				break;
6897c478bd9Sstevel@tonic-gate 
6907c478bd9Sstevel@tonic-gate 			case AT_LAST_FAILED:
691*75e21072SPeter Shoults 				ent->last_failed = (krb5_timestamp) u.av_last_failed;
6927c478bd9Sstevel@tonic-gate 				break;
6937c478bd9Sstevel@tonic-gate 
6947c478bd9Sstevel@tonic-gate 			case AT_FAIL_AUTH_COUNT:
695*75e21072SPeter Shoults 				ent->fail_auth_count = (krb5_kvno) u.av_fail_auth_count;
6967c478bd9Sstevel@tonic-gate 				break;
6977c478bd9Sstevel@tonic-gate 
6987c478bd9Sstevel@tonic-gate 			case AT_PRINC:
699*75e21072SPeter Shoults 				tmpprinc = conv_princ_2db(context, &u.av_princ);
700*75e21072SPeter Shoults 				if (tmpprinc == NULL)
701*75e21072SPeter Shoults 					return ENOMEM;
702*75e21072SPeter Shoults 				if (nprincs)
703*75e21072SPeter Shoults 					krb5_free_principal(context, ent->princ);
704*75e21072SPeter Shoults 				ent->princ = tmpprinc;
7057c478bd9Sstevel@tonic-gate 				break;
7067c478bd9Sstevel@tonic-gate 
7077c478bd9Sstevel@tonic-gate 			case AT_KEYDATA:
7087c478bd9Sstevel@tonic-gate 
7097c478bd9Sstevel@tonic-gate 				if (nprincs != 0)
7107c478bd9Sstevel@tonic-gate 					prev_n_keys = ent->n_key_data;
711*75e21072SPeter Shoults 				else
712*75e21072SPeter Shoults 					prev_n_keys = 0;
713*75e21072SPeter Shoults 				ent->n_key_data = (krb5_int16)u.av_keydata.av_keydata_len;
7147c478bd9Sstevel@tonic-gate 				if (nprincs == 0)
7157c478bd9Sstevel@tonic-gate 					ent->key_data = NULL;
7167c478bd9Sstevel@tonic-gate 
717*75e21072SPeter Shoults 				ent->key_data = (krb5_key_data *)realloc(ent->key_data,
718*75e21072SPeter Shoults 						(ent->n_key_data *
7197c478bd9Sstevel@tonic-gate 						sizeof (krb5_key_data)));
720*75e21072SPeter Shoults 				 /* XXX Memory leak: Old key data in
721*75e21072SPeter Shoults 				    records eliminated by resizing to
722*75e21072SPeter Shoults 				    smaller size. */
7237c478bd9Sstevel@tonic-gate 				if (ent->key_data == NULL)
724*75e21072SPeter Shoults 					/* XXX Memory leak: old storage.  */
7257c478bd9Sstevel@tonic-gate 					return (ENOMEM);
7267c478bd9Sstevel@tonic-gate 
7277c478bd9Sstevel@tonic-gate /* BEGIN CSTYLED */
728*75e21072SPeter Shoults 				for (j = prev_n_keys; j < ent->n_key_data; j++) {
729*75e21072SPeter Shoults 					for (cnt = 0; cnt < 2; cnt++) {
730*75e21072SPeter Shoults 						ent->key_data[j].key_data_contents[cnt] = NULL;
731*75e21072SPeter Shoults 					}
732*75e21072SPeter Shoults 				}
7337c478bd9Sstevel@tonic-gate 				for (j = 0; j < ent->n_key_data; j++) {
734*75e21072SPeter Shoults 					krb5_key_data *kp = &ent->key_data[j];
735*75e21072SPeter Shoults 					kdbe_key_t *kv = &ULOG_ENTRY_KEYVAL(upd, i, j);
736*75e21072SPeter Shoults 					kp->key_data_ver = (krb5_int16)kv->k_ver;
737*75e21072SPeter Shoults 					kp->key_data_kvno = (krb5_int16)kv->k_kvno;
738*75e21072SPeter Shoults 					if (kp->key_data_ver > 2) {
739*75e21072SPeter Shoults 						return EINVAL; /* XXX ? */
740*75e21072SPeter Shoults 					}
7417c478bd9Sstevel@tonic-gate 
742*75e21072SPeter Shoults 					for (cnt = 0; cnt < kp->key_data_ver; cnt++) {
743*75e21072SPeter Shoults 						void *newptr;
744*75e21072SPeter Shoults 						kp->key_data_type[cnt] = (krb5_int16)kv->k_enctype.k_enctype_val[cnt];
745*75e21072SPeter Shoults 						kp->key_data_length[cnt] = (krb5_int16)kv->k_contents.k_contents_val[cnt].utf8str_t_len;
746*75e21072SPeter Shoults 						newptr = realloc(kp->key_data_contents[cnt],
747*75e21072SPeter Shoults 								 kp->key_data_length[cnt]);
748*75e21072SPeter Shoults 						if (newptr == NULL)
749*75e21072SPeter Shoults 							return ENOMEM;
750*75e21072SPeter Shoults 						kp->key_data_contents[cnt] = newptr;
751*75e21072SPeter Shoults 
752*75e21072SPeter Shoults 						(void) memset(kp->key_data_contents[cnt], 0,
753*75e21072SPeter Shoults 						    	      kp->key_data_length[cnt]);
754*75e21072SPeter Shoults 						(void) memcpy(kp->key_data_contents[cnt],
755*75e21072SPeter Shoults 						    	      kv->k_contents.k_contents_val[cnt].utf8str_t_val,
756*75e21072SPeter Shoults 						    	      kp->key_data_length[cnt]);
7577c478bd9Sstevel@tonic-gate 					}
7587c478bd9Sstevel@tonic-gate 				}
7597c478bd9Sstevel@tonic-gate 				break;
7607c478bd9Sstevel@tonic-gate 
7617c478bd9Sstevel@tonic-gate 			case AT_TL_DATA:
762*75e21072SPeter Shoults 				cnt = u.av_tldata.av_tldata_len;
7637c478bd9Sstevel@tonic-gate 				newtl = malloc(cnt * sizeof (krb5_tl_data));
7647c478bd9Sstevel@tonic-gate 				(void) memset(newtl, 0, (cnt * sizeof (krb5_tl_data)));
7657c478bd9Sstevel@tonic-gate 				if (newtl == NULL)
7667c478bd9Sstevel@tonic-gate 					return (ENOMEM);
7677c478bd9Sstevel@tonic-gate 
768*75e21072SPeter Shoults 				for (j = 0; j < cnt; j++) {
769*75e21072SPeter Shoults 					newtl[j].tl_data_type = (krb5_int16)u.av_tldata.av_tldata_val[j].tl_type;
770*75e21072SPeter Shoults 					newtl[j].tl_data_length = (krb5_int16)u.av_tldata.av_tldata_val[j].tl_data.tl_data_len;
7717c478bd9Sstevel@tonic-gate 					newtl[j].tl_data_contents = NULL;
7727c478bd9Sstevel@tonic-gate 					newtl[j].tl_data_contents = malloc(newtl[j].tl_data_length * sizeof (krb5_octet));
7737c478bd9Sstevel@tonic-gate 					if (newtl[j].tl_data_contents == NULL)
774*75e21072SPeter Shoults 						/* XXX Memory leak: newtl
775*75e21072SPeter Shoults 						   and previously
776*75e21072SPeter Shoults 						   allocated elements.  */
7777c478bd9Sstevel@tonic-gate 						return (ENOMEM);
7787c478bd9Sstevel@tonic-gate 
7797c478bd9Sstevel@tonic-gate 					(void) memset(newtl[j].tl_data_contents, 0, (newtl[j].tl_data_length * sizeof (krb5_octet)));
780*75e21072SPeter Shoults 					(void) memcpy(newtl[j].tl_data_contents, u.av_tldata.av_tldata_val[j].tl_data.tl_data_val, newtl[j].tl_data_length);
7817c478bd9Sstevel@tonic-gate 					newtl[j].tl_data_next = NULL;
7827c478bd9Sstevel@tonic-gate 					if (j > 0)
783*75e21072SPeter Shoults 						newtl[j - 1].tl_data_next = &newtl[j];
7847c478bd9Sstevel@tonic-gate 				}
7857c478bd9Sstevel@tonic-gate 
786*75e21072SPeter Shoults 				if ((ret = krb5_dbe_update_tl_data(context, ent, newtl)))
7877c478bd9Sstevel@tonic-gate 					return (ret);
7887c478bd9Sstevel@tonic-gate 				for (j = 0; j < cnt; j++)
7897c478bd9Sstevel@tonic-gate 					if (newtl[j].tl_data_contents) {
7907c478bd9Sstevel@tonic-gate 						free(newtl[j].tl_data_contents);
7917c478bd9Sstevel@tonic-gate 						newtl[j].tl_data_contents = NULL;
7927c478bd9Sstevel@tonic-gate 					}
7937c478bd9Sstevel@tonic-gate 				if (newtl) {
7947c478bd9Sstevel@tonic-gate 					free(newtl);
7957c478bd9Sstevel@tonic-gate 					newtl = NULL;
7967c478bd9Sstevel@tonic-gate 				}
7977c478bd9Sstevel@tonic-gate 				break;
7987c478bd9Sstevel@tonic-gate /* END CSTYLED */
7997c478bd9Sstevel@tonic-gate 
8007c478bd9Sstevel@tonic-gate 			case AT_PW_LAST_CHANGE:
801*75e21072SPeter Shoults 				if ((ret = krb5_dbe_update_last_pwd_change(context, ent,
802*75e21072SPeter Shoults 				    					   u.av_pw_last_change)))
8037c478bd9Sstevel@tonic-gate 						return (ret);
8047c478bd9Sstevel@tonic-gate 				break;
8057c478bd9Sstevel@tonic-gate 
8067c478bd9Sstevel@tonic-gate 			case AT_MOD_PRINC:
807*75e21072SPeter Shoults 				tmpprinc = conv_princ_2db(context, &u.av_mod_princ);
808*75e21072SPeter Shoults 				if (tmpprinc == NULL)
809*75e21072SPeter Shoults 					return ENOMEM;
810*75e21072SPeter Shoults 				mod_princ = tmpprinc;
8117c478bd9Sstevel@tonic-gate 				break;
8127c478bd9Sstevel@tonic-gate 
8137c478bd9Sstevel@tonic-gate 			case AT_MOD_TIME:
814*75e21072SPeter Shoults 				mod_time = u.av_mod_time;
8157c478bd9Sstevel@tonic-gate 				break;
8167c478bd9Sstevel@tonic-gate 
8177c478bd9Sstevel@tonic-gate 			case AT_LEN:
818*75e21072SPeter Shoults 				ent->len = (krb5_int16) u.av_len;
8197c478bd9Sstevel@tonic-gate 				break;
8207c478bd9Sstevel@tonic-gate 
8217c478bd9Sstevel@tonic-gate 			default:
8227c478bd9Sstevel@tonic-gate 				break;
8237c478bd9Sstevel@tonic-gate 			}
824*75e21072SPeter Shoults #undef u
8257c478bd9Sstevel@tonic-gate 		}
8267c478bd9Sstevel@tonic-gate 
8277c478bd9Sstevel@tonic-gate 		/*
8287c478bd9Sstevel@tonic-gate 		 * process mod_princ_data request
8297c478bd9Sstevel@tonic-gate 		 */
8307c478bd9Sstevel@tonic-gate 		if (mod_time && mod_princ) {
8317c478bd9Sstevel@tonic-gate 			ret = krb5_dbe_update_mod_princ_data(context, ent,
8327c478bd9Sstevel@tonic-gate 			    mod_time, mod_princ);
8337c478bd9Sstevel@tonic-gate 			krb5_free_principal(context, mod_princ);
834*75e21072SPeter Shoults 			mod_princ = NULL;
8357c478bd9Sstevel@tonic-gate 			if (ret)
8367c478bd9Sstevel@tonic-gate 				return (ret);
8377c478bd9Sstevel@tonic-gate 		}
8387c478bd9Sstevel@tonic-gate 
8397c478bd9Sstevel@tonic-gate next:
8407c478bd9Sstevel@tonic-gate 		/*
8417c478bd9Sstevel@tonic-gate 		 * Bump up to next struct
8427c478bd9Sstevel@tonic-gate 		 */
8437c478bd9Sstevel@tonic-gate 		upd++;
8447c478bd9Sstevel@tonic-gate 		ent++;
8457c478bd9Sstevel@tonic-gate 	}
8467c478bd9Sstevel@tonic-gate 	return (0);
8477c478bd9Sstevel@tonic-gate }
8487c478bd9Sstevel@tonic-gate 
8497c478bd9Sstevel@tonic-gate 
8507c478bd9Sstevel@tonic-gate 
8517c478bd9Sstevel@tonic-gate /*
8527c478bd9Sstevel@tonic-gate  * This routine frees up memory associated with the bunched ulog entries.
8537c478bd9Sstevel@tonic-gate  */
8547c478bd9Sstevel@tonic-gate void
ulog_free_entries(kdb_incr_update_t * updates,int no_of_updates)855*75e21072SPeter Shoults ulog_free_entries(kdb_incr_update_t *updates, int no_of_updates)
856*75e21072SPeter Shoults {
8577c478bd9Sstevel@tonic-gate 
8587c478bd9Sstevel@tonic-gate 	kdb_incr_update_t *upd;
8597c478bd9Sstevel@tonic-gate 	int i, j, k, cnt;
8607c478bd9Sstevel@tonic-gate 
8617c478bd9Sstevel@tonic-gate 	if (updates == NULL)
8627c478bd9Sstevel@tonic-gate 		return;
8637c478bd9Sstevel@tonic-gate 
8647c478bd9Sstevel@tonic-gate 	upd = updates;
8657c478bd9Sstevel@tonic-gate 
8667c478bd9Sstevel@tonic-gate 	/*
8677c478bd9Sstevel@tonic-gate 	 * Loop thru each ulog entry
8687c478bd9Sstevel@tonic-gate 	 */
8697c478bd9Sstevel@tonic-gate 	for (cnt = 0; cnt < no_of_updates; cnt++) {
8707c478bd9Sstevel@tonic-gate 
8717c478bd9Sstevel@tonic-gate 		/*
8727c478bd9Sstevel@tonic-gate 		 * ulog entry - kdb_princ_name
8737c478bd9Sstevel@tonic-gate 		 */
874*75e21072SPeter Shoults 		free(upd->kdb_princ_name.utf8str_t_val);
8757c478bd9Sstevel@tonic-gate 
8767c478bd9Sstevel@tonic-gate /* BEGIN CSTYLED */
8777c478bd9Sstevel@tonic-gate 
8787c478bd9Sstevel@tonic-gate 		/*
8797c478bd9Sstevel@tonic-gate 		 * ulog entry - kdb_kdcs_seen_by
8807c478bd9Sstevel@tonic-gate 		 */
8817c478bd9Sstevel@tonic-gate 		if (upd->kdb_kdcs_seen_by.kdb_kdcs_seen_by_val) {
882*75e21072SPeter Shoults 			for (i = 0; i < upd->kdb_kdcs_seen_by.kdb_kdcs_seen_by_len; i++)
883*75e21072SPeter Shoults 				free(upd->kdb_kdcs_seen_by.kdb_kdcs_seen_by_val[i].utf8str_t_val);
884*75e21072SPeter Shoults 			free(upd->kdb_kdcs_seen_by.kdb_kdcs_seen_by_val);
8857c478bd9Sstevel@tonic-gate 		}
8867c478bd9Sstevel@tonic-gate 
8877c478bd9Sstevel@tonic-gate 		/*
8887c478bd9Sstevel@tonic-gate 		 * ulog entry - kdb_futures
8897c478bd9Sstevel@tonic-gate 		 */
890*75e21072SPeter Shoults 		free(upd->kdb_futures.kdb_futures_val);
8917c478bd9Sstevel@tonic-gate 
8927c478bd9Sstevel@tonic-gate 		/*
8937c478bd9Sstevel@tonic-gate 		 * ulog entry - kdb_update
8947c478bd9Sstevel@tonic-gate 		 */
895*75e21072SPeter Shoults 		if (upd->kdb_update.kdbe_t_val) {
8967c478bd9Sstevel@tonic-gate 			/*
8977c478bd9Sstevel@tonic-gate 			 * Loop thru all the attributes and free up stuff
8987c478bd9Sstevel@tonic-gate 			 */
8997c478bd9Sstevel@tonic-gate 			for (i = 0; i < upd->kdb_update.kdbe_t_len; i++) {
9007c478bd9Sstevel@tonic-gate 
9017c478bd9Sstevel@tonic-gate 				/*
9027c478bd9Sstevel@tonic-gate 				 * Free av_key_data
9037c478bd9Sstevel@tonic-gate 				 */
9047c478bd9Sstevel@tonic-gate 				if ((ULOG_ENTRY_TYPE(upd, i).av_type == AT_KEYDATA) && ULOG_ENTRY(upd, i).av_keydata.av_keydata_val) {
9057c478bd9Sstevel@tonic-gate 
9067c478bd9Sstevel@tonic-gate 					for (j = 0; j < ULOG_ENTRY(upd, i).av_keydata.av_keydata_len; j++) {
907*75e21072SPeter Shoults 						free(ULOG_ENTRY_KEYVAL(upd, i, j).k_enctype.k_enctype_val);
9087c478bd9Sstevel@tonic-gate 						if (ULOG_ENTRY_KEYVAL(upd, i, j).k_contents.k_contents_val) {
9097c478bd9Sstevel@tonic-gate 							for (k = 0; k < ULOG_ENTRY_KEYVAL(upd, i, j).k_ver; k++) {
910*75e21072SPeter Shoults 								free(ULOG_ENTRY_KEYVAL(upd, i, j).k_contents.k_contents_val[k].utf8str_t_val);
9117c478bd9Sstevel@tonic-gate 							}
9127c478bd9Sstevel@tonic-gate 							free(ULOG_ENTRY_KEYVAL(upd, i, j).k_contents.k_contents_val);
9137c478bd9Sstevel@tonic-gate 						}
9147c478bd9Sstevel@tonic-gate 					}
9157c478bd9Sstevel@tonic-gate 					free(ULOG_ENTRY(upd, i).av_keydata.av_keydata_val);
9167c478bd9Sstevel@tonic-gate 				}
9177c478bd9Sstevel@tonic-gate 
9187c478bd9Sstevel@tonic-gate 
9197c478bd9Sstevel@tonic-gate 				/*
9207c478bd9Sstevel@tonic-gate 				 * Free av_tl_data
9217c478bd9Sstevel@tonic-gate 				 */
9227c478bd9Sstevel@tonic-gate 				if ((ULOG_ENTRY_TYPE(upd, i).av_type == AT_TL_DATA) && ULOG_ENTRY(upd, i).av_tldata.av_tldata_val) {
9237c478bd9Sstevel@tonic-gate 					for (j = 0; j < ULOG_ENTRY(upd, i).av_tldata.av_tldata_len; j++) {
924*75e21072SPeter Shoults 						free(ULOG_ENTRY(upd, i).av_tldata.av_tldata_val[j].tl_data.tl_data_val);
9257c478bd9Sstevel@tonic-gate 					}
9267c478bd9Sstevel@tonic-gate 					free(ULOG_ENTRY(upd, i).av_tldata.av_tldata_val);
9277c478bd9Sstevel@tonic-gate 				}
9287c478bd9Sstevel@tonic-gate 
9297c478bd9Sstevel@tonic-gate 				/*
9307c478bd9Sstevel@tonic-gate 				 * Free av_princ
9317c478bd9Sstevel@tonic-gate 				 */
9327c478bd9Sstevel@tonic-gate 				if (ULOG_ENTRY_TYPE(upd, i).av_type == AT_PRINC) {
933*75e21072SPeter Shoults 					free(ULOG_ENTRY(upd, i).av_princ.k_realm.utf8str_t_val);
9347c478bd9Sstevel@tonic-gate 					if (ULOG_ENTRY(upd, i).av_princ.k_components.k_components_val) {
9357c478bd9Sstevel@tonic-gate 						for (j = 0; j < ULOG_ENTRY(upd, i).av_princ.k_components.k_components_len; j++) {
936*75e21072SPeter Shoults 							free(ULOG_ENTRY_PRINC(upd, i, j).k_data.utf8str_t_val);
9377c478bd9Sstevel@tonic-gate 						}
9387c478bd9Sstevel@tonic-gate 						free(ULOG_ENTRY(upd, i).av_princ.k_components.k_components_val);
9397c478bd9Sstevel@tonic-gate 					}
9407c478bd9Sstevel@tonic-gate 				}
9417c478bd9Sstevel@tonic-gate 
9427c478bd9Sstevel@tonic-gate 				/*
9437c478bd9Sstevel@tonic-gate 				 * Free av_mod_princ
9447c478bd9Sstevel@tonic-gate 				 */
9457c478bd9Sstevel@tonic-gate 				if (ULOG_ENTRY_TYPE(upd, i).av_type == AT_MOD_PRINC) {
946*75e21072SPeter Shoults 					free(ULOG_ENTRY(upd, i).av_mod_princ.k_realm.utf8str_t_val);
9477c478bd9Sstevel@tonic-gate 					if (ULOG_ENTRY(upd, i).av_mod_princ.k_components.k_components_val) {
9487c478bd9Sstevel@tonic-gate 						for (j = 0; j < ULOG_ENTRY(upd, i).av_mod_princ.k_components.k_components_len; j++) {
949*75e21072SPeter Shoults 							free(ULOG_ENTRY_MOD_PRINC(upd, i, j).k_data.utf8str_t_val);
9507c478bd9Sstevel@tonic-gate 						}
9517c478bd9Sstevel@tonic-gate 						free(ULOG_ENTRY(upd, i).av_mod_princ.k_components.k_components_val);
9527c478bd9Sstevel@tonic-gate 					}
9537c478bd9Sstevel@tonic-gate 				}
9547c478bd9Sstevel@tonic-gate 
9557c478bd9Sstevel@tonic-gate 				/*
9567c478bd9Sstevel@tonic-gate 				 * Free av_mod_where
9577c478bd9Sstevel@tonic-gate 				 */
9587c478bd9Sstevel@tonic-gate 				if ((ULOG_ENTRY_TYPE(upd, i).av_type == AT_MOD_WHERE) && ULOG_ENTRY(upd, i).av_mod_where.utf8str_t_val)
9597c478bd9Sstevel@tonic-gate 					free(ULOG_ENTRY(upd, i).av_mod_where.utf8str_t_val);
9607c478bd9Sstevel@tonic-gate 
9617c478bd9Sstevel@tonic-gate 				/*
9627c478bd9Sstevel@tonic-gate 				 * Free av_pw_policy
9637c478bd9Sstevel@tonic-gate 				 */
9647c478bd9Sstevel@tonic-gate 				if ((ULOG_ENTRY_TYPE(upd, i).av_type == AT_PW_POLICY) && ULOG_ENTRY(upd, i).av_pw_policy.utf8str_t_val)
9657c478bd9Sstevel@tonic-gate 					free(ULOG_ENTRY(upd, i).av_pw_policy.utf8str_t_val);
9667c478bd9Sstevel@tonic-gate 
9677c478bd9Sstevel@tonic-gate 				/*
9687c478bd9Sstevel@tonic-gate 				 * XXX: Free av_pw_hist
9697c478bd9Sstevel@tonic-gate 				 *
9707c478bd9Sstevel@tonic-gate 				 * For now, we just free the pointer
971*75e21072SPeter Shoults 				 * to av_pw_hist_val, since we aren't
9727c478bd9Sstevel@tonic-gate 				 * populating this union member in
9737c478bd9Sstevel@tonic-gate 				 * the conv api function(s) anyways.
9747c478bd9Sstevel@tonic-gate 				 */
9757c478bd9Sstevel@tonic-gate 				if ((ULOG_ENTRY_TYPE(upd, i).av_type == AT_PW_HIST) && ULOG_ENTRY(upd, i).av_pw_hist.av_pw_hist_val)
9767c478bd9Sstevel@tonic-gate 					free(ULOG_ENTRY(upd, i).av_pw_hist.av_pw_hist_val);
9777c478bd9Sstevel@tonic-gate 
9787c478bd9Sstevel@tonic-gate 			 }
9797c478bd9Sstevel@tonic-gate 
9807c478bd9Sstevel@tonic-gate 			/*
9817c478bd9Sstevel@tonic-gate 			 * Free up the pointer to kdbe_t_val
9827c478bd9Sstevel@tonic-gate 			 */
983*75e21072SPeter Shoults 			free(upd->kdb_update.kdbe_t_val);
9847c478bd9Sstevel@tonic-gate 		}
9857c478bd9Sstevel@tonic-gate 
9867c478bd9Sstevel@tonic-gate /* END CSTYLED */
9877c478bd9Sstevel@tonic-gate 
9887c478bd9Sstevel@tonic-gate 		/*
9897c478bd9Sstevel@tonic-gate 		 * Bump up to next struct
9907c478bd9Sstevel@tonic-gate 		 */
9917c478bd9Sstevel@tonic-gate 		upd++;
9927c478bd9Sstevel@tonic-gate 	}
9937c478bd9Sstevel@tonic-gate 
9947c478bd9Sstevel@tonic-gate 
9957c478bd9Sstevel@tonic-gate 	/*
9967c478bd9Sstevel@tonic-gate 	 * Finally, free up the pointer to the bunched ulog entries
9977c478bd9Sstevel@tonic-gate 	 */
998*75e21072SPeter Shoults 	free(updates);
9997c478bd9Sstevel@tonic-gate }
1000