diff options
author | Ray Strode <rstrode@redhat.com> | 2023-03-15 10:41:05 -0400 |
---|---|---|
committer | Ray Strode <rstrode@redhat.com> | 2023-03-15 10:50:38 -0400 |
commit | 78794fafaf1d3228a4b0b70c9eea53dba37c9497 (patch) | |
tree | 420c13940589e17671b4b50f52e19d323df5de6f | |
parent | 453f893e3c38c209ae9dff47bca74ccb33a5bd34 (diff) | |
download | accountsservice-78794fafaf1d3228a4b0b70c9eea53dba37c9497.tar.gz |
daemon: Track local users outside of fgetpwent generator
Right now we assume all local users are in /etc/shadow. This
mostly right, but there may be cases where an admin wants a user
to be treated as local even though they don't have a password
set there.
As a first step toward supporting that end goal, this commit changes
the code to track local users in a hash table allocated outside
of the generator function. This way the table can be used from
more than one generator.
A future commit will change the cache file generator to populate
the local users hash table as well.
-rw-r--r-- | src/daemon.c | 65 |
1 files changed, 35 insertions, 30 deletions
diff --git a/src/daemon.c b/src/daemon.c index 447893b..7a05baf 100644 --- a/src/daemon.c +++ b/src/daemon.c @@ -97,9 +97,9 @@ typedef struct typedef struct passwd * (* EntryGeneratorFunc) (Daemon *, GHashTable *, + GHashTable *, gpointer *, - struct spwd **shadow_entry, - GHashTable **local_users); + struct spwd **shadow_entry); typedef struct { @@ -208,9 +208,9 @@ remove_cache_files (const gchar *user_name) static struct passwd * entry_generator_fgetpwent (Daemon *daemon, GHashTable *users, + GHashTable *local_users, gpointer *state, - struct spwd **spent, - GHashTable **local_users) + struct spwd **spent) { struct passwd *pwent; @@ -227,11 +227,9 @@ entry_generator_fgetpwent (Daemon *daemon, * /etc/shadow, so sites that rsync NIS/LDAP users into * /etc/passwd don't get them all treated as local) * username -> copy of shadow_entry_buffers */ - GHashTable *local_users; + GHashTable *shadow_users; } *generator_state; - g_assert (local_users == NULL || *local_users == NULL); - /* First iteration */ if (*state == NULL) { GHashTable *shadow_users = NULL; @@ -257,6 +255,7 @@ entry_generator_fgetpwent (Daemon *daemon, ret = fgetspent_r (fp, &shadow_entry_buffers->spbuf, shadow_entry_buffers->buf, sizeof(shadow_entry_buffers->buf), &shadow_entry); if (ret == 0) { g_hash_table_insert (shadow_users, g_strdup (shadow_entry->sp_namp), shadow_entry_buffers); + g_hash_table_add (local_users, g_strdup (shadow_entry->sp_namp)); } else { g_free (shadow_entry_buffers); @@ -283,7 +282,7 @@ entry_generator_fgetpwent (Daemon *daemon, generator_state = g_malloc0 (sizeof(*generator_state)); generator_state->fp = fp; - generator_state->local_users = shadow_users; + generator_state->shadow_users = shadow_users; *state = generator_state; } @@ -294,7 +293,7 @@ entry_generator_fgetpwent (Daemon *daemon, if (g_hash_table_size (users) < MAX_LOCAL_USERS) { pwent = fgetpwent (generator_state->fp); if (pwent != NULL) { - shadow_entry_buffers = g_hash_table_lookup (generator_state->local_users, pwent->pw_name); + shadow_entry_buffers = g_hash_table_lookup (generator_state->shadow_users, pwent->pw_name); if (shadow_entry_buffers != NULL) { *spent = &shadow_entry_buffers->spbuf; @@ -304,20 +303,15 @@ entry_generator_fgetpwent (Daemon *daemon, if (!user_classify_is_human (pwent->pw_uid, pwent->pw_name, pwent->pw_shell)) { g_debug ("skipping user: %s", pwent->pw_name); - return entry_generator_fgetpwent (daemon, users, state, spent, local_users); + return entry_generator_fgetpwent (daemon, users, local_users, state, spent); } return pwent; } } - /* Last iteration */ - if (local_users != NULL) { - *local_users = g_hash_table_ref (generator_state->local_users); - } - fclose (generator_state->fp); - g_hash_table_unref (generator_state->local_users); + g_hash_table_unref (generator_state->shadow_users); g_free (generator_state); *state = NULL; @@ -327,9 +321,9 @@ entry_generator_fgetpwent (Daemon *daemon, static struct passwd * entry_generator_cachedir (Daemon *daemon, GHashTable *users, + GHashTable *local_users, gpointer *state, - struct spwd **shadow_entry, - GHashTable **local_users) + struct spwd **shadow_entry) { struct passwd *pwent; @@ -403,9 +397,9 @@ entry_generator_cachedir (Daemon *daemon, static struct passwd * entry_generator_requested_users (Daemon *daemon, GHashTable *users, + GHashTable *local_users, gpointer *state, - struct spwd **shadow_entry, - GHashTable **local_users) + struct spwd **shadow_entry) { DaemonPrivate *priv = daemon_get_instance_private (daemon); struct passwd *pwent; @@ -450,9 +444,9 @@ entry_generator_requested_users (Daemon *daemon, static void load_entries (Daemon *daemon, GHashTable *users, + GHashTable *local_users, gboolean explicitly_requested, - EntryGeneratorFunc entry_generator, - GHashTable **local_users) + EntryGeneratorFunc entry_generator) { DaemonPrivate *priv = daemon_get_instance_private (daemon); gpointer generator_state = NULL; @@ -461,11 +455,10 @@ load_entries (Daemon *daemon, User *user = NULL; g_assert (entry_generator != NULL); - g_assert (local_users == NULL || *local_users == NULL); for (;;) { spent = NULL; - pwent = entry_generator (daemon, users, &generator_state, &spent, local_users); + pwent = entry_generator (daemon, users, local_users, &generator_state, &spent); if (pwent == NULL) break; @@ -510,6 +503,15 @@ create_users_hash_table (void) g_object_unref); } +static GHashTable * +create_local_users_hash_table (void) +{ + return g_hash_table_new_full (g_str_hash, + g_str_equal, + g_free, + NULL); +} + static void reload_users (Daemon *daemon) { @@ -517,8 +519,8 @@ 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 *local_users = NULL; GHashTable *old_users; - GHashTable *local = NULL; GHashTableIter iter; gsize number_of_normal_users = 0; gpointer name, value; @@ -526,6 +528,9 @@ reload_users (Daemon *daemon) /* Track the users that we saw during our (re)load */ users = create_users_hash_table (); + /* Track which users are local */ + local_users = create_local_users_hash_table (); + /* * NOTE: As we load data from all the sources, notifies are * frozen in load_entries() and then thawed as we process @@ -533,13 +538,13 @@ reload_users (Daemon *daemon) */ /* Load the local users into our hash tables */ - load_entries (daemon, users, FALSE, entry_generator_fgetpwent, &local); + load_entries (daemon, users, local_users, FALSE, entry_generator_fgetpwent); /* Now add/update users from other sources, possibly non-local */ - load_entries (daemon, users, TRUE, entry_generator_cachedir, NULL); + load_entries (daemon, users, local_users, TRUE, entry_generator_cachedir); /* and add users to hash table that were explicitly requested */ - load_entries (daemon, users, TRUE, entry_generator_requested_users, NULL); + load_entries (daemon, users, local_users, TRUE, entry_generator_requested_users); wtmp_helper_update_login_frequencies (users); @@ -549,9 +554,9 @@ reload_users (Daemon *daemon) User *user = value; if (!user_get_system_account (user)) number_of_normal_users++; - user_update_local_account_property (user, local != NULL && g_hash_table_lookup (local, name) != NULL); + user_update_local_account_property (user, g_hash_table_contains (local_users, name)); } - g_clear_pointer (&local, g_hash_table_destroy); + g_clear_pointer (&local_users, g_hash_table_destroy); had_no_users = accounts_accounts_get_has_no_users (accounts); has_no_users = number_of_normal_users == 0; |