diff options
author | Matthias Clasen <mclasen@redhat.com> | 2011-05-19 21:30:30 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2011-10-21 02:16:06 -0400 |
commit | 0a274f874af12ec4de5ed8e0f9012f52392e24b6 (patch) | |
tree | 379c063b41477f0f8b05def58b3a21325ced8e70 | |
parent | b925c76ac7725283c45cfa9ab3cc8751c5e3b736 (diff) | |
download | gdm-0a274f874af12ec4de5ed8e0f9012f52392e24b6.tar.gz |
Slave: First attempt at running setup as a separate user
-rw-r--r-- | daemon/Makefile.am | 1 | ||||
-rw-r--r-- | daemon/gdm-simple-slave.c | 124 | ||||
-rw-r--r-- | daemon/gdm-slave.c | 15 |
3 files changed, 132 insertions, 8 deletions
diff --git a/daemon/Makefile.am b/daemon/Makefile.am index 588bf3b4..c4f9b8b8 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -12,6 +12,7 @@ AM_CPPFLAGS = \ -DGDMCONFDIR=\"$(gdmconfdir)\" \ -DLIBDIR=\"$(libdir)\" \ -DLIBEXECDIR=\"$(libexecdir)\" \ + -DLOCALSTATEDIR=\"$(localstatedir)\" \ -DLOGDIR=\"$(logdir)\" \ -DSBINDIR=\"$(sbindir)\" \ -DGNOMELOCALEDIR=\""$(datadir)/locale"\" \ diff --git a/daemon/gdm-simple-slave.c b/daemon/gdm-simple-slave.c index 8534d718..4a5bcb1d 100644 --- a/daemon/gdm-simple-slave.c +++ b/daemon/gdm-simple-slave.c @@ -38,6 +38,8 @@ #include <glib/gstdio.h> #include <glib-object.h> +#include <act/act-user-manager.h> + #define DBUS_API_SUBJECT_TO_CHANGE #include <dbus/dbus-glib.h> #include <dbus/dbus-glib-lowlevel.h> @@ -1201,7 +1203,7 @@ start_greeter (GdmSimpleSlave *slave) char *display_hostname; char *auth_file; char *address; - gboolean res; + gboolean res G_GNUC_UNUSED; g_debug ("GdmSimpleSlave: Running greeter"); @@ -1338,12 +1340,115 @@ start_greeter (GdmSimpleSlave *slave) g_free (auth_file); } +static const gboolean +create_initial_setup_user (GdmSimpleSlave *slave) +{ + ActUserManager *act; + ActUser *user; + GError *error; + const gchar *username; + gboolean preexisting_user; + const gchar *src_filename; + const gchar *dest_filename; + + username = "gdm-initial-setup"; + src_filename = DATADIR "/gdm/" "20-gdm-initial-setup.pkla"; + dest_filename = LOCALSTATEDIR "/lib/polkit-1/localauthority/10-vendor.d/" "20-gdm-initial-setup.pkla"; + + preexisting_user = FALSE; + + /* First, create the user */ + act = act_user_manager_get_default (); + + error = NULL; + user = act_user_manager_create_user (act, username, "", 0, &error); + if (user == NULL) { + const gchar *e; + if (error->domain == DBUS_GERROR && + error->code == DBUS_GERROR_REMOTE_EXCEPTION) + e = dbus_g_error_get_name (error); + else + e = NULL; + + g_warning ("Creating user '%s' failed: %s / %s", username, e, error->message); + + if (g_strcmp0 (e, "org.freedesktop.Accounts.Error.UserExists") == 0) { + preexisting_user = TRUE; + } + else { + return FALSE; + } + } + else { + g_object_unref (user); + } + + /* Now, make sure the PolicyKit policy is in place */ + if (preexisting_user) { + if (!g_file_test (dest_filename, G_FILE_TEST_EXISTS)) { + g_warning ("User '%s' exists, but file '%s' doesn't", username, dest_filename); + return FALSE; + } + } + else { + gchar *contents; + gsize length; + GError *error; + + contents = NULL; + error = NULL; + if (!g_file_get_contents (src_filename, &contents, &length, &error)) { + g_warning ("Failed to read '%s': %s", src_filename, error->message); + g_error_free (error); + return FALSE; + } + if (!g_file_set_contents (dest_filename, contents, length, &error)) { + g_warning ("Failed to write '%s': %s", dest_filename, error->message); + g_error_free (error); + g_free (contents); + return FALSE; + } + g_free (contents); + } + + return TRUE; +} + +static void +remove_initial_setup_user (GdmSimpleSlave *slave) +{ + ActUserManager *act; + ActUser *user; + const gchar *username; + const gchar *filename; + GError *error; + + username = "gdm-initial-setup"; + filename = LOCALSTATEDIR "/lib/polkit-1/localauthority/10-vendor.d/" "20-gdm-initial-setup.pkla"; + + if (g_remove (filename) < 0) { + g_warning ("Failed to remove '%s': %s", filename, g_strerror (errno)); + } + + act = act_user_manager_get_default (); + + error = NULL; + user = act_user_manager_get_user (act, username); + if (!act_user_manager_delete_user (act, user, TRUE, &error)) { + g_warning ("Failed to create user '%s': %s", username, error->message); + g_error_free (error); + } + + g_object_unref (user); +} + static void on_setup_session_stop (GdmGreeterSession *greeter, GdmSimpleSlave *slave) { g_debug ("GdmSimpleSlave: Setup stopped"); clear_initial_setup_request (slave); + remove_initial_setup_user (slave); gdm_slave_stopped (GDM_SLAVE (slave)); } static void @@ -1357,7 +1462,7 @@ run_initial_setup (GdmSimpleSlave *slave) char *display_hostname; char *auth_file; char *address; - gboolean res; + gboolean res G_GNUC_UNUSED; g_debug ("GdmSimpleSlave: Running initial setup"); @@ -1399,6 +1504,13 @@ run_initial_setup (GdmSimpleSlave *slave) gdm_slave_run_script (GDM_SLAVE (slave), GDMCONFDIR "/Init", GDM_USERNAME); slave->priv->greeter_server = gdm_greeter_server_new (display_id); + + /* tell the greeter_server which user to expect a call from */ + g_object_set (slave->priv->greeter_server, + "user-name", "gdm-initial-setup", + "group-name", "gdm-initial-setup", + NULL); + g_signal_connect (slave->priv->greeter_server, "begin-auto-login", G_CALLBACK (on_greeter_begin_auto_login), @@ -1457,6 +1569,7 @@ run_initial_setup (GdmSimpleSlave *slave) display_device, display_hostname, display_is_local); + g_signal_connect (slave->priv->greeter, "started", G_CALLBACK (on_greeter_session_start), @@ -1473,7 +1586,10 @@ run_initial_setup (GdmSimpleSlave *slave) "died", G_CALLBACK (on_greeter_session_died), slave); + + /* tell the greeter which user to run as */ g_object_set (slave->priv->greeter, + "user-name", "gdm-initial-setup", "x11-authority-file", auth_file, NULL); @@ -1510,7 +1626,7 @@ clear_initial_setup_request (GdmSimpleSlave *slave) filename = GDMCONFDIR "/run-initial-setup"; if (g_remove (filename) < 0) { - g_warning ("Failed to remove %s", filename); + g_warning ("Failed to remove %s: %s", filename, strerror (errno)); } } @@ -1527,7 +1643,6 @@ idle_connect_to_display (GdmSimpleSlave *slave) int timed_login_delay; gboolean initial_setup_enabled; gboolean initial_setup_requested; - const gchar *filename; /* FIXME: handle wait-for-go */ @@ -1542,6 +1657,7 @@ idle_connect_to_display (GdmSimpleSlave *slave) timed_login_enabled = FALSE; gdm_slave_get_timed_login_details (GDM_SLAVE (slave), &timed_login_enabled, NULL, &timed_login_delay); if (initial_setup_enabled && initial_setup_requested) { + create_initial_setup_user (slave); run_initial_setup (slave); create_new_session (slave); } else if (! timed_login_enabled || timed_login_delay > 0) { diff --git a/daemon/gdm-slave.c b/daemon/gdm-slave.c index 33a22eb1..3052961c 100644 --- a/daemon/gdm-slave.c +++ b/daemon/gdm-slave.c @@ -456,11 +456,15 @@ gdm_slave_setup_xhost_auth (XHostAddress *host_entries, XServerInterpretedAddres si_entries[0].typelength = strlen ("localuser"); si_entries[1].type = "localuser"; si_entries[1].typelength = strlen ("localuser"); + si_entries[2].type = "localuser"; + si_entries[2].typelength = strlen ("localuser"); si_entries[0].value = "root"; si_entries[0].valuelength = strlen ("root"); si_entries[1].value = GDM_USERNAME; si_entries[1].valuelength = strlen (GDM_USERNAME); + si_entries[2].value = "gdm-initial-setup"; + si_entries[2].valuelength = strlen ("gdm-initial-setup"); host_entries[0].family = FamilyServerInterpreted; host_entries[0].address = (char *) &si_entries[0]; @@ -468,6 +472,9 @@ gdm_slave_setup_xhost_auth (XHostAddress *host_entries, XServerInterpretedAddres host_entries[1].family = FamilyServerInterpreted; host_entries[1].address = (char *) &si_entries[1]; host_entries[1].length = sizeof (XServerInterpretedAddress); + host_entries[2].family = FamilyServerInterpreted; + host_entries[2].address = (char *) &si_entries[2]; + host_entries[2].length = sizeof (XServerInterpretedAddress); } static void @@ -583,8 +590,8 @@ gdm_slave_connect_to_x11_display (GdmSlave *slave) g_warning ("Unable to connect to display %s", slave->priv->display_name); ret = FALSE; } else if (slave->priv->display_is_local) { - XServerInterpretedAddress si_entries[2]; - XHostAddress host_entries[2]; + XServerInterpretedAddress si_entries[3]; + XHostAddress host_entries[3]; g_debug ("GdmSlave: Connected to display %s", slave->priv->display_name); ret = TRUE; @@ -898,8 +905,8 @@ gdm_slave_add_user_authorization (GdmSlave *slave, const char *username, char **filenamep) { - XServerInterpretedAddress si_entries[2]; - XHostAddress host_entries[2]; + XServerInterpretedAddress si_entries[3]; + XHostAddress host_entries[3]; gboolean res; GError *error; char *filename; |