summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2020-09-24 19:35:57 +0200
committerThomas Haller <thaller@redhat.com>2020-09-25 21:03:27 +0200
commit39b52d0fd015382a5089f57b4559a97340c7d4fc (patch)
tree45cd3b885d095891dac7d2d10998b572ff7f99b1
parent0efa507265e8cf3623f44b4140084d7a232d86a1 (diff)
downloadNetworkManager-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.c79
-rw-r--r--shared/nm-glib-aux/nm-shared-utils.h3
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__ */