summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/krb5_wrap/krb5_samba.c82
-rw-r--r--lib/krb5_wrap/krb5_samba.h20
-rw-r--r--source4/auth/kerberos/kerberos_util.c28
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";