From 46638aa6212e99b5cab67b522fea4ca96f13325e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Sat, 2 Feb 2002 18:22:20 +0000 Subject: [PATCH] Add a flag to struct pam_handle that openpam_dispatch() uses to detect and prevent indirect recursion. Fail immediately if the requested chain is empty. If a module couldn't be loaded, or doesn't provide the requested service, treat it as a normal failure instead of terminating the chain. (Solaris actually ignores this condition!) Sponsored by: DARPA, NAI Labs git-svn-id: svn+ssh://svn.openpam.org/svn/openpam/trunk@20 185d5e19-27fe-0310-9dcf-9bff6b9f3609 --- lib/openpam_dispatch.c | 31 +++++++++++++++++++++++-------- lib/openpam_impl.h | 1 + 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/lib/openpam_dispatch.c b/lib/openpam_dispatch.c index 6b5d0f4..525e41d 100644 --- a/lib/openpam_dispatch.c +++ b/lib/openpam_dispatch.c @@ -61,6 +61,14 @@ openpam_dispatch(pam_handle_t *pamh, if (pamh == NULL) return (PAM_SYSTEM_ERR); + /* prevent recursion */ + if (pamh->dispatching) { + openpam_log(PAM_LOG_ERROR, "indirect recursion"); + return (PAM_SYSTEM_ERR); + } + pamh->dispatching = 1; + + /* pick a chain */ switch (primitive) { case PAM_AUTHENTICATE: case PAM_SETCRED: @@ -77,19 +85,27 @@ openpam_dispatch(pam_handle_t *pamh, module = pamh->chains[PAM_PASSWORD]; break; default: + pamh->dispatching = 0; return (PAM_SYSTEM_ERR); } + /* fail if the chain is empty */ + if (module == NULL) + return (PAM_SYSTEM_ERR); + + /* execute */ for (err = fail = 0; module != NULL; module = module->next) { if (module->primitive[primitive] == NULL) { openpam_log(PAM_LOG_ERROR, "%s: no %s()", module->modpath, _pam_sm_func_name[primitive]); - return (PAM_SYMBOL_ERR); + pamh->dispatching = 0; + r = PAM_SYMBOL_ERR; + } else { + r = (module->primitive[primitive])(pamh, flags); + openpam_log(PAM_LOG_DEBUG, "%s: %s(): %s", + module->modpath, _pam_sm_func_name[primitive], + pam_strerror(pamh, r)); } - r = (module->primitive[primitive])(pamh, flags); - openpam_log(PAM_LOG_DEBUG, "%s: %s(): %s", - module->modpath, _pam_sm_func_name[primitive], - pam_strerror(pamh, r)); if (r == PAM_IGNORE) continue; @@ -131,9 +147,8 @@ openpam_dispatch(pam_handle_t *pamh, } } - if (fail) - return (err); - return (PAM_SUCCESS); + pamh->dispatching = 0; + return (fail ? err : PAM_SUCCESS); } #if !defined(OPENPAM_RELAX_CHECKS) diff --git a/lib/openpam_impl.h b/lib/openpam_impl.h index ec358f7..9de06a5 100644 --- a/lib/openpam_impl.h +++ b/lib/openpam_impl.h @@ -91,6 +91,7 @@ struct pam_data { struct pam_handle { char *service; + int dispatching; /* chains */ pam_chain_t *chains[PAM_NUM_CHAINS];