1*54925bf6Swillf /*
2*54925bf6Swillf * lib/kdb/kdb_ldap/kdb_xdr.c
3*54925bf6Swillf *
4*54925bf6Swillf * Copyright 1995 by the Massachusetts Institute of Technology.
5*54925bf6Swillf * All Rights Reserved.
6*54925bf6Swillf *
7*54925bf6Swillf * Export of this software from the United States of America may
8*54925bf6Swillf * require a specific license from the United States Government.
9*54925bf6Swillf * It is the responsibility of any person or organization contemplating
10*54925bf6Swillf * export to obtain such a license before exporting.
11*54925bf6Swillf *
12*54925bf6Swillf * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13*54925bf6Swillf * distribute this software and its documentation for any purpose and
14*54925bf6Swillf * without fee is hereby granted, provided that the above copyright
15*54925bf6Swillf * notice appear in all copies and that both that copyright notice and
16*54925bf6Swillf * this permission notice appear in supporting documentation, and that
17*54925bf6Swillf * the name of M.I.T. not be used in advertising or publicity pertaining
18*54925bf6Swillf * to distribution of the software without specific, written prior
19*54925bf6Swillf * permission. Furthermore if you modify this software you must label
20*54925bf6Swillf * your software as modified software and not distribute it in such a
21*54925bf6Swillf * fashion that it might be confused with the original M.I.T. software.
22*54925bf6Swillf * M.I.T. makes no representations about the suitability of
23*54925bf6Swillf * this software for any purpose. It is provided "as is" without express
24*54925bf6Swillf * or implied warranty.
25*54925bf6Swillf *
26*54925bf6Swillf */
27*54925bf6Swillf
28*54925bf6Swillf #include <k5-int.h>
29*54925bf6Swillf #include <string.h>
30*54925bf6Swillf #include <stdio.h>
31*54925bf6Swillf #include <errno.h>
32*54925bf6Swillf #include "kdb_xdr.h"
33*54925bf6Swillf
34*54925bf6Swillf #define safe_realloc(p,n) ((p)?(realloc(p,n)):(malloc(n)))
35*54925bf6Swillf
36*54925bf6Swillf krb5_error_code
krb5_dbe_update_tl_data(context,entry,new_tl_data)37*54925bf6Swillf krb5_dbe_update_tl_data(context, entry, new_tl_data)
38*54925bf6Swillf krb5_context context;
39*54925bf6Swillf krb5_db_entry * entry;
40*54925bf6Swillf krb5_tl_data * new_tl_data;
41*54925bf6Swillf {
42*54925bf6Swillf krb5_tl_data * tl_data;
43*54925bf6Swillf krb5_octet * tmp;
44*54925bf6Swillf
45*54925bf6Swillf /* copy the new data first, so we can fail cleanly if malloc()
46*54925bf6Swillf fails */
47*54925bf6Swillf
48*54925bf6Swillf if ((tmp = (krb5_octet *) malloc(new_tl_data->tl_data_length)) == NULL)
49*54925bf6Swillf return(ENOMEM);
50*54925bf6Swillf
51*54925bf6Swillf /* Find an existing entry of the specified type and point at
52*54925bf6Swillf it, or NULL if not found */
53*54925bf6Swillf
54*54925bf6Swillf for (tl_data = entry->tl_data; tl_data; tl_data = tl_data->tl_data_next)
55*54925bf6Swillf if (tl_data->tl_data_type == new_tl_data->tl_data_type)
56*54925bf6Swillf break;
57*54925bf6Swillf
58*54925bf6Swillf /* if necessary, chain a new record in the beginning and point at it */
59*54925bf6Swillf
60*54925bf6Swillf if (!tl_data) {
61*54925bf6Swillf if ((tl_data = (krb5_tl_data *) calloc(1, sizeof(krb5_tl_data)))
62*54925bf6Swillf == NULL) {
63*54925bf6Swillf free(tmp);
64*54925bf6Swillf return(ENOMEM);
65*54925bf6Swillf }
66*54925bf6Swillf tl_data->tl_data_next = entry->tl_data;
67*54925bf6Swillf entry->tl_data = tl_data;
68*54925bf6Swillf entry->n_tl_data++;
69*54925bf6Swillf }
70*54925bf6Swillf
71*54925bf6Swillf /* fill in the record */
72*54925bf6Swillf
73*54925bf6Swillf if (tl_data->tl_data_contents)
74*54925bf6Swillf free(tl_data->tl_data_contents);
75*54925bf6Swillf
76*54925bf6Swillf tl_data->tl_data_type = new_tl_data->tl_data_type;
77*54925bf6Swillf tl_data->tl_data_length = new_tl_data->tl_data_length;
78*54925bf6Swillf tl_data->tl_data_contents = tmp;
79*54925bf6Swillf memcpy(tmp, new_tl_data->tl_data_contents, tl_data->tl_data_length);
80*54925bf6Swillf
81*54925bf6Swillf return(0);
82*54925bf6Swillf }
83*54925bf6Swillf
84*54925bf6Swillf krb5_error_code
krb5_dbe_lookup_tl_data(context,entry,ret_tl_data)85*54925bf6Swillf krb5_dbe_lookup_tl_data(context, entry, ret_tl_data)
86*54925bf6Swillf krb5_context context;
87*54925bf6Swillf krb5_db_entry * entry;
88*54925bf6Swillf krb5_tl_data * ret_tl_data;
89*54925bf6Swillf {
90*54925bf6Swillf krb5_tl_data *tl_data;
91*54925bf6Swillf
92*54925bf6Swillf for (tl_data = entry->tl_data; tl_data; tl_data = tl_data->tl_data_next) {
93*54925bf6Swillf if (tl_data->tl_data_type == ret_tl_data->tl_data_type) {
94*54925bf6Swillf *ret_tl_data = *tl_data;
95*54925bf6Swillf return(0);
96*54925bf6Swillf }
97*54925bf6Swillf }
98*54925bf6Swillf
99*54925bf6Swillf /* if the requested record isn't found, return zero bytes.
100*54925bf6Swillf if it ever means something to have a zero-length tl_data,
101*54925bf6Swillf this code and its callers will have to be changed */
102*54925bf6Swillf
103*54925bf6Swillf ret_tl_data->tl_data_length = 0;
104*54925bf6Swillf ret_tl_data->tl_data_contents = NULL;
105*54925bf6Swillf return(0);
106*54925bf6Swillf }
107*54925bf6Swillf
108*54925bf6Swillf krb5_error_code
krb5_dbe_update_last_pwd_change(context,entry,stamp)109*54925bf6Swillf krb5_dbe_update_last_pwd_change(context, entry, stamp)
110*54925bf6Swillf krb5_context context;
111*54925bf6Swillf krb5_db_entry * entry;
112*54925bf6Swillf krb5_timestamp stamp;
113*54925bf6Swillf {
114*54925bf6Swillf krb5_tl_data tl_data;
115*54925bf6Swillf krb5_octet buf[4]; /* this is the encoded size of an int32 */
116*54925bf6Swillf
117*54925bf6Swillf tl_data.tl_data_type = KRB5_TL_LAST_PWD_CHANGE;
118*54925bf6Swillf tl_data.tl_data_length = sizeof(buf);
119*54925bf6Swillf krb5_kdb_encode_int32((krb5_int32) stamp, buf);
120*54925bf6Swillf tl_data.tl_data_contents = buf;
121*54925bf6Swillf
122*54925bf6Swillf return(krb5_dbe_update_tl_data(context, entry, &tl_data));
123*54925bf6Swillf }
124*54925bf6Swillf
125*54925bf6Swillf krb5_error_code
krb5_dbe_lookup_last_pwd_change(context,entry,stamp)126*54925bf6Swillf krb5_dbe_lookup_last_pwd_change(context, entry, stamp)
127*54925bf6Swillf krb5_context context;
128*54925bf6Swillf krb5_db_entry * entry;
129*54925bf6Swillf krb5_timestamp * stamp;
130*54925bf6Swillf {
131*54925bf6Swillf krb5_tl_data tl_data;
132*54925bf6Swillf krb5_error_code code;
133*54925bf6Swillf krb5_int32 tmp;
134*54925bf6Swillf
135*54925bf6Swillf tl_data.tl_data_type = KRB5_TL_LAST_PWD_CHANGE;
136*54925bf6Swillf
137*54925bf6Swillf if ((code = krb5_dbe_lookup_tl_data(context, entry, &tl_data)))
138*54925bf6Swillf return(code);
139*54925bf6Swillf
140*54925bf6Swillf if (tl_data.tl_data_length != 4) {
141*54925bf6Swillf *stamp = 0;
142*54925bf6Swillf return(0);
143*54925bf6Swillf }
144*54925bf6Swillf
145*54925bf6Swillf krb5_kdb_decode_int32(tl_data.tl_data_contents, tmp);
146*54925bf6Swillf
147*54925bf6Swillf *stamp = (krb5_timestamp) tmp;
148*54925bf6Swillf
149*54925bf6Swillf return(0);
150*54925bf6Swillf }
151*54925bf6Swillf
152*54925bf6Swillf /* it seems odd that there's no function to remove a tl_data, but if
153*54925bf6Swillf I need one, I'll add one */
154*54925bf6Swillf
155*54925bf6Swillf krb5_error_code
krb5_dbe_update_mod_princ_data(context,entry,mod_date,mod_princ)156*54925bf6Swillf krb5_dbe_update_mod_princ_data(context, entry, mod_date, mod_princ)
157*54925bf6Swillf krb5_context context;
158*54925bf6Swillf krb5_db_entry * entry;
159*54925bf6Swillf krb5_timestamp mod_date;
160*54925bf6Swillf krb5_const_principal mod_princ;
161*54925bf6Swillf {
162*54925bf6Swillf krb5_tl_data tl_data;
163*54925bf6Swillf
164*54925bf6Swillf krb5_error_code retval = 0;
165*54925bf6Swillf krb5_octet * nextloc = 0;
166*54925bf6Swillf char * unparse_mod_princ = 0;
167*54925bf6Swillf unsigned int unparse_mod_princ_size;
168*54925bf6Swillf
169*54925bf6Swillf if ((retval = krb5_unparse_name(context, mod_princ,
170*54925bf6Swillf &unparse_mod_princ)))
171*54925bf6Swillf return(retval);
172*54925bf6Swillf
173*54925bf6Swillf unparse_mod_princ_size = strlen(unparse_mod_princ) + 1;
174*54925bf6Swillf
175*54925bf6Swillf if ((nextloc = (krb5_octet *) malloc(unparse_mod_princ_size + 4))
176*54925bf6Swillf == NULL) {
177*54925bf6Swillf free(unparse_mod_princ);
178*54925bf6Swillf return(ENOMEM);
179*54925bf6Swillf }
180*54925bf6Swillf
181*54925bf6Swillf tl_data.tl_data_type = KRB5_TL_MOD_PRINC;
182*54925bf6Swillf tl_data.tl_data_length = unparse_mod_princ_size + 4;
183*54925bf6Swillf tl_data.tl_data_contents = nextloc;
184*54925bf6Swillf
185*54925bf6Swillf /* Mod Date */
186*54925bf6Swillf krb5_kdb_encode_int32(mod_date, nextloc);
187*54925bf6Swillf
188*54925bf6Swillf /* Mod Princ */
189*54925bf6Swillf memcpy(nextloc+4, unparse_mod_princ, unparse_mod_princ_size);
190*54925bf6Swillf
191*54925bf6Swillf retval = krb5_dbe_update_tl_data(context, entry, &tl_data);
192*54925bf6Swillf
193*54925bf6Swillf free(unparse_mod_princ);
194*54925bf6Swillf free(nextloc);
195*54925bf6Swillf
196*54925bf6Swillf return(retval);
197*54925bf6Swillf }
198*54925bf6Swillf
199*54925bf6Swillf krb5_error_code
krb5_dbe_lookup_mod_princ_data(context,entry,mod_time,mod_princ)200*54925bf6Swillf krb5_dbe_lookup_mod_princ_data(context, entry, mod_time, mod_princ)
201*54925bf6Swillf krb5_context context;
202*54925bf6Swillf krb5_db_entry * entry;
203*54925bf6Swillf krb5_timestamp * mod_time;
204*54925bf6Swillf krb5_principal * mod_princ;
205*54925bf6Swillf {
206*54925bf6Swillf krb5_tl_data tl_data;
207*54925bf6Swillf krb5_error_code code;
208*54925bf6Swillf
209*54925bf6Swillf tl_data.tl_data_type = KRB5_TL_MOD_PRINC;
210*54925bf6Swillf
211*54925bf6Swillf if ((code = krb5_dbe_lookup_tl_data(context, entry, &tl_data)))
212*54925bf6Swillf return(code);
213*54925bf6Swillf
214*54925bf6Swillf if ((tl_data.tl_data_length < 5) ||
215*54925bf6Swillf (tl_data.tl_data_contents[tl_data.tl_data_length-1] != '\0'))
216*54925bf6Swillf return(KRB5_KDB_TRUNCATED_RECORD);
217*54925bf6Swillf
218*54925bf6Swillf /* Mod Date */
219*54925bf6Swillf krb5_kdb_decode_int32(tl_data.tl_data_contents, *mod_time);
220*54925bf6Swillf
221*54925bf6Swillf /* Mod Princ */
222*54925bf6Swillf if ((code = krb5_parse_name(context,
223*54925bf6Swillf (const char *) (tl_data.tl_data_contents+4),
224*54925bf6Swillf mod_princ)))
225*54925bf6Swillf return(code);
226*54925bf6Swillf
227*54925bf6Swillf return(0);
228*54925bf6Swillf }
229