summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2011-06-08 08:53:16 +1000
committerAndrew Bartlett <abartlet@samba.org>2011-06-08 03:08:22 +0200
commit9cf686f56fa50932a67f80a455c36025ca3470db (patch)
treea7447641e8f04711d8b3cba1efe047ccebc5cca6 /source4
parent8dbab93f28d8ddbce8f44116f45a107a05a59a15 (diff)
downloadsamba-9cf686f56fa50932a67f80a455c36025ca3470db.tar.gz
samba-9cf686f56fa50932a67f80a455c36025ca3470db.tar.bz2
samba-9cf686f56fa50932a67f80a455c36025ca3470db.zip
s4-credentials Don't use expired Kerberos or GSSAPI credentials
In a long-lived credentials cache situation, we may need to refetch the ticket after (say) 10 hours. This code should help that happen, by checking the lifetime before returning any credentials cache or GSSAPI credentials. Andrew Bartlett
Diffstat (limited to 'source4')
-rw-r--r--source4/auth/credentials/credentials_krb5.c61
1 files changed, 57 insertions, 4 deletions
diff --git a/source4/auth/credentials/credentials_krb5.c b/source4/auth/credentials/credentials_krb5.c
index aba010453d..26fa8099ab 100644
--- a/source4/auth/credentials/credentials_krb5.c
+++ b/source4/auth/credentials/credentials_krb5.c
@@ -294,8 +294,38 @@ _PUBLIC_ int cli_credentials_get_named_ccache(struct cli_credentials *cred,
if (cred->ccache_obtained >= cred->ccache_threshold &&
cred->ccache_obtained > CRED_UNINITIALISED) {
- *ccc = cred->ccache;
- return 0;
+ time_t lifetime;
+ bool expired = false;
+ ret = krb5_cc_get_lifetime(cred->ccache->smb_krb5_context->krb5_context,
+ cred->ccache->ccache, &lifetime);
+ if (ret == KRB5_CC_END) {
+ /* If we have a particular ccache set, without
+ * an initial ticket, then assume there is a
+ * good reason */
+ } else if (ret == 0) {
+ if (lifetime == 0) {
+ DEBUG(3, ("Ticket in credentials cache for %s expired, will refresh\n",
+ cli_credentials_get_principal(cred, cred)));
+ expired = true;
+ } else if (lifetime < 300) {
+ DEBUG(3, ("Ticket in credentials cache for %s will shortly expire (%u secs), will refresh\n",
+ cli_credentials_get_principal(cred, cred), (unsigned int)lifetime));
+ expired = true;
+ }
+ } else {
+ (*error_string) = talloc_asprintf(cred, "failed to get ccache lifetime: %s\n",
+ smb_get_krb5_error_message(cred->ccache->smb_krb5_context->krb5_context,
+ ret, cred));
+ return ret;
+ }
+
+ DEBUG(5, ("Ticket in credentials cache for %s will expire in %u secs\n",
+ cli_credentials_get_principal(cred, cred), (unsigned int)lifetime));
+
+ if (!expired) {
+ *ccc = cred->ccache;
+ return 0;
+ }
}
if (cli_credentials_is_anonymous(cred)) {
(*error_string) = "Cannot get anonymous kerberos credentials";
@@ -422,8 +452,31 @@ _PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred,
if (cred->client_gss_creds_obtained >= cred->client_gss_creds_threshold &&
cred->client_gss_creds_obtained > CRED_UNINITIALISED) {
- *_gcc = cred->client_gss_creds;
- return 0;
+ bool expired = false;
+ OM_uint32 lifetime = 0;
+ gss_cred_usage_t usage = 0;
+ maj_stat = gss_inquire_cred(&min_stat, cred->client_gss_creds->creds,
+ NULL, &lifetime, &usage, NULL);
+ if (maj_stat == GSS_S_CREDENTIALS_EXPIRED) {
+ DEBUG(3, ("Credentials for %s expired, must refresh credentials cache\n", cli_credentials_get_principal(cred, cred)));
+ expired = true;
+ } else if (maj_stat == GSS_S_COMPLETE && lifetime < 300) {
+ DEBUG(3, ("Credentials for %s will expire shortly (%u sec), must refresh credentials cache\n", cli_credentials_get_principal(cred, cred), lifetime));
+ expired = true;
+ } else if (maj_stat != GSS_S_COMPLETE) {
+ *error_string = talloc_asprintf(cred, "inquiry of credential lifefime via GSSAPI gss_inquire_cred failed: %s\n",
+ gssapi_error_string(cred, maj_stat, min_stat, NULL));
+ return EINVAL;
+ }
+ if (expired) {
+ cli_credentials_unconditionally_invalidate_client_gss_creds(cred);
+ } else {
+ DEBUG(5, ("GSSAPI credentials for %s will expire in %u secs\n",
+ cli_credentials_get_principal(cred, cred), (unsigned int)lifetime));
+
+ *_gcc = cred->client_gss_creds;
+ return 0;
+ }
}
ret = cli_credentials_get_ccache(cred, event_ctx, lp_ctx,