diff options
-rw-r--r-- | ChangeLog | 13 | ||||
-rw-r--r-- | daemon/errorgui.c | 4 | ||||
-rw-r--r-- | daemon/server.c | 4 | ||||
-rw-r--r-- | daemon/slave.c | 108 |
4 files changed, 99 insertions, 30 deletions
@@ -1,3 +1,16 @@ +Sat Oct 20 14:11:02 2001 George Lebl <jirka@5z.com> + + * daemon/errorgui.c, daemon/server.c: a bit of debug output. + + * daemon/slave.c: check the home dir, if it doesn't exist (or is not + a directory, then tell the user and try again. Maybe we should + continue and let the session fail, should we? I don't see any + merit in trying to log in with no home dir. Also, clean up verify + on auth problems, in term handler don't reset the signal mask, + and fix some possible races and whack the chooser, same in + xioerror handler. In slave_exit, mask the CHLD signal to avoid + races, and other race fixes + Sat Oct 20 13:31:07 2001 George Lebl <jirka@5z.com> * utils/gdmopen.c: set VT_NUMBER env var diff --git a/daemon/errorgui.c b/daemon/errorgui.c index 10ba0f9e..ce62ccba 100644 --- a/daemon/errorgui.c +++ b/daemon/errorgui.c @@ -139,7 +139,7 @@ gdm_error_box (GdmDisplay *d, const char *dialog_type, const char *error) close(i); /* No error checking here - if it's messed the best response - * is to ignore & try to continue */ + * is to ignore & try to continue */ open ("/dev/null", O_RDONLY); /* open stdin - fd 0 */ open ("/dev/null", O_RDWR); /* open stdout - fd 1 */ open ("/dev/null", O_RDWR); /* open stderr - fd 2 */ @@ -165,7 +165,9 @@ gdm_error_box (GdmDisplay *d, const char *dialog_type, const char *error) gdm_error (_("gdm_error_box: Failed to execute self")); _exit (1); } else if (pid > 0) { + gdm_debug ("gdm_error_box: Ran error box, waiting..."); waitpid (pid, 0, 0); + gdm_debug ("gdm_error_box: Wait done"); extra_process = -1; } else { gdm_error (_("gdm_error_box: Cannot fork to display error/info box")); diff --git a/daemon/server.c b/daemon/server.c index 63461b00..5164c60f 100644 --- a/daemon/server.c +++ b/daemon/server.c @@ -141,8 +141,12 @@ gdm_server_stop (GdmDisplay *disp) /* avoid SIGCHLD race */ disp->servpid = 0; + gdm_debug ("gdm_server_stop: Killing server pid %d", (int)servpid); + if (kill (servpid, SIGTERM) == 0) waitpid (servpid, 0, 0); + + gdm_debug ("gdm_server_stop: Server pid %d dead", (int)servpid); } gdm_server_wipe_cookies (disp); diff --git a/daemon/slave.c b/daemon/slave.c index 5c1a5677..ef67d74a 100644 --- a/daemon/slave.c +++ b/daemon/slave.c @@ -1741,9 +1741,34 @@ gdm_slave_session_start (void) pwent = getpwnam (login); - if (!pwent) - gdm_slave_exit (DISPLAY_REMANAGE, - _("gdm_slave_session_start: User passed auth but getpwnam(%s) failed!"), login); + if (pwent == NULL) { + /* This is sort of an "assert", this should NEVER happen */ + if (greet) + gdm_slave_whack_greeter(); + gdm_slave_exit (DISPLAY_REMANAGE, + _("gdm_slave_session_start: User passed auth but getpwnam(%s) failed!"), login); + } + + if (pwent->pw_dir == NULL || + ! g_file_test (pwent->pw_dir, G_FILE_TEST_ISDIR)) { + char *msg = g_strdup_printf ( + _("Your home directory is listed as '%s'\n" + "but it does not appear to exist.\n" + "GDM cannot log you in unless you have\n" + "a valid home directory."), + ve_sure_string (pwent->pw_dir)); + /* pretend we "logged in" */ + if (greet) + gdm_slave_whack_greeter(); + /* then tell the user to piss off */ + gdm_error_box (d, GNOME_MESSAGE_BOX_ERROR, msg); + + gdm_error (_("%s: Home directory for %s: '%s' does not exist!"), + "gdm_slave_session_start", + login, + ve_sure_string (pwent->pw_dir)); + return; + } setegid (pwent->pw_gid); seteuid (pwent->pw_uid); @@ -1902,6 +1927,8 @@ gdm_slave_session_start (void) gdm_slave_session_cleanup (); gdm_server_stop (d); + gdm_verify_cleanup (d); + _exit (DISPLAY_REMANAGE); } @@ -2234,7 +2261,7 @@ gdm_slave_session_cleanup (void) static void gdm_slave_term_handler (int sig) { - sigset_t tmask, omask; + sigset_t tmask; gdm_debug ("gdm_slave_term_handler: %s got TERM/INT signal", d->name); @@ -2244,7 +2271,7 @@ gdm_slave_term_handler (int sig) sigemptyset (&tmask); sigaddset (&tmask, SIGCHLD); - sigprocmask (SIG_BLOCK, &tmask, &omask); + sigprocmask (SIG_BLOCK, &tmask, NULL); if (extra_process > 1) { /* we sigterm extra processes, and we @@ -2254,17 +2281,24 @@ gdm_slave_term_handler (int sig) } if (d->greetpid != 0) { + pid_t pid = d->greetpid; + d->greetpid = 0; greet = FALSE; gdm_debug ("gdm_slave_term_handler: Whacking greeter"); - if (kill (d->greetpid, sig) == 0) - waitpid (d->greetpid, 0, 0); - d->greetpid = 0; + if (kill (pid, sig) == 0) + waitpid (pid, 0, 0); } else if (login != NULL) { gdm_slave_session_stop (d->sesspid); gdm_slave_session_cleanup (); } - sigprocmask (SIG_SETMASK, &omask, NULL); + if (d->chooserpid != 0) { + pid_t pid = d->chooserpid; + d->chooserpid = 0; + gdm_debug ("gdm_slave_term_handler: Whacking chooser"); + if (kill (pid, sig) == 0) + waitpid (pid, 0, 0); + } gdm_debug ("gdm_slave_term_handler: Whacking server"); @@ -2377,7 +2411,7 @@ gdm_slave_xerror_handler (Display *disp, XErrorEvent *evt) static gint gdm_slave_xioerror_handler (Display *disp) { - sigset_t tmask, omask; + sigset_t tmask; gdm_debug ("gdm_slave_xioerror_handler: I/O error for display %s", d->name); @@ -2387,17 +2421,25 @@ gdm_slave_xioerror_handler (Display *disp) sigemptyset (&tmask); sigaddset (&tmask, SIGCHLD); - sigprocmask (SIG_BLOCK, &tmask, &omask); + sigprocmask (SIG_BLOCK, &tmask, NULL); if (d->greetpid != 0) { - greet = FALSE; - if (kill (d->greetpid, SIGINT) == 0) - waitpid (d->greetpid, 0, 0); + pid_t pid = d->greetpid; d->greetpid = 0; + greet = FALSE; + if (kill (pid, SIGINT) == 0) + waitpid (pid, 0, 0); } else if (login != NULL) { gdm_slave_session_stop (d->sesspid); gdm_slave_session_cleanup (); } + + if (d->chooserpid != 0) { + pid_t pid = d->chooserpid; + d->chooserpid = 0; + if (kill (pid, SIGINT) == 0) + waitpid (pid, 0, 0); + } gdm_error (_("gdm_slave_xioerror_handler: Fatal X error - Restarting %s"), d->name); @@ -2469,25 +2511,33 @@ gdm_slave_exit (gint status, const gchar *format, ...) seteuid (0); setegid (0); - gdm_server_stop (d); - gdm_verify_cleanup (d); + if (d != NULL) { + sigset_t tmask; - /* Kill children where applicable */ - if (d->greetpid != 0) - kill (d->greetpid, SIGTERM); - d->greetpid = 0; + sigemptyset (&tmask); + sigaddset (&tmask, SIGCHLD); + sigprocmask (SIG_BLOCK, &tmask, NULL); - if (d->chooserpid != 0) - kill (d->chooserpid, SIGTERM); - d->chooserpid = 0; + /* Kill children where applicable */ + if (d->greetpid != 0) + kill (d->greetpid, SIGTERM); + d->greetpid = 0; - if (d->sesspid != 0) - kill (-(d->sesspid), SIGTERM); - d->sesspid = 0; + if (d->chooserpid != 0) + kill (d->chooserpid, SIGTERM); + d->chooserpid = 0; + + if (d->sesspid != 0) + kill (-(d->sesspid), SIGTERM); + d->sesspid = 0; - if (d->servpid != 0) - kill (d->servpid, SIGTERM); - d->servpid = 0; + gdm_server_stop (d); + gdm_verify_cleanup (d); + + if (d->servpid != 0) + kill (d->servpid, SIGTERM); + d->servpid = 0; + } _exit (status); } |