[SCM] Samba Shared Repository - branch master updated
Stefan Metzmacher
metze at samba.org
Wed Jun 22 01:11:02 MDT 2011
The branch, master has been updated
via ede3046 s4:auth/kerberos: protect kerberos_kinit_password_cc() against old KDCs
via e5378e6 s4:auth/kerberos: remove one indentation level in kerberos_kinit_password_cc()
via b98428e s4:auth/kerberos: reformat kerberos_kinit_password_cc()
via 9c56303 s4:auth/kerberos: don't mix s4u2self creds with machine account creds
via b3d4962 s4:auth/kerberos: use better variable names in kerberos_kinit_password_cc()
via 7cf3842 s4:auth/kerberos: don't ignore return code in kerberos_kinit_password_cc()
from 9e766f0 samba-tool: added missing GUID component checks to dbcheck
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit ede3046b8b9b0576a35626026cb28c31b42da46d
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Jun 21 01:39:58 2011 +0200
s4:auth/kerberos: protect kerberos_kinit_password_cc() against old KDCs
Old KDCs may not support S4U2Self (or S4U2Proxy) and return tickets
which belongs to the client principal of the TGT.
metze
Autobuild-User: Stefan Metzmacher <metze at samba.org>
Autobuild-Date: Wed Jun 22 09:10:55 CEST 2011 on sn-devel-104
commit e5378e600e507241dd64c1ea7345676076dc8755
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Jun 20 21:23:45 2011 +0200
s4:auth/kerberos: remove one indentation level in kerberos_kinit_password_cc()
This will make the following changes easier to review.
metze
commit b98428e630cc5a1bbc18bf4260030a24322fdf9e
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Jun 20 21:09:13 2011 +0200
s4:auth/kerberos: reformat kerberos_kinit_password_cc()
In order to make the following changes easier to review.
metze
commit 9c56303f5a56697470ea9f2ee1a428aed2367d75
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Jun 20 15:27:58 2011 +0200
s4:auth/kerberos: don't mix s4u2self creds with machine account creds
It's important that we don't store the tgt for the machine account
in the same krb5_ccache as the ticket for the impersonated principal.
We may pass it to some krb5/gssapi functions and they may use them
in the wrong way, which would grant machine account privileges to
the client.
metze
commit b3d49620875d878e2ad39896a6fe9fddb039253e
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Jun 20 18:01:49 2011 +0200
s4:auth/kerberos: use better variable names in kerberos_kinit_password_cc()
This will make the following changes easier to review.
metze
commit 7cf38425b274c43144a2216accf5330d8ef1fe36
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Jun 20 17:41:52 2011 +0200
s4:auth/kerberos: don't ignore return code in kerberos_kinit_password_cc()
metze
-----------------------------------------------------------------------
Summary of changes:
source4/auth/kerberos/kerberos.c | 228 +++++++++++++++++++++++++++++--------
1 files changed, 178 insertions(+), 50 deletions(-)
Changeset truncated at 500 lines:
diff --git a/source4/auth/kerberos/kerberos.c b/source4/auth/kerberos/kerberos.c
index 0db0dd3..fa8c64b 100644
--- a/source4/auth/kerberos/kerberos.c
+++ b/source4/auth/kerberos/kerberos.c
@@ -84,82 +84,210 @@
The target_service defaults to the krbtgt if NULL, but could be kpasswd/realm or the local service (if we are doing s4u2self)
*/
- 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_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 *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_creds_opt options;
+ krb5_principal store_principal;
+ krb5_creds store_creds;
+ const char *self_service = target_service;
+ krb5_creds *s4u2self_creds;
+ krb5_principal self_princ;
+ krb5_ccache tmp_cc;
+ const char *self_realm;
+ krb5_principal blacklist_principal = NULL;
- /* If we are not impersonating, then get this ticket for the
+ /*
+ * If we are not impersonating, then get this ticket for the
* target service, otherwise a krbtgt, and get the next ticket
- * for the target */
- if ((code = krb5_get_init_creds_password(ctx, &my_creds, principal, password,
- NULL, NULL,
- 0,
- impersonate_principal ? NULL : target_service,
- krb_options))) {
+ * for the target
+ */
+ code = krb5_get_init_creds_password(ctx, &store_creds,
+ init_principal,
+ init_password,
+ NULL, NULL,
+ 0,
+ impersonate_principal ? NULL : target_service,
+ krb_options);
+ if (code != 0) {
return code;
}
- if ((code = krb5_cc_initialize(ctx, cc, principal))) {
- krb5_free_cred_contents(ctx, &my_creds);
+ store_principal = init_principal;
+
+ if (impersonate_principal == NULL) {
+ goto store;
+ }
+
+ /*
+ * We are trying S4U2Self now:
+ *
+ * As we do not want to expose our TGT in the
+ * krb5_ccache, which is also holds the impersonated creds.
+ *
+ * Some low level krb5/gssapi function might use the TGT
+ * identity and let the client act as our machine account.
+ *
+ * We need to avoid that and use a temporary krb5_ccache
+ * in order to pass our TGT to the krb5_get_creds() function.
+ */
+ code = krb5_cc_new_unique(ctx, NULL, NULL, &tmp_cc);
+ if (code != 0) {
+ krb5_free_cred_contents(ctx, &store_creds);
return code;
}
-
- if ((code = krb5_cc_store_cred(ctx, cc, &my_creds))) {
- krb5_free_cred_contents(ctx, &my_creds);
+
+ code = krb5_cc_initialize(ctx, tmp_cc, store_creds.client);
+ if (code != 0) {
+ krb5_cc_destroy(ctx, tmp_cc);
+ krb5_free_cred_contents(ctx, &store_creds);
return code;
}
-
- if (expire_time) {
- *expire_time = (time_t) my_creds.times.endtime;
+
+ code = krb5_cc_store_cred(ctx, tmp_cc, &store_creds);
+ if (code != 0) {
+ krb5_free_cred_contents(ctx, &store_creds);
+ krb5_cc_destroy(ctx, tmp_cc);
+ return code;
}
- if (kdc_time) {
- *kdc_time = (time_t) my_creds.times.starttime;
+ /*
+ * we need to remember the client principal of our
+ * TGT and make sure the KDC does not return this
+ * in the impersonated tickets. This can happen
+ * if the KDC does not support S4U2Self and S4U2Proxy.
+ */
+ blacklist_principal = store_creds.client;
+ store_creds.client = NULL;
+ krb5_free_cred_contents(ctx, &store_creds);
+
+ /*
+ * For S4U2Self we need our own service principal,
+ * which belongs to our own realm (available on
+ * our client principal).
+ */
+ self_realm = krb5_principal_get_realm(ctx, init_principal);
+
+ code = krb5_parse_name(ctx, self_service, &self_princ);
+ if (code != 0) {
+ krb5_free_principal(ctx, blacklist_principal);
+ krb5_cc_destroy(ctx, tmp_cc);
+ return code;
}
- krb5_free_cred_contents(ctx, &my_creds);
-
- if (code == 0 && impersonate_principal) {
- krb5_principal target_princ;
- if ((code = krb5_get_creds_opt_alloc(ctx, &options))) {
- return code;
- }
+ code = krb5_principal_set_realm(ctx, self_princ, self_realm);
+ if (code != 0) {
+ krb5_free_principal(ctx, blacklist_principal);
+ krb5_free_principal(ctx, self_princ);
+ krb5_cc_destroy(ctx, tmp_cc);
+ return code;
+ }
- if ((code = krb5_get_creds_opt_set_impersonate(ctx, options, impersonate_principal))) {
- krb5_get_creds_opt_free(ctx, options);
- return code;
- }
+ code = krb5_get_creds_opt_alloc(ctx, &options);
+ if (code != 0) {
+ krb5_free_principal(ctx, blacklist_principal);
+ krb5_free_principal(ctx, self_princ);
+ krb5_cc_destroy(ctx, tmp_cc);
+ return code;
+ }
- if ((code = krb5_parse_name(ctx, target_service, &target_princ))) {
- krb5_get_creds_opt_free(ctx, options);
- return code;
- }
+ code = krb5_get_creds_opt_set_impersonate(ctx, options,
+ impersonate_principal);
+ if (code != 0) {
+ krb5_get_creds_opt_free(ctx, options);
+ krb5_free_principal(ctx, blacklist_principal);
+ krb5_free_principal(ctx, self_princ);
+ krb5_cc_destroy(ctx, tmp_cc);
+ return code;
+ }
- if ((code = krb5_principal_set_realm(ctx, target_princ, krb5_principal_get_realm(ctx, principal)))) {
- krb5_get_creds_opt_free(ctx, options);
- krb5_free_principal(ctx, target_princ);
- return code;
- }
+ code = krb5_get_creds(ctx, options, tmp_cc,
+ self_princ, &s4u2self_creds);
+ krb5_get_creds_opt_free(ctx, options);
+ krb5_free_principal(ctx, self_princ);
+ krb5_cc_destroy(ctx, tmp_cc);
+ if (code != 0) {
+ krb5_free_principal(ctx, blacklist_principal);
+ return code;
+ }
- if ((code = krb5_get_creds(ctx, options, cc, target_princ, &impersonate_creds))) {
- krb5_free_principal(ctx, target_princ);
- krb5_get_creds_opt_free(ctx, options);
- return code;
+ /*
+ * Now make sure we store the impersonated principal
+ * and creds instead of the TGT related stuff
+ * in the krb5_ccache of the caller.
+ */
+ code = krb5_copy_creds_contents(ctx, s4u2self_creds,
+ &store_creds);
+ krb5_free_creds(ctx, s4u2self_creds);
+ if (code != 0) {
+ krb5_free_principal(ctx, blacklist_principal);
+ return code;
+ }
+
+ /*
+ * It's important to store the principal the KDC
+ * returned, as otherwise the caller would not find
+ * the S4U2Self ticket in the krb5_ccache lookup.
+ */
+ store_principal = store_creds.client;
+
+ store:
+ if (blacklist_principal &&
+ krb5_principal_compare(ctx, store_creds.client, blacklist_principal)) {
+ char *sp = NULL;
+ char *ip = NULL;
+
+ code = krb5_unparse_name(ctx, blacklist_principal, &sp);
+ if (code != 0) {
+ sp = NULL;
+ }
+ code = krb5_unparse_name(ctx, impersonate_principal, &ip);
+ if (code != 0) {
+ ip = NULL;
}
+ DEBUG(1, ("kerberos_kinit_password_cc: "
+ "KDC returned self principal[%s] while impersonating [%s]\n",
+ sp?sp:"<no memory>",
+ ip?ip:"<no memory>"));
- krb5_free_principal(ctx, target_princ);
+ SAFE_FREE(sp);
+ SAFE_FREE(ip);
- code = krb5_cc_store_cred(ctx, cc, impersonate_creds);
- krb5_get_creds_opt_free(ctx, options);
- krb5_free_creds(ctx, impersonate_creds);
+ krb5_free_principal(ctx, blacklist_principal);
+ krb5_free_cred_contents(ctx, &store_creds);
+ return KRB5_FWD_BAD_PRINCIPAL;
}
+ if (blacklist_principal) {
+ krb5_free_principal(ctx, blacklist_principal);
+ }
+
+ code = krb5_cc_initialize(ctx, store_cc, store_principal);
+ if (code != 0) {
+ krb5_free_cred_contents(ctx, &store_creds);
+ return code;
+ }
+
+ code = krb5_cc_store_cred(ctx, store_cc, &store_creds);
+ if (code != 0) {
+ krb5_free_cred_contents(ctx, &store_creds);
+ return code;
+ }
+
+ if (expire_time) {
+ *expire_time = (time_t) store_creds.times.endtime;
+ }
+
+ if (kdc_time) {
+ *kdc_time = (time_t) store_creds.times.starttime;
+ }
+
+ krb5_free_cred_contents(ctx, &store_creds);
return 0;
}
--
Samba Shared Repository
More information about the samba-cvs
mailing list