diff options
author | Tomas Mraz <tm@t8m.info> | 2007-10-19 17:06:29 +0000 |
---|---|---|
committer | Tomas Mraz <tm@t8m.info> | 2007-10-19 17:06:29 +0000 |
commit | 695f6e358dd1e8c05e77bd13f93d85e5963c9c3e (patch) | |
tree | 4b0c40f2bbc890af8f98f26710d0778c82019cdc /libpam/pam_dispatch.c | |
parent | fba28bf5631dac07841542dd81f6f2ede3198b6e (diff) | |
download | pam-695f6e358dd1e8c05e77bd13f93d85e5963c9c3e.tar.gz pam-695f6e358dd1e8c05e77bd13f93d85e5963c9c3e.tar.bz2 pam-695f6e358dd1e8c05e77bd13f93d85e5963c9c3e.zip |
Relevant BUGIDs:
Purpose of commit: new feature
Commit summary:
---------------
2007-10-19 Tomas Mraz <t8m@centrum.cz>
* xtests/tst-pam_access1.c: Use different name for user and group.
* xtests/tst-pam_access1.sh: Likewise.
* xtests/tst-pam_access2.c: Likewise.
* xtests/tst-pam_access2.sh: Likewise.
* xtests/tst-pam_access4.c: Likewise.
* xtests/tst-pam_access4.sh: Likewise.
* xtests/group.conf: Likewise.
* xtests/tst-pam_group1.c: Likewise.
* xtests/tst-pam_group1.sh: Likewise.
* libpam/pam_dispatch.c (_pam_dispatch_aux): Save states for substacks,
record substack level, skip over virtual substack modules, implement
evaluation of done, die, reset and jumps in substacks. Also fixes
too far jumps in substacks.
* libpam/pam_end.c (pam_end): Drop substack evaluation states.
* libpam/pam_handlers.c (_pam_parse_conf_file): Add substack level
parameter, instead of must_fail use handler_type needed for virtual
substack modules.
(_pam_load_conf_file): Add substack level parameter.
(_pam_init_handlers): Substack level parameter added to
_pam_parse_conf_file() calls.
(_pam_load_module): New function.
(_pam_add_handler): Refactor code into the _pam_load_module(). Add
support for virtual substack modules.
* libpam/pam_private.h: Rename must_fail to handler_type, add stack_level
to struct handler. Define handler type constants. Add struct
for substack evaluation states. Define constant for maximum
substack level. Add substack states pointer to former state struct.
* libpam/pam_start.c (pam_start): Initialize pointer to substack states.
* doc/man/pam.conf-syntax.xml: Document substack control.
* xtests/Makefile.am: Add new tests for substack evaluation.
* xtests/run_xtests.sh: Support multiple .pamd files in a test.
* xtests/tst-pam_authfail.pamd: New tests for substack evaluation.
* xtests/tst-pam_authsucceed.pamd: Likewise.
* xtests/tst-pam_substack1.pamd: Likewise.
* xtests/tst-pam_substack1a.pamd: Likewise.
* xtests/tst-pam_substack1.sh: Likewise.
* xtests/tst-pam_substack2.pamd: Likewise.
* xtests/tst-pam_substack2a.pamd: Likewise.
* xtests/tst-pam_substack2.sh: Likewise.
* xtests/tst-pam_substack3.pamd: Likewise.
* xtests/tst-pam_substack3a.pamd: Likewise.
* xtests/tst-pam_substack3.sh: Likewise.
* xtests/tst-pam_substack4.pamd: Likewise.
* xtests/tst-pam_substack4a.pamd: Likewise.
* xtests/tst-pam_substack4.sh: Likewise.
* xtests/tst-pam_substack5.pamd: Likewise.
* xtests/tst-pam_substack5a.pamd: Likewise.
* xtests/tst-pam_substack5.sh: Likewise.
Diffstat (limited to 'libpam/pam_dispatch.c')
-rw-r--r-- | libpam/pam_dispatch.c | 66 |
1 files changed, 49 insertions, 17 deletions
diff --git a/libpam/pam_dispatch.c b/libpam/pam_dispatch.c index ab032d74..fa4e5ed4 100644 --- a/libpam/pam_dispatch.c +++ b/libpam/pam_dispatch.c @@ -34,7 +34,8 @@ static int _pam_dispatch_aux(pam_handle_t *pamh, int flags, struct handler *h, _pam_boolean resumed, int use_cached_chain) { - int depth, impression, status, skip_depth; + int depth, impression, status, skip_depth, prev_level, stack_level; + struct _pam_substack_state *substates = NULL; IF_NO_PAMH("_pam_dispatch_aux", pamh, PAM_SYSTEM_ERR); @@ -54,27 +55,51 @@ static int _pam_dispatch_aux(pam_handle_t *pamh, int flags, struct handler *h, skip_depth = pamh->former.depth; status = pamh->former.status; impression = pamh->former.impression; + substates = pamh->former.substates; /* forget all that */ pamh->former.impression = _PAM_UNDEF; pamh->former.status = PAM_MUST_FAIL_CODE; pamh->former.depth = 0; + pamh->former.substates = NULL; } else { skip_depth = 0; - impression = _PAM_UNDEF; - status = PAM_MUST_FAIL_CODE; + substates = malloc(PAM_SUBSTACK_MAX_LEVEL * sizeof(*substates)); + if (substates == NULL) { + pam_syslog(pamh, LOG_CRIT, + "_pam_dispatch_aux: no memory for substack states"); + return PAM_BUF_ERR; + } + substates[0].impression = impression = _PAM_UNDEF; + substates[0].status = status = PAM_MUST_FAIL_CODE; } + prev_level = 0; + /* Loop through module logic stack */ - for (depth=0 ; h != NULL ; h = h->next, ++depth) { + for (depth=0 ; h != NULL ; prev_level = stack_level, h = h->next, ++depth) { int retval, cached_retval, action; + stack_level = h->stack_level; + /* skip leading modules if they have already returned */ if (depth < skip_depth) { continue; } + /* remember state if we are entering a substack */ + if (prev_level < stack_level) { + substates[stack_level].impression = impression; + substates[stack_level].status = status; + } + /* attempt to call the module */ - if (h->func == NULL) { + if (h->handler_type == PAM_HT_MUST_FAIL) { + D(("module poorly listed in PAM config; forcing failure")); + retval = PAM_MUST_FAIL_CODE; + } else if (h->handler_type == PAM_HT_SUBSTACK) { + D(("skipping substack handler")); + continue; + } else if (h->func == NULL) { D(("module function is not defined, indicating failure")); retval = PAM_MODULE_UNKNOWN; } else { @@ -83,10 +108,6 @@ static int _pam_dispatch_aux(pam_handle_t *pamh, int flags, struct handler *h, retval = h->func(pamh, flags, h->argc, h->argv); pamh->mod_name=NULL; D(("module returned: %s", pam_strerror(pamh, retval))); - if (h->must_fail) { - D(("module poorly listed in PAM config; forcing failure")); - retval = PAM_MUST_FAIL_CODE; - } } /* @@ -100,6 +121,7 @@ static int _pam_dispatch_aux(pam_handle_t *pamh, int flags, struct handler *h, pamh->former.impression = impression; pamh->former.status = status; pamh->former.depth = depth; + pamh->former.substates = substates; D(("module %d returned PAM_INCOMPLETE", depth)); return retval; @@ -176,8 +198,8 @@ static int _pam_dispatch_aux(pam_handle_t *pamh, int flags, struct handler *h, switch (action) { case _PAM_ACTION_RESET: - impression = _PAM_UNDEF; - status = PAM_MUST_FAIL_CODE; + impression = substates[stack_level].impression; + status = substates[stack_level].status; break; case _PAM_ACTION_OK: @@ -244,9 +266,13 @@ static int _pam_dispatch_aux(pam_handle_t *pamh, int flags, struct handler *h, } /* this means that we need to skip #action stacked modules */ - do { - h = h->next; - } while ( --action > 0 && h != NULL ); + while (h->next != NULL && h->next->stack_level >= stack_level && action > 0) { + do { + h = h->next; + ++depth; + } while (h->next != NULL && h->next->stack_level > stack_level); + --action; + } /* note if we try to skip too many modules action is still non-zero and we snag the next if. */ @@ -254,14 +280,19 @@ static int _pam_dispatch_aux(pam_handle_t *pamh, int flags, struct handler *h, /* this case is a syntax error: we can't succeed */ if (action) { - D(("action syntax error")); + pam_syslog(pamh, LOG_ERR, "bad jump in stack"); impression = _PAM_NEGATIVE; status = PAM_MUST_FAIL_CODE; } } - } - + continue; + decision_made: /* by getting here we have made a decision */ + while (h->next != NULL && h->next->stack_level >= stack_level) { + h = h->next; + ++depth; + } + } /* Sanity check */ if ( status == PAM_SUCCESS && impression != _PAM_POSITIVE ) { @@ -269,6 +300,7 @@ decision_made: /* by getting here we have made a decision */ status = PAM_MUST_FAIL_CODE; } + free(substates); /* We have made a decision about the modules executed */ return status; } |