I tested this patch out this morning finally.  I modified it to work in
cases where the user has PAM compiled in but wants to use shadow or crypt.
It works quite well here but wanted to your input sebastian.  I also
(hopefully) simplified the fork mess/cleanup when the sessions are
actually started.  We were getting two end sessions calls becuase of
entrance_auth_session_end.  This should apply fine from today's cvs.

* Corey Donohoe ([EMAIL PROTECTED]) wrote:
> Hello again !
> * Sebastian Dransfeld ([EMAIL PROTECTED]) wrote:
> > Hi!
> > 
> > Two things:
> > 
> > 1. Why isn't ecore_x_shutdown() and ecore_shutdown() called in 
> > entrance_session.c before the exec's?
> Probably was just forgotten, omitted, or fell into the category of "it just
> didn't work when i put it in its normal spot." We'll see about cleaning it
> up though. :)
> 
> > 
> > 2. I sent at patch a while ago to fix the pam_close_session() problem. I 
> > have since checked quickly through the modules included with pam, and it 
> > seems no core module is erronous coded. Therefore I think that my patch 
> > still is a better way to do it than to simply ignore the error. If it 
> > leads to problems, maybe people will fix their pam modules!
> ok, my 2cents on this issue.
> 
> As for Ibukun's comments last time, I'm not sure of the security
> ramifications that exist with this approach, as per my understanding of the
> docs your approach is correct.  Unfortunately it doesn't give examples of
> what we're tryign to accomplish here.  I'm not sure about the double auth
> thing he mentioned either, because the pam_open_session call is only called
> when the user's session is executed from entrance_session.c (shit you didn't
> even touch).  
> 
> I personally haven't had the chance to fully test your patch, and I imagine
> Ibukun has been busy lately.  I'll do my best to get some testing on this
> patch done in the next few days, and provide my observations.  If all is
> well, we'll team up on Ibukun until he gives in. :D
> 
> btw, you're going to need to call openlog to use the syslog facitilyt in
> entrance_login.
> 
> once again, thx for the problem identifications and the patches !
> 
> > 
> > From the pam guide:
> > "It should be possible for sessions to be opened by one application and 
> > closed by another. This either requires that the module uses only 
> > information obtained from pam_get_item(), or that information regarding 
> > the session is stored in some way by the operating system (in a file for 
> > example)."
> > 
> > Regards
> > Sebastian
> 
> 
> __
> Corey Donohoe
> http://www.atmos.org
> 
__ 
Corey Donohoe
http://www.atmos.org
Index: AUTHORS
===================================================================
RCS file: /cvsroot/enlightenment/e17/apps/entrance/AUTHORS,v
retrieving revision 1.2
diff -u -r1.2 AUTHORS
--- AUTHORS     26 May 2003 05:59:43 -0000      1.2
+++ AUTHORS     30 Jan 2005 16:31:38 -0000
@@ -1,5 +1,6 @@
 Ibukun Olumuyiwa <[EMAIL PROTECTED]>
 Corey Donohoe <[EMAIL PROTECTED]>
 Tilman Sauerbeck <[EMAIL PROTECTED]>
+Sebastian Dransfeld <[EMAIL PROTECTED]>
 
 Credits to Chris Thomas for some of the original work on elogin.
Index: src/client/Makefile.am
===================================================================
RCS file: /cvsroot/enlightenment/e17/apps/entrance/src/client/Makefile.am,v
retrieving revision 1.15
diff -u -r1.15 Makefile.am
--- src/client/Makefile.am      27 Jun 2004 17:05:27 -0000      1.15
+++ src/client/Makefile.am      30 Jan 2005 16:31:40 -0000
@@ -19,7 +19,9 @@
 entrance_LDADD = @edje_libs@ @ecore_libs@ @edb_libs@ @evas_libs@ \
 @esmart_libs@ -lesmart_container -lesmart_text_entry
 
-entrance_login_SOURCES = entrance_login.c
+entrance_login_SOURCES = entrance_login.c \
+               entrance_auth.c \
+               util.c
 
 entrance_edit_SOURCES = entrance_edit.c \
                entrance_config.c entrance_user.c \
