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

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