Blame SOURCES/0001-display-ask-accountservice-if-there-are-users-rather.patch

4dd5a8
From 781e865705b0c134271c9ec21655cd5d8ce37fec Mon Sep 17 00:00:00 2001
4dd5a8
From: Ray Strode <rstrode@redhat.com>
4dd5a8
Date: Sat, 14 Dec 2019 13:50:53 -0500
4dd5a8
Subject: [PATCH] display: ask accountservice if there are users rather than
4dd5a8
 enumerate users
4dd5a8
4dd5a8
At the moment we ask accountsservice to give us the list of users just
4dd5a8
to find out if there is a list of users.
4dd5a8
4dd5a8
That's rather inefficient and might be wrong for directory server users
4dd5a8
that have never logged in before.
4dd5a8
4dd5a8
This commit changes gdm to ask accountsservice the question we really
4dd5a8
want to know the answer to; whether or not there are users.
4dd5a8
---
4dd5a8
 daemon/gdm-display.c | 55 ++++++++++++++++++--------------------------
4dd5a8
 1 file changed, 22 insertions(+), 33 deletions(-)
4dd5a8
4dd5a8
diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c
4dd5a8
index 878be88da..875534272 100644
4dd5a8
--- a/daemon/gdm-display.c
4dd5a8
+++ b/daemon/gdm-display.c
4dd5a8
@@ -57,62 +57,60 @@
4dd5a8
 struct GdmDisplayPrivate
4dd5a8
 {
4dd5a8
         char                 *id;
4dd5a8
         char                 *seat_id;
4dd5a8
         char                 *session_id;
4dd5a8
         char                 *session_class;
4dd5a8
         char                 *session_type;
4dd5a8
 
4dd5a8
         char                 *remote_hostname;
4dd5a8
         int                   x11_display_number;
4dd5a8
         char                 *x11_display_name;
4dd5a8
         int                   status;
4dd5a8
         time_t                creation_time;
4dd5a8
         GTimer               *server_timer;
4dd5a8
 
4dd5a8
         char                 *x11_cookie;
4dd5a8
         gsize                 x11_cookie_size;
4dd5a8
         GdmDisplayAccessFile *access_file;
4dd5a8
 
4dd5a8
         guint                 finish_idle_id;
4dd5a8
 
4dd5a8
         xcb_connection_t     *xcb_connection;
4dd5a8
         int                   xcb_screen_number;
4dd5a8
 
4dd5a8
         GDBusConnection      *connection;
4dd5a8
         GdmDisplayAccessFile *user_access_file;
4dd5a8
 
4dd5a8
         GdmDBusDisplay       *display_skeleton;
4dd5a8
         GDBusObjectSkeleton  *object_skeleton;
4dd5a8
 
4dd5a8
-        GDBusProxy           *accountsservice_proxy;
4dd5a8
-
4dd5a8
         /* this spawns and controls the greeter session */
4dd5a8
         GdmLaunchEnvironment *launch_environment;
4dd5a8
 
4dd5a8
         guint                 is_local : 1;
4dd5a8
         guint                 is_initial : 1;
4dd5a8
         guint                 allow_timed_login : 1;
4dd5a8
         guint                 have_existing_user_accounts : 1;
4dd5a8
         guint                 doing_initial_setup : 1;
4dd5a8
 };
4dd5a8
 
4dd5a8
 enum {
4dd5a8
         PROP_0,
4dd5a8
         PROP_ID,
4dd5a8
         PROP_STATUS,
4dd5a8
         PROP_SEAT_ID,
4dd5a8
         PROP_SESSION_ID,
4dd5a8
         PROP_SESSION_CLASS,
4dd5a8
         PROP_SESSION_TYPE,
4dd5a8
         PROP_REMOTE_HOSTNAME,
4dd5a8
         PROP_X11_DISPLAY_NUMBER,
4dd5a8
         PROP_X11_DISPLAY_NAME,
4dd5a8
         PROP_X11_COOKIE,
4dd5a8
         PROP_X11_AUTHORITY_FILE,
4dd5a8
         PROP_IS_CONNECTED,
4dd5a8
         PROP_IS_LOCAL,
4dd5a8
         PROP_LAUNCH_ENVIRONMENT,
4dd5a8
         PROP_IS_INITIAL,
4dd5a8
         PROP_ALLOW_TIMED_LOGIN,
4dd5a8
         PROP_HAVE_EXISTING_USER_ACCOUNTS,
4dd5a8
         PROP_DOING_INITIAL_SETUP,
4dd5a8
@@ -512,96 +510,88 @@ queue_finish (GdmDisplay *self)
4dd5a8
         if (self->priv->finish_idle_id == 0) {
4dd5a8
                 self->priv->finish_idle_id = g_idle_add ((GSourceFunc)finish_idle, self);
4dd5a8
         }
4dd5a8
 }
4dd5a8
 
4dd5a8
 static void
4dd5a8
 _gdm_display_set_status (GdmDisplay *self,
4dd5a8
                          int         status)
4dd5a8
 {
4dd5a8
         if (status != self->priv->status) {
4dd5a8
                 self->priv->status = status;
4dd5a8
                 g_object_notify (G_OBJECT (self), "status");
4dd5a8
         }
4dd5a8
 }
4dd5a8
 
4dd5a8
 static gboolean
4dd5a8
 gdm_display_real_prepare (GdmDisplay *self)
4dd5a8
 {
4dd5a8
         g_return_val_if_fail (GDM_IS_DISPLAY (self), FALSE);
4dd5a8
 
4dd5a8
         g_debug ("GdmDisplay: prepare display");
4dd5a8
 
4dd5a8
         _gdm_display_set_status (self, GDM_DISPLAY_PREPARED);
4dd5a8
 
4dd5a8
         return TRUE;
4dd5a8
 }
4dd5a8
 
4dd5a8
 static void
4dd5a8
 look_for_existing_users_sync (GdmDisplay *self)
4dd5a8
 {
4dd5a8
-        GError *error = NULL;
4dd5a8
-        GVariant *call_result;
4dd5a8
-        GVariant *user_list;
4dd5a8
-
4dd5a8
-        self->priv->accountsservice_proxy = g_dbus_proxy_new_sync (self->priv->connection,
4dd5a8
-                                                                   0, NULL,
4dd5a8
-                                                                   "org.freedesktop.Accounts",
4dd5a8
-                                                                   "/org/freedesktop/Accounts",
4dd5a8
-                                                                   "org.freedesktop.Accounts",
4dd5a8
-                                                                   NULL,
4dd5a8
-                                                                   &error);
4dd5a8
-
4dd5a8
-        if (!self->priv->accountsservice_proxy) {
4dd5a8
-                g_warning ("Failed to contact accountsservice: %s", error->message);
4dd5a8
-                goto out;
4dd5a8
-        }
4dd5a8
-
4dd5a8
-        call_result = g_dbus_proxy_call_sync (self->priv->accountsservice_proxy,
4dd5a8
-                                              "ListCachedUsers",
4dd5a8
-                                              NULL,
4dd5a8
-                                              0,
4dd5a8
+        g_autoptr (GVariant) result = NULL;
4dd5a8
+        g_autoptr (GVariant) result_child = NULL;
4dd5a8
+        g_autoptr (GError) error = NULL;
4dd5a8
+        gboolean has_no_users = FALSE;
4dd5a8
+
4dd5a8
+        result = g_dbus_connection_call_sync (self->priv->connection,
4dd5a8
+                                              "org.freedesktop.Accounts",
4dd5a8
+                                              "/org/freedesktop/Accounts",
4dd5a8
+                                              "org.freedesktop.DBus.Properties",
4dd5a8
+                                              "Get",
4dd5a8
+                                              g_variant_new ("(ss)", "org.freedesktop.Accounts", "HasNoUsers"),
4dd5a8
+                                              G_VARIANT_TYPE ("(v)"),
4dd5a8
+                                              G_DBUS_CALL_FLAGS_NONE,
4dd5a8
                                               -1,
4dd5a8
                                               NULL,
4dd5a8
                                               &error);
4dd5a8
 
4dd5a8
-        if (!call_result) {
4dd5a8
-                g_warning ("Failed to list cached users: %s", error->message);
4dd5a8
-                goto out;
4dd5a8
+        if (result == NULL) {
4dd5a8
+                g_warning ("Failed to contact accountsservice: %s", error->message);
4dd5a8
+                return;
4dd5a8
         }
4dd5a8
 
4dd5a8
-        g_variant_get (call_result, "(@ao)", &user_list);
4dd5a8
-        self->priv->have_existing_user_accounts = g_variant_n_children (user_list) > 0;
4dd5a8
-        g_variant_unref (user_list);
4dd5a8
-        g_variant_unref (call_result);
4dd5a8
-out:
4dd5a8
-        g_clear_error (&error);
4dd5a8
+        g_variant_get (result, "(v)", &result_child);
4dd5a8
+        has_no_users = g_variant_get_boolean (result_child);
4dd5a8
+        self->priv->have_existing_user_accounts = !has_no_users;
4dd5a8
+
4dd5a8
+        g_debug ("GdmDisplay: machine does %shave existing user accounts",
4dd5a8
+                 has_no_users? "not " : "");
4dd5a8
 }
4dd5a8
 
4dd5a8
 gboolean
4dd5a8
 gdm_display_prepare (GdmDisplay *self)
4dd5a8
 {
4dd5a8
         gboolean ret;
4dd5a8
 
4dd5a8
         g_return_val_if_fail (GDM_IS_DISPLAY (self), FALSE);
4dd5a8
 
4dd5a8
         g_debug ("GdmDisplay: Preparing display: %s", self->priv->id);
4dd5a8
 
4dd5a8
         /* FIXME: we should probably do this in a more global place,
4dd5a8
          * asynchronously
4dd5a8
          */
4dd5a8
         look_for_existing_users_sync (self);
4dd5a8
 
4dd5a8
         self->priv->doing_initial_setup = wants_initial_setup (self);
4dd5a8
 
4dd5a8
         g_object_ref (self);
4dd5a8
         ret = GDM_DISPLAY_GET_CLASS (self)->prepare (self);
4dd5a8
         g_object_unref (self);
4dd5a8
 
4dd5a8
         return ret;
4dd5a8
 }
4dd5a8
 
4dd5a8
 gboolean
4dd5a8
 gdm_display_manage (GdmDisplay *self)
4dd5a8
 {
4dd5a8
         gboolean res;
4dd5a8
 
4dd5a8
@@ -1332,61 +1322,60 @@ gdm_display_init (GdmDisplay *self)
4dd5a8
 
4dd5a8
         self->priv = GDM_DISPLAY_GET_PRIVATE (self);
4dd5a8
 
4dd5a8
         self->priv->creation_time = time (NULL);
4dd5a8
         self->priv->server_timer = g_timer_new ();
4dd5a8
 }
4dd5a8
 
4dd5a8
 static void
4dd5a8
 gdm_display_finalize (GObject *object)
4dd5a8
 {
4dd5a8
         GdmDisplay *self;
4dd5a8
 
4dd5a8
         g_return_if_fail (object != NULL);
4dd5a8
         g_return_if_fail (GDM_IS_DISPLAY (object));
4dd5a8
 
4dd5a8
         self = GDM_DISPLAY (object);
4dd5a8
 
4dd5a8
         g_return_if_fail (self->priv != NULL);
4dd5a8
 
4dd5a8
         g_debug ("GdmDisplay: Finalizing display: %s", self->priv->id);
4dd5a8
         g_free (self->priv->id);
4dd5a8
         g_free (self->priv->seat_id);
4dd5a8
         g_free (self->priv->session_class);
4dd5a8
         g_free (self->priv->remote_hostname);
4dd5a8
         g_free (self->priv->x11_display_name);
4dd5a8
         g_free (self->priv->x11_cookie);
4dd5a8
 
4dd5a8
         g_clear_object (&self->priv->display_skeleton);
4dd5a8
         g_clear_object (&self->priv->object_skeleton);
4dd5a8
         g_clear_object (&self->priv->connection);
4dd5a8
-        g_clear_object (&self->priv->accountsservice_proxy);
4dd5a8
 
4dd5a8
         if (self->priv->access_file != NULL) {
4dd5a8
                 g_object_unref (self->priv->access_file);
4dd5a8
         }
4dd5a8
 
4dd5a8
         if (self->priv->user_access_file != NULL) {
4dd5a8
                 g_object_unref (self->priv->user_access_file);
4dd5a8
         }
4dd5a8
 
4dd5a8
         if (self->priv->server_timer != NULL) {
4dd5a8
                 g_timer_destroy (self->priv->server_timer);
4dd5a8
         }
4dd5a8
 
4dd5a8
         G_OBJECT_CLASS (gdm_display_parent_class)->finalize (object);
4dd5a8
 }
4dd5a8
 
4dd5a8
 GDBusObjectSkeleton *
4dd5a8
 gdm_display_get_object_skeleton (GdmDisplay *self)
4dd5a8
 {
4dd5a8
         return self->priv->object_skeleton;
4dd5a8
 }
4dd5a8
 
4dd5a8
 static void
4dd5a8
 on_launch_environment_session_opened (GdmLaunchEnvironment *launch_environment,
4dd5a8
                                       GdmDisplay           *self)
4dd5a8
 {
4dd5a8
         char       *session_id;
4dd5a8
 
4dd5a8
         g_debug ("GdmDisplay: Greeter session opened");
4dd5a8
         session_id = gdm_launch_environment_get_session_id (launch_environment);
4dd5a8
-- 
4dd5a8
2.21.0
4dd5a8