From: Stefan Metzmacher Date: Thu, 14 Apr 2022 11:29:47 +0000 (+0200) Subject: auth/credentials: add cli_credentials_get_ccache_name_obtained() X-Git-Tag: tdb-1.4.11~857 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c7d3946659ff9ce167f68f3f052fae02a8907869;p=thirdparty%2Fsamba.git auth/credentials: add cli_credentials_get_ccache_name_obtained() It's often good to know if a credential structure already has a valid kerberos credential cache attached, without the side effect of doing a kinit and prompt for a password. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15018 Signed-off-by: Stefan Metzmacher Reviewed-by: Andreas Schneider --- diff --git a/auth/credentials/credentials.h b/auth/credentials/credentials.h index 6b35914b431..3f8474eec26 100644 --- a/auth/credentials/credentials.h +++ b/auth/credentials/credentials.h @@ -120,6 +120,10 @@ int cli_credentials_get_named_ccache(struct cli_credentials *cred, struct loadparm_context *lp_ctx, char *ccache_name, struct ccache_container **ccc, const char **error_string); +bool cli_credentials_get_ccache_name_obtained(struct cli_credentials *cred, + TALLOC_CTX *mem_ctx, + char **ccache_name, + enum credentials_obtained *obtained); bool cli_credentials_failed_kerberos_login(struct cli_credentials *cred, const char *principal, unsigned int *count); diff --git a/auth/credentials/credentials_krb5.c b/auth/credentials/credentials_krb5.c index dcfa2e4daee..45fabc19447 100644 --- a/auth/credentials/credentials_krb5.c +++ b/auth/credentials/credentials_krb5.c @@ -758,6 +758,95 @@ _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); } +/** + * @brief Check if a valid Kerberos credential cache is attached. + * + * This will not ask for a password nor do a kinit. + * + * @param cred The credentials context. + * + * @param mem_ctx A memory context to allocate the ccache_name. + * + * @param ccache_name A pointer to a string to store the ccache name. + * + * @param obtained A pointer to store the information how the ccache was + * obtained. + * + * @return True if a credential cache is attached, false if not or an error + * occurred. + */ +_PUBLIC_ bool cli_credentials_get_ccache_name_obtained( + struct cli_credentials *cred, + TALLOC_CTX *mem_ctx, + char **ccache_name, + enum credentials_obtained *obtained) +{ + if (ccache_name != NULL) { + *ccache_name = NULL; + } + + if (obtained != NULL) { + *obtained = CRED_UNINITIALISED; + } + + if (cred->machine_account_pending) { + return false; + } + + if (cred->ccache_obtained == CRED_UNINITIALISED) { + return false; + } + + if (cred->ccache_obtained >= cred->ccache_threshold) { + krb5_context k5ctx = cred->ccache->smb_krb5_context->krb5_context; + krb5_ccache k5ccache = cred->ccache->ccache; + krb5_error_code ret; + time_t lifetime = 0; + + ret = smb_krb5_cc_get_lifetime(k5ctx, k5ccache, &lifetime); + if (ret == KRB5_CC_END || ret == ENOENT) { + return false; + } + if (ret != 0) { + 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. + */ + return false; + } + } + + if (ccache_name != NULL) { + char *name = NULL; + + ret = krb5_cc_get_full_name(k5ctx, k5ccache, &name); + if (ret != 0) { + return false; + } + + *ccache_name = talloc_strdup(mem_ctx, name); + SAFE_FREE(name); + if (*ccache_name == NULL) { + return false; + } + } + + if (obtained != NULL) { + *obtained = cred->ccache_obtained; + } + + return true; + } + + return false; +} + /* 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) {