Blame SOURCES/0001-daemon-Allow-SystemAccount-false-to-be-set-in-cache-.patch

70a90c
From 14c902f42a4ea74ce9450eb53817e1bf5be05d26 Mon Sep 17 00:00:00 2001
70a90c
From: Ray Strode <rstrode@redhat.com>
70a90c
Date: Wed, 8 Sep 2021 16:38:17 -0400
70a90c
Subject: [PATCH 1/2] daemon: Allow SystemAccount=false to be set in cache file
70a90c
70a90c
At the moment we do dodgy checks based on uid to decide whether or not
70a90c
an account is a system account.
70a90c
70a90c
For legacy reasons, sometimes normal users have really low UIDs.
70a90c
70a90c
This commit reshuffles things, so the cache file "wins" for deciding
70a90c
whether or not a user is a system user.
70a90c
---
70a90c
 src/daemon.c | 24 ++++++++++++------------
70a90c
 1 file changed, 12 insertions(+), 12 deletions(-)
70a90c
70a90c
diff --git a/src/daemon.c b/src/daemon.c
70a90c
index 66ac7ba..2b6650b 100644
70a90c
--- a/src/daemon.c
70a90c
+++ b/src/daemon.c
70a90c
@@ -219,60 +219,68 @@ entry_generator_fgetpwent (Daemon       *daemon,
70a90c
                 if (g_hash_table_size (shadow_users) == 0) {
70a90c
                         g_clear_pointer (&shadow_users, g_hash_table_unref);
70a90c
                         return NULL;
70a90c
                 }
70a90c
 
70a90c
                 fp = fopen (PATH_PASSWD, "r");
70a90c
                 if (fp == NULL) {
70a90c
                         g_clear_pointer (&shadow_users, g_hash_table_unref);
70a90c
                         g_warning ("Unable to open %s: %s", PATH_PASSWD, g_strerror (errno));
70a90c
                         return NULL;
70a90c
                 }
70a90c
 
70a90c
                 generator_state = g_malloc0 (sizeof (*generator_state));
70a90c
                 generator_state->fp = fp;
70a90c
                 generator_state->users = shadow_users;
70a90c
 
70a90c
                 *state = generator_state;
70a90c
         }
70a90c
 
70a90c
         /* Every iteration */
70a90c
         generator_state = *state;
70a90c
 
70a90c
         if (g_hash_table_size (users) < MAX_LOCAL_USERS) {
70a90c
                 pwent = fgetpwent (generator_state->fp);
70a90c
                 if (pwent != NULL) {
70a90c
                         shadow_entry_buffers = g_hash_table_lookup (generator_state->users, pwent->pw_name);
70a90c
 
70a90c
                         if (shadow_entry_buffers != NULL) {
70a90c
                             *spent = &shadow_entry_buffers->spbuf;
70a90c
                         }
70a90c
+
70a90c
+                        /* Skip system users... */
70a90c
+                        if (!user_classify_is_human (pwent->pw_uid, pwent->pw_name, pwent->pw_shell, (*spent)? (*spent)->sp_pwdp : NULL)) {
70a90c
+                                g_debug ("skipping user: %s", pwent->pw_name);
70a90c
+
70a90c
+                                return entry_generator_fgetpwent (daemon, users, state, spent);
70a90c
+                        }
70a90c
+
70a90c
                         return pwent;
70a90c
                 }
70a90c
         }
70a90c
 
70a90c
         /* Last iteration */
70a90c
         fclose (generator_state->fp);
70a90c
         g_hash_table_unref (generator_state->users);
70a90c
         g_free (generator_state);
70a90c
         *state = NULL;
70a90c
 
70a90c
         return NULL;
70a90c
 }
70a90c
 
70a90c
 static struct passwd *
70a90c
 entry_generator_cachedir (Daemon       *daemon,
70a90c
                           GHashTable   *users,
70a90c
                           gpointer     *state,
70a90c
                           struct spwd **shadow_entry)
70a90c
 {
70a90c
         struct passwd *pwent;
70a90c
         g_autoptr(GError) error = NULL;
70a90c
         gboolean regular;
70a90c
         GHashTableIter iter;
70a90c
         gpointer key, value;
70a90c
         GDir *dir;
70a90c
 
70a90c
         /* First iteration */
70a90c
         if (*state == NULL) {
70a90c
                 *state = g_dir_open (USERDIR, 0, &error);
70a90c
                 if (error != NULL) {
70a90c
@@ -373,66 +381,60 @@ entry_generator_requested_users (Daemon       *daemon,
70a90c
                         }
70a90c
                 }
70a90c
         }
70a90c
 
70a90c
         /* Last iteration */
70a90c
 
70a90c
         *state = NULL;
70a90c
         return NULL;
70a90c
 }
70a90c
 
