From 131aba915fe300332134c0e09310a82699d022d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Tue, 9 Sep 2014 08:08:13 +0000 Subject: [PATCH] From NetBSD: require at least one service function to have succeeded. git-svn-id: svn+ssh://svn.openpam.org/svn/openpam/trunk@802 185d5e19-27fe-0310-9dcf-9bff6b9f3609 --- lib/libpam/openpam_dispatch.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/lib/libpam/openpam_dispatch.c b/lib/libpam/openpam_dispatch.c index 009e269..9ff4497 100644 --- a/lib/libpam/openpam_dispatch.c +++ b/lib/libpam/openpam_dispatch.c @@ -63,7 +63,7 @@ openpam_dispatch(pam_handle_t *pamh, int flags) { pam_chain_t *chain; - int err, fail, r; + int err, fail, nsuccess, r; int debug; ENTER(); @@ -101,7 +101,9 @@ openpam_dispatch(pam_handle_t *pamh, } /* execute */ - for (err = fail = 0; chain != NULL; chain = chain->next) { + err = PAM_SUCCESS; + fail = nsuccess = 0; + for (; chain != NULL; chain = chain->next) { if (chain->module->func[primitive] == NULL) { openpam_log(PAM_LOG_ERROR, "%s: no %s()", chain->module->path, pam_sm_func_name[primitive]); @@ -126,7 +128,8 @@ openpam_dispatch(pam_handle_t *pamh, if (r == PAM_IGNORE) continue; - if (r == PAM_SUCCESS) { + if (r == PAM_SUCCESS) { + ++nsuccess; /* * For pam_setcred() and pam_chauthtok() with the * PAM_PRELIM_CHECK flag, treat "sufficient" as @@ -148,7 +151,7 @@ openpam_dispatch(pam_handle_t *pamh, * fail. If a required module fails, record the * return code from the first required module to fail. */ - if (err == 0) + if (err == PAM_SUCCESS) err = r; if ((chain->flag == PAM_REQUIRED || chain->flag == PAM_BINDING) && !fail) { @@ -170,6 +173,18 @@ openpam_dispatch(pam_handle_t *pamh, if (!fail && err != PAM_NEW_AUTHTOK_REQD) err = PAM_SUCCESS; + + /* + * Require the chain to be non-empty, and at least one module + * in the chain to be successful, so that we don't fail open. + */ + if (err == PAM_SUCCESS && nsuccess < 1) { + openpam_log(PAM_LOG_ERROR, + "all modules were unsuccessful for %s()", + pam_sm_func_name[primitive]); + err = PAM_SYSTEM_ERR; + } + RETURNC(err); }