diff options
Diffstat (limited to 'lib/libpam/openpam_dispatch.c')
-rw-r--r-- | lib/libpam/openpam_dispatch.c | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/lib/libpam/openpam_dispatch.c b/lib/libpam/openpam_dispatch.c index 0dcc73223ce3..5fa068f8e261 100644 --- a/lib/libpam/openpam_dispatch.c +++ b/lib/libpam/openpam_dispatch.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: openpam_dispatch.c 649 2013-03-05 17:58:33Z des $ + * $Id: openpam_dispatch.c 807 2014-09-09 09:41:32Z des $ */ #ifdef HAVE_CONFIG_H @@ -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); } |