summaryrefslogtreecommitdiffstats
path: root/src/lib/krb5/krb
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/krb5/krb')
-rw-r--r--src/lib/krb5/krb/Makefile.in3
-rw-r--r--src/lib/krb5/krb/deps11
-rw-r--r--src/lib/krb5/krb/fast.c15
-rw-r--r--src/lib/krb5/krb/fast.h2
-rw-r--r--src/lib/krb5/krb/get_in_tkt.c102
-rw-r--r--src/lib/krb5/krb/gic_opt.c439
-rw-r--r--src/lib/krb5/krb/gic_opt_set_pa.c99
-rw-r--r--src/lib/krb5/krb/gic_pwd.c53
-rw-r--r--src/lib/krb5/krb/init_creds_ctx.h3
-rw-r--r--src/lib/krb5/krb/int-proto.h118
-rw-r--r--src/lib/krb5/krb/preauth2.c22
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;