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