From a41efe6802da4e81a4af72aa231daa00f5012ab8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 22 Apr 2011 11:22:50 +0200 Subject: s4:auth/credentials: pass 'self_service' to cli_credentials_set_impersonate_principal() This also adds a cli_credentials_get_self_service() helper function. In order to support S4U2Proxy we need to be able to set the service principal for the S4U2Self step independent of the target principal. metze --- source4/auth/credentials/credentials.c | 1 + source4/auth/credentials/credentials.h | 6 +++++- source4/auth/credentials/credentials_krb5.c | 24 ++++++++++++++++++++---- source4/auth/kerberos/kerberos_util.c | 8 ++++++-- source4/torture/rpc/remote_pac.c | 7 ++++--- 5 files changed, 36 insertions(+), 10 deletions(-) diff --git a/source4/auth/credentials/credentials.c b/source4/auth/credentials/credentials.c index 015c549693..83e90344bf 100644 --- a/source4/auth/credentials/credentials.c +++ b/source4/auth/credentials/credentials.c @@ -64,6 +64,7 @@ _PUBLIC_ struct cli_credentials *cli_credentials_init(TALLOC_CTX *mem_ctx) cred->principal = NULL; cred->salt_principal = NULL; cred->impersonate_principal = NULL; + cred->self_service = NULL; cred->target_service = NULL; cred->bind_dn = NULL; diff --git a/source4/auth/credentials/credentials.h b/source4/auth/credentials/credentials.h index 0b0de59752..f8fa2f864b 100644 --- a/source4/auth/credentials/credentials.h +++ b/source4/auth/credentials/credentials.h @@ -84,6 +84,7 @@ struct cli_credentials { const char *principal; char *salt_principal; char *impersonate_principal; + char *self_service; char *target_service; const char *bind_dn; @@ -277,10 +278,13 @@ bool cli_credentials_parse_password_fd(struct cli_credentials *credentials, void cli_credentials_invalidate_ccache(struct cli_credentials *cred, enum credentials_obtained obtained); void cli_credentials_set_salt_principal(struct cli_credentials *cred, const char *principal); -void cli_credentials_set_impersonate_principal(struct cli_credentials *cred, const char *principal); +void cli_credentials_set_impersonate_principal(struct cli_credentials *cred, + const char *principal, + const char *self_service); void cli_credentials_set_target_service(struct cli_credentials *cred, const char *principal); const char *cli_credentials_get_salt_principal(struct cli_credentials *cred); const char *cli_credentials_get_impersonate_principal(struct cli_credentials *cred); +const char *cli_credentials_get_self_service(struct cli_credentials *cred); const char *cli_credentials_get_target_service(struct cli_credentials *cred); enum credentials_use_kerberos cli_credentials_get_kerberos_state(struct cli_credentials *creds); enum credentials_krb_forwardable cli_credentials_get_krb_forwardable(struct cli_credentials *creds); diff --git a/source4/auth/credentials/credentials_krb5.c b/source4/auth/credentials/credentials_krb5.c index d3925a01f6..5883282c25 100644 --- a/source4/auth/credentials/credentials_krb5.c +++ b/source4/auth/credentials/credentials_krb5.c @@ -788,19 +788,35 @@ _PUBLIC_ void cli_credentials_set_salt_principal(struct cli_credentials *cred, c * member of the domain to get the groups of a user. This is also * known as S4U2Self */ -const char *cli_credentials_get_impersonate_principal(struct cli_credentials *cred) +_PUBLIC_ const char *cli_credentials_get_impersonate_principal(struct cli_credentials *cred) { return cred->impersonate_principal; } -_PUBLIC_ void cli_credentials_set_impersonate_principal(struct cli_credentials *cred, const char *principal) +/* + * The 'self_service' is the service principal that + * represents the same object (by its objectSid) + * as the client principal (typically our machine account). + * When trying to impersonate 'impersonate_principal' with + * S4U2Self. + */ +_PUBLIC_ const char *cli_credentials_get_self_service(struct cli_credentials *cred) +{ + return cred->self_service; +} + +_PUBLIC_ void cli_credentials_set_impersonate_principal(struct cli_credentials *cred, + const char *principal, + const char *self_service) { talloc_free(cred->impersonate_principal); cred->impersonate_principal = talloc_strdup(cred, principal); + talloc_free(cred->self_service); + cred->self_service = talloc_strdup(cred, self_service); } -/* when impersonating for S4U2Self we need to set the target principal - * to ourself, as otherwise we would need additional rights. +/* + * when impersonating for S4U2proxy we need to set the target principal. * Similarly, we may only be authorized to do general impersonation to * some particular services. * diff --git a/source4/auth/kerberos/kerberos_util.c b/source4/auth/kerberos/kerberos_util.c index 45b0b07e13..f05016b873 100644 --- a/source4/auth/kerberos/kerberos_util.c +++ b/source4/auth/kerberos/kerberos_util.c @@ -338,7 +338,9 @@ krb5_error_code principal_from_credentials(TALLOC_CTX *parent_ctx, const char **error_string) { krb5_error_code ret; - const char *password, *target_service; + const char *password; + const char *self_service; + const char *target_service; time_t kdc_time = 0; krb5_principal princ; krb5_principal impersonate_principal; @@ -363,6 +365,7 @@ krb5_error_code principal_from_credentials(TALLOC_CTX *parent_ctx, return ret; } + self_service = cli_credentials_get_self_service(credentials); target_service = cli_credentials_get_target_service(credentials); password = cli_credentials_get_password(credentials); @@ -403,7 +406,8 @@ krb5_error_code principal_from_credentials(TALLOC_CTX *parent_ctx, if (password) { ret = kerberos_kinit_password_cc(smb_krb5_context->krb5_context, ccache, princ, password, - impersonate_principal, target_service, + impersonate_principal, + self_service, krb_options, NULL, &kdc_time); } else if (impersonate_principal) { diff --git a/source4/torture/rpc/remote_pac.c b/source4/torture/rpc/remote_pac.c index c4efabcebc..70912781a8 100644 --- a/source4/torture/rpc/remote_pac.c +++ b/source4/torture/rpc/remote_pac.c @@ -476,8 +476,9 @@ static bool test_S2U4Self(struct torture_context *tctx, /* Wipe out any existing ccache */ cli_credentials_invalidate_ccache(credentials, CRED_SPECIFIED); - cli_credentials_set_target_service(credentials, talloc_asprintf(tmp_ctx, "host/%s", test_machine_name)); - cli_credentials_set_impersonate_principal(credentials, cli_credentials_get_principal(cmdline_credentials, tmp_ctx)); + cli_credentials_set_impersonate_principal(credentials, + cli_credentials_get_principal(cmdline_credentials, tmp_ctx), + talloc_asprintf(tmp_ctx, "host/%s", test_machine_name)); status = gensec_client_start(tctx, &gensec_client_context, tctx->ev, lpcfg_gensec_settings(tctx, tctx->lp_ctx)); @@ -525,7 +526,7 @@ static bool test_S2U4Self(struct torture_context *tctx, /* Don't pollute the remaining tests with the changed credentials */ cli_credentials_invalidate_ccache(credentials, CRED_SPECIFIED); cli_credentials_set_target_service(credentials, NULL); - cli_credentials_set_impersonate_principal(credentials, NULL); + cli_credentials_set_impersonate_principal(credentials, NULL, NULL); /* Extract the PAC using Samba's code */ -- cgit