mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
s4-kerberos: obey the credentials setting for forwardable tickets
Pair-Programmed-With: Andrew Bartlett <abartlet@samba.org>
This commit is contained in:
parent
efb37a5b8c
commit
89827af525
@ -41,31 +41,23 @@
|
||||
krb5_error_code kerberos_kinit_keyblock_cc(krb5_context ctx, krb5_ccache cc,
|
||||
krb5_principal principal, krb5_keyblock *keyblock,
|
||||
const char *target_service,
|
||||
krb5_get_init_creds_opt *krb_options,
|
||||
time_t *expire_time, time_t *kdc_time)
|
||||
{
|
||||
krb5_error_code code = 0;
|
||||
krb5_creds my_creds;
|
||||
krb5_get_init_creds_opt *options;
|
||||
|
||||
if ((code = krb5_get_init_creds_opt_alloc(ctx, &options))) {
|
||||
return code;
|
||||
}
|
||||
|
||||
krb5_get_init_creds_opt_set_default_flags(ctx, NULL, NULL, options);
|
||||
|
||||
if ((code = krb5_get_init_creds_keyblock(ctx, &my_creds, principal, keyblock,
|
||||
0, target_service, options))) {
|
||||
0, target_service, krb_options))) {
|
||||
return code;
|
||||
}
|
||||
|
||||
if ((code = krb5_cc_initialize(ctx, cc, principal))) {
|
||||
krb5_get_init_creds_opt_free(ctx, options);
|
||||
krb5_free_cred_contents(ctx, &my_creds);
|
||||
return code;
|
||||
}
|
||||
|
||||
if ((code = krb5_cc_store_cred(ctx, cc, &my_creds))) {
|
||||
krb5_get_init_creds_opt_free(ctx, options);
|
||||
krb5_free_cred_contents(ctx, &my_creds);
|
||||
return code;
|
||||
}
|
||||
@ -78,7 +70,6 @@
|
||||
*kdc_time = (time_t) my_creds.times.starttime;
|
||||
}
|
||||
|
||||
krb5_get_init_creds_opt_free(ctx, options);
|
||||
krb5_free_cred_contents(ctx, &my_creds);
|
||||
|
||||
return 0;
|
||||
@ -96,20 +87,14 @@
|
||||
krb5_error_code kerberos_kinit_password_cc(krb5_context ctx, krb5_ccache cc,
|
||||
krb5_principal principal, const char *password,
|
||||
krb5_principal impersonate_principal, const char *target_service,
|
||||
krb5_get_init_creds_opt *krb_options,
|
||||
time_t *expire_time, time_t *kdc_time)
|
||||
{
|
||||
krb5_error_code code = 0;
|
||||
krb5_creds my_creds;
|
||||
krb5_creds *impersonate_creds;
|
||||
krb5_get_init_creds_opt *init_options;
|
||||
krb5_get_creds_opt options;
|
||||
|
||||
if ((code = krb5_get_init_creds_opt_alloc(ctx, &init_options))) {
|
||||
return code;
|
||||
}
|
||||
|
||||
krb5_get_init_creds_opt_set_default_flags(ctx, NULL, NULL, init_options);
|
||||
|
||||
/* If we are not impersonating, then get this ticket for the
|
||||
* target service, otherwise a krbtgt, and get the next ticket
|
||||
* for the target */
|
||||
@ -117,19 +102,16 @@
|
||||
NULL, NULL,
|
||||
0,
|
||||
impersonate_principal ? NULL : target_service,
|
||||
init_options))) {
|
||||
krb5_get_init_creds_opt_free(ctx, init_options);
|
||||
krb_options))) {
|
||||
return code;
|
||||
}
|
||||
|
||||
if ((code = krb5_cc_initialize(ctx, cc, principal))) {
|
||||
krb5_get_init_creds_opt_free(ctx, init_options);
|
||||
krb5_free_cred_contents(ctx, &my_creds);
|
||||
return code;
|
||||
}
|
||||
|
||||
if ((code = krb5_cc_store_cred(ctx, cc, &my_creds))) {
|
||||
krb5_get_init_creds_opt_free(ctx, init_options);
|
||||
krb5_free_cred_contents(ctx, &my_creds);
|
||||
return code;
|
||||
}
|
||||
@ -142,7 +124,6 @@
|
||||
*kdc_time = (time_t) my_creds.times.starttime;
|
||||
}
|
||||
|
||||
krb5_get_init_creds_opt_free(ctx, init_options);
|
||||
krb5_free_cred_contents(ctx, &my_creds);
|
||||
|
||||
if (code == 0 && impersonate_principal) {
|
||||
|
@ -94,11 +94,13 @@ bool get_auth_data_from_tkt(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, krb5_tick
|
||||
krb5_error_code kerberos_kinit_password_cc(krb5_context ctx, krb5_ccache cc,
|
||||
krb5_principal principal, const char *password,
|
||||
krb5_principal impersonate_principal, const char *target_service,
|
||||
krb5_get_init_creds_opt *krb_options,
|
||||
time_t *expire_time, time_t *kdc_time);
|
||||
krb5_error_code kerberos_kinit_keyblock_cc(krb5_context ctx, krb5_ccache cc,
|
||||
krb5_principal principal, krb5_keyblock *keyblock,
|
||||
const char *target_service,
|
||||
time_t *expire_time, time_t *kdc_time);
|
||||
krb5_principal principal, krb5_keyblock *keyblock,
|
||||
const char *target_service,
|
||||
krb5_get_init_creds_opt *krb_options,
|
||||
time_t *expire_time, time_t *kdc_time);
|
||||
krb5_principal kerberos_fetch_salt_princ_for_host_princ(krb5_context context,
|
||||
krb5_principal host_princ,
|
||||
int enctype);
|
||||
|
@ -200,6 +200,7 @@ static krb5_error_code salt_principal_from_credentials(TALLOC_CTX *parent_ctx,
|
||||
krb5_principal impersonate_principal;
|
||||
int tries;
|
||||
TALLOC_CTX *mem_ctx = talloc_new(parent_ctx);
|
||||
krb5_get_init_creds_opt *krb_options;
|
||||
|
||||
if (!mem_ctx) {
|
||||
(*error_string) = strerror(ENOMEM);
|
||||
@ -222,12 +223,37 @@ static krb5_error_code salt_principal_from_credentials(TALLOC_CTX *parent_ctx,
|
||||
|
||||
password = cli_credentials_get_password(credentials);
|
||||
|
||||
/* setup the krb5 options we want */
|
||||
if ((ret = krb5_get_init_creds_opt_alloc(smb_krb5_context->krb5_context, &krb_options))) {
|
||||
(*error_string) = talloc_asprintf(credentials, "krb5_get_init_creds_opt_alloc failed (%s)\n",
|
||||
smb_get_krb5_error_message(smb_krb5_context->krb5_context,
|
||||
ret, mem_ctx));
|
||||
talloc_free(mem_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* get the defaults */
|
||||
krb5_get_init_creds_opt_set_default_flags(smb_krb5_context->krb5_context, NULL, NULL, krb_options);
|
||||
|
||||
/* set if we want a forwardable ticket */
|
||||
switch (cli_credentials_get_krb_forwardable(credentials)) {
|
||||
case CRED_AUTO_KRB_FORWARDABLE:
|
||||
break;
|
||||
case CRED_NO_KRB_FORWARDABLE:
|
||||
krb5_get_init_creds_opt_set_forwardable(krb_options, FALSE);
|
||||
break;
|
||||
case CRED_FORCE_KRB_FORWARDABLE:
|
||||
krb5_get_init_creds_opt_set_forwardable(krb_options, TRUE);
|
||||
break;
|
||||
}
|
||||
|
||||
tries = 2;
|
||||
while (tries--) {
|
||||
if (password) {
|
||||
ret = kerberos_kinit_password_cc(smb_krb5_context->krb5_context, ccache,
|
||||
princ, password,
|
||||
impersonate_principal, target_service,
|
||||
krb_options,
|
||||
NULL, &kdc_time);
|
||||
} else if (impersonate_principal) {
|
||||
(*error_string) = "INTERNAL error: Cannot impersonate principal with just a keyblock. A password must be specified in the credentials";
|
||||
@ -241,6 +267,7 @@ static krb5_error_code salt_principal_from_credentials(TALLOC_CTX *parent_ctx,
|
||||
if (!mach_pwd) {
|
||||
talloc_free(mem_ctx);
|
||||
(*error_string) = "kinit_to_ccache: No password available for kinit\n";
|
||||
krb5_get_init_creds_opt_free(smb_krb5_context->krb5_context, krb_options);
|
||||
return EINVAL;
|
||||
}
|
||||
ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
|
||||
@ -251,7 +278,7 @@ static krb5_error_code salt_principal_from_credentials(TALLOC_CTX *parent_ctx,
|
||||
if (ret == 0) {
|
||||
ret = kerberos_kinit_keyblock_cc(smb_krb5_context->krb5_context, ccache,
|
||||
princ, &keyblock,
|
||||
target_service,
|
||||
target_service, krb_options,
|
||||
NULL, &kdc_time);
|
||||
krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &keyblock);
|
||||
}
|
||||
@ -267,6 +294,8 @@ static krb5_error_code salt_principal_from_credentials(TALLOC_CTX *parent_ctx,
|
||||
}
|
||||
}
|
||||
|
||||
krb5_get_init_creds_opt_free(smb_krb5_context->krb5_context, krb_options);
|
||||
|
||||
if (ret == KRB5KRB_AP_ERR_SKEW || ret == KRB5_KDCREP_SKEW) {
|
||||
(*error_string) = talloc_asprintf(credentials, "kinit for %s failed (%s)\n",
|
||||
cli_credentials_get_principal(credentials, mem_ctx),
|
||||
@ -291,6 +320,7 @@ static krb5_error_code salt_principal_from_credentials(TALLOC_CTX *parent_ctx,
|
||||
ccache, obtained,
|
||||
error_string);
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
(*error_string) = talloc_asprintf(credentials, "kinit for %s failed (%s)\n",
|
||||
cli_credentials_get_principal(credentials, mem_ctx),
|
||||
|
Loading…
Reference in New Issue
Block a user