70a90c
 static void
70a90c
 load_entries (Daemon             *daemon,
70a90c
               GHashTable         *users,
70a90c
               gboolean            explicitly_requested,
70a90c
               EntryGeneratorFunc  entry_generator)
70a90c
 {
70a90c
         DaemonPrivate *priv = daemon_get_instance_private (daemon);
70a90c
         gpointer generator_state = NULL;
70a90c
         struct passwd *pwent;
70a90c
         struct spwd *spent = NULL;
70a90c
         User *user = NULL;
70a90c
 
70a90c
         g_assert (entry_generator != NULL);
70a90c
 
70a90c
         for (;;) {
70a90c
                 spent = NULL;
70a90c
                 pwent = entry_generator (daemon, users, &generator_state, &spent);
70a90c
                 if (pwent == NULL)
70a90c
                         break;
70a90c
 
70a90c
-                /* Skip system users... */
70a90c
-                if (!explicitly_requested && !user_classify_is_human (pwent->pw_uid, pwent->pw_name, pwent->pw_shell, spent? spent->sp_pwdp : NULL)) {
70a90c
-                        g_debug ("skipping user: %s", pwent->pw_name);
70a90c
-                        continue;
70a90c
-                }
70a90c
-
70a90c
                 /* Only process users that haven't been processed yet.
70a90c
                  * We do always make sure entries get promoted
70a90c
                  * to "cached" status if they are supposed to be
70a90c
                  */
70a90c
 
70a90c
                 user = g_hash_table_lookup (users, pwent->pw_name);
70a90c
 
70a90c
                 if (user == NULL) {
70a90c
                         user = g_hash_table_lookup (priv->users, pwent->pw_name);
70a90c
                         if (user == NULL) {
70a90c
                                 user = user_new (daemon, pwent->pw_uid);
70a90c
                         } else {
70a90c
                                 g_object_ref (user);
70a90c
                         }
70a90c
 
70a90c
                         /* freeze & update users not already in the new list */
70a90c
                         g_object_freeze_notify (G_OBJECT (user));
70a90c
                         user_update_from_pwent (user, pwent, spent);
70a90c
 
70a90c
                         g_hash_table_insert (users, g_strdup (user_get_user_name (user)), user);
70a90c
                         g_debug ("loaded user: %s", user_get_user_name (user));
70a90c
                 }
70a90c
 
70a90c
                 if (!explicitly_requested) {
70a90c
                         user_set_cached (user, TRUE);
70a90c
                 }
70a90c
         }
70a90c
 
70a90c
         /* Generator should have cleaned up */
70a90c
         g_assert (generator_state == NULL);
70a90c
@@ -501,66 +503,66 @@ has_network_realms (Daemon *daemon)
70a90c
 
70a90c
 static void
70a90c
 reload_users (Daemon *daemon)
70a90c
 {
70a90c
         DaemonPrivate *priv = daemon_get_instance_private (daemon);
70a90c
         AccountsAccounts *accounts = ACCOUNTS_ACCOUNTS (daemon);
70a90c
         gboolean had_no_users, has_no_users, had_multiple_users, has_multiple_users;
70a90c
         GHashTable *users;
70a90c
         GHashTable *old_users;
70a90c
         GHashTable *local;
70a90c
         GHashTableIter iter;
70a90c
         gsize number_of_normal_users = 0;
70a90c
         gpointer name, value;
70a90c
 
70a90c
         /* Track the users that we saw during our (re)load */
70a90c
         users = create_users_hash_table ();
70a90c
 
70a90c
         /*
70a90c
          * NOTE: As we load data from all the sources, notifies are
70a90c
          * frozen in load_entries() and then thawed as we process
70a90c
          * them below.
70a90c
          */
70a90c
 
70a90c
         /* Load the local users into our hash table */
70a90c
         load_entries (daemon, users, FALSE, entry_generator_fgetpwent);
70a90c
         local = g_hash_table_new (g_str_hash, g_str_equal);
70a90c
         g_hash_table_iter_init (&iter, users);
70a90c
         while (g_hash_table_iter_next (&iter, &name, NULL))
70a90c
                 g_hash_table_add (local, name);
70a90c
 
70a90c
-        /* and add users to hash table that were explicitly requested  */
70a90c
-        load_entries (daemon, users, TRUE, entry_generator_requested_users);
70a90c
-
70a90c
         /* Now add/update users from other sources, possibly non-local */
70a90c
         load_entries (daemon, users, FALSE, entry_generator_cachedir);
70a90c
 
70a90c
+        /* and add users to hash table that were explicitly requested  */
70a90c
+        load_entries (daemon, users, TRUE, entry_generator_requested_users);
70a90c
+
70a90c
         wtmp_helper_update_login_frequencies (users);
70a90c
 
70a90c
         /* Count the non-system users. Mark which users are local, which are not. */
70a90c
         g_hash_table_iter_init (&iter, users);
70a90c
         while (g_hash_table_iter_next (&iter, &name, &value)) {
70a90c
                 User *user = value;
70a90c
                 if (!user_get_system_account (user))
70a90c
                         number_of_normal_users++;
70a90c
                 user_update_local_account_property (user, g_hash_table_lookup (local, name) != NULL);
70a90c
         }
70a90c
         g_hash_table_destroy (local);
70a90c
 
70a90c
         had_no_users = accounts_accounts_get_has_no_users (accounts);
70a90c
         has_no_users = number_of_normal_users == 0;
70a90c
 
70a90c
         if (has_no_users && has_network_realms (daemon)) {
70a90c
                 g_debug ("No local users, but network realms detected, presuming there are remote users");
70a90c
                 has_no_users = FALSE;
70a90c
         }
70a90c
 
70a90c
         if (had_no_users != has_no_users)
70a90c
                 accounts_accounts_set_has_no_users (accounts, has_no_users);
70a90c
 
70a90c
         had_multiple_users = accounts_accounts_get_has_multiple_users (accounts);
70a90c
         has_multiple_users = number_of_normal_users > 1;
70a90c
 
70a90c
         if (had_multiple_users != has_multiple_users)
70a90c
                 accounts_accounts_set_has_multiple_users (accounts, has_multiple_users);
70a90c
 
70a90c
         /* Swap out the users */
70a90c
@@ -1017,73 +1019,71 @@ daemon_find_user_by_name (AccountsAccounts      *accounts,
70a90c
 
70a90c
 static ListUserData *
70a90c
 list_user_data_new (Daemon                *daemon,
70a90c
                     GDBusMethodInvocation *context)
70a90c
 {
70a90c
         ListUserData *data;
70a90c
 
70a90c
         data = g_new0 (ListUserData, 1);
70a90c
 
70a90c
         data->daemon = g_object_ref (daemon);
70a90c
         data->context = context;
70a90c
 
70a90c
         return data;
70a90c
 }
70a90c
 
70a90c
 static void
70a90c
 list_user_data_free (ListUserData *data)
70a90c
 {
70a90c
         g_object_unref (data->daemon);
70a90c
         g_free (data);
70a90c
 }
70a90c
 
70a90c
 static void
70a90c
 finish_list_cached_users (ListUserData *data)
70a90c
 {
70a90c
         DaemonPrivate *priv = daemon_get_instance_private (data->daemon);
70a90c
         g_autoptr(GPtrArray) object_paths = NULL;
70a90c
         GHashTableIter iter;
70a90c
         gpointer key, value;
70a90c
         uid_t uid;
70a90c
-        const gchar *shell;
70a90c
 
70a90c
         object_paths = g_ptr_array_new ();
70a90c
 
70a90c
         g_hash_table_iter_init (&iter, priv->users);
70a90c
         while (g_hash_table_iter_next (&iter, &key, &value)) {
70a90c
                 const gchar *name = key;
70a90c
                 User *user = value;
70a90c
 
70a90c
                 uid = user_get_uid (user);
70a90c
-                shell = user_get_shell (user);
70a90c
 
70a90c
-                if (!user_classify_is_human (uid, name, shell, NULL)) {
70a90c
+                if (user_get_system_account (user)) {
70a90c
                         g_debug ("user %s %ld excluded", name, (long) uid);
70a90c
                         continue;
70a90c
                 }
70a90c
 
70a90c
                 if (!user_get_cached (user)) {
70a90c
                         g_debug ("user %s %ld not cached", name, (long) uid);
70a90c
                         continue;
70a90c
                 }
70a90c
 
70a90c
                 g_debug ("user %s %ld not excluded", name, (long) uid);
70a90c
                 g_ptr_array_add (object_paths, (gpointer) user_get_object_path (user));
70a90c
         }
70a90c
         g_ptr_array_add (object_paths, NULL);
70a90c
 
70a90c
         accounts_accounts_complete_list_cached_users (NULL, data->context, (const gchar * const *) object_paths->pdata);
70a90c
 
70a90c
         list_user_data_free (data);
70a90c
 }
70a90c
 
70a90c
 static gboolean
70a90c
 daemon_list_cached_users (AccountsAccounts      *accounts,
70a90c
                           GDBusMethodInvocation *context)
70a90c
 {
70a90c
         Daemon *daemon = (Daemon*)accounts;
70a90c
         DaemonPrivate *priv = daemon_get_instance_private (daemon);
70a90c
         ListUserData *data;
70a90c
 
70a90c
         data = list_user_data_new (daemon, context);
70a90c
 
70a90c
         if (priv->reload_id > 0) {
70a90c
-- 
70a90c
2.31.1
70a90c