Index: src/client/entrance_auth.c
===================================================================
RCS file: /cvsroot/enlightenment/e17/apps/entrance/src/client/entrance_auth.c,v
retrieving revision 1.23
diff -u -r1.23 entrance_auth.c
--- src/client/entrance_auth.c  5 Jan 2005 23:10:28 -0000       1.23
+++ src/client/entrance_auth.c  30 Jan 2005 16:31:40 -0000
@@ -2,7 +2,7 @@
 @file entrance_auth.c
 @brief Variables and data relating to system authentication
 */
-#include"entrance_auth.h"
+#include "entrance_auth.h"
 #include "util.h"
 
 static char *
@@ -87,13 +87,11 @@
 #if HAVE_PAM
    if (e->pam.handle)
    {
-      pam_close_session(e->pam.handle, 0);
+      /* pam_close_session(e->pam.handle, 0); */
       pam_end(e->pam.handle, PAM_SUCCESS);
       e->pam.handle = NULL;
    }
 #endif
-   /* 
-      syslog(LOG_INFO, "Auth: Session Closed Successfully."); */
 }
 
 /**
@@ -147,12 +145,12 @@
 
 #if HAVE_PAM
 /**
- * _entrance_auth_pam_initialize - initialize PAM session, structures etc.
+ * entrance_auth_pam_initialize - initialize PAM session, structures etc.
  * This function will call pam_start() and set the conversation
  * function and others.
  */
-static int
-_entrance_auth_pam_initialize(Entrance_Auth * e, const char *display)
+int
+entrance_auth_pam_initialize(Entrance_Auth * e, const char *display)
 {
    int pamerr;
 
@@ -213,7 +211,7 @@
    int result = AUTH_FAIL;
    int pamerr;
 
-   if (_entrance_auth_pam_initialize(e, display) != E_SUCCESS)
+   if (entrance_auth_pam_initialize(e, display) != E_SUCCESS)
       return ERROR_NO_PAM_INIT;
 
    if ((pamerr = pam_authenticate(e->pam.handle, 0)) == PAM_SUCCESS)
@@ -257,7 +255,7 @@
 {
    char *encrypted;
    char *correct;
-   
+
    correct = e->pw->pw_passwd;
 
    /* Only successfully auth blank password *if* a blank password is given */
@@ -276,7 +274,7 @@
    char *encrypted;
    char *correct;
    struct spwd *sp;
-   
+
    sp = getspnam(e->pw->pw_name);
    endspent();
 
@@ -287,7 +285,7 @@
       syslog(LOG_CRIT, "FATAL: Unable to fetch shadow password.");
       return AUTH_FAIL;
    }
-   
+
    /* Don't authenticate blank password unless blank password is given */
    if ((!correct || !correct[0]) && !strcmp(e->pass, ""))
       return AUTH_SUCCESS;
@@ -323,7 +321,8 @@
         return (entrance_auth_cmp_crypt(e));
         break;
      default:
-        syslog(LOG_CRIT, "FATAL: Invalid authentication mode %d requested", 
mode);
+        syslog(LOG_CRIT, "FATAL: Invalid authentication mode %d requested",
+               mode);
         break;
    }
    return AUTH_FAIL;
Index: src/client/entrance_auth.h
===================================================================
RCS file: /cvsroot/enlightenment/e17/apps/entrance/src/client/entrance_auth.h,v
retrieving revision 1.12
diff -u -r1.12 entrance_auth.h
--- src/client/entrance_auth.h  27 Dec 2004 06:45:14 -0000      1.12
+++ src/client/entrance_auth.h  30 Jan 2005 16:31:40 -0000
@@ -67,6 +67,10 @@
 void entrance_auth_session_end(Entrance_Auth * e);
 void entrance_auth_clear_pass(Entrance_Auth * e);
 
+#ifdef HAVE_PAM
+int entrance_auth_pam_initialize(Entrance_Auth * e, const char *display);
+#endif
+
 /* 0 on success, 1 on failure */
 int entrance_auth_cmp(Entrance_Auth * e, const char *display, int mode);
 void entrance_auth_pass_set(Entrance_Auth * e, const char *str);
