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