cred->keytab_obtained = CRED_UNINITIALISED;
cred->principal_obtained = CRED_UNINITIALISED;
+ cred->ccache_threshold = CRED_UNINITIALISED;
+ cred->client_gss_creds_threshold = CRED_UNINITIALISED;
+
cred->old_password = NULL;
cred->smb_krb5_context = NULL;
cred->salt_principal = NULL;
cred->username = cred->username_cb(cred);
cred->callback_running = False;
cred->username_obtained = CRED_SPECIFIED;
+ cli_credentials_invalidate_ccache(cred, cred->username_obtained);
}
return cred->username;
if (obtained >= cred->username_obtained) {
cred->username = talloc_strdup(cred, val);
cred->username_obtained = obtained;
+ cli_credentials_invalidate_ccache(cred, cred->username_obtained);
return True;
}
cred->principal = cred->principal_cb(cred);
cred->callback_running = False;
cred->principal_obtained = CRED_SPECIFIED;
+ cli_credentials_invalidate_ccache(cred, cred->principal_obtained);
}
if (cred->principal_obtained < cred->username_obtained) {
if (obtained >= cred->principal_obtained) {
cred->principal = talloc_strdup(cred, val);
cred->principal_obtained = obtained;
+ cli_credentials_invalidate_ccache(cred, cred->principal_obtained);
return True;
}
cred->password = cred->password_cb(cred);
cred->callback_running = False;
cred->password_obtained = CRED_CALLBACK_RESULT;
+ cli_credentials_invalidate_ccache(cred, cred->password_obtained);
}
return cred->password;
if (obtained >= cred->password_obtained) {
cred->password = talloc_strdup(cred, val);
cred->password_obtained = obtained;
+ cli_credentials_invalidate_ccache(cred, cred->password_obtained);
cred->nt_hash = NULL;
return True;
if (cred->password_obtained < CRED_CALLBACK) {
cred->password_cb = password_cb;
cred->password_obtained = CRED_CALLBACK;
+ cli_credentials_invalidate_ccache(cred, cred->password_obtained);
return True;
}
cred->domain = cred->domain_cb(cred);
cred->callback_running = False;
cred->domain_obtained = CRED_SPECIFIED;
+ cli_credentials_invalidate_ccache(cred, cred->domain_obtained);
}
return cred->domain;
* calculations */
cred->domain = strupper_talloc(cred, val);
cred->domain_obtained = obtained;
+ cli_credentials_invalidate_ccache(cred, cred->domain_obtained);
return True;
}
cred->realm = cred->realm_cb(cred);
cred->callback_running = False;
cred->realm_obtained = CRED_SPECIFIED;
+ cli_credentials_invalidate_ccache(cred, cred->realm_obtained);
}
return cred->realm;
if (obtained >= cred->realm_obtained) {
cred->realm = strupper_talloc(cred, val);
cred->realm_obtained = obtained;
+ cli_credentials_invalidate_ccache(cred, cred->realm_obtained);
return True;
}
krb5_free_principal(cred->ccache->smb_krb5_context->krb5_context, princ);
+ /* set the ccache_obtained here, as it just got set to UNINITIALISED by the calls above */
cred->ccache_obtained = obtained;
+ cli_credentials_invalidate_client_gss_creds(cred, cred->ccache_obtained);
return 0;
}
cli_credentials_set_machine_account(cred);
}
- if (cred->ccache_obtained >=(MAX(MAX(cred->principal_obtained,
- cred->username_obtained),
- cred->password_obtained))) {
+ if (cred->ccache_obtained >= cred->ccache_threshold) {
*ccc = cred->ccache;
return 0;
}
return ret;
}
+void cli_credentials_invalidate_client_gss_creds(struct cli_credentials *cred,
+ enum credentials_obtained obtained)
+{
+ /* If the caller just changed the username/password etc, then
+ * any cached credentials are now invalid */
+ if (obtained >= cred->client_gss_creds_obtained) {
+ if (cred->client_gss_creds_obtained > CRED_UNINITIALISED) {
+ talloc_free(cred->client_gss_creds);
+ }
+ cred->client_gss_creds_obtained = CRED_UNINITIALISED;
+ }
+ /* Now that we know that the data is 'this specified', then
+ * don't allow something less 'known' to be returned as a
+ * ccache. Ie, if the username is on the commmand line, we
+ * don't want to later guess to use a file-based ccache */
+ if (obtained > cred->client_gss_creds_threshold) {
+ cred->client_gss_creds_threshold = obtained;
+ }
+}
+
+void cli_credentials_invalidate_ccache(struct cli_credentials *cred,
+ enum credentials_obtained obtained)
+{
+ /* If the caller just changed the username/password etc, then
+ * any cached credentials are now invalid */
+ if (obtained >= cred->ccache_obtained) {
+ if (cred->ccache_obtained > CRED_UNINITIALISED) {
+ talloc_free(cred->ccache);
+ }
+ cred->ccache_obtained = CRED_UNINITIALISED;
+ }
+ /* Now that we know that the data is 'this specified', then
+ * don't allow something less 'known' to be returned as a
+ * ccache. Ie, if the username is on the commmand line, we
+ * don't want to later guess to use a file-based ccache */
+ if (obtained > cred->ccache_threshold) {
+ cred->ccache_threshold = obtained;
+ }
+
+ cli_credentials_invalidate_client_gss_creds(cred,
+ obtained);
+}
+
static int free_gssapi_creds(struct gssapi_creds_container *gcc)
{
OM_uint32 min_stat, maj_stat;
OM_uint32 maj_stat, min_stat;
struct gssapi_creds_container *gcc;
struct ccache_container *ccache;
- if (cred->client_gss_creds_obtained >= (MAX(cred->ccache_obtained,
- MAX(cred->principal_obtained,
- cred->username_obtained)))) {
+ if (cred->client_gss_creds_obtained >= cred->client_gss_creds_threshold) {
*_gcc = cred->client_gss_creds;
return 0;
}
gcc->creds = gssapi_cred;
talloc_set_destructor(gcc, free_gssapi_creds);
+ /* set the clinet_gss_creds_obtained here, as it just
+ got set to UNINITIALISED by the calls above */
cred->client_gss_creds_obtained = obtained;
cred->client_gss_creds = gcc;
}