From 967603c6823180b055c6f1b5e76b05c377076eda 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/Makefile.am | 1 + data/org.freedesktop.realmd.xml | 730 ++++++++++++++++++++++++++++++++ src/Makefile.am | 5 + src/daemon.c | 61 ++- src/org.freedesktop.realmd.xml | 730 ++++++++++++++++++++++++++++++++ 5 files changed, 1523 insertions(+), 4 deletions(-) create mode 100644 data/org.freedesktop.realmd.xml create mode 100644 src/org.freedesktop.realmd.xml diff --git a/data/Makefile.am b/data/Makefile.am index 521c6c2..6cf5e30 100644 --- a/data/Makefile.am +++ b/data/Makefile.am @@ -7,38 +7,39 @@ dbusif_DATA = \ dbusconfdir = $(sysconfdir)/dbus-1/system.d dbusconf_DATA = org.freedesktop.Accounts.conf servicedir = $(datadir)/dbus-1/system-services service_in_files = org.freedesktop.Accounts.service.in service_DATA = $(service_in_files:.service.in=.service) $(service_DATA): $(service_in_files) Makefile @sed -e "s|\@libexecdir\@|$(libexecdir)|" $< >$@ policydir = $(datadir)/polkit-1/actions policy_in_files = org.freedesktop.accounts.policy.in policy_DATA = $(policy_in_files:.policy.in=.policy) @INTLTOOL_POLICY_RULE@ if HAVE_SYSTEMD systemdsystemunit_DATA = \ accounts-daemon.service accounts-daemon.service: accounts-daemon.service.in @sed -e "s|\@libexecdir\@|$(libexecdir)|" $< >$@ endif EXTRA_DIST = \ $(dbusif_DATA) \ $(dbusconf_DATA) \ $(service_in_files) \ $(policy_in_files) \ + org.freedesktop.realmd.xml \ accounts-daemon.service.in DISTCLEANFILES = \ $(service_DATA) \ $(policy_DATA) CLEANFILES = \ accounts-daemon.service 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/Makefile.am b/src/Makefile.am index f53e3e1..7a5b382 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,59 +1,64 @@ NULL = BUILT_SOURCES = SUBDIRS = . libaccountsservice INCLUDES = \ -DLOCALSTATEDIR=\""$(localstatedir)"\" \ -DDATADIR=\""$(datadir)"\" \ -DICONDIR=\"$(localstatedir)/lib/AccountsService/icons\" \ -DUSERDIR=\"$(localstatedir)/lib/AccountsService/users\" \ -I$(srcdir) \ -I$(builddir) \ $(ACCOUNTS_DAEMON_CFLAGS) \ $(WARN_CFLAGS) noinst_LTLIBRARIES = libaccounts-generated.la libaccounts_generated_la_SOURCES = \ accounts-generated.c \ accounts-generated.h \ accounts-user-generated.c \ accounts-user-generated.h \ + realmd-generated.c \ + realmd-generated.h \ $(NULL) BUILT_SOURCES += $(libaccounts_generated_la_SOURCES) accounts-generated.c accounts-generated.h: $(top_srcdir)/data/org.freedesktop.Accounts.xml Makefile gdbus-codegen --generate-c-code accounts-generated --c-namespace Accounts --interface-prefix=org.freedesktop. $(top_srcdir)/data/org.freedesktop.Accounts.xml accounts-user-generated.c accounts-user-generated.h: $(top_srcdir)/data/org.freedesktop.Accounts.User.xml Makefile gdbus-codegen --generate-c-code accounts-user-generated --c-namespace Accounts --interface-prefix=org.freedesktop.Accounts. $(top_srcdir)/data/org.freedesktop.Accounts.User.xml +realmd-generated.c realmd-generated.h: $(top_srcdir)/data/org.freedesktop.realmd.xml Makefile + gdbus-codegen --c-generate-autocleanup all --c-generate-object-manager --generate-c-code realmd-generated --c-namespace Accounts --interface-prefix=org.freedesktop. $(top_srcdir)/data/org.freedesktop.realmd.xml + libexec_PROGRAMS = accounts-daemon accounts_daemon_SOURCES = \ $(enums_h_sources) \ types.h \ daemon.h \ daemon.c \ extensions.c \ user-classify.h \ user-classify.c \ user.h \ user.c \ util.h \ util.c \ wtmp-helper.h \ wtmp-helper.c \ main.c accounts_daemon_LDADD = \ libaccounts-generated.la \ $(ACCOUNTS_DAEMON_LIBS) EXTRA_DIST = \ fgetpwent.c \ $(NULL) CLEANFILES = \ $(BUILT_SOURCES) \ *.gcda \ *.gcno \ diff --git a/src/daemon.c b/src/daemon.c index 00dff51..23e60ce 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 }; struct DaemonPrivate { 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; guint reload_id; guint autologin_id; PolkitAuthority *authority; GHashTable *extension_ifaces; @@ -414,109 +415,164 @@ 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) +{ + g_autoptr (GError) error = NULL; + + if (daemon->priv->bus_connection != NULL) + return TRUE; + + daemon->priv->bus_connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); + if (daemon->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) +{ + 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 (daemon->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) { 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 = daemon->priv->users; daemon->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); @@ -733,64 +789,61 @@ daemon_finalize (GObject *object) Daemon *daemon; g_return_if_fail (IS_DAEMON (object)); daemon = DAEMON (object); if (daemon->priv->bus_connection != NULL) g_object_unref (daemon->priv->bus_connection); g_list_free_full (daemon->priv->explicitly_requested_users, g_free); g_hash_table_destroy (daemon->priv->users); g_hash_table_unref (daemon->priv->extension_ifaces); G_OBJECT_CLASS (daemon_parent_class)->finalize (object); } static gboolean register_accounts_daemon (Daemon *daemon) { g_autoptr(GError) error = NULL; daemon->priv->authority = polkit_authority_get_sync (NULL, &error); if (daemon->priv->authority == NULL) { if (error != NULL) g_critical ("error getting polkit authority: %s", error->message); return FALSE; } - daemon->priv->bus_connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); - if (daemon->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), 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/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.21.0