aboutsummaryrefslogtreecommitdiff
path: root/lib/libpam/openpam_dispatch.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libpam/openpam_dispatch.c')
-rw-r--r--lib/libpam/openpam_dispatch.c25
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);
}