This patch introduces the changes needed for iterating through the
"/etc/groups" file. But because we currently provide only a single hardcoded
group, we will return just one single entry. This can be extended easily,
either by adding more hardcoded groups or by using the actual "/etc/groups".
However, the latter option is subject to future work, when we will need a more
consistent analysis regarding user management and permissions on Unikraft.
The groups iterator is thread safe, therefore we also introduce the `__uk_tls`,
qualifier which depends on `CONFIG_HAVE_SCHED`, and mark the users iterator as
TLS as well. Another minor change revisits this library constructor by marking
it as a Unikraft constructor.
Signed-off-by: Costin Lupu <costin.lupu@xxxxxxxxx>
---
include/uk/essentials.h | 6 ++++
lib/posix-user/user.c | 70 +++++++++++++++++++++++++++++++++++++++--
2 files changed, 74 insertions(+), 2 deletions(-)
diff --git a/include/uk/essentials.h b/include/uk/essentials.h
index e8264c5f..a6d969e7 100644
--- a/include/uk/essentials.h
+++ b/include/uk/essentials.h
@@ -124,6 +124,12 @@ extern "C" {
#define __constructor_prio(lvl) __attribute__ ((constructor (lvl)))
#endif
+#ifdef CONFIG_HAVE_SCHED
+#define __uk_tls __thread
+#else
+#define __uk_tls
+#endif
+
#else
/* TO BE DEFINED */
#endif /* __GNUC__ */
diff --git a/lib/posix-user/user.c b/lib/posix-user/user.c
index 0d6ca3fb..ba01ab74 100644
--- a/lib/posix-user/user.c
+++ b/lib/posix-user/user.c
@@ -41,6 +41,7 @@
#include <sys/types.h>
#include <uk/essentials.h>
#include <uk/list.h>
+#include <uk/ctors.h>
#include <uk/print.h>
#include <uk/user.h>
@@ -50,7 +51,7 @@
#define UK_DEFAULT_GROUP "root"
#define UK_DEFAULT_PASS "x"
-static struct passwd_entry {
+static __uk_tls struct passwd_entry {
struct passwd *passwd;
UK_SLIST_ENTRY(struct passwd_entry) entries;
@@ -60,7 +61,13 @@ UK_SLIST_HEAD(uk_entry_list, struct passwd_entry);
static struct uk_entry_list passwds;
-void __constructor init_ukunistd()
+static void init_groups(void);
+
+/*
+ * TODO make passwd management consistent with group management
+ */
+
+static void init_posix_user()
{
static struct passwd_entry p1;
static struct passwd passwd = {
@@ -77,7 +84,10 @@ void __constructor init_ukunistd()
UK_SLIST_INIT(&passwds);
UK_SLIST_INSERT_HEAD(&passwds, &p1, entries);
+
+ init_groups();
}
+UK_CTOR_FUNC(2, init_posix_user);
uid_t getuid(void)
{
@@ -328,3 +338,59 @@ int getgrnam_r(const char *name, struct group *grp,
return 0;
}
+
+struct group *getgrgid(gid_t gid)
+{
+ struct group *res;
+
+ if (gid == g__.gr_gid)
+ res = &g__;
+ else {
+ res = NULL;
+ errno = ENOENT;
+ }
+
+ return res;
+}
+
+static __uk_tls struct group_entry {
+ struct group *group;
+ UK_SLIST_ENTRY(struct group_entry) entries;
+} *groups_iter;
+
+UK_SLIST_HEAD(uk_group_entry_list, struct group_entry);
+
+static struct uk_group_entry_list groups;
+
+static void init_groups(void)
+{
+ static struct group_entry ge;
+
+ ge.group = &g__;
+ UK_SLIST_INIT(&groups);
+ UK_SLIST_INSERT_HEAD(&groups, &ge, entries);
+}
+
+void setgrent(void)
+{
+ groups_iter = UK_SLIST_FIRST(&groups);
+}
+
+void endgrent(void)
+{
+ setgrent();
+}
+
+struct group *getgrent(void)
+{
+ struct group *res;
+
+ if (groups_iter) {
+ res = groups_iter->group;
+ groups_iter = UK_SLIST_NEXT(groups_iter, entries);
+ } else
+ res = NULL;
+
+ return res;
+
+}