diff options
author | Simo Sorce <idra@samba.org> | 2012-04-26 11:05:51 -0400 |
---|---|---|
committer | Simo Sorce <idra@samba.org> | 2012-05-04 16:51:28 +0200 |
commit | 29d284c245c1b3458712c8140cd7b0d1ae175d1f (patch) | |
tree | 292f7657a2a06dcef322553d34b314ca66ab0471 /source4/auth/kerberos/kerberos.c | |
parent | 38a5a2c5c59029889d6c7c6dc80ab087956ca651 (diff) | |
download | samba-29d284c245c1b3458712c8140cd7b0d1ae175d1f.tar.gz samba-29d284c245c1b3458712c8140cd7b0d1ae175d1f.tar.bz2 samba-29d284c245c1b3458712c8140cd7b0d1ae175d1f.zip |
Move kerberos_kinit_password_cc to krb5samba lib
Diffstat (limited to 'source4/auth/kerberos/kerberos.c')
-rw-r--r-- | source4/auth/kerberos/kerberos.c | 421 |
1 files changed, 0 insertions, 421 deletions
diff --git a/source4/auth/kerberos/kerberos.c b/source4/auth/kerberos/kerberos.c deleted file mode 100644 index b4e989d2ae..0000000000 --- a/source4/auth/kerberos/kerberos.c +++ /dev/null @@ -1,421 +0,0 @@ -/* - Unix SMB/CIFS implementation. - kerberos utility library - Copyright (C) Andrew Tridgell 2001 - Copyright (C) Remus Koos 2001 - Copyright (C) Nalin Dahyabhai 2004. - Copyright (C) Jeremy Allison 2004. - Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2005 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include "includes.h" -#include "system/kerberos.h" -#include "auth/kerberos/kerberos.h" - -#ifdef HAVE_KRB5 - -/* - 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 self_service, should be the local service (for S4U2Self if impersonate_principal is given). - - The target_service defaults to the krbtgt if NULL, but could be 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 code = 0; - krb5_get_creds_opt options; - krb5_principal store_principal; - krb5_creds store_creds; - krb5_creds *s4u2self_creds; - Ticket s4u2self_ticket; - size_t s4u2self_ticketlen; - krb5_creds *s4u2proxy_creds; - krb5_principal self_princ; - bool s4u2proxy; - krb5_principal target_princ; - krb5_ccache tmp_cc; - const char *self_realm; - 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, - krb_options); - if (code != 0) { - return code; - } - - 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; - } - - 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; - } - - 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; - } - - /* - * 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); - - /* - * Check if we also need S4U2Proxy or if S4U2Self is - * enough in order to get a ticket for the target. - */ - if (target_service == NULL) { - s4u2proxy = false; - } else if (strcmp(target_service, self_service) == 0) { - s4u2proxy = false; - } else { - s4u2proxy = true; - } - - /* - * 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; - } - - 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; - } - - 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 (s4u2proxy) { - /* - * If we want S4U2Proxy, we need the forwardable flag - * on the S4U2Self ticket. - */ - krb5_get_creds_opt_set_options(ctx, options, KRB5_GC_FORWARDABLE); - } - - 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; - } - - 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); - if (code != 0) { - krb5_free_principal(ctx, blacklist_principal); - krb5_cc_destroy(ctx, tmp_cc); - return code; - } - - if (!s4u2proxy) { - krb5_cc_destroy(ctx, tmp_cc); - - /* - * 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) { - 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; - goto store; - } - - /* - * We are trying S4U2Proxy: - * - * We need the ticket from the S4U2Self step - * and our TGT in order to get the delegated ticket. - */ - code = decode_Ticket((const uint8_t *)s4u2self_creds->ticket.data, - s4u2self_creds->ticket.length, - &s4u2self_ticket, - &s4u2self_ticketlen); - if (code != 0) { - krb5_free_creds(ctx, s4u2self_creds); - krb5_free_principal(ctx, blacklist_principal); - krb5_cc_destroy(ctx, tmp_cc); - return code; - } - - /* - * we need to remember the client principal of the - * S4U2Self stage and as it needs to match the one we - * will get for the S4U2Proxy stage. We need this - * in order to detect KDCs which does not support S4U2Proxy. - */ - whitelist_principal = s4u2self_creds->client; - s4u2self_creds->client = NULL; - krb5_free_creds(ctx, s4u2self_creds); - - /* - * For S4U2Proxy we also got a target service principal, - * which also belongs to our own realm (available on - * our client principal). - */ - code = krb5_parse_name(ctx, target_service, &target_princ); - if (code != 0) { - free_Ticket(&s4u2self_ticket); - krb5_free_principal(ctx, whitelist_principal); - krb5_free_principal(ctx, blacklist_principal); - krb5_cc_destroy(ctx, tmp_cc); - return code; - } - - code = krb5_principal_set_realm(ctx, target_princ, self_realm); - if (code != 0) { - free_Ticket(&s4u2self_ticket); - krb5_free_principal(ctx, target_princ); - krb5_free_principal(ctx, whitelist_principal); - krb5_free_principal(ctx, blacklist_principal); - krb5_cc_destroy(ctx, tmp_cc); - return code; - } - - code = krb5_get_creds_opt_alloc(ctx, &options); - if (code != 0) { - free_Ticket(&s4u2self_ticket); - krb5_free_principal(ctx, target_princ); - krb5_free_principal(ctx, whitelist_principal); - krb5_free_principal(ctx, blacklist_principal); - krb5_cc_destroy(ctx, tmp_cc); - return code; - } - - krb5_get_creds_opt_set_options(ctx, options, KRB5_GC_FORWARDABLE); - krb5_get_creds_opt_set_options(ctx, options, KRB5_GC_CONSTRAINED_DELEGATION); - - code = krb5_get_creds_opt_set_ticket(ctx, options, &s4u2self_ticket); - free_Ticket(&s4u2self_ticket); - if (code != 0) { - krb5_get_creds_opt_free(ctx, options); - krb5_free_principal(ctx, target_princ); - krb5_free_principal(ctx, whitelist_principal); - krb5_free_principal(ctx, blacklist_principal); - krb5_cc_destroy(ctx, tmp_cc); - return code; - } - - code = krb5_get_creds(ctx, options, tmp_cc, - target_princ, &s4u2proxy_creds); - krb5_get_creds_opt_free(ctx, options); - krb5_free_principal(ctx, target_princ); - krb5_cc_destroy(ctx, tmp_cc); - if (code != 0) { - krb5_free_principal(ctx, whitelist_principal); - krb5_free_principal(ctx, blacklist_principal); - 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, s4u2proxy_creds, - &store_creds); - krb5_free_creds(ctx, s4u2proxy_creds); - if (code != 0) { - krb5_free_principal(ctx, whitelist_principal); - 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>")); - - SAFE_FREE(sp); - SAFE_FREE(ip); - - krb5_free_principal(ctx, whitelist_principal); - 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); - } - - if (whitelist_principal && - !krb5_principal_compare(ctx, store_creds.client, whitelist_principal)) { - char *sp = NULL; - char *ep = NULL; - - code = krb5_unparse_name(ctx, store_creds.client, &sp); - if (code != 0) { - sp = NULL; - } - code = krb5_unparse_name(ctx, whitelist_principal, &ep); - if (code != 0) { - ep = NULL; - } - DEBUG(1, ("kerberos_kinit_password_cc: " - "KDC returned wrong principal[%s] we expected [%s]\n", - sp?sp:"<no memory>", - ep?ep:"<no memory>")); - - SAFE_FREE(sp); - SAFE_FREE(ep); - - krb5_free_principal(ctx, whitelist_principal); - krb5_free_cred_contents(ctx, &store_creds); - return KRB5_FWD_BAD_PRINCIPAL; - } - if (whitelist_principal) { - krb5_free_principal(ctx, whitelist_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; -} - - -#endif |