2 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
6 /* #pragma ident "@(#)kdb_convert.c 1.3 05/01/05 SMI" */
9 * This file contains api's for conversion of the kdb_incr_update_t
10 * struct(s) into krb5_db_entry struct(s) and vice-versa.
12 #include <sys/types.h>
16 #include <iprop_hdr.h>
23 #define ULOG_ENTRY_TYPE(upd, i) ((kdb_incr_update_t *)upd)->kdb_update.kdbe_t_val[i]
25 #define ULOG_ENTRY(upd, i) ((kdb_incr_update_t *)upd)->kdb_update.kdbe_t_val[i].kdbe_val_t_u
27 #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]
29 #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]
31 #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]
41 * This routine tracks the krb5_db_entry fields that have been modified
42 * (by comparing it to the db_entry currently present in principal.db)
46 find_changed_attrs(krb5_db_entry *current, krb5_db_entry *new,
47 krb5_boolean exclude_nra,
48 kdbe_attr_type_t *attrs, int *nattrs)
52 krb5_tl_data *first, *second;
54 if (current->attributes != new->attributes)
55 attrs[i++] = AT_ATTRFLAGS;
57 if (current->max_life != new->max_life)
58 attrs[i++] = AT_MAX_LIFE;
60 if (current->max_renewable_life != new->max_renewable_life)
61 attrs[i++] = AT_MAX_RENEW_LIFE;
63 if (current->expiration != new->expiration)
66 if (current->pw_expiration != new->pw_expiration)
67 attrs[i++] = AT_PW_EXP;
70 if (current->last_success != new->last_success)
71 attrs[i++] = AT_LAST_SUCCESS;
73 if (current->last_failed != new->last_failed)
74 attrs[i++] = AT_LAST_FAILED;
76 if (current->fail_auth_count != new->fail_auth_count)
77 attrs[i++] = AT_FAIL_AUTH_COUNT;
80 if ((current->princ->type == new->princ->type) &&
81 (current->princ->length == new->princ->length)) {
82 if ((current->princ->realm.length ==
83 new->princ->realm.length) &&
84 strncmp(current->princ->realm.data,
85 new->princ->realm.data,
86 current->princ->realm.length)) {
87 for (j = 0; j < current->princ->length; j++) {
88 if ((current->princ->data[j].data != NULL) &&
89 (strncmp(current->princ->data[j].data,
90 new->princ->data[j].data,
91 current->princ->data[j].length))) {
92 attrs[i++] = AT_PRINC;
97 attrs[i++] = AT_PRINC;
100 attrs[i++] = AT_PRINC;
103 if (current->n_key_data == new->n_key_data) {
104 /* Assuming key ordering is the same in new & current */
105 for (j = 0; j < new->n_key_data; j++) {
106 if (current->key_data[j].key_data_kvno !=
107 new->key_data[j].key_data_kvno) {
108 attrs[i++] = AT_KEYDATA;
113 attrs[i++] = AT_KEYDATA;
116 if (current->n_tl_data == new->n_tl_data) {
117 /* Assuming we preserve the TL_DATA ordering between updates */
118 for (first = current->tl_data, second = new->tl_data;
119 first; first = first->tl_data_next,
120 second = second->tl_data_next) {
121 if ((first->tl_data_length == second->tl_data_length) &&
122 (first->tl_data_type == second->tl_data_type)) {
123 if ((memcmp((char *)first->tl_data_contents,
124 (char *)second->tl_data_contents,
125 first->tl_data_length)) != 0) {
126 attrs[i++] = AT_TL_DATA;
130 attrs[i++] = AT_TL_DATA;
135 attrs[i++] = AT_TL_DATA;
138 if (current->len != new->len)
141 * Store the no. of (possibly :)) changed attributes
150 data_to_utf8str(utf8str_t *u, krb5_data d)
152 u->utf8str_t_len = d.length;
154 u->utf8str_t_val = malloc(d.length);
155 if (u->utf8str_t_val == NULL)
157 memcpy(u->utf8str_t_val, d.data, d.length);
159 u->utf8str_t_val = NULL;
164 * Converts the krb5_principal struct from db2 to ulog format.
166 static krb5_error_code
167 conv_princ_2ulog(krb5_principal princ, kdb_incr_update_t *upd,
168 int cnt, princ_type tp)
172 kdbe_data_t *components;
174 if ((upd == NULL) || !princ)
175 return (KRB5KRB_ERR_GENERIC);
180 p = &ULOG_ENTRY(upd, cnt).av_princ; /* or av_mod_princ */
181 p->k_nametype = (int32_t)princ->type;
183 if (data_to_utf8str(&p->k_realm, princ->realm) < 0) {
187 p->k_components.k_components_len = princ->length;
189 p->k_components.k_components_val = components
190 = malloc(princ->length * sizeof (kdbe_data_t));
191 if (p->k_components.k_components_val == NULL) {
192 free(p->k_realm.utf8str_t_val);
193 p->k_realm.utf8str_t_val = NULL;
197 memset(components, 0, princ->length * sizeof(kdbe_data_t));
198 for (i = 0; i < princ->length; i++)
199 components[i].k_data.utf8str_t_val = NULL;
200 for (i = 0; i < princ->length; i++) {
201 components[i].k_magic = princ->data[i].magic;
202 if (data_to_utf8str(&components[i].k_data, princ->data[i]) < 0) {
204 for (j = 0; j < i; j++) {
205 free(components[j].k_data.utf8str_t_val);
206 components[j].k_data.utf8str_t_val = NULL;
209 p->k_components.k_components_val = NULL;
210 free(p->k_realm.utf8str_t_val);
211 p->k_realm.utf8str_t_val = NULL;
224 * Copies a UTF-8 string from ulog to a krb5_data object, which may
225 * already have allocated storage associated with it.
227 * Maybe a return value should indicate success/failure?
230 set_from_utf8str(krb5_data *d, utf8str_t u)
232 if (u.utf8str_t_len > INT_MAX-1 || u.utf8str_t_len >= SIZE_MAX-1) {
236 d->length = u.utf8str_t_len;
237 d->data = malloc(d->length + 1);
240 if (d->length) /* Pointer may be null if length = 0. */
241 strncpy(d->data, u.utf8str_t_val, d->length);
242 d->data[d->length] = 0;
246 * Converts the krb5_principal struct from ulog to db2 format.
248 static krb5_principal
249 conv_princ_2db(krb5_context context, kdbe_princ_t *kdbe_princ)
252 krb5_principal princ;
253 kdbe_data_t *components;
255 princ = calloc(1, sizeof (krb5_principal_data));
262 components = kdbe_princ->k_components.k_components_val;
264 princ->type = (krb5_int32) kdbe_princ->k_nametype;
265 princ->realm.data = NULL;
266 set_from_utf8str(&princ->realm, kdbe_princ->k_realm);
267 if (princ->realm.data == NULL)
270 princ->data = calloc(kdbe_princ->k_components.k_components_len,
272 if (princ->data == NULL)
274 for (i = 0; i < kdbe_princ->k_components.k_components_len; i++)
275 princ->data[i].data = NULL;
276 princ->length = (krb5_int32)kdbe_princ->k_components.k_components_len;
278 for (i = 0; i < princ->length; i++) {
279 princ->data[i].magic = components[i].k_magic;
280 set_from_utf8str(&princ->data[i], components[i].k_data);
281 if (princ->data[i].data == NULL)
287 krb5_free_principal(context, princ);
293 * This routine converts one or more krb5 db2 records into update
294 * log (ulog) entry format. Space for the update log entries should
295 * be allocated prior to invocation of this routine.
298 ulog_conv_2logentry(krb5_context context, krb5_db_entry *entries,
299 kdb_incr_update_t *updates,
302 int i, j, k, cnt, final, nattrs, tmpint, nprincs;
304 krb5_principal tmpprinc;
308 kdbe_attr_type_t *attr_types;
309 kdb_incr_update_t *upd;
312 /* always exclude non-replicated attributes, for now */
313 krb5_boolean exclude_nra = TRUE;
315 if ((updates == NULL) || (entries == NULL))
316 return (KRB5KRB_ERR_GENERIC);
321 for (k = 0; k < nentries; k++) {
322 nprincs = nattrs = tmpint = 0;
328 * XXX we rely on the good behaviour of the database not to
331 if ((upd->kdb_update.kdbe_t_val = (kdbe_val_t *)
332 malloc(MAXENTRY_SIZE)) == NULL) {
337 * Find out which attrs have been modified
339 if ((attr_types = (kdbe_attr_type_t *)malloc(
340 sizeof (kdbe_attr_type_t) * MAXATTRS_SIZE))
345 if ((ret = krb5_db_get_principal(context, ent->princ, &curr,
353 * This is a new entry to the database, hence will
354 * include all the attribute-value pairs
356 * We leave out the TL_DATA types which we model as
357 * attrs in kdbe_attr_type_t, since listing AT_TL_DATA
358 * encompasses these other types-turned-attributes
360 * So, we do *NOT* consider AT_MOD_PRINC, AT_MOD_TIME,
361 * AT_MOD_WHERE, AT_PW_LAST_CHANGE, AT_PW_POLICY,
362 * AT_PW_POLICY_SWITCH, AT_PW_HIST_KVNO and AT_PW_HIST,
365 while (nattrs < MAXATTRS_SIZE - 8) {
366 attr_types[nattrs] = nattrs;
370 find_changed_attrs(&curr, ent, exclude_nra, attr_types, &nattrs);
372 krb5_db_free_principal(context, &curr, nprincs);
375 for (i = 0; i < nattrs; i++) {
376 switch (attr_types[i]) {
378 if (ent->attributes >= 0) {
379 ULOG_ENTRY_TYPE(upd, ++final).av_type =
381 ULOG_ENTRY(upd, final).av_attrflags =
382 (uint32_t)ent->attributes;
387 if (ent->max_life >= 0) {
388 ULOG_ENTRY_TYPE(upd, ++final).av_type =
390 ULOG_ENTRY(upd, final).av_max_life =
391 (uint32_t)ent->max_life;
395 case AT_MAX_RENEW_LIFE:
396 if (ent->max_renewable_life >= 0) {
397 ULOG_ENTRY_TYPE(upd, ++final).av_type =
400 final).av_max_renew_life =
401 (uint32_t)ent->max_renewable_life;
406 if (ent->expiration >= 0) {
407 ULOG_ENTRY_TYPE(upd, ++final).av_type =
409 ULOG_ENTRY(upd, final).av_exp =
410 (uint32_t)ent->expiration;
415 if (ent->pw_expiration >= 0) {
416 ULOG_ENTRY_TYPE(upd, ++final).av_type =
418 ULOG_ENTRY(upd, final).av_pw_exp =
419 (uint32_t)ent->pw_expiration;
423 case AT_LAST_SUCCESS:
424 if (!exclude_nra && ent->last_success >= 0) {
425 ULOG_ENTRY_TYPE(upd, ++final).av_type =
428 final).av_last_success =
429 (uint32_t)ent->last_success;
434 if (!exclude_nra && ent->last_failed >= 0) {
435 ULOG_ENTRY_TYPE(upd, ++final).av_type =
438 final).av_last_failed =
439 (uint32_t)ent->last_failed;
443 case AT_FAIL_AUTH_COUNT:
444 if (!exclude_nra && ent->fail_auth_count >= (krb5_kvno)0) {
445 ULOG_ENTRY_TYPE(upd, ++final).av_type =
448 final).av_fail_auth_count =
449 (uint32_t)ent->fail_auth_count;
454 if (ent->princ->length > 0) {
455 ULOG_ENTRY_TYPE(upd, ++final).av_type =
457 if ((ret = conv_princ_2ulog(ent->princ,
458 upd, final, REG_PRINC))) {
467 if (ent->n_key_data >= 0) {
468 ULOG_ENTRY_TYPE(upd, ++final).av_type =
470 ULOG_ENTRY(upd, final).av_keydata.av_keydata_len = ent->n_key_data;
472 ULOG_ENTRY(upd, final).av_keydata.av_keydata_val = malloc(ent->n_key_data * sizeof (kdbe_key_t));
473 if (ULOG_ENTRY(upd, final).av_keydata.av_keydata_val == NULL) {
478 for (j = 0; j < ent->n_key_data; j++) {
479 ULOG_ENTRY_KEYVAL(upd, final, j).k_ver = ent->key_data[j].key_data_ver;
480 ULOG_ENTRY_KEYVAL(upd, final, j).k_kvno = ent->key_data[j].key_data_kvno;
481 ULOG_ENTRY_KEYVAL(upd, final, j).k_enctype.k_enctype_len = ent->key_data[j].key_data_ver;
482 ULOG_ENTRY_KEYVAL(upd, final, j).k_contents.k_contents_len = ent->key_data[j].key_data_ver;
484 ULOG_ENTRY_KEYVAL(upd, final, j).k_enctype.k_enctype_val = malloc(ent->key_data[j].key_data_ver * sizeof(int32_t));
485 if (ULOG_ENTRY_KEYVAL(upd, final, j).k_enctype.k_enctype_val == NULL) {
490 ULOG_ENTRY_KEYVAL(upd, final, j).k_contents.k_contents_val = malloc(ent->key_data[j].key_data_ver * sizeof(utf8str_t));
491 if (ULOG_ENTRY_KEYVAL(upd, final, j).k_contents.k_contents_val == NULL) {
496 for (cnt = 0; cnt < ent->key_data[j].key_data_ver; cnt++) {
497 ULOG_ENTRY_KEYVAL(upd, final, j).k_enctype.k_enctype_val[cnt] = ent->key_data[j].key_data_type[cnt];
498 ULOG_ENTRY_KEYVAL(upd, final, j).k_contents.k_contents_val[cnt].utf8str_t_len = ent->key_data[j].key_data_length[cnt];
499 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));
500 if (ULOG_ENTRY_KEYVAL(upd, final, j).k_contents.k_contents_val[cnt].utf8str_t_val == NULL) {
504 (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]);
511 ret = krb5_dbe_lookup_last_pwd_change(context,
514 ULOG_ENTRY_TYPE(upd, ++final).av_type =
516 ULOG_ENTRY(upd, final).av_pw_last_change = tmpint;
520 if(!(ret = krb5_dbe_lookup_mod_princ_data(
521 context, ent, &tmpint, &tmpprinc))) {
523 ULOG_ENTRY_TYPE(upd, ++final).av_type =
526 ret = conv_princ_2ulog(tmpprinc,
527 upd, final, MOD_PRINC);
528 krb5_free_principal(context, tmpprinc);
533 ULOG_ENTRY_TYPE(upd, ++final).av_type =
535 ULOG_ENTRY(upd, final).av_mod_time =
539 newtl = ent->tl_data;
541 switch (newtl->tl_data_type) {
542 case KRB5_TL_LAST_PWD_CHANGE:
543 case KRB5_TL_MOD_PRINC:
546 case KRB5_TL_KADM_DATA:
548 if (kadm_data_yes == 0) {
549 ULOG_ENTRY_TYPE(upd, ++final).av_type = AT_TL_DATA;
550 ULOG_ENTRY(upd, final).av_tldata.av_tldata_len = 0;
551 ULOG_ENTRY(upd, final).av_tldata.av_tldata_val = malloc(ent->n_tl_data * sizeof(kdbe_tl_t));
553 if (ULOG_ENTRY(upd, final).av_tldata.av_tldata_val == NULL) {
560 tmpint = ULOG_ENTRY(upd, final).av_tldata.av_tldata_len;
561 ULOG_ENTRY(upd, final).av_tldata.av_tldata_len++;
562 ULOG_ENTRY(upd, final).av_tldata.av_tldata_val[tmpint].tl_type = newtl->tl_data_type;
563 ULOG_ENTRY(upd, final).av_tldata.av_tldata_val[tmpint].tl_data.tl_data_len = newtl->tl_data_length;
564 ULOG_ENTRY(upd, final).av_tldata.av_tldata_val[tmpint].tl_data.tl_data_val = malloc(newtl->tl_data_length * sizeof (char));
565 if (ULOG_ENTRY(upd, final).av_tldata.av_tldata_val[tmpint].tl_data.tl_data_val == NULL) {
569 (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);
572 newtl = newtl->tl_data_next;
579 ULOG_ENTRY_TYPE(upd, ++final).av_type =
581 ULOG_ENTRY(upd, final).av_len =
595 * Update len field in kdb_update
597 upd->kdb_update.kdbe_t_len = ++final;
600 * Bump up to next struct
609 * This routine converts one or more update log (ulog) entries into
610 * kerberos db2 records. Required memory should be allocated
611 * for the db2 records (pointed to by krb5_db_entry *ent), prior
612 * to calling this routine.
615 ulog_conv_2dbentry(krb5_context context, krb5_db_entry *entries,
616 kdb_incr_update_t *updates,
621 kdb_incr_update_t *upd;
624 if ((updates == NULL) || (entries == NULL))
625 return (KRB5KRB_ERR_GENERIC);
630 slave = (context->kdblog_context != NULL) &&
631 (context->kdblog_context->iproprole == IPROP_SLAVE);
633 for (k = 0; k < nentries; k++) {
634 krb5_principal mod_princ = NULL;
635 int i, j, cnt = 0, mod_time = 0, nattrs, nprincs = 0;
636 krb5_principal dbprinc;
637 char *dbprincstr = NULL;
639 krb5_tl_data *newtl = NULL;
642 unsigned int prev_n_keys = 0;
645 * If the ulog entry represents a DELETE update,
646 * just skip to the next entry.
648 if (upd->kdb_deleted == TRUE)
652 * Store the no. of changed attributes in nattrs
654 nattrs = upd->kdb_update.kdbe_t_len;
656 dbprincstr = malloc((upd->kdb_princ_name.utf8str_t_len + 1)
658 if (dbprincstr == NULL)
660 strncpy(dbprincstr, (char *)upd->kdb_princ_name.utf8str_t_val,
661 upd->kdb_princ_name.utf8str_t_len);
662 dbprincstr[upd->kdb_princ_name.utf8str_t_len] = 0;
664 ret = krb5_parse_name(context, dbprincstr, &dbprinc);
669 ret = krb5_db_get_principal(context, dbprinc, ent, &nprincs,
671 krb5_free_principal(context, dbprinc);
676 * Set ent->n_tl_data = 0 initially, if this is an ADD update
681 for (i = 0; i < nattrs; i++) {
682 krb5_principal tmpprinc = NULL;
684 #define u (ULOG_ENTRY(upd, i))
685 switch (ULOG_ENTRY_TYPE(upd, i).av_type) {
687 ent->attributes = (krb5_flags) u.av_attrflags;
691 ent->max_life = (krb5_deltat) u.av_max_life;
694 case AT_MAX_RENEW_LIFE:
695 ent->max_renewable_life = (krb5_deltat) u.av_max_renew_life;
699 ent->expiration = (krb5_timestamp) u.av_exp;
703 ent->pw_expiration = (krb5_timestamp) u.av_pw_exp;
706 case AT_LAST_SUCCESS:
708 ent->last_success = (krb5_timestamp) u.av_last_success;
713 ent->last_failed = (krb5_timestamp) u.av_last_failed;
716 case AT_FAIL_AUTH_COUNT:
718 ent->fail_auth_count = (krb5_kvno) u.av_fail_auth_count;
722 tmpprinc = conv_princ_2db(context, &u.av_princ);
723 if (tmpprinc == NULL)
726 krb5_free_principal(context, ent->princ);
727 ent->princ = tmpprinc;
732 prev_n_keys = ent->n_key_data;
735 ent->n_key_data = (krb5_int16)u.av_keydata.av_keydata_len;
737 ent->key_data = NULL;
739 ent->key_data = (krb5_key_data *)realloc(ent->key_data,
741 sizeof (krb5_key_data)));
742 /* XXX Memory leak: Old key data in
743 records eliminated by resizing to
745 if (ent->key_data == NULL)
746 /* XXX Memory leak: old storage. */
750 for (j = prev_n_keys; j < ent->n_key_data; j++) {
751 for (cnt = 0; cnt < 2; cnt++) {
752 ent->key_data[j].key_data_contents[cnt] = NULL;
755 for (j = 0; j < ent->n_key_data; j++) {
756 krb5_key_data *kp = &ent->key_data[j];
757 kdbe_key_t *kv = &ULOG_ENTRY_KEYVAL(upd, i, j);
758 kp->key_data_ver = (krb5_int16)kv->k_ver;
759 kp->key_data_kvno = (krb5_int16)kv->k_kvno;
760 if (kp->key_data_ver > 2) {
761 return EINVAL; /* XXX ? */
764 for (cnt = 0; cnt < kp->key_data_ver; cnt++) {
766 kp->key_data_type[cnt] = (krb5_int16)kv->k_enctype.k_enctype_val[cnt];
767 kp->key_data_length[cnt] = (krb5_int16)kv->k_contents.k_contents_val[cnt].utf8str_t_len;
768 newptr = realloc(kp->key_data_contents[cnt],
769 kp->key_data_length[cnt]);
772 kp->key_data_contents[cnt] = newptr;
774 (void) memset(kp->key_data_contents[cnt], 0,
775 kp->key_data_length[cnt]);
776 (void) memcpy(kp->key_data_contents[cnt],
777 kv->k_contents.k_contents_val[cnt].utf8str_t_val,
778 kp->key_data_length[cnt]);
786 cnt = u.av_tldata.av_tldata_len;
787 newtl = calloc(cnt, sizeof (krb5_tl_data));
791 for (j = 0, t = 0; j < cnt; j++) {
792 newtl[t].tl_data_type = (krb5_int16)u.av_tldata.av_tldata_val[j].tl_type;
793 newtl[t].tl_data_length = (krb5_int16)u.av_tldata.av_tldata_val[j].tl_data.tl_data_len;
794 newtl[t].tl_data_contents = malloc(newtl[t].tl_data_length * sizeof (krb5_octet));
795 if (newtl[t].tl_data_contents == NULL)
796 /* XXX Memory leak: newtl
798 allocated elements. */
801 (void) memcpy(newtl[t].tl_data_contents, u.av_tldata.av_tldata_val[t].tl_data.tl_data_val, newtl[t].tl_data_length);
802 newtl[t].tl_data_next = NULL;
804 newtl[t - 1].tl_data_next = &newtl[t];
808 if ((ret = krb5_dbe_update_tl_data(context, ent, newtl)))
810 for (j = 0; j < t; j++)
811 if (newtl[j].tl_data_contents) {
812 free(newtl[j].tl_data_contents);
813 newtl[j].tl_data_contents = NULL;
822 case AT_PW_LAST_CHANGE:
823 if ((ret = krb5_dbe_update_last_pwd_change(context, ent,
824 u.av_pw_last_change)))
829 tmpprinc = conv_princ_2db(context, &u.av_mod_princ);
830 if (tmpprinc == NULL)
832 mod_princ = tmpprinc;
836 mod_time = u.av_mod_time;
840 ent->len = (krb5_int16) u.av_len;
850 * process mod_princ_data request
852 if (mod_time && mod_princ) {
853 ret = krb5_dbe_update_mod_princ_data(context, ent,
854 mod_time, mod_princ);
855 krb5_free_principal(context, mod_princ);
863 * Bump up to next struct
874 * This routine frees up memory associated with the bunched ulog entries.
877 ulog_free_entries(kdb_incr_update_t *updates, int no_of_updates)
880 kdb_incr_update_t *upd;
889 * Loop thru each ulog entry
891 for (cnt = 0; cnt < no_of_updates; cnt++) {
894 * ulog entry - kdb_princ_name
896 free(upd->kdb_princ_name.utf8str_t_val);
901 * ulog entry - kdb_kdcs_seen_by
903 if (upd->kdb_kdcs_seen_by.kdb_kdcs_seen_by_val) {
904 for (i = 0; i < upd->kdb_kdcs_seen_by.kdb_kdcs_seen_by_len; i++)
905 free(upd->kdb_kdcs_seen_by.kdb_kdcs_seen_by_val[i].utf8str_t_val);
906 free(upd->kdb_kdcs_seen_by.kdb_kdcs_seen_by_val);
910 * ulog entry - kdb_futures
912 free(upd->kdb_futures.kdb_futures_val);
915 * ulog entry - kdb_update
917 if (upd->kdb_update.kdbe_t_val) {
919 * Loop thru all the attributes and free up stuff
921 for (i = 0; i < upd->kdb_update.kdbe_t_len; i++) {
926 if ((ULOG_ENTRY_TYPE(upd, i).av_type == AT_KEYDATA) && ULOG_ENTRY(upd, i).av_keydata.av_keydata_val) {
928 for (j = 0; j < ULOG_ENTRY(upd, i).av_keydata.av_keydata_len; j++) {
929 free(ULOG_ENTRY_KEYVAL(upd, i, j).k_enctype.k_enctype_val);
930 if (ULOG_ENTRY_KEYVAL(upd, i, j).k_contents.k_contents_val) {
931 for (k = 0; k < ULOG_ENTRY_KEYVAL(upd, i, j).k_ver; k++) {
932 free(ULOG_ENTRY_KEYVAL(upd, i, j).k_contents.k_contents_val[k].utf8str_t_val);
934 free(ULOG_ENTRY_KEYVAL(upd, i, j).k_contents.k_contents_val);
937 free(ULOG_ENTRY(upd, i).av_keydata.av_keydata_val);
944 if ((ULOG_ENTRY_TYPE(upd, i).av_type == AT_TL_DATA) && ULOG_ENTRY(upd, i).av_tldata.av_tldata_val) {
945 for (j = 0; j < ULOG_ENTRY(upd, i).av_tldata.av_tldata_len; j++) {
946 free(ULOG_ENTRY(upd, i).av_tldata.av_tldata_val[j].tl_data.tl_data_val);
948 free(ULOG_ENTRY(upd, i).av_tldata.av_tldata_val);
954 if (ULOG_ENTRY_TYPE(upd, i).av_type == AT_PRINC) {
955 free(ULOG_ENTRY(upd, i).av_princ.k_realm.utf8str_t_val);
956 if (ULOG_ENTRY(upd, i).av_princ.k_components.k_components_val) {
957 for (j = 0; j < ULOG_ENTRY(upd, i).av_princ.k_components.k_components_len; j++) {
958 free(ULOG_ENTRY_PRINC(upd, i, j).k_data.utf8str_t_val);
960 free(ULOG_ENTRY(upd, i).av_princ.k_components.k_components_val);
967 if (ULOG_ENTRY_TYPE(upd, i).av_type == AT_MOD_PRINC) {
968 free(ULOG_ENTRY(upd, i).av_mod_princ.k_realm.utf8str_t_val);
969 if (ULOG_ENTRY(upd, i).av_mod_princ.k_components.k_components_val) {
970 for (j = 0; j < ULOG_ENTRY(upd, i).av_mod_princ.k_components.k_components_len; j++) {
971 free(ULOG_ENTRY_MOD_PRINC(upd, i, j).k_data.utf8str_t_val);
973 free(ULOG_ENTRY(upd, i).av_mod_princ.k_components.k_components_val);
980 if ((ULOG_ENTRY_TYPE(upd, i).av_type == AT_MOD_WHERE) && ULOG_ENTRY(upd, i).av_mod_where.utf8str_t_val)
981 free(ULOG_ENTRY(upd, i).av_mod_where.utf8str_t_val);
986 if ((ULOG_ENTRY_TYPE(upd, i).av_type == AT_PW_POLICY) && ULOG_ENTRY(upd, i).av_pw_policy.utf8str_t_val)
987 free(ULOG_ENTRY(upd, i).av_pw_policy.utf8str_t_val);
990 * XXX: Free av_pw_hist
992 * For now, we just free the pointer
993 * to av_pw_hist_val, since we aren't
994 * populating this union member in
995 * the conv api function(s) anyways.
997 if ((ULOG_ENTRY_TYPE(upd, i).av_type == AT_PW_HIST) && ULOG_ENTRY(upd, i).av_pw_hist.av_pw_hist_val)
998 free(ULOG_ENTRY(upd, i).av_pw_hist.av_pw_hist_val);
1003 * Free up the pointer to kdbe_t_val
1005 free(upd->kdb_update.kdbe_t_val);
1011 * Bump up to next struct
1018 * Finally, free up the pointer to the bunched ulog entries