diff options
Diffstat (limited to 'src/lib/krb5/krb')
-rw-r--r-- | src/lib/krb5/krb/Makefile.in | 3 | ||||
-rw-r--r-- | src/lib/krb5/krb/deps | 11 | ||||
-rw-r--r-- | src/lib/krb5/krb/fast.c | 15 | ||||
-rw-r--r-- | src/lib/krb5/krb/fast.h | 2 | ||||
-rw-r--r-- | src/lib/krb5/krb/get_in_tkt.c | 102 | ||||
-rw-r--r-- | src/lib/krb5/krb/gic_opt.c | 439 | ||||
-rw-r--r-- | src/lib/krb5/krb/gic_opt_set_pa.c | 99 | ||||
-rw-r--r-- | src/lib/krb5/krb/gic_pwd.c | 53 | ||||
-rw-r--r-- | src/lib/krb5/krb/init_creds_ctx.h | 3 | ||||
-rw-r--r-- | src/lib/krb5/krb/int-proto.h | 118 | ||||
-rw-r--r-- | src/lib/krb5/krb/preauth2.c | 22 |
11 files changed, 316 insertions, 551 deletions
diff --git a/src/lib/krb5/krb/Makefile.in b/src/lib/krb5/krb/Makefile.in index 91010ba22..62f0b90f6 100644 --- a/src/lib/krb5/krb/Makefile.in +++ b/src/lib/krb5/krb/Makefile.in @@ -79,7 +79,6 @@ STLIBOBJS= \ preauth_otp.o \ preauth_pkinit.o \ preauth_sam2.o \ - gic_opt_set_pa.o \ princ_comp.o \ privsafe.o \ random_str.o \ @@ -189,7 +188,6 @@ OBJS= $(OUTPRE)addr_comp.$(OBJEXT) \ $(OUTPRE)preauth_otp.$(OBJEXT) \ $(OUTPRE)preauth_pkinit.$(OBJEXT) \ $(OUTPRE)preauth_sam2.$(OBJEXT) \ - $(OUTPRE)gic_opt_set_pa.$(OBJEXT) \ $(OUTPRE)princ_comp.$(OBJEXT) \ $(OUTPRE)privsafe.$(OBJEXT) \ $(OUTPRE)random_str.$(OBJEXT) \ @@ -299,7 +297,6 @@ SRCS= $(srcdir)/addr_comp.c \ $(srcdir)/preauth_otp.c \ $(srcdir)/preauth_pkinit.c \ $(srcdir)/preauth_sam2.c \ - $(srcdir)/gic_opt_set_pa.c \ $(srcdir)/princ_comp.c \ $(srcdir)/privsafe.c \ $(srcdir)/random_str.c \ diff --git a/src/lib/krb5/krb/deps b/src/lib/krb5/krb/deps index db9c4ec41..d08d53371 100644 --- a/src/lib/krb5/krb/deps +++ b/src/lib/krb5/krb/deps @@ -783,17 +783,6 @@ preauth_sam2.so preauth_sam2.po $(OUTPRE)preauth_sam2.$(OBJEXT): \ $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ init_creds_ctx.h int-proto.h preauth_sam2.c -gic_opt_set_pa.so gic_opt_set_pa.po $(OUTPRE)gic_opt_set_pa.$(OBJEXT): \ - $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ - $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ - $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ - $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ - $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ - $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ - $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ - $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ - $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ - gic_opt_set_pa.c int-proto.h princ_comp.so princ_comp.po $(OUTPRE)princ_comp.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ diff --git a/src/lib/krb5/krb/fast.c b/src/lib/krb5/krb/fast.c index 56e61a63a..8d622681e 100644 --- a/src/lib/krb5/krb/fast.c +++ b/src/lib/krb5/krb/fast.c @@ -171,21 +171,21 @@ krb5int_fast_prep_req_body(krb5_context context, krb5_error_code krb5int_fast_as_armor(krb5_context context, struct krb5int_fast_request_state *state, - krb5_gic_opt_ext *opte, - krb5_kdc_req *request) + krb5_get_init_creds_opt *opt, krb5_kdc_req *request) { krb5_error_code retval = 0; krb5_ccache ccache = NULL; krb5_principal target_principal = NULL; krb5_data *target_realm; + const char *ccname = k5_gic_opt_get_fast_ccache_name(opt); + krb5_flags fast_flags; krb5_clear_error_message(context); target_realm = &request->server->realm; - if (opte->opt_private->fast_ccache_name) { - TRACE_FAST_ARMOR_CCACHE(context, opte->opt_private->fast_ccache_name); + if (ccname != NULL) { + TRACE_FAST_ARMOR_CCACHE(context, ccname); state->fast_state_flags |= KRB5INT_FAST_ARMOR_AVAIL; - retval = krb5_cc_resolve(context, opte->opt_private->fast_ccache_name, - &ccache); + retval = krb5_cc_resolve(context, ccname, &ccache); if (retval == 0) { retval = krb5int_tgtname(context, target_realm, target_realm, &target_principal); @@ -202,7 +202,8 @@ krb5int_fast_as_armor(krb5_context context, krb5_free_data_contents(context, &config_data); retval = 0; } - if (opte->opt_private->fast_flags & KRB5_FAST_REQUIRED) { + fast_flags = k5_gic_opt_get_fast_flags(opt); + if (fast_flags & KRB5_FAST_REQUIRED) { TRACE_FAST_REQUIRED(context); state->fast_state_flags |= KRB5INT_FAST_DO_FAST; } diff --git a/src/lib/krb5/krb/fast.h b/src/lib/krb5/krb/fast.h index 88456741a..684e25d0d 100644 --- a/src/lib/krb5/krb/fast.h +++ b/src/lib/krb5/krb/fast.h @@ -83,7 +83,7 @@ krb5int_fast_free_state(krb5_context context, krb5_error_code krb5int_fast_as_armor(krb5_context context, struct krb5int_fast_request_state *state, - krb5_gic_opt_ext *opte, krb5_kdc_req *request); + krb5_get_init_creds_opt *opt, krb5_kdc_req *request); krb5_error_code krb5int_fast_reply_key(krb5_context context, diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c index d7b2bd9eb..ebd28440d 100644 --- a/src/lib/krb5/krb/get_in_tkt.c +++ b/src/lib/krb5/krb/get_in_tkt.c @@ -485,10 +485,6 @@ krb5_init_creds_free(krb5_context context, if (ctx == NULL) return; - if (ctx->opte != NULL && gic_opt_is_shadowed(ctx->opte)) { - krb5_get_init_creds_opt_free(context, - (krb5_get_init_creds_opt *)ctx->opte); - } k5_response_items_free(ctx->rctx.items); free(ctx->in_tkt_service); zapfree(ctx->gakpw.storage.data, ctx->gakpw.storage.length); @@ -749,11 +745,11 @@ restart_init_creds_loop(krb5_context context, krb5_init_creds_context ctx, krb5_free_data(context, ctx->outer_request_body); ctx->outer_request_body = NULL; } - if (ctx->opte && - (ctx->opte->flags & KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST)) { - if ((code = make_preauth_list(context, ctx->opte->preauth_list, - ctx->opte->preauth_list_length, - &ctx->preauth_to_use))) + if (ctx->opt->flags & KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST) { + code = make_preauth_list(context, ctx->opt->preauth_list, + ctx->opt->preauth_list_length, + &ctx->preauth_to_use); + if (code) goto cleanup; } @@ -766,18 +762,18 @@ restart_init_creds_loop(krb5_context context, krb5_init_creds_context ctx, if (code != 0) goto cleanup; - code = krb5int_fast_as_armor(context, ctx->fast_state, - ctx->opte, ctx->request); + code = krb5int_fast_as_armor(context, ctx->fast_state, ctx->opt, + ctx->request); if (code != 0) goto cleanup; if (krb5int_upgrade_to_fast_p(context, ctx->fast_state, padata)) { - code = krb5int_fast_as_armor(context, ctx->fast_state, - ctx->opte, ctx->request); + code = krb5int_fast_as_armor(context, ctx->fast_state, ctx->opt, + ctx->request); if (code != 0) goto cleanup; } /* give the preauth plugins a chance to prep the request body */ - k5_preauth_prepare_request(context, ctx->opte, ctx->request); + k5_preauth_prepare_request(context, ctx->opt, ctx->request); code = krb5int_fast_prep_req_body(context, ctx->fast_state, ctx->request, @@ -794,15 +790,13 @@ krb5_init_creds_init(krb5_context context, krb5_prompter_fct prompter, void *data, krb5_deltat start_time, - krb5_get_init_creds_opt *options, + krb5_get_init_creds_opt *opt, krb5_init_creds_context *pctx) { krb5_error_code code; krb5_init_creds_context ctx; int tmp; char *str = NULL; - krb5_gic_opt_ext *opte; - krb5_get_init_creds_opt local_opts; TRACE_INIT_CREDS(context, client); @@ -825,34 +819,23 @@ krb5_init_creds_init(krb5_context context, ctx->start_time = start_time; - if (options == NULL) { - /* - * We initialize a non-extended options because that way the shadowed - * flag will be sent and they will be freed when the init_creds context - * is freed. The options will be extended and copied off the stack into - * storage by opt_to_opte. - */ - krb5_get_init_creds_opt_init(&local_opts); - options = &local_opts; + if (opt == NULL) { + ctx->opt = &ctx->opt_storage; + krb5_get_init_creds_opt_init(ctx->opt); + } else { + ctx->opt = opt; } - code = k5_gic_opt_to_opte(context, options, &ctx->opte, 1, - "krb5_init_creds_init"); - if (code != 0) - goto cleanup; - code = k5_response_items_new(&ctx->rctx.items); if (code != 0) goto cleanup; - opte = ctx->opte; - /* Initialise request parameters as per krb5_get_init_creds() */ ctx->request->kdc_options = context->kdc_default_options; /* forwardable */ - if (opte->flags & KRB5_GET_INIT_CREDS_OPT_FORWARDABLE) - tmp = opte->forwardable; + if (ctx->opt->flags & KRB5_GET_INIT_CREDS_OPT_FORWARDABLE) + tmp = ctx->opt->forwardable; else if (krb5int_libdefault_boolean(context, &ctx->request->client->realm, KRB5_CONF_FORWARDABLE, &tmp) == 0) ; @@ -862,8 +845,8 @@ krb5_init_creds_init(krb5_context context, ctx->request->kdc_options |= KDC_OPT_FORWARDABLE; /* proxiable */ - if (opte->flags & KRB5_GET_INIT_CREDS_OPT_PROXIABLE) - tmp = opte->proxiable; + if (ctx->opt->flags & KRB5_GET_INIT_CREDS_OPT_PROXIABLE) + tmp = ctx->opt->proxiable; else if (krb5int_libdefault_boolean(context, &ctx->request->client->realm, KRB5_CONF_PROXIABLE, &tmp) == 0) ; @@ -873,7 +856,7 @@ krb5_init_creds_init(krb5_context context, ctx->request->kdc_options |= KDC_OPT_PROXIABLE; /* canonicalize */ - if (opte->flags & KRB5_GET_INIT_CREDS_OPT_CANONICALIZE) + if (ctx->opt->flags & KRB5_GET_INIT_CREDS_OPT_CANONICALIZE) tmp = 1; else if (krb5int_libdefault_boolean(context, &ctx->request->client->realm, KRB5_CONF_CANONICALIZE, &tmp) == 0) @@ -888,8 +871,8 @@ krb5_init_creds_init(krb5_context context, ctx->request->kdc_options |= KDC_OPT_ALLOW_POSTDATE | KDC_OPT_POSTDATED; /* ticket lifetime */ - if (opte->flags & KRB5_GET_INIT_CREDS_OPT_TKT_LIFE) - ctx->tkt_life = options->tkt_life; + if (ctx->opt->flags & KRB5_GET_INIT_CREDS_OPT_TKT_LIFE) + ctx->tkt_life = ctx->opt->tkt_life; else if (krb5int_libdefault_string(context, &ctx->request->client->realm, KRB5_CONF_TICKET_LIFETIME, &str) == 0) { code = krb5_string_to_deltat(str, &ctx->tkt_life); @@ -901,8 +884,8 @@ krb5_init_creds_init(krb5_context context, ctx->tkt_life = 24 * 60 * 60; /* previously hardcoded in kinit */ /* renewable lifetime */ - if (opte->flags & KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE) - ctx->renew_life = options->renew_life; + if (ctx->opt->flags & KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE) + ctx->renew_life = ctx->opt->renew_life; else if (krb5int_libdefault_string(context, &ctx->request->client->realm, KRB5_CONF_RENEW_LIFETIME, &str) == 0) { code = krb5_string_to_deltat(str, &ctx->renew_life); @@ -917,13 +900,14 @@ krb5_init_creds_init(krb5_context context, ctx->request->kdc_options |= KDC_OPT_RENEWABLE; /* enctypes */ - if (opte->flags & KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST) { + if (ctx->opt->flags & KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST) { ctx->request->ktype = - k5memdup(opte->etype_list, - opte->etype_list_length * sizeof(krb5_enctype), &code); + k5memdup(ctx->opt->etype_list, + ctx->opt->etype_list_length * sizeof(krb5_enctype), + &code); if (code != 0) goto cleanup; - ctx->request->nktypes = opte->etype_list_length; + ctx->request->nktypes = ctx->opt->etype_list_length; } else if (krb5_get_default_in_tkt_ktypes(context, &ctx->request->ktype) == 0) { ctx->request->nktypes = k5_count_etypes(ctx->request->ktype); @@ -942,8 +926,8 @@ krb5_init_creds_init(krb5_context context, ctx->etype = ctx->request->ktype[0]; /* addresses */ - if (opte->flags & KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST) { - code = krb5_copy_addresses(context, opte->address_list, + if (ctx->opt->flags & KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST) { + code = krb5_copy_addresses(context, ctx->opt->address_list, &ctx->request->addresses); if (code != 0) goto cleanup; @@ -957,8 +941,8 @@ krb5_init_creds_init(krb5_context context, goto cleanup; } - if (opte->flags & KRB5_GET_INIT_CREDS_OPT_SALT) { - code = krb5int_copy_data_contents(context, opte->salt, &ctx->salt); + if (ctx->opt->flags & KRB5_GET_INIT_CREDS_OPT_SALT) { + code = krb5int_copy_data_contents(context, ctx->opt->salt, &ctx->salt); if (code != 0) goto cleanup; ctx->default_salt = FALSE; @@ -968,7 +952,7 @@ krb5_init_creds_init(krb5_context context, } /* Anonymous. */ - if(opte->flags & KRB5_GET_INIT_CREDS_OPT_ANONYMOUS) { + if (ctx->opt->flags & KRB5_GET_INIT_CREDS_OPT_ANONYMOUS) { ctx->request->kdc_options |= KDC_OPT_REQUEST_ANONYMOUS; /* Remap @REALM to WELLKNOWN/ANONYMOUS@REALM. */ if (client->length == 1 && client->data[0].length ==0) { @@ -1108,13 +1092,13 @@ read_allowed_preauth_type(krb5_context context, krb5_init_creds_context ctx) krb5_error_code ret; krb5_data config; char *tmp, *p; + krb5_ccache in_ccache = k5_gic_opt_get_in_ccache(ctx->opt); ctx->allowed_preauth_type = KRB5_PADATA_NONE; - if (ctx->opte->opt_private->in_ccache == NULL) + if (in_ccache == NULL) return; memset(&config, 0, sizeof(config)); - if (krb5_cc_get_config(context, ctx->opte->opt_private->in_ccache, - ctx->request->server, + if (krb5_cc_get_config(context, in_ccache, ctx->request->server, KRB5_CC_CONF_PA_TYPE, &config) != 0) return; tmp = k5memdup0(config.data, config.length, &ret); @@ -1162,16 +1146,16 @@ read_cc_config_in_data(krb5_context context, krb5_init_creds_context ctx) char *encoded; krb5_error_code code; int i; + krb5_ccache in_ccache = k5_gic_opt_get_in_ccache(ctx->opt); k5_json_release(ctx->cc_config_in); ctx->cc_config_in = NULL; - if (ctx->opte->opt_private->in_ccache == NULL) + if (in_ccache == NULL) return 0; memset(&config, 0, sizeof(config)); - code = krb5_cc_get_config(context, ctx->opte->opt_private->in_ccache, - ctx->request->server, + code = krb5_cc_get_config(context, in_ccache, ctx->request->server, KRB5_CC_CONF_PA_CONFIG_DATA, &config); if (code) return code; @@ -1438,6 +1422,7 @@ init_creds_step_reply(krb5_context context, krb5_keyblock *strengthen_key = NULL; krb5_keyblock encrypting_key; krb5_boolean fast_avail; + krb5_ccache out_ccache = k5_gic_opt_get_out_ccache(ctx->opt); encrypting_key.length = 0; encrypting_key.contents = NULL; @@ -1631,8 +1616,7 @@ init_creds_step_reply(krb5_context context, code = stash_as_reply(context, ctx->reply, &ctx->cred, NULL); if (code != 0) goto cleanup; - if (ctx->opte && ctx->opte->opt_private->out_ccache) { - krb5_ccache out_ccache = ctx->opte->opt_private->out_ccache; + if (out_ccache != NULL) { krb5_data config_data; code = krb5_cc_initialize(context, out_ccache, ctx->cred.client); if (code != 0) diff --git a/src/lib/krb5/krb/gic_opt.c b/src/lib/krb5/krb/gic_opt.c index 40a51d7c0..55f915264 100644 --- a/src/lib/krb5/krb/gic_opt.c +++ b/src/lib/krb5/krb/gic_opt.c @@ -3,17 +3,29 @@ #include "int-proto.h" #include <krb5/clpreauth_plugin.h> -static void -init_common(krb5_get_init_creds_opt *opt) -{ - opt->flags |= KRB5_GET_INIT_CREDS_OPT_CHG_PWD_PRMPT; -} +#define GIC_OPT_EXTENDED 0x80000000 +#define GIC_OPT_SHALLOW_COPY 0x40000000 + +#define DEFAULT_FLAGS KRB5_GET_INIT_CREDS_OPT_CHG_PWD_PRMPT + +struct extended_options { + krb5_get_init_creds_opt opt; + int num_preauth_data; + krb5_gic_opt_pa_data *preauth_data; + char *fast_ccache_name; + krb5_ccache in_ccache; + krb5_ccache out_ccache; + krb5_flags fast_flags; + krb5_expire_callback_func expire_cb; + void *expire_data; + krb5_responder_fn responder; + void *responder_data; +}; void KRB5_CALLCONV krb5_get_init_creds_opt_init(krb5_get_init_creds_opt *opt) { - opt->flags = 0; - init_common(opt); + opt->flags = DEFAULT_FLAGS; } void KRB5_CALLCONV @@ -101,81 +113,22 @@ krb5_get_init_creds_opt_set_change_password_prompt(krb5_get_init_creds_opt *opt, opt->flags &= ~KRB5_GET_INIT_CREDS_OPT_CHG_PWD_PRMPT; } -/* Forward prototype */ -static void -free_gic_opt_ext_preauth_data(krb5_context context, - krb5_gic_opt_ext *opte); - -static krb5_error_code -gic_opte_private_alloc(krb5_context context, krb5_gic_opt_ext *opte) -{ - if (NULL == opte || !gic_opt_is_extended(opte)) - return EINVAL; - - opte->opt_private = calloc(1, sizeof(*opte->opt_private)); - if (NULL == opte->opt_private) { - return ENOMEM; - } - /* Allocate any private stuff */ - opte->opt_private->num_preauth_data = 0; - opte->opt_private->preauth_data = NULL; - return 0; -} - -static krb5_error_code -gic_opte_private_free(krb5_context context, krb5_gic_opt_ext *opte) -{ - if (NULL == opte || !gic_opt_is_extended(opte)) - return EINVAL; - - /* Free up any private stuff */ - if (opte->opt_private->preauth_data != NULL) - free_gic_opt_ext_preauth_data(context, opte); - if (opte->opt_private->fast_ccache_name) - free(opte->opt_private->fast_ccache_name); - free(opte->opt_private); - opte->opt_private = NULL; - return 0; -} - -static krb5_gic_opt_ext * -gic_opte_alloc(krb5_context context) -{ - krb5_gic_opt_ext *opte; - krb5_error_code code; - - opte = calloc(1, sizeof(*opte)); - if (NULL == opte) - return NULL; - opte->flags = GIC_OPT_EXTENDED; - - code = gic_opte_private_alloc(context, opte); - if (code) { - free(opte); - return NULL; - } - return(opte); -} - krb5_error_code KRB5_CALLCONV krb5_get_init_creds_opt_alloc(krb5_context context, krb5_get_init_creds_opt **opt) { - krb5_gic_opt_ext *opte; + struct extended_options *opte; if (NULL == opt) return EINVAL; *opt = NULL; - /* - * We return a new extended structure cast as a krb5_get_init_creds_opt - */ - opte = gic_opte_alloc(context); - if (NULL == opte) + /* Return an extended structure cast as a krb5_get_init_creds_opt. */ + opte = calloc(1, sizeof(*opte)); + if (opte == NULL) return ENOMEM; - - *opt = (krb5_get_init_creds_opt *) opte; - init_common(*opt); + opte->opt.flags = DEFAULT_FLAGS | GIC_OPT_EXTENDED; + *opt = (krb5_get_init_creds_opt *)opte; return 0; } @@ -183,111 +136,54 @@ void KRB5_CALLCONV krb5_get_init_creds_opt_free(krb5_context context, krb5_get_init_creds_opt *opt) { - krb5_gic_opt_ext *opte; - - if (NULL == opt) - return; + struct extended_options *opte = (struct extended_options *)opt; + int i; - /* Don't touch it if we didn't allocate it */ - if (!gic_opt_is_extended(opt)) + if (opt == NULL || !(opt->flags & GIC_OPT_EXTENDED)) return; - - opte = (krb5_gic_opt_ext *)opt; - if (opte->opt_private) - gic_opte_private_free(context, opte); - + assert(!(opt->flags & GIC_OPT_SHALLOW_COPY)); + for (i = 0; i < opte->num_preauth_data; i++) { + free(opte->preauth_data[i].attr); + free(opte->preauth_data[i].value); + } + free(opte->preauth_data); + free(opte->fast_ccache_name); free(opte); } -static krb5_error_code -gic_opte_copy(krb5_context context, - krb5_get_init_creds_opt *opt, - krb5_gic_opt_ext **opte) +krb5_error_code KRB5_CALLCONV +krb5_get_init_creds_opt_set_pa(krb5_context context, + krb5_get_init_creds_opt *opt, + const char *attr, + const char *value) { - krb5_gic_opt_ext *oe; - - oe = gic_opte_alloc(context); - if (NULL == oe) - return ENOMEM; + struct extended_options *opte = (struct extended_options *)opt; + krb5_gic_opt_pa_data *t, *pa; - if (opt) { - oe->flags = opt->flags; - oe->tkt_life = opt->tkt_life; - oe->renew_life = opt->renew_life; - oe->forwardable = opt->forwardable; - oe->proxiable = opt->proxiable; - oe->etype_list = opt->etype_list; - oe->etype_list_length = opt->etype_list_length; - oe->address_list = opt->address_list; - oe->preauth_list = opt->preauth_list; - oe->preauth_list_length = opt->preauth_list_length; - oe->salt = opt->salt; - } + if (opt == NULL || !(opt->flags & GIC_OPT_EXTENDED)) + return EINVAL; + assert(!(opt->flags & GIC_OPT_SHALLOW_COPY)); - /* - * Fix the flags -- the EXTENDED flag would have been - * overwritten by the copy if there was one. The - * SHADOWED flag is necessary to ensure that the - * krb5_gic_opt_ext structure that was allocated - * here will be freed by the library because the - * application is unaware of its existence. - */ - oe->flags |= (GIC_OPT_EXTENDED | GIC_OPT_SHADOWED); - - *opte = oe; - return 0; -} + /* Allocate space for another option. */ + t = realloc(opte->preauth_data, (opte->num_preauth_data + 1) * sizeof(*t)); + if (t == NULL) + return ENOMEM; + opte->preauth_data = t; -/* - * Convert a krb5_get_init_creds_opt pointer to a pointer to - * an extended, krb5_gic_opt_ext pointer. If the original - * pointer already points to an extended structure, then simply - * return the original pointer. Otherwise, if 'force' is non-zero, - * allocate an extended structure and copy the original over it. - * If the original pointer did not point to an extended structure - * and 'force' is zero, then return an error. This is used in - * cases where the original *should* be an extended structure. - */ -krb5_error_code -k5_gic_opt_to_opte(krb5_context context, krb5_get_init_creds_opt *opt, - krb5_gic_opt_ext **opte, unsigned int force, - const char *where) -{ - if (!gic_opt_is_extended(opt)) { - if (force) { - return gic_opte_copy(context, opt, opte); - } else { - krb5_set_error_message(context, EINVAL, - _("%s: attempt to convert non-extended " - "krb5_get_init_creds_opt"), where); - return EINVAL; - } + /* Copy the option into the new slot. */ + pa = &opte->preauth_data[opte->num_preauth_data]; + pa->attr = strdup(attr); + if (pa->attr == NULL) + return ENOMEM; + pa->value = strdup(value); + if (pa->value == NULL) { + free(pa->attr); + return ENOMEM; } - /* If it is already extended, just return it */ - *opte = (krb5_gic_opt_ext *)opt; - return 0; -} + opte->num_preauth_data++; -static void -free_gic_opt_ext_preauth_data(krb5_context context, - krb5_gic_opt_ext *opte) -{ - int i; - - if (NULL == opte || !gic_opt_is_extended(opte)) - return; - if (NULL == opte->opt_private || NULL == opte->opt_private->preauth_data) - return; - - for (i = 0; i < opte->opt_private->num_preauth_data; i++) { - if (opte->opt_private->preauth_data[i].attr != NULL) - free(opte->opt_private->preauth_data[i].attr); - if (opte->opt_private->preauth_data[i].value != NULL) - free(opte->opt_private->preauth_data[i].value); - } - free(opte->opt_private->preauth_data); - opte->opt_private->preauth_data = NULL; - opte->opt_private->num_preauth_data = 0; + /* Give preauth modules a chance to look at the option now. */ + return krb5_preauth_supply_preauth_data(context, opt, attr, value); } /* @@ -304,41 +200,36 @@ krb5_get_init_creds_opt_get_pa(krb5_context context, int *num_preauth_data, krb5_gic_opt_pa_data **preauth_data) { - krb5_error_code retval; - krb5_gic_opt_ext *opte; + struct extended_options *opte = (struct extended_options *)opt; krb5_gic_opt_pa_data *p = NULL; int i; size_t allocsize; - retval = k5_gic_opt_to_opte(context, opt, &opte, 0, - "krb5_get_init_creds_opt_get_pa"); - if (retval) - return retval; - if (num_preauth_data == NULL || preauth_data == NULL) return EINVAL; - *num_preauth_data = 0; *preauth_data = NULL; + if (opt == NULL || !(opt->flags & GIC_OPT_EXTENDED)) + return EINVAL; - if (opte->opt_private->num_preauth_data == 0) + if (opte->num_preauth_data == 0) return 0; allocsize = - opte->opt_private->num_preauth_data * sizeof(krb5_gic_opt_pa_data); + opte->num_preauth_data * sizeof(krb5_gic_opt_pa_data); p = malloc(allocsize); if (p == NULL) return ENOMEM; /* Init these to make cleanup easier */ - for (i = 0; i < opte->opt_private->num_preauth_data; i++) { + for (i = 0; i < opte->num_preauth_data; i++) { p[i].attr = NULL; p[i].value = NULL; } - for (i = 0; i < opte->opt_private->num_preauth_data; i++) { - p[i].attr = strdup(opte->opt_private->preauth_data[i].attr); - p[i].value = strdup(opte->opt_private->preauth_data[i].value); + for (i = 0; i < opte->num_preauth_data; i++) { + p[i].attr = strdup(opte->preauth_data[i].attr); + p[i].value = strdup(opte->preauth_data[i].value); if (p[i].attr == NULL || p[i].value == NULL) goto cleanup; } @@ -346,7 +237,7 @@ krb5_get_init_creds_opt_get_pa(krb5_context context, *preauth_data = p; return 0; cleanup: - for (i = 0; i < opte->opt_private->num_preauth_data; i++) { + for (i = 0; i < opte->num_preauth_data; i++) { if (p[i].attr != NULL) free(p[i].attr); if (p[i].value != NULL) @@ -384,20 +275,16 @@ krb5_get_init_creds_opt_set_fast_ccache_name(krb5_context context, krb5_get_init_creds_opt *opt, const char *ccache_name) { - krb5_error_code retval = 0; - krb5_gic_opt_ext *opte; - - retval = k5_gic_opt_to_opte(context, opt, &opte, 0, - "krb5_get_init_creds_opt_set_fast_ccache_name"); - if (retval) - return retval; - if (opte->opt_private->fast_ccache_name) { - free(opte->opt_private->fast_ccache_name); - } - opte->opt_private->fast_ccache_name = strdup(ccache_name); - if (opte->opt_private->fast_ccache_name == NULL) - retval = ENOMEM; - return retval; + struct extended_options *opte = (struct extended_options *)opt; + + if (opt == NULL || !(opt->flags & GIC_OPT_EXTENDED)) + return EINVAL; + assert(!(opt->flags & GIC_OPT_SHALLOW_COPY)); + free(opte->fast_ccache_name); + opte->fast_ccache_name = strdup(ccache_name); + if (opte->fast_ccache_name == NULL) + return ENOMEM; + return 0; } krb5_error_code KRB5_CALLCONV @@ -423,52 +310,73 @@ krb5_get_init_creds_opt_set_fast_ccache(krb5_context context, return retval; } +const char * +k5_gic_opt_get_fast_ccache_name(krb5_get_init_creds_opt *opt) +{ + struct extended_options *opte = (struct extended_options *)opt; + + if (opt == NULL || !(opt->flags & GIC_OPT_EXTENDED)) + return NULL; + return opte->fast_ccache_name; +} + krb5_error_code KRB5_CALLCONV krb5_get_init_creds_opt_set_in_ccache(krb5_context context, krb5_get_init_creds_opt *opt, krb5_ccache ccache) { - krb5_error_code retval = 0; - krb5_gic_opt_ext *opte; + struct extended_options *opte = (struct extended_options *)opt; - retval = k5_gic_opt_to_opte(context, opt, &opte, 0, - "krb5_get_init_creds_opt_set_in_ccache"); - if (retval) - return retval; - opte->opt_private->in_ccache = ccache; + if (opt == NULL || !(opt->flags & GIC_OPT_EXTENDED)) + return EINVAL; + opte->in_ccache = ccache; return 0; } +krb5_ccache +k5_gic_opt_get_in_ccache(krb5_get_init_creds_opt *opt) +{ + struct extended_options *opte = (struct extended_options *)opt; + + if (opt == NULL || !(opt->flags & GIC_OPT_EXTENDED)) + return NULL; + return opte->in_ccache; +} + krb5_error_code KRB5_CALLCONV krb5_get_init_creds_opt_set_out_ccache(krb5_context context, krb5_get_init_creds_opt *opt, krb5_ccache ccache) { - krb5_error_code retval = 0; - krb5_gic_opt_ext *opte; + struct extended_options *opte = (struct extended_options *)opt; - retval = k5_gic_opt_to_opte(context, opt, &opte, 0, - "krb5_get_init_creds_opt_set_out_ccache"); - if (retval) - return retval; - opte->opt_private->out_ccache = ccache; + if (opt == NULL || !(opt->flags & GIC_OPT_EXTENDED)) + return EINVAL; + opte->out_ccache = ccache; return 0; } +krb5_ccache +k5_gic_opt_get_out_ccache(krb5_get_init_creds_opt *opt) +{ + struct extended_options *opte = (struct extended_options *)opt; + + if (opt == NULL || !(opt->flags & GIC_OPT_EXTENDED)) + return NULL; + return opte->out_ccache; +} + krb5_error_code KRB5_CALLCONV krb5_get_init_creds_opt_set_fast_flags(krb5_context context, krb5_get_init_creds_opt *opt, krb5_flags flags) { - krb5_error_code retval = 0; - krb5_gic_opt_ext *opte; + struct extended_options *opte = (struct extended_options *)opt; - retval = k5_gic_opt_to_opte(context, opt, &opte, 0, - "krb5_get_init_creds_opt_set_fast_flags"); - if (retval) - return retval; - opte->opt_private->fast_flags = flags; - return retval; + if (opt == NULL || !(opt->flags & GIC_OPT_EXTENDED)) + return EINVAL; + opte->fast_flags = flags; + return 0; } krb5_error_code KRB5_CALLCONV @@ -476,18 +384,25 @@ krb5_get_init_creds_opt_get_fast_flags(krb5_context context, krb5_get_init_creds_opt *opt, krb5_flags *out_flags) { - krb5_error_code retval = 0; - krb5_gic_opt_ext *opte; + struct extended_options *opte = (struct extended_options *)opt; if (out_flags == NULL) return EINVAL; *out_flags = 0; - retval = k5_gic_opt_to_opte(context, opt, &opte, 0, - "krb5_get_init_creds_opt_get_fast_flags"); - if (retval) - return retval; - *out_flags = opte->opt_private->fast_flags; - return retval; + if (opt == NULL || !(opt->flags & GIC_OPT_EXTENDED)) + return EINVAL; + *out_flags = opte->fast_flags; + return 0; +} + +krb5_flags +k5_gic_opt_get_fast_flags(krb5_get_init_creds_opt *opt) +{ + struct extended_options *opte = (struct extended_options *)opt; + + if (opt == NULL || !(opt->flags & GIC_OPT_EXTENDED)) + return 0; + return opte->fast_flags; } krb5_error_code KRB5_CALLCONV @@ -496,16 +411,27 @@ krb5_get_init_creds_opt_set_expire_callback(krb5_context context, krb5_expire_callback_func cb, void *data) { - krb5_error_code retval = 0; - krb5_gic_opt_ext *opte; - - retval = k5_gic_opt_to_opte(context, opt, &opte, 0, - "krb5_get_init_creds_opt_set_expire_callback"); - if (retval) - return retval; - opte->opt_private->expire_cb = cb; - opte->opt_private->expire_data = data; - return retval; + struct extended_options *opte = (struct extended_options *)opt; + + if (opt == NULL || !(opt->flags & GIC_OPT_EXTENDED)) + return EINVAL; + opte->expire_cb = cb; + opte->expire_data = data; + return 0; +} + +void +k5_gic_opt_get_expire_cb(krb5_get_init_creds_opt *opt, + krb5_expire_callback_func *cb_out, void **data_out) +{ + struct extended_options *opte = (struct extended_options *)opt; + + *cb_out = NULL; + *data_out = NULL; + if (opt == NULL || !(opt->flags & GIC_OPT_EXTENDED)) + return; + *cb_out = opte->expire_cb; + *data_out = opte->expire_data; } krb5_error_code KRB5_CALLCONV @@ -513,14 +439,41 @@ krb5_get_init_creds_opt_set_responder(krb5_context context, krb5_get_init_creds_opt *opt, krb5_responder_fn responder, void *data) { - krb5_error_code ret; - krb5_gic_opt_ext *opte; + struct extended_options *opte = (struct extended_options *)opt; - ret = k5_gic_opt_to_opte(context, opt, &opte, 0, - "krb5_get_init_creds_opt_set_responder"); - if (ret) - return ret; - opte->opt_private->responder = responder; - opte->opt_private->responder_data = data; + if (opt == NULL || !(opt->flags & GIC_OPT_EXTENDED)) + return EINVAL; + opte->responder = responder; + opte->responder_data = data; return 0; } + +void +k5_gic_opt_get_responder(krb5_get_init_creds_opt *opt, + krb5_responder_fn *responder_out, void **data_out) +{ + struct extended_options *opte = (struct extended_options *)opt; + + *responder_out = NULL; + *data_out = NULL; + if (opt == NULL || !(opt->flags & GIC_OPT_EXTENDED)) + return; + *responder_out = opte->responder; + *data_out = opte->responder_data; +} + +krb5_get_init_creds_opt * +k5_gic_opt_shallow_copy(krb5_get_init_creds_opt *opt) +{ + struct extended_options *opte; + + opte = calloc(1, sizeof(*opte)); + if (opt == NULL) + opte->opt.flags = DEFAULT_FLAGS; + else if (opt->flags & GIC_OPT_EXTENDED) + *opte = *(struct extended_options *)opt; + else + opte->opt = *opt; + opte->opt.flags |= GIC_OPT_SHALLOW_COPY; + return (krb5_get_init_creds_opt *)opte; +} diff --git a/src/lib/krb5/krb/gic_opt_set_pa.c b/src/lib/krb5/krb/gic_opt_set_pa.c deleted file mode 100644 index d44780599..000000000 --- a/src/lib/krb5/krb/gic_opt_set_pa.c +++ /dev/null @@ -1,99 +0,0 @@ -/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ -/* - * Copyright 1995, 2003, 2008 by the Massachusetts Institute of Technology. All - * Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. Furthermore if you modify this software you must label - * your software as modified software and not distribute it in such a - * fashion that it might be confused with the original M.I.T. software. - * M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - * - * krb5_get_init_creds_opt_set_pa() - * krb5_preauth_supply_preauth_data() - */ - -#include "k5-int.h" -#include "int-proto.h" - -static krb5_error_code -add_gic_opt_ext_preauth_data(krb5_context context, - krb5_gic_opt_ext *opte, - const char *attr, - const char *value) -{ - size_t newsize; - int i; - krb5_gic_opt_pa_data *newpad; - - newsize = opte->opt_private->num_preauth_data + 1; - newsize = newsize * sizeof(*opte->opt_private->preauth_data); - if (opte->opt_private->preauth_data == NULL) - newpad = malloc(newsize); - else - newpad = realloc(opte->opt_private->preauth_data, newsize); - if (newpad == NULL) - return ENOMEM; - opte->opt_private->preauth_data = newpad; - - i = opte->opt_private->num_preauth_data; - newpad[i].attr = strdup(attr); - if (newpad[i].attr == NULL) - return ENOMEM; - newpad[i].value = strdup(value); - if (newpad[i].value == NULL) { - free(newpad[i].attr); - return ENOMEM; - } - opte->opt_private->num_preauth_data += 1; - return 0; -} - -/* - * This function allows the caller to supply options to preauth - * plugins. Preauth plugin modules are given a chance to look - * at each option at the time this function is called in ordre - * to check the validity of the option. - * The 'opt' pointer supplied to this function must have been - * obtained using krb5_get_init_creds_opt_alloc() - */ -krb5_error_code KRB5_CALLCONV -krb5_get_init_creds_opt_set_pa(krb5_context context, - krb5_get_init_creds_opt *opt, - const char *attr, - const char *value) -{ - krb5_error_code retval; - krb5_gic_opt_ext *opte; - - retval = k5_gic_opt_to_opte(context, opt, &opte, 0, - "krb5_get_init_creds_opt_set_pa"); - if (retval) - return retval; - - /* - * Copy the option into the extended get_init_creds_opt structure - */ - retval = add_gic_opt_ext_preauth_data(context, opte, attr, value); - if (retval) - return retval; - - /* - * Give the plugins a chance to look at the option now. - */ - retval = krb5_preauth_supply_preauth_data(context, opte, attr, value); - return retval; -} diff --git a/src/lib/krb5/krb/gic_pwd.c b/src/lib/krb5/krb/gic_pwd.c index 6aec7c3a7..e95673fe4 100644 --- a/src/lib/krb5/krb/gic_pwd.c +++ b/src/lib/krb5/krb/gic_pwd.c @@ -178,21 +178,19 @@ warn_pw_expiry(krb5_context context, krb5_get_init_creds_opt *options, const char *in_tkt_service, krb5_kdc_rep *as_reply) { krb5_error_code ret; + krb5_expire_callback_func expire_cb; + void *expire_data; krb5_timestamp pw_exp, acct_exp, now; krb5_boolean is_last_req; krb5_deltat delta; - krb5_gic_opt_ext *opte; char ts[256], banner[1024]; get_expiry_times(as_reply->enc_part2, &pw_exp, &acct_exp, &is_last_req); - ret = k5_gic_opt_to_opte(context, options, &opte, 0, ""); - if (ret == 0 && opte->opt_private->expire_cb != NULL) { - krb5_expire_callback_func cb = opte->opt_private->expire_cb; - void *cb_data = opte->opt_private->expire_data; - + k5_gic_opt_get_expire_cb(options, &expire_cb, &expire_data); + if (expire_cb != NULL) { /* Invoke the expire callback and don't send prompter warnings. */ - (*cb)(context, cb_data, pw_exp, acct_exp, is_last_req); + (*expire_cb)(context, expire_data, pw_exp, acct_exp, is_last_req); return; } @@ -249,31 +247,20 @@ warn_pw_expiry(krb5_context context, krb5_get_init_creds_opt *options, * resulting ticket or how it is stored. Set lifetime and flags appropriate * for a ticket which we will use immediately and then discard. * - * storage1 and storage2 will be used to hold the temporary options. The - * caller must not free the result, as it will contain aliases into the - * application options. + * The caller should free the result with free(). */ -static krb5_get_init_creds_opt * -make_chpw_options(krb5_get_init_creds_opt *in, krb5_gic_opt_ext *storage1, - gic_opt_private *storage2) +static krb5_error_code +make_chpw_options(krb5_context context, krb5_get_init_creds_opt *in, + krb5_get_init_creds_opt **out) { - krb5_gic_opt_ext *in_ext; krb5_get_init_creds_opt *opt; - /* Copy the application's options to storage. */ - if (in == NULL) { - storage1->flags = 0; - } else if (gic_opt_is_extended(in)) { - in_ext = (krb5_gic_opt_ext *)in; - *storage1 = *in_ext; - *storage2 = *in_ext->opt_private; - storage1->opt_private = storage2; - } else { - *(krb5_get_init_creds_opt *)storage1 = *in; - } + *out = NULL; + opt = k5_gic_opt_shallow_copy(in); + if (opt == NULL) + return ENOMEM; /* Get a non-forwardable, non-proxiable, short-lifetime ticket. */ - opt = (krb5_get_init_creds_opt *)storage1; krb5_get_init_creds_opt_set_tkt_life(opt, 5 * 60); krb5_get_init_creds_opt_set_renew_life(opt, 0); krb5_get_init_creds_opt_set_forwardable(opt, 0); @@ -284,10 +271,10 @@ make_chpw_options(krb5_get_init_creds_opt *in, krb5_gic_opt_ext *storage1, opt->flags &= ~KRB5_GET_INIT_CREDS_OPT_ANONYMOUS; /* The output ccache should only be used for the actual ticket. */ - if (gic_opt_is_extended(opt)) - storage2->out_ccache = NULL; + krb5_get_init_creds_opt_set_out_ccache(context, opt, NULL); - return opt; + *out = opt; + return 0; } krb5_error_code KRB5_CALLCONV @@ -307,8 +294,6 @@ krb5_get_init_creds_password(krb5_context context, int tries; krb5_creds chpw_creds; krb5_get_init_creds_opt *chpw_opts = NULL; - krb5_gic_opt_ext storage1; - gic_opt_private storage2; struct gak_password gakpw; krb5_data pw0, pw1; char banner[1024], pw0array[1024], pw1array[1024]; @@ -395,7 +380,9 @@ krb5_get_init_creds_password(krb5_context context, /* ok, we have an expired password. Give the user a few chances to change it */ - chpw_opts = make_chpw_options(options, &storage1, &storage2); + ret = make_chpw_options(context, options, &chpw_opts); + if (ret) + goto cleanup; ret = k5_get_init_creds(context, &chpw_creds, client, prompter, data, start_time, "kadmin/changepw", chpw_opts, krb5_get_as_key_password, &gakpw, &use_master, @@ -511,7 +498,7 @@ cleanup: if (ret == 0) warn_pw_expiry(context, options, prompter, data, in_tkt_service, as_reply); - + free(chpw_opts); zapfree(gakpw.storage.data, gakpw.storage.length); memset(pw0array, 0, sizeof(pw0array)); memset(pw1array, 0, sizeof(pw1array)); diff --git a/src/lib/krb5/krb/init_creds_ctx.h b/src/lib/krb5/krb/init_creds_ctx.h index 4dbb0e92a..6ecf0966c 100644 --- a/src/lib/krb5/krb/init_creds_ctx.h +++ b/src/lib/krb5/krb/init_creds_ctx.h @@ -16,7 +16,8 @@ struct gak_password { }; struct _krb5_init_creds_context { - krb5_gic_opt_ext *opte; + krb5_get_init_creds_opt *opt; + krb5_get_init_creds_opt opt_storage; char *in_tkt_service; krb5_prompter_fct prompter; void *prompter_data; diff --git a/src/lib/krb5/krb/int-proto.h b/src/lib/krb5/krb/int-proto.h index 3a139b520..db6fa95ea 100644 --- a/src/lib/krb5/krb/int-proto.h +++ b/src/lib/krb5/krb/int-proto.h @@ -37,84 +37,6 @@ typedef krb5_error_code krb5_keyblock *as_key, void *gak_data, k5_response_items *ritems); -/* - * Extending the krb5_get_init_creds_opt structure. The original - * krb5_get_init_creds_opt structure is defined publicly. The new extended - * version is private. The original interface assumed a pre-allocated - * structure which was passed to krb5_get_init_creds_init(). The new interface - * assumes that the caller will call krb5_get_init_creds_alloc() and - * krb5_get_init_creds_free(). - * - * Callers MUST NOT call krb5_get_init_creds_init() after allocating an opts - * structure using krb5_get_init_creds_alloc(). To do so will introduce memory - * leaks. Unfortunately, there is no way to enforce this behavior. - * - * Two private flags are added for backward compatibility. GIC_OPT_EXTENDED - * says that the structure was allocated with the new - * krb5_get_init_creds_opt_alloc() function. GIC_OPT_SHADOWED is set to - * indicate that the extended structure is a shadow copy of an original - * krb5_get_init_creds_opt structure. If GIC_OPT_SHADOWED is set after a call - * to k5_gic_opt_to_opte(), the resulting extended structure should be freed - * (using krb5_get_init_creds_free). Otherwise, the original structure was - * already extended and there is no need to free it. - */ - -#define GIC_OPT_EXTENDED 0x80000000 -#define GIC_OPT_SHADOWED 0x40000000 - -#define gic_opt_is_extended(s) ((s) != NULL && ((s)->flags & GIC_OPT_EXTENDED)) -#define gic_opt_is_shadowed(s) ((s) != NULL && ((s)->flags & GIC_OPT_SHADOWED)) - -typedef struct gic_opt_private_st { - int num_preauth_data; - krb5_gic_opt_pa_data *preauth_data; - char * fast_ccache_name; - krb5_ccache in_ccache; - krb5_ccache out_ccache; - krb5_flags fast_flags; - krb5_expire_callback_func expire_cb; - void *expire_data; - krb5_responder_fn responder; - void *responder_data; -} gic_opt_private; - -/* - * On the Mac, ensure that the layout of krb5_gic_opt_ext matches that - * of krb5_get_init_creds_opt. - */ -#if TARGET_OS_MAC -# pragma pack(push,2) -#endif - -typedef struct _krb5_gic_opt_ext { - krb5_flags flags; - krb5_deltat tkt_life; - krb5_deltat renew_life; - int forwardable; - int proxiable; - krb5_enctype *etype_list; - int etype_list_length; - krb5_address **address_list; - krb5_preauthtype *preauth_list; - int preauth_list_length; - krb5_data *salt; - /* - * Do not change anything above this point in this structure. - * It is identical to the public krb5_get_init_creds_opt structure. - * New members must be added below. - */ - gic_opt_private *opt_private; -} krb5_gic_opt_ext; - -#if TARGET_OS_MAC -# pragma pack(pop) -#endif - -krb5_error_code -k5_gic_opt_to_opte(krb5_context context, krb5_get_init_creds_opt *opt, - krb5_gic_opt_ext **opte, unsigned int force, - const char *where); - krb5_error_code krb5int_tgtname(krb5_context context, const krb5_data *, const krb5_data *, krb5_principal *); @@ -137,9 +59,8 @@ krb5_error_code krb5_ser_authdata_context_init (krb5_context); krb5_error_code krb5_preauth_supply_preauth_data(krb5_context context, - krb5_gic_opt_ext *opte, - const char *attr, - const char *value); + krb5_get_init_creds_opt *opt, + const char *attr, const char *value); krb5_error_code clpreauth_encrypted_challenge_initvt(krb5_context context, int maj_ver, @@ -278,7 +199,7 @@ void k5_reset_preauth_types_tried(krb5_context context); void -k5_preauth_prepare_request(krb5_context context, krb5_gic_opt_ext *opte, +k5_preauth_prepare_request(krb5_context context, krb5_get_init_creds_opt *opt, krb5_kdc_req *request); void @@ -368,4 +289,37 @@ k5_count_etypes(const krb5_enctype *list); krb5_error_code k5_copy_etypes(const krb5_enctype *old_list, krb5_enctype **new_list); +krb5_ccache +k5_gic_opt_get_in_ccache(krb5_get_init_creds_opt *opt); + +krb5_ccache +k5_gic_opt_get_out_ccache(krb5_get_init_creds_opt *opt); + +const char * +k5_gic_opt_get_fast_ccache_name(krb5_get_init_creds_opt *opt); + +krb5_flags +k5_gic_opt_get_fast_flags(krb5_get_init_creds_opt *opt); + +void +k5_gic_opt_get_expire_cb(krb5_get_init_creds_opt *opt, + krb5_expire_callback_func *cb_out, void **data_out); + +void +k5_gic_opt_get_responder(krb5_get_init_creds_opt *opt, + krb5_responder_fn *responder_out, void **data_out); + +/* + * Make a shallow copy of opt, with all pointer fields aliased, or NULL on an + * out-of-memory failure. The caller must free the result with free, and must + * not use it with the following functions: + * + * krb5_get_init_creds_opt_free + * krb5_get_init_creds_opt_set_pa + * krb5_get_init_creds_opt_set_fast_ccache + * krb5_get_init_creds_opt_set_fast_ccache_name + */ +krb5_get_init_creds_opt * +k5_gic_opt_shallow_copy(krb5_get_init_creds_opt *opt); + #endif /* KRB5_INT_FUNC_PROTO__ */ diff --git a/src/lib/krb5/krb/preauth2.c b/src/lib/krb5/krb/preauth2.c index f1b364dd9..cda91b908 100644 --- a/src/lib/krb5/krb/preauth2.c +++ b/src/lib/krb5/krb/preauth2.c @@ -492,7 +492,7 @@ static struct krb5_clpreauth_callbacks_st callbacks = { * to add support for to the list, but in the future perhaps doing more * involved things. */ void -k5_preauth_prepare_request(krb5_context context, krb5_gic_opt_ext *opte, +k5_preauth_prepare_request(krb5_context context, krb5_get_init_creds_opt *opt, krb5_kdc_req *req) { struct krb5_preauth_context_st *pctx = context->preauth_context; @@ -502,7 +502,7 @@ k5_preauth_prepare_request(krb5_context context, krb5_gic_opt_ext *opte, if (pctx == NULL) return; /* Don't modify the enctype list if it's specified in the gic opts. */ - if (opte != NULL && (opte->flags & KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST)) + if (opt != NULL && (opt->flags & KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST)) return; for (hp = pctx->handles; *hp != NULL; hp++) { h = *hp; @@ -586,7 +586,6 @@ process_pa_data(krb5_context context, krb5_init_creds_context ctx, krb5_preauthtype *out_type) { struct krb5_preauth_context_st *pctx = context->preauth_context; - krb5_get_init_creds_opt *opt = (krb5_get_init_creds_opt *)ctx->opte; struct errinfo save = EMPTY_ERRINFO; krb5_pa_data *pa, **pa_ptr, **mod_pa; krb5_error_code ret = 0; @@ -614,7 +613,7 @@ process_pa_data(krb5_context context, krb5_init_creds_context ctx, if (real && already_tried(context, pa->pa_type)) continue; mod_pa = NULL; - ret = clpreauth_process(context, h, opt, &callbacks, + ret = clpreauth_process(context, h, ctx->opt, &callbacks, (krb5_clpreauth_rock)ctx, ctx->request, ctx->inner_request_body, ctx->encoded_previous_request, pa, @@ -863,7 +862,6 @@ k5_preauth_tryagain(krb5_context context, krb5_init_creds_context ctx, struct krb5_preauth_context_st *pctx = context->preauth_context; krb5_error_code ret; krb5_pa_data **mod_pa; - krb5_get_init_creds_opt *opt = (krb5_get_init_creds_opt *)ctx->opte; clpreauth_handle h; int i; @@ -878,7 +876,7 @@ k5_preauth_tryagain(krb5_context context, krb5_init_creds_context ctx, if (h == NULL) continue; mod_pa = NULL; - ret = clpreauth_tryagain(context, h, opt, &callbacks, + ret = clpreauth_tryagain(context, h, ctx->opt, &callbacks, (krb5_clpreauth_rock)ctx, ctx->request, ctx->inner_request_body, ctx->encoded_previous_request, @@ -901,7 +899,6 @@ fill_response_items(krb5_context context, krb5_init_creds_context ctx, krb5_pa_data **in_padata) { struct krb5_preauth_context_st *pctx = context->preauth_context; - krb5_get_init_creds_opt *opt = (krb5_get_init_creds_opt *)ctx->opte; krb5_error_code ret; krb5_pa_data *pa; clpreauth_handle h; @@ -915,7 +912,7 @@ fill_response_items(krb5_context context, krb5_init_creds_context ctx, h = find_module(pctx->handles, pa->pa_type); if (h == NULL) continue; - ret = clpreauth_prep_questions(context, h, opt, &callbacks, + ret = clpreauth_prep_questions(context, h, ctx->opt, &callbacks, (krb5_clpreauth_rock)ctx, ctx->request, ctx->inner_request_body, ctx->encoded_previous_request, pa); @@ -933,8 +930,8 @@ k5_preauth(krb5_context context, krb5_init_creds_context ctx, int out_pa_list_size = 0; krb5_pa_data **out_pa_list = NULL; krb5_error_code ret; - krb5_responder_fn responder = ctx->opte->opt_private->responder; - void *responder_data = ctx->opte->opt_private->responder_data; + krb5_responder_fn responder; + void *responder_data; *padata_out = NULL; *pa_type_out = KRB5_PADATA_NONE; @@ -978,6 +975,7 @@ k5_preauth(krb5_context context, krb5_init_creds_context ctx, goto error; /* Call the responder to answer response items. */ + k5_gic_opt_get_responder(ctx->opt, &responder, &responder_data); if (responder != NULL && !k5_response_items_empty(ctx->rctx.items)) { ret = (*responder)(context, responder_data, &ctx->rctx); if (ret) @@ -1003,11 +1001,11 @@ error: * has just been set */ krb5_error_code -krb5_preauth_supply_preauth_data(krb5_context context, krb5_gic_opt_ext *opte, +krb5_preauth_supply_preauth_data(krb5_context context, + krb5_get_init_creds_opt *opt, const char *attr, const char *value) { struct krb5_preauth_context_st *pctx = context->preauth_context; - krb5_get_init_creds_opt *opt = (krb5_get_init_creds_opt *)opte; clpreauth_handle *hp, h; krb5_error_code ret; const char *emsg = NULL; |