diff options
author | Thomas Haller <thaller@redhat.com> | 2020-09-24 19:35:57 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2020-09-25 21:03:27 +0200 |
commit | 39b52d0fd015382a5089f57b4559a97340c7d4fc (patch) | |
tree | 45cd3b885d095891dac7d2d10998b572ff7f99b1 | |
parent | 0efa507265e8cf3623f44b4140084d7a232d86a1 (diff) | |
download | NetworkManager-39b52d0fd015382a5089f57b4559a97340c7d4fc.tar.gz |
shared: add nm_utils_uid_to_name()/nm_utils_name_to_uid() helpers
These are inspired by systemd.
We should replace our calls to getpwuid() and getpwnam() with
their thread safe variants.
We run possibly multiple threads (e.g. helper threads from GDBus and
GResolver). It's hard to be sure that they don't also access the
functions.
-rw-r--r-- | shared/nm-glib-aux/nm-shared-utils.c | 79 | ||||
-rw-r--r-- | shared/nm-glib-aux/nm-shared-utils.h | 3 |
2 files changed, 82 insertions, 0 deletions
diff --git a/shared/nm-glib-aux/nm-shared-utils.c b/shared/nm-glib-aux/nm-shared-utils.c index 57c1caeb6b..38a680928e 100644 --- a/shared/nm-glib-aux/nm-shared-utils.c +++ b/shared/nm-glib-aux/nm-shared-utils.c @@ -7,6 +7,7 @@ #include "nm-shared-utils.h" +#include <pwd.h> #include <arpa/inet.h> #include <poll.h> #include <fcntl.h> @@ -5636,3 +5637,81 @@ nm_utils_is_specific_hostname (const char *name) return TRUE; } + +/*****************************************************************************/ + +/* taken from systemd's uid_to_name(). */ +char * +nm_utils_uid_to_name (uid_t uid) +{ + gs_free char *buf_heap = NULL; + char buf_stack[4096]; + gsize bufsize; + char *buf; + + bufsize = sizeof (buf_stack); + buf = buf_stack; + + for (;;) { + struct passwd pwbuf; + struct passwd *pw = NULL; + int r; + + r = getpwuid_r (uid, &pwbuf, buf, bufsize, &pw); + if ( r == 0 + && pw) + return nm_strdup_not_empty (pw->pw_name); + + if (r != ERANGE) + return NULL; + + if (bufsize > G_MAXSIZE / 2u) + return NULL; + + bufsize *= 2u; + g_free (buf_heap); + buf_heap = g_malloc (bufsize); + buf = buf_heap; + } +} + +/* taken from systemd's nss_user_record_by_name() */ +gboolean +nm_utils_name_to_uid (const char *name, uid_t *out_uid) +{ + gs_free char *buf_heap = NULL; + char buf_stack[4096]; + gsize bufsize; + char *buf; + + if (!name) + return nm_assert_unreachable_val (FALSE); + + bufsize = sizeof (buf_stack); + buf = buf_stack; + + for (;;) { + struct passwd *result; + struct passwd pwd; + int r; + + r = getpwnam_r (name, &pwd, buf, bufsize, &result); + if (r == 0) { + if (!result) + return FALSE; + NM_SET_OUT (out_uid, pwd.pw_uid); + return TRUE; + } + + if (r != ERANGE) + return FALSE; + + if (bufsize > G_MAXSIZE / 2u) + return FALSE; + + bufsize *= 2u; + g_free (buf_heap); + buf_heap = g_malloc (bufsize); + buf = buf_heap; + } +} diff --git a/shared/nm-glib-aux/nm-shared-utils.h b/shared/nm-glib-aux/nm-shared-utils.h index 28a519ae44..f4caf3d74c 100644 --- a/shared/nm-glib-aux/nm-shared-utils.h +++ b/shared/nm-glib-aux/nm-shared-utils.h @@ -2339,4 +2339,7 @@ gboolean nm_utils_is_localhost (const char *name); gboolean nm_utils_is_specific_hostname (const char *name); +char *nm_utils_uid_to_name (uid_t uid); +gboolean nm_utils_name_to_uid (const char *name, uid_t *out_uid); + #endif /* __NM_SHARED_UTILS_H__ */ |