Commit b71f5350 authored by Brian Cameron's avatar Brian Cameron Committed by Brian Cameron

Patch that makes the GDM daemon (rather than the forked slave) cause all

2006-12-04  Brian Cameron  <brian.cameron@sun.com>

        * daemon/errorgui.c, daemon/gdm.[ch], daemon/slave.c,
          daemon/verify-pam.c:  Patch that makes the GDM daemon
          (rather than the forked slave) cause all dialogs to be
          displayed.  This improves accessibility for GDM because
          any AT programs (such as GOK, Gnopernicus or Orca) which
          are launched from GDM will now better work with such
          dialogs.  This is needed because dialogs will show up
          running as the user if they appear after authentication
          and at this point the at-spi-registryd is running as the
          gdm user.  We want all GDM dialogs to run as the gdm
          user.  Patch by Leena Gunda <leena.gunda@wipro.com> and
          Srirama Sharma <Srirama.Sharma@Sun.COM>.  Note that
          there have been some reports that this change triggers
          GDK bug #376315 on Linux when a11y is turned off.  This
          will probably need to be fixed before the next stable
          release.  I think this a11y fix is important enough to
          introduce this bug in the development cycle.  Workaround
          for now is to turn on a11y.
parent b52e2ad9
2006-12-04 Brian Cameron <brian.cameron@sun.com>
* daemon/errorgui.c, daemon/gdm.[ch], daemon/slave.c,
daemon/verify-pam.c: Patch that makes the GDM daemon
(rather than the forked slave) cause all dialogs to be
displayed. This improves accessibility for GDM because
any AT programs (such as GOK, Gnopernicus or Orca) which
are launched from GDM will now better work with such
dialogs. This is needed because dialogs will show up
running as the user if they appear after authentication
and at this point the at-spi-registryd is running as the
gdm user. We want all GDM dialogs to run as the gdm
user. Patch by Leena Gunda <leena.gunda@wipro.com> and
Srirama Sharma <Srirama.Sharma@Sun.COM>. Note that
there have been some reports that this change triggers
GDK bug #376315 on Linux when a11y is turned off. This
will probably need to be fixed before the next stable
release. I think this a11y fix is important enough to
introduce this bug in the development cycle. Workaround
for now is to turn on a11y.
2006-12-01 Brian Cameron <brian.cameron@sun.com>
* gui/gdmsetup.desktop.in.in. Implement the tooltip suggestion
......
......@@ -41,6 +41,7 @@
#include "auth.h"
#include "gdmconfig.h"
#include "errorgui.h"
#include "slave.h"
/* set in the main function */
extern char **stored_argv;
......@@ -225,7 +226,7 @@ setup_dialog (GdmDisplay *d, const char *name, int closefdexcept, gboolean set_g
g_setenv ("DISPLAY", d->name, TRUE);
g_unsetenv ("XAUTHORITY");
gdm_auth_set_local_auth (d);
g_setenv ("XAUTHORITY", GDM_AUTHFILE (d), TRUE);
/* sanity env stuff */
g_setenv ("SHELL", "/bin/sh", TRUE);
......@@ -316,6 +317,17 @@ gdm_error_box_full (GdmDisplay *d, GtkMessageType type, const char *error,
char *loc;
char *details;
if (details_label != NULL) {
if (strncmp (details_label, "NIL", 3) == 0)
g_free (details_label);
details_label = NULL;
}
if (details_file != NULL) {
if (strncmp (details_file, "NIL", 3) == 0)
g_free (details_file);
details_file = NULL;
}
if (uid != 0) {
gid_t groups[1] = { gid };
......@@ -498,10 +510,14 @@ press_ok (GtkWidget *entry, gpointer data)
void
gdm_error_box (GdmDisplay *d, GtkMessageType type, const char *error)
{
gdm_error_box_full (d, type, error, NULL, NULL,
/* zero for uid/gid doesn't mean root, but
it means to use the gdm user/group */
0, 0);
char *msg;
int id = 0;
msg = g_strdup_printf ("type=%d$$error=%s$$details_label=%s$$details_file=%s$$uid=%d$$gid=%d", type, error, "NIL", "NIL", id, id);
gdm_slave_send_string (GDM_SOP_SHOW_ERROR_DIALOG, msg);
g_free (msg);
}
char *
......@@ -775,7 +791,7 @@ gdm_failsafe_ask_buttons (GdmDisplay *d,
loc);
g_free (loc);
gtk_widget_set_events (dlg, GDK_ALL_EVENTS_MASK);
for (i = 0; but[i] != NULL; i++) {
for (i = 0; but[i] != NULL && strcmp (but[i], "NIL"); i++) {
loc = gdm_locale_to_utf8 (but[i]);
gtk_dialog_add_button (GTK_DIALOG (dlg),
loc, i);
......
......@@ -41,6 +41,7 @@
#include <syslog.h>
#include <locale.h>
#include <dirent.h>
#include <gtk/gtk.h>
/* This should be moved to auth.c I suppose */
......@@ -64,6 +65,7 @@
#include "cookie.h"
#include "filecheck.h"
#include "gdmconfig.h"
#include "errorgui.h"
#define DYNAMIC_ADD 0
#define DYNAMIC_RELEASE 1
......@@ -1872,6 +1874,55 @@ write_x_servers (GdmDisplay *d)
g_free (file);
}
static void
send_slave_ack_dialog_int (GdmDisplay *d, int type, int response)
{
if (d->master_notify_fd >= 0) {
char *not;
not = g_strdup_printf ("%c%c%d\n", GDM_SLAVE_NOTIFY_RESPONSE, type, response);
VE_IGNORE_EINTR (write (d->master_notify_fd, not, strlen (not)));
g_free (not);
}
if (d->slavepid > 1) {
/* now yield the CPU as the other process has more
useful work to do then we do */
#if defined (_POSIX_PRIORITY_SCHEDULING) && defined (HAVE_SCHED_YIELD)
sched_yield ();
#endif
}
}
static void
send_slave_ack_dialog_char (GdmDisplay *d, int type, const char *resp)
{
if (d->master_notify_fd >= 0) {
if (resp == NULL) {
char not[3];
not[0] = GDM_SLAVE_NOTIFY_RESPONSE;
not[1] = type;
not[2] = '\n';
VE_IGNORE_EINTR (write (d->master_notify_fd, not, 3));
} else {
char *not = g_strdup_printf ("%c%c%s\n",
GDM_SLAVE_NOTIFY_RESPONSE,
type,
resp);
VE_IGNORE_EINTR (write (d->master_notify_fd, not, strlen (not)));
g_free (not);
}
}
if (d->slavepid > 1) {
/* now yield the CPU as the other process has more
useful work to do then we do */
#if defined (_POSIX_PRIORITY_SCHEDULING) && defined (HAVE_SCHED_YIELD)
sched_yield ();
#endif
}
}
static void
send_slave_ack (GdmDisplay *d, const char *resp)
{
......@@ -2499,6 +2550,193 @@ gdm_handle_message (GdmConnection *conn, const char *msg, gpointer data)
TRUE /* handled */,
FALSE /* chooser */,
NULL, 0, NULL, NULL);
} else if (strncmp (msg, "opcode="GDM_SOP_SHOW_ERROR_DIALOG,
strlen ("opcode="GDM_SOP_SHOW_ERROR_DIALOG)) == 0) {
GdmDisplay *d;
GtkMessageType type;
char **list;
char *ptr;
char *error;
char *details_label;
char *details_file;
long slave_pid;
int uid, gid;
list = g_strsplit (msg, "$$", -1);
ptr = strchr (list[1], '=');
slave_pid = atol (ptr + 1);
ptr = strchr (list[2], '=');
type = atoi (ptr + 1);
ptr = strchr (list[3], '=');
error = g_malloc0 (strlen (ptr));
strcpy (error, ptr + 1);
ptr = strchr (list[4], '=');
details_label = g_malloc0 (strlen (ptr));
strcpy (details_label, ptr + 1);
ptr = strchr (list[5], '=');
details_file = g_malloc0 (strlen (ptr));
strcpy (details_file, ptr + 1);
ptr = strchr (list[6], '=');
uid = atoi (ptr + 1);
ptr = strchr (list[7], '=');
gid = atoi (ptr + 1);
d = gdm_display_lookup (slave_pid);
if (d != NULL) {
if (GDM_AUTHFILE (d)) {
VE_IGNORE_EINTR (chmod (GDM_AUTHFILE (d), 0644));
}
gdm_error_box_full (d, type, error, details_label, details_file, 0, 0);
if (GDM_AUTHFILE (d)) {
VE_IGNORE_EINTR (chmod (GDM_AUTHFILE (d), 0640));
}
send_slave_ack_dialog_char (d, GDM_SLAVE_NOTIFY_ERROR_RESPONSE, NULL);
}
g_free (error);
g_free (details_label);
g_free (details_file);
g_strfreev (list);
} else if (strncmp (msg, "opcode="GDM_SOP_SHOW_YESNO_DIALOG,
strlen ("opcode="GDM_SOP_SHOW_YESNO_DIALOG)) == 0) {
GdmDisplay *d;
char **list;
char *ptr;
char *yesno_msg;
long slave_pid;
gboolean response_yesno;
list = g_strsplit (msg, "$$", -1);
ptr = strchr (list [1], '=');
slave_pid = atol (ptr + 1);
ptr = strchr (list [2], '=');
yesno_msg = g_malloc0 (strlen (ptr));
strcpy (yesno_msg, ptr + 1);
d = gdm_display_lookup (slave_pid);
if (d != NULL) {
if (GDM_AUTHFILE (d)) {
VE_IGNORE_EINTR (chmod (GDM_AUTHFILE (d), 0644));
}
response_yesno = gdm_failsafe_yesno (d, yesno_msg);
send_slave_ack_dialog_int (d, GDM_SLAVE_NOTIFY_YESNO_RESPONSE, response_yesno);
if (GDM_AUTHFILE (d)) {
VE_IGNORE_EINTR (chmod (GDM_AUTHFILE (d), 0640));
}
}
g_free (yesno_msg);
g_strfreev (list);
} else if (strncmp (msg, "opcode="GDM_SOP_SHOW_QUESTION_DIALOG,
strlen ("opcode="GDM_SOP_SHOW_QUESTION_DIALOG)) == 0) {
GdmDisplay *d;
char **list;
char *ptr;
char *question_msg;
char *response_question;
long slave_pid;
gboolean echo;
list = g_strsplit (msg, "$$", -1);
ptr = strchr (list [1], '=');
slave_pid = atol (ptr + 1);
ptr = strchr (list [2], '=');
question_msg = g_malloc0 (strlen (ptr));
strcpy (question_msg, ptr + 1);
ptr = strchr (list [3], '=');
echo = atoi (ptr + 1);
d = gdm_display_lookup (slave_pid);
if (d != NULL) {
if (GDM_AUTHFILE (d)) {
VE_IGNORE_EINTR (chmod (GDM_AUTHFILE (d), 0644));
}
response_question = gdm_failsafe_question (d, question_msg, echo);
send_slave_ack_dialog_char (d, GDM_SLAVE_NOTIFY_QUESTION_RESPONSE, response_question);
if (GDM_AUTHFILE (d)) {
VE_IGNORE_EINTR (chmod (GDM_AUTHFILE (d), 0640));
}
}
g_free (question_msg);
g_strfreev (list);
} else if (strncmp (msg, "opcode="GDM_SOP_SHOW_ASKBUTTONS_DIALOG,
strlen ("opcode="GDM_SOP_SHOW_ASKBUTTONS_DIALOG)) == 0) {
GdmDisplay *d;
char *askbuttons_msg;
char **list;
char *ptr;
char *options[4];
long slave_pid;
int i;
int response_askbuttons;
list = g_strsplit (msg, "$$", -1);
ptr = strchr (list [1], '=');
slave_pid = atol (ptr + 1);
ptr = strchr (list [2], '=');
askbuttons_msg = g_malloc0 (strlen (ptr));
strcpy (askbuttons_msg, ptr + 1);
ptr = strchr (list [3], '=');
options[0] = g_malloc0 (strlen (ptr));
strcpy (options[0], ptr + 1);
ptr = strchr (list [4], '=');
options[1] = g_malloc0 (strlen (ptr));
strcpy (options[1], ptr + 1);
ptr = strchr (list [5], '=');
options[2] = g_malloc0 (strlen (ptr));
strcpy (options[2], ptr + 1);
ptr = strchr (list [6], '=');
options[3] = g_malloc0 (strlen (ptr));
strcpy (options[3], ptr + 1);
d = gdm_display_lookup (slave_pid);
if (d != NULL) {
if (GDM_AUTHFILE (d)) {
VE_IGNORE_EINTR (chmod (GDM_AUTHFILE (d), 0644));
}
response_askbuttons = gdm_failsafe_ask_buttons (d, askbuttons_msg, options);
send_slave_ack_dialog_int (d, GDM_SLAVE_NOTIFY_ASKBUTTONS_RESPONSE, response_askbuttons);
if (GDM_AUTHFILE (d)) {
VE_IGNORE_EINTR (chmod (GDM_AUTHFILE (d), 0640));
}
}
g_free (askbuttons_msg);
for (i = 0; i < 3; i ++)
g_free (options[i]);
g_strfreev (list);
}
}
......
......@@ -742,6 +742,11 @@ void gdm_final_cleanup (void);
/* Start a new standard X flexible server */
#define GDM_SOP_FLEXI_XSERVER "FLEXI_XSERVER" /* no arguments */
#define GDM_SOP_SHOW_ERROR_DIALOG "SHOW_ERROR_DIALOG" /* show the error dialog from daemon */
#define GDM_SOP_SHOW_YESNO_DIALOG "SHOW_YESNO_DIALOG" /* show the yesno dialog from daemon */
#define GDM_SOP_SHOW_QUESTION_DIALOG "SHOW_QUESTION_DIALOG" /* show the question dialog from daemon */
#define GDM_SOP_SHOW_ASKBUTTONS_DIALOG "SHOW_ASKBUTTON_DIALOG" /* show the askbutton dialog from daemon */
/* Notification protocol */
/* keys */
#define GDM_NOTIFY_ALLOW_REMOTE_ROOT "AllowRemoteRoot" /* <true/false as int> */
......@@ -777,6 +782,16 @@ void gdm_final_cleanup (void);
#define GDM_SLAVE_NOTIFY_KEY '!'
/* notify a command */
#define GDM_SLAVE_NOTIFY_COMMAND '#'
/* send the response */
#define GDM_SLAVE_NOTIFY_RESPONSE 'R'
/* send the error dialog response */
#define GDM_SLAVE_NOTIFY_ERROR_RESPONSE 'E'
/* send the yesno dialog response */
#define GDM_SLAVE_NOTIFY_YESNO_RESPONSE 'Y'
/* send the askbuttons dialog response */
#define GDM_SLAVE_NOTIFY_ASKBUTTONS_RESPONSE 'B'
/* send the question dialog response */
#define GDM_SLAVE_NOTIFY_QUESTION_RESPONSE 'Q'
/*
* Maximum number of messages allowed over the sockets protocol. This
......
......@@ -89,6 +89,7 @@
#include "errorgui.h"
#include "cookie.h"
#include "gdmconfig.h"
#include "display.h"
#ifdef WITH_CONSOLE_KIT
#include "gdmconsolekit.h"
......@@ -194,6 +195,7 @@ gboolean gdm_is_user_valid (const char *username);
static gboolean x_error_occurred = FALSE;
static gboolean gdm_got_ack = FALSE;
static char * gdm_ack_response = NULL;
char * gdm_ack_question_response = NULL;
static GList *unhandled_notifies = NULL;
......@@ -1135,6 +1137,7 @@ ask_migrate (const char *migrate_to)
int r;
char *msg;
char *but[4];
char *askbuttons_msg;
but[0] = _("Log in anyway");
if (migrate_to != NULL) {
......@@ -1144,19 +1147,29 @@ ask_migrate (const char *migrate_to)
"login");
but[1] = _("Return to previous login");
but[2] = _("Abort login");
but[3] = NULL;
but[3] = "NIL";
} else {
msg = _("You are already logged in. "
"You can log in anyway or abort this "
"login");
but[1] = _("Abort login");
but[2] = NULL;
but[2] = "NIL";
but[3] = "NIL";
}
if (greet)
gdm_slave_greeter_ctl_no_ret (GDM_DISABLE, "");
r = gdm_failsafe_ask_buttons (d, msg, but);
askbuttons_msg = g_strdup_printf ("askbuttons_msg=%s$$options_msg1=%s$$options_msg2=%s$$options_msg3=%s$$options_msg4=%s", msg, but[0], but[1], but[2], but[3]);
gdm_slave_send_string (GDM_SOP_SHOW_ASKBUTTONS_DIALOG, askbuttons_msg);
r = atoi (gdm_ack_response);
g_free (askbuttons_msg);
g_free (gdm_ack_response);
gdm_ack_response = NULL;
if (greet)
gdm_slave_greeter_ctl_no_ret (GDM_ENABLE, "");
......@@ -1762,7 +1775,7 @@ run_config (GdmDisplay *display, struct passwd *pwent)
closelog ();
gdm_close_all_descriptors (0 /* from */, -1 /* except */, -1 /* except2 */);
gdm_close_all_descriptors (0 /* from */, slave_fifo_pipe_fd /* except */, d->slave_notify_fd /* except2 */);
/* No error checking here - if it's messed the best response
* is to ignore & try to continue */
......@@ -2483,7 +2496,7 @@ gdm_slave_greeter (void)
closelog ();
gdm_close_all_descriptors (2 /* from */, -1 /* except */, -1 /* except2 */);
gdm_close_all_descriptors (2 /* from */, slave_fifo_pipe_fd/* except */, d->slave_notify_fd/* except2 */);
gdm_open_dev_null (O_RDWR); /* open stderr - fd 2 */
......@@ -2625,7 +2638,7 @@ gdm_slave_greeter (void)
something works instead of a flickering screen */
gdm_error_box (d,
GTK_MESSAGE_ERROR,
_("The greeter application appears to be crashing.\n"
_("The greeter application appears to be crashing."
"Attempting to use a different one."));
if (strstr (command, "gdmlogin") != NULL) {
/* in case it is gdmlogin that's crashing
......@@ -2720,7 +2733,7 @@ gdm_slave_send (const char *str, gboolean wait_for_ack)
}
/* ensure this is sent from the actual slave with the pipe always, this is anal I know */
if G_LIKELY (d->slavepid == getpid ()) {
if (G_LIKELY (d->slavepid == getppid ()) || G_LIKELY (d->slavepid == getpid ())) {
fd = slave_fifo_pipe_fd;
} else {
fd = -1;
......@@ -2767,34 +2780,56 @@ gdm_slave_send (const char *str, gboolean wait_for_ack)
}
#endif
for (i = 0;
wait_for_ack &&
! gdm_got_ack &&
parent_exists () &&
i < 10;
i++) {
if (in_usr2_signal > 0) {
/* Wait till you get a response from the daemon */
if (strncmp (str, "opcode="GDM_SOP_SHOW_ERROR_DIALOG,
strlen ("opcode="GDM_SOP_SHOW_ERROR_DIALOG)) == 0 ||
strncmp (str, "opcode="GDM_SOP_SHOW_YESNO_DIALOG,
strlen ("opcode="GDM_SOP_SHOW_YESNO_DIALOG)) == 0 ||
strncmp (str, "opcode="GDM_SOP_SHOW_QUESTION_DIALOG,
strlen ("opcode="GDM_SOP_SHOW_QUESTION_DIALOG)) == 0 ||
strncmp (str, "opcode="GDM_SOP_SHOW_ASKBUTTONS_DIALOG,
strlen ("opcode="GDM_SOP_SHOW_ASKBUTTONS_DIALOG)) == 0) {
for (; wait_for_ack && !gdm_got_ack ; ) {
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) {
if (select (d->slave_notify_fd+1, &rfds, NULL, NULL, NULL) > 0) {
gdm_slave_handle_usr2_message ();
}
} 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 */
}
} else {
for (i = 0;
wait_for_ack &&
! gdm_got_ack &&
parent_exists () &&
i < 10;
i++) {
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_handle_usr2_message ();
}
} 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 */
}
}
}
......@@ -2844,8 +2879,16 @@ gdm_slave_send_string (const char *opcode, const char *str)
(long)getpid ());
}
msg = g_strdup_printf ("%s %ld %s", opcode,
(long)getpid (), ve_sure_string (str));
if (strcmp (opcode, GDM_SOP_SHOW_ERROR_DIALOG) == 0 ||
strcmp (opcode, GDM_SOP_SHOW_YESNO_DIALOG) == 0 ||
strcmp (opcode, GDM_SOP_SHOW_QUESTION_DIALOG) == 0 ||
strcmp (opcode, GDM_SOP_SHOW_ASKBUTTONS_DIALOG) == 0) {
msg = g_strdup_printf ("opcode=%s$$pid=%ld$$%s", opcode,
(long)d->slavepid, ve_sure_string (str));
} else {
msg = g_strdup_printf ("%s %ld %s", opcode,
(long)getpid (), ve_sure_string (str));
}
gdm_slave_send (msg, TRUE);
......@@ -2953,7 +2996,7 @@ gdm_slave_chooser (void)
closelog ();
VE_IGNORE_EINTR (close (0));
gdm_close_all_descriptors (2 /* from */, -1 /* except */, -1 /* except2 */);
gdm_close_all_descriptors (2 /* from */, slave_fifo_pipe_fd /* except */, d->slave_notify_fd /* except2 */);
gdm_open_dev_null (O_RDONLY); /* open stdin - fd 0 */
gdm_open_dev_null (O_RDWR); /* open stderr - fd 2 */
......@@ -3591,7 +3634,7 @@ session_child_run (struct passwd *pwent,
closelog ();
gdm_close_all_descriptors (3 /* from */, -1 /* except */, -1 /* except2 */);
gdm_close_all_descriptors (3 /* from */, slave_fifo_pipe_fd /* except */, d->slave_notify_fd /* except2 */);
openlog ("gdm", LOG_PID, LOG_DAEMON);
......@@ -4004,11 +4047,12 @@ gdm_slave_session_start (void)
if G_UNLIKELY (pwent->pw_dir == NULL ||
! g_file_test (pwent->pw_dir, G_FILE_TEST_IS_DIR)) {
char *yesno_msg;
char *msg = g_strdup_printf (
_("Your home directory is listed as:\n'%s'\n"
_("Your home directory is listed as:'%s'"
"but it does not appear to exist. "
"Do you want to log in with the / (root) "
"directory as your home directory?\n\n"
"directory as your home directory?"
"It is unlikely anything will work unless "
"you use a failsafe session."),
ve_sure_string (pwent->pw_dir));
......@@ -4023,14 +4067,24 @@ gdm_slave_session_start (void)
ve_sure_string (pwent->pw_dir));
/* Check what the user wants to do */
if ( ! gdm_failsafe_yesno (d, msg)) {
g_free (msg);
gdm_verify_cleanup (d);
session_started = FALSE;
return;
}
yesno_msg = g_strdup_printf ("yesno_msg=%s", msg);
gdm_slave_send_string (GDM_SOP_SHOW_YESNO_DIALOG, yesno_msg);
g_free (yesno_msg);
if (strcmp (gdm_ack_response, "no") == 0) {
gdm_verify_cleanup (d);
session_started = FALSE;
g_free (msg);
g_free (gdm_ack_response);
gdm_ack_response = NULL;
return;
}
g_free (msg);
g_free (gdm_ack_response);
gdm_ack_response = NULL;
/* Reset euid, egid back to user */
if G_UNLIKELY (setegid (pwent->pw_gid) != 0 ||
......@@ -4353,24 +4407,31 @@ gdm_slave_session_start (void)
(end_time - 10 <= session_start_time) &&
/* only if the X server still exist! */
d->servpid > 1) {
gdm_debug ("Session less than 10 seconds!");
char *msg_string;
char *error_msg =
_("Your session only lasted less than "
"10 seconds. If you have not logged out "
"yourself, this could mean that there is "
"some installation problem or that you may "
"be out of diskspace. Try logging in with "
"one of the failsafe sessions to see if you "
"can fix this problem.");
/* 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 than "
"10 seconds. If you have not logged out "
"yourself, this could mean that there is "
"some installation problem or that you may "
"be out of diskspace. Try logging in with "
"one of the failsafe sessions to see if you "
"can fix this problem."),
(d->xsession_errors_filename != NULL) ?
_("View details (~/.xsession-errors file)") :
NULL,
d->xsession_errors_filename,
uid, gid);
gdm_debug ("Session less than 10 seconds!");
msg_string = g_strdup_printf ("type=%d$$error_msg=%s$$details_label=%s$$details_file=%s$$uid=%d$$gid=%d",
GTK_MESSAGE_WARNING,error_msg,
(d->xsession_errors_filename != NULL) ?
_("View details (~/.xsession-errors file)") :
NULL,
d->xsession_errors_filename,
0, 0);
gdm_slave_send_string (GDM_SOP_SHOW_ERROR_DIALOG, msg_string);
g_free (msg_string);
}
gdm_slave_session_stop (pid != 0 /* run_post_session */,
......@@ -4841,6 +4902,28 @@ gdm_slave_handle_usr2_message (void)
} else if (strcmp (&s[1], GDM_NOTIFY_TWIDDLE_POINTER) == 0) {
gdm_twiddle_pointer (d);
}
} else if (s[0] == GDM_SLAVE_NOTIFY_RESPONSE) {
gdm_got_ack = TRUE;
if (gdm_ack_response)
g_free (gdm_ack_response);
if (s[1] == GDM_SLAVE_NOTIFY_YESNO_RESPONSE) {
if (s[2] == '0') {
gdm_ack_response = g_strdup ("no");
} else {
gdm_ack_response = g_strdup ("yes");
}
} else if (s[1] == GDM_SLAVE_NOTIFY_ASKBUTTONS_RESPONSE) {
gdm_ack_response = g_strdup (&s[2]);
} else if (s[1] == GDM_SLAVE_NOTIFY_QUESTION_RESPONSE) {
gdm_ack_question_response = g_strdup (&s[2]);
} else if (s[1] == GDM_SLAVE_NOTIFY_ERROR_RESPONSE) {
if (s[2] != '\0') {
gdm_ack_response = g_strdup (&s[2]);
} else {
gdm_ack_response = NULL;
}
}
}
}
......
......@@ -63,6 +63,8 @@ static char *selected_user = NULL;
static gboolean opened_session = FALSE;
static gboolean did_setcred = FALSE;
extern char *gdm_ack_question_response;
#ifdef HAVE_ADT
#define PW_FALSE 1 /* no password change */
#define PW_TRUE 2 /* successful password change */
......@@ -631,7 +633,8 @@ gdm_verify_standalone_pam_conv (int num_msg, struct pam_message **msg,
{
int replies = 0;
int i;
char *s, *text;
char *text;
char *question_msg;
struct pam_response *reply = NULL;
if (pamh == NULL)
......@@ -652,38 +655,53 @@ gdm_verify_standalone_pam_conv (int num_msg, struct pam_message **msg,
case PAM_PROMPT_ECHO_ON:
if (extra_standalone_message != NULL)
text = g_strdup_printf
("%s\n%s", extra_standalone_message,
("%s%s", extra_standalone_message,
m);
else
text = g_strdup (m);
/* PAM requested textual input with echo on */
s = gdm_failsafe_question (cur_gdm_disp, text,
TRUE /* echo */);
question_msg = g_strdup_printf ("question_msg=%s$$echo=%d", text, TRUE);
gdm_slave_send_string (GDM_SOP_SHOW_QUESTION_DIALOG, question_msg);
g_free (question_msg);
g_free (text);
reply[replies].resp_retcode = PAM_SUCCESS;
reply[replies].resp = strdup (ve_sure_string (s));
g_free (s);