diff options
author | George Lebl <jirka@5z.com> | 2003-07-31 21:13:43 +0000 |
---|---|---|
committer | George Lebl <jirka@src.gnome.org> | 2003-07-31 21:13:43 +0000 |
commit | 391c23dc2329811fc0bd658a6673f5cb7707f4d9 (patch) | |
tree | 29a2f83020980a4b373a53403636b9903e682595 | |
parent | 45e5fe2328ea162dd5c4b36423cb44e5261d6f42 (diff) | |
download | gdm-391c23dc2329811fc0bd658a6673f5cb7707f4d9.tar.gz |
A bunch of fixes backported from the devel version
Thu Jul 31 14:07:25 2003 George Lebl <jirka@5z.com>
A bunch of fixes backported from the devel version
* config/XKeepsCrashing: fix rh #84247 by not using gettext
if it doesn't exist (empty dialogs)
* config/XKeepsCrashing, daemon/gdm.c, daemon/misc.c,
utils/gdmopen.c: Fix rh #74911 by setting TERM to linux,
and using a login shell to start the dialogs, backported from
devel
* daemon/slave.c, daemon/verify-pam.c: fix rh #86481 by cleaning
pam way before stopping server and all that. Should make sure
the session is closed if the X server crashes or is killed.
Also doesn't close session if it wasn't opened.
* daemon/gdm.c, utils/gdmaskpass.c: use GETTEXT_PACKAGE, not
PACKAGE
* config/gdm.conf.in, daemon/gdm.h: fix comment on PingInterval to
say 'minutes' and not seconds and make the default be 1
* daemon/errorgui.c: cap error lines at 100, and convert to utf8
if not properly utf8 already.
* gui/**/*.c: add gtk_dialog_set_has_separator (foo, FALSE)
to get at least marginally closer to the HIG without actually
doing any intrustive change in the code
* daemon/gdm.c, daemon/slave.c, daemon/server.c, daemon/misc.[ch],
daemon/verify-*.c: use a sleep replacement using select which
handles signals better and doesn't conflict with alarm.
* daemon/gdm.c: suspend now doesn't whack the gdm main daemon
process, duh!
* daemon/verify-pam.c, daemon/slave.c, daemon/misc.[ch]: add
gdm_reset_limits and reset limits in the parent process
and when cleaning up the verify
* daemon/misc.c, daemon/gdmXnestchooser.c: fix the code that
checks for a free display number to find one without
a lockfile.
* daemon/server.c: whack server lockfile if it still exists
along with the cookies. Handles X crashes.
* daemon/server.c: correct select usage when waiting for server
* daemon/slave.c, daemon/misc.c: ignore SIGUSR1 and SIGPIPE by
default and don't mask out all signals, just unmask the ones
we're interested in. and also unset SIGINT in unset_signals
* daemon/slave.c: handle restarts of greeter during configuration
semi sanely. Can't completely backport the fix from devel,
so there is a loop with a sleep instead of the waitpid replacement.
doesn't restart greeter in a signal, and allow messages to be sent
from the usr2 signal handler.
* daemon/slave.c: chdir to the home_dir when we're still root,
just in case something is weird, so that we don't say in the
ServAuthDir
* gui/greeter/greeter.[ch], gui/greeter/greeter_item_pam.c: follow
full protocol just like the gdmlogin
* gui/gdmsetup.c: when the gdmsetup encounters more then 50 users,
stop filling the combobox list
* gui/greeter/greeter_item_parser.c: Semi fix for rh #83369. When
we are at lower resolutions, size fonts to be smaller.
* gui/greeter/greeter_action_language.c,
gui/greeter/greeter_system.c, gui/greeter/greeter_session.c:
make OK the default response for these dialogs
* daemon/verify-pam.c: make sure to translate "Password: "
if it comes from pam untranslated.
* daemon/slave.c: setsid right after fork to avoid a race.
* README: add website link
-rw-r--r-- | ChangeLog | 84 | ||||
-rw-r--r-- | NEWS | 46 | ||||
-rw-r--r-- | README | 1 | ||||
-rwxr-xr-x | config/XKeepsCrashing | 32 | ||||
-rw-r--r-- | config/gdm.conf.in | 8 | ||||
-rw-r--r-- | configure.in | 2 | ||||
-rw-r--r-- | daemon/errorgui.c | 46 | ||||
-rw-r--r-- | daemon/gdm.c | 37 | ||||
-rw-r--r-- | daemon/gdm.h | 2 | ||||
-rw-r--r-- | daemon/misc.c | 186 | ||||
-rw-r--r-- | daemon/misc.h | 3 | ||||
-rw-r--r-- | daemon/server.c | 38 | ||||
-rw-r--r-- | daemon/slave.c | 121 | ||||
-rw-r--r-- | daemon/verify-crypt.c | 4 | ||||
-rw-r--r-- | daemon/verify-pam.c | 88 | ||||
-rw-r--r-- | daemon/verify-shadow.c | 4 | ||||
-rw-r--r-- | gui/gdmXnestchooser.c | 19 | ||||
-rw-r--r-- | gui/gdmflexiserver.c | 4 | ||||
-rw-r--r-- | gui/gdmlogin.c | 16 | ||||
-rw-r--r-- | gui/gdmphotosetup.c | 8 | ||||
-rw-r--r-- | gui/gdmsetup.c | 16 | ||||
-rw-r--r-- | gui/greeter/greeter.c | 68 | ||||
-rw-r--r-- | gui/greeter/greeter.h | 2 | ||||
-rw-r--r-- | gui/greeter/greeter_action_language.c | 3 | ||||
-rw-r--r-- | gui/greeter/greeter_item_pam.c | 36 | ||||
-rw-r--r-- | gui/greeter/greeter_parser.c | 20 | ||||
-rw-r--r-- | gui/greeter/greeter_session.c | 4 | ||||
-rw-r--r-- | gui/greeter/greeter_system.c | 4 | ||||
-rw-r--r-- | utils/gdmaskpass.c | 4 | ||||
-rw-r--r-- | utils/gdmopen.c | 45 |
30 files changed, 777 insertions, 174 deletions
@@ -1,3 +1,87 @@ +Thu Jul 31 14:07:25 2003 George Lebl <jirka@5z.com> + + A bunch of fixes backported from the devel version + + * config/XKeepsCrashing: fix rh #84247 by not using gettext + if it doesn't exist (empty dialogs) + + * config/XKeepsCrashing, daemon/gdm.c, daemon/misc.c, + utils/gdmopen.c: Fix rh #74911 by setting TERM to linux, + and using a login shell to start the dialogs, backported from + devel + + * daemon/slave.c, daemon/verify-pam.c: fix rh #86481 by cleaning + pam way before stopping server and all that. Should make sure + the session is closed if the X server crashes or is killed. + Also doesn't close session if it wasn't opened. + + * daemon/gdm.c, utils/gdmaskpass.c: use GETTEXT_PACKAGE, not + PACKAGE + + * config/gdm.conf.in, daemon/gdm.h: fix comment on PingInterval to + say 'minutes' and not seconds and make the default be 1 + + * daemon/errorgui.c: cap error lines at 100, and convert to utf8 + if not properly utf8 already. + + * gui/**/*.c: add gtk_dialog_set_has_separator (foo, FALSE) + to get at least marginally closer to the HIG without actually + doing any intrustive change in the code + + * daemon/gdm.c, daemon/slave.c, daemon/server.c, daemon/misc.[ch], + daemon/verify-*.c: use a sleep replacement using select which + handles signals better and doesn't conflict with alarm. + + * daemon/gdm.c: suspend now doesn't whack the gdm main daemon + process, duh! + + * daemon/verify-pam.c, daemon/slave.c, daemon/misc.[ch]: add + gdm_reset_limits and reset limits in the parent process + and when cleaning up the verify + + * daemon/misc.c, daemon/gdmXnestchooser.c: fix the code that + checks for a free display number to find one without + a lockfile. + + * daemon/server.c: whack server lockfile if it still exists + along with the cookies. Handles X crashes. + + * daemon/server.c: correct select usage when waiting for server + + * daemon/slave.c, daemon/misc.c: ignore SIGUSR1 and SIGPIPE by + default and don't mask out all signals, just unmask the ones + we're interested in. and also unset SIGINT in unset_signals + + * daemon/slave.c: handle restarts of greeter during configuration + semi sanely. Can't completely backport the fix from devel, + so there is a loop with a sleep instead of the waitpid replacement. + doesn't restart greeter in a signal, and allow messages to be sent + from the usr2 signal handler. + + * daemon/slave.c: chdir to the home_dir when we're still root, + just in case something is weird, so that we don't say in the + ServAuthDir + + * gui/greeter/greeter.[ch], gui/greeter/greeter_item_pam.c: follow + full protocol just like the gdmlogin + + * gui/gdmsetup.c: when the gdmsetup encounters more then 50 users, + stop filling the combobox list + + * gui/greeter/greeter_item_parser.c: Semi fix for rh #83369. When + we are at lower resolutions, size fonts to be smaller. + + * gui/greeter/greeter_action_language.c, + gui/greeter/greeter_system.c, gui/greeter/greeter_session.c: + make OK the default response for these dialogs + + * daemon/verify-pam.c: make sure to translate "Password: " + if it comes from pam untranslated. + + * daemon/slave.c: setsid right after fork to avoid a race. + + * README: add website link + 2003-06-30 Mohammad DAMT <mdamt@bisnisweb.com> * po/id.po: Added Indonesian translation @@ -1,5 +1,51 @@ Ahh news... +2.4.1.5 stuff: + +- When at lower resolutions use smaller fonts (rh #83369) + +- Fix text dialogs (rh #84247, rh #74911) + +- Fix logout by ctrl-alt-bs to really close your session with + pam to allow others to gain console access (rh #86481) + +- PingInterval default now 1 (it's in minutes) and fix + the comment + +- Fix sleep/alarm conflict for xdmcp logins + +- Fix restarts of greeters during setup sanely and fix + hang after setup ends. + +- gdmsetup won't put more then 50 entries in it's combobox + making it not hang on large systems + +- Suspend doesn't whack the main daemon + +- Reset user limits after user is logging in making + AlwaysRestart=false safe again, but leave that at true + for now. + +- Fix checking for free display numbers + +- Handle X crashes vs. lock files by whacking the lockfiles + +- Ignore SIGUSR1 and SIGPIPE normally which should fix those + weird errors with X busy + +- "Password: " should always be translated now + +- Kill separators from all dialogs I could find. + +- Cap .xsession-errors at 100 lines and convert to utf8 if not + in utf8 to allow display. + +- Other minor fixes + +- Translation updates (Mohammad DAMT, Guntupalli Karunakar, + Arafat Medini, Abel Cheung, Ravishankar Shrivastava, + Danilo, Segan) + 2.4.1.4 stuff: - Raise DisplaysPerHost default to 2 to avoid a FAQ-type-problem @@ -1,6 +1,7 @@ GDM - GNOME DISPLAY MANAGER + Web: http://www.jirka.org/gdm.html The Gnome Display Manager is a re-implementation of the well known xdm program. diff --git a/config/XKeepsCrashing b/config/XKeepsCrashing index df768c52..1a5d3c62 100755 --- a/config/XKeepsCrashing +++ b/config/XKeepsCrashing @@ -1,11 +1,21 @@ #!/bin/sh -MSG3=`gettext -s "I cannot start the X server (your graphical interface). It is likely that it is not set up correctly. You will need to log in on a console and rerun the X configuration program. Then restart GDM."` -MSG4=`gettext -s "Would you like me to try to run the X configuration program? Note that you will need the root password for this."` -MSG5=`gettext -s "Please type in the root (privileged user) password."` -MSG6=`gettext -s "I will now try to restart the X server again."` -MSG7=`gettext -s "I will disable this X server for now. Restart GDM when it is configured correctly."` -MSG8=`gettext -s "I cannot start the X server (your graphical interface). It is likely that it is not set up correctly. Would you like to view the X server output to diagnose the problem?"` +gettextbin=`which gettext 2>/dev/null` + +gettextfunc () { + if [ "x$gettextbin" != "x" ] ; then + $gettextbin -s "$1" + else + echo "$1" + fi +} + +MSG3=`gettextfunc "I cannot start the X server (your graphical interface). It is likely that it is not set up correctly. You will need to log in on a console and rerun the X configuration program. Then restart GDM."` +MSG4=`gettextfunc "Would you like me to try to run the X configuration program? Note that you will need the root password for this."` +MSG5=`gettextfunc "Please type in the root (privileged user) password."` +MSG6=`gettextfunc "I will now try to restart the X server again."` +MSG7=`gettextfunc "I will disable this X server for now. Restart GDM when it is configured correctly."` +MSG8=`gettextfunc "I cannot start the X server (your graphical interface). It is likely that it is not set up correctly. Would you like to view the X server output to diagnose the problem?"` # there are some env vars defined: # XLOG = the log file for the X server @@ -62,20 +72,16 @@ fi # if grep '^Cannot open mouse ' "$XLOG" ; then - MSG8=`gettext -s "I cannot start the X server (your graphical interface). It seems that the pointer device (your mouse) is not set up correctly. Would you like to view the X server output to diagnose the problem?"` + MSG8=`gettextfunc "I cannot start the X server (your graphical interface). It seems that the pointer device (your mouse) is not set up correctly. Would you like to view the X server output to diagnose the problem?"` if test -x /usr/sbin/mouseconfig ; then XCONFIGURATOR=/usr/sbin/mouseconfig # Note: we know this is a mouse problem and yay we have mouseconfig - MSG4=`gettext -s "Would you like me to try to run the mouse configuration program? Note that you will need the root password for this."` + MSG4=`gettextfunc "Would you like me to try to run the mouse configuration program? Note that you will need the root password for this."` fi fi -# -# If we don't have an X configurator we abort right now -# - # we require 'gdmopen', to open a console, because we really dont # have one. Perhaps someone should try to figure out some shell # black magic to get this to work on other then linux systems @@ -91,7 +97,7 @@ else # We do a lot of work wastefully over again, but oh well, # perhaps this needs fixing. # - "$SBINDIR/gdmopen" $0 -noopen "$@" + "$SBINDIR/gdmopen" -l /bin/sh -c "$0 -noopen $@" exit $? fi diff --git a/config/gdm.conf.in b/config/gdm.conf.in index fc00ab24..d918d242 100644 --- a/config/gdm.conf.in +++ b/config/gdm.conf.in @@ -145,9 +145,11 @@ MaxWaitIndirect=15 # host. This is now set at 2 since if the server crashes then gdm doesn't # know for some time and wouldn't allow another session. DisplaysPerHost=2 -# The number of seconds after which a non-responsive session is logged off. -# Better keep this low. -PingInterval=5 +# The number of minutes after which a non-responsive session is logged off. +# Better keep this low. This is the last version where this will be minutes. +# In the current development versions this is replaced with PingIntervalSeconds +# which defaults to 15 which is much nicer. +PingInterval=1 # The port. 177 is the standard port so better keep it that way Port=177 # Willing script, none is shipped and by default we'll send diff --git a/configure.in b/configure.in index c4e2b615..a7bdc8a5 100644 --- a/configure.in +++ b/configure.in @@ -8,7 +8,7 @@ dnl AC_PROG_INTLTOOL([0.21]) AM_CONFIG_HEADER(config.h) -AM_INIT_AUTOMAKE(gdm,2.4.1.4) +AM_INIT_AUTOMAKE(gdm,2.4.1.5) AM_MAINTAINER_MODE GDK_PIXBUF_REQUIRED=1.3.1 diff --git a/daemon/errorgui.c b/daemon/errorgui.c index 7de951a1..8246f6e7 100644 --- a/daemon/errorgui.c +++ b/daemon/errorgui.c @@ -27,6 +27,7 @@ #include <syslog.h> #include <sys/types.h> #include <sys/wait.h> +#include <sys/stat.h> #include <fcntl.h> #include "gdm.h" #include "misc.h" @@ -116,21 +117,44 @@ static void show_errors (GtkWidget *button, gpointer data) { const char *file = data; + char *details; FILE *fp; + struct stat s; GtkWidget *sw; GtkWidget *label; GtkWidget *dlg = gtk_widget_get_toplevel (button); GtkWidget *parent = button->parent; GString *gs = g_string_new (NULL); + gboolean valid_utf8 = TRUE; + + fp = NULL; + if (stat (file, &s) == 0) { + if (S_ISREG (s.st_mode)) + fp = fopen (file, "r"); + else { + g_string_printf (gs, "%s not a regular file!\n", file); + } + } - fp = fopen (file, "r"); if (fp != NULL) { - char buf[256]; - while (fgets (buf, sizeof (buf), fp)) + char buf[128]; + int lines = 0; + while (fgets (buf, sizeof (buf), fp)) { + if ( ! g_utf8_validate (buf, -1, NULL)) + valid_utf8 = FALSE; g_string_append (gs, buf); + /* cap lines at 100 */ + if (lines ++ > 100) { + g_string_append (gs, "\n... File too long to display ...\n"); + break; + } + } fclose (fp); } else { - g_string_printf (gs, _("%s could not be opened"), file); + char *loc; + loc = gdm_locale_to_utf8 (_("%s could not be opened")); + g_string_append_printf (gs, loc, file); + g_free (loc); } gtk_widget_destroy (button); @@ -149,15 +173,21 @@ show_errors (GtkWidget *button, gpointer data) gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_IN); - label = gtk_label_new (gs->str); + details = g_string_free (gs, FALSE); + + if ( ! valid_utf8) { + char *tmp = gdm_locale_to_utf8 (details); + g_free (details); + details = tmp; + } + + label = gtk_label_new (details); gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (sw), label); gtk_widget_show (label); gtk_box_pack_start (GTK_BOX (parent), sw, TRUE, TRUE, 0); - g_string_free (gs, TRUE); - center_window (dlg); } @@ -223,6 +253,7 @@ gdm_error_box_full (GdmDisplay *d, GtkMessageType type, const char *error, "%s", loc); g_free (loc); + gtk_dialog_set_has_separator (GTK_DIALOG (dlg), FALSE); if (details_label != NULL) { loc = gdm_locale_to_utf8 (details_label); @@ -500,6 +531,7 @@ gdm_failsafe_yesno (GdmDisplay *d, GTK_BUTTONS_YES_NO, "%s", loc); + gtk_dialog_set_has_separator (GTK_DIALOG (dlg), FALSE); sid = g_signal_lookup ("event", GTK_TYPE_WIDGET); diff --git a/daemon/gdm.c b/daemon/gdm.c index becc3a07..2cfe554e 100644 --- a/daemon/gdm.c +++ b/daemon/gdm.c @@ -831,7 +831,7 @@ gdm_final_cleanup (void) * because X is stupid and full of races and will hang my * keyboard if I don't */ if (li != list) - sleep (2); + gdm_sleep_no_signal (2); gdm_display_unmanage (d); } g_slist_free (list); @@ -921,7 +921,7 @@ deal_with_x_crashes (GdmDisplay *d) gnome_setenv ("SBINDIR", EXPANDED_SBINDIR, TRUE); /* To enable gettext stuff in the script */ - gnome_setenv ("TEXTDOMAIN", PACKAGE, TRUE); + gnome_setenv ("TEXTDOMAIN", GETTEXT_PACKAGE, TRUE); gnome_setenv ("TEXTDOMAINDIR", GNOMELOCALEDIR, TRUE); execv (argv[0], argv); @@ -978,6 +978,30 @@ deal_with_x_crashes (GdmDisplay *d) return FALSE; } +static void +suspend_machine (void) +{ + if (GdmSuspendReal != NULL && + fork () == 0) { + char **argv; + if (GdmXdmcp) + gdm_xdmcp_close (); + /* In the child setup empty mask and set all signals to + * default values */ + gdm_unset_signals (); + + /* Also make a new process group */ + setsid (); + + chdir ("/"); + + argv = ve_split (GdmSuspendReal); + execv (argv[0], argv); + /* FIXME: what about fail */ + _exit (1); + } +} + static gboolean gdm_cleanup_children (void) { @@ -1142,14 +1166,7 @@ start_autopsy: case DISPLAY_SUSPEND: /* Suspend machine */ gdm_info (_("gdm_child_action: Master suspending...")); - - gdm_final_cleanup (); - chdir ("/"); - - argv = ve_split (GdmSuspendReal); - execv (argv[0], argv); - - gdm_error (_("gdm_child_action: Suspend failed: %s"), strerror (errno)); + suspend_machine (); status = DISPLAY_REMANAGE; goto start_autopsy; diff --git a/daemon/gdm.h b/daemon/gdm.h index 72510d57..86a0abfb 100644 --- a/daemon/gdm.h +++ b/daemon/gdm.h @@ -193,7 +193,7 @@ enum { #define GDM_KEY_INDIRECT "xdmcp/HonorIndirect=true" #define GDM_KEY_MAXINDIR "xdmcp/MaxPendingIndirect=4" #define GDM_KEY_MAXINDWAIT "xdmcp/MaxWaitIndirect=30" -#define GDM_KEY_PINGINTERVAL "xdmcp/PingInterval=5" +#define GDM_KEY_PINGINTERVAL "xdmcp/PingInterval=1" #define GDM_KEY_WILLING "xdmcp/Willing=" EXPANDED_SYSCONFDIR "/gdm/Xwilling" #define GDM_KEY_GTKRC "gui/GtkRC=" EXPANDED_DATADIR "/themes/Default/gtk/gtkrc" diff --git a/daemon/misc.c b/daemon/misc.c index 4f5f0a74..aea74d63 100644 --- a/daemon/misc.c +++ b/daemon/misc.c @@ -37,6 +37,7 @@ #ifdef HAVE_SYS_SOCKIO_H #include <sys/sockio.h> #endif +#include <sys/resource.h> #include <vicious.h> @@ -319,6 +320,7 @@ gdm_get_free_display (int start, uid_t server_uid) GSList *li; struct stat s; char buf[256]; + FILE *fp; for (li = displays; li != NULL; li = li->next) { GdmDisplay *dsp = li->data; @@ -344,6 +346,32 @@ gdm_get_free_display (int start, uid_t server_uid) } close (sock); + /* if lock file exists and the process exists */ + g_snprintf (buf, sizeof (buf), "/tmp/.X%d-lock", i); + if (stat (buf, &s) == 0 && + ! S_ISREG (s.st_mode)) { + /* Eeeek! not a regular file? Perhaps someone + is trying to play tricks on us */ + continue; + } + fp = fopen (buf, "r"); + if (fp != NULL) { + char buf2[100]; + if (fgets (buf2, sizeof (buf2), fp) != NULL) { + gulong pid; + if (sscanf (buf2, "%lu", &pid) == 1 && + kill (pid, 0) == 0) { + fclose (fp); + continue; + } + + } + fclose (fp); + + /* whack the file, it's a stale lock file */ + unlink (buf); + } + /* if starting as root, we'll be able to overwrite any * stale sockets or lock files, but a user may not be * able to */ @@ -373,53 +401,62 @@ gboolean gdm_text_message_dialog (const char *msg) { char *dialog; /* do we have dialog?*/ + char *msg_quoted; if (access (EXPANDED_SBINDIR "/gdmopen", X_OK) != 0) return FALSE; + msg_quoted = g_shell_quote (msg); + dialog = g_find_program_in_path ("dialog"); if (dialog == NULL) dialog = g_find_program_in_path ("gdialog"); if (dialog == NULL) dialog = g_find_program_in_path ("whiptail"); if (dialog != NULL) { - char *argv[7]; - + char *argv[6]; + argv[0] = EXPANDED_SBINDIR "/gdmopen"; - argv[1] = dialog; - argv[2] = "--msgbox"; - argv[3] = (char *)msg; - argv[4] = "11"; - argv[5] = "70"; - argv[6] = NULL; + argv[1] = "-l"; + argv[2] = "/bin/sh"; + argv[3] = "-c"; + argv[4] = g_strdup_printf ("%s --msgbox %s 11 70", + dialog, msg_quoted); + argv[5] = NULL; /* make sure gdialog wouldn't get confused */ if (gdm_exec_wait (argv, TRUE /* no display */, TRUE /* de_setuid */) < 0) { g_free (dialog); + g_free (msg_quoted); + g_free (argv[4]); return FALSE; } g_free (dialog); + g_free (argv[4]); } else { - char *argv[5]; + char *argv[6]; argv[0] = EXPANDED_SBINDIR "/gdmopen"; - argv[1] = "/bin/sh"; - argv[2] = "-c"; - argv[3] = g_strdup_printf + argv[1] = "-l"; + argv[2] = "/bin/sh"; + argv[3] = "-c"; + argv[4] = g_strdup_printf ("clear ; " - "echo \"%s\" ; read ; clear", - msg); - argv[4] = NULL; + "echo %s ; read ; clear", + msg_quoted); + argv[5] = NULL; if (gdm_exec_wait (argv, TRUE /* no display */, TRUE /* de_setuid */) < 0) { - g_free (argv[3]); + g_free (argv[4]); + g_free (msg_quoted); return FALSE; } - g_free (argv[3]); + g_free (argv[4]); } + g_free (msg_quoted); return TRUE; } @@ -427,6 +464,7 @@ gboolean gdm_text_yesno_dialog (const char *msg, gboolean *ret) { char *dialog; /* do we have dialog?*/ + char *msg_quoted; if (access (EXPANDED_SBINDIR "/gdmopen", X_OK) != 0) return FALSE; @@ -434,36 +472,42 @@ gdm_text_yesno_dialog (const char *msg, gboolean *ret) if (ret != NULL) *ret = FALSE; + msg_quoted = g_shell_quote (msg); + dialog = g_find_program_in_path ("dialog"); if (dialog == NULL) dialog = g_find_program_in_path ("gdialog"); if (dialog == NULL) dialog = g_find_program_in_path ("whiptail"); if (dialog != NULL) { - char *argv[7]; + char *argv[6]; int retint; argv[0] = EXPANDED_SBINDIR "/gdmopen"; - argv[1] = dialog; - argv[2] = "--yesno"; - argv[3] = (char *)msg; - argv[4] = "11"; - argv[5] = "70"; - argv[6] = NULL; + argv[1] = "-l"; + argv[2] = "/bin/sh"; + argv[3] = "-c"; + argv[4] = g_strdup_printf ("%s --yesno %s 11 70", + dialog, msg_quoted); + argv[5] = NULL; /* will unset DISPLAY and XAUTHORITY if they exist * so that gdialog (if used) doesn't get confused */ retint = gdm_exec_wait (argv, TRUE /* no display */, TRUE /* de_setuid */); if (retint < 0) { + g_free (argv[4]); g_free (dialog); + g_free (msg_quoted); return FALSE; } if (ret != NULL) *ret = (retint == 0) ? TRUE : FALSE; + g_free (argv[4]); g_free (dialog); + g_free (msg_quoted); return TRUE; } else { @@ -471,33 +515,37 @@ gdm_text_yesno_dialog (const char *msg, gboolean *ret) int tempfd; FILE *fp; char buf[256]; - char *argv[5]; + char *argv[6]; tempfd = g_mkstemp (tempname); - if (tempfd < 0) + if (tempfd < 0) { + g_free (msg_quoted); return FALSE; + } close (tempfd); argv[0] = EXPANDED_SBINDIR "/gdmopen"; - argv[1] = "/bin/sh"; - argv[2] = "-c"; - argv[3] = g_strdup_printf + argv[1] = "-l"; + argv[2] = "/bin/sh"; + argv[3] = "-c"; + argv[4] = g_strdup_printf ("clear ; " - "echo \"%s\" ; echo ; echo \"%s\" ; " + "echo %s ; echo ; echo \"%s\" ; " "read RETURN ; echo $RETURN > %s ; clear'", - msg, + msg_quoted, /* Translators, don't translate the 'y' and 'n' */ _("y = Yes or n = No? >"), tempname); - argv[4] = NULL; + argv[5] = NULL; if (gdm_exec_wait (argv, TRUE /* no display */, TRUE /* de_setuid */) < 0) { - g_free (argv[3]); + g_free (argv[4]); + g_free (msg_quoted); return FALSE; } - g_free (argv[3]); + g_free (argv[4]); if (ret != NULL) { fp = fopen (tempname, "r"); @@ -507,12 +555,14 @@ gdm_text_yesno_dialog (const char *msg, gboolean *ret) *ret = TRUE; fclose (fp); } else { + g_free (msg_quoted); return FALSE; } } unlink (tempname); + g_free (msg_quoted); return TRUE; } } @@ -1085,6 +1135,7 @@ gdm_unset_signals (void) signal (SIGUSR1, SIG_DFL); signal (SIGUSR2, SIG_DFL); signal (SIGCHLD, SIG_DFL); + signal (SIGINT, SIG_DFL); signal (SIGTERM, SIG_DFL); signal (SIGPIPE, SIG_DFL); signal (SIGALRM, SIG_DFL); @@ -1149,6 +1200,73 @@ gdm_locale_from_utf8 (const char *text) return out; } +void +gdm_sleep_no_signal (int secs) +{ + time_t endtime = time (NULL)+secs; + + while (secs > 0) { + struct timeval tv; + tv.tv_sec = secs; + tv.tv_usec = 0; + select (0, NULL, NULL, NULL, &tv); + /* don't want to use sleep since we're using alarm + for pinging */ + secs = endtime - time (NULL); + } +} + +void +gdm_reset_limits (void) +{ + struct rlimit unlim = { RLIM_INFINITY, RLIM_INFINITY }; + + /* Note: I don't really know which ones are really very standard + and which ones are not, so I just test for them all one by one */ + +#ifdef RLIMIT_CPU + setrlimit (RLIMIT_CPU, &unlim); +#endif +#ifdef RLIMIT_DATA + setrlimit (RLIMIT_DATA, &unlim); +#endif +#ifdef RLIMIT_FSIZE + setrlimit (RLIMIT_FSIZE, &unlim); +#endif +#ifdef RLIMIT_LOCKS + setrlimit (RLIMIT_LOCKS, &unlim); +#endif +#ifdef RLIMIT_MEMLOCK + setrlimit (RLIMIT_MEMLOCK, &unlim); +#endif +#ifdef RLIMIT_NOFILE + setrlimit (RLIMIT_NOFILE, &unlim); +#endif +#ifdef RLIMIT_OFILE + setrlimit (RLIMIT_OFILE, &unlim); +#endif +#ifdef RLIMIT_NPROC + setrlimit (RLIMIT_NPROC, &unlim); +#endif +#ifdef RLIMIT_RSS + setrlimit (RLIMIT_RSS, &unlim); +#endif +#ifdef RLIMIT_STACK + setrlimit (RLIMIT_STACK, &unlim); +#endif +#ifdef RLIMIT_CORE + setrlimit (RLIMIT_CORE, &unlim); +#endif +#ifdef RLIMIT_AS + setrlimit (RLIMIT_AS, &unlim); +#endif +#ifdef RLIMIT_VMEM + setrlimit (RLIMIT_VMEM, &unlim); +#endif +#ifdef RLIMIT_PTHREAD + setrlimit (RLIMIT_PTHREAD, &unlim); +#endif +} /* EOF */ diff --git a/daemon/misc.h b/daemon/misc.h index d483875d..06bed764 100644 --- a/daemon/misc.h +++ b/daemon/misc.h @@ -88,6 +88,9 @@ void gdm_saveenv (void); /* leaks */ void gdm_restoreenv (void); +void gdm_sleep_no_signal (int secs); +void gdm_reset_limits (void); + #endif /* GDM_MISC_H */ /* EOF */ diff --git a/daemon/server.c b/daemon/server.c index e59db78a..b2e20853 100644 --- a/daemon/server.c +++ b/daemon/server.c @@ -78,6 +78,8 @@ static int server_signal_pipe[2]; void gdm_server_wipe_cookies (GdmDisplay *disp) { + char buf[256]; + if ( ! ve_string_empty (disp->authfile)) unlink (disp->authfile); g_free (disp->authfile); @@ -86,6 +88,27 @@ gdm_server_wipe_cookies (GdmDisplay *disp) unlink (disp->authfile_gdm); g_free (disp->authfile_gdm); disp->authfile_gdm = NULL; + + /* X seems to be sometimes broken with its lock files and + doesn't seem to remove them always, and if you manage + to get into the weird state where the old pid now + corresponds to some new pid, X will just die with + a stupid error. */ + + /* Yes there could be a race here if another X server starts + at this exact instant. Oh well such is life. Very unlikely + to happen though as we should really be the only ones + trying to start X servers, and we aren't starting an + X server on this display yet. */ + + /* if lock file exists and it is our process, whack it! */ + g_snprintf (buf, sizeof (buf), "/tmp/.X%d-lock", disp->dispnum); + unlink (buf); + + /* whack the unix socket as well */ + g_snprintf (buf, sizeof (buf), + "/tmp/.X11-unix/X%d", disp->dispnum); + unlink (buf); } /* ignore handlers */ @@ -146,7 +169,7 @@ gdm_server_reinit (GdmDisplay *disp) * get whacked ourselves after we open the connection and we'll think * it's an X screwup, which is really OK to happen and will just * restart the Xserver, it's just more nasty. Oh how fun */ - sleep (1); + gdm_sleep_no_signal (1); } else if (pid == 0) { Display *dsp; @@ -176,7 +199,7 @@ gdm_server_reinit (GdmDisplay *disp) if (dsp == NULL) { /* HACK, see note above */ - sleep (1); + gdm_sleep_no_signal (1); _exit (0); } else { /* Wait for an xioerror */ @@ -540,7 +563,7 @@ gdm_server_start (GdmDisplay *disp, gboolean treat_as_flexi, * just wait a few seconds and hope things just work, * fortunately there is no such case yet and probably * never will, but just for code anality's sake */ - sleep (5); + gdm_sleep_no_signal (5); /* In case we got a SIGCHLD */ check_child_status (); } else if (d->server_uid != 0) { @@ -563,7 +586,7 @@ gdm_server_start (GdmDisplay *disp, gboolean treat_as_flexi, i++) { d->dsp = XOpenDisplay (d->name); if (d->dsp == NULL) - sleep (1); + gdm_sleep_no_signal (1); else d->servstat = SERVER_RUNNING; @@ -577,14 +600,13 @@ gdm_server_start (GdmDisplay *disp, gboolean treat_as_flexi, d->servstat = SERVER_TIMEOUT; } } else { - fd_set rfds; gdm_debug ("gdm_server_start: Before mainloop waiting for server"); - FD_ZERO (&rfds); - FD_SET (server_signal_pipe[0], &rfds); - do { + fd_set rfds; + FD_ZERO (&rfds); + FD_SET (server_signal_pipe[0], &rfds); select (server_signal_pipe[0]+1, &rfds, NULL, NULL, NULL); /* In case we got a SIGCHLD */ check_child_status (); diff --git a/daemon/slave.c b/daemon/slave.c index 0c3da0bb..89440fbf 100644 --- a/daemon/slave.c +++ b/daemon/slave.c @@ -75,8 +75,6 @@ static gboolean do_configurator = FALSE; /* if this is true, login as root * and start the configurator */ static gboolean do_restart_greeter = FALSE; /* if this is true, whack the greeter and try again */ -static gboolean restart_greeter_now = FALSE; /* restart_greeter_when the - SIGCHLD hits */ static int check_notifies_immediately = 0; /* check notifies as they come */ static gboolean gdm_wait_for_ack = TRUE; /* wait for ack on all messages to * the daemon */ @@ -87,6 +85,8 @@ static gboolean interrupted = FALSE; static gchar *ParsedAutomaticLogin = NULL; static gchar *ParsedTimedLogin = NULL; +static int in_usr2_signal = 0; + int greeter_fd_out = -1; int greeter_fd_in = -1; @@ -247,12 +247,15 @@ gdm_slave_start (GdmDisplay *display) { time_t first_time; int death_count; - static sigset_t mask; + sigset_t mask; struct sigaction alrm, term, child, usr2; if (!display) return; + signal (SIGPIPE, SIG_IGN); + signal (SIGUSR1, SIG_IGN); + gdm_debug ("gdm_slave_start: Starting slave process for %s", display->name); if (display->type == TYPE_XDMCP && GdmPingInterval > 0) { @@ -302,16 +305,16 @@ gdm_slave_start (GdmDisplay *display) "gdm_slave_start", g_strerror (errno)); /* The signals we wish to listen to */ - sigfillset (&mask); - sigdelset (&mask, SIGINT); - sigdelset (&mask, SIGTERM); - sigdelset (&mask, SIGCHLD); - sigdelset (&mask, SIGUSR2); + sigemptyset (&mask); + sigaddset (&mask, SIGINT); + sigaddset (&mask, SIGTERM); + sigaddset (&mask, SIGCHLD); + sigaddset (&mask, SIGUSR2); if (display->type == TYPE_XDMCP && GdmPingInterval > 0) { - sigdelset (&mask, SIGALRM); + sigaddset (&mask, SIGALRM); } - sigprocmask (SIG_SETMASK, &mask, NULL); + sigprocmask (SIG_UNBLOCK, &mask, NULL); first_time = time (NULL); death_count = 0; @@ -486,7 +489,7 @@ gdm_slave_run (GdmDisplay *display) if (d->sleep_before_run > 0) { gdm_debug ("gdm_slave_run: Sleeping %d seconds before server start", d->sleep_before_run); - sleep (d->sleep_before_run); + gdm_sleep_no_signal (d->sleep_before_run); d->sleep_before_run = 0; check_notifies_now (); @@ -569,7 +572,7 @@ gdm_slave_run (GdmDisplay *display) if (d->dsp == NULL) { gdm_debug ("gdm_slave_run: Sleeping %d on a retry", 1+openretries*2); - sleep (1+openretries*2); + gdm_sleep_no_signal (1+openretries*2); openretries++; } } @@ -587,7 +590,7 @@ gdm_slave_run (GdmDisplay *display) /* Just a race avoiding sleep, probably not necessary though, * but doesn't hurt anything */ if ( ! d->handled) - sleep (1); + gdm_sleep_no_signal (1); if (SERVER_IS_LOCAL (d)) { gdm_slave_send (GDM_SOP_START_NEXT_LOCAL, FALSE); @@ -739,6 +742,8 @@ focus_first_x_window (const char *class_res_name) } /* parent */ if (pid > 0) { + /* wait a second for the child to init self */ + gdm_sleep_no_signal (1); return; } @@ -809,6 +814,8 @@ focus_first_x_window (const char *class_res_name) } } +static void restart_the_greeter (void); + static void run_config (GdmDisplay *display, struct passwd *pwent) { @@ -922,11 +929,17 @@ run_config (GdmDisplay *display, struct passwd *pwent) /* XXX: is this a race if we don't push a sigchld block? * but then we don't get a signal for restarting the greeter */ /* wait for the config proggie to die */ - if (d->sesspid > 0) - /* must use the pid var here since sesspid might get - * zeroed between the check and here by sigchld - * handler */ - ve_waitpid_no_signal (pid, 0, 0); + while (d->sesspid > 0) { + /* FIXME: evil, but without the waitpid setup from devel + we can't do this safely otherwise */ + sleep (5); + + if (do_restart_greeter) { + do_restart_greeter = FALSE; + interrupted = FALSE; + restart_the_greeter (); + } + } display->sesspid = 0; configurator = FALSE; } @@ -1104,11 +1117,9 @@ gdm_slave_wait_for_login (void) check_notifies_now (); check_notifies_immediately++; - restart_greeter_now = TRUE; run_config (d, pwent); - restart_greeter_now = FALSE; check_notifies_immediately--; gdm_verify_cleanup (d); @@ -1696,7 +1707,29 @@ gdm_slave_send (const char *str, gboolean wait_for_ack) ! gdm_got_ack && i < 10; i++) { - sleep (1); + if (in_usr2_signal > 0) { + fd_set rfds; + struct timeval tv; + + FD_ZERO (&rfds); + FD_SET (d->slave_notify_fd, &rfds); + + /* Wait up to 1 second. */ + tv.tv_sec = 1; + tv.tv_usec = 0; + + if (select (d->slave_notify_fd+1, &rfds, NULL, NULL, &tv) > 0) { + gdm_slave_usr2_handler (SIGUSR2); + } + } else { + struct timeval tv; + /* Wait 1 second. */ + tv.tv_sec = 1; + tv.tv_usec = 0; + select (0, NULL, NULL, NULL, &tv); + /* don't want to use sleep since we're using alarm + for pinging */ + } } if (wait_for_ack && @@ -2189,6 +2222,11 @@ session_child_run (struct passwd *pwent, gdm_unset_signals (); + if (setsid() < 0) + /* should never happen */ + gdm_error (_("%s: setsid() failed: %s!"), + "session_child_run", strerror(errno)); + gnome_setenv ("XAUTHORITY", d->authfile, TRUE); disp = XOpenDisplay (d->name); @@ -2276,11 +2314,6 @@ session_child_run (struct passwd *pwent, gdm_clearenv (); - if (setsid() < 0) - /* should never happen */ - gdm_error (_("%s: setsid() failed: %s!"), - "session_child_run", strerror(errno)); - /* Prepare user session */ gnome_setenv ("XAUTHORITY", d->userauth, TRUE); gnome_setenv ("DISPLAY", d->name, TRUE); @@ -2315,6 +2348,8 @@ session_child_run (struct passwd *pwent, umask (022); + chdir (home_dir); + /* setup the verify env vars */ if ( ! gdm_verify_setup_env (d)) gdm_child_exit (DISPLAY_REMANAGE, @@ -2809,6 +2844,13 @@ gdm_slave_session_start (void) break; } + /* We must be root for this, and we are, but just to make sure */ + seteuid (0); + setegid (GdmGroupId); + /* Reset all the process limits, pam may have set some up for our process and that + is quite evil. But pam is generally evil, so this is to be expected. */ + gdm_reset_limits (); + g_free (session); g_free (save_session); g_free (language); @@ -3034,15 +3076,9 @@ gdm_slave_child_handler (int sig) whack_greeter_fds (); gdm_slave_send_num (GDM_SOP_GREETPID, 0); - if (restart_greeter_now) { - do_restart_greeter = FALSE; - restart_the_greeter (); - } else { - interrupted = TRUE; - do_restart_greeter = TRUE; - } - gdm_in_signal--; - return; + interrupted = TRUE; + do_restart_greeter = TRUE; + continue; } whack_greeter_fds (); @@ -3109,12 +3145,14 @@ gdm_slave_usr2_handler (int sig) int i; gdm_in_signal++; + in_usr2_signal++; gdm_debug ("gdm_slave_usr2_handler: %s got USR2 signal", d->name); count = read (d->slave_notify_fd, buf, sizeof (buf) -1); if (count <= 0) { gdm_in_signal--; + in_usr2_signal--; return; } @@ -3123,6 +3161,7 @@ gdm_slave_usr2_handler (int sig) vec = g_strsplit (buf, "\n", -1); if (vec == NULL) { gdm_in_signal--; + in_usr2_signal--; return; } @@ -3166,6 +3205,7 @@ gdm_slave_usr2_handler (int sig) g_strfreev (vec); gdm_in_signal--; + in_usr2_signal--; } /* Minor X faults */ @@ -3308,6 +3348,8 @@ gdm_slave_quick_exit (gint status) setegid (0); if (d != NULL) { + gdm_verify_cleanup (d); + /* Well now we're just going to kill * everything including the X server, * so no need doing XCloseDisplay which @@ -3334,7 +3376,6 @@ gdm_slave_quick_exit (gint status) d->sesspid = 0; gdm_server_stop (d); - gdm_verify_cleanup (d); if (d->servpid > 1) kill (d->servpid, SIGTERM); @@ -3742,8 +3783,8 @@ gdm_slave_handle_notify (const char *msg) GdmGreeter = g_strdup (&msg[strlen (GDM_NOTIFY_GREETER) + 1]); if (d->console) { - if (restart_greeter_now) { - restart_the_greeter (); + if (configurator) { + do_restart_greeter = TRUE; } else if (d->type == TYPE_LOCAL) { /* FIXME: can't handle flexi servers like this * without going all cranky */ @@ -3760,8 +3801,8 @@ gdm_slave_handle_notify (const char *msg) GdmRemoteGreeter = g_strdup (&msg[strlen (GDM_NOTIFY_REMOTEGREETER) + 1]); if ( ! d->console) { - if (restart_greeter_now) { - restart_the_greeter (); + if (configurator) { + do_restart_greeter = TRUE; } else if (d->type == TYPE_XDMCP) { /* FIXME: can't handle flexi servers like this * without going all cranky */ diff --git a/daemon/verify-crypt.c b/daemon/verify-crypt.c index 7cbcdf02..68d40286 100644 --- a/daemon/verify-crypt.c +++ b/daemon/verify-crypt.c @@ -110,7 +110,7 @@ gdm_verify_user (GdmDisplay *d, gdm_slave_greeter_ctl_no_ret (GDM_STOPTIMER, ""); if (pwent == NULL) { - sleep (GdmRetryDelay); + gdm_sleep_no_signal (GdmRetryDelay); gdm_error (_("Couldn't authenticate user")); /* FIXME: Hmm, how are we sure that the login is username * and password. That is the most common case but not @@ -131,7 +131,7 @@ gdm_verify_user (GdmDisplay *d, /* Check whether password is valid */ if (ppasswd == NULL || (ppasswd[0] != '\0' && strcmp (crypt (passwd, ppasswd), ppasswd) != 0)) { - sleep (GdmRetryDelay); + gdm_sleep_no_signal (GdmRetryDelay); /* FIXME: Hmm, how are we sure that the login is username * and password. That is the most common case but not * necessarily true, this message needs to be changed diff --git a/daemon/verify-pam.c b/daemon/verify-pam.c index a48f4b44..556916fe 100644 --- a/daemon/verify-pam.c +++ b/daemon/verify-pam.c @@ -48,6 +48,9 @@ static pam_handle_t *pamh = NULL; static GdmDisplay *cur_gdm_disp = NULL; +static gboolean opened_session = FALSE; +static gboolean did_setcred = FALSE; + /* Internal PAM conversation function. Interfaces between the PAM * authentication system and the actual greeter program */ @@ -88,7 +91,11 @@ gdm_verify_pam_conv (int num_msg, const struct pam_message **msg, case PAM_PROMPT_ECHO_OFF: /* PAM requested textual input with echo off */ - s = gdm_slave_greeter_ctl (GDM_NOECHO, msg[replies]->msg); + if (strcmp (msg[replies]->msg, "Password: ") == 0) + /* hack to make sure we translate "Password: " */ + s = gdm_slave_greeter_ctl (GDM_NOECHO, _("Password: ")); + else + s = gdm_slave_greeter_ctl (GDM_NOECHO, msg[replies]->msg); if (gdm_slave_greeter_check_interruption ()) { g_free (s); free (reply); @@ -245,6 +252,8 @@ create_pamh (GdmDisplay *d, pam_end (pamh, PAM_SUCCESS); } pamh = NULL; + opened_session = FALSE; + did_setcred = FALSE; /* Initialize a PAM session for the user */ if ((*pamerr = pam_start (service, login, conv, &pamh)) != PAM_SUCCESS) { @@ -260,20 +269,16 @@ create_pamh (GdmDisplay *d, return FALSE; } - /* gdm is requesting the login */ - if ((*pamerr = pam_set_item (pamh, PAM_RUSER, GdmUser)) != PAM_SUCCESS) { - if (gdm_slave_should_complain ()) - gdm_error (_("Can't set PAM_RUSER=%s"), GdmUser); - return FALSE; - } - - /* From the host of the display */ - if ((*pamerr = pam_set_item (pamh, PAM_RHOST, - d->console ? "localhost" : d->hostname)) != PAM_SUCCESS) { - if (gdm_slave_should_complain ()) - gdm_error (_("Can't set PAM_RHOST=%s"), - d->console ? "localhost" : d->hostname); - return FALSE; + if ( ! d->console) { + /* Only set RHOST if host is remote */ + /* From the host of the display */ + if ((*pamerr = pam_set_item (pamh, PAM_RHOST, + d->hostname)) != PAM_SUCCESS) { + if (gdm_slave_should_complain ()) + gdm_error (_("Can't set PAM_RHOST=%s"), + d->hostname); + return FALSE; + } } return TRUE; @@ -353,7 +358,7 @@ gdm_verify_user (GdmDisplay *d, /* Start authentication session */ if ((pamerr = pam_authenticate (pamh, 0)) != PAM_SUCCESS) { #ifndef PAM_FAIL_DELAY - sleep (GdmRetryDelay); + gdm_sleep_no_signal (GdmRetryDelay); #endif /* PAM_FAIL_DELAY */ if (started_timer) gdm_slave_greeter_ctl_no_ret (GDM_STOPTIMER, ""); @@ -428,8 +433,10 @@ gdm_verify_user (GdmDisplay *d, } /* Set credentials */ + did_setcred = TRUE; pamerr = pam_setcred (pamh, PAM_ESTABLISH_CRED); if (pamerr != PAM_SUCCESS) { + did_setcred = FALSE; if (gdm_slave_should_complain ()) gdm_error (_("Couldn't set credentials for %s"), login); goto pamerr; @@ -438,8 +445,12 @@ gdm_verify_user (GdmDisplay *d, credentials_set = TRUE; /* Register the session */ + opened_session = TRUE; pamerr = pam_open_session (pamh, 0); if (pamerr != PAM_SUCCESS) { + opened_session = FALSE; + /* we handle this above */ + did_setcred = FALSE; if (gdm_slave_should_complain ()) gdm_error (_("Couldn't open session for %s"), login); goto pamerr; @@ -476,6 +487,9 @@ gdm_verify_user (GdmDisplay *d, } } + did_setcred = FALSE; + opened_session = FALSE; + if (pamh != NULL) { /* Throw away the credentials */ if (credentials_set) @@ -589,16 +603,21 @@ gdm_verify_setup_user (GdmDisplay *d, const gchar *login, const gchar *display) } /* Set credentials */ + did_setcred = TRUE; pamerr = pam_setcred (pamh, PAM_ESTABLISH_CRED); if (pamerr != PAM_SUCCESS) { + did_setcred = FALSE; if (gdm_slave_should_complain ()) gdm_error (_("Couldn't set credentials for %s"), login); goto setup_pamerr; } /* Register the session */ + opened_session = TRUE; pamerr = pam_open_session (pamh, 0); if (pamerr != PAM_SUCCESS) { + opened_session = FALSE; + did_setcred = FALSE; /* Throw away the credentials */ pam_setcred (pamh, PAM_DELETE_CRED); @@ -619,6 +638,9 @@ gdm_verify_setup_user (GdmDisplay *d, const gchar *login, const gchar *display) return TRUE; setup_pamerr: + + did_setcred = FALSE; + opened_session = FALSE; if (pamh != NULL) pam_end (pamh, pamerr); @@ -651,22 +673,46 @@ gdm_verify_cleanup (GdmDisplay *d) if (pamh != NULL) { gint pamerr; + pam_handle_t *tmp_pamh; + gboolean old_opened_session; + gboolean old_did_setcred; + + gdm_debug ("Running gdm_verify_cleanup and pamh != NULL"); + + gdm_sigterm_block_push (); + gdm_sigchld_block_push (); + tmp_pamh = pamh; + pamh = NULL; + old_opened_session = opened_session; + opened_session = FALSE; + old_did_setcred = did_setcred; + did_setcred = FALSE; + gdm_sigchld_block_pop (); + gdm_sigterm_block_pop (); + + pamerr = PAM_SUCCESS; /* Close the users session */ - pamerr = pam_close_session (pamh, 0); + if (old_opened_session) { + gdm_debug ("Running pam_close_session"); + pamerr = pam_close_session (tmp_pamh, 0); + } /* Throw away the credentials */ - pamerr = pam_setcred (pamh, PAM_DELETE_CRED); + if (old_did_setcred) { + gdm_debug ("Running pam_setcred with PAM_DELETE_CRED"); + pamerr = pam_setcred (tmp_pamh, PAM_DELETE_CRED); + } - if (pamh != NULL) - pam_end (pamh, pamerr); - pamh = NULL; + pam_end (tmp_pamh, pamerr); /* Workaround to avoid gdm messages being logged as PAM_pwdb */ closelog (); openlog ("gdm", LOG_PID, LOG_DAEMON); } + gdm_reset_limits (); + /* Clear the group setup */ setgid (0); /* this will get rid of any suplementary groups etc... */ diff --git a/daemon/verify-shadow.c b/daemon/verify-shadow.c index 643010cb..53800c50 100644 --- a/daemon/verify-shadow.c +++ b/daemon/verify-shadow.c @@ -119,7 +119,7 @@ gdm_verify_user (GdmDisplay *d, const char *username, const gchar *display, gboo gdm_slave_greeter_ctl_no_ret (GDM_STOPTIMER, ""); if (pwent == NULL) { - sleep (GdmRetryDelay); + gdm_sleep_no_signal (GdmRetryDelay); gdm_error (_("Couldn't authenticate user")); /* FIXME: Hmm, how are we sure that the login is username * and password. That is the most common case but not @@ -140,7 +140,7 @@ gdm_verify_user (GdmDisplay *d, const char *username, const gchar *display, gboo /* Check whether password is valid */ if (ppasswd == NULL || (ppasswd[0] != '\0' && strcmp (crypt (passwd, ppasswd), ppasswd) != 0)) { - sleep (GdmRetryDelay); + gdm_sleep_no_signal (GdmRetryDelay); /* FIXME: Hmm, how are we sure that the login is username * and password. That is the most common case but not * necessarily true, this message needs to be changed diff --git a/gui/gdmXnestchooser.c b/gui/gdmXnestchooser.c index c77938ba..48f05faf 100644 --- a/gui/gdmXnestchooser.c +++ b/gui/gdmXnestchooser.c @@ -64,6 +64,8 @@ get_free_display (void) for (i = 20; i < 3000; i ++) { struct stat s; char buf[256]; + FILE *fp; + sock = socket (AF_INET, SOCK_STREAM, 0); serv_addr.sin_port = htons (6000 + i); @@ -78,6 +80,23 @@ get_free_display (void) close (sock); + /* if lock file exists and the process exists */ + g_snprintf (buf, sizeof (buf), "/tmp/.X%d-lock", i); + fp = fopen (buf, "r"); + if (fp != NULL) { + char buf2[100]; + if (fgets (buf2, sizeof (buf2), fp) != NULL) { + gulong pid; + if (sscanf (buf2, "%lu", &pid) == 1 && + kill (pid, 0) == 0) { + fclose (fp); + continue; + } + + } + fclose (fp); + } + g_snprintf (buf, sizeof (buf), "/tmp/.X11-unix/X%d", i); if (stat (buf, &s) == 0 && s.st_uid != getuid ()) { diff --git a/gui/gdmflexiserver.c b/gui/gdmflexiserver.c index 99c2de8b..fc8fd645 100644 --- a/gui/gdmflexiserver.c +++ b/gui/gdmflexiserver.c @@ -251,6 +251,7 @@ main (int argc, char *argv[]) GTK_BUTTONS_OK, _("Cannot communicate with gdm, perhaps " "you have an old version running.")); + gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); gtk_widget_show_all (dialog); gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); @@ -270,6 +271,7 @@ main (int argc, char *argv[]) "authentication needed for this " "operation. Perhaps your .Xauthority " "file is not set up correctly.")); + gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); gtk_widget_show_all (dialog); gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); @@ -295,6 +297,7 @@ main (int argc, char *argv[]) _("You do not seem to be logged in on the " "console. Starting a new login only " "works correctly on the console.")); + gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); gtk_widget_show_all (dialog); gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); @@ -338,6 +341,7 @@ main (int argc, char *argv[]) GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, "%s", message); + gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); gtk_widget_show_all (dialog); gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); diff --git a/gui/gdmlogin.c b/gui/gdmlogin.c index c8a2c534..6ae9188e 100644 --- a/gui/gdmlogin.c +++ b/gui/gdmlogin.c @@ -686,6 +686,7 @@ gdm_login_message (const gchar *msg) GTK_BUTTONS_CLOSE, "%s", msg); + gtk_dialog_set_has_separator (GTK_DIALOG (req), FALSE); g_signal_connect (G_OBJECT (req), "destroy", G_CALLBACK (gtk_widget_destroyed), &req); @@ -716,6 +717,7 @@ gdm_login_query (const gchar *msg) GTK_BUTTONS_YES_NO, "%s", msg); + gtk_dialog_set_has_separator (GTK_DIALOG (req), FALSE); gtk_label_set_use_markup (GTK_LABEL (GTK_MESSAGE_DIALOG (req)->label), TRUE); @@ -755,6 +757,7 @@ gdm_run_command (const char *command) _("Could not fork a new process!\n\n" "You likely won't be able to log " "in either.")); + gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); gtk_widget_show_all (dialog); gdm_wm_center_window (GTK_WINDOW (dialog)); @@ -2211,6 +2214,7 @@ gdm_login_ctrl_handler (GIOChannel *source, GIOCondition cond, gint fd) GTK_BUTTONS_OK, "%s", tmp); + gtk_dialog_set_has_separator (GTK_DIALOG (dlg), FALSE); g_free (tmp); gdm_wm_center_window (GTK_WINDOW (dlg)); @@ -2326,14 +2330,15 @@ gdm_login_ctrl_handler (GIOChannel *source, GIOCondition cond, gint fd) /* we should be now fine for focusing new windows */ gdm_wm_focus_new_windows (TRUE); - /* translators: This is a nice and evil eggie text, translate - * to your favourite currency */ dlg = gtk_message_dialog_new (NULL /* parent */, GTK_DIALOG_MODAL /* flags */, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, + /* translators: This is a nice and evil eggie text, translate + * to your favourite currency */ _("Please insert 25 cents " "to log in.")); + gtk_dialog_set_has_separator (GTK_DIALOG (dlg), FALSE); gdm_wm_center_window (GTK_WINDOW (dlg)); gdm_wm_no_login_focus_push (); @@ -2359,6 +2364,7 @@ gdm_login_ctrl_handler (GIOChannel *source, GIOCondition cond, gint fd) GTK_BUTTONS_OK, "%s", oldtext); + gtk_dialog_set_has_separator (GTK_DIALOG (dlg), FALSE); gtk_window_set_modal (GTK_WINDOW (dlg), TRUE); gdm_wm_center_window (GTK_WINDOW (dlg)); @@ -4086,6 +4092,7 @@ main (int argc, char *argv[]) "You have probably just upgraded gdm.\n" "Please restart the gdm daemon or reboot the computer."), VERSION); + gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); gtk_widget_show_all (dialog); gdm_wm_center_window (GTK_WINDOW (dialog)); @@ -4115,6 +4122,7 @@ main (int argc, char *argv[]) "You have probably just upgraded gdm.\n" "Please restart the gdm daemon or reboot the computer."), VERSION); + gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); gtk_dialog_add_buttons (GTK_DIALOG (dialog), _("Reboot"), RESPONSE_REBOOT, @@ -4157,6 +4165,7 @@ main (int argc, char *argv[]) "You have probably just upgraded gdm.\n" "Please restart the gdm daemon or reboot the computer."), VERSION, gdm_version); + gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); gtk_dialog_add_buttons (GTK_DIALOG (dialog), _("Restart"), RESPONSE_RESTART, @@ -4308,6 +4317,7 @@ main (int argc, char *argv[]) _("Your session directory is missing or empty!\n\n" "There are two available sessions you can use, but\n" "you should log in and correct the gdm configuration.")); + gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); gtk_widget_show_all (dialog); gdm_wm_center_window (GTK_WINDOW (dialog)); @@ -4331,6 +4341,7 @@ main (int argc, char *argv[]) _("The configuration file contains an invalid command\n" "line for the login dialog, and thus I ran the\n" "default command. Please fix your configuration.")); + gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); gtk_widget_show_all (dialog); gdm_wm_center_window (GTK_WINDOW (dialog)); @@ -4356,6 +4367,7 @@ main (int argc, char *argv[]) "defaults to run this session. You should log in\n" "and create a configuration file with the GDM\n" "configuration program.")); + gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); gtk_widget_show_all (dialog); gdm_wm_center_window (GTK_WINDOW (dialog)); diff --git a/gui/gdmphotosetup.c b/gui/gdmphotosetup.c index d18ced94..f3d37697 100644 --- a/gui/gdmphotosetup.c +++ b/gui/gdmphotosetup.c @@ -63,7 +63,8 @@ gdm_check (void) GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, "foo"); - gtk_label_set_markup + gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); + gtk_label_set_markup (GTK_LABEL (GTK_MESSAGE_DIALOG (dialog)->label), _("<b>GDM (The GNOME Display Manager) " "is not running.</b>\n\n" @@ -131,6 +132,7 @@ main (int argc, char *argv[]) "system administrator to enable " "it\nin the GDM configurator " "program.")); + gtk_dialog_set_has_separator (GTK_DIALOG (d), FALSE); gtk_dialog_run (GTK_DIALOG (d)); gtk_widget_destroy (d); } @@ -183,6 +185,7 @@ main (int argc, char *argv[]) GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, _("No picture selected.")); + gtk_dialog_set_has_separator (GTK_DIALOG (d), FALSE); gtk_dialog_run (GTK_DIALOG (d)); gtk_widget_destroy (d); } else if (s.st_size > max_size) { @@ -197,6 +200,7 @@ main (int argc, char *argv[]) "then %d bytes to\n" "show in the face browser"), max_size); + gtk_dialog_set_has_separator (GTK_DIALOG (d), FALSE); gtk_dialog_run (GTK_DIALOG (d)); gtk_widget_destroy (d); } else { @@ -221,6 +225,7 @@ main (int argc, char *argv[]) "reading\nError: %s"), pixmap, g_strerror (errno)); + gtk_dialog_set_has_separator (GTK_DIALOG (d), FALSE); gtk_dialog_run (GTK_DIALOG (d)); gtk_widget_destroy (d); g_free (cfg_file); @@ -239,6 +244,7 @@ main (int argc, char *argv[]) "writing\nError: %s"), photofile, g_strerror (errno)); + gtk_dialog_set_has_separator (GTK_DIALOG (d), FALSE); gtk_dialog_run (GTK_DIALOG (d)); gtk_widget_destroy (d); g_free (cfg_file); diff --git a/gui/gdmsetup.c b/gui/gdmsetup.c index 00d1c63d..ba69cf6d 100644 --- a/gui/gdmsetup.c +++ b/gui/gdmsetup.c @@ -147,6 +147,7 @@ check_update_error: "login screens. Not all " "updates may have taken " "effect.")); + gtk_dialog_set_has_separator (GTK_DIALOG (dlg), FALSE); gtk_dialog_run (GTK_DIALOG (dlg)); gtk_widget_destroy (dlg); shown_error = TRUE; @@ -414,6 +415,7 @@ setup_user_combo (const char *name, const char *key) GList *users = NULL; struct passwd *pwent; char *str; + int cnt; str = ve_config_get_string (ve_config_get (GDM_CONFIG_FILE), key); @@ -426,12 +428,20 @@ setup_user_combo (const char *name, const char *key) setpwent (); pwent = getpwent(); + cnt = 0; while (pwent != NULL) { if (pwent->pw_uid >= GdmMinimalUID && strcmp (ve_sure_string (str), pwent->pw_name) != 0) { + cnt ++; users = g_list_append (users, g_strdup (pwent->pw_name)); + /* FIXME: fix properly, see bug #111830 */ + if (cnt >= 50) { + users = g_list_append (users, + g_strdup ("...")); + break; + } } pwent = getpwent(); @@ -1486,6 +1496,7 @@ install_ok (GtkWidget *button, gpointer data) GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("No file selected")); + gtk_dialog_set_has_separator (GTK_DIALOG (dlg), FALSE); gtk_dialog_run (GTK_DIALOG (dlg)); gtk_widget_destroy (dlg); g_free (cwd); @@ -1514,6 +1525,7 @@ install_ok (GtkWidget *button, gpointer data) _("Not a theme archive\n" "Details: %s"), error); + gtk_dialog_set_has_separator (GTK_DIALOG (dlg), FALSE); gtk_dialog_run (GTK_DIALOG (dlg)); gtk_widget_destroy (dlg); g_free (filename); @@ -1536,6 +1548,7 @@ install_ok (GtkWidget *button, gpointer data) _("Theme directory '%s' seems to be already " "installed, install again anyway?"), fname); + gtk_dialog_set_has_separator (GTK_DIALOG (dlg), FALSE); g_free (fname); if (gtk_dialog_run (GTK_DIALOG (dlg)) != GTK_RESPONSE_YES) { gtk_widget_destroy (dlg); @@ -1580,6 +1593,7 @@ install_ok (GtkWidget *button, gpointer data) GTK_BUTTONS_OK, _("Some error occured when " "installing the theme")); + gtk_dialog_set_has_separator (GTK_DIALOG (dlg), FALSE); gtk_dialog_run (GTK_DIALOG (dlg)); gtk_widget_destroy (dlg); } @@ -1771,6 +1785,7 @@ dialog_response (GtkWidget *dlg, int response, gpointer data) "are listed here. You may want to edit %s " "if you cannot find what you are looking for."), GDM_CONFIG_FILE); + gtk_dialog_set_has_separator (GTK_DIALOG (dlg), FALSE); g_signal_connect (G_OBJECT (dlg), "destroy", G_CALLBACK (gtk_widget_destroyed), &dlg); @@ -2068,6 +2083,7 @@ main (int argc, char *argv[]) GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("You must be the superuser (root) to configure GDM.\n")); + gtk_dialog_set_has_separator (GTK_DIALOG (fatal_error), FALSE); if (RUNNING_UNDER_GDM) setup_cursor (GDK_LEFT_PTR); gtk_dialog_run (GTK_DIALOG (fatal_error)); diff --git a/gui/greeter/greeter.c b/gui/greeter/greeter.c index 56515886..20d8e82f 100644 --- a/gui/greeter/greeter.c +++ b/gui/greeter/greeter.c @@ -60,6 +60,7 @@ static gboolean used_defaults = FALSE; gint greeter_current_delay = 0; extern gboolean session_dir_whacked_out; +extern gboolean require_quarter; static void @@ -141,8 +142,8 @@ greeter_parse_config (void) GdmXineramaScreen = 0; } -static void -setup_cursor (GdkCursorType type) +void +greeter_setup_cursor (GdkCursorType type) { GdkCursor *cursor = gdk_cursor_new (type); gdk_window_set_cursor (gdk_get_default_root_window (), cursor); @@ -258,6 +259,7 @@ greeter_ctrl_handler (GIOChannel *source, GTK_BUTTONS_OK, "%s", tmp); + gtk_dialog_set_has_separator (GTK_DIALOG (dlg), FALSE); g_free (tmp); gdm_wm_center_window (GTK_WINDOW (dlg)); @@ -342,6 +344,28 @@ greeter_ctrl_handler (GIOChannel *source, g_io_channel_read_chars (source, buf, PIPE_SIZE-1, &len, NULL); /* Empty */ greeter_item_timed_stop (); + + if (require_quarter) { + /* we should be now fine for focusing new windows */ + gdm_wm_focus_new_windows (TRUE); + + dlg = gtk_message_dialog_new (NULL /* parent */, + GTK_DIALOG_MODAL /* flags */, + GTK_MESSAGE_INFO, + GTK_BUTTONS_OK, + /* translators: This is a nice and evil eggie text, translate + * to your favourite currency */ + _("Please insert 25 cents " + "to log in.")); + gtk_dialog_set_has_separator (GTK_DIALOG (dlg), FALSE); + gdm_wm_center_window (GTK_WINDOW (dlg)); + + gdm_wm_no_login_focus_push (); + gtk_dialog_run (GTK_DIALOG (dlg)); + gtk_widget_destroy (dlg); + gdm_wm_no_login_focus_pop (); + } + greeter_item_pam_leftover_messages (); gdk_flush (); @@ -475,7 +499,7 @@ greeter_ctrl_handler (GIOChannel *source, g_io_channel_read_chars (source, buf, PIPE_SIZE-1, &len, NULL); /* Empty */ /* Set busy cursor */ - setup_cursor (GDK_WATCH); + greeter_setup_cursor (GDK_WATCH); gdm_wm_save_wm_order (); @@ -558,11 +582,12 @@ verify_gdm_version (void) "You have probably just upgraded gdm.\n" "Please restart the gdm daemon or reboot the computer."), VERSION); + gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); gtk_widget_show_all (dialog); gdm_wm_center_window (GTK_WINDOW (dialog)); - setup_cursor (GDK_LEFT_PTR); + greeter_setup_cursor (GDK_LEFT_PTR); gtk_dialog_run (GTK_DIALOG (dialog)); @@ -587,6 +612,7 @@ verify_gdm_version (void) "You have probably just upgraded gdm.\n" "Please restart the gdm daemon or reboot the computer."), VERSION); + gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); gtk_dialog_add_buttons (GTK_DIALOG (dialog), _("Reboot"), RESPONSE_REBOOT, @@ -597,7 +623,7 @@ verify_gdm_version (void) gtk_widget_show_all (dialog); gdm_wm_center_window (GTK_WINDOW (dialog)); - setup_cursor (GDK_LEFT_PTR); + greeter_setup_cursor (GDK_LEFT_PTR); switch (gtk_dialog_run (GTK_DIALOG (dialog))) { @@ -630,6 +656,7 @@ verify_gdm_version (void) "You have probably just upgraded gdm.\n" "Please restart the gdm daemon or reboot the computer."), VERSION, gdm_version); + gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); gtk_dialog_add_buttons (GTK_DIALOG (dialog), _("Restart"), RESPONSE_RESTART, @@ -645,7 +672,7 @@ verify_gdm_version (void) gtk_dialog_set_default_response (GTK_DIALOG (dialog), RESPONSE_RESTART); - setup_cursor (GDK_LEFT_PTR); + greeter_setup_cursor (GDK_LEFT_PTR); switch (gtk_dialog_run (GTK_DIALOG (dialog))) { @@ -678,6 +705,7 @@ greeter_message (const gchar *msg) GTK_BUTTONS_CLOSE, "%s", msg); + gtk_dialog_set_has_separator (GTK_DIALOG (req), FALSE); g_signal_connect (G_OBJECT (req), "destroy", G_CALLBACK (gtk_widget_destroyed), &req); @@ -708,6 +736,7 @@ greeter_query (const gchar *msg) GTK_BUTTONS_YES_NO, "%s", msg); + gtk_dialog_set_has_separator (GTK_DIALOG (req), FALSE); gtk_label_set_use_markup (GTK_LABEL (GTK_MESSAGE_DIALOG (req)->label), TRUE); @@ -866,7 +895,7 @@ greeter_reread_config (int sig, gpointer data) "theme '%s' theme_dir '%s'", theme, theme_dir); /* Set busy cursor */ - setup_cursor (GDK_WATCH); + greeter_setup_cursor (GDK_WATCH); gdm_wm_save_wm_order (); @@ -1030,7 +1059,7 @@ main (int argc, char *argv[]) gtk_init (&argc, &argv); /* Should be a watch already, but anyway */ - setup_cursor (GDK_WATCH); + greeter_setup_cursor (GDK_WATCH); if ( ! ve_string_empty (GdmGtkRC)) gtk_rc_parse (GdmGtkRC); @@ -1141,11 +1170,12 @@ main (int argc, char *argv[]) _("There was an error loading the " "theme %s"), g_getenv ("GDM_THEME")); + gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); gtk_widget_show_all (dialog); gdm_wm_center_window (GTK_WINDOW (dialog)); - setup_cursor (GDK_LEFT_PTR); + greeter_setup_cursor (GDK_LEFT_PTR); gtk_dialog_run (GTK_DIALOG (dialog)); @@ -1180,11 +1210,12 @@ main (int argc, char *argv[]) "is corrupt. It does not contain " "definition for the username/password " "entry element.")); + gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); gtk_widget_show_all (dialog); gdm_wm_center_window (GTK_WINDOW (dialog)); - setup_cursor (GDK_LEFT_PTR); + greeter_setup_cursor (GDK_LEFT_PTR); gtk_dialog_run (GTK_DIALOG (dialog)); @@ -1214,11 +1245,12 @@ main (int argc, char *argv[]) "also could not have been loaded, " "I will attempt to start the " "standard greeter")); + gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); gtk_widget_show_all (dialog); gdm_wm_center_window (GTK_WINDOW (dialog)); - setup_cursor (GDK_LEFT_PTR); + greeter_setup_cursor (GDK_LEFT_PTR); gtk_dialog_run (GTK_DIALOG (dialog)); @@ -1234,11 +1266,12 @@ main (int argc, char *argv[]) "and you may have to login another " "way and fix the installation of " "gdm")); + gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); gtk_widget_show_all (dialog); gdm_wm_center_window (GTK_WINDOW (dialog)); - setup_cursor (GDK_LEFT_PTR); + greeter_setup_cursor (GDK_LEFT_PTR); gtk_dialog_run (GTK_DIALOG (dialog)); @@ -1279,10 +1312,11 @@ main (int argc, char *argv[]) _("Your session directory is missing or empty!\n\n" "There are two available sessions you can use, but\n" "you should log in and correct the gdm configuration.")); + gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); gtk_widget_show_all (dialog); gdm_wm_center_window (GTK_WINDOW (dialog)); - setup_cursor (GDK_LEFT_PTR); + greeter_setup_cursor (GDK_LEFT_PTR); gdm_wm_no_login_focus_push (); gtk_dialog_run (GTK_DIALOG (dialog)); @@ -1303,10 +1337,11 @@ main (int argc, char *argv[]) _("The configuration file contains an invalid command\n" "line for the login dialog, and thus I ran the\n" "default command. Please fix your configuration.")); + gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); gtk_widget_show_all (dialog); gdm_wm_center_window (GTK_WINDOW (dialog)); - setup_cursor (GDK_LEFT_PTR); + greeter_setup_cursor (GDK_LEFT_PTR); gdm_wm_no_login_focus_push (); gtk_dialog_run (GTK_DIALOG (dialog)); @@ -1329,10 +1364,11 @@ main (int argc, char *argv[]) "defaults to run this session. You should log in\n" "and create a configuration file with the GDM\n" "configuration program.")); + gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); gtk_widget_show_all (dialog); gdm_wm_center_window (GTK_WINDOW (dialog)); - setup_cursor (GDK_LEFT_PTR); + greeter_setup_cursor (GDK_LEFT_PTR); gdm_wm_no_login_focus_push (); gtk_dialog_run (GTK_DIALOG (dialog)); @@ -1342,7 +1378,7 @@ main (int argc, char *argv[]) gdm_wm_restore_wm_order (); - setup_cursor (GDK_LEFT_PTR); + greeter_setup_cursor (GDK_LEFT_PTR); gtk_main (); diff --git a/gui/greeter/greeter.h b/gui/greeter/greeter.h index aa6c3242..eb4cc2d7 100644 --- a/gui/greeter/greeter.h +++ b/gui/greeter/greeter.h @@ -11,4 +11,6 @@ void greeter_abort (const gchar *format, ...); gboolean greeter_query (const gchar *msg); void greeter_message (const gchar *msg); +void greeter_setup_cursor (GdkCursorType type); + #endif diff --git a/gui/greeter/greeter_action_language.c b/gui/greeter/greeter_action_language.c index 4ea55426..03edf556 100644 --- a/gui/greeter/greeter_action_language.c +++ b/gui/greeter/greeter_action_language.c @@ -202,6 +202,9 @@ greeter_action_language (GreeterItemInfo *info, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); + gtk_dialog_set_default_response (GTK_DIALOG (dialog), + GTK_RESPONSE_OK); + gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); g_object_add_weak_pointer (G_OBJECT (dialog), (gpointer *) &dialog); s = g_strdup_printf ("<span size=\"x-large\" weight=\"bold\">%s</span>", _("Select a language for your session to use:")); diff --git a/gui/greeter/greeter_item_pam.c b/gui/greeter/greeter_item_pam.c index a690108a..cdf092d5 100644 --- a/gui/greeter/greeter_item_pam.c +++ b/gui/greeter/greeter_item_pam.c @@ -5,6 +5,7 @@ #include <gdk/gdkkeysyms.h> #include "greeter_item_pam.h" #include "greeter_parser.h" +#include "greeter.h" #include "gdm.h" #include "gdmwm.h" #include "vicious.h" @@ -20,6 +21,8 @@ extern gboolean GdmSystemMenu; gchar *greeter_current_user = NULL; +gboolean require_quarter = FALSE; + void greeter_item_pam_set_user (const char *user) { @@ -27,11 +30,44 @@ greeter_item_pam_set_user (const char *user) greeter_current_user = g_strdup (user); } +static gboolean +evil (GtkEntry *entry, const char *user) +{ + /* do not translate */ + if (strcmp (user, "Gimme Random Cursor") == 0) { + greeter_setup_cursor (((rand () >> 3) % (GDK_LAST_CURSOR/2)) * 2); + gtk_entry_set_text (GTK_ENTRY (entry), ""); + return TRUE; + /* do not translate */ + } else if (strcmp (user, "Require Quater") == 0 || + strcmp (user, "Require Quarter") == 0) { + /* btw, note that I misspelled quarter before and + * thus this checks for Quater as well as Quarter to + * keep compatibility which is obviously important for + * something like this */ + require_quarter = TRUE; + gtk_entry_set_text (GTK_ENTRY (entry), ""); + return TRUE; + } + + return FALSE; +} + static void user_pw_activate (GtkEntry *entry, GreeterItemInfo *info) { char *tmp; + const char *str; GreeterItemInfo *error_info; + + str = gtk_entry_get_text (GTK_ENTRY (entry)); + if (entry_is_login && + /* evilness */ + evil (entry, str)) + { + gtk_entry_set_text (GTK_ENTRY (entry), ""); + return; + } gtk_widget_set_sensitive (GTK_WIDGET (entry), FALSE); diff --git a/gui/greeter/greeter_parser.c b/gui/greeter/greeter_parser.c index 517f0446..e5ac21f5 100644 --- a/gui/greeter/greeter_parser.c +++ b/gui/greeter/greeter_parser.c @@ -12,6 +12,7 @@ #include <vicious.h> +#include "gdmwm.h" #include "greeter_parser.h" #include "greeter_events.h" @@ -994,6 +995,7 @@ parse_label (xmlNodePtr node, { xmlNodePtr child; int i; + double size_reduction = 1.0; char *translated_text; gint translation_score = 1000; @@ -1079,6 +1081,24 @@ parse_label (xmlNodePtr node, if (info->fonts[GREETER_ITEM_STATE_NORMAL] == NULL) info->fonts[GREETER_ITEM_STATE_NORMAL] = pango_font_description_from_string ("Sans"); + if (gdm_wm_screen.width <= 800 && + gdm_wm_screen.width > 640) + size_reduction = PANGO_SCALE_SMALL; + else if (gdm_wm_screen.width <= 640) + size_reduction = PANGO_SCALE_X_SMALL; + + if (size_reduction < 0.99) + { + for (i = 0; i < GREETER_ITEM_STATE_MAX; i++) + { + if (info->fonts[i] != NULL) + { + int old_size = pango_font_description_get_size (info->fonts[i]); + pango_font_description_set_size (info->fonts[i], old_size * size_reduction); + } + } + } + info->orig_text = translated_text; return TRUE; diff --git a/gui/greeter/greeter_session.c b/gui/greeter/greeter_session.c index ff487204..f9efd36d 100644 --- a/gui/greeter/greeter_session.c +++ b/gui/greeter/greeter_session.c @@ -208,6 +208,7 @@ greeter_session_init (void) current_session = NULL; session_dialog = dialog = gtk_dialog_new (); + gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); tooltips = gtk_tooltips_new (); gtk_dialog_add_button (GTK_DIALOG (dialog), @@ -217,6 +218,9 @@ greeter_session_init (void) gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_OK); + + gtk_dialog_set_default_response (GTK_DIALOG (dialog), + GTK_RESPONSE_OK); if (GdmShowLastSession) { diff --git a/gui/greeter/greeter_system.c b/gui/greeter/greeter_system.c index 11173665..54295f47 100644 --- a/gui/greeter/greeter_system.c +++ b/gui/greeter/greeter_system.c @@ -144,6 +144,7 @@ greeter_system_handler (GreeterItemInfo *info, return; dialog = gtk_dialog_new (); + gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); if (working_command_exists (GdmHalt)) { halt_radio = gtk_radio_button_new_with_mnemonic (NULL, @@ -199,6 +200,9 @@ greeter_system_handler (GreeterItemInfo *info, gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_OK); + + gtk_dialog_set_default_response (GTK_DIALOG (dialog), + GTK_RESPONSE_OK); gtk_widget_show_all (dialog); gdm_wm_center_window (GTK_WINDOW (dialog)); diff --git a/utils/gdmaskpass.c b/utils/gdmaskpass.c index 09f0eb0e..5270937e 100644 --- a/utils/gdmaskpass.c +++ b/utils/gdmaskpass.c @@ -32,8 +32,8 @@ main (int argc, char *argv[]) } setlocale (LC_ALL, ""); - bindtextdomain (PACKAGE, GNOMELOCALEDIR); - textdomain (PACKAGE); + bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); + textdomain (GETTEXT_PACKAGE); for (tries = 3; tries > 0; tries --) { if ((retval = pam_start ("gdm", username, &conv, &pamh)) != PAM_SUCCESS) { diff --git a/utils/gdmopen.c b/utils/gdmopen.c index 00f91b2a..967dd053 100644 --- a/utils/gdmopen.c +++ b/utils/gdmopen.c @@ -59,7 +59,7 @@ static pid_t child_pid = -1; struct vt_stat vt; static int vtno; static int fd = 0; -static int do_dealloc = FALSE; +static int do_switchback = FALSE; static void sighandler (int sig) @@ -69,14 +69,11 @@ sighandler (int sig) waitpid (child_pid, NULL, 0); } - if (do_dealloc) { + if (do_switchback) { /* Switch back... */ (void) ioctl(fd, VT_ACTIVATE, vt.v_active); /* wait to be really sure we have switched */ (void) ioctl(fd, VT_WAITACTIVE, vt.v_active); - - /* Now deallocate our new one */ - (void) ioctl(fd, VT_DISALLOCATE, vtno); } /* Kill myself with this signal */ @@ -89,6 +86,8 @@ main (int argc, char *argv[]) { char vtname[256]; int status; + int cmd_start = 1; + char *command = NULL; if (getuid () != geteuid () || getuid () != 0) { @@ -105,6 +104,29 @@ main (int argc, char *argv[]) return 66; } + command = argv[1]; + + if (strcmp (argv[1], "-l") == 0) { + char *p; + if (argc <= 2) { + fprintf (stderr, "gdmopen: must supply a command!\n"); + return 66; + } + /* prepend '-' and start the command at + * argument 2 */ + cmd_start = 2; + command = argv[2]; + argv[2] = malloc (strlen (command) + 2); + p = strrchr (command, '/'); + if (p != NULL) { + /* make it "-basename" */ + strcpy (argv[2]+1, p+1); + } else { + strcpy (argv[2]+1, command); + } + *(argv[2]) = '-'; + } + fd = open ("/dev/console", O_WRONLY, 0); if (fd < 0) { perror ("gdmopen: Failed to open /dev/console"); @@ -132,6 +154,10 @@ main (int argc, char *argv[]) if (child_pid == 0) { char VT_NUMBER[256]; +#ifdef __linux__ + putenv ("TERM=linux"); +#endif + snprintf (VT_NUMBER, sizeof (VT_NUMBER), "VT_NUMBER=%d", vtno); putenv (VT_NUMBER); @@ -176,7 +202,7 @@ main (int argc, char *argv[]) write (0, "\033(K", 3); #endif /* __linux__ */ - execvp (argv[1], &argv[1]); + execvp (command, &argv[cmd_start]); _exit (66); /* failed */ } @@ -186,21 +212,18 @@ main (int argc, char *argv[]) return 66; } - do_dealloc = TRUE; + do_switchback = TRUE; waitpid (child_pid, &status, 0); child_pid = -1; - do_dealloc = FALSE; + do_switchback = FALSE; /* Switch back... */ (void) ioctl(fd, VT_ACTIVATE, vt.v_active); /* wait to be really sure we have switched */ (void) ioctl(fd, VT_WAITACTIVE, vt.v_active); - /* Now deallocate our new one */ - (void) ioctl(fd, VT_DISALLOCATE, vtno); - close (fd); if (WIFEXITED (status)) |