Index: src/client/entrance_login.c
===================================================================
RCS file: /cvsroot/enlightenment/e17/apps/entrance/src/client/entrance_login.c,v
retrieving revision 1.2
diff -u -r1.2 entrance_login.c
--- src/client/entrance_login.c 4 Feb 2004 20:59:35 -0000       1.2
+++ src/client/entrance_login.c 30 Jan 2005 16:31:43 -0000
@@ -4,16 +4,78 @@
 #include <sys/types.h>
 #include <sys/wait.h>
 
+#ifdef HAVE_CONFIG_H
+#   include "../config.h"
+#endif
+
+#ifdef HAVE_PAM
+#   include "entrance_auth.h"
+#endif
+
+#ifdef HAVE_PAM
+int
+entrance_end_user_session(Entrance_Auth * e)
+{
+   int pamerr;
+
+   if (!e->pam.handle)
+      return ERROR_NO_PAM_INIT;
+
+   syslog(LOG_INFO, "Ending PAM session for user \"%s\".", e->user);
+
+   if ((pamerr = pam_close_session(e->pam.handle, PAM_SILENT)) != PAM_SUCCESS)
+   {
+      syslog(LOG_CRIT, "PAM: %s.", pam_strerror(e->pam.handle, pamerr));
+      return ERROR_NO_PAM_INIT;
+   }
+
+   return E_SUCCESS;
+}
+#endif
+
 int
 main(int argc, char **argv)
 {
-   pid_t pid;
+   pid_t pid = 0;
+   char *user = NULL;
+   char *display = NULL;
 
-   if (argc != 2)
-      return 0;
+#ifdef HAVE_PAM
+   Entrance_Auth *e = NULL;
+#endif
+
+   if (getuid() != 0)
+   {
+      exit(1);
+   }
+   openlog("entrance_login", LOG_PID, LOG_DAEMON);
 
    pid = atoi(argv[1]);
+   user = argv[2];
+   display = argv[3];
+
+#ifdef HAVE_PAM
+   if (user && display)
+   {
+      e = entrance_auth_new();
+      if (entrance_auth_user_set(e, user))
+         return -1;
+      entrance_auth_pam_initialize(e, display);
+   }
+#endif
+
    if (waitpid(pid, NULL, 0) == pid)
+   {
+#ifdef HAVE_PAM
+      if (e)
+      {
+         if (entrance_end_user_session(e) != E_SUCCESS)
+            syslog(LOG_INFO, "Error Shutting down PAM");
+         entrance_auth_free(e);
+      }
+#endif
+      closelog();
       exit(0);
+   }
    return -1;
 }
Index: src/client/entrance_session.c
===================================================================
RCS file: 
/cvsroot/enlightenment/e17/apps/entrance/src/client/entrance_session.c,v
retrieving revision 1.67
diff -u -r1.67 entrance_session.c
--- src/client/entrance_session.c       27 Dec 2004 06:45:14 -0000      1.67
+++ src/client/entrance_session.c       30 Jan 2005 16:31:44 -0000
@@ -357,6 +357,7 @@
    pid_t pid;
    char buf[PATH_MAX];
    char *shell = NULL;
+   struct passwd *pwent = NULL;
 
    entrance_auth_setup_environment(e->auth, e->display);
    if ((e->session) && (strlen(e->session) > 0))
@@ -385,6 +386,7 @@
       ecore_evas_free(e->ee);
       e->ee = NULL;
    }
+   edje_shutdown();
    ecore_evas_shutdown();
    ecore_x_sync();
    entrance_ipc_shutdown();
@@ -403,40 +405,54 @@
             return;
          }
       }
+      syslog(LOG_INFO, "Opened PAM session. %s : %s.", e->auth->pw->pw_name,
+             e->display);
    }
 #endif
-
+   /* avoid doubling up pam handles before the fork */
+   pwent = struct_passwd_dup(e->auth->pw);
+   entrance_auth_free(e->auth);
+   e->auth = NULL;
    switch ((pid = fork()))
    {
      case 0:
-        if (initgroups(e->auth->pw->pw_name, e->auth->pw->pw_gid))
+        if (initgroups(pwent->pw_name, pwent->pw_gid))
            syslog(LOG_CRIT,
                   "Unable to initialize group (is entrance running as 
root?).");
-        if (setgid(e->auth->pw->pw_gid))
+        if (setgid(pwent->pw_gid))
            syslog(LOG_CRIT, "Unable to set group id.");
-        if (setuid(e->auth->pw->pw_uid))
+        if (setuid(pwent->pw_uid))
            syslog(LOG_CRIT, "Unable to set user id.");
-        shell = strdup(e->auth->pw->pw_shell);
-        entrance_session_free(e);
-        execl(shell, "-", "-c", buf, NULL);
-        exit(0);
+        shell = strdup(pwent->pw_shell);
         break;
      case -1:
         syslog(LOG_INFO, "FORK FAILED, UH OH");
         exit(0);
      default:
+#ifdef HAVE_PAM
+        if (e->config->auth == ENTRANCE_USE_PAM)
+        {
+           snprintf(buf, sizeof(buf), "%s/entrance_login %i %s %s",
+                    PACKAGE_BIN_DIR, (int) pid, pwent->pw_name, e->display);
+        }
+        else
+#endif
+        {
+           snprintf(buf, sizeof(buf), "%s/entrance_login %i", PACKAGE_BIN_DIR,
+                    (int) pid);
+        }
+        _entrance_session_user_list_fix(e);
+        shell = strdup("/bin/sh");
+        /* this bypasses a race condition where entrance loses its x
+           connection before the wm gets it and x goes and resets itself */
+        sleep(10);
         break;
    }
-   _entrance_session_user_list_fix(e);
+   struct_passwd_free(pwent);
    entrance_session_free(e);
-   /* this bypasses a race condition where entrance loses its x connection */
-   /* before the wm gets it and x goes and resets itself */
-   sleep(10);
-   /* replace this rpcoess with a clean small one that just waits for its */
-   /* child to exit.. passed on the cmd-line */
-   snprintf(buf, sizeof(buf), "%s/entrance_login %i", PACKAGE_BIN_DIR,
-            (int) pid);
-   execl("/bin/sh", "/bin/sh", "-c", buf, NULL);
+   /* replace this rpcoess with a clean small one that just waits for its
+      child to exit.. passed on the cmd-line */
+   execl(shell, "-", "-c", buf, NULL);
 }
 
 
Index: src/client/main.c
===================================================================
RCS file: /cvsroot/enlightenment/e17/apps/entrance/src/client/main.c,v
retrieving revision 1.69
diff -u -r1.69 main.c
--- src/client/main.c   4 Jan 2005 23:44:44 -0000       1.69
+++ src/client/main.c   30 Jan 2005 16:31:46 -0000
@@ -629,13 +629,14 @@
    if (!ecore_init())
       return (-1);
    ecore_app_args_set(argc, (const char **) argv);
-   
+
    /* Set locale to user's environment */
-   if(!(setlocale(LC_ALL, "")))
-      fprintf(stderr, "Locale set failed!\n"
-                      "Please make sure you have your locale files installed 
for \"%s\"\n",
-                      getenv("LANG"));
-   
+   if (!(setlocale(LC_ALL, "")))
+      fprintf(stderr,
+              "Locale set failed!\n"
+              "Please make sure you have your locale files installed for 
\"%s\"\n",
+              getenv("LANG"));
+
 
    /* Parse command-line options */
    while (1)
@@ -768,19 +769,25 @@
          specified in config. On systems with * hardware acceleration, GL
          should improve performance appreciably */
       if (!session->config->engine)
+      {
          e = ecore_evas_software_x11_new(NULL, 0, 0, 0, g_x, g_y);
+         ew = ecore_evas_software_x11_window_get(e);
+      }
 #ifdef HAVE_ECORE_GL_X11
       else if (session->config->engine)
+      {
          e = ecore_evas_gl_x11_new(NULL, 0, 0, 0, g_x, g_y);
+         ew = ecore_evas_gl_x11_window_get(e);
+      }
 #endif
       else
       {
          fprintf(stderr,
                  "Warning: Invalid Evas engine specified in config. Defaulting 
to software engine.\n");
          e = ecore_evas_software_x11_new(NULL, 0, 0, 0, g_x, g_y);
+         ew = ecore_evas_software_x11_window_get(e);
       }
 
-      ew = ecore_evas_software_x11_window_get(e);
       if (session->testing)
          ecore_evas_title_set(e, "Entrance - Testing Mode");
       else

Reply via email to