]>
Commit | Line | Data |
---|---|---|
6cf77d05 SS |
1 | Adds an "ANY" keytab type which is a list of other keytab locations to search |
2 | when searching for a specific entry. When iterated through, it only presents | |
3 | the contents of the first keytab. | |
4 | ||
5 | diff -up /dev/null krb5-1.7/src/lib/krb5/keytab/kt_any.c | |
6 | --- /dev/null 2009-06-04 10:34:55.169007373 -0400 | |
7 | +++ krb5-1.7/src/lib/krb5/keytab/kt_any.c 2009-06-04 13:54:36.000000000 -0400 | |
8 | @@ -0,0 +1,292 @@ | |
9 | +/* | |
10 | + * lib/krb5/keytab/kt_any.c | |
11 | + * | |
12 | + * Copyright 1998, 1999 by the Massachusetts Institute of Technology. | |
13 | + * All Rights Reserved. | |
14 | + * | |
15 | + * Export of this software from the United States of America may | |
16 | + * require a specific license from the United States Government. | |
17 | + * It is the responsibility of any person or organization contemplating | |
18 | + * export to obtain such a license before exporting. | |
19 | + * | |
20 | + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and | |
21 | + * distribute this software and its documentation for any purpose and | |
22 | + * without fee is hereby granted, provided that the above copyright | |
23 | + * notice appear in all copies and that both that copyright notice and | |
24 | + * this permission notice appear in supporting documentation, and that | |
25 | + * the name of M.I.T. not be used in advertising or publicity pertaining | |
26 | + * to distribution of the software without specific, written prior | |
27 | + * permission. M.I.T. makes no representations about the suitability of | |
28 | + * this software for any purpose. It is provided "as is" without express | |
29 | + * or implied warranty. | |
30 | + * | |
31 | + * | |
32 | + * krb5_kta_ops | |
33 | + */ | |
34 | + | |
35 | +#include "k5-int.h" | |
36 | + | |
37 | +typedef struct _krb5_ktany_data { | |
38 | + char *name; | |
39 | + krb5_keytab *choices; | |
40 | + int nchoices; | |
41 | +} krb5_ktany_data; | |
42 | + | |
43 | +typedef struct _krb5_ktany_cursor_data { | |
44 | + int which; | |
45 | + krb5_kt_cursor cursor; | |
46 | +} krb5_ktany_cursor_data; | |
47 | + | |
48 | +static krb5_error_code krb5_ktany_resolve | |
49 | + (krb5_context, | |
50 | + const char *, | |
51 | + krb5_keytab *); | |
52 | +static krb5_error_code krb5_ktany_get_name | |
53 | + (krb5_context context, | |
54 | + krb5_keytab id, | |
55 | + char *name, | |
56 | + unsigned int len); | |
57 | +static krb5_error_code krb5_ktany_close | |
58 | + (krb5_context context, | |
59 | + krb5_keytab id); | |
60 | +static krb5_error_code krb5_ktany_get_entry | |
61 | + (krb5_context context, | |
62 | + krb5_keytab id, | |
63 | + krb5_const_principal principal, | |
64 | + krb5_kvno kvno, | |
65 | + krb5_enctype enctype, | |
66 | + krb5_keytab_entry *entry); | |
67 | +static krb5_error_code krb5_ktany_start_seq_get | |
68 | + (krb5_context context, | |
69 | + krb5_keytab id, | |
70 | + krb5_kt_cursor *cursorp); | |
71 | +static krb5_error_code krb5_ktany_next_entry | |
72 | + (krb5_context context, | |
73 | + krb5_keytab id, | |
74 | + krb5_keytab_entry *entry, | |
75 | + krb5_kt_cursor *cursor); | |
76 | +static krb5_error_code krb5_ktany_end_seq_get | |
77 | + (krb5_context context, | |
78 | + krb5_keytab id, | |
79 | + krb5_kt_cursor *cursor); | |
80 | +static void cleanup | |
81 | + (krb5_context context, | |
82 | + krb5_ktany_data *data, | |
83 | + int nchoices); | |
84 | + | |
85 | +struct _krb5_kt_ops krb5_kta_ops = { | |
86 | + 0, | |
87 | + "ANY", /* Prefix -- this string should not appear anywhere else! */ | |
88 | + krb5_ktany_resolve, | |
89 | + krb5_ktany_get_name, | |
90 | + krb5_ktany_close, | |
91 | + krb5_ktany_get_entry, | |
92 | + krb5_ktany_start_seq_get, | |
93 | + krb5_ktany_next_entry, | |
94 | + krb5_ktany_end_seq_get, | |
95 | + NULL, | |
96 | + NULL, | |
97 | + NULL, | |
98 | +}; | |
99 | + | |
100 | +static krb5_error_code | |
101 | +krb5_ktany_resolve(context, name, id) | |
102 | + krb5_context context; | |
103 | + const char *name; | |
104 | + krb5_keytab *id; | |
105 | +{ | |
106 | + const char *p, *q; | |
107 | + char *copy; | |
108 | + krb5_error_code kerror; | |
109 | + krb5_ktany_data *data; | |
110 | + int i; | |
111 | + | |
112 | + /* Allocate space for our data and remember a copy of the name. */ | |
113 | + if ((data = (krb5_ktany_data *)malloc(sizeof(krb5_ktany_data))) == NULL) | |
114 | + return(ENOMEM); | |
115 | + if ((data->name = (char *)malloc(strlen(name) + 1)) == NULL) { | |
116 | + krb5_xfree(data); | |
117 | + return(ENOMEM); | |
118 | + } | |
119 | + strcpy(data->name, name); | |
120 | + | |
121 | + /* Count the number of choices and allocate memory for them. */ | |
122 | + data->nchoices = 1; | |
123 | + for (p = name; (q = strchr(p, ',')) != NULL; p = q + 1) | |
124 | + data->nchoices++; | |
125 | + if ((data->choices = (krb5_keytab *) | |
126 | + malloc(data->nchoices * sizeof(krb5_keytab))) == NULL) { | |
127 | + krb5_xfree(data->name); | |
128 | + krb5_xfree(data); | |
129 | + return(ENOMEM); | |
130 | + } | |
131 | + | |
132 | + /* Resolve each of the choices. */ | |
133 | + i = 0; | |
134 | + for (p = name; (q = strchr(p, ',')) != NULL; p = q + 1) { | |
135 | + /* Make a copy of the choice name so we can terminate it. */ | |
136 | + if ((copy = (char *)malloc(q - p + 1)) == NULL) { | |
137 | + cleanup(context, data, i); | |
138 | + return(ENOMEM); | |
139 | + } | |
140 | + memcpy(copy, p, q - p); | |
141 | + copy[q - p] = 0; | |
142 | + | |
143 | + /* Try resolving the choice name. */ | |
144 | + kerror = krb5_kt_resolve(context, copy, &data->choices[i]); | |
145 | + krb5_xfree(copy); | |
146 | + if (kerror) { | |
147 | + cleanup(context, data, i); | |
148 | + return(kerror); | |
149 | + } | |
150 | + i++; | |
151 | + } | |
152 | + if ((kerror = krb5_kt_resolve(context, p, &data->choices[i]))) { | |
153 | + cleanup(context, data, i); | |
154 | + return(kerror); | |
155 | + } | |
156 | + | |
157 | + /* Allocate and fill in an ID for the caller. */ | |
158 | + if ((*id = (krb5_keytab)malloc(sizeof(**id))) == NULL) { | |
159 | + cleanup(context, data, i); | |
160 | + return(ENOMEM); | |
161 | + } | |
162 | + (*id)->ops = &krb5_kta_ops; | |
163 | + (*id)->data = (krb5_pointer)data; | |
164 | + (*id)->magic = KV5M_KEYTAB; | |
165 | + | |
166 | + return(0); | |
167 | +} | |
168 | + | |
169 | +static krb5_error_code | |
170 | +krb5_ktany_get_name(context, id, name, len) | |
171 | + krb5_context context; | |
172 | + krb5_keytab id; | |
173 | + char *name; | |
174 | + unsigned int len; | |
175 | +{ | |
176 | + krb5_ktany_data *data = (krb5_ktany_data *)id->data; | |
177 | + | |
178 | + if (len < strlen(data->name) + 1) | |
179 | + return(KRB5_KT_NAME_TOOLONG); | |
180 | + strcpy(name, data->name); | |
181 | + return(0); | |
182 | +} | |
183 | + | |
184 | +static krb5_error_code | |
185 | +krb5_ktany_close(context, id) | |
186 | + krb5_context context; | |
187 | + krb5_keytab id; | |
188 | +{ | |
189 | + krb5_ktany_data *data = (krb5_ktany_data *)id->data; | |
190 | + | |
191 | + cleanup(context, data, data->nchoices); | |
192 | + id->ops = 0; | |
193 | + krb5_xfree(id); | |
194 | + return(0); | |
195 | +} | |
196 | + | |
197 | +static krb5_error_code | |
198 | +krb5_ktany_get_entry(context, id, principal, kvno, enctype, entry) | |
199 | + krb5_context context; | |
200 | + krb5_keytab id; | |
201 | + krb5_const_principal principal; | |
202 | + krb5_kvno kvno; | |
203 | + krb5_enctype enctype; | |
204 | + krb5_keytab_entry *entry; | |
205 | +{ | |
206 | + krb5_ktany_data *data = (krb5_ktany_data *)id->data; | |
207 | + krb5_error_code kerror = KRB5_KT_NOTFOUND; | |
208 | + int i; | |
209 | + | |
210 | + for (i = 0; i < data->nchoices; i++) { | |
211 | + if ((kerror = krb5_kt_get_entry(context, data->choices[i], principal, | |
212 | + kvno, enctype, entry)) != ENOENT) | |
213 | + return kerror; | |
214 | + } | |
215 | + return kerror; | |
216 | +} | |
217 | + | |
218 | +static krb5_error_code | |
219 | +krb5_ktany_start_seq_get(context, id, cursorp) | |
220 | + krb5_context context; | |
221 | + krb5_keytab id; | |
222 | + krb5_kt_cursor *cursorp; | |
223 | +{ | |
224 | + krb5_ktany_data *data = (krb5_ktany_data *)id->data; | |
225 | + krb5_ktany_cursor_data *cdata; | |
226 | + krb5_error_code kerror = ENOENT; | |
227 | + int i; | |
228 | + | |
229 | + if ((cdata = (krb5_ktany_cursor_data *) | |
230 | + malloc(sizeof(krb5_ktany_cursor_data))) == NULL) | |
231 | + return(ENOMEM); | |
232 | + | |
233 | + /* Find a choice which can handle the serialization request. */ | |
234 | + for (i = 0; i < data->nchoices; i++) { | |
235 | + if ((kerror = krb5_kt_start_seq_get(context, data->choices[i], | |
236 | + &cdata->cursor)) == 0) | |
237 | + break; | |
238 | + else if (kerror != ENOENT) { | |
239 | + krb5_xfree(cdata); | |
240 | + return(kerror); | |
241 | + } | |
242 | + } | |
243 | + | |
244 | + if (i == data->nchoices) { | |
245 | + /* Everyone returned ENOENT, so no go. */ | |
246 | + krb5_xfree(cdata); | |
247 | + return(kerror); | |
248 | + } | |
249 | + | |
250 | + cdata->which = i; | |
251 | + *cursorp = (krb5_kt_cursor)cdata; | |
252 | + return(0); | |
253 | +} | |
254 | + | |
255 | +static krb5_error_code | |
256 | +krb5_ktany_next_entry(context, id, entry, cursor) | |
257 | + krb5_context context; | |
258 | + krb5_keytab id; | |
259 | + krb5_keytab_entry *entry; | |
260 | + krb5_kt_cursor *cursor; | |
261 | +{ | |
262 | + krb5_ktany_data *data = (krb5_ktany_data *)id->data; | |
263 | + krb5_ktany_cursor_data *cdata = (krb5_ktany_cursor_data *)*cursor; | |
264 | + krb5_keytab choice_id; | |
265 | + | |
266 | + choice_id = data->choices[cdata->which]; | |
267 | + return(krb5_kt_next_entry(context, choice_id, entry, &cdata->cursor)); | |
268 | +} | |
269 | + | |
270 | +static krb5_error_code | |
271 | +krb5_ktany_end_seq_get(context, id, cursor) | |
272 | + krb5_context context; | |
273 | + krb5_keytab id; | |
274 | + krb5_kt_cursor *cursor; | |
275 | +{ | |
276 | + krb5_ktany_data *data = (krb5_ktany_data *)id->data; | |
277 | + krb5_ktany_cursor_data *cdata = (krb5_ktany_cursor_data *)*cursor; | |
278 | + krb5_keytab choice_id; | |
279 | + krb5_error_code kerror; | |
280 | + | |
281 | + choice_id = data->choices[cdata->which]; | |
282 | + kerror = krb5_kt_end_seq_get(context, choice_id, &cdata->cursor); | |
283 | + krb5_xfree(cdata); | |
284 | + return(kerror); | |
285 | +} | |
286 | + | |
287 | +static void | |
288 | +cleanup(context, data, nchoices) | |
289 | + krb5_context context; | |
290 | + krb5_ktany_data *data; | |
291 | + int nchoices; | |
292 | +{ | |
293 | + int i; | |
294 | + | |
295 | + krb5_xfree(data->name); | |
296 | + for (i = 0; i < nchoices; i++) | |
297 | + krb5_kt_close(context, data->choices[i]); | |
298 | + krb5_xfree(data->choices); | |
299 | + krb5_xfree(data); | |
300 | +} | |
301 | diff -up krb5-1.7/src/lib/krb5/keytab/ktbase.c krb5-1.7/src/lib/krb5/keytab/ktbase.c | |
302 | --- krb5-1.7/src/lib/krb5/keytab/ktbase.c 2009-02-18 13:18:56.000000000 -0500 | |
303 | +++ krb5-1.7/src/lib/krb5/keytab/ktbase.c 2009-06-04 13:54:36.000000000 -0400 | |
304 | @@ -59,14 +59,19 @@ extern const krb5_kt_ops krb5_ktf_ops; | |
305 | extern const krb5_kt_ops krb5_ktf_writable_ops; | |
306 | extern const krb5_kt_ops krb5_kts_ops; | |
307 | extern const krb5_kt_ops krb5_mkt_ops; | |
308 | +extern const krb5_kt_ops krb5_kta_ops; | |
309 | ||
310 | struct krb5_kt_typelist { | |
311 | const krb5_kt_ops *ops; | |
312 | const struct krb5_kt_typelist *next; | |
313 | }; | |
314 | +static struct krb5_kt_typelist krb5_kt_typelist_any = { | |
315 | + &krb5_kta_ops, | |
316 | + NULL | |
317 | +}; | |
318 | const static struct krb5_kt_typelist krb5_kt_typelist_srvtab = { | |
319 | &krb5_kts_ops, | |
320 | - NULL | |
321 | + &krb5_kt_typelist_any | |
322 | }; | |
323 | const static struct krb5_kt_typelist krb5_kt_typelist_memory = { | |
324 | &krb5_mkt_ops, | |
325 | diff -up krb5-1.7/src/lib/krb5/keytab/Makefile.in krb5-1.7/src/lib/krb5/keytab/Makefile.in | |
326 | --- krb5-1.7/src/lib/krb5/keytab/Makefile.in 2009-01-05 15:27:53.000000000 -0500 | |
327 | +++ krb5-1.7/src/lib/krb5/keytab/Makefile.in 2009-06-04 13:54:36.000000000 -0400 | |
328 | @@ -19,6 +19,7 @@ STLIBOBJS= \ | |
329 | ktfr_entry.o \ | |
330 | ktremove.o \ | |
331 | ktfns.o \ | |
332 | + kt_any.o \ | |
333 | kt_file.o \ | |
334 | kt_memory.o \ | |
335 | kt_srvtab.o \ | |
336 | @@ -31,6 +32,7 @@ OBJS= \ | |
337 | $(OUTPRE)ktfr_entry.$(OBJEXT) \ | |
338 | $(OUTPRE)ktremove.$(OBJEXT) \ | |
339 | $(OUTPRE)ktfns.$(OBJEXT) \ | |
340 | + $(OUTPRE)kt_any.$(OBJEXT) \ | |
341 | $(OUTPRE)kt_file.$(OBJEXT) \ | |
342 | $(OUTPRE)kt_memory.$(OBJEXT) \ | |
343 | $(OUTPRE)kt_srvtab.$(OBJEXT) \ | |
344 | @@ -43,6 +45,7 @@ SRCS= \ | |
345 | $(srcdir)/ktfr_entry.c \ | |
346 | $(srcdir)/ktremove.c \ | |
347 | $(srcdir)/ktfns.c \ | |
348 | + $(srcdir)/kt_any.c \ | |
349 | $(srcdir)/kt_file.c \ | |
350 | $(srcdir)/kt_memory.c \ | |
351 | $(srcdir)/kt_srvtab.c \ |