Hello everyone. Recently, I found myself needing the ability to do user login session setup/teardown in the form of a shell script invoked as root. PAM seemed the right place to hook this in, and I came across pam_script and no less than four different implementations of pam_exec to do the job. All of these, however, left something to be desired. Most notably, all but one didn't allow sending standard-channel output to the user [via the conversation function], and none provided a way of modifying the PAM environment. I have taken the current Linux-PAM implementation of pam_exec, and expanded it to include (1) the features I needed, (2) the superset of features in all the aforementioned implementations of this concept, and (3) some extra niceties that I didn't need, but might find useful someday. A summary of features of the new implementation: * The external program's stdout is sent to the PAM conversation function, provided that the PAM_SILENT flag has not been set. * The program's stderr is sent to syslog (as specially-marked LOG_INFO messages). * If a certain module option is specified, the program can write pseudo-shell-ish directives to fd 3 to set and unset PAM environment variables. * Piped output from the program is checked for illegal characters (currently via isprint(), for locale-friendliness). * Overlong output lines from the program are detected and dropped. * Several classes of environment variables are provided to the program: -- Everything in the current PAM environment -- All PAM items (PAM_USER, PAM_RHOST, etc.), with the exception of PAM_(OLD)AUTHTOK -- PAM_AUTHTOK and PAM_OLDAUTHTOK are provided if an additional option is given (described with suitably scary warnings in the documentation) -- The various fields of the user's passwd entry (PW_GECOS, PW_GID, PW_SHELL et al.) -- Various PAM return codes (e.g. EXIT_PAM_SUCCESS, EXIT_PAM_PERM_DENIED) so that the program can return error codes meaningful to PAM (imagine a shell script with "exit $EXIT_PAM_IGNORE" or similar). Inapplicable return values are filtered out at the end of each of the module's entry points. * When being invoked as a session module, an option can be specified to invoke the program only on opening or closing a session. (The default is both; the program can distinguish between the two using the ACTION environment variable.) * Instead of directly exec'ing a named program, the module invokes a /bin/sh command string, for greater flexibility. * The program can be invoked with a different UID/GID than the PAM-enabled application; the UID/GID can be specified by name or by number. * The module's command-line syntax allows specifying a shell command string without any option-or-command ambiguity. * The code is portable to OpenPAM. (I will make an effort to contribute it to that project as well; Dag-Erling Smørgrav has received a copy of this message.) * The code is mostly portable to Solaris, just for giggles. (The only issue is a missing setenv() implementation.) There are still some things that need to be addressed, however: * Is the syslog interaction properly following convention? I noticed an inconsistency in the formatting of syslog messages between pam_exec and pam_unix (both invoked from sshd)... Jul 7 15:12:53 bassoon pam_exec[28567]: Command exited with status 0 Jul 7 15:12:53 bassoon sshd[28567]: (pam_unix) session opened for user skunk by (uid=0) ...but am uncertain of how things ought to be done here. * The module will accept the following options, but I'm not sure what exactly it should do (if anything) with them: expose_account try_first_pass use_first_pass use_mapped_pass * Stylistically, PAM options sometimes use run-together words (e.g. "authtok", "nullok", "readenv"), sometimes words separated by underscores ("expose_account", "try_mapped_pass"), and sometimes even a combination of the two ("nullok_secure"). Is my choice of option names a reasonable fit to those currently in use? * I'm a bit unclear on how pam_fail_delay() is supposed to work. Is the manner in which I handled it---and described it in the documentation---at all incorrect? * The man page still needs fleshing out, mainly in describing all the environment variables that the module provides (see all the "????????" strings). Because these map mostly one-to-one to their namesake PAM constants, there may be some redundancy in describing them; I'm not quite sure what is the best way to deal with this. * Some parts of the man page are a bit confused vis-a-vis "services." There's the service provided by the PAM-enabled application (e.g. "Welcome to localhost's ftp service"), the PAM service name (e.g. "ssh", "login"), and the PAM module service ("auth", "account", "session", "passwd"). It is a little difficult to keep all these conceptually distinct, especially the latter two. * I'm not very good at editing DocBook XML. I would like someone to review my draft, particularly to check for wrong or poorly-chosen tags. (One thing that I couldn't figure out is how to make the environment variable names in the lists appear boldfaced in the nroff output; another is how to get a forward section reference to work.) * The man page presents four different synopses, corresponding to the different options available in the four ways the module can be invoked. Did I lay this out correctly? * The nroff stylesheet doesn't handle long-lined <programlisting> blocks very gracefully; see my silly example with beep(1). * (Not specific to pam_exec) The nroff stylesheet doesn't set the title that you sometimes see centered at the top; I believe that "Linux-PAM Manual" should be up there, from the XML's <refmiscinfo> tag. Attached is a patch against current CVS to pam_exec.c and pam_exec.8.xml. It is gzipped, owing to its size. I would appreciate feedback from close scrutiny of the code. It was written with the goals of security, correctness and clarity in mind, but there may be spots or areas lacking in these. (This goes for the comments as well.) I would likewise appreciate being informed of any desirable/necessary conventions that have not been followed. I am by no means a regular contributor to this project, nor any related projects; while I have read the documentation, and referred to other Linux-PAM code in some instances, this is probably not enough to bring me up to speed on everything. Of course, there is room as well for design and stylistic feedback. While I would shy away from suggestions to the effect of rewriting large portions of the module, smaller changes that would make its use and execution more sensible overall will be welcomed. Everything should be here. I look forward to hearing feedback on this list. Sincerely, --Daniel -- NAME = Daniel Richard G. ## Remember, skunks _\|/_ meef? EMAIL1 = skunk@xxxxxxxxxx ## don't smell bad--- (/o|o\) / EMAIL2 = skunk@xxxxxxxxxxxx ## it's the people who < (^),> WWW = http://www.******.org/ ## annoy them that do! / \ -- (****** = site not yet online)
Attachment:
new-pam-exec.patch.gz
Description: Binary data
_______________________________________________ Pam-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/pam-list