On 9/14/07, Jeffrey Hutzelman <jhutz at cmu.edu> wrote:
>
>
> On Wednesday, September 12, 2007 07:53:06 PM -0500 Nicolas Williams
> <Nicolas.Williams at sun.com> wrote:
>
> >> Short implementation question - which of the following concepts is
> >> better:
> >> 1. Simple solution: Start a shell script each time a |pam_sm_*()|
> >> function is called, run it until it finishes and collect the results
> >>
> >>     or
> >>
> >> 2. Create a shell instance for each created |pam_handle_t| and run the
> >> script, the script defines a set of shell functions, one per
> >> | pam_sm_*()| callback and when such a callback is called it launches the
> >> matching shell function. The shell instance is destroyed when the
> >> matching |pam_handle_t| is disposed.
> >>
> >> Erm, the 2nd solution is a little bit more compliciated to implement but
> >> would be more flexible since the shell and all it's global variables
> >> would live as long the matching |pam_handle_t| exists.
> >
> > (2), so the module can keep state.  I still think Perl5 is better
> > because there is so much functionality in CPAN that could be used for
> > all sorts of PAM modules.
>
> Yes, (2) would be better if you could do it.  But you can't, without
> modifying the framework.  PAM modules don't get control when a handle is
> created, only when one of the six main interfaces is called, or when a
> PAM_DATA item is destroyed.  I suppose you could create the shell instance
> the first time one of the main operations is called, and store a reference
> to it in a data item.  But I don't believe there's any guarantee that the
> framework doesn't unload modules, and in any case you'd have to figure out
> a way to name the data item that doesn't preclude admins from using this
> module more than once with different scripts.
> _______________________________________________
> security-discuss mailing list
> security-discuss at opensolaris.org
>

Perhaps I'm missing something but why not in pam_sm_*:

rc = pam_get_data(pamh, PAM_SHELL_DATA_NAME, &data);
if (data == NULL || rc == PAM_NO_MODULE_DATA) {
   /* create shell context */
   pam_set_data(pamh, PAM_SHELL_DATA_NAME, data, cleanup_fn);
}

void
cleanup_fn(pam_handle_t *pamh, void *data, int status)
{
     /* destroy shell context */
}

Reply via email to