aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDag-Erling Smørgrav <des@FreeBSD.org>2002-01-24 15:30:03 +0000
committerDag-Erling Smørgrav <des@FreeBSD.org>2002-01-24 15:30:03 +0000
commite9ae7bc23482c20cdefe4845a80cba54bb221534 (patch)
tree76e70ca2bfa4da76aa868ee1fd2ea3c96fc99735
parenta3e5380a47a146bdeff8bc89c7100af2490efc4d (diff)
downloadsrc-e9ae7bc23482c20cdefe4845a80cba54bb221534.tar.gz
src-e9ae7bc23482c20cdefe4845a80cba54bb221534.zip
This commit disables chain caching.
Chain caching is a feature of Linux-PAM, where pam_authenticate() and pam_open_session() "freeze" the chain so that their companion primitive (pam_setcred() and pam_close_session() respectively) will call the exact same modules, skipping those that failed in the previous call. There are several reasons not to do this, the most prominent of which is that it makes it impossible to call pam_setcred() without first calling pam_authenticate() - which is perfectly valid according to DCE/RFC 86.0 and XSSO, and is necessary to make 'login -f' work. Instead of chain caching, implement something similar to the way Solaris' libpam behaves: pam_setcred treats "sufficient" modules as if they were "required", i.e. does not break the chain when they succeed. PAM modules whose pam_sm_setcred() should not be called unless their pam_sm_authenticate() succeeded can simply set a state variable using pam_set_data() in pam_sm_authenticate(), and use pam_get_data() to check it in pam_sm_setcred(). Sponsored by: DARPA, NAI Labs
Notes
Notes: svn path=/head/; revision=89738
-rw-r--r--contrib/libpam/libpam/pam_dispatch.c73
1 files changed, 11 insertions, 62 deletions
diff --git a/contrib/libpam/libpam/pam_dispatch.c b/contrib/libpam/libpam/pam_dispatch.c
index ffb50f5226e8..d9b3de081ba1 100644
--- a/contrib/libpam/libpam/pam_dispatch.c
+++ b/contrib/libpam/libpam/pam_dispatch.c
@@ -4,6 +4,8 @@
* Copyright (c) 1998 Andrew G. Morgan <morgan@kernel.org>
*
* $Id: pam_dispatch.c,v 1.3 2001/02/05 06:50:41 agmorgan Exp $
+ *
+ * $FreeBSD$
*/
#include <stdlib.h>
@@ -28,7 +30,7 @@
*/
static int _pam_dispatch_aux(pam_handle_t *pamh, int flags, struct handler *h,
- _pam_boolean resumed, int use_cached_chain)
+ _pam_boolean resumed, int ignore_sufficient)
{
int depth, impression, status, skip_depth;
@@ -99,46 +101,18 @@ static int _pam_dispatch_aux(pam_handle_t *pamh, int flags, struct handler *h,
return retval;
}
- if (use_cached_chain) {
- /* a former stack execution has frozen the chain */
- cached_retval = *(h->cached_retval_p);
- } else {
- /* this stack execution is defining the frozen chain */
- cached_retval = h->cached_retval = retval;
- }
-
/* verify that the return value is a valid one */
- if ((cached_retval < PAM_SUCCESS)
- || (cached_retval >= _PAM_RETURN_VALUES)) {
+ if ((retval < PAM_SUCCESS) || (retval >= _PAM_RETURN_VALUES)) {
retval = PAM_MUST_FAIL_CODE;
action = _PAM_ACTION_BAD;
} else {
- /* We treat the current retval with some respect. It may
- (for example, in the case of setcred) have a value that
- needs to be propagated to the user. We want to use the
- cached_retval to determine the modules to be executed
- in the stacked chain, but we want to treat each
- non-ignored module in the cached chain as now being
- 'required'. We only need to treat the,
- _PAM_ACTION_IGNORE, _PAM_ACTION_IS_JUMP and
- _PAM_ACTION_RESET actions specially. */
-
- action = h->actions[cached_retval];
+ action = h->actions[retval];
}
- D((stderr,
- "use_cached_chain=%d action=%d cached_retval=%d retval=%d\n",
- use_cached_chain, action, cached_retval, retval));
-
/* decide what to do */
switch (action) {
case _PAM_ACTION_RESET:
- /* if (use_cached_chain) {
- XXX - we need to consider the use_cached_chain case
- do we want to trash accumulated info here..?
- } */
-
impression = _PAM_UNDEF;
status = PAM_MUST_FAIL_CODE;
break;
@@ -146,16 +120,13 @@ static int _pam_dispatch_aux(pam_handle_t *pamh, int flags, struct handler *h,
case _PAM_ACTION_OK:
case _PAM_ACTION_DONE:
- /* XXX - should we maintain cached_status and status in
- the case of use_cached_chain? The same with BAD&DIE
- below */
-
if ( impression == _PAM_UNDEF
|| (impression == _PAM_POSITIVE && status == PAM_SUCCESS) ) {
impression = _PAM_POSITIVE;
status = retval;
}
- if ( impression == _PAM_POSITIVE && action == _PAM_ACTION_DONE ) {
+ if ( impression == _PAM_POSITIVE && action == _PAM_ACTION_DONE
+ && !ignore_sufficient ) {
goto decision_made;
}
break;
@@ -179,11 +150,6 @@ static int _pam_dispatch_aux(pam_handle_t *pamh, int flags, struct handler *h,
break;
case _PAM_ACTION_IGNORE:
- /* if (use_cached_chain) {
- XXX - when evaluating a cached
- chain, do we still want to ignore the module's
- return value?
- } */
break;
/* if we get here, we expect action is a positive number --
@@ -192,19 +158,6 @@ static int _pam_dispatch_aux(pam_handle_t *pamh, int flags, struct handler *h,
default:
if ( _PAM_ACTION_IS_JUMP(action) ) {
- /* If we are evaluating a cached chain, we treat this
- module as required (aka _PAM_ACTION_OK) as well as
- executing the jump. */
-
- if (use_cached_chain) {
- if (impression == _PAM_UNDEF
- || (impression == _PAM_POSITIVE
- && status == PAM_SUCCESS) ) {
- impression = _PAM_POSITIVE;
- status = retval;
- }
- }
-
/* this means that we need to skip #action stacked modules */
do {
h = h->next;
@@ -245,7 +198,7 @@ decision_made: /* by getting here we have made a decision */
int _pam_dispatch(pam_handle_t *pamh, int flags, int choice)
{
struct handler *h = NULL;
- int retval, use_cached_chain;
+ int retval, ignore_sufficient;
_pam_boolean resumed;
IF_NO_PAMH("_pam_dispatch", pamh, PAM_SYSTEM_ERR);
@@ -262,7 +215,7 @@ int _pam_dispatch(pam_handle_t *pamh, int flags, int choice)
return retval;
}
- use_cached_chain = 0; /* default to setting h->cached_retval */
+ ignore_sufficient = 0; /* default to setting h->cached_retval */
switch (choice) {
case PAM_AUTHENTICATE:
@@ -270,7 +223,7 @@ int _pam_dispatch(pam_handle_t *pamh, int flags, int choice)
break;
case PAM_SETCRED:
h = pamh->handlers.conf.setcred;
- use_cached_chain = 1;
+ ignore_sufficient = 1;
break;
case PAM_ACCOUNT:
h = pamh->handlers.conf.acct_mgmt;
@@ -280,13 +233,9 @@ int _pam_dispatch(pam_handle_t *pamh, int flags, int choice)
break;
case PAM_CLOSE_SESSION:
h = pamh->handlers.conf.close_session;
- use_cached_chain = 1;
break;
case PAM_CHAUTHTOK:
h = pamh->handlers.conf.chauthtok;
- if (flags & PAM_UPDATE_AUTHTOK) {
- use_cached_chain = 1;
- }
break;
default:
_pam_system_log(LOG_ERR, "undefined fn choice; %d", choice);
@@ -333,7 +282,7 @@ int _pam_dispatch(pam_handle_t *pamh, int flags, int choice)
__PAM_TO_MODULE(pamh);
/* call the list of module functions */
- retval = _pam_dispatch_aux(pamh, flags, h, resumed, use_cached_chain);
+ retval = _pam_dispatch_aux(pamh, flags, h, resumed, ignore_sufficient);
resumed = PAM_FALSE;
__PAM_TO_APP(pamh);