diff options
author | Andrew Bartlett <abartlet@samba.org> | 2010-05-01 10:33:08 +1000 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2010-05-02 06:54:23 +1000 |
commit | 44e7ea692708c1c956fc9bd20ed9a6d5de9479a4 (patch) | |
tree | c2677201a5cdab1772371611242f0fcdac6826a7 /source4/auth/credentials/credentials_krb5.c | |
parent | 485def3b5dae7c77fb0c01ed99b6865b7c5ceeb8 (diff) | |
download | samba-44e7ea692708c1c956fc9bd20ed9a6d5de9479a4.tar.gz samba-44e7ea692708c1c956fc9bd20ed9a6d5de9479a4.tar.bz2 samba-44e7ea692708c1c956fc9bd20ed9a6d5de9479a4.zip |
s4:credentials Make the CCACHE in credentials depend on the things that built it
This means that we consider the ccache only as reliable as the least
specified of the inputs we used.
This means that we will regenerate the ccache if any of the inputs change.
Andrew Bartlett
Diffstat (limited to 'source4/auth/credentials/credentials_krb5.c')
-rw-r--r-- | source4/auth/credentials/credentials_krb5.c | 75 |
1 files changed, 57 insertions, 18 deletions
diff --git a/source4/auth/credentials/credentials_krb5.c b/source4/auth/credentials/credentials_krb5.c index d76073093b..12bf610bf8 100644 --- a/source4/auth/credentials/credentials_krb5.c +++ b/source4/auth/credentials/credentials_krb5.c @@ -27,6 +27,7 @@ #include "auth/credentials/credentials.h" #include "auth/credentials/credentials_proto.h" #include "auth/credentials/credentials_krb5.h" +#include "auth/kerberos/kerberos_credentials.h" #include "param/param.h" _PUBLIC_ int cli_credentials_get_krb5_context(struct cli_credentials *cred, @@ -282,6 +283,7 @@ _PUBLIC_ int cli_credentials_get_named_ccache(struct cli_credentials *cred, const char **error_string) { krb5_error_code ret; + enum credentials_obtained obtained; if (cred->machine_account_pending) { cli_credentials_set_machine_account(cred, lp_ctx); @@ -302,15 +304,13 @@ _PUBLIC_ int cli_credentials_get_named_ccache(struct cli_credentials *cred, return ret; } - ret = kinit_to_ccache(cred, cred, (*ccc)->smb_krb5_context, (*ccc)->ccache, error_string); + ret = kinit_to_ccache(cred, cred, (*ccc)->smb_krb5_context, (*ccc)->ccache, &obtained, error_string); if (ret) { return ret; } ret = cli_credentials_set_from_ccache(cred, *ccc, - (MAX(MAX(cred->principal_obtained, - cred->username_obtained), - cred->password_obtained)), error_string); + obtained, error_string); cred->ccache = *ccc; cred->ccache_obtained = cred->principal_obtained; @@ -330,6 +330,16 @@ _PUBLIC_ int cli_credentials_get_ccache(struct cli_credentials *cred, return cli_credentials_get_named_ccache(cred, event_ctx, lp_ctx, NULL, ccc, error_string); } +/* We have good reason to think the ccache in these credentials is invalid - blow it away */ +static void cli_credentials_unconditionally_invalidate_client_gss_creds(struct cli_credentials *cred) +{ + if (cred->client_gss_creds_obtained > CRED_UNINITIALISED) { + talloc_unlink(cred, cred->client_gss_creds); + cred->client_gss_creds = NULL; + } + cred->client_gss_creds_obtained = CRED_UNINITIALISED; +} + void cli_credentials_invalidate_client_gss_creds(struct cli_credentials *cred, enum credentials_obtained obtained) { @@ -351,6 +361,18 @@ void cli_credentials_invalidate_client_gss_creds(struct cli_credentials *cred, } } +/* We have good reason to think this CCACHE is invalid. Blow it away */ +static void cli_credentials_unconditionally_invalidate_ccache(struct cli_credentials *cred) +{ + if (cred->ccache_obtained > CRED_UNINITIALISED) { + talloc_unlink(cred, cred->ccache); + cred->ccache = NULL; + } + cred->ccache_obtained = CRED_UNINITIALISED; + + cli_credentials_unconditionally_invalidate_client_gss_creds(cred); +} + _PUBLIC_ void cli_credentials_invalidate_ccache(struct cli_credentials *cred, enum credentials_obtained obtained) { @@ -416,6 +438,23 @@ _PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred, maj_stat = gss_krb5_import_cred(&min_stat, ccache->ccache, NULL, NULL, &gcc->creds); + if ((maj_stat == GSS_S_FAILURE) && (min_stat == (OM_uint32)KRB5_CC_END || min_stat == (OM_uint32) KRB5_CC_NOTFOUND)) { + /* This CCACHE is no good. Ensure we don't use it again */ + cli_credentials_unconditionally_invalidate_ccache(cred); + + /* Now try again to get a ccache */ + ret = cli_credentials_get_ccache(cred, event_ctx, lp_ctx, + &ccache, error_string); + if (ret) { + DEBUG(1, ("Failed to re-get CCACHE for GSSAPI client: %s\n", error_message(ret))); + return ret; + } + + maj_stat = gss_krb5_import_cred(&min_stat, ccache->ccache, NULL, NULL, + &gcc->creds); + + } + if (maj_stat) { talloc_free(gcc); if (min_stat) { @@ -698,12 +737,11 @@ _PUBLIC_ int cli_credentials_get_server_gss_creds(struct cli_credentials *cred, TALLOC_CTX *mem_ctx; krb5_principal princ; const char *error_string; + enum credentials_obtained obtained; - if (cred->server_gss_creds_obtained >= (MAX(cred->keytab_obtained, - MAX(cred->principal_obtained, - cred->username_obtained)))) { - *_gcc = cred->server_gss_creds; - return 0; + mem_ctx = talloc_new(cred); + if (!mem_ctx) { + return ENOMEM; } ret = cli_credentials_get_krb5_context(cred, event_ctx, lp_ctx, &smb_krb5_context); @@ -711,22 +749,23 @@ _PUBLIC_ int cli_credentials_get_server_gss_creds(struct cli_credentials *cred, return ret; } - ret = cli_credentials_get_keytab(cred, event_ctx, lp_ctx, &ktc); + ret = principal_from_credentials(mem_ctx, cred, smb_krb5_context, &princ, &obtained, &error_string); if (ret) { - DEBUG(1, ("Failed to get keytab for GSSAPI server: %s\n", error_message(ret))); + DEBUG(1,("cli_credentials_get_server_gss_creds: makeing krb5 principal failed (%s)\n", + error_string)); + talloc_free(mem_ctx); return ret; } - mem_ctx = talloc_new(cred); - if (!mem_ctx) { - return ENOMEM; + if (cred->server_gss_creds_obtained >= (MAX(cred->keytab_obtained, obtained))) { + talloc_free(mem_ctx); + *_gcc = cred->server_gss_creds; + return 0; } - ret = principal_from_credentials(mem_ctx, cred, smb_krb5_context, &princ, &error_string); + ret = cli_credentials_get_keytab(cred, event_ctx, lp_ctx, &ktc); if (ret) { - DEBUG(1,("cli_credentials_get_server_gss_creds: makeing krb5 principal failed (%s)\n", - error_string)); - talloc_free(mem_ctx); + DEBUG(1, ("Failed to get keytab for GSSAPI server: %s\n", error_message(ret))); return ret; } |