bool kinit_required = false;
ret = smb_krb5_cc_get_lifetime(cred->ccache->smb_krb5_context->krb5_context,
cred->ccache->ccache, &lifetime);
- if (ret == KRB5_CC_END || ret == ENOENT) {
+ if (ret == KRB5_PLUGIN_NO_HANDLE) {
+ /*
+ * KRB5_PLUGIN_NO_HANDLE is a special case of the encrypted
+ * GSSProxy credential. We don't know its lifetime but assume it
+ * is a valid one. Acquiring it will show the lifetime.
+ */
+ kinit_required = false;
+ } else if (ret == KRB5_CC_END || ret == ENOENT) {
kinit_required = true;
} else if (ret == 0) {
if (lifetime == 0) {
if (ret == KRB5_CC_END || ret == ENOENT) {
return false;
}
- if (ret != 0) {
+
+ /*
+ * KRB5_PLUGIN_NO_HANDLE is a special case of the encrypted
+ * GSSProxy credential. We don't know its lifetime but assume it
+ * is a valid one. Acquiring it will show the lifetime.
+ * */
+ if (ret != 0 && ret != KRB5_PLUGIN_NO_HANDLE) {
return false;
}
- if (lifetime == 0) {
- return false;
- } else if (lifetime < 300) {
- if (cred->password_obtained >= cred->ccache_obtained) {
- /*
- * we have a password to re-kinit
- * so let the caller try that.
- */
+
+ if (ret == 0) {
+ if (lifetime == 0) {
return false;
+ } else if (lifetime < 300) {
+ if (cred->password_obtained >= cred->ccache_obtained) {
+ /*
+ * we have a password to re-kinit
+ * so let the caller try that.
+ */
+ return false;
+ }
}
}
krb5_creds cred;
krb5_timestamp endtime = 0;
krb5_timestamp now;
+ char *realm = NULL;
+ TALLOC_CTX *mem_ctx = NULL;
*t = 0;
return kerr;
}
+ mem_ctx = talloc_stackframe();
+ if (mem_ctx == NULL) {
+ krb5_cc_end_seq_get(context, id, &cursor);
+ return ENOMEM;
+ }
+
while ((kerr = krb5_cc_next_cred(context, id, &cursor, &cred)) == 0) {
if (krb5_is_config_principal(context, cred.server)) {
krb5_free_cred_contents(context, &cred);
continue;
}
+ realm = smb_krb5_principal_get_realm(mem_ctx, context, cred.server);
+ if (realm == NULL) {
+ krb5_free_cred_contents(context, &cred);
+ kerr = ENOMEM;
+ break;
+ }
+
+ /*
+ * 'X-GSSPROXY:' is the realm for an encrypted credential stored
+ * by the GSSProxy. There are no other creds in such ccache and
+ * we cannot see the actual lifetime (it is set to 0),
+ * indicate to the caller they need to handle this themselves.
+ */
+ if (strcmp(realm, "X-GSSPROXY:") == 0) {
+ krb5_free_cred_contents(context, &cred);
+ kerr = KRB5_PLUGIN_NO_HANDLE;
+ break;
+ }
+
#ifndef HAVE_FLAGS_IN_KRB5_CREDS
if (cred.ticket_flags & TKT_FLG_INITIAL) {
#else
krb5_free_cred_contents(context, &cred);
}
+ krb5_cc_end_seq_get(context, id, &cursor);
+ talloc_free(mem_ctx);
+ if (kerr == ENOMEM || kerr == KRB5_PLUGIN_NO_HANDLE) {
+ return kerr;
+ }
+
if (now < endtime) {
*t = (time_t) (endtime - now);
kerr = 0;
}
- krb5_cc_end_seq_get(context, id, &cursor);
-
return kerr;
}
#endif /* HAVE_KRB5_CC_GET_LIFETIME */