From 781e865705b0c134271c9ec21655cd5d8ce37fec Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
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