summaryrefslogtreecommitdiffstats
path: root/src/providers/krb5/krb5_auth.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/providers/krb5/krb5_auth.c')
-rw-r--r--src/providers/krb5/krb5_auth.c223
1 files changed, 28 insertions, 195 deletions
diff --git a/src/providers/krb5/krb5_auth.c b/src/providers/krb5/krb5_auth.c
index 5ed561601..e791aee1c 100644
--- a/src/providers/krb5/krb5_auth.c
+++ b/src/providers/krb5/krb5_auth.c
@@ -41,45 +41,6 @@
#include "providers/krb5/krb5_utils.h"
#include "providers/krb5/krb5_ccache.h"
-static errno_t
-check_old_ccache(const char *old_ccache, struct krb5child_req *kr,
- const char *realm, bool *active, bool *valid)
-{
- errno_t ret;
-
- *active = false;
- *valid = false;
-
- ret = sss_krb5_cc_verify_ccache(old_ccache,
- kr->uid, kr->gid,
- realm, kr->upn);
- switch (ret) {
- case ERR_NOT_FOUND:
- case ENOENT:
- DEBUG(SSSDBG_TRACE_FUNC,
- "Saved ccache %s doesn't exist.\n", old_ccache);
- return ENOENT;
- case EINVAL:
- /* cache found but no tgt or expired */
- case EOK:
- *valid = true;
- break;
- default:
- DEBUG(SSSDBG_OP_FAILURE,
- "Cannot check if saved ccache %s is valid\n",
- old_ccache);
- return ret;
- }
-
- ret = check_if_uid_is_active(kr->uid, active);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "check_if_uid_is_active failed.\n");
- return ret;
- }
-
- return EOK;
-}
-
static int krb5_mod_ccname(TALLOC_CTX *mem_ctx,
struct sysdb_ctx *sysdb,
struct sss_domain_info *domain,
@@ -225,7 +186,6 @@ errno_t krb5_setup(TALLOC_CTX *mem_ctx, struct pam_data *pd,
return ENOMEM;
}
kr->is_offline = false;
- kr->active_ccache = true;
kr->run_as_user = true;
talloc_set_destructor((TALLOC_CTX *) kr, krb5_cleanup);
@@ -276,47 +236,26 @@ static void krb5_auth_cache_creds(struct krb5_ctx *krb5_ctx,
}
static errno_t krb5_auth_prepare_ccache_name(struct krb5child_req *kr,
+ struct ldb_message *user_msg,
struct be_ctx *be_ctx)
{
const char *ccname_template;
- errno_t ret;
- if (!kr->is_offline) {
- kr->is_offline = be_is_offline(be_ctx);
- }
+ ccname_template = dp_opt_get_cstring(kr->krb5_ctx->opts, KRB5_CCNAME_TMPL);
- /* The ccache file should be (re)created if one of the following conditions
- * is true:
- * - it doesn't exist (kr->ccname == NULL)
- * - the backend is online and the current ccache file is not used, i.e
- * the related user is currently not logged in and it is not a renewal
- * request
- * (!kr->is_offline && !kr->active_ccache && kr->pd->cmd != SSS_CMD_RENEW)
- * - the backend is offline and the current cache file not used and
- * it does not contain a valid tgt
- * (kr->is_offline && !kr->active_ccache && !kr->valid_tgt)
- */
- if (kr->ccname == NULL ||
- (kr->is_offline && !kr->active_ccache && !kr->valid_tgt) ||
- (!kr->is_offline && !kr->active_ccache && kr->pd->cmd != SSS_CMD_RENEW)) {
- DEBUG(SSSDBG_TRACE_ALL, "Recreating ccache file.\n");
- ccname_template = dp_opt_get_cstring(kr->krb5_ctx->opts,
- KRB5_CCNAME_TMPL);
- kr->ccname = expand_ccname_template(kr, kr, ccname_template,
- kr->krb5_ctx->illegal_path_re,
- true,
- be_ctx->domain->case_sensitive);
- if (kr->ccname == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, "expand_ccname_template failed.\n");
- return ENOMEM;
- }
+ kr->ccname = expand_ccname_template(kr, kr, ccname_template,
+ kr->krb5_ctx->illegal_path_re, true,
+ be_ctx->domain->case_sensitive);
+ if (kr->ccname == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "expand_ccname_template failed.\n");
+ return ENOMEM;
+ }
- ret = sss_krb5_precreate_ccache(kr->ccname,
- kr->uid, kr->gid);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "ccache creation failed.\n");
- return ret;
- }
+ kr->old_ccname = ldb_msg_find_attr_as_string(user_msg,
+ SYSDB_CCACHE_FILE, NULL);
+ if (kr->old_ccname == NULL) {
+ DEBUG(SSSDBG_TRACE_LIBS,
+ "No ccache file for user [%s] found.\n", kr->pd->user);
}
return EOK;
@@ -402,7 +341,6 @@ struct tevent_req *krb5_auth_send(TALLOC_CTX *mem_ctx,
struct krb5_auth_state *state;
struct ldb_result *res;
struct krb5child_req *kr = NULL;
- const char *ccache_file = NULL;
const char *realm;
struct tevent_req *req;
struct tevent_req *subreq;
@@ -588,45 +526,10 @@ struct tevent_req *krb5_auth_send(TALLOC_CTX *mem_ctx,
goto done;
}
- ccache_file = ldb_msg_find_attr_as_string(res->msgs[0],
- SYSDB_CCACHE_FILE,
- NULL);
- if (ccache_file != NULL) {
- ret = check_old_ccache(ccache_file, kr, realm,
- &kr->active_ccache,
- &kr->valid_tgt);
- if (ret == ENOENT) {
- DEBUG(SSSDBG_FUNC_DATA,
- "Ignoring ccache attribute [%s], because it doesn't"
- "exist.\n", ccache_file);
- ccache_file = NULL;
- } else if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE,
- "check_if_ccache_file_is_used failed.\n");
- ccache_file = NULL;
- }
- } else {
- kr->active_ccache = false;
- kr->valid_tgt = false;
- DEBUG(SSSDBG_CONF_SETTINGS,
- "No ccache file for user [%s] found.\n", pd->user);
- }
- DEBUG(SSSDBG_TRACE_ALL,
- "Ccache_file is [%s] and is %s active and TGT is %s valid.\n",
- ccache_file ? ccache_file : "not set",
- kr->active_ccache ? "" : "not",
- kr->valid_tgt ? "" : "not");
- if (ccache_file != NULL) {
- kr->ccname = ccache_file;
- kr->old_ccname = talloc_strdup(kr, ccache_file);
- if (kr->old_ccname == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed.\n");
- ret = ENOMEM;
- goto done;
- }
- } else {
- kr->ccname = NULL;
- kr->old_ccname = NULL;
+ ret = krb5_auth_prepare_ccache_name(kr, res->msgs[0], state->be_ctx);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Cannot prepare ccache names!\n");
+ goto done;
}
break;
@@ -669,7 +572,6 @@ static void krb5_auth_resolve_done(struct tevent_req *subreq)
struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req);
struct krb5_auth_state *state = tevent_req_data(req, struct krb5_auth_state);
struct krb5child_req *kr = state->kr;
- char *msg;
int ret;
if (!state->search_kpasswd) {
@@ -728,45 +630,8 @@ static void krb5_auth_resolve_done(struct tevent_req *subreq)
}
}
- ret = krb5_auth_prepare_ccache_name(kr, state->be_ctx);
- if (ret) {
- goto done;
- }
-
- if (kr->is_offline) {
- DEBUG(SSSDBG_TRACE_ALL, "Preparing for offline operation.\n");
-
- if (kr->valid_tgt || kr->active_ccache) {
- DEBUG(SSSDBG_TRACE_ALL, "Valid TGT available or "
- "ccache file is already in use.\n");
- kr->ccname = kr->old_ccname;
- msg = talloc_asprintf(kr->pd,
- "%s=%s", CCACHE_ENV_NAME, kr->ccname);
- if (msg == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n");
- } else {
- ret = pam_add_response(kr->pd, SSS_PAM_ENV_ITEM,
- strlen(msg) + 1, (uint8_t *) msg);
- if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n");
- }
- }
-
- if (dp_opt_get_bool(kr->krb5_ctx->opts,
- KRB5_STORE_PASSWORD_IF_OFFLINE)) {
- krb5_auth_cache_creds(state->kr->krb5_ctx,
- state->domain,
- state->be_ctx->cdb,
- kr->pd, kr->uid,
- &state->pam_status, &state->dp_err);
- } else {
- state->pam_status = PAM_AUTHINFO_UNAVAIL;
- state->dp_err = DP_ERR_OFFLINE;
- }
- ret = EOK;
- goto done;
-
- }
+ if (!kr->is_offline) {
+ kr->is_offline = be_is_offline(state->be_ctx);
}
/* We need to keep the root privileges to read the keytab file if
@@ -814,7 +679,6 @@ static void krb5_auth_done(struct tevent_req *subreq)
char *renew_interval_str;
time_t renew_interval_time = 0;
bool use_enterprise_principal;
- uint32_t user_info_type;
ret = handle_child_recv(subreq, pd, &buf, &len);
talloc_zfree(subreq);
@@ -974,6 +838,14 @@ static void krb5_auth_done(struct tevent_req *subreq)
}
break;
+ case ERR_CREDS_EXPIRED_CCACHE:
+ ret = krb5_delete_ccname(state, state->sysdb, state->domain,
+ pd->user, kr->old_ccname);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "krb5_delete_ccname failed.\n");
+ }
+ /* FALLTHROUGH */
+
case ERR_CREDS_EXPIRED:
/* If the password is expired we can safely remove the ccache from the
* cache and disk if it is not actively used anymore. This will allow
@@ -981,14 +853,6 @@ static void krb5_auth_done(struct tevent_req *subreq)
* used. */
if (pd->cmd == SSS_PAM_AUTHENTICATE && !kr->active_ccache) {
if (kr->old_ccname != NULL) {
- ret = safe_remove_old_ccache_file(kr->old_ccname, NULL,
- kr->uid, kr->gid);
- if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE,
- "Failed to remove old ccache file [%s], "
- "please remove it manually.\n", kr->old_ccname);
- }
-
ret = krb5_delete_ccname(state, state->sysdb, state->domain,
pd->user, kr->old_ccname);
if (ret != EOK) {
@@ -1062,37 +926,6 @@ static void krb5_auth_done(struct tevent_req *subreq)
goto done;
}
- ret = sss_krb5_check_ccache_princ(kr->uid, kr->gid, kr->ccname, kr->upn);
- if (ret) {
- if (res->otp == true && pd->cmd == SSS_PAM_CHAUTHTOK) {
- DEBUG(SSSDBG_IMPORTANT_INFO,
- "Password change succeeded but currently "
- "post-chpass kinit is not implemented\n");
-
- user_info_type = SSS_PAM_USER_INFO_OTP_CHPASS;
- ret = pam_add_response(pd, SSS_PAM_USER_INFO, sizeof(uint32_t),
- (const uint8_t *) &user_info_type);
- if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n");
- /* Not fatal */
- }
- } else {
- DEBUG(SSSDBG_CRIT_FAILURE,
- "No ccache for %s in %s?\n", kr->upn, kr->ccname);
- goto done;
- }
- }
-
- if (kr->old_ccname) {
- ret = safe_remove_old_ccache_file(kr->old_ccname, kr->ccname,
- kr->uid, kr->gid);
- if (ret != EOK) {
- DEBUG(SSSDBG_MINOR_FAILURE,
- "Failed to remove old ccache file [%s], "
- "please remove it manually.\n", kr->old_ccname);
- }
- }
-
ret = krb5_save_ccname(state, state->sysdb, state->domain,
pd->user, kr->ccname);
if (ret) {