Line data Source code
1 : /*
2 : * Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan
3 : * (Royal Institute of Technology, Stockholm, Sweden).
4 : * All rights reserved.
5 : *
6 : * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
7 : *
8 : * Redistribution and use in source and binary forms, with or without
9 : * modification, are permitted provided that the following conditions
10 : * are met:
11 : *
12 : * 1. Redistributions of source code must retain the above copyright
13 : * notice, this list of conditions and the following disclaimer.
14 : *
15 : * 2. Redistributions in binary form must reproduce the above copyright
16 : * notice, this list of conditions and the following disclaimer in the
17 : * documentation and/or other materials provided with the distribution.
18 : *
19 : * 3. Neither the name of the Institute nor the names of its contributors
20 : * may be used to endorse or promote products derived from this software
21 : * without specific prior written permission.
22 : *
23 : * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24 : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 : * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27 : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 : * SUCH DAMAGE.
34 : */
35 :
36 : #include "krb5_locl.h"
37 :
38 : #undef __attribute__
39 : #define __attribute__(x)
40 :
41 : /**
42 : * @page krb5_init_creds_intro The initial credential handing functions
43 : * @section section_krb5_init_creds Initial credential
44 : *
45 : * Functions to get initial credentials: @ref krb5_credential .
46 : */
47 :
48 : /**
49 : * Allocate a new krb5_get_init_creds_opt structure, free with
50 : * krb5_get_init_creds_opt_free().
51 : *
52 : * @ingroup krb5_credential
53 : */
54 :
55 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
56 22753 : krb5_get_init_creds_opt_alloc(krb5_context context,
57 : krb5_get_init_creds_opt **opt)
58 : {
59 585 : krb5_get_init_creds_opt *o;
60 :
61 22753 : *opt = NULL;
62 22753 : o = calloc(1, sizeof(*o));
63 22753 : if (o == NULL)
64 0 : return krb5_enomem(context);
65 :
66 22753 : o->opt_private = calloc(1, sizeof(*o->opt_private));
67 22753 : if (o->opt_private == NULL) {
68 0 : free(o);
69 0 : return krb5_enomem(context);
70 : }
71 22753 : o->opt_private->refcount = 1;
72 22753 : *opt = o;
73 22753 : return 0;
74 : }
75 :
76 : /**
77 : * Free krb5_get_init_creds_opt structure.
78 : *
79 : * @ingroup krb5_credential
80 : */
81 :
82 : KRB5_LIB_FUNCTION void KRB5_LIB_CALL
83 22481 : krb5_get_init_creds_opt_free(krb5_context context,
84 : krb5_get_init_creds_opt *opt)
85 : {
86 22481 : if (opt == NULL || opt->opt_private == NULL)
87 48 : return;
88 22433 : if (opt->opt_private->refcount < 1) /* abort ? */
89 0 : return;
90 22433 : if (--opt->opt_private->refcount == 0) {
91 22433 : _krb5_get_init_creds_opt_free_pkinit(opt);
92 22433 : free(opt->opt_private->fast_armor_ccache_name);
93 22433 : free(opt->opt_private);
94 : }
95 22433 : memset(opt, 0, sizeof(*opt));
96 22433 : free(opt);
97 : }
98 :
99 : static int
100 12046 : get_config_time (krb5_context context,
101 : const char *realm,
102 : const char *name,
103 : int def)
104 : {
105 585 : int ret;
106 :
107 12046 : ret = krb5_config_get_time (context, NULL,
108 : "realms",
109 : realm,
110 : name,
111 : NULL);
112 12046 : if (ret >= 0)
113 0 : return ret;
114 12046 : ret = krb5_config_get_time (context, NULL,
115 : "libdefaults",
116 : name,
117 : NULL);
118 12046 : if (ret >= 0)
119 0 : return ret;
120 11461 : return def;
121 : }
122 :
123 : static krb5_boolean
124 24092 : get_config_bool (krb5_context context,
125 : krb5_boolean def_value,
126 : const char *realm,
127 : const char *name)
128 : {
129 1170 : krb5_boolean b;
130 :
131 24092 : b = krb5_config_get_bool_default(context, NULL, def_value,
132 : "realms", realm, name, NULL);
133 24092 : if (b != def_value)
134 0 : return b;
135 24092 : b = krb5_config_get_bool_default (context, NULL, def_value,
136 : "libdefaults", name, NULL);
137 24092 : if (b != def_value)
138 0 : return b;
139 22922 : return def_value;
140 : }
141 :
142 : /*
143 : * set all the values in `opt' to the appropriate values for
144 : * application `appname' (default to getprogname() if NULL), and realm
145 : * `realm'. First looks in [appdefaults] but falls back to
146 : * [realms] or [libdefaults] for some of the values.
147 : */
148 :
149 : KRB5_LIB_FUNCTION void KRB5_LIB_CALL
150 12046 : krb5_get_init_creds_opt_set_default_flags(krb5_context context,
151 : const char *appname,
152 : krb5_const_realm realm,
153 : krb5_get_init_creds_opt *opt)
154 : {
155 585 : krb5_boolean b;
156 585 : time_t t;
157 :
158 12046 : b = get_config_bool (context, KRB5_FORWARDABLE_DEFAULT,
159 : realm, "forwardable");
160 12046 : krb5_appdefault_boolean(context, appname, realm, "forwardable", b, &b);
161 12046 : krb5_get_init_creds_opt_set_forwardable(opt, b);
162 :
163 12046 : b = get_config_bool (context, FALSE, realm, "proxiable");
164 12046 : krb5_appdefault_boolean(context, appname, realm, "proxiable", b, &b);
165 12046 : krb5_get_init_creds_opt_set_proxiable (opt, b);
166 :
167 12046 : krb5_appdefault_time(context, appname, realm, "ticket_lifetime", 0, &t);
168 12046 : if (t == 0)
169 0 : t = get_config_time (context, realm, "ticket_lifetime", 0);
170 12046 : if(t != 0)
171 12046 : krb5_get_init_creds_opt_set_tkt_life(opt, t);
172 :
173 12046 : krb5_appdefault_time(context, appname, realm, "renew_lifetime", 0, &t);
174 12046 : if (t == 0)
175 12046 : t = get_config_time (context, realm, "renew_lifetime", 0);
176 12046 : if(t != 0)
177 0 : krb5_get_init_creds_opt_set_renew_life(opt, t);
178 :
179 12046 : krb5_appdefault_boolean(context, appname, realm, "no-addresses",
180 : KRB5_ADDRESSLESS_DEFAULT, &b);
181 12046 : krb5_get_init_creds_opt_set_addressless (context, opt, b);
182 :
183 : #if 0
184 : krb5_appdefault_boolean(context, appname, realm, "anonymous", FALSE, &b);
185 : krb5_get_init_creds_opt_set_anonymous (opt, b);
186 :
187 : krb5_get_init_creds_opt_set_etype_list(opt, enctype,
188 : etype_str.num_strings);
189 :
190 : krb5_get_init_creds_opt_set_salt(krb5_get_init_creds_opt *opt,
191 : krb5_data *salt);
192 :
193 : krb5_get_init_creds_opt_set_preauth_list(krb5_get_init_creds_opt *opt,
194 : krb5_preauthtype *preauth_list,
195 : int preauth_list_length);
196 : #endif
197 12046 : }
198 :
199 : KRB5_LIB_FUNCTION void KRB5_LIB_CALL
200 0 : krb5_get_init_creds_opt_set_change_password_prompt(krb5_get_init_creds_opt *opt,
201 : int change_password_prompt)
202 : {
203 0 : opt->flags |= KRB5_GET_INIT_CREDS_OPT_CHANGE_PASSWORD_PROMPT;
204 0 : opt->change_password_prompt = change_password_prompt;
205 0 : }
206 :
207 : KRB5_LIB_FUNCTION void KRB5_LIB_CALL
208 12166 : krb5_get_init_creds_opt_set_tkt_life(krb5_get_init_creds_opt *opt,
209 : krb5_deltat tkt_life)
210 : {
211 12166 : opt->flags |= KRB5_GET_INIT_CREDS_OPT_TKT_LIFE;
212 12166 : opt->tkt_life = tkt_life;
213 12166 : }
214 :
215 : KRB5_LIB_FUNCTION void KRB5_LIB_CALL
216 8668 : krb5_get_init_creds_opt_set_renew_life(krb5_get_init_creds_opt *opt,
217 : krb5_deltat renew_life)
218 : {
219 8668 : opt->flags |= KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE;
220 8668 : opt->renew_life = renew_life;
221 8668 : }
222 :
223 : KRB5_LIB_FUNCTION void KRB5_LIB_CALL
224 20698 : krb5_get_init_creds_opt_set_forwardable(krb5_get_init_creds_opt *opt,
225 : int forwardable)
226 : {
227 20698 : opt->flags |= KRB5_GET_INIT_CREDS_OPT_FORWARDABLE;
228 20698 : opt->forwardable = forwardable;
229 20698 : }
230 :
231 : KRB5_LIB_FUNCTION void KRB5_LIB_CALL
232 12059 : krb5_get_init_creds_opt_set_proxiable(krb5_get_init_creds_opt *opt,
233 : int proxiable)
234 : {
235 12059 : opt->flags |= KRB5_GET_INIT_CREDS_OPT_PROXIABLE;
236 12059 : opt->proxiable = proxiable;
237 12059 : }
238 :
239 : KRB5_LIB_FUNCTION void KRB5_LIB_CALL
240 26 : krb5_get_init_creds_opt_set_etype_list(krb5_get_init_creds_opt *opt,
241 : krb5_enctype *etype_list,
242 : int etype_list_length)
243 : {
244 26 : opt->flags |= KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST;
245 26 : opt->etype_list = etype_list;
246 26 : opt->etype_list_length = etype_list_length;
247 26 : }
248 :
249 : KRB5_LIB_FUNCTION void KRB5_LIB_CALL
250 3 : krb5_get_init_creds_opt_set_address_list(krb5_get_init_creds_opt *opt,
251 : krb5_addresses *addresses)
252 : {
253 3 : opt->flags |= KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST;
254 3 : opt->address_list = addresses;
255 3 : }
256 :
257 : KRB5_LIB_FUNCTION void KRB5_LIB_CALL
258 0 : krb5_get_init_creds_opt_set_preauth_list(krb5_get_init_creds_opt *opt,
259 : krb5_preauthtype *preauth_list,
260 : int preauth_list_length)
261 : {
262 0 : opt->flags |= KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST;
263 0 : opt->preauth_list_length = preauth_list_length;
264 0 : opt->preauth_list = preauth_list;
265 0 : }
266 :
267 : KRB5_LIB_FUNCTION void KRB5_LIB_CALL
268 0 : krb5_get_init_creds_opt_set_salt(krb5_get_init_creds_opt *opt,
269 : krb5_data *salt)
270 : {
271 0 : opt->flags |= KRB5_GET_INIT_CREDS_OPT_SALT;
272 0 : opt->salt = salt;
273 0 : }
274 :
275 : KRB5_LIB_FUNCTION void KRB5_LIB_CALL
276 104 : krb5_get_init_creds_opt_set_anonymous(krb5_get_init_creds_opt *opt,
277 : int anonymous)
278 : {
279 104 : opt->flags |= KRB5_GET_INIT_CREDS_OPT_ANONYMOUS;
280 104 : opt->anonymous = anonymous;
281 104 : }
282 :
283 : static krb5_error_code
284 56818 : require_ext_opt(krb5_context context,
285 : krb5_get_init_creds_opt *opt,
286 : const char *type)
287 : {
288 56818 : if (opt->opt_private == NULL) {
289 0 : krb5_set_error_message(context, EINVAL,
290 0 : N_("%s on non extendable opt", ""), type);
291 0 : return EINVAL;
292 : }
293 55063 : return 0;
294 : }
295 :
296 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
297 0 : krb5_get_init_creds_opt_set_pa_password(krb5_context context,
298 : krb5_get_init_creds_opt *opt,
299 : const char *password,
300 : krb5_s2k_proc key_proc)
301 : {
302 0 : krb5_error_code ret;
303 0 : ret = require_ext_opt(context, opt, "init_creds_opt_set_pa_password");
304 0 : if (ret)
305 0 : return ret;
306 0 : opt->opt_private->password = password;
307 0 : opt->opt_private->key_proc = key_proc;
308 0 : return 0;
309 : }
310 :
311 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
312 198 : krb5_get_init_creds_opt_set_pac_request(krb5_context context,
313 : krb5_get_init_creds_opt *opt,
314 : krb5_boolean req_pac)
315 : {
316 0 : krb5_error_code ret;
317 198 : ret = require_ext_opt(context, opt, "init_creds_opt_set_pac_req");
318 198 : if (ret)
319 0 : return ret;
320 198 : opt->opt_private->req_pac = req_pac ?
321 198 : KRB5_INIT_CREDS_TRISTATE_TRUE :
322 : KRB5_INIT_CREDS_TRISTATE_FALSE;
323 198 : return 0;
324 : }
325 :
326 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
327 12046 : krb5_get_init_creds_opt_set_addressless(krb5_context context,
328 : krb5_get_init_creds_opt *opt,
329 : krb5_boolean addressless)
330 : {
331 585 : krb5_error_code ret;
332 12046 : ret = require_ext_opt(context, opt, "init_creds_opt_set_pac_req");
333 12046 : if (ret)
334 0 : return ret;
335 12046 : if (addressless)
336 12046 : opt->opt_private->addressless = KRB5_INIT_CREDS_TRISTATE_TRUE;
337 : else
338 0 : opt->opt_private->addressless = KRB5_INIT_CREDS_TRISTATE_FALSE;
339 11461 : return 0;
340 : }
341 :
342 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
343 22270 : krb5_get_init_creds_opt_set_canonicalize(krb5_context context,
344 : krb5_get_init_creds_opt *opt,
345 : krb5_boolean req)
346 : {
347 585 : krb5_error_code ret;
348 22270 : ret = require_ext_opt(context, opt, "init_creds_opt_set_canonicalize");
349 22270 : if (ret)
350 0 : return ret;
351 22270 : if (req)
352 21630 : opt->opt_private->flags |= KRB5_INIT_CREDS_CANONICALIZE;
353 : else
354 640 : opt->opt_private->flags &= ~KRB5_INIT_CREDS_CANONICALIZE;
355 21685 : return 0;
356 : }
357 :
358 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
359 22304 : krb5_get_init_creds_opt_set_win2k(krb5_context context,
360 : krb5_get_init_creds_opt *opt,
361 : krb5_boolean req)
362 : {
363 585 : krb5_error_code ret;
364 22304 : ret = require_ext_opt(context, opt, "init_creds_opt_set_win2k");
365 22304 : if (ret)
366 0 : return ret;
367 22304 : if (req) {
368 21424 : opt->opt_private->flags |= KRB5_INIT_CREDS_NO_C_CANON_CHECK;
369 21424 : opt->opt_private->flags |= KRB5_INIT_CREDS_NO_C_NO_EKU_CHECK;
370 21424 : opt->opt_private->flags |= KRB5_INIT_CREDS_PKINIT_NO_KRBTGT_OTHERNAME_CHECK;
371 : } else {
372 880 : opt->opt_private->flags &= ~KRB5_INIT_CREDS_NO_C_CANON_CHECK;
373 880 : opt->opt_private->flags &= ~KRB5_INIT_CREDS_NO_C_NO_EKU_CHECK;
374 880 : opt->opt_private->flags &= ~KRB5_INIT_CREDS_PKINIT_NO_KRBTGT_OTHERNAME_CHECK;
375 : }
376 21719 : return 0;
377 : }
378 :
379 :
380 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
381 0 : krb5_get_init_creds_opt_set_process_last_req(krb5_context context,
382 : krb5_get_init_creds_opt *opt,
383 : krb5_gic_process_last_req func,
384 : void *ctx)
385 : {
386 0 : krb5_error_code ret;
387 0 : ret = require_ext_opt(context, opt, "init_creds_opt_set_process_last_req");
388 0 : if (ret)
389 0 : return ret;
390 :
391 0 : opt->opt_private->lr.func = func;
392 0 : opt->opt_private->lr.ctx = ctx;
393 :
394 0 : return 0;
395 : }
396 :
397 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
398 10 : krb5_get_init_creds_opt_set_fast_ccache(krb5_context context,
399 : krb5_get_init_creds_opt *opt,
400 : krb5_ccache fast_ccache)
401 : {
402 0 : char *fast_ccache_name;
403 10 : int ret = krb5_cc_get_full_name(context,
404 : fast_ccache,
405 : &fast_ccache_name);
406 10 : if (ret)
407 0 : return ret;
408 :
409 10 : ret = krb5_get_init_creds_opt_set_fast_ccache_name(context,
410 : opt,
411 : fast_ccache_name);
412 10 : krb5_xfree(fast_ccache_name);
413 10 : return ret;
414 : }
415 :
416 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
417 10 : krb5_get_init_creds_opt_set_fast_ccache_name(krb5_context context,
418 : krb5_get_init_creds_opt *opt,
419 : const char *fast_ccache_name)
420 : {
421 10 : if (opt->opt_private->fast_armor_ccache_name)
422 0 : free(opt->opt_private->fast_armor_ccache_name);
423 :
424 10 : opt->opt_private->fast_armor_ccache_name = strdup(fast_ccache_name);
425 10 : if (opt->opt_private->fast_armor_ccache_name == NULL)
426 0 : return krb5_enomem(context);
427 :
428 10 : return 0;
429 : }
430 :
431 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
432 10 : krb5_get_init_creds_opt_set_fast_flags(krb5_context context,
433 : krb5_get_init_creds_opt *opt,
434 : krb5_flags flags)
435 : {
436 10 : heim_assert((flags & ~KRB5_FAST_PUBLIC_FLAGS) == 0, "invalid flags passed to krb5_get_init_creds_opt_set_fast_flags()");
437 10 : opt->opt_private->fast_flags = flags;
438 10 : return 0;
439 : }
440 :
441 :
442 :
443 : #ifndef HEIMDAL_SMALLER
444 :
445 : /**
446 : * Deprecated: use krb5_get_init_creds_opt_alloc().
447 : *
448 : * The reason krb5_get_init_creds_opt_init() is deprecated is that
449 : * krb5_get_init_creds_opt is a static structure and for ABI reason it
450 : * can't grow, ie can't add new functionality.
451 : *
452 : * @ingroup krb5_deprecated
453 : */
454 :
455 : KRB5_LIB_FUNCTION void KRB5_LIB_CALL
456 0 : krb5_get_init_creds_opt_init(krb5_get_init_creds_opt *opt)
457 : KRB5_DEPRECATED_FUNCTION("Use krb5_get_init_creds_opt_alloc instead")
458 : {
459 0 : memset (opt, 0, sizeof(*opt));
460 0 : }
461 :
462 : /**
463 : * Deprecated: use the new krb5_init_creds_init() and
464 : * krb5_init_creds_get_error().
465 : *
466 : * @ingroup krb5_deprecated
467 : */
468 :
469 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
470 0 : krb5_get_init_creds_opt_get_error(krb5_context context,
471 : krb5_get_init_creds_opt *opt,
472 : KRB_ERROR **error)
473 : KRB5_DEPRECATED_FUNCTION("Use X instead")
474 : {
475 0 : *error = calloc(1, sizeof(**error));
476 0 : if (*error == NULL)
477 0 : return krb5_enomem(context);
478 :
479 0 : return 0;
480 : }
481 :
482 : #endif /* HEIMDAL_SMALLER */
|