dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / lib / krb5 / kdb / kdb_convert.c
blob039c4e4f0376acba33e590421177b13d2295a6fc
1 /*
2 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
6 /*
7 * This file contains api's for conversion of the kdb_incr_update_t
8 * struct(s) into krb5_db_entry struct(s) and vice-versa.
9 */
10 #include <sys/types.h>
11 #include <com_err.h>
12 #include <locale.h>
13 #include <errno.h>
14 #include <iprop_hdr.h>
15 #include "iprop.h"
16 #include <k5-int.h>
17 #include <kdb.h>
18 #include <kdb_log.h>
20 /* BEGIN CSTYLED */
21 #define ULOG_ENTRY_TYPE(upd, i) ((kdb_incr_update_t *)upd)->kdb_update.kdbe_t_val[i]
23 #define ULOG_ENTRY(upd, i) ((kdb_incr_update_t *)upd)->kdb_update.kdbe_t_val[i].kdbe_val_t_u
25 #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]
27 #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]
29 #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]
30 /* END CSTYLED */
32 typedef enum {
33 REG_PRINC = 0,
34 MOD_PRINC = 1
35 } princ_type;
39 * This routine tracks the krb5_db_entry fields that have been modified
40 * (by comparing it to the db_entry currently present in principal.db)
41 * in the update.
43 static void
44 find_changed_attrs(krb5_db_entry *current, krb5_db_entry *new,
45 kdbe_attr_type_t *attrs, int *nattrs)
47 int i = 0, j = 0;
49 krb5_tl_data *first, *second;
51 if (current->attributes != new->attributes)
52 attrs[i++] = AT_ATTRFLAGS;
54 if (current->max_life != new->max_life)
55 attrs[i++] = AT_MAX_LIFE;
57 if (current->max_renewable_life != new->max_renewable_life)
58 attrs[i++] = AT_MAX_RENEW_LIFE;
60 if (current->expiration != new->expiration)
61 attrs[i++] = AT_EXP;
63 if (current->pw_expiration != new->pw_expiration)
64 attrs[i++] = AT_PW_EXP;
66 if (current->last_success != new->last_success)
67 attrs[i++] = AT_LAST_SUCCESS;
69 if (current->last_failed != new->last_failed)
70 attrs[i++] = AT_LAST_FAILED;
72 if (current->fail_auth_count != new->fail_auth_count)
73 attrs[i++] = AT_FAIL_AUTH_COUNT;
75 if ((current->princ->type == new->princ->type) &&
76 (current->princ->length == new->princ->length)) {
77 if ((current->princ->realm.length ==
78 new->princ->realm.length) &&
79 strncmp(current->princ->realm.data,
80 new->princ->realm.data,
81 current->princ->realm.length)) {
82 for (j = 0; j < current->princ->length; j++) {
83 if ((current->princ->data[j].data != NULL) &&
84 (strncmp(current->princ->data[j].data,
85 new->princ->data[j].data,
86 current->princ->data[j].length))) {
87 attrs[i++] = AT_PRINC;
88 break;
91 } else {
92 attrs[i++] = AT_PRINC;
94 } else {
95 attrs[i++] = AT_PRINC;
98 if (current->n_key_data == new->n_key_data) {
99 /* Assuming key ordering is the same in new & current */
100 for (j = 0; j < new->n_key_data; j++) {
101 if (current->key_data[j].key_data_kvno !=
102 new->key_data[j].key_data_kvno) {
103 attrs[i++] = AT_KEYDATA;
104 break;
107 } else {
108 attrs[i++] = AT_KEYDATA;
111 if (current->n_tl_data == new->n_tl_data) {
112 /* Assuming we preserve the TL_DATA ordering between updates */
113 for (first = current->tl_data, second = new->tl_data;
114 first; first = first->tl_data_next,
115 second = second->tl_data_next) {
116 if ((first->tl_data_length == second->tl_data_length) &&
117 (first->tl_data_type == second->tl_data_type)) {
118 if ((memcmp((char *)first->tl_data_contents,
119 (char *)second->tl_data_contents,
120 first->tl_data_length)) != 0) {
121 attrs[i++] = AT_TL_DATA;
122 break;
124 } else {
125 attrs[i++] = AT_TL_DATA;
126 break;
130 } else {
131 attrs[i++] = AT_TL_DATA;
134 if (current->len != new->len)
135 attrs[i++] = AT_LEN;
137 * Store the no. of (possibly :)) changed attributes
139 *nattrs = i;
142 static int
143 data_to_utf8str(utf8str_t *u, krb5_data d)
145 u->utf8str_t_len = d.length;
146 if (d.data) {
147 u->utf8str_t_val = malloc(d.length);
148 if (u->utf8str_t_val == NULL)
149 return -1;
150 memcpy(u->utf8str_t_val, d.data, d.length);
151 } else
152 u->utf8str_t_val = NULL;
153 return 0;
157 * Converts the krb5_principal struct from db2 to ulog format.
159 static krb5_error_code
160 conv_princ_2ulog(krb5_principal princ, kdb_incr_update_t *upd,
161 int cnt, princ_type tp) {
162 int i = 0;
163 kdbe_princ_t *p;
164 kdbe_data_t *components;
166 if ((upd == NULL) || !princ)
167 return (KRB5KRB_ERR_GENERIC);
169 switch (tp) {
170 case REG_PRINC:
171 case MOD_PRINC:
172 p = &ULOG_ENTRY(upd, cnt).av_princ; /* or av_mod_princ */
173 p->k_nametype = (int32_t)princ->type;
175 if (data_to_utf8str(&p->k_realm, princ->realm) < 0) {
176 return ENOMEM;
179 p->k_components.k_components_len = princ->length;
181 p->k_components.k_components_val = components
182 = malloc(princ->length * sizeof (kdbe_data_t));
183 if (p->k_components.k_components_val == NULL) {
184 free(p->k_realm.utf8str_t_val);
185 p->k_realm.utf8str_t_val = NULL;
186 return (ENOMEM);
189 memset(components, 0, princ->length * sizeof(kdbe_data_t));
190 for (i = 0; i < princ->length; i++)
191 components[i].k_data.utf8str_t_val = NULL;
192 for (i = 0; i < princ->length; i++) {
193 components[i].k_magic = princ->data[i].magic;
194 if (data_to_utf8str(&components[i].k_data,
195 princ->data[i]) < 0) {
196 int j;
197 for (j = 0; j < i; j++) {
198 free(components[j].k_data.utf8str_t_val);
199 components[j].k_data.utf8str_t_val = NULL;
201 free(components);
202 p->k_components.k_components_val = NULL;
203 free(p->k_realm.utf8str_t_val);
204 p->k_realm.utf8str_t_val = NULL;
205 return ENOMEM;
208 break;
210 default:
211 break;
213 return (0);
217 * Copies a UTF-8 string from ulog to a krb5_data object, which may
218 * already have allocated storage associated with it.
220 * Maybe a return value should indicate success/failure?
222 static void
223 set_from_utf8str(krb5_data *d, utf8str_t u)
225 if (u.utf8str_t_len > INT_MAX-1 || u.utf8str_t_len >= SIZE_MAX-1) {
226 d->data = NULL;
227 return;
229 d->length = u.utf8str_t_len;
230 d->data = malloc(d->length + 1);
231 if (d->data == NULL)
232 return;
233 if (d->length) /* Pointer may be null if length = 0. */
234 strncpy(d->data, u.utf8str_t_val, d->length);
235 d->data[d->length] = 0;
239 * Converts the krb5_principal struct from ulog to db2 format.
241 static krb5_principal
242 conv_princ_2db(krb5_context context, kdbe_princ_t *kdbe_princ)
244 int i;
245 krb5_principal princ;
246 kdbe_data_t *components;
248 princ = calloc(1, sizeof (krb5_principal_data));
249 if (princ == NULL) {
250 return NULL;
252 princ->length = 0;
253 princ->data = NULL;
255 components = kdbe_princ->k_components.k_components_val;
257 princ->type = (krb5_int32) kdbe_princ->k_nametype;
258 princ->realm.data = NULL;
259 set_from_utf8str(&princ->realm, kdbe_princ->k_realm);
260 if (princ->realm.data == NULL)
261 goto error;
263 princ->data = calloc(kdbe_princ->k_components.k_components_len,
264 sizeof (krb5_data));
265 if (princ->data == NULL)
266 goto error;
267 for (i = 0; i < kdbe_princ->k_components.k_components_len; i++)
268 princ->data[i].data = NULL;
269 princ->length = (krb5_int32)kdbe_princ->k_components.k_components_len;
271 for (i = 0; i < princ->length; i++) {
272 princ->data[i].magic = components[i].k_magic;
273 set_from_utf8str(&princ->data[i], components[i].k_data);
274 if (princ->data[i].data == NULL)
275 goto error;
278 return princ;
279 error:
280 krb5_free_principal(context, princ);
281 return NULL;
285 * This routine converts one or more krb5 db2 records into update
286 * log (ulog) entry format. Space for the update log entries should
287 * be allocated prior to invocation of this routine.
289 krb5_error_code
290 ulog_conv_2logentry(krb5_context context, krb5_db_entry *entries,
291 kdb_incr_update_t *updates,
292 int nentries)
294 int i, j, k, cnt, final, nattrs, tmpint, nprincs;
295 unsigned int more;
296 krb5_principal tmpprinc;
297 krb5_tl_data *newtl;
298 krb5_db_entry curr;
299 krb5_error_code ret;
300 kdbe_attr_type_t *attr_types;
301 kdb_incr_update_t *upd;
302 krb5_db_entry *ent;
303 int kadm_data_yes;
305 if ((updates == NULL) || (entries == NULL))
306 return (KRB5KRB_ERR_GENERIC);
308 upd = updates;
309 ent = entries;
311 for (k = 0; k < nentries; k++) {
312 nprincs = nattrs = tmpint = 0;
313 final = -1;
314 kadm_data_yes = 0;
315 attr_types = NULL;
317 if ((upd->kdb_update.kdbe_t_val = (kdbe_val_t *)
318 malloc(MAXENTRY_SIZE)) == NULL) {
319 return (ENOMEM);
323 * Find out which attrs have been modified
325 if ((attr_types = (kdbe_attr_type_t *)malloc(
326 sizeof (kdbe_attr_type_t) * MAXATTRS_SIZE))
327 == NULL) {
328 return (ENOMEM);
331 if ((ret = krb5_db_get_principal_nolock(context, ent->princ, &curr,
332 &nprincs, &more))) {
333 free(attr_types);
334 return (ret);
337 if (nprincs == 0) {
339 * This is a new entry to the database, hence will
340 * include all the attribute-value pairs
342 * We leave out the TL_DATA types which we model as
343 * attrs in kdbe_attr_type_t, since listing AT_TL_DATA
344 * encompasses these other types-turned-attributes
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.
351 while (nattrs < MAXATTRS_SIZE - 8) {
352 attr_types[nattrs] = nattrs;
353 nattrs++;
355 } else {
356 find_changed_attrs(&curr, ent, attr_types, &nattrs);
358 krb5_db_free_principal(context, &curr, nprincs);
361 for (i = 0; i < nattrs; i++) {
362 switch (attr_types[i]) {
363 case AT_ATTRFLAGS:
364 if (ent->attributes >= 0) {
365 ULOG_ENTRY_TYPE(upd, ++final).av_type =
366 AT_ATTRFLAGS;
367 ULOG_ENTRY(upd, final).av_attrflags =
368 (uint32_t)ent->attributes;
370 break;
372 case AT_MAX_LIFE:
373 if (ent->max_life >= 0) {
374 ULOG_ENTRY_TYPE(upd, ++final).av_type =
375 AT_MAX_LIFE;
376 ULOG_ENTRY(upd, final).av_max_life =
377 (uint32_t)ent->max_life;
379 break;
381 case AT_MAX_RENEW_LIFE:
382 if (ent->max_renewable_life >= 0) {
383 ULOG_ENTRY_TYPE(upd, ++final).av_type =
384 AT_MAX_RENEW_LIFE;
385 ULOG_ENTRY(upd,
386 final).av_max_renew_life =
387 (uint32_t)ent->max_renewable_life;
389 break;
391 case AT_EXP:
392 if (ent->expiration >= 0) {
393 ULOG_ENTRY_TYPE(upd, ++final).av_type =
394 AT_EXP;
395 ULOG_ENTRY(upd, final).av_exp =
396 (uint32_t)ent->expiration;
398 break;
400 case AT_PW_EXP:
401 if (ent->pw_expiration >= 0) {
402 ULOG_ENTRY_TYPE(upd, ++final).av_type =
403 AT_PW_EXP;
404 ULOG_ENTRY(upd, final).av_pw_exp =
405 (uint32_t)ent->pw_expiration;
407 break;
409 case AT_LAST_SUCCESS:
410 if (ent->last_success >= 0) {
411 ULOG_ENTRY_TYPE(upd, ++final).av_type =
412 AT_LAST_SUCCESS;
413 ULOG_ENTRY(upd,
414 final).av_last_success =
415 (uint32_t)ent->last_success;
417 break;
419 case AT_LAST_FAILED:
420 if (ent->last_failed >= 0) {
421 ULOG_ENTRY_TYPE(upd, ++final).av_type =
422 AT_LAST_FAILED;
423 ULOG_ENTRY(upd,
424 final).av_last_failed =
425 (uint32_t)ent->last_failed;
427 break;
429 case AT_FAIL_AUTH_COUNT:
430 if (ent->fail_auth_count >= (krb5_kvno)0) {
431 ULOG_ENTRY_TYPE(upd, ++final).av_type =
432 AT_FAIL_AUTH_COUNT;
433 ULOG_ENTRY(upd,
434 final).av_fail_auth_count =
435 (uint32_t)ent->fail_auth_count;
437 break;
439 case AT_PRINC:
440 if (ent->princ->length > 0) {
441 ULOG_ENTRY_TYPE(upd, ++final).av_type =
442 AT_PRINC;
443 if ((ret = conv_princ_2ulog(ent->princ,
444 upd, final, REG_PRINC))) {
445 free(attr_types);
446 return (ret);
449 break;
451 case AT_KEYDATA:
452 /* BEGIN CSTYLED */
453 if (ent->n_key_data >= 0) {
454 ULOG_ENTRY_TYPE(upd, ++final).av_type =
455 AT_KEYDATA;
456 ULOG_ENTRY(upd, final).av_keydata.av_keydata_len = ent->n_key_data;
458 ULOG_ENTRY(upd, final).av_keydata.av_keydata_val = malloc(ent->n_key_data * sizeof (kdbe_key_t));
459 if (ULOG_ENTRY(upd, final).av_keydata.av_keydata_val == NULL) {
460 free(attr_types);
461 return (ENOMEM);
464 for (j = 0; j < ent->n_key_data; j++) {
465 ULOG_ENTRY_KEYVAL(upd, final, j).k_ver = ent->key_data[j].key_data_ver;
466 ULOG_ENTRY_KEYVAL(upd, final, j).k_kvno = ent->key_data[j].key_data_kvno;
467 ULOG_ENTRY_KEYVAL(upd, final, j).k_enctype.k_enctype_len = ent->key_data[j].key_data_ver;
468 ULOG_ENTRY_KEYVAL(upd, final, j).k_contents.k_contents_len = ent->key_data[j].key_data_ver;
470 ULOG_ENTRY_KEYVAL(upd, final, j).k_enctype.k_enctype_val = malloc(ent->key_data[j].key_data_ver * sizeof(int32_t));
471 if (ULOG_ENTRY_KEYVAL(upd, final, j).k_enctype.k_enctype_val == NULL) {
472 free(attr_types);
473 return (ENOMEM);
476 ULOG_ENTRY_KEYVAL(upd, final, j).k_contents.k_contents_val = malloc(ent->key_data[j].key_data_ver * sizeof(utf8str_t));
477 if (ULOG_ENTRY_KEYVAL(upd, final, j).k_contents.k_contents_val == NULL) {
478 free(attr_types);
479 return (ENOMEM);
482 for (cnt = 0; cnt < ent->key_data[j].key_data_ver; cnt++) {
483 ULOG_ENTRY_KEYVAL(upd, final, j).k_enctype.k_enctype_val[cnt] = ent->key_data[j].key_data_type[cnt];
484 ULOG_ENTRY_KEYVAL(upd, final, j).k_contents.k_contents_val[cnt].utf8str_t_len = ent->key_data[j].key_data_length[cnt];
485 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 if (ULOG_ENTRY_KEYVAL(upd, final, j).k_contents.k_contents_val[cnt].utf8str_t_val == NULL) {
487 free(attr_types);
488 return (ENOMEM);
490 (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]);
494 break;
496 case AT_TL_DATA:
497 ret = krb5_dbe_lookup_last_pwd_change(context,
498 ent, &tmpint);
499 if (ret == 0) {
500 ULOG_ENTRY_TYPE(upd, ++final).av_type =
501 AT_PW_LAST_CHANGE;
502 ULOG_ENTRY(upd, final).av_pw_last_change = tmpint;
504 tmpint = 0;
506 if(!(ret = krb5_dbe_lookup_mod_princ_data(
507 context, ent, &tmpint, &tmpprinc))) {
509 ULOG_ENTRY_TYPE(upd, ++final).av_type =
510 AT_MOD_PRINC;
512 ret = conv_princ_2ulog(tmpprinc,
513 upd, final, MOD_PRINC);
514 krb5_free_principal(context, tmpprinc);
515 if (ret) {
516 free(attr_types);
517 return (ret);
519 ULOG_ENTRY_TYPE(upd, ++final).av_type =
520 AT_MOD_TIME;
521 ULOG_ENTRY(upd, final).av_mod_time =
522 tmpint;
525 newtl = ent->tl_data;
526 while (newtl) {
527 switch (newtl->tl_data_type) {
528 case KRB5_TL_LAST_PWD_CHANGE:
529 case KRB5_TL_MOD_PRINC:
530 break;
532 case KRB5_TL_KADM_DATA:
533 default:
534 if (kadm_data_yes == 0) {
535 ULOG_ENTRY_TYPE(upd, ++final).av_type = AT_TL_DATA;
536 ULOG_ENTRY(upd, final).av_tldata.av_tldata_len = 0;
537 ULOG_ENTRY(upd, final).av_tldata.av_tldata_val = malloc(ent->n_tl_data * sizeof(kdbe_tl_t));
539 if (ULOG_ENTRY(upd, final).av_tldata.av_tldata_val == NULL) {
540 free(attr_types);
541 return (ENOMEM);
543 kadm_data_yes = 1;
546 tmpint = ULOG_ENTRY(upd, final).av_tldata.av_tldata_len;
547 ULOG_ENTRY(upd, final).av_tldata.av_tldata_len++;
548 ULOG_ENTRY(upd, final).av_tldata.av_tldata_val[tmpint].tl_type = newtl->tl_data_type;
549 ULOG_ENTRY(upd, final).av_tldata.av_tldata_val[tmpint].tl_data.tl_data_len = newtl->tl_data_length;
550 ULOG_ENTRY(upd, final).av_tldata.av_tldata_val[tmpint].tl_data.tl_data_val = malloc(newtl->tl_data_length * sizeof (char));
551 if (ULOG_ENTRY(upd, final).av_tldata.av_tldata_val[tmpint].tl_data.tl_data_val == NULL) {
552 free(attr_types);
553 return (ENOMEM);
555 (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);
556 break;
558 newtl = newtl->tl_data_next;
560 break;
561 /* END CSTYLED */
563 case AT_LEN:
564 ULOG_ENTRY_TYPE(upd, ++final).av_type =
565 AT_LEN;
566 ULOG_ENTRY(upd, final).av_len =
567 (int16_t)ent->len;
568 break;
570 default:
571 break;
576 free(attr_types);
579 * Update len field in kdb_update
581 upd->kdb_update.kdbe_t_len = ++final;
584 * Bump up to next struct
586 upd++;
587 ent++;
589 return (0);
593 * This routine converts one or more update log (ulog) entries into
594 * kerberos db2 records. Required memory should be allocated
595 * for the db2 records (pointed to by krb5_db_entry *ent), prior
596 * to calling this routine.
598 krb5_error_code
599 ulog_conv_2dbentry(krb5_context context, krb5_db_entry *entries,
600 kdb_incr_update_t *updates,
601 int nentries)
603 int k;
604 krb5_db_entry *ent;
605 kdb_incr_update_t *upd;
607 if ((updates == NULL) || (entries == NULL))
608 return (KRB5KRB_ERR_GENERIC);
610 ent = entries;
611 upd = updates;
613 for (k = 0; k < nentries; k++) {
614 krb5_principal mod_princ = NULL;
615 int i, j, cnt = 0, mod_time = 0, nattrs, nprincs = 0;
616 krb5_principal dbprinc;
617 char *dbprincstr = NULL;
619 krb5_tl_data *newtl = NULL;
620 krb5_error_code ret;
621 unsigned int more;
622 unsigned int prev_n_keys = 0;
625 * If the ulog entry represents a DELETE update,
626 * just skip to the next entry.
628 if (upd->kdb_deleted == TRUE)
629 goto next;
632 * Store the no. of changed attributes in nattrs
634 nattrs = upd->kdb_update.kdbe_t_len;
636 dbprincstr = malloc((upd->kdb_princ_name.utf8str_t_len + 1)
637 * sizeof (char));
638 if (dbprincstr == NULL)
639 return (ENOMEM);
640 strncpy(dbprincstr, (char *)upd->kdb_princ_name.utf8str_t_val,
641 upd->kdb_princ_name.utf8str_t_len);
642 dbprincstr[upd->kdb_princ_name.utf8str_t_len] = 0;
643 ret = krb5_parse_name(context, dbprincstr, &dbprinc);
644 free(dbprincstr);
645 if (ret)
646 return (ret);
648 ret = krb5_db_get_principal(context, dbprinc, ent, &nprincs,
649 &more);
650 krb5_free_principal(context, dbprinc);
651 if (ret)
652 return (ret);
655 * Set ent->n_tl_data = 0 initially, if this is an ADD update
657 if (nprincs == 0)
658 ent->n_tl_data = 0;
660 for (i = 0; i < nattrs; i++) {
661 krb5_principal tmpprinc = NULL;
663 #define u (ULOG_ENTRY(upd, i))
664 switch (ULOG_ENTRY_TYPE(upd, i).av_type) {
665 case AT_ATTRFLAGS:
666 ent->attributes = (krb5_flags) u.av_attrflags;
667 break;
669 case AT_MAX_LIFE:
670 ent->max_life = (krb5_deltat) u.av_max_life;
671 break;
673 case AT_MAX_RENEW_LIFE:
674 ent->max_renewable_life = (krb5_deltat) u.av_max_renew_life;
675 break;
677 case AT_EXP:
678 ent->expiration = (krb5_timestamp) u.av_exp;
679 break;
681 case AT_PW_EXP:
682 ent->pw_expiration = (krb5_timestamp) u.av_pw_exp;
683 break;
685 case AT_LAST_SUCCESS:
686 ent->last_success = (krb5_timestamp) u.av_last_success;
687 break;
689 case AT_LAST_FAILED:
690 ent->last_failed = (krb5_timestamp) u.av_last_failed;
691 break;
693 case AT_FAIL_AUTH_COUNT:
694 ent->fail_auth_count = (krb5_kvno) u.av_fail_auth_count;
695 break;
697 case AT_PRINC:
698 tmpprinc = conv_princ_2db(context, &u.av_princ);
699 if (tmpprinc == NULL)
700 return ENOMEM;
701 if (nprincs)
702 krb5_free_principal(context, ent->princ);
703 ent->princ = tmpprinc;
704 break;
706 case AT_KEYDATA:
708 if (nprincs != 0)
709 prev_n_keys = ent->n_key_data;
710 else
711 prev_n_keys = 0;
712 ent->n_key_data = (krb5_int16)u.av_keydata.av_keydata_len;
713 if (nprincs == 0)
714 ent->key_data = NULL;
716 ent->key_data = (krb5_key_data *)realloc(ent->key_data,
717 (ent->n_key_data *
718 sizeof (krb5_key_data)));
719 /* XXX Memory leak: Old key data in
720 records eliminated by resizing to
721 smaller size. */
722 if (ent->key_data == NULL)
723 /* XXX Memory leak: old storage. */
724 return (ENOMEM);
726 /* BEGIN CSTYLED */
727 for (j = prev_n_keys; j < ent->n_key_data; j++) {
728 for (cnt = 0; cnt < 2; cnt++) {
729 ent->key_data[j].key_data_contents[cnt] = NULL;
732 for (j = 0; j < ent->n_key_data; j++) {
733 krb5_key_data *kp = &ent->key_data[j];
734 kdbe_key_t *kv = &ULOG_ENTRY_KEYVAL(upd, i, j);
735 kp->key_data_ver = (krb5_int16)kv->k_ver;
736 kp->key_data_kvno = (krb5_int16)kv->k_kvno;
737 if (kp->key_data_ver > 2) {
738 return EINVAL; /* XXX ? */
741 for (cnt = 0; cnt < kp->key_data_ver; cnt++) {
742 void *newptr;
743 kp->key_data_type[cnt] = (krb5_int16)kv->k_enctype.k_enctype_val[cnt];
744 kp->key_data_length[cnt] = (krb5_int16)kv->k_contents.k_contents_val[cnt].utf8str_t_len;
745 newptr = realloc(kp->key_data_contents[cnt],
746 kp->key_data_length[cnt]);
747 if (newptr == NULL)
748 return ENOMEM;
749 kp->key_data_contents[cnt] = newptr;
751 (void) memset(kp->key_data_contents[cnt], 0,
752 kp->key_data_length[cnt]);
753 (void) memcpy(kp->key_data_contents[cnt],
754 kv->k_contents.k_contents_val[cnt].utf8str_t_val,
755 kp->key_data_length[cnt]);
758 break;
760 case AT_TL_DATA:
761 cnt = u.av_tldata.av_tldata_len;
762 newtl = malloc(cnt * sizeof (krb5_tl_data));
763 (void) memset(newtl, 0, (cnt * sizeof (krb5_tl_data)));
764 if (newtl == NULL)
765 return (ENOMEM);
767 for (j = 0; j < cnt; j++) {
768 newtl[j].tl_data_type = (krb5_int16)u.av_tldata.av_tldata_val[j].tl_type;
769 newtl[j].tl_data_length = (krb5_int16)u.av_tldata.av_tldata_val[j].tl_data.tl_data_len;
770 newtl[j].tl_data_contents = NULL;
771 newtl[j].tl_data_contents = malloc(newtl[j].tl_data_length * sizeof (krb5_octet));
772 if (newtl[j].tl_data_contents == NULL)
773 /* XXX Memory leak: newtl
774 and previously
775 allocated elements. */
776 return (ENOMEM);
778 (void) memset(newtl[j].tl_data_contents, 0, (newtl[j].tl_data_length * sizeof (krb5_octet)));
779 (void) memcpy(newtl[j].tl_data_contents, u.av_tldata.av_tldata_val[j].tl_data.tl_data_val, newtl[j].tl_data_length);
780 newtl[j].tl_data_next = NULL;
781 if (j > 0)
782 newtl[j - 1].tl_data_next = &newtl[j];
785 if ((ret = krb5_dbe_update_tl_data(context, ent, newtl)))
786 return (ret);
787 for (j = 0; j < cnt; j++)
788 if (newtl[j].tl_data_contents) {
789 free(newtl[j].tl_data_contents);
790 newtl[j].tl_data_contents = NULL;
792 if (newtl) {
793 free(newtl);
794 newtl = NULL;
796 break;
797 /* END CSTYLED */
799 case AT_PW_LAST_CHANGE:
800 if ((ret = krb5_dbe_update_last_pwd_change(context, ent,
801 u.av_pw_last_change)))
802 return (ret);
803 break;
805 case AT_MOD_PRINC:
806 tmpprinc = conv_princ_2db(context, &u.av_mod_princ);
807 if (tmpprinc == NULL)
808 return ENOMEM;
809 mod_princ = tmpprinc;
810 break;
812 case AT_MOD_TIME:
813 mod_time = u.av_mod_time;
814 break;
816 case AT_LEN:
817 ent->len = (krb5_int16) u.av_len;
818 break;
820 default:
821 break;
823 #undef u
827 * process mod_princ_data request
829 if (mod_time && mod_princ) {
830 ret = krb5_dbe_update_mod_princ_data(context, ent,
831 mod_time, mod_princ);
832 krb5_free_principal(context, mod_princ);
833 mod_princ = NULL;
834 if (ret)
835 return (ret);
838 next:
840 * Bump up to next struct
842 upd++;
843 ent++;
845 return (0);
851 * This routine frees up memory associated with the bunched ulog entries.
853 void
854 ulog_free_entries(kdb_incr_update_t *updates, int no_of_updates)
857 kdb_incr_update_t *upd;
858 int i, j, k, cnt;
860 if (updates == NULL)
861 return;
863 upd = updates;
866 * Loop thru each ulog entry
868 for (cnt = 0; cnt < no_of_updates; cnt++) {
871 * ulog entry - kdb_princ_name
873 free(upd->kdb_princ_name.utf8str_t_val);
875 /* BEGIN CSTYLED */
878 * ulog entry - kdb_kdcs_seen_by
880 if (upd->kdb_kdcs_seen_by.kdb_kdcs_seen_by_val) {
881 for (i = 0; i < upd->kdb_kdcs_seen_by.kdb_kdcs_seen_by_len; i++)
882 free(upd->kdb_kdcs_seen_by.kdb_kdcs_seen_by_val[i].utf8str_t_val);
883 free(upd->kdb_kdcs_seen_by.kdb_kdcs_seen_by_val);
887 * ulog entry - kdb_futures
889 free(upd->kdb_futures.kdb_futures_val);
892 * ulog entry - kdb_update
894 if (upd->kdb_update.kdbe_t_val) {
896 * Loop thru all the attributes and free up stuff
898 for (i = 0; i < upd->kdb_update.kdbe_t_len; i++) {
901 * Free av_key_data
903 if ((ULOG_ENTRY_TYPE(upd, i).av_type == AT_KEYDATA) && ULOG_ENTRY(upd, i).av_keydata.av_keydata_val) {
905 for (j = 0; j < ULOG_ENTRY(upd, i).av_keydata.av_keydata_len; j++) {
906 free(ULOG_ENTRY_KEYVAL(upd, i, j).k_enctype.k_enctype_val);
907 if (ULOG_ENTRY_KEYVAL(upd, i, j).k_contents.k_contents_val) {
908 for (k = 0; k < ULOG_ENTRY_KEYVAL(upd, i, j).k_ver; k++) {
909 free(ULOG_ENTRY_KEYVAL(upd, i, j).k_contents.k_contents_val[k].utf8str_t_val);
911 free(ULOG_ENTRY_KEYVAL(upd, i, j).k_contents.k_contents_val);
914 free(ULOG_ENTRY(upd, i).av_keydata.av_keydata_val);
919 * Free av_tl_data
921 if ((ULOG_ENTRY_TYPE(upd, i).av_type == AT_TL_DATA) && ULOG_ENTRY(upd, i).av_tldata.av_tldata_val) {
922 for (j = 0; j < ULOG_ENTRY(upd, i).av_tldata.av_tldata_len; j++) {
923 free(ULOG_ENTRY(upd, i).av_tldata.av_tldata_val[j].tl_data.tl_data_val);
925 free(ULOG_ENTRY(upd, i).av_tldata.av_tldata_val);
929 * Free av_princ
931 if (ULOG_ENTRY_TYPE(upd, i).av_type == AT_PRINC) {
932 free(ULOG_ENTRY(upd, i).av_princ.k_realm.utf8str_t_val);
933 if (ULOG_ENTRY(upd, i).av_princ.k_components.k_components_val) {
934 for (j = 0; j < ULOG_ENTRY(upd, i).av_princ.k_components.k_components_len; j++) {
935 free(ULOG_ENTRY_PRINC(upd, i, j).k_data.utf8str_t_val);
937 free(ULOG_ENTRY(upd, i).av_princ.k_components.k_components_val);
942 * Free av_mod_princ
944 if (ULOG_ENTRY_TYPE(upd, i).av_type == AT_MOD_PRINC) {
945 free(ULOG_ENTRY(upd, i).av_mod_princ.k_realm.utf8str_t_val);
946 if (ULOG_ENTRY(upd, i).av_mod_princ.k_components.k_components_val) {
947 for (j = 0; j < ULOG_ENTRY(upd, i).av_mod_princ.k_components.k_components_len; j++) {
948 free(ULOG_ENTRY_MOD_PRINC(upd, i, j).k_data.utf8str_t_val);
950 free(ULOG_ENTRY(upd, i).av_mod_princ.k_components.k_components_val);
955 * Free av_mod_where
957 if ((ULOG_ENTRY_TYPE(upd, i).av_type == AT_MOD_WHERE))
958 free(ULOG_ENTRY(upd, i).av_mod_where.utf8str_t_val);
961 * Free av_pw_policy
963 if ((ULOG_ENTRY_TYPE(upd, i).av_type == AT_PW_POLICY))
964 free(ULOG_ENTRY(upd, i).av_pw_policy.utf8str_t_val);
967 * XXX: Free av_pw_hist
969 * For now, we just free the pointer
970 * to av_pw_hist_val, since we aren't
971 * populating this union member in
972 * the conv api function(s) anyways.
974 if ((ULOG_ENTRY_TYPE(upd, i).av_type == AT_PW_HIST))
975 free(ULOG_ENTRY(upd, i).av_pw_hist.av_pw_hist_val);
980 * Free up the pointer to kdbe_t_val
982 free(upd->kdb_update.kdbe_t_val);
985 /* END CSTYLED */
988 * Bump up to next struct
990 upd++;
995 * Finally, free up the pointer to the bunched ulog entries
997 free(updates);