[gdm/wip/initial-setup] First attempt at running setup as a separate user



commit 64ee0ed8b486d859efdbccc24f59da56b7f17743
Author: Matthias Clasen <mclasen redhat com>
Date:   Thu May 19 21:30:30 2011 -0400

    First attempt at running setup as a separate user

 daemon/Makefile.am        |    1 +
 daemon/gdm-simple-slave.c |  124 +++++++++++++++++++++++++++++++++++++++++++--
 daemon/gdm-slave.c        |   15 ++++--
 3 files changed, 132 insertions(+), 8 deletions(-)
---
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index 6f989c4..453868e 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 4976c91..88d36b0 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>
@@ -1124,7 +1126,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");
 
@@ -1257,12 +1259,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
@@ -1276,7 +1381,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");
 
@@ -1318,6 +1423,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),
@@ -1376,6 +1488,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),
@@ -1392,7 +1505,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);
 
@@ -1429,7 +1545,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));
         }
 }
 
@@ -1446,7 +1562,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 */
 
@@ -1461,6 +1576,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 33a22eb..3052961 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;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]