Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/krb5/src/lib/kdb/kdb_convert.c
39566 views
1
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
/*
3
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
4
* Use is subject to license terms.
5
*/
6
7
/* #pragma ident "@(#)kdb_convert.c 1.3 05/01/05 SMI" */
8
9
/*
10
* This file contains api's for conversion of the kdb_incr_update_t
11
* struct(s) into krb5_db_entry struct(s) and vice-versa.
12
*/
13
#include <k5-int.h>
14
#include <sys/types.h>
15
#include <com_err.h>
16
#include <locale.h>
17
#include <iprop_hdr.h>
18
#include "iprop.h"
19
#include <kdb.h>
20
#include <kdb_log.h>
21
22
/* BEGIN CSTYLED */
23
#define ULOG_ENTRY_TYPE(upd, i) ((kdb_incr_update_t *)upd)->kdb_update.kdbe_t_val[i]
24
25
#define ULOG_ENTRY(upd, i) ((kdb_incr_update_t *)upd)->kdb_update.kdbe_t_val[i].kdbe_val_t_u
26
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]
28
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]
30
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]
32
/* END CSTYLED */
33
34
typedef enum {
35
REG_PRINC = 0,
36
MOD_PRINC = 1
37
} princ_type;
38
39
40
/*
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)
43
* in the update.
44
*/
45
static void
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)
49
{
50
int i = 0, j = 0;
51
52
krb5_tl_data *first, *second;
53
54
if (current->attributes != new->attributes)
55
attrs[i++] = AT_ATTRFLAGS;
56
57
if (current->max_life != new->max_life)
58
attrs[i++] = AT_MAX_LIFE;
59
60
if (current->max_renewable_life != new->max_renewable_life)
61
attrs[i++] = AT_MAX_RENEW_LIFE;
62
63
if (current->expiration != new->expiration)
64
attrs[i++] = AT_EXP;
65
66
if (current->pw_expiration != new->pw_expiration)
67
attrs[i++] = AT_PW_EXP;
68
69
if (!exclude_nra) {
70
if (current->last_success != new->last_success)
71
attrs[i++] = AT_LAST_SUCCESS;
72
73
if (current->last_failed != new->last_failed)
74
attrs[i++] = AT_LAST_FAILED;
75
76
if (current->fail_auth_count != new->fail_auth_count)
77
attrs[i++] = AT_FAIL_AUTH_COUNT;
78
}
79
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;
93
break;
94
}
95
}
96
} else {
97
attrs[i++] = AT_PRINC;
98
}
99
} else {
100
attrs[i++] = AT_PRINC;
101
}
102
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;
109
break;
110
}
111
}
112
} else {
113
attrs[i++] = AT_KEYDATA;
114
}
115
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;
127
break;
128
}
129
} else {
130
attrs[i++] = AT_TL_DATA;
131
break;
132
}
133
}
134
} else {
135
attrs[i++] = AT_TL_DATA;
136
}
137
138
if (current->len != new->len)
139
attrs[i++] = AT_LEN;
140
/*
141
* Store the no. of (possibly :)) changed attributes
142
*/
143
*nattrs = i;
144
}
145
146
147
/* Initialize *u with a copy of d. Return 0 on success, -1 on failure. */
148
static int
149
data_to_utf8str(utf8str_t *u, krb5_data d)
150
{
151
u->utf8str_t_len = d.length;
152
if (d.data) {
153
u->utf8str_t_val = malloc(d.length);
154
if (u->utf8str_t_val == NULL)
155
return -1;
156
memcpy(u->utf8str_t_val, d.data, d.length);
157
} else
158
u->utf8str_t_val = NULL;
159
return 0;
160
}
161
162
/*
163
* Converts the krb5_principal struct from db2 to ulog format.
164
*/
165
static krb5_error_code
166
conv_princ_2ulog(krb5_principal princ, kdb_incr_update_t *upd,
167
int cnt, princ_type tp)
168
{
169
int i = 0;
170
kdbe_princ_t *p;
171
kdbe_data_t *components;
172
173
if ((upd == NULL) || !princ)
174
return (KRB5KRB_ERR_GENERIC);
175
176
switch (tp) {
177
case REG_PRINC:
178
case MOD_PRINC:
179
p = &ULOG_ENTRY(upd, cnt).av_princ; /* or av_mod_princ */
180
p->k_nametype = (int32_t)princ->type;
181
182
if (data_to_utf8str(&p->k_realm, princ->realm) < 0) {
183
return ENOMEM;
184
}
185
186
p->k_components.k_components_len = princ->length;
187
188
p->k_components.k_components_val = components
189
= malloc(princ->length * sizeof (kdbe_data_t));
190
if (p->k_components.k_components_val == NULL) {
191
free(p->k_realm.utf8str_t_val);
192
p->k_realm.utf8str_t_val = NULL;
193
return (ENOMEM);
194
}
195
196
memset(components, 0, princ->length * sizeof(kdbe_data_t));
197
for (i = 0; i < princ->length; i++)
198
components[i].k_data.utf8str_t_val = NULL;
199
for (i = 0; i < princ->length; i++) {
200
components[i].k_magic = princ->data[i].magic;
201
if (data_to_utf8str(&components[i].k_data, princ->data[i]) < 0) {
202
int j;
203
for (j = 0; j < i; j++) {
204
free(components[j].k_data.utf8str_t_val);
205
components[j].k_data.utf8str_t_val = NULL;
206
}
207
free(components);
208
p->k_components.k_components_val = NULL;
209
free(p->k_realm.utf8str_t_val);
210
p->k_realm.utf8str_t_val = NULL;
211
return ENOMEM;
212
}
213
}
214
break;
215
216
default:
217
break;
218
}
219
return (0);
220
}
221
222
/*
223
* Copies a UTF-8 string from ulog to a krb5_data object, which may
224
* already have allocated storage associated with it.
225
*
226
* Maybe a return value should indicate success/failure?
227
*/
228
static void
229
set_from_utf8str(krb5_data *d, utf8str_t u)
230
{
231
if (u.utf8str_t_len > INT_MAX - 1) {
232
d->data = NULL;
233
return;
234
}
235
d->length = u.utf8str_t_len;
236
d->data = malloc(d->length + 1);
237
if (d->data == NULL)
238
return;
239
if (d->length) /* Pointer may be null if length = 0. */
240
strncpy(d->data, u.utf8str_t_val, d->length);
241
d->data[d->length] = 0;
242
}
243
244
/*
245
* Converts the krb5_principal struct from ulog to db2 format.
246
*/
247
static krb5_principal
248
conv_princ_2db(krb5_context context, kdbe_princ_t *kdbe_princ)
249
{
250
unsigned int i;
251
int j;
252
krb5_principal princ;
253
kdbe_data_t *components;
254
255
princ = calloc(1, sizeof (krb5_principal_data));
256
if (princ == NULL) {
257
return NULL;
258
}
259
princ->length = 0;
260
princ->data = NULL;
261
262
components = kdbe_princ->k_components.k_components_val;
263
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)
268
goto error;
269
270
princ->data = calloc(kdbe_princ->k_components.k_components_len,
271
sizeof (krb5_data));
272
if (princ->data == NULL)
273
goto error;
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;
277
278
for (j = 0; j < princ->length; j++) {
279
princ->data[j].magic = components[j].k_magic;
280
set_from_utf8str(&princ->data[j], components[j].k_data);
281
if (princ->data[j].data == NULL)
282
goto error;
283
}
284
285
return princ;
286
error:
287
krb5_free_principal(context, princ);
288
return NULL;
289
}
290
291
292
/*
293
* This routine converts a krb5 DB record into update log (ulog) entry format.
294
* Space for the update log entry should be allocated prior to invocation of
295
* this routine.
296
*/
297
krb5_error_code
298
ulog_conv_2logentry(krb5_context context, krb5_db_entry *entry,
299
kdb_incr_update_t *update)
300
{
301
int i, j, cnt, final, nattrs, tmpint;
302
krb5_principal tmpprinc;
303
krb5_tl_data *newtl;
304
krb5_db_entry *curr;
305
krb5_error_code ret;
306
kdbe_attr_type_t *attr_types;
307
int kadm_data_yes;
308
309
nattrs = tmpint = 0;
310
final = -1;
311
kadm_data_yes = 0;
312
attr_types = NULL;
313
314
/*
315
* XXX we rely on the good behaviour of the database not to
316
* exceed this limit.
317
*/
318
if ((update->kdb_update.kdbe_t_val = (kdbe_val_t *)
319
malloc(MAXENTRY_SIZE)) == NULL) {
320
return (ENOMEM);
321
}
322
323
/*
324
* Find out which attrs have been modified
325
*/
326
if ((attr_types = (kdbe_attr_type_t *)malloc(
327
sizeof (kdbe_attr_type_t) * MAXATTRS_SIZE))
328
== NULL) {
329
return (ENOMEM);
330
}
331
332
ret = krb5_db_get_principal(context, entry->princ, 0, &curr);
333
if (ret && ret != KRB5_KDB_NOENTRY) {
334
free(attr_types);
335
return (ret);
336
}
337
338
if (ret == KRB5_KDB_NOENTRY) {
339
/*
340
* This is a new entry to the database, hence will
341
* include all the attribute-value pairs
342
*
343
* We leave out the TL_DATA types which we model as
344
* attrs in kdbe_attr_type_t, since listing AT_TL_DATA
345
* encompasses these other types-turned-attributes
346
*
347
* So, we do *NOT* consider AT_MOD_PRINC, AT_MOD_TIME,
348
* AT_MOD_WHERE, AT_PW_LAST_CHANGE, AT_PW_POLICY,
349
* AT_PW_POLICY_SWITCH, AT_PW_HIST_KVNO and AT_PW_HIST,
350
* totalling 8 attrs.
351
*/
352
while (nattrs < MAXATTRS_SIZE - 8) {
353
attr_types[nattrs] = nattrs;
354
nattrs++;
355
}
356
} else {
357
/* Always exclude non-replicated attributes for now. */
358
find_changed_attrs(curr, entry, TRUE, attr_types, &nattrs);
359
krb5_db_free_principal(context, curr);
360
}
361
362
for (i = 0; i < nattrs; i++) {
363
switch (attr_types[i]) {
364
case AT_ATTRFLAGS:
365
if (entry->attributes >= 0) {
366
ULOG_ENTRY_TYPE(update, ++final).av_type =
367
AT_ATTRFLAGS;
368
ULOG_ENTRY(update, final).av_attrflags =
369
(uint32_t)entry->attributes;
370
}
371
break;
372
373
case AT_MAX_LIFE:
374
if (entry->max_life >= 0) {
375
ULOG_ENTRY_TYPE(update, ++final).av_type = AT_MAX_LIFE;
376
ULOG_ENTRY(update, final).av_max_life =
377
(uint32_t)entry->max_life;
378
}
379
break;
380
381
case AT_MAX_RENEW_LIFE:
382
if (entry->max_renewable_life >= 0) {
383
ULOG_ENTRY_TYPE(update, ++final).av_type = AT_MAX_RENEW_LIFE;
384
ULOG_ENTRY(update, final).av_max_renew_life =
385
(uint32_t)entry->max_renewable_life;
386
}
387
break;
388
389
case AT_EXP:
390
if (entry->expiration >= 0) {
391
ULOG_ENTRY_TYPE(update, ++final).av_type = AT_EXP;
392
ULOG_ENTRY(update, final).av_exp = (uint32_t)entry->expiration;
393
}
394
break;
395
396
case AT_PW_EXP:
397
if (entry->pw_expiration >= 0) {
398
ULOG_ENTRY_TYPE(update, ++final).av_type = AT_PW_EXP;
399
ULOG_ENTRY(update, final).av_pw_exp =
400
(uint32_t)entry->pw_expiration;
401
}
402
break;
403
404
case AT_PRINC:
405
if (entry->princ->length > 0) {
406
ULOG_ENTRY_TYPE(update, ++final).av_type = AT_PRINC;
407
if ((ret = conv_princ_2ulog(entry->princ,
408
update, final, REG_PRINC))) {
409
free(attr_types);
410
return (ret);
411
}
412
}
413
break;
414
415
case AT_KEYDATA:
416
/* BEGIN CSTYLED */
417
if (entry->n_key_data >= 0) {
418
ULOG_ENTRY_TYPE(update, ++final).av_type = AT_KEYDATA;
419
ULOG_ENTRY(update, final).av_keydata.av_keydata_len =
420
entry->n_key_data;
421
ULOG_ENTRY(update, final).av_keydata.av_keydata_val =
422
malloc(entry->n_key_data * sizeof (kdbe_key_t));
423
if (ULOG_ENTRY(update, final).av_keydata.av_keydata_val ==
424
NULL) {
425
free(attr_types);
426
return (ENOMEM);
427
}
428
429
for (j = 0; j < entry->n_key_data; j++) {
430
ULOG_ENTRY_KEYVAL(update, final, j).k_ver =
431
entry->key_data[j].key_data_ver;
432
ULOG_ENTRY_KEYVAL(update, final, j).k_kvno =
433
entry->key_data[j].key_data_kvno;
434
ULOG_ENTRY_KEYVAL(update, final, j).k_enctype.k_enctype_len = entry->key_data[j].key_data_ver;
435
ULOG_ENTRY_KEYVAL(update, final, j).k_contents.k_contents_len = entry->key_data[j].key_data_ver;
436
437
ULOG_ENTRY_KEYVAL(update, final, j).k_enctype.k_enctype_val = malloc(entry->key_data[j].key_data_ver * sizeof(int32_t));
438
if (ULOG_ENTRY_KEYVAL(update, final, j).k_enctype.k_enctype_val == NULL) {
439
free(attr_types);
440
return (ENOMEM);
441
}
442
443
ULOG_ENTRY_KEYVAL(update, final, j).k_contents.k_contents_val = malloc(entry->key_data[j].key_data_ver * sizeof(utf8str_t));
444
if (ULOG_ENTRY_KEYVAL(update, final, j).k_contents.k_contents_val == NULL) {
445
free(attr_types);
446
return (ENOMEM);
447
}
448
449
for (cnt = 0; cnt < entry->key_data[j].key_data_ver;
450
cnt++) {
451
ULOG_ENTRY_KEYVAL(update, final, j).k_enctype.k_enctype_val[cnt] = entry->key_data[j].key_data_type[cnt];
452
ULOG_ENTRY_KEYVAL(update, final, j).k_contents.k_contents_val[cnt].utf8str_t_len = entry->key_data[j].key_data_length[cnt];
453
ULOG_ENTRY_KEYVAL(update, final, j).k_contents.k_contents_val[cnt].utf8str_t_val = malloc(entry->key_data[j].key_data_length[cnt] * sizeof (char));
454
if (ULOG_ENTRY_KEYVAL(update, final, j).k_contents.k_contents_val[cnt].utf8str_t_val == NULL) {
455
free(attr_types);
456
return (ENOMEM);
457
}
458
(void) memcpy(ULOG_ENTRY_KEYVAL(update, final, j).k_contents.k_contents_val[cnt].utf8str_t_val, entry->key_data[j].key_data_contents[cnt], entry->key_data[j].key_data_length[cnt]);
459
}
460
}
461
}
462
break;
463
464
case AT_TL_DATA:
465
ret = krb5_dbe_lookup_last_pwd_change(context, entry, &tmpint);
466
if (ret == 0) {
467
ULOG_ENTRY_TYPE(update, ++final).av_type = AT_PW_LAST_CHANGE;
468
ULOG_ENTRY(update, final).av_pw_last_change = tmpint;
469
}
470
tmpint = 0;
471
472
if(!(ret = krb5_dbe_lookup_mod_princ_data(context, entry, &tmpint,
473
&tmpprinc))) {
474
475
ULOG_ENTRY_TYPE(update, ++final).av_type = AT_MOD_PRINC;
476
477
ret = conv_princ_2ulog(tmpprinc, update, final, MOD_PRINC);
478
krb5_free_principal(context, tmpprinc);
479
if (ret) {
480
free(attr_types);
481
return (ret);
482
}
483
ULOG_ENTRY_TYPE(update, ++final).av_type = AT_MOD_TIME;
484
ULOG_ENTRY(update, final).av_mod_time =
485
tmpint;
486
}
487
488
newtl = entry->tl_data;
489
while (newtl) {
490
switch (newtl->tl_data_type) {
491
case KRB5_TL_LAST_PWD_CHANGE:
492
case KRB5_TL_MOD_PRINC:
493
break;
494
495
case KRB5_TL_KADM_DATA:
496
default:
497
if (kadm_data_yes == 0) {
498
ULOG_ENTRY_TYPE(update, ++final).av_type = AT_TL_DATA;
499
ULOG_ENTRY(update, final).av_tldata.av_tldata_len = 0;
500
ULOG_ENTRY(update, final).av_tldata.av_tldata_val =
501
malloc(entry->n_tl_data * sizeof(kdbe_tl_t));
502
503
if (ULOG_ENTRY(update, final).av_tldata.av_tldata_val
504
== NULL) {
505
free(attr_types);
506
return (ENOMEM);
507
}
508
kadm_data_yes = 1;
509
}
510
511
tmpint = ULOG_ENTRY(update, final).av_tldata.av_tldata_len;
512
ULOG_ENTRY(update, final).av_tldata.av_tldata_len++;
513
ULOG_ENTRY(update, final).av_tldata.av_tldata_val[tmpint].tl_type = newtl->tl_data_type;
514
ULOG_ENTRY(update, final).av_tldata.av_tldata_val[tmpint].tl_data.tl_data_len = newtl->tl_data_length;
515
ULOG_ENTRY(update, final).av_tldata.av_tldata_val[tmpint].tl_data.tl_data_val = malloc(newtl->tl_data_length * sizeof (char));
516
if (ULOG_ENTRY(update, final).av_tldata.av_tldata_val[tmpint].tl_data.tl_data_val == NULL) {
517
free(attr_types);
518
return (ENOMEM);
519
}
520
(void) memcpy(ULOG_ENTRY(update, final).av_tldata.av_tldata_val[tmpint].tl_data.tl_data_val, newtl->tl_data_contents, newtl->tl_data_length);
521
break;
522
}
523
newtl = newtl->tl_data_next;
524
}
525
break;
526
/* END CSTYLED */
527
528
case AT_LEN:
529
ULOG_ENTRY_TYPE(update, ++final).av_type = AT_LEN;
530
ULOG_ENTRY(update, final).av_len = (int16_t)entry->len;
531
break;
532
533
default:
534
break;
535
}
536
537
}
538
539
free(attr_types);
540
541
/*
542
* Update len field in kdb_update
543
*/
544
update->kdb_update.kdbe_t_len = ++final;
545
return (0);
546
}
547
548
/* Convert an update log (ulog) entry into a kerberos record. */
549
krb5_error_code
550
ulog_conv_2dbentry(krb5_context context, krb5_db_entry **entry,
551
kdb_incr_update_t *update)
552
{
553
krb5_db_entry *ent = NULL;
554
int replica;
555
krb5_principal mod_princ = NULL;
556
int i, j, cnt = 0, mod_time = 0, nattrs;
557
krb5_principal dbprinc;
558
char *dbprincstr = NULL;
559
krb5_tl_data newtl;
560
krb5_error_code ret;
561
unsigned int prev_n_keys = 0;
562
krb5_boolean is_add;
563
void *newptr;
564
565
*entry = NULL;
566
567
replica = (context->kdblog_context != NULL) &&
568
(context->kdblog_context->iproprole == IPROP_REPLICA);
569
570
/*
571
* Store the no. of changed attributes in nattrs
572
*/
573
nattrs = update->kdb_update.kdbe_t_len;
574
575
dbprincstr = k5memdup0(update->kdb_princ_name.utf8str_t_val,
576
update->kdb_princ_name.utf8str_t_len, &ret);
577
if (dbprincstr == NULL)
578
goto cleanup;
579
580
ret = krb5_parse_name(context, dbprincstr, &dbprinc);
581
free(dbprincstr);
582
if (ret)
583
goto cleanup;
584
585
ret = krb5_db_get_principal(context, dbprinc, 0, &ent);
586
krb5_free_principal(context, dbprinc);
587
if (ret && ret != KRB5_KDB_NOENTRY)
588
goto cleanup;
589
is_add = (ret == KRB5_KDB_NOENTRY);
590
591
/*
592
* Set ent->n_tl_data = 0 initially, if this is an ADD update
593
*/
594
if (is_add) {
595
ent = calloc(1, sizeof(*ent));
596
if (ent == NULL)
597
return (ENOMEM);
598
ent->n_tl_data = 0;
599
}
600
601
for (i = 0; i < nattrs; i++) {
602
krb5_principal tmpprinc = NULL;
603
604
#define u (ULOG_ENTRY(update, i))
605
switch (ULOG_ENTRY_TYPE(update, i).av_type) {
606
case AT_ATTRFLAGS:
607
ent->attributes = (krb5_flags) u.av_attrflags;
608
break;
609
610
case AT_MAX_LIFE:
611
ent->max_life = (krb5_deltat) u.av_max_life;
612
break;
613
614
case AT_MAX_RENEW_LIFE:
615
ent->max_renewable_life = (krb5_deltat) u.av_max_renew_life;
616
break;
617
618
case AT_EXP:
619
ent->expiration = (krb5_timestamp) u.av_exp;
620
break;
621
622
case AT_PW_EXP:
623
ent->pw_expiration = (krb5_timestamp) u.av_pw_exp;
624
break;
625
626
case AT_LAST_SUCCESS:
627
if (!replica)
628
ent->last_success = (krb5_timestamp) u.av_last_success;
629
break;
630
631
case AT_LAST_FAILED:
632
if (!replica)
633
ent->last_failed = (krb5_timestamp) u.av_last_failed;
634
break;
635
636
case AT_FAIL_AUTH_COUNT:
637
if (!replica)
638
ent->fail_auth_count = (krb5_kvno) u.av_fail_auth_count;
639
break;
640
641
case AT_PRINC:
642
tmpprinc = conv_princ_2db(context, &u.av_princ);
643
if (tmpprinc == NULL) {
644
ret = ENOMEM;
645
goto cleanup;
646
}
647
krb5_free_principal(context, ent->princ);
648
ent->princ = tmpprinc;
649
break;
650
651
case AT_KEYDATA:
652
if (!is_add)
653
prev_n_keys = ent->n_key_data;
654
else
655
prev_n_keys = 0;
656
ent->n_key_data = (krb5_int16)u.av_keydata.av_keydata_len;
657
if (is_add)
658
ent->key_data = NULL;
659
660
/* Allocate one extra key data to avoid allocating zero bytes. */
661
newptr = realloc(ent->key_data, (ent->n_key_data + 1) *
662
sizeof(krb5_key_data));
663
if (newptr == NULL) {
664
ret = ENOMEM;
665
goto cleanup;
666
}
667
ent->key_data = newptr;
668
669
/* BEGIN CSTYLED */
670
for (j = prev_n_keys; j < ent->n_key_data; j++) {
671
for (cnt = 0; cnt < 2; cnt++) {
672
ent->key_data[j].key_data_contents[cnt] = NULL;
673
}
674
}
675
for (j = 0; j < ent->n_key_data; j++) {
676
krb5_key_data *kp = &ent->key_data[j];
677
kdbe_key_t *kv = &ULOG_ENTRY_KEYVAL(update, i, j);
678
kp->key_data_ver = (krb5_int16)kv->k_ver;
679
kp->key_data_kvno = (krb5_ui_2)kv->k_kvno;
680
if (kp->key_data_ver > 2) {
681
ret = EINVAL; /* XXX ? */
682
goto cleanup;
683
}
684
685
for (cnt = 0; cnt < kp->key_data_ver; cnt++) {
686
kp->key_data_type[cnt] = (krb5_int16)kv->k_enctype.k_enctype_val[cnt];
687
kp->key_data_length[cnt] = (krb5_int16)kv->k_contents.k_contents_val[cnt].utf8str_t_len;
688
newptr = realloc(kp->key_data_contents[cnt],
689
kp->key_data_length[cnt]);
690
if (newptr == NULL) {
691
ret = ENOMEM;
692
goto cleanup;
693
}
694
kp->key_data_contents[cnt] = newptr;
695
696
(void) memset(kp->key_data_contents[cnt], 0,
697
kp->key_data_length[cnt]);
698
(void) memcpy(kp->key_data_contents[cnt],
699
kv->k_contents.k_contents_val[cnt].utf8str_t_val,
700
kp->key_data_length[cnt]);
701
}
702
}
703
break;
704
705
case AT_TL_DATA: {
706
for (j = 0; j < (int)u.av_tldata.av_tldata_len; j++) {
707
newtl.tl_data_type = (krb5_int16)u.av_tldata.av_tldata_val[j].tl_type;
708
newtl.tl_data_length = (krb5_int16)u.av_tldata.av_tldata_val[j].tl_data.tl_data_len;
709
newtl.tl_data_contents = (krb5_octet *)u.av_tldata.av_tldata_val[j].tl_data.tl_data_val;
710
newtl.tl_data_next = NULL;
711
ret = krb5_dbe_update_tl_data(context, ent, &newtl);
712
if (ret)
713
goto cleanup;
714
}
715
break;
716
/* END CSTYLED */
717
}
718
case AT_PW_LAST_CHANGE:
719
ret = krb5_dbe_update_last_pwd_change(context, ent,
720
u.av_pw_last_change);
721
if (ret)
722
goto cleanup;
723
break;
724
725
case AT_MOD_PRINC:
726
tmpprinc = conv_princ_2db(context, &u.av_mod_princ);
727
if (tmpprinc == NULL) {
728
ret = ENOMEM;
729
goto cleanup;
730
}
731
mod_princ = tmpprinc;
732
break;
733
734
case AT_MOD_TIME:
735
mod_time = u.av_mod_time;
736
break;
737
738
case AT_LEN:
739
ent->len = (krb5_int16) u.av_len;
740
break;
741
742
default:
743
break;
744
}
745
#undef u
746
}
747
748
/*
749
* process mod_princ_data request
750
*/
751
if (mod_time && mod_princ) {
752
ret = krb5_dbe_update_mod_princ_data(context, ent,
753
mod_time, mod_princ);
754
if (ret)
755
goto cleanup;
756
}
757
758
*entry = ent;
759
ent = NULL;
760
ret = 0;
761
cleanup:
762
krb5_db_free_principal(context, ent);
763
krb5_free_principal(context, mod_princ);
764
return ret;
765
}
766
767
768
769
/*
770
* This routine frees up memory associated with the bunched ulog entries.
771
*/
772
void
773
ulog_free_entries(kdb_incr_update_t *updates, int no_of_updates)
774
{
775
776
kdb_incr_update_t *upd;
777
unsigned int i, j;
778
int k, cnt;
779
780
if (updates == NULL)
781
return;
782
783
upd = updates;
784
785
/*
786
* Loop thru each ulog entry
787
*/
788
for (cnt = 0; cnt < no_of_updates; cnt++) {
789
790
/*
791
* ulog entry - kdb_princ_name
792
*/
793
free(upd->kdb_princ_name.utf8str_t_val);
794
795
/* BEGIN CSTYLED */
796
797
/*
798
* ulog entry - kdb_kdcs_seen_by
799
*/
800
if (upd->kdb_kdcs_seen_by.kdb_kdcs_seen_by_val) {
801
for (i = 0; i < upd->kdb_kdcs_seen_by.kdb_kdcs_seen_by_len; i++)
802
free(upd->kdb_kdcs_seen_by.kdb_kdcs_seen_by_val[i].utf8str_t_val);
803
free(upd->kdb_kdcs_seen_by.kdb_kdcs_seen_by_val);
804
}
805
806
/*
807
* ulog entry - kdb_futures
808
*/
809
free(upd->kdb_futures.kdb_futures_val);
810
811
/*
812
* ulog entry - kdb_update
813
*/
814
if (upd->kdb_update.kdbe_t_val) {
815
/*
816
* Loop thru all the attributes and free up stuff
817
*/
818
for (i = 0; i < upd->kdb_update.kdbe_t_len; i++) {
819
820
/*
821
* Free av_key_data
822
*/
823
if ((ULOG_ENTRY_TYPE(upd, i).av_type == AT_KEYDATA) && ULOG_ENTRY(upd, i).av_keydata.av_keydata_val) {
824
825
for (j = 0; j < ULOG_ENTRY(upd, i).av_keydata.av_keydata_len; j++) {
826
free(ULOG_ENTRY_KEYVAL(upd, i, j).k_enctype.k_enctype_val);
827
if (ULOG_ENTRY_KEYVAL(upd, i, j).k_contents.k_contents_val) {
828
for (k = 0; k < ULOG_ENTRY_KEYVAL(upd, i, j).k_ver; k++) {
829
free(ULOG_ENTRY_KEYVAL(upd, i, j).k_contents.k_contents_val[k].utf8str_t_val);
830
}
831
free(ULOG_ENTRY_KEYVAL(upd, i, j).k_contents.k_contents_val);
832
}
833
}
834
free(ULOG_ENTRY(upd, i).av_keydata.av_keydata_val);
835
}
836
837
838
/*
839
* Free av_tl_data
840
*/
841
if ((ULOG_ENTRY_TYPE(upd, i).av_type == AT_TL_DATA) && ULOG_ENTRY(upd, i).av_tldata.av_tldata_val) {
842
for (j = 0; j < ULOG_ENTRY(upd, i).av_tldata.av_tldata_len; j++) {
843
free(ULOG_ENTRY(upd, i).av_tldata.av_tldata_val[j].tl_data.tl_data_val);
844
}
845
free(ULOG_ENTRY(upd, i).av_tldata.av_tldata_val);
846
}
847
848
/*
849
* Free av_princ
850
*/
851
if (ULOG_ENTRY_TYPE(upd, i).av_type == AT_PRINC) {
852
free(ULOG_ENTRY(upd, i).av_princ.k_realm.utf8str_t_val);
853
if (ULOG_ENTRY(upd, i).av_princ.k_components.k_components_val) {
854
for (j = 0; j < ULOG_ENTRY(upd, i).av_princ.k_components.k_components_len; j++) {
855
free(ULOG_ENTRY_PRINC(upd, i, j).k_data.utf8str_t_val);
856
}
857
free(ULOG_ENTRY(upd, i).av_princ.k_components.k_components_val);
858
}
859
}
860
861
/*
862
* Free av_mod_princ
863
*/
864
if (ULOG_ENTRY_TYPE(upd, i).av_type == AT_MOD_PRINC) {
865
free(ULOG_ENTRY(upd, i).av_mod_princ.k_realm.utf8str_t_val);
866
if (ULOG_ENTRY(upd, i).av_mod_princ.k_components.k_components_val) {
867
for (j = 0; j < ULOG_ENTRY(upd, i).av_mod_princ.k_components.k_components_len; j++) {
868
free(ULOG_ENTRY_MOD_PRINC(upd, i, j).k_data.utf8str_t_val);
869
}
870
free(ULOG_ENTRY(upd, i).av_mod_princ.k_components.k_components_val);
871
}
872
}
873
874
/*
875
* Free av_mod_where
876
*/
877
if ((ULOG_ENTRY_TYPE(upd, i).av_type == AT_MOD_WHERE) && ULOG_ENTRY(upd, i).av_mod_where.utf8str_t_val)
878
free(ULOG_ENTRY(upd, i).av_mod_where.utf8str_t_val);
879
880
/*
881
* Free av_pw_policy
882
*/
883
if ((ULOG_ENTRY_TYPE(upd, i).av_type == AT_PW_POLICY) && ULOG_ENTRY(upd, i).av_pw_policy.utf8str_t_val)
884
free(ULOG_ENTRY(upd, i).av_pw_policy.utf8str_t_val);
885
886
/*
887
* XXX: Free av_pw_hist
888
*
889
* For now, we just free the pointer
890
* to av_pw_hist_val, since we aren't
891
* populating this union member in
892
* the conv api function(s) anyways.
893
*/
894
if ((ULOG_ENTRY_TYPE(upd, i).av_type == AT_PW_HIST) && ULOG_ENTRY(upd, i).av_pw_hist.av_pw_hist_val)
895
free(ULOG_ENTRY(upd, i).av_pw_hist.av_pw_hist_val);
896
897
}
898
899
/*
900
* Free up the pointer to kdbe_t_val
901
*/
902
free(upd->kdb_update.kdbe_t_val);
903
}
904
905
/* END CSTYLED */
906
907
/*
908
* Bump up to next struct
909
*/
910
upd++;
911
}
912
913
914
/*
915
* Finally, free up the pointer to the bunched ulog entries
916
*/
917
free(updates);
918
}
919
920