Commit 7bef5408 authored by Jiri (George) Lebl's avatar Jiri (George) Lebl Committed by George Lebl

check for setresuid

Tue May 21 15:12:51 2002  George Lebl <jirka@5z.com>

	* configure.in, accconfig.h: check for setresuid

	* daemon/errorgui.c, daemon/misc.[ch]: use setresuid to really
	  get rid of setuidiness

	* gui/gdmlogin.c: fix accelerators.  Since now we have nice
	  visible accelerators (mnemonics) we no longer need the Esc one
	  which wasn't working anyway

	* daemon/gdm.c, daemon/slave.c, gui/gdmphotosetup.c:  Don't init
	  gnome.  This only breaks the getting of the gnome pixmap dir, so
	  whack the places where this is done.  It's not a big deal really.
	  And not initting things really helps a lot in both init speed,
	  random crashes, hangs, and security.

	* daemon/slave.c, daemon/errorgui.[ch], config/Xsession:  Now
	  we open the .xsession-errors file early on, in fact for all
	  non-failsafe sessions.  If the session is less then 10 seconds
	  long warn the user of possible errors and let him view the
	  .xsession-errors file.

	* daemon/slave.c, daemon/auth.c: give error output when we can't
	  setup the authentication file.

	* daemon/slave.c, daemon/errorgui.c: fix focus issues, fix crash
	  for the error gui boxes

	* daemon/verify-pam.c: fix typo
parent 6e18a19b
Tue May 21 15:12:51 2002 George Lebl <jirka@5z.com>
* configure.in, accconfig.h: check for setresuid
* daemon/errorgui.c, daemon/misc.[ch]: use setresuid to really
get rid of setuidiness
* gui/gdmlogin.c: fix accelerators. Since now we have nice
visible accelerators (mnemonics) we no longer need the Esc one
which wasn't working anyway
* daemon/gdm.c, daemon/slave.c, gui/gdmphotosetup.c: Don't init
gnome. This only breaks the getting of the gnome pixmap dir, so
whack the places where this is done. It's not a big deal really.
And not initting things really helps a lot in both init speed,
random crashes, hangs, and security.
* daemon/slave.c, daemon/errorgui.[ch], config/Xsession: Now
we open the .xsession-errors file early on, in fact for all
non-failsafe sessions. If the session is less then 10 seconds
long warn the user of possible errors and let him view the
.xsession-errors file.
* daemon/slave.c, daemon/auth.c: give error output when we can't
setup the authentication file.
* daemon/slave.c, daemon/errorgui.c: fix focus issues, fix crash
for the error gui boxes
* daemon/verify-pam.c: fix typo
Mon May 20 17:55:57 2002 George Lebl <jirka@5z.com>
* daemon/slave.c: don't allow autologin on anything but
......
......@@ -15,6 +15,7 @@
#undef HAVE_SETENV
#undef HAVE_UNSETENV
#undef HAVE_CLEARENV
#undef HAVE_SETRESUID
#undef EXPANDED_DATADIR
#undef EXPANDED_PIXMAPDIR
#undef EXPANDED_BINDIR
......
......@@ -10,16 +10,8 @@ case $# in
esac
esac
# redirect errors to a file in user's home directory if we can
for errfile in "$HOME/.xsession-errors" "${TMPDIR-/tmp}/xses-$USER" "/tmp/xses-$USER"
do
if ( cp /dev/null "$errfile" 2> /dev/null )
then
chmod 600 "$errfile"
exec > "$errfile" 2>&1
break
fi
done
# Note: ~/.xsession-errors is now done in the daemon so that it
# works for ALL sessions (except ones named 'Failsafe')
# clean up after xbanner
if which freetemp 2> /dev/null ; then
......
......@@ -107,6 +107,7 @@ dnl AC_ARG_PROGRAM
AM_PROG_LIBTOOL
AC_PATH_XTRA
AC_CHECK_TYPE(socklen_t,size_t)
AC_CHECK_FUNCS(setresuid)
GNOME_COMPILER_WARNINGS
......
......@@ -48,6 +48,27 @@ extern gint GdmUserMaxFile;
extern gint GdmRelaxPerms;
extern gboolean GdmDebug;
static void
display_add_error (GdmDisplay *d)
{
if (errno != 0)
gdm_error (_("%s: Could not write new authorization entry: %s"),
"add_auth_entry", g_strerror (errno));
else
gdm_error (_("%s: Could not write new authorization entry. "
"Possibly out of diskspace"),
"add_auth_entry");
if (d->console) {
char *s = g_strdup_printf
(_("GDM could not write a new authorization "
"entry to disk. Possibly out of diskspace.%s%s"),
errno != 0 ? " Error: " : "",
errno != 0 ? g_strerror (errno) : "");
gdm_text_message_dialog (s);
g_free (s);
}
}
static gboolean
add_auth_entry (GdmDisplay *d, FILE *af, FILE *af2,
unsigned short family, const char *addr, int addrlen)
......@@ -92,9 +113,19 @@ add_auth_entry (GdmDisplay *d, FILE *af, FILE *af2,
memcpy (xa->data, d->bcookie, 16);
xa->data_length = 16;
XauWriteAuth (af, xa);
if (af2 != NULL)
XauWriteAuth (af2, xa);
errno = 0;
if ( ! XauWriteAuth (af, xa)) {
display_add_error (d);
return FALSE;
}
if (af2 != NULL) {
errno = 0;
if ( ! XauWriteAuth (af2, xa)) {
display_add_error (d);
return FALSE;
}
}
d->auths = g_slist_append (d->auths, xa);
......@@ -323,6 +354,18 @@ gdm_auth_secure_display (GdmDisplay *d)
return TRUE;
}
static gboolean
try_open_append (const char *file)
{
FILE *fp;
fp = fopen (file, "a+");
if (fp != NULL) {
fclose (fp);
return TRUE;
} else {
return FALSE;
}
}
/**
* gdm_auth_user_add:
......@@ -343,6 +386,7 @@ gdm_auth_user_add (GdmDisplay *d, uid_t user, const char *homedir)
gint authfd;
FILE *af;
GSList *auths = NULL;
gboolean ret = TRUE;
if (!d)
return FALSE;
......@@ -357,13 +401,17 @@ gdm_auth_user_add (GdmDisplay *d, uid_t user, const char *homedir)
umask (077);
d->userauth = g_strconcat (authdir, "/", GdmUserAuthFile, NULL);
/* Find out if the Xauthority file passes the paranoia check */
if (authdir == NULL ||
! gdm_file_check ("gdm_auth_user_add", user, authdir, GdmUserAuthFile,
TRUE, GdmUserMaxFile, GdmRelaxPerms)) {
TRUE, GdmUserMaxFile, GdmRelaxPerms) ||
! try_open_append (d->userauth)) {
/* No go. Let's create a fallback file in GdmUserAuthFB (/tmp) */
d->authfb = TRUE;
g_free (d->userauth);
d->userauth = g_strconcat (GdmUserAuthFB, "/.gdmXXXXXX", NULL);
authfd = g_mkstemp (d->userauth);
......@@ -381,7 +429,6 @@ gdm_auth_user_add (GdmDisplay *d, uid_t user, const char *homedir)
}
else { /* User's Xauthority file is ok */
d->authfb = FALSE;
d->userauth = g_strconcat (authdir, "/", GdmUserAuthFile, NULL);
/* FIXME: Better implement my own locking. The libXau one is not kosher */
if (XauLockAuth (d->userauth, 3, 3, 0) != LOCK_SUCCESS) {
......@@ -419,7 +466,12 @@ gdm_auth_user_add (GdmDisplay *d, uid_t user, const char *homedir)
auths = d->auths;
while (auths) {
XauWriteAuth (af, auths->data);
if ( ! XauWriteAuth (af, auths->data)) {
gdm_error (_("%s: Could not write cookie"));
ret = FALSE;
break;
}
auths = auths->next;
}
......@@ -430,7 +482,7 @@ gdm_auth_user_add (GdmDisplay *d, uid_t user, const char *homedir)
umask (022);
return TRUE;
return ret;
}
......
......@@ -46,11 +46,17 @@ gdm_event (GSignalInvocationHint *ihint,
const GValue *param_values,
gpointer data)
{
GdkEvent *event;
/* HAAAAAAAAAAAAAAAAACK */
/* Since the user has not logged in yet and may have left/right
* mouse buttons switched, we just translate every right mouse click
* to a left mouse click */
GdkEvent *event = g_value_get_pointer ((GValue *)param_values);
if (n_param_values != 2 ||
!G_VALUE_HOLDS (&param_values[1], GDK_TYPE_EVENT))
return FALSE;
event = g_value_get_boxed (&param_values[1]);
if ((event->type == GDK_BUTTON_PRESS ||
event->type == GDK_2BUTTON_PRESS ||
event->type == GDK_3BUTTON_PRESS ||
......@@ -61,8 +67,52 @@ gdm_event (GSignalInvocationHint *ihint,
return TRUE;
}
static void
show_errors (GtkWidget *button, gpointer data)
{
const char *file = data;
FILE *fp;
GtkWidget *sw;
GtkWidget *label;
GtkWidget *parent = button->parent;
GString *gs = g_string_new (NULL);
fp = fopen (file, "r");
if (fp != NULL) {
char buf[256];
while (fgets (buf, sizeof (buf), fp))
g_string_append (gs, buf);
fclose (fp);
} else {
g_string_printf (gs, _("%s could not be opened"), file);
}
gtk_widget_destroy (button);
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_widget_set_size_request (sw, 200, 150);
gtk_widget_show (sw);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_ALWAYS);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
GTK_SHADOW_IN);
label = gtk_label_new (gs->str);
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);
}
void
gdm_error_box (GdmDisplay *d, GtkMessageType type, const char *error)
gdm_error_box_full (GdmDisplay *d, GtkMessageType type, const char *error,
const char *details_label, const char *details_file)
{
pid_t pid;
......@@ -74,6 +124,7 @@ gdm_error_box (GdmDisplay *d, GtkMessageType type, const char *error)
int argc = 1;
char **argv;
GtkWidget *dlg;
GtkWidget *button;
GtkRequisition req;
int screenx = 0;
int screeny = 0;
......@@ -92,10 +143,9 @@ gdm_error_box (GdmDisplay *d, GtkMessageType type, const char *error)
open ("/dev/null", O_RDWR); /* open stdout - fd 1 */
open ("/dev/null", O_RDWR); /* open stderr - fd 2 */
openlog ("gdm", LOG_PID, LOG_DAEMON);
gdm_desetuid ();
seteuid (getuid ());
setegid (getgid ());
openlog ("gdm", LOG_PID, LOG_DAEMON);
argv = g_new0 (char *, 2);
argv[0] = "gtk-error-box";
......@@ -119,10 +169,31 @@ gdm_error_box (GdmDisplay *d, GtkMessageType type, const char *error)
dlg = gtk_message_dialog_new (NULL /* parent */,
0 /* flags */,
type,
GTK_BUTTONS_OK,
GTK_BUTTONS_NONE,
"%s",
loc);
g_free (loc);
if (details_label != NULL) {
loc = g_locale_to_utf8 (details_label,
-1, NULL, NULL, NULL);
button = gtk_button_new_with_label (loc);
g_free (loc);
gtk_widget_show (button);
g_signal_connect (button, "clicked",
G_CALLBACK (show_errors),
/* leak? who cares we exit right
* away */
g_strdup (details_file));
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox),
button, FALSE, FALSE, 3);
}
button = gtk_dialog_add_button (GTK_DIALOG (dlg),
GTK_STOCK_OK,
GTK_RESPONSE_OK);
sid = g_signal_lookup ("event",
GTK_TYPE_WIDGET);
g_signal_add_emission_hook (sid,
......@@ -141,6 +212,8 @@ gdm_error_box (GdmDisplay *d, GtkMessageType type, const char *error)
(screenheight / 2) -
(req.height / 2));
gtk_widget_grab_focus (button);
gtk_widget_show_now (dlg);
if (dlg->window != NULL) {
......@@ -155,6 +228,11 @@ gdm_error_box (GdmDisplay *d, GtkMessageType type, const char *error)
gtk_dialog_run (GTK_DIALOG (dlg));
XSetInputFocus (GDK_DISPLAY (),
PointerRoot,
RevertToPointerRoot,
CurrentTime);
_exit (0);
} else if (pid > 0) {
gdm_wait_for_extra (NULL);
......@@ -170,6 +248,12 @@ press_ok (GtkWidget *entry, gpointer data)
gtk_dialog_response (GTK_DIALOG (dlg), GTK_RESPONSE_OK);
}
void
gdm_error_box (GdmDisplay *d, GtkMessageType type, const char *error)
{
gdm_error_box_full (d, type, error, NULL, NULL);
}
char *
gdm_failsafe_question (GdmDisplay *d,
const char *question,
......@@ -206,10 +290,9 @@ gdm_failsafe_question (GdmDisplay *d,
open ("/dev/null", O_RDWR); /* open stdout - fd 1 */
open ("/dev/null", O_RDWR); /* open stderr - fd 2 */
openlog ("gdm", LOG_PID, LOG_DAEMON);
gdm_desetuid ();
seteuid (getuid ());
setegid (getgid ());
openlog ("gdm", LOG_PID, LOG_DAEMON);
argv = g_new0 (char *, 2);
argv[0] = "gtk-failsafe-question";
......@@ -349,10 +432,9 @@ gdm_failsafe_yesno (GdmDisplay *d,
open ("/dev/null", O_RDWR); /* open stdout - fd 1 */
open ("/dev/null", O_RDWR); /* open stderr - fd 2 */
openlog ("gdm", LOG_PID, LOG_DAEMON);
gdm_desetuid ();
seteuid (getuid ());
setegid (getgid ());
openlog ("gdm", LOG_PID, LOG_DAEMON);
argv = g_new0 (char *, 2);
argv[0] = "gtk-failsafe-yesno";
......
......@@ -22,6 +22,12 @@
#include "gdm.h"
#include <gtk/gtkmessagedialog.h>
void gdm_error_box_full (GdmDisplay *d,
GtkMessageType type,
const char *error,
const char *details_label,
const char *details_file);
void gdm_error_box (GdmDisplay *d,
GtkMessageType type,
const char *error);
......
......@@ -1325,6 +1325,8 @@ main (int argc, char *argv[])
sigset_t mask;
struct sigaction term, child;
FILE *pf;
poptContext ctx;
int nextopt;
store_argv (argc, argv);
......@@ -1336,12 +1338,18 @@ main (int argc, char *argv[])
/* Initialize runtime environment */
umask (022);
gnome_program_init ("gdm", VERSION,
LIBGNOME_MODULE /* module_info */,
argc, argv,
GNOME_PARAM_POPT_TABLE, options,
GNOME_PARAM_CREATE_DIRECTORIES, FALSE,
NULL);
ctx = poptGetContext ("gdm", argc, (const char **) argv,
options, 0);
while ((nextopt = poptGetNextOpt (ctx)) > 0 || nextopt == POPT_ERROR_BADOPT)
/* do nothing */ ;
if (nextopt != -1) {
g_print (_("Error on option %s: %s.\nRun '%s --help' to see a full list of available command line options.\n"),
poptBadOption (ctx, 0),
poptStrerror (nextopt),
argv[0]);
exit (1);
}
/* XDM compliant error message */
if (getuid () != 0) {
......
......@@ -491,8 +491,7 @@ gdm_exec_wait (char * const *argv, gboolean no_display,
open ("/dev/null", O_RDWR); /* open stderr - fd 2 */
if (de_setuid) {
seteuid (getuid ());
setegid (getgid ());
gdm_desetuid ();
}
openlog ("gdm", LOG_PID, LOG_DAEMON);
......@@ -829,4 +828,23 @@ gdm_setup_gids (const char *login, gid_t gid)
return TRUE;
}
void
gdm_desetuid (void)
{
uid_t uid = getuid ();
gid_t gid = getgid ();
#ifdef HAVE_SETRESUID
{
int setresuid(uid_t ruid, uid_t euid, uid_t suid);
int setresgid(gid_t rgid, gid_t egid, gid_t sgid);
setresuid (uid, uid, uid);
setresgid (gid, gid, gid);
}
#else
seteuid (getuid ());
setegid (getgid ());
#endif
}
/* EOF */
......@@ -67,6 +67,8 @@ gboolean gdm_is_loopback_addr (struct in_addr *ia);
gboolean gdm_setup_gids (const char *login, gid_t gid);
void gdm_desetuid (void);
#endif /* GDM_MISC_H */
/* EOF */
......@@ -1020,12 +1020,17 @@ gdm_slave_wait_for_login (void)
static gboolean
is_in_trusted_pic_dir (const char *path)
{
#if 0
GSList *locations = NULL, *li;
#endif
/* our own pixmap dir is trusted */
if (strncmp (path, EXPANDED_PIXMAPDIR, sizeof (EXPANDED_PIXMAPDIR)) == 0)
return TRUE;
/* FIXME: somehow get gnomes locations and all that */
#if 0
/* we have no gnome-program and we don't want one */
g_free (gnome_program_locate_file (NULL /* program */,
GNOME_FILE_DOMAIN_PIXMAP,
"" /* file_name */,
......@@ -1041,6 +1046,7 @@ is_in_trusted_pic_dir (const char *path)
}
g_slist_foreach (locations, (GFunc)g_free, NULL);
g_slist_free (locations);
#endif
return FALSE;
}
......@@ -2008,6 +2014,7 @@ dequote (const char *in)
static void
session_child_run (struct passwd *pwent,
const char *home_dir,
gboolean home_dir_ok,
const char *session,
const char *save_session,
const char *language,
......@@ -2020,10 +2027,21 @@ session_child_run (struct passwd *pwent,
gboolean savegnomesess)
{
sigset_t mask;
int logfd;
int i;
gboolean failsafe = FALSE;
char *sesspath, *sessexec;
gboolean need_config_sync = FALSE;
const char *shell = NULL;
Display *disp;
disp = XOpenDisplay (d->name);
if (disp != NULL) {
XSetInputFocus (disp, PointerRoot,
RevertToPointerRoot, CurrentTime);
XCloseDisplay (disp);
}
gdm_clearenv ();
......@@ -2109,7 +2127,7 @@ session_child_run (struct passwd *pwent,
* to write */
gnome_config_drop_all ();
if (usrcfgok && savesess) {
if (usrcfgok && savesess && home_dir_ok) {
gchar *cfgstr = g_strconcat ("=", home_dir,
"/.gnome/gdm=/session/last", NULL);
gnome_config_set_string (cfgstr, save_session);
......@@ -2117,7 +2135,7 @@ session_child_run (struct passwd *pwent,
g_free (cfgstr);
}
if (usrcfgok && savelang) {
if (usrcfgok && savelang && home_dir_ok) {
gchar *cfgstr = g_strconcat ("=", home_dir,
"/.gnome/gdm=/session/lang", NULL);
gnome_config_set_string (cfgstr, language);
......@@ -2127,7 +2145,8 @@ session_child_run (struct passwd *pwent,
if (sessoptok &&
savegnomesess &&
gnome_session != NULL) {
gnome_session != NULL &&
home_dir_ok) {
gchar *cfgstr = g_strconcat ("=", home_dir, "/.gnome/session-options=/Options/CurrentSession", NULL);
gnome_config_set_string (cfgstr, gnome_session);
need_config_sync = TRUE;
......@@ -2194,6 +2213,7 @@ session_child_run (struct passwd *pwent,
"run. This is only to fix problems in\n"
"your installation."));
}
failsafe = TRUE;
}
/* an if and not an else, we could have done a fall-through
......@@ -2222,8 +2242,14 @@ session_child_run (struct passwd *pwent,
"'exit' and an enter into the window."));
focus_first_x_window ("xterm");
}
failsafe = TRUE;
}
/* hack */
if (strcmp (session, "Failsafe") == 0) {
failsafe = TRUE;
}
if (sesspath == NULL) {
if (GdmSessDir != NULL) {
sesspath = g_strconcat
......@@ -2245,6 +2271,21 @@ session_child_run (struct passwd *pwent,
shell = "/bin/sh";
}
/* Log all output from session programs to a file,
* unless in failsafe mode which needs to work when there is
* no diskspace as well */
if ( ! failsafe && home_dir_ok) {
logfd = open (g_strconcat (home_dir, "/.xsession-errors", NULL),
O_CREAT|O_TRUNC|O_WRONLY, 0644);
if (logfd != -1) {
dup2 (logfd, 1);
dup2 (logfd, 2);
} else {
gdm_error (_("%s: Could not open ~/.xsession-errors"),
"run_session_child");
}
}
/* just a stupid test, the below would fail, but this gives a better
* message */
if (strcmp (shell, "/sbin/nologin") == 0 ||
......@@ -2292,6 +2333,8 @@ gdm_slave_session_start (void)
gboolean def_language = FALSE;
const char *home_dir = NULL;
gboolean home_dir_ok = FALSE;
time_t session_start_time, end_time;
gboolean failsafe = FALSE;
pid_t pid;
gdm_debug ("gdm_slave_session_start: Attempting session for user '%s'",
......@@ -2501,15 +2544,36 @@ gdm_slave_session_start (void)
setegid (GdmGroupId);
if ( ! authok) {
gdm_debug ("gdm_slave_session_start: Auth not OK");
gdm_slave_session_stop (0);
gdm_slave_session_cleanup ();
gdm_server_stop (d);
gdm_verify_cleanup (d);
gdm_debug ("gdm_slave_session_start: Auth not OK");
gnome_setenv ("XAUTHORITY", d->authfile, TRUE);
gdm_error_box (d,
GTK_MESSAGE_ERROR,
_("GDM could not write to your authorization\n"
"file. This could mean that you are out of\n"
"disk space or that your home directory could\n"
"not be opened for writing. In any case, it\n"
"is not possible to log in. Please contact\n"
"your system administrator"));
_exit (DISPLAY_REMANAGE);
}
gdm_slave_session_stop (0);
gdm_slave_session_cleanup ();
gdm_server_stop (d);
gdm_verify_cleanup (d);
_exit (DISPLAY_REMANAGE);
}
if (strcmp (session, GDM_SESSION_FAILSAFE_GNOME) == 0 ||
strcmp (session, GDM_SESSION_FAILSAFE_XTERM) == 0 ||
strcmp (session, "Failsafe") == 0 /* hack */)
failsafe = TRUE;
/* don't completely rely on this, the user
* could reset time or do other crazy things */
session_start_time = time (NULL);
/* Start user process */
gdm_sigchld_block_push ();
......@@ -2528,6 +2592,7 @@ gdm_slave_session_start (void)
/* Never returns */
session_child_run (pwent,
home_dir,
home_dir_ok,
session,
save_session,
language,
......@@ -2564,6 +2629,36 @@ gdm_slave_session_start (void)
gdm_sigchld_block_pop ();
}
end_time = time (NULL);
gdm_debug ("Session: start_time: %ld end_time: %ld",
(long)session_start_time, (long)end_time);
if ((/* sanity */ end_time >= session_start_time) &&
(end_time - 10 <= session_start_time)) {
char *errfile = g_strconcat (home_dir, "/.xsession-errors", NULL);
gdm_debug ("Session less then 10 seconds!");
gnome_setenv ("XAUTHORITY", d->authfile, TRUE);
/* FIXME: perhaps do some checking to display a better error,
* such as gnome-session missing and such things. */
gdm_error_box_full (d,
GTK_MESSAGE_WARNING,
_("Your session only lasted less then\n"
"10 seconds. If you have not logged out\n"
"yourself, this could mean that there is\n"
"some installation problem or that you may\n"
"be out of diskspace. Try logging in with\n"
"one of the failsafe sessions to see if you\n"
"can fix this problem."),
(home_dir_ok && ! failsafe) ?
_("View details (~/.xsession-errors file)") :
NULL,
errfile);
g_free (errfile);
}
gdm_debug ("gdm_slave_session_start: Session ended OK");
gdm_slave_session_stop (pid);
......
......@@ -381,7 +381,7 @@ gdm_verify_user (GdmDisplay *d,
case PAM_PERM_DENIED :
gdm_error (_("User %s not permitted to gain access at this time"), login);
gdm_slave_greeter_ctl_no_ret (GDM_ERRBOX,
_("\nThe system administrator has disabled access to the system temporary."));
_("\nThe system administrator has disabled access to the system temporairly."));
error_msg_given = TRUE;
goto pamerr;
default :
......
......@@ -2813,7 +2813,6 @@ gdm_login_gui_init (void)
GtkWidget *bbox = NULL;
GtkWidget *logoframe = NULL;
GtkWidget /**help_button,*/ *button_box;
GtkAccelGroup *accel;
gchar *greeting;
gint cols, rows;
struct stat statbuf;
......@@ -2832,9 +2831,6 @@ gdm_login_gui_init (void)
G_CALLBACK (window_browser_event),
NULL);
accel = gtk_accel_group_new ();
gtk_window_add_accel_group (GTK_WINDOW (login), accel);
frame1 = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame1), GTK_SHADOW_OUT);
gtk_container_set_border_width (GTK_CONTAINER (frame1), 0);
......@@ -2871,22 +2867,16 @@ gdm_login_gui_init (void)
menu = gtk_menu_new();
gdm_login_session_init (menu);
sessmenu = gtk_menu_item_new_with_label (_("Session"));
sessmenu = gtk_menu_item_new_with_mnemonic (_("_Session"));
gtk_menu_shell_append (GTK_MENU_SHELL (menubar), sessmenu);
gtk_menu_item_set_submenu (GTK_MENU_ITEM (sessmenu), menu);
gtk_widget_add_accelerator (sessmenu, "activate", accel,
GDK_Escape, 0, 0);
gtk_widget_add_accelerator (sessmenu, "activate", accel,
GDK_s, GDK_MOD1_MASK, 0);
gtk_widget_show (GTK_WIDGET (sessmenu));
menu = gdm_login_language_menu_new ();
if (menu != NULL) {
langmenu = gtk_menu_item_new_with_label (_("Language"));
langmenu = gtk_menu_item_new_with_mnemonic (_("_Language"));
gtk_menu_shell_append (GTK_MENU_SHELL (menubar), langmenu);
gtk_menu_item_set_submenu (GTK_MENU_ITEM (langmenu), menu);
gtk_widget_add_accelerator (langmenu, "activate", accel,
GDK_l, GDK_MOD1_MASK, 0);
gtk_widget_show (GTK_WIDGET (langmenu));
}
......@@ -2896,7 +2886,7 @@ gdm_login_gui_init (void)
menu = gtk_menu_new();
if (GdmConfigAvailable &&
bin_exists (GdmConfigurator)) {
item = gtk_menu_item_new_with_label (_("Configure..."));
item = gtk_menu_item_new_with_mnemonic (_("_Configure..."));
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
g_signal_connect (G_OBJECT (item), "activate",
G_CALLBACK (gdm_run_gdmconfig),
......@@ -2910,7 +2900,7 @@ gdm_login_gui_init (void)
}
if (bin_exists (GdmReboot)) {
item = gtk_menu_item_new_with_label (_("Reboot..."));
item = gtk_menu_item_new_with_mnemonic (_("_Reboot..."));