Apologies, I sent a version of the patch that used the wrong name for the environment variable. Here it is with the correct patch. Aaron On 3/21/07, Aaron Cohen <aaron@xxxxxxxxxxxxx> wrote:
I'm currently trying to use pam_exec to call a script to synchronize my home directories with a central server and have come across a couple of issues. Firstly, does pam_exec make any sense outside of the "session" section of pam.conf? It seems slightly hairy to me, because for instance if it's in the auth section a user could cause a program to be executed by another user by only unsuccessfully attempting to log in as that user. Secondly, is there any way to distinguish in the exec'ed program that the session is being opened or closed? I've finally created a simple patch that defines a PAM_SESSION_ACTION environment variable in the executed subprocess so that my script can do the correct actions. Thirdly, does the seteuid option actually work correctly? It seems to me that it simply sets the effective user id to whatever the effective user id already was. My patch changes this by setting the effective userid of the subprocess to the user id of the user who's session is being created if this option is specified. Thanks, Aaron
diff -r -U3 a/modules/pam_exec/pam_exec.8.xml b/modules/pam_exec/pam_exec.8.xml --- a/modules/pam_exec/pam_exec.8.xml 2006-06-09 12:44:06.000000000 -0400 +++ b/modules/pam_exec/pam_exec.8.xml 2007-03-21 18:35:42.000000000 -0400 @@ -42,7 +42,14 @@ <para> pam_exec is a PAM module that can be used to run - an external command. + an external command. + + It is only intended for use in the "session" + portion of your pam configuration. + + An environment variable named "PAM_SESSION_ACTION" + will be defined to either "open" or "close" as + appropriate. </para> </refsect1> @@ -83,9 +90,12 @@ <listitem> <para> Per default pam_exec.so will execute the external command - with the real user ID of the calling process. + with the real and effective user ID of the calling process. Specifying this option means the command is run - with the effective user ID. + with the effective user ID of the user being authenticated. + + Note that if the uid of the calling process is root, both + the real and effective uids will be set. </para> </listitem> </varlistentry> diff -r -U3 a/modules/pam_exec/pam_exec.c b/modules/pam_exec/pam_exec.c --- a/modules/pam_exec/pam_exec.c 2006-08-29 10:43:25.000000000 -0400 +++ b/modules/pam_exec/pam_exec.c 2007-03-21 19:08:23.000000000 -0400 @@ -45,6 +45,7 @@ #include <syslog.h> #include <unistd.h> #include <stdlib.h> +#include <pwd.h> #include <sys/wait.h> #include <sys/stat.h> #include <sys/types.h> @@ -187,14 +188,23 @@ exit (err); } - if (call_setuid) - if (setuid (geteuid ()) == -1) - { - int err = errno; - pam_syslog (pamh, LOG_ERR, "setuid(%lu) failed: %m", - (unsigned long) geteuid ()); - exit (err); - } + /* Set euid to the user id of the user who's session this is */ + if (call_setuid) + { + const char* uname; + struct passwd* pwd; + + pam_get_user(pamh, &uname, NULL); + pwd = getpwnam(uname); + + if (setuid (pwd->pw_uid) == -1) + { + int err = errno; + pam_syslog (pamh, LOG_ERR, "setuid(%lu) failed: %m", + (unsigned long) geteuid ()); + exit (err); + } + } if (setsid () == -1) { @@ -230,7 +240,7 @@ pam_sm_authenticate (pam_handle_t *pamh, int flags UNUSED, int argc, const char **argv) { - return call_exec (pamh, argc, argv); + return PAM_IGNORE; } PAM_EXTERN int @@ -246,30 +256,58 @@ pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv) { - if (flags & PAM_PRELIM_CHECK) - return PAM_SUCCESS; - return call_exec (pamh, argc, argv); + return PAM_IGNORE; } PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags UNUSED, int argc, const char **argv) { - return call_exec (pamh, argc, argv); + return PAM_IGNORE; } PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags UNUSED, int argc, const char **argv) { - return call_exec (pamh, argc, argv); + + char* session_environment; + + asprintf(&session_environment, "PAM_SESSION_ACTION=open"); + int pamResult = putenv(session_environment); + pam_syslog (pamh, LOG_DEBUG, "Tried to set PAM_SESSION_ACTION environment variable to 'open', result %d.", pamResult); + + int result = call_exec (pamh, argc, argv); + + sprintf(session_environment, "PAM_SESSION_ACTION"); + + pamResult = putenv(session_environment); + pam_syslog (pamh, LOG_DEBUG, "Tried to unset PAM_SESSION_ACTION environment variable, result %d.", pamResult); + + free(session_environment); + + return result; } PAM_EXTERN int pam_sm_close_session(pam_handle_t *pamh, int flags UNUSED, int argc, const char **argv) { - return call_exec (pamh, argc, argv); + char* session_environment; + + asprintf(&session_environment, "PAM_SESSION_ACTION=close"); + int pamResult = putenv(session_environment); + pam_syslog (pamh, LOG_DEBUG, "Tried to set PAM_SESSION_ACTION environment variable to 'close', result %d.", pamResult); + + int result = call_exec (pamh, argc, argv); + + sprintf(session_environment, "PAM_SESSION_ACTION"); + pamResult = putenv(session_environment); + pam_syslog (pamh, LOG_DEBUG, "Tried to unset PAM_SESSION_ACTION environment variable, result %d.", pamResult); + + free(session_environment); + + return result; } #ifdef PAM_STATIC
_______________________________________________ Pam-list mailing list Pam-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/pam-list