s4:auth/credentials: pass 'self_service' to cli_credentials_set_impersonate_principal()
authorStefan Metzmacher <metze@samba.org>
Fri, 22 Apr 2011 09:22:50 +0000 (11:22 +0200)
committerStefan Metzmacher <metze@samba.org>
Wed, 18 May 2011 05:46:39 +0000 (07:46 +0200)
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
source4/auth/credentials/credentials.h
source4/auth/credentials/credentials_krb5.c
source4/auth/kerberos/kerberos_util.c
source4/torture/rpc/remote_pac.c

index 015c549693174c9505e04c6fbc9661eeb1a47e7a..83e90344bfcbe34459e5d25af77689588a9f09bc 100644 (file)
@@ -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;
index 0b0de597523f98a1c04ac597221fe6aeda222a4f..f8fa2f864b944b4a866d23804297a82958902552 100644 (file)
@@ -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);
index d3925a01f67a67bef6e6661bbe0ad096457161c3..5883282c2501f9a8b1284a45648852f33ed0b9f5 100644 (file)
@@ -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.
  *
index 45b0b07e137916a5faf4c0bc7627d014b3e20ac8..f05016b8735b2882fcc63b2333f15592f20e9186 100644 (file)
@@ -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) {
index c4efabcebc24259b4de538bfa50a6d448fb67ceb..70912781a82b9292dba8f25fe2f6d86ec6c3d257 100644 (file)
@@ -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 */