[Bug 249445] sysutils/accountsservice: Update to 0.6.55
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 26 Jun 2021 22:45:43 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=249445
david@dcrosstech.com changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |david@dcrosstech.com
--- Comment #12 from david@dcrosstech.com ---
I have been hitting this issue myself, and I think the bug exists in 2 places.
1 in accountservice/src/daemon.c:
daemon.c:197
> /* First iteration */
> if (*state == NULL) {
> GHashTable *shadow_users = NULL;
> FILE *fp;
> #ifdef HAVE_SHADOW_H
> struct spwd *shadow_entry;
>
> fp = fopen (PATH_SHADOW, "r");
> if (fp == NULL) {
> g_warning ("Unable to open %s: %s", PATH_SHADOW, g_strerror (errno));
> return NULL;
> }
>
> shadow_users = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
>
> do {
> int ret = 0;
>
> shadow_entry_buffers = g_malloc0 (sizeof (*shadow_entry_buffers));
>
> 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);
> } else {
> g_free (shadow_entry_buffers);
>
> if (errno != EINTR) {
> break;
> }
> }
> } while (shadow_entry != NULL);
>
> fclose (fp);
>
> if (g_hash_table_size (shadow_users) == 0) {
> g_clear_pointer (&shadow_users, g_hash_table_unref);
> return NULL;
> }
> #endif
>
> fp = fopen (PATH_PASSWD, "r");
> if (fp == NULL) {
> g_clear_pointer (&shadow_users, g_hash_table_unref);
> g_warning ("Unable to open %s: %s", PATH_PASSWD, g_strerror (errno));
> return NULL;
> }
>
> generator_state = g_malloc0 (sizeof (*generator_state));
> generator_state->fp = fp;
> generator_state->users = shadow_users;
>
> *state = generator_state;
> }
>
> /* Every iteration */
> generator_state = *state;
>
> if (g_hash_table_size (users) < MAX_LOCAL_USERS) {
> pwent = fgetpwent (generator_state->fp);
> if (pwent != NULL) {
> #ifdef HAVE_SHADOW_H
> shadow_entry_buffers = g_hash_table_lookup (generator_state->users, pwent->pw_name);
>
> if (shadow_entry_buffers != NULL) {
> *spent = &shadow_entry_buffers->spbuf;
> }
> return pwent;
> #else
> if (!generator_state->users || g_hash_table_lookup (generator_state->users, pwent->pw_name))
> return pwent;
> #endif
> }
> }
Note that my reading of the code is that it pulls all of /etc/shadow into
memory (and does it extremely hamfistedly), and then uses that to prune
/etc/passwd in such a way that users that aren't in /etc/shadow don't even show
up:
> if (!generator_state->users || g_hash_table_lookup (generator_state->users, pwent->pw_name))
> return pwent;
So generator_state-> users has to be non-null, AND it has to have a user by
that name in it... but in the first iteration generator_state->users is set to
shadow_users (L246), however shadow_users is set L210 (inside the #ifdef
block), and populated in that block, what WE get is the initial value (NULL),
L199.... Therefore that check NEVER passes, and we never have ANY users.
So I fixed that by removing the if conditional and always returned pwent.
This however did not fix it. In experimenting I would swap out JUST
account-daemon (or whatever it is called), and hit gdm. THIS worked.... and
later I discovered that there is libaccountservice at play here, I think there
is a *second* bug lurking in there. I did a git diff between the two versions
that we upgraded and .. a lot changed.
I am not done investigating yet, but I figured more eyes will help. I hope
this helps.
--
You are receiving this mail because:
You are on the CC list for the bug.