mirror of
https://github.com/samba-team/samba.git
synced 2025-01-08 21:18:16 +03:00
third_party/heimdal: Provide krb5_init_creds_opt_set_fast_ccache() and krb5_init_creds_opt_set_fast_flags() (import lorikeet-heimdal-202311290114 (commit 4c8517e161396330c76240bf09609a0dd5f9ea20))
It is easier for external callers to manipulate the krb5_get_init_creds_opt (via the helpers) as this is passed down from higher up than the krb5_init_creds_context. And just as importantly, alignment with MIT makes end-user callers happier. Finally, this resolves the ambiguity as to which layer owns the krb5_ccache, because now we match the MIT behaviour the init_creds code re-opens a private copy inside libkrb5, meaning the caller closes the cache it opened, rather than handing it over to the library. (The unrelated changes are fixes to the test_pac test, also included in this import, but in distinct lorikeet-heimdal commits, to allow it to compile) Signed-off-by: Andrew Bartlett <abartlet@samba.org> Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz>
This commit is contained in:
parent
a757a51a26
commit
6222d572ee
16
third_party/heimdal/kdc/kdc-tester.c
vendored
16
third_party/heimdal/kdc/kdc-tester.c
vendored
@ -258,10 +258,6 @@ eval_kinit(heim_dict_t o)
|
||||
krb5_err(kdc_context, 1, ret, "krb5_get_init_creds_opt_set_pkinit");
|
||||
}
|
||||
|
||||
ret = krb5_init_creds_init(kdc_context, client, NULL, NULL, 0, opt, &ctx);
|
||||
if (ret)
|
||||
krb5_err(kdc_context, 1, ret, "krb5_init_creds_init");
|
||||
|
||||
fast_armor_cc = heim_dict_get_value(o, HSTR("fast-armor-cc"));
|
||||
if (fast_armor_cc) {
|
||||
|
||||
@ -269,13 +265,21 @@ eval_kinit(heim_dict_t o)
|
||||
if (ret)
|
||||
krb5_err(kdc_context, 1, ret, "krb5_cc_resolve");
|
||||
|
||||
ret = krb5_init_creds_set_fast_ccache(kdc_context, ctx, fast_cc);
|
||||
ret = krb5_get_init_creds_opt_set_fast_ccache(kdc_context, opt, fast_cc);
|
||||
if (ret)
|
||||
krb5_err(kdc_context, 1, ret, "krb5_init_creds_set_fast_ccache");
|
||||
krb5_err(kdc_context, 1, ret, "krb5_get_init_creds_set_fast_ccache");
|
||||
|
||||
ret = krb5_get_init_creds_opt_set_fast_flags(kdc_context, opt, KRB5_FAST_REQUIRED|KRB5_FAST_KDC_VERIFIED);
|
||||
if (ret)
|
||||
krb5_err(kdc_context, 1, ret, "krb5_get_init_creds_set_fast_ccache");
|
||||
|
||||
fast_cc = NULL;
|
||||
}
|
||||
|
||||
ret = krb5_init_creds_init(kdc_context, client, NULL, NULL, 0, opt, &ctx);
|
||||
if (ret)
|
||||
krb5_err(kdc_context, 1, ret, "krb5_init_creds_init");
|
||||
|
||||
if (password) {
|
||||
ret = krb5_init_creds_set_password(kdc_context, ctx,
|
||||
heim_string_get_utf8(password));
|
||||
|
50
third_party/heimdal/kuser/kinit.c
vendored
50
third_party/heimdal/kuser/kinit.c
vendored
@ -742,6 +742,7 @@ get_new_tickets(krb5_context context,
|
||||
gss_cred_id_t gss_cred = GSS_C_NO_CREDENTIAL;
|
||||
gss_OID gss_mech = GSS_C_NO_OID;
|
||||
krb5_principal federated_name = NULL;
|
||||
krb5_ccache fastid = NULL;
|
||||
|
||||
#ifndef NO_NTLM
|
||||
struct ntlm_buf ntlmkey;
|
||||
@ -970,6 +971,33 @@ get_new_tickets(krb5_context context,
|
||||
}
|
||||
}
|
||||
|
||||
if (fast_armor_cache_string) {
|
||||
if (pk_anon_fast_armor > 0)
|
||||
krb5_errx(context, 1,
|
||||
N_("cannot specify FAST armor cache with FAST "
|
||||
"anonymous PKINIT option", ""));
|
||||
pk_anon_fast_armor = 0;
|
||||
|
||||
ret = krb5_cc_resolve(context, fast_armor_cache_string, &fastid);
|
||||
if (ret) {
|
||||
krb5_warn(context, ret, "krb5_cc_resolve(FAST cache)");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = krb5_get_init_creds_opt_set_fast_ccache(context, opt, fastid);
|
||||
if (ret) {
|
||||
krb5_warn(context, ret, "krb5_init_creds_set_fast_ccache");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = krb5_get_init_creds_opt_set_fast_flags(context, opt,
|
||||
KRB5_FAST_REQUIRED);
|
||||
if (ret) {
|
||||
krb5_warn(context, ret, "krb5_init_creds_set_fast_flags");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
ret = krb5_init_creds_init(context, principal, prompter, NULL, start_time, opt, &ctx);
|
||||
if (ret) {
|
||||
krb5_warn(context, ret, "krb5_init_creds_init");
|
||||
@ -1001,25 +1029,7 @@ get_new_tickets(krb5_context context,
|
||||
}
|
||||
|
||||
if (fast_armor_cache_string) {
|
||||
krb5_ccache fastid = NULL;
|
||||
|
||||
if (pk_anon_fast_armor > 0)
|
||||
krb5_errx(context, 1,
|
||||
N_("cannot specify FAST armor cache with FAST "
|
||||
"anonymous PKINIT option", ""));
|
||||
pk_anon_fast_armor = 0;
|
||||
|
||||
ret = krb5_cc_resolve(context, fast_armor_cache_string, &fastid);
|
||||
if (ret) {
|
||||
krb5_warn(context, ret, "krb5_cc_resolve(FAST cache)");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = krb5_init_creds_set_fast_ccache(context, ctx, fastid);
|
||||
if (ret) {
|
||||
krb5_warn(context, ret, "krb5_init_creds_set_fast_ccache");
|
||||
goto out;
|
||||
}
|
||||
/* handled above */
|
||||
} else if (pk_anon_fast_armor == -1) {
|
||||
ret = _krb5_init_creds_set_fast_anon_pkinit_optimistic(context, ctx);
|
||||
if (ret) {
|
||||
@ -1227,6 +1237,8 @@ out:
|
||||
krb5_cc_destroy(context, tempccache);
|
||||
if (enctype)
|
||||
free(enctype);
|
||||
if (fastid)
|
||||
krb5_cc_close(context, fastid);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
46
third_party/heimdal/lib/krb5/init_creds.c
vendored
46
third_party/heimdal/lib/krb5/init_creds.c
vendored
@ -89,6 +89,7 @@ krb5_get_init_creds_opt_free(krb5_context context,
|
||||
return;
|
||||
if (--opt->opt_private->refcount == 0) {
|
||||
_krb5_get_init_creds_opt_free_pkinit(opt);
|
||||
free(opt->opt_private->fast_armor_ccache_name);
|
||||
free(opt->opt_private);
|
||||
}
|
||||
memset(opt, 0, sizeof(*opt));
|
||||
@ -393,6 +394,51 @@ krb5_get_init_creds_opt_set_process_last_req(krb5_context context,
|
||||
return 0;
|
||||
}
|
||||
|
||||
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
|
||||
krb5_get_init_creds_opt_set_fast_ccache(krb5_context context,
|
||||
krb5_get_init_creds_opt *opt,
|
||||
krb5_ccache fast_ccache)
|
||||
{
|
||||
char *fast_ccache_name;
|
||||
int ret = krb5_cc_get_full_name(context,
|
||||
fast_ccache,
|
||||
&fast_ccache_name);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = krb5_get_init_creds_opt_set_fast_ccache_name(context,
|
||||
opt,
|
||||
fast_ccache_name);
|
||||
krb5_xfree(fast_ccache_name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
|
||||
krb5_get_init_creds_opt_set_fast_ccache_name(krb5_context context,
|
||||
krb5_get_init_creds_opt *opt,
|
||||
const char *fast_ccache_name)
|
||||
{
|
||||
if (opt->opt_private->fast_armor_ccache_name)
|
||||
free(opt->opt_private->fast_armor_ccache_name);
|
||||
|
||||
opt->opt_private->fast_armor_ccache_name = strdup(fast_ccache_name);
|
||||
if (opt->opt_private->fast_armor_ccache_name == NULL)
|
||||
return krb5_enomem(context);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
|
||||
krb5_get_init_creds_opt_set_fast_flags(krb5_context context,
|
||||
krb5_get_init_creds_opt *opt,
|
||||
krb5_flags flags)
|
||||
{
|
||||
heim_assert((flags & ~KRB5_FAST_PUBLIC_FLAGS) == 0, "invalid flags passed to krb5_get_init_creds_opt_set_fast_flags()");
|
||||
opt->opt_private->fast_flags = flags;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifndef HEIMDAL_SMALLER
|
||||
|
||||
|
19
third_party/heimdal/lib/krb5/init_creds_pw.c
vendored
19
third_party/heimdal/lib/krb5/init_creds_pw.c
vendored
@ -579,6 +579,25 @@ get_init_creds_common(krb5_context context,
|
||||
else
|
||||
ctx->runflags.change_password_prompt = ctx->prompter != NULL;
|
||||
|
||||
if (options->opt_private->fast_armor_ccache_name) {
|
||||
/* Open the caller-supplied FAST ccache and set the caller flags */
|
||||
ret = krb5_cc_resolve(context, options->opt_private->fast_armor_ccache_name,
|
||||
&ctx->fast_state.armor_ccache);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
ctx->fast_state.flags = options->opt_private->fast_flags;
|
||||
|
||||
/*
|
||||
* If FAST is required with a real credential cache, then the KDC
|
||||
* will be verified. This allows the
|
||||
* krb5_get_init_creds_opt_set_fast API to work like MIT without
|
||||
* exposing KRB5_FAST_KDC_VERIFIED to callers
|
||||
*/
|
||||
if (ctx->fast_state.flags & KRB5_FAST_REQUIRED)
|
||||
ctx->fast_state.flags |= KRB5_FAST_KDC_VERIFIED;
|
||||
|
||||
out:
|
||||
if (default_opt)
|
||||
krb5_get_init_creds_opt_free(context, default_opt);
|
||||
|
2
third_party/heimdal/lib/krb5/krb5.h
vendored
2
third_party/heimdal/lib/krb5/krb5.h
vendored
@ -804,6 +804,8 @@ typedef struct _krb5_get_init_creds_opt krb5_get_init_creds_opt;
|
||||
#define KRB5_GET_INIT_CREDS_OPT_DISABLE_TRANSITED_CHECK 0x0200
|
||||
#define KRB5_GET_INIT_CREDS_OPT_CHANGE_PASSWORD_PROMPT 0x0400
|
||||
|
||||
#define KRB5_FAST_REQUIRED 0x0001 /* fast required by action of caller */
|
||||
|
||||
/* krb5_init_creds_step flags argument */
|
||||
#define KRB5_INIT_CREDS_STEP_FLAG_CONTINUE 0x0001
|
||||
|
||||
|
33
third_party/heimdal/lib/krb5/krb5_locl.h
vendored
33
third_party/heimdal/lib/krb5/krb5_locl.h
vendored
@ -263,6 +263,9 @@ struct _krb5_get_init_creds_opt_private {
|
||||
krb5_gic_process_last_req func;
|
||||
void *ctx;
|
||||
} lr;
|
||||
|
||||
krb5_flags fast_flags;
|
||||
char *fast_armor_ccache_name;
|
||||
};
|
||||
|
||||
typedef uint32_t krb5_enctype_set;
|
||||
@ -433,22 +436,24 @@ struct krb5_pk_init_ctx_data {
|
||||
struct krb5_fast_state {
|
||||
enum PA_FX_FAST_REQUEST_enum type;
|
||||
unsigned int flags;
|
||||
#define KRB5_FAST_REPLY_KEY_USE_TO_ENCRYPT_THE_REPLY 0x0001
|
||||
#define KRB5_FAST_REPLY_KEY_USE_IN_TRANSACTION 0x0002
|
||||
#define KRB5_FAST_KDC_REPLY_KEY_REPLACED 0x0004
|
||||
#define KRB5_FAST_REPLY_REPLY_VERIFIED 0x0008
|
||||
#define KRB5_FAST_STRONG 0x0010
|
||||
#define KRB5_FAST_EXPECTED 0x0020 /* in exchange with KDC, fast was discovered */
|
||||
#define KRB5_FAST_REQUIRED 0x0040 /* fast required by action of caller */
|
||||
#define KRB5_FAST_DISABLED 0x0080
|
||||
#define KRB5_FAST_PUBLIC_FLAGS 0x0000ff
|
||||
/* #define KRB5_FAST_REQUIRED 0x000001 - fast required by action of caller defined in krb5.h*/
|
||||
|
||||
#define KRB5_FAST_AP_ARMOR_SERVICE 0x0100
|
||||
#define KRB5_FAST_OPTIMISTIC 0x0200 /* Optimistic try, like Anon + PKINIT or service fast bit */
|
||||
#define KRB5_FAST_REQUIRE_ENC_PA 0x0400
|
||||
#define KRB5_FAST_REPLY_KEY_USE_TO_ENCRYPT_THE_REPLY 0x000100
|
||||
#define KRB5_FAST_REPLY_KEY_USE_IN_TRANSACTION 0x000200
|
||||
#define KRB5_FAST_KDC_REPLY_KEY_REPLACED 0x000400
|
||||
#define KRB5_FAST_REPLY_REPLY_VERIFIED 0x000800
|
||||
#define KRB5_FAST_STRONG 0x001000
|
||||
#define KRB5_FAST_EXPECTED 0x002000 /* in exchange with KDC, fast was discovered */
|
||||
#define KRB5_FAST_DISABLED 0x008000
|
||||
|
||||
#define KRB5_FAST_AS_REQ 0x1000
|
||||
#define KRB5_FAST_ANON_PKINIT_ARMOR 0x2000
|
||||
#define KRB5_FAST_KDC_VERIFIED 0x4000
|
||||
#define KRB5_FAST_AP_ARMOR_SERVICE 0x010000
|
||||
#define KRB5_FAST_OPTIMISTIC 0x020000 /* Optimistic try, like Anon + PKINIT or service fast bit */
|
||||
#define KRB5_FAST_REQUIRE_ENC_PA 0x040000
|
||||
|
||||
#define KRB5_FAST_AS_REQ 0x100000
|
||||
#define KRB5_FAST_ANON_PKINIT_ARMOR 0x200000
|
||||
#define KRB5_FAST_KDC_VERIFIED 0x400000
|
||||
|
||||
krb5_keyblock *reply_key;
|
||||
krb5_ccache armor_ccache;
|
||||
|
@ -374,6 +374,9 @@ EXPORTS
|
||||
krb5_get_init_creds_opt_set_salt
|
||||
krb5_get_init_creds_opt_set_tkt_life
|
||||
krb5_get_init_creds_opt_set_win2k
|
||||
krb5_get_init_creds_opt_set_fast_ccache
|
||||
krb5_get_init_creds_opt_set_fast_ccache_name
|
||||
krb5_get_init_creds_opt_set_fast_flags
|
||||
krb5_get_init_creds_password
|
||||
krb5_get_instance
|
||||
krb5_get_kdc_cred
|
||||
|
38
third_party/heimdal/lib/krb5/test_pac.c
vendored
38
third_party/heimdal/lib/krb5/test_pac.c
vendored
@ -872,8 +872,12 @@ check_ticket_signature(krb5_context context,
|
||||
&ticket.sname) == !!signedticket,
|
||||
"ticket-signature");
|
||||
|
||||
/*
|
||||
* We have to not verify the KDC checksum as the saved PAC has no
|
||||
* full checksum, and krb5_pac_verify requires this now
|
||||
*/
|
||||
ret = krb5_pac_verify(context, pac, et.authtime, client,
|
||||
tkt->key, tkt->kdc_key);
|
||||
tkt->key, NULL);
|
||||
if (ret)
|
||||
t_err(context, tkt->name, "krb5_pac_verify ticket-sig", ret);
|
||||
|
||||
@ -894,9 +898,13 @@ check_ticket_signature(krb5_context context,
|
||||
if (ret)
|
||||
t_err(context, tkt->name, "remove_AuthorizationData", ret);
|
||||
|
||||
/*
|
||||
* While we should do a full PAC signature in the same case as
|
||||
* signedticket, the saved examples do not have one
|
||||
*/
|
||||
ret = _krb5_kdc_pac_sign_ticket(context, pac, client, tkt->key,
|
||||
tkt->kdc_key, tkt->rodc_id,
|
||||
NULL, NULL, signedticket, &et, NULL);
|
||||
NULL, NULL, signedticket, FALSE, &et, NULL);
|
||||
if (ret)
|
||||
t_err(context, tkt->name, "_krb5_kdc_pac_sign_ticket", ret);
|
||||
|
||||
@ -915,9 +923,14 @@ check_ticket_signature(krb5_context context,
|
||||
if (ret)
|
||||
t_err(context, tkt->name, "remove_AuthorizationData 2", ret);
|
||||
|
||||
/*
|
||||
* This time we will not be doing a krb5_data_cmp() so we add the
|
||||
* full signature so that we can run that check in
|
||||
* krb5_pac_verify()
|
||||
*/
|
||||
ret = _krb5_kdc_pac_sign_ticket(context, pac, client, tkt->key,
|
||||
tkt->kdc_key, tkt->rodc_id,
|
||||
NULL, NULL, signedticket, &et, NULL);
|
||||
NULL, NULL, signedticket, TRUE, &et, NULL);
|
||||
if (ret)
|
||||
t_err(context, tkt->name, "_krb5_kdcsignedticketsign_ticket 2", ret);
|
||||
|
||||
@ -1015,13 +1028,18 @@ main(int argc, char **argv)
|
||||
if (ret)
|
||||
krb5_err(context, 1, ret, "krb5_pac_parse");
|
||||
|
||||
/*
|
||||
* We have to not verify the KDC checksum as the saved PAC has no
|
||||
* full checksum, and krb5_pac_verify requires this now
|
||||
*/
|
||||
ret = krb5_pac_verify(context, pac, authtime, p,
|
||||
&member_keyblock, &kdc_keyblock);
|
||||
&member_keyblock, NULL);
|
||||
if (ret)
|
||||
krb5_err(context, 1, ret, "krb5_pac_verify");
|
||||
|
||||
ret = _krb5_pac_sign(context, pac, authtime, p,
|
||||
&member_keyblock, &kdc_keyblock, 0, NULL, NULL,
|
||||
TRUE,
|
||||
NULL, &data);
|
||||
if (ret)
|
||||
krb5_err(context, 1, ret, "_krb5_pac_sign");
|
||||
@ -1048,14 +1066,14 @@ main(int argc, char **argv)
|
||||
if (ret)
|
||||
krb5_err(context, 1, ret, "krb5_pac_init");
|
||||
|
||||
/* our two user buffer plus the three "system" buffers */
|
||||
/* our two user buffer plus the four "system" buffers */
|
||||
ret = krb5_pac_get_types(context, pac, &len, &list);
|
||||
if (ret)
|
||||
krb5_err(context, 1, ret, "krb5_pac_get_types");
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
/* skip server_cksum, privsvr_cksum, and logon_name */
|
||||
if (list[i] == 6 || list[i] == 7 || list[i] == 10)
|
||||
if (list[i] == 6 || list[i] == 7 || list[i] == 10 || list[i] == 19)
|
||||
continue;
|
||||
|
||||
ret = krb5_pac_get_buffer(context, pac, list[i], &data);
|
||||
@ -1079,7 +1097,7 @@ main(int argc, char **argv)
|
||||
|
||||
ret = _krb5_pac_sign(context, pac2, authtime, p,
|
||||
&member_keyblock, &kdc_keyblock, 0,
|
||||
NULL, NULL, NULL, &data);
|
||||
NULL, NULL, TRUE, NULL, &data);
|
||||
if (ret)
|
||||
krb5_err(context, 1, ret, "_krb5_pac_sign 4");
|
||||
|
||||
@ -1179,7 +1197,7 @@ main(int argc, char **argv)
|
||||
|
||||
ret = _krb5_pac_sign(context, pac, authtime, p,
|
||||
&member_keyblock, &kdc_keyblock, 0,
|
||||
NULL, NULL, NULL, &data);
|
||||
NULL, NULL, TRUE, NULL, &data);
|
||||
if (ret)
|
||||
krb5_err(context, 1, ret, "_krb5_pac_sign");
|
||||
|
||||
@ -1199,11 +1217,11 @@ main(int argc, char **argv)
|
||||
uint32_t *list;
|
||||
size_t len;
|
||||
|
||||
/* our two user buffer plus the three "system" buffers */
|
||||
/* our two user buffer plus the four "system" buffers */
|
||||
ret = krb5_pac_get_types(context, pac, &len, &list);
|
||||
if (ret)
|
||||
krb5_err(context, 1, ret, "krb5_pac_get_types");
|
||||
if (len != 5)
|
||||
if (len != 6)
|
||||
krb5_errx(context, 1, "list wrong length");
|
||||
free(list);
|
||||
}
|
||||
|
@ -370,6 +370,9 @@ HEIMDAL_KRB5_2.0 {
|
||||
krb5_get_init_creds_opt_set_salt;
|
||||
krb5_get_init_creds_opt_set_tkt_life;
|
||||
krb5_get_init_creds_opt_set_win2k;
|
||||
krb5_get_init_creds_opt_set_fast_ccache;
|
||||
krb5_get_init_creds_opt_set_fast_ccache_name;
|
||||
krb5_get_init_creds_opt_set_fast_flags;
|
||||
krb5_get_init_creds_password;
|
||||
krb5_get_instance;
|
||||
krb5_get_kdc_cred;
|
||||
|
Loading…
Reference in New Issue
Block a user