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