summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog29
-rw-r--r--daemon/Makefile.am2
-rw-r--r--daemon/gdm-greeter-server.c20
-rw-r--r--daemon/gdm-greeter-server.h4
-rw-r--r--daemon/gdm-session-direct.c56
-rw-r--r--daemon/gdm-session-private.h6
-rw-r--r--daemon/gdm-session-worker.c99
-rw-r--r--daemon/gdm-session.c43
-rw-r--r--daemon/gdm-session.h5
-rw-r--r--daemon/gdm-simple-slave.c29
10 files changed, 289 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 68cdc96d..e8e7fcb4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,32 @@
+2008-02-18 Ray Strode <rstrode@redhat.com>
+
+ Read ~/.dmrc when available, and bubble the
+ results up to the greeter
+
+ * daemon/Makefile.am: add gdm-session-settings.[ch] to
+ worker sources
+ * daemon/gdm-session-private.h:
+ * daemon/gdm-session.[ch]:
+ (_gdm_session_saved_language_name_read),
+ (_gdm_session_saved_session_name_read),
+ (gdm_session_class_init):
+ Add two new signals: "saved-language-name-read"
+ and "saved-session-name-read"
+ * daemon/gdm-session-worker.c (GdmSessionWorkerPrivate):
+ session settings object to hold ~/.dmrc info.
+ (attempt_to_load_user_settings_as_root): new function
+ to switch from root to user, load settings, and switch
+ back
+ (do_setup), (gdm_session_worker_update_username):
+ Create session settings object, and try to load ~/.dmrc
+ in to object at various points in the pam conversation.
+ (on_saved_language_name_read), (on_saved_session_name_read):
+ report session settings changes from worker to slave
+ * daemon/gdm-greeter-server.[ch]:
+ (gdm_greeter_server_saved_language_name_read),
+ (gdm_greeter_server_saved_session_name_read),
+ (do_introspect): send language and session name to greeter
+
2008-02-18 William Jon McCann <jmccann@redhat.com>
* gui/simple-greeter/gdm-language-option-widget.c:
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index 93b18cf2..03b7e83f 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -244,6 +244,8 @@ gdm_xdmcp_chooser_slave_LDADD = \
gdm_session_worker_SOURCES = \
session-worker-main.c \
+ gdm-session-settings.h \
+ gdm-session-settings.c \
gdm-session-auditor.h \
gdm-session-auditor.c \
gdm-session-worker.h \
diff --git a/daemon/gdm-greeter-server.c b/daemon/gdm-greeter-server.c
index db568d7d..2fa8a8f2 100644
--- a/daemon/gdm-greeter-server.c
+++ b/daemon/gdm-greeter-server.c
@@ -221,6 +221,20 @@ gdm_greeter_server_selected_user_changed (GdmGreeterServer *greeter_server,
send_dbus_string_signal (greeter_server, "SelectedUserChanged", username);
}
+void
+gdm_greeter_server_saved_language_name_read (GdmGreeterServer *greeter_server,
+ const char *language_name)
+{
+ send_dbus_string_signal (greeter_server, "SavedLanguageNameRead", language_name);
+}
+
+void
+gdm_greeter_server_saved_session_name_read (GdmGreeterServer *greeter_server,
+ const char *session_name)
+{
+ send_dbus_string_signal (greeter_server, "SavedSessionNameRead", session_name);
+}
+
/* Note: Use abstract sockets like dbus does by default on Linux. Abstract
* sockets are only available on Linux.
*/
@@ -576,6 +590,12 @@ do_introspect (DBusConnection *connection,
" <signal name=\"SelectedUserChanged\">\n"
" <arg name=\"username\" type=\"s\"/>\n"
" </signal>\n"
+ " <signal name=\"SavedLanguageNameRead\">\n"
+ " <arg name=\"language_name\" type=\"s\"/>\n"
+ " </signal>\n"
+ " <signal name=\"SavedSessionNameRead\">\n"
+ " <arg name=\"session_name\" type=\"s\"/>\n"
+ " </signal>\n"
" <signal name=\"Ready\">\n"
" </signal>\n"
" <signal name=\"Reset\">\n"
diff --git a/daemon/gdm-greeter-server.h b/daemon/gdm-greeter-server.h
index 1b9ef288..c37a43ab 100644
--- a/daemon/gdm-greeter-server.h
+++ b/daemon/gdm-greeter-server.h
@@ -83,6 +83,10 @@ gboolean gdm_greeter_server_reset (GdmGreeterServer *
gboolean gdm_greeter_server_ready (GdmGreeterServer *greeter_server);
void gdm_greeter_server_selected_user_changed (GdmGreeterServer *greeter_server,
const char *text);
+void gdm_greeter_server_saved_language_name_read (GdmGreeterServer *greeter_server,
+ const char *text);
+void gdm_greeter_server_saved_session_name_read (GdmGreeterServer *greeter_server,
+ const char *text);
G_END_DECLS
diff --git a/daemon/gdm-session-direct.c b/daemon/gdm-session-direct.c
index 46277f67..e3c258a0 100644
--- a/daemon/gdm-session-direct.c
+++ b/daemon/gdm-session-direct.c
@@ -775,6 +775,58 @@ gdm_session_direct_handle_session_died (GdmSessionDirect *session,
}
static DBusHandlerResult
+gdm_session_direct_handle_saved_language_name_read (GdmSessionDirect *session,
+ DBusConnection *connection,
+ DBusMessage *message)
+{
+ DBusMessage *reply;
+ DBusError error;
+ const char *language_name;
+ int code;
+
+ dbus_error_init (&error);
+ if (! dbus_message_get_args (message, &error,
+ DBUS_TYPE_STRING, &language_name,
+ DBUS_TYPE_INVALID)) {
+ g_warning ("ERROR: %s", error.message);
+ }
+
+ reply = dbus_message_new_method_return (message);
+ dbus_connection_send (connection, reply, NULL);
+ dbus_message_unref (reply);
+
+ _gdm_session_saved_language_name_read (GDM_SESSION (session), language_name);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static DBusHandlerResult
+gdm_session_direct_handle_saved_session_name_read (GdmSessionDirect *session,
+ DBusConnection *connection,
+ DBusMessage *message)
+{
+ DBusMessage *reply;
+ DBusError error;
+ const char *session_name;
+ int code;
+
+ dbus_error_init (&error);
+ if (! dbus_message_get_args (message, &error,
+ DBUS_TYPE_STRING, &session_name,
+ DBUS_TYPE_INVALID)) {
+ g_warning ("ERROR: %s", error.message);
+ }
+
+ reply = dbus_message_new_method_return (message);
+ dbus_connection_send (connection, reply, NULL);
+ dbus_message_unref (reply);
+
+ _gdm_session_saved_session_name_read (GDM_SESSION (session), session_name);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static DBusHandlerResult
session_worker_message (DBusConnection *connection,
DBusMessage *message,
void *user_data)
@@ -821,6 +873,10 @@ session_worker_message (DBusConnection *connection,
return gdm_session_direct_handle_session_exited (session, connection, message);
} else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SessionDied")) {
return gdm_session_direct_handle_session_died (session, connection, message);
+ } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SavedLanguageNameRead")) {
+ return gdm_session_direct_handle_saved_language_name_read (session, connection, message);
+ } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SavedSessionNameRead")) {
+ return gdm_session_direct_handle_saved_session_name_read (session, connection, message);
}
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
diff --git a/daemon/gdm-session-private.h b/daemon/gdm-session-private.h
index af22f14b..491eab0d 100644
--- a/daemon/gdm-session-private.h
+++ b/daemon/gdm-session-private.h
@@ -52,7 +52,11 @@ void _gdm_session_session_died (GdmSession *sessio
int signal_number);
void _gdm_session_closed (GdmSession *session);
-
+/* user settings read from ~/.dmrc */
+void _gdm_session_saved_language_name_read (GdmSession *session,
+ const char *language_name);
+void _gdm_session_saved_session_name_read (GdmSession *session,
+ const char *session_name);
/* user is selected/changed internally */
void _gdm_session_selected_user_changed (GdmSession *session,
const char *text);
diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c
index 66e045ed..4f2a50ef 100644
--- a/daemon/gdm-session-worker.c
+++ b/daemon/gdm-session-worker.c
@@ -54,6 +54,8 @@
#include "gdm-session-auditor.h"
#endif
+#include "gdm-session-settings.h"
+
#define GDM_SESSION_WORKER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_SESSION_WORKER, GdmSessionWorkerPrivate))
#define GDM_SESSION_DBUS_PATH "/org/gnome/DisplayManager/Session"
@@ -119,7 +121,8 @@ struct GdmSessionWorkerPrivate
char *server_address;
DBusConnection *connection;
- GdmSessionAuditor *auditor;
+ GdmSessionAuditor *auditor;
+ GdmSessionSettings *user_settings;
};
enum {
@@ -483,6 +486,39 @@ gdm_session_worker_get_username (GdmSessionWorker *worker,
}
static void
+attempt_to_load_user_settings_as_root (GdmSessionWorker *worker,
+ const char *username)
+{
+ struct passwd *passwd_entry;
+ uid_t old_uid;
+ gid_t old_gid;
+
+ old_uid = geteuid ();
+ old_gid = getegid ();
+
+ g_assert (old_uid == 0);
+ g_assert (old_gid == 0);
+
+ passwd_entry = getpwnam (username);
+
+ /* User input isn't a valid username
+ */
+ if (passwd_entry == NULL) {
+ return;
+ }
+
+ setegid (passwd_entry->pw_gid);
+ seteuid (passwd_entry->pw_uid);
+
+ gdm_session_settings_load (worker->priv->user_settings,
+ passwd_entry->pw_dir,
+ NULL);
+
+ seteuid (old_uid);
+ setegid (old_gid);
+}
+
+static void
gdm_session_worker_update_username (GdmSessionWorker *worker)
{
char *username;
@@ -497,6 +533,16 @@ gdm_session_worker_update_username (GdmSessionWorker *worker)
gdm_session_auditor_set_username (worker->priv->auditor, worker->priv->username);
+ /* We have a new username to try. If we haven't been able to
+ * read user settings up until now, then give it a go now
+ * (see the comment in do_setup for rationale on why it's useful
+ * to keep trying to read settings)
+ */
+ if (username != NULL &&
+ !gdm_session_settings_is_loaded (worker->priv->user_settings)) {
+ attempt_to_load_user_settings_as_root (worker, username);
+ }
+
if ((worker->priv->username == username) ||
((worker->priv->username != NULL) && (username != NULL) &&
(strcmp (worker->priv->username, username) == 0)))
@@ -1579,11 +1625,62 @@ on_set_environment_variable (GdmSessionWorker *worker,
}
static void
+on_saved_language_name_read (GdmSessionWorker *worker)
+{
+ char *language_name;
+
+ language_name = gdm_session_settings_get_language_name (worker->priv->user_settings);
+ send_dbus_string_method (worker->priv->connection,
+ "SavedLanguageNameRead",
+ language_name);
+ g_free (language_name);
+}
+
+static void
+on_saved_session_name_read (GdmSessionWorker *worker)
+{
+ char *session_name;
+
+ session_name = gdm_session_settings_get_session_name (worker->priv->user_settings);
+ send_dbus_string_method (worker->priv->connection,
+ "SavedSessionNameRead",
+ session_name);
+ g_free (session_name);
+}
+
+static void
do_setup (GdmSessionWorker *worker)
{
GError *error;
gboolean res;
+ worker->priv->user_settings = gdm_session_settings_new ();
+
+ g_signal_connect_swapped (worker->priv->user_settings,
+ "notify::language-name",
+ G_CALLBACK (on_saved_language_name_read),
+ worker);
+
+ g_signal_connect_swapped (worker->priv->user_settings,
+ "notify::session-name",
+ G_CALLBACK (on_saved_session_name_read),
+ worker);
+
+ /* In some setups the user can read ~/.dmrc at this point.
+ * In some other setups the user can only read ~/.dmrc after completing
+ * the pam conversation.
+ *
+ * The user experience is better if we can read .dmrc now since we can
+ * prefill in the language and session combo boxes in the greeter with
+ * the right values.
+ *
+ * We'll try now, and if it doesn't work out, try later.
+ */
+ if (worker->priv->username != NULL) {
+ attempt_to_load_user_settings_as_root (worker,
+ worker->priv->username);
+ }
+
error = NULL;
res = gdm_session_worker_initialize_pam (worker,
worker->priv->service,
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
index 99548915..34ae9392 100644
--- a/daemon/gdm-session.c
+++ b/daemon/gdm-session.c
@@ -49,6 +49,8 @@ enum {
SESSION_EXITED,
SESSION_DIED,
SELECTED_USER_CHANGED,
+ SAVED_LANGUAGE_NAME_READ,
+ SAVED_SESSION_NAME_READ,
LAST_SIGNAL
};
@@ -413,7 +415,28 @@ gdm_session_class_init (gpointer g_iface)
G_TYPE_NONE,
1,
G_TYPE_STRING);
-
+ signals [SAVED_LANGUAGE_NAME_READ] =
+ g_signal_new ("saved-language-name-read",
+ iface_type,
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GdmSessionIface, saved_language_name_read),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_STRING);
+ signals [SAVED_SESSION_NAME_READ] =
+ g_signal_new ("saved-session-name-read",
+ iface_type,
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GdmSessionIface, saved_session_name_read),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_STRING);
}
void
@@ -574,6 +597,24 @@ _gdm_session_closed (GdmSession *session)
}
void
+_gdm_session_saved_language_name_read (GdmSession *session,
+ const char *language_name)
+{
+ g_return_if_fail (GDM_IS_SESSION (session));
+
+ g_signal_emit (session, signals [SAVED_LANGUAGE_NAME_READ], 0, language_name);
+}
+
+void
+_gdm_session_saved_session_name_read (GdmSession *session,
+ const char *session_name)
+{
+ g_return_if_fail (GDM_IS_SESSION (session));
+
+ g_signal_emit (session, signals [SAVED_SESSION_NAME_READ], 0, session_name);
+}
+
+void
_gdm_session_selected_user_changed (GdmSession *session,
const char *text)
{
diff --git a/daemon/gdm-session.h b/daemon/gdm-session.h
index 50cf28bb..579f2590 100644
--- a/daemon/gdm-session.h
+++ b/daemon/gdm-session.h
@@ -102,7 +102,10 @@ struct _GdmSessionIface
void (* closed) (GdmSession *session);
void (* selected_user_changed) (GdmSession *session,
const char *text);
-
+ void (* saved_language_name_read) (GdmSession *session,
+ const char *text);
+ void (* saved_session_name_read) (GdmSession *session,
+ const char *text);
};
GType gdm_session_get_type (void) G_GNUC_CONST;
diff --git a/daemon/gdm-simple-slave.c b/daemon/gdm-simple-slave.c
index 59dab017..35bff1d0 100644
--- a/daemon/gdm-simple-slave.c
+++ b/daemon/gdm-simple-slave.c
@@ -373,6 +373,25 @@ on_session_selected_user_changed (GdmSession *session,
gdm_greeter_server_selected_user_changed (slave->priv->greeter_server, text);
}
+static void
+on_saved_language_name_read (GdmSession *session,
+ const char *text,
+ GdmSimpleSlave *slave)
+{
+ g_debug ("GdmSimpleSlave: Saved language name read: %s", text);
+
+ gdm_greeter_server_saved_language_name_read (slave->priv->greeter_server, text);
+}
+
+static void
+on_saved_session_name_read (GdmSession *session,
+ const char *text,
+ GdmSimpleSlave *slave)
+{
+ g_debug ("GdmSimpleSlave: Saved session name read: %s", text);
+
+ gdm_greeter_server_saved_session_name_read (slave->priv->greeter_server, text);
+}
static void
create_new_session (GdmSimpleSlave *slave)
@@ -488,6 +507,16 @@ create_new_session (GdmSimpleSlave *slave)
"selected-user-changed",
G_CALLBACK (on_session_selected_user_changed),
slave);
+
+ g_signal_connect (slave->priv->session,
+ "saved-language-name-read",
+ G_CALLBACK (on_saved_language_name_read),
+ slave);
+
+ g_signal_connect (slave->priv->session,
+ "saved-session-name-read",
+ G_CALLBACK (on_saved_session_name_read),
+ slave);
}
static void