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