summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/providers/krb5/krb5_child.c1
-rw-r--r--server/providers/ldap/ldap_auth.c8
-rw-r--r--server/responder/pam/pamsrv_cmd.c86
-rw-r--r--sss_client/pam_sss.c24
-rw-r--r--sss_client/sss_cli.h3
5 files changed, 84 insertions, 38 deletions
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;
diff --git a/sss_client/pam_sss.c b/sss_client/pam_sss.c
index 6e238eccd..8c970e489 100644
--- a/sss_client/pam_sss.c
+++ b/sss_client/pam_sss.c
@@ -475,6 +475,27 @@ static int user_info_offline_auth_delayed(pam_handle_t *pamh, size_t buflen,
return PAM_SUCCESS;
}
+static int user_info_offline_chpass(pam_handle_t *pamh, size_t buflen,
+ uint8_t *buf)
+{
+ int ret;
+
+ if (buflen != sizeof(uint32_t)) {
+ D(("User info response data has the wrong size"));
+ return PAM_BUF_ERR;
+ }
+
+ ret = do_pam_conversation(pamh, PAM_TEXT_INFO,
+ _("System is offline, password change not possible"),
+ NULL, NULL);
+ if (ret != PAM_SUCCESS) {
+ D(("do_pam_conversation failed."));
+ return PAM_SYSTEM_ERR;
+ }
+
+ return PAM_SUCCESS;
+}
+
static int eval_user_info_response(pam_handle_t *pamh, size_t buflen,
uint8_t *buf)
{
@@ -495,6 +516,9 @@ static int eval_user_info_response(pam_handle_t *pamh, size_t buflen,
case SSS_PAM_USER_INFO_OFFLINE_AUTH_DELAYED:
ret = user_info_offline_auth_delayed(pamh, buflen, buf);
break;
+ case SSS_PAM_USER_INFO_OFFLINE_CHPASS:
+ ret = user_info_offline_chpass(pamh, buflen, buf);
+ break;
default:
D(("Unknown user info type [%d]", type));
ret = PAM_SYSTEM_ERR;
diff --git a/sss_client/sss_cli.h b/sss_client/sss_cli.h
index 954696117..55d5a2825 100644
--- a/sss_client/sss_cli.h
+++ b/sss_client/sss_cli.h
@@ -179,7 +179,8 @@ enum response_type {
enum user_info_type {
SSS_PAM_USER_INFO_OFFLINE_AUTH = 0x01,
- SSS_PAM_USER_INFO_OFFLINE_AUTH_DELAYED
+ SSS_PAM_USER_INFO_OFFLINE_AUTH_DELAYED,
+ SSS_PAM_USER_INFO_OFFLINE_CHPASS
};
enum nss_status sss_nss_make_request(enum sss_cli_command cmd,