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 */ }