From 54b207649979475ea7f1fa5eaaea94be31d20935 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Fri, 13 Dec 2019 15:16:06 -0500 Subject: [PATCH] daemon: if no local users, check if machine is enrolled in network GDM will show gnome initial-setup if a machine has no local users. But it's totally possible that a machine has only remote users, and shouldn't have a local user. This commit detects that case, and avoids setting the HasNoUsers property. --- data/org.freedesktop.realmd.xml | 730 ++++++++++++++++++++++++++++++++ src/daemon.c | 63 ++- src/meson.build | 1 + src/org.freedesktop.realmd.xml | 730 ++++++++++++++++++++++++++++++++ 4 files changed, 1520 insertions(+), 4 deletions(-) create mode 100644 data/org.freedesktop.realmd.xml create mode 100644 src/org.freedesktop.realmd.xml diff --git a/data/org.freedesktop.realmd.xml b/data/org.freedesktop.realmd.xml new file mode 100644 index 0000000..c34a47a --- /dev/null +++ b/data/org.freedesktop.realmd.xml @@ -0,0 +1,730 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/daemon.c b/src/daemon.c index c52bda3..5ce0216 100644 --- a/src/daemon.c +++ b/src/daemon.c @@ -20,60 +20,61 @@ * Written by: Matthias Clasen */ #include "config.h" #include #include #include #include #include #include #include #ifdef HAVE_SHADOW_H #include #endif #include #include #include #include #include #include #include #include #include #include "user-classify.h" #include "wtmp-helper.h" #include "daemon.h" #include "util.h" +#include "realmd-generated.h" #define PATH_PASSWD "/etc/passwd" #define PATH_SHADOW "/etc/shadow" #define PATH_GROUP "/etc/group" enum { PROP_0, PROP_DAEMON_VERSION }; typedef struct { GDBusConnection *bus_connection; GHashTable *users; gsize number_of_normal_users; GList *explicitly_requested_users; User *autologin; GFileMonitor *passwd_monitor; GFileMonitor *shadow_monitor; GFileMonitor *group_monitor; GFileMonitor *gdm_monitor; GFileMonitor *wtmp_monitor; GQueue *pending_list_cached_users; guint reload_id; guint autologin_id; @@ -425,110 +426,167 @@ load_entries (Daemon *daemon, } else { g_object_ref (user); } /* freeze & update users not already in the new list */ g_object_freeze_notify (G_OBJECT (user)); user_update_from_pwent (user, pwent, spent); g_hash_table_insert (users, g_strdup (user_get_user_name (user)), user); g_debug ("loaded user: %s", user_get_user_name (user)); } if (!explicitly_requested) { user_set_cached (user, TRUE); } } /* Generator should have cleaned up */ g_assert (generator_state == NULL); } static GHashTable * create_users_hash_table (void) { return g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); } +static gboolean +ensure_bus_connection (Daemon *daemon) +{ + DaemonPrivate *priv = daemon_get_instance_private (daemon); + g_autoptr (GError) error = NULL; + + if (priv->bus_connection != NULL) + return TRUE; + + priv->bus_connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); + if (priv->bus_connection == NULL) { + if (error != NULL) + g_critical ("error getting system bus: %s", error->message); + return FALSE; + } + + return TRUE; +} + +static gboolean +has_network_realms (Daemon *daemon) +{ + DaemonPrivate *priv = daemon_get_instance_private (daemon); + g_autoptr (AccountsRealmdProvider) realmd_provider = NULL; + g_autoptr (GError) error = NULL; + const char *const *realms = NULL; + + if (!ensure_bus_connection (daemon)) { + return FALSE; + } + + realmd_provider = accounts_realmd_provider_proxy_new_sync (priv->bus_connection, + G_DBUS_PROXY_FLAGS_NONE, + "org.freedesktop.realmd", + "/org/freedesktop/realmd", + NULL, + &error); + if (realmd_provider == NULL) { + g_debug ("failed to contact realmd: %s", error->message); + return FALSE; + } + + realms = accounts_realmd_provider_get_realms (realmd_provider); + + if (!realms) { + g_debug("realmd provider 'Realms' property is unset"); + return FALSE; + } + + return realms[0] != NULL; +} + static void reload_users (Daemon *daemon) { DaemonPrivate *priv = daemon_get_instance_private (daemon); AccountsAccounts *accounts = ACCOUNTS_ACCOUNTS (daemon); gboolean had_no_users, has_no_users, had_multiple_users, has_multiple_users; GHashTable *users; GHashTable *old_users; GHashTable *local; GHashTableIter iter; gsize number_of_normal_users = 0; gpointer name, value; /* Track the users that we saw during our (re)load */ users = create_users_hash_table (); /* * NOTE: As we load data from all the sources, notifies are * frozen in load_entries() and then thawed as we process * them below. */ /* Load the local users into our hash table */ load_entries (daemon, users, FALSE, entry_generator_fgetpwent); local = g_hash_table_new (g_str_hash, g_str_equal); g_hash_table_iter_init (&iter, users); while (g_hash_table_iter_next (&iter, &name, NULL)) g_hash_table_add (local, name); /* and add users to hash table that were explicitly requested */ load_entries (daemon, users, TRUE, entry_generator_requested_users); /* Now add/update users from other sources, possibly non-local */ load_entries (daemon, users, FALSE, entry_generator_cachedir); wtmp_helper_update_login_frequencies (users); /* Count the non-system users. Mark which users are local, which are not. */ g_hash_table_iter_init (&iter, users); while (g_hash_table_iter_next (&iter, &name, &value)) { User *user = value; if (!user_get_system_account (user)) number_of_normal_users++; user_update_local_account_property (user, g_hash_table_lookup (local, name) != NULL); } g_hash_table_destroy (local); had_no_users = accounts_accounts_get_has_no_users (accounts); has_no_users = number_of_normal_users == 0; + if (has_no_users && has_network_realms (daemon)) { + g_debug ("No local users, but network realms detected, presuming there are remote users"); + has_no_users = FALSE; + } + if (had_no_users != has_no_users) accounts_accounts_set_has_no_users (accounts, has_no_users); had_multiple_users = accounts_accounts_get_has_multiple_users (accounts); has_multiple_users = number_of_normal_users > 1; if (had_multiple_users != has_multiple_users) accounts_accounts_set_has_multiple_users (accounts, has_multiple_users); /* Swap out the users */ old_users = priv->users; priv->users = users; /* Remove all the old users */ g_hash_table_iter_init (&iter, old_users); while (g_hash_table_iter_next (&iter, &name, &value)) { User *user = value; User *refreshed_user; refreshed_user = g_hash_table_lookup (users, name); if (!refreshed_user || (user_get_cached (user) && !user_get_cached (refreshed_user))) { accounts_accounts_emit_user_deleted (ACCOUNTS_ACCOUNTS (daemon), user_get_object_path (user)); user_unregister (user); } } /* Register all the new users */ g_hash_table_iter_init (&iter, users); @@ -766,64 +824,61 @@ daemon_finalize (GObject *object) priv = daemon_get_instance_private (daemon); if (priv->bus_connection != NULL) g_object_unref (priv->bus_connection); g_queue_free_full (priv->pending_list_cached_users, (GDestroyNotify) list_user_data_free); g_list_free_full (priv->explicitly_requested_users, g_free); g_hash_table_destroy (priv->users); g_hash_table_unref (priv->extension_ifaces); G_OBJECT_CLASS (daemon_parent_class)->finalize (object); } static gboolean register_accounts_daemon (Daemon *daemon) { DaemonPrivate *priv = daemon_get_instance_private (daemon); g_autoptr(GError) error = NULL; priv->authority = polkit_authority_get_sync (NULL, &error); if (priv->authority == NULL) { if (error != NULL) g_critical ("error getting polkit authority: %s", error->message); return FALSE; } - priv->bus_connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); - if (priv->bus_connection == NULL) { - if (error != NULL) - g_critical ("error getting system bus: %s", error->message); + if (!ensure_bus_connection (daemon)) { return FALSE; } if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (daemon), priv->bus_connection, "/org/freedesktop/Accounts", &error)) { if (error != NULL) g_critical ("error exporting interface: %s", error->message); return FALSE; } return TRUE; } Daemon * daemon_new (void) { g_autoptr(Daemon) daemon = NULL; daemon = DAEMON (g_object_new (TYPE_DAEMON, NULL)); if (!register_accounts_daemon (DAEMON (daemon))) { return NULL; } return g_steal_pointer (&daemon); } static void diff --git a/src/meson.build b/src/meson.build index 20d5276..3970749 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,37 +1,38 @@ sources = [] gdbus_headers = [] ifaces = [ ['accounts-generated', 'org.freedesktop.', 'Accounts'], ['accounts-user-generated', act_namespace + '.', 'User'], + ['realmd-generated', 'org.freedesktop.', 'realmd'], ] foreach iface: ifaces gdbus_sources = gnome.gdbus_codegen( iface[0], join_paths(data_dir, iface[1] + iface[2] + '.xml'), interface_prefix: iface[1], namespace: 'Accounts', ) sources += gdbus_sources gdbus_headers += gdbus_sources[1] endforeach deps = [ gio_dep, gio_unix_dep, ] cflags = [ '-DLOCALSTATEDIR="@0@"'.format(act_localstatedir), '-DDATADIR="@0@"'.format(act_datadir), '-DICONDIR="@0@"'.format(join_paths(act_localstatedir, 'lib', 'AccountsService', 'icons')), '-DUSERDIR="@0@"'.format(join_paths(act_localstatedir, 'lib', 'AccountsService', 'users')), ] libaccounts_generated = static_library( 'accounts-generated', sources: sources, include_directories: top_inc, dependencies: deps, diff --git a/src/org.freedesktop.realmd.xml b/src/org.freedesktop.realmd.xml new file mode 100644 index 0000000..c34a47a --- /dev/null +++ b/src/org.freedesktop.realmd.xml @@ -0,0 +1,730 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 2.27.0