From 69cd195c3acc460f564e6c439b3a37a6e6c2418b Mon Sep 17 00:00:00 2001 From: Ruixin Bao Date: Mon, 11 Jun 2018 13:50:36 +0000 Subject: [PATCH] passwd-util: add conversion for passwd entries to sysusers Adds initial implementation of converting passwd entries(read from /etc/passwd file) into sysuser_ent structs. The converted sysuser_ent struct will then get tracked inside a pointer array. Closes: #1519 Approved by: cgwalters --- src/libpriv/rpmostree-passwd-util.c | 52 +++++++++++++++++++++++++++++ src/libpriv/rpmostree-passwd-util.h | 5 +++ 2 files changed, 57 insertions(+) diff --git a/src/libpriv/rpmostree-passwd-util.c b/src/libpriv/rpmostree-passwd-util.c index d92f6eda..a934ac08 100644 --- a/src/libpriv/rpmostree-passwd-util.c +++ b/src/libpriv/rpmostree-passwd-util.c @@ -186,6 +186,17 @@ conv_group_ent_free (void *vptr) g_free (ptr); } +static void +sysuser_ent_free (void *vptr) +{ + struct sysuser_ent *ptr = vptr; + g_free (ptr->name); + g_free (ptr->id); + g_free (ptr->gecos); + g_free (ptr->dir); + g_free (ptr->shell); +} + GPtrArray * rpmostree_passwd_data2groupents (const char *data) { @@ -217,6 +228,47 @@ compare_group_ents (gconstpointer a, gconstpointer b) return strcmp ((*sa)->name, (*sb)->name); } +gboolean +rpmostree_passwdents2sysusers (GPtrArray *passwd_ents, + GPtrArray **out_sysusers_entries, + GError **error) +{ + /* Do the assignment inside the function so we don't need to expose sysuser_ent + * to other files */ + GPtrArray *sysusers_array = NULL; + sysusers_array = *out_sysusers_entries ?: g_ptr_array_new_with_free_func (sysuser_ent_free); + + for (int counter = 0; counter < passwd_ents->len; counter++) + { + struct conv_passwd_ent *convent = passwd_ents->pdata[counter]; + struct sysuser_ent *sysent = g_new (struct sysuser_ent, 1); + + /* Systemd-sysusers also supports uid:gid format. That case was used + * when creating user and group pairs with different numeric UID and GID values.*/ + if (convent->uid != convent->gid) + sysent->id = g_strdup_printf ("%u:%u", convent->uid, convent->gid); + else + sysent->id = g_strdup_printf ("%u", convent->uid); + + sysent->type = "u"; + sysent->name = g_strdup (convent->name); + + /* Gecos may contain multiple words, thus adding a quote here to make it as a 'word' */ + sysent->gecos = (g_str_equal (convent->pw_gecos, "")) ? NULL : + g_strdup_printf ("\"%s\"", convent->pw_gecos); + sysent->dir = (g_str_equal (convent->pw_dir, ""))? NULL : + g_steal_pointer (&convent->pw_dir); + sysent->shell = g_steal_pointer (&convent->pw_shell); + + g_ptr_array_add (sysusers_array, sysent); + } + /* Do the assignment at the end if the sysusers_table was not initialized */ + if (*out_sysusers_entries == NULL) + *out_sysusers_entries = g_steal_pointer (&sysusers_array); + + return TRUE; +} + /* See "man 5 passwd" We just make sure the name and uid/gid match, and that none are missing. don't care about GECOS/dir/shell. */ diff --git a/src/libpriv/rpmostree-passwd-util.h b/src/libpriv/rpmostree-passwd-util.h index 1998dd90..a000f627 100644 --- a/src/libpriv/rpmostree-passwd-util.h +++ b/src/libpriv/rpmostree-passwd-util.h @@ -117,3 +117,8 @@ rpmostree_passwd_data2passwdents (const char *data); GPtrArray * rpmostree_passwd_data2groupents (const char *data); + +gboolean +rpmostree_passwdents2sysusers (GPtrArray *passwd_ents, + GPtrArray **out_sysusers_entries, + GError **error);