From 9dc76c9405860004ebbaeb7da944e06e7767780d Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Mon, 8 Feb 2010 11:53:43 +0100 Subject: Make return values more specific during password change - return PAM_AUTHTOK_ERR instead of PAM_SYSTEM_ERR if the password change operation fails - send a message to the user if the system is offline and the password cannot be changed --- server/providers/krb5/krb5_child.c | 1 + server/providers/ldap/ldap_auth.c | 8 ++-- server/responder/pam/pamsrv_cmd.c | 86 +++++++++++++++++++++++--------------- 3 files changed, 58 insertions(+), 37 deletions(-) (limited to 'server') diff --git a/server/providers/krb5/krb5_child.c b/server/providers/krb5/krb5_child.c index 08e16b4a2..b73032605 100644 --- a/server/providers/krb5/krb5_child.c +++ b/server/providers/krb5/krb5_child.c @@ -579,6 +579,7 @@ static errno_t changepw_child(int fd, struct krb5_req *kr) result_string.length, result_string.data)); } + pam_status = PAM_AUTHTOK_ERR; goto sendresponse; } diff --git a/server/providers/ldap/ldap_auth.c b/server/providers/ldap/ldap_auth.c index fbb4e53b6..1d1346c07 100644 --- a/server/providers/ldap/ldap_auth.c +++ b/server/providers/ldap/ldap_auth.c @@ -772,7 +772,7 @@ static void sdap_auth4chpass_done(struct tevent_req *req) if (pw_expire_type == PWEXPIRE_SHADOW) { /* TODO: implement async ldap modify request */ DEBUG(1, ("Changing shadow password attributes not implemented.\n")); - state->pd->pam_status = PAM_SYSTEM_ERR; + state->pd->pam_status = PAM_MODULE_UNKNOWN; goto done; } else { subreq = sdap_exop_modify_passwd_send(state, @@ -791,7 +791,9 @@ static void sdap_auth4chpass_done(struct tevent_req *req) return; } break; - + case SDAP_AUTH_FAILED: + state->pd->pam_status = PAM_AUTH_ERR; + break; default: state->pd->pam_status = PAM_SYSTEM_ERR; } @@ -821,7 +823,7 @@ static void sdap_pam_chpass_done(struct tevent_req *req) dp_err = DP_ERR_OK; break; default: - state->pd->pam_status = PAM_SYSTEM_ERR; + state->pd->pam_status = PAM_AUTHTOK_ERR; } done: diff --git a/server/responder/pam/pamsrv_cmd.c b/server/responder/pam/pamsrv_cmd.c index 3172a97dd..c204e0a88 100644 --- a/server/responder/pam/pamsrv_cmd.c +++ b/server/responder/pam/pamsrv_cmd.c @@ -484,50 +484,68 @@ static void pam_reply(struct pam_auth_req *preq) struct tevent_req *req; struct sysdb_ctx *sysdb; struct pam_ctx *pctx; + uint32_t user_info_type; pd = preq->pd; DEBUG(4, ("pam_reply get called.\n")); - if ((pd->cmd == SSS_PAM_AUTHENTICATE) && - (preq->domain != NULL) && - (preq->domain->cache_credentials == true) && - (pd->offline_auth == false)) { + if (pd->pam_status == PAM_AUTHINFO_UNAVAIL) { + switch(pd->cmd) { + case SSS_PAM_AUTHENTICATE: + if ((preq->domain != NULL) && + (preq->domain->cache_credentials == true) && + (pd->offline_auth == false)) { - if (pd->pam_status == PAM_AUTHINFO_UNAVAIL) { - /* do auth with offline credentials */ - pd->offline_auth = true; + /* do auth with offline credentials */ + pd->offline_auth = true; - ret = sysdb_get_ctx_from_list(preq->cctx->rctx->db_list, - preq->domain, &sysdb); - if (ret != EOK) { - DEBUG(0, ("Fatal: Sysdb CTX not found for this domain!\n")); - goto done; - } - - pctx = talloc_get_type(preq->cctx->rctx->pvt_ctx, struct pam_ctx); - - req = sysdb_cache_auth_send(preq, preq->cctx->ev, sysdb, - preq->domain, pd->user, pd->authtok, - pd->authtok_size, pctx->rctx->cdb); - if (req == NULL) { - DEBUG(1, ("Failed to setup offline auth")); - /* this error is not fatal, continue */ - } else { - tevent_req_set_callback(req, pam_cache_auth_done, preq); - return; - } - } - } + ret = sysdb_get_ctx_from_list(preq->cctx->rctx->db_list, + preq->domain, &sysdb); + if (ret != EOK) { + DEBUG(0, ("Fatal: Sysdb CTX not found for " + "domain [%s]!\n", preq->domain->name)); + goto done; + } + pctx = talloc_get_type(preq->cctx->rctx->pvt_ctx, + struct pam_ctx); + + req = sysdb_cache_auth_send(preq, preq->cctx->ev, sysdb, + preq->domain, pd->user, + pd->authtok, pd->authtok_size, + pctx->rctx->cdb); + if (req == NULL) { + DEBUG(1, ("Failed to setup offline auth.\n")); + /* this error is not fatal, continue */ + } else { + tevent_req_set_callback(req, pam_cache_auth_done, preq); + return; + } + } + break; + case SSS_PAM_CHAUTHTOK_PRELIM: + case SSS_PAM_CHAUTHTOK: + DEBUG(5, ("Password change not possible while offline.\n")); + pd->pam_status = PAM_AUTHTOK_ERR; + user_info_type = SSS_PAM_USER_INFO_OFFLINE_CHPASS; + pam_add_response(pd, SSS_PAM_USER_INFO, sizeof(uint32_t), + (const uint8_t *) &user_info_type); + break; /* TODO: we need the pam session cookie here to make sure that cached * authentication was successful */ - if ((pd->cmd == SSS_PAM_SETCRED || pd->cmd == SSS_PAM_ACCT_MGMT || - pd->cmd == SSS_PAM_OPEN_SESSION || pd->cmd == SSS_PAM_CLOSE_SESSION) && - pd->pam_status == PAM_AUTHINFO_UNAVAIL) { - DEBUG(2, ("Assuming offline authentication " - "setting status for pam call %d to PAM_SUCCESS.\n", pd->cmd)); - pd->pam_status = PAM_SUCCESS; + case SSS_PAM_SETCRED: + case SSS_PAM_ACCT_MGMT: + case SSS_PAM_OPEN_SESSION: + case SSS_PAM_CLOSE_SESSION: + DEBUG(2, ("Assuming offline authentication setting status for " + "pam call %d to PAM_SUCCESS.\n", pd->cmd)); + pd->pam_status = PAM_SUCCESS; + break; + default: + DEBUG(1, ("Unknown PAM call [%d].\n", pd->cmd)); + pd->pam_status = PAM_MODULE_UNKNOWN; + } } cctx = preq->cctx; -- cgit