[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[PATCH] pam_exec questions and possible patch



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 18:58:45.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, "SESSION=open");
+  int pamResult = putenv(session_environment);
+  pam_syslog (pamh, LOG_DEBUG, "Tried to set SESSION environment variable to 'open', result %d.", pamResult);
+
+  int result = call_exec (pamh, argc, argv);
+
+  sprintf(session_environment, "SESSION");
+
+  pamResult = putenv(session_environment);
+  pam_syslog (pamh, LOG_DEBUG, "Tried to unset SESSION 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, "SESSION=close");
+  int pamResult = putenv(session_environment);
+  pam_syslog (pamh, LOG_DEBUG, "Tried to set SESSION environment variable to 'close', result %d.", pamResult);
+
+  int result = call_exec (pamh, argc, argv);
+
+  sprintf(session_environment, "SESSION");
+  pamResult = putenv(session_environment);
+  pam_syslog (pamh, LOG_DEBUG, "Tried to unset SESSION environment variable, result %d.", pamResult);
+
+  free(session_environment);
+
+  return result;
 }
 
 #ifdef PAM_STATIC

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]