diff options
-rw-r--r-- | lib/krb5_wrap/krb5_samba.c | 82 | ||||
-rw-r--r-- | lib/krb5_wrap/krb5_samba.h | 20 | ||||
-rw-r--r-- | source4/auth/kerberos/kerberos_util.c | 28 |
3 files changed, 92 insertions, 38 deletions
diff --git a/lib/krb5_wrap/krb5_samba.c b/lib/krb5_wrap/krb5_samba.c index 28cd6471ef..82c25103e7 100644 --- a/lib/krb5_wrap/krb5_samba.c +++ b/lib/krb5_wrap/krb5_samba.c @@ -1646,12 +1646,54 @@ done: return code; } +krb5_error_code kerberos_kinit_password_cc(krb5_context ctx, krb5_ccache cc, + krb5_principal principal, + const char *password, + 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; + + code = krb5_get_init_creds_password(ctx, &my_creds, principal, + password, NULL, NULL, 0, + target_service, krb_options); + if (code) { + return code; + } + + code = krb5_cc_initialize(ctx, cc, principal); + if (code) { + goto done; + } + + code = krb5_cc_store_cred(ctx, cc, &my_creds); + if (code) { + goto done; + } + + if (expire_time) { + *expire_time = (time_t) my_creds.times.endtime; + } + + if (kdc_time) { + *kdc_time = (time_t) my_creds.times.starttime; + } + + code = 0; +done: + krb5_free_cred_contents(ctx, &my_creds); + return code; +} + +#ifdef SAMBA4_USES_HEIMDAL /* simulate a kinit, putting the tgt in the given credentials cache. Orignally by remus@snapserver.com - The impersonate_principal is the principal if NULL, or the principal to - impersonate + The impersonate_principal is the principal The self_service, should be the local service (for S4U2Self if impersonate_principal is given). @@ -1660,16 +1702,16 @@ done: kpasswd/realm or a remote service (for S4U2Proxy) */ -krb5_error_code kerberos_kinit_password_cc(krb5_context ctx, - krb5_ccache store_cc, - krb5_principal init_principal, - const char *init_password, - krb5_principal impersonate_principal, - const char *self_service, - const char *target_service, - krb5_get_init_creds_opt *krb_options, - time_t *expire_time, - time_t *kdc_time) +krb5_error_code kerberos_kinit_s4u2_cc(krb5_context ctx, + krb5_ccache store_cc, + krb5_principal init_principal, + const char *init_password, + krb5_principal impersonate_principal, + const char *self_service, + 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_get_creds_opt options; @@ -1687,21 +1729,12 @@ krb5_error_code kerberos_kinit_password_cc(krb5_context ctx, krb5_principal blacklist_principal = NULL; krb5_principal whitelist_principal = NULL; - if (impersonate_principal && self_service == NULL) { - return EINVAL; - } - - /* - * If we are not impersonating, then get this ticket for the - * target service, otherwise a krbtgt, and get the next ticket - * for the target - */ code = krb5_get_init_creds_password(ctx, &store_creds, init_principal, init_password, NULL, NULL, 0, - impersonate_principal ? NULL : target_service, + NULL, krb_options); if (code != 0) { return code; @@ -1709,10 +1742,6 @@ krb5_error_code kerberos_kinit_password_cc(krb5_context ctx, store_principal = init_principal; - if (impersonate_principal == NULL) { - goto store; - } - /* * We are trying S4U2Self now: * @@ -2040,6 +2069,7 @@ krb5_error_code kerberos_kinit_password_cc(krb5_context ctx, return 0; } +#endif /* * smb_krb5_principal_get_realm diff --git a/lib/krb5_wrap/krb5_samba.h b/lib/krb5_wrap/krb5_samba.h index d235563a7b..864cda67bb 100644 --- a/lib/krb5_wrap/krb5_samba.h +++ b/lib/krb5_wrap/krb5_samba.h @@ -206,15 +206,25 @@ krb5_error_code kerberos_kinit_keyblock_cc(krb5_context ctx, krb5_ccache cc, time_t *expire_time, time_t *kdc_time); krb5_error_code kerberos_kinit_password_cc(krb5_context ctx, - krb5_ccache store_cc, - krb5_principal init_principal, - const char *init_password, - krb5_principal impersonate_principal, - const char *self_service, + krb5_ccache cc, + krb5_principal principal, + const char *password, const char *target_service, krb5_get_init_creds_opt *krb_options, time_t *expire_time, time_t *kdc_time); +#ifdef SAMBA4_USES_HEIMDAL +krb5_error_code kerberos_kinit_s4u2_cc(krb5_context ctx, + krb5_ccache store_cc, + krb5_principal init_principal, + const char *init_password, + krb5_principal impersonate_principal, + const char *self_service, + const char *target_service, + krb5_get_init_creds_opt *krb_options, + time_t *expire_time, + time_t *kdc_time); +#endif char *smb_krb5_principal_get_realm(krb5_context context, krb5_principal principal); diff --git a/source4/auth/kerberos/kerberos_util.c b/source4/auth/kerberos/kerberos_util.c index 9933ca84c7..31a8405a7f 100644 --- a/source4/auth/kerberos/kerberos_util.c +++ b/source4/auth/kerberos/kerberos_util.c @@ -232,13 +232,27 @@ static krb5_error_code impersonate_principal_from_credentials( } #endif if (password) { - ret = kerberos_kinit_password_cc(smb_krb5_context->krb5_context, ccache, - princ, password, - impersonate_principal, - self_service, - target_service, - krb_options, - NULL, &kdc_time); + if (impersonate_principal) { +#ifdef SAMBA4_USES_HEIMDAL + ret = kerberos_kinit_s4u2_cc( + smb_krb5_context->krb5_context, + ccache, princ, password, + impersonate_principal, + self_service, target_service, + krb_options, NULL, &kdc_time); +#else + talloc_free(mem_ctx); + (*error_string) = "INTERNAL error: s4u2 ops " + "are not supported with MIT build yet"; + return EINVAL; +#endif + } else { + ret = kerberos_kinit_password_cc( + smb_krb5_context->krb5_context, + ccache, princ, password, + target_service, + krb_options, NULL, &kdc_time); + } } else if (impersonate_principal) { talloc_free(mem_ctx); (*error_string) = "INTERNAL error: Cannot impersonate principal with just a keyblock. A password must be specified in the credentials"; |