summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2015-10-25 23:20:05 +0100
committerLennart Poettering <lennart@poettering.net>2015-10-26 01:24:38 +0100
commitd02608170e599b1ffbc7c9a22062bae2579d6e36 (patch)
tree607136c4d409d664388def7b934bedc23604f4d0 /src
parentb1d5277372a26e5a5b9980174652e1e287ba6b14 (diff)
util: remove lookup_uid(), replace by uid_to_name()
So far we had two pretty much identical calls in user-util.[ch]: lookup_uid() and uid_to_name(). Get rid of the former, in favour of the latter, and while we are at it, rewrite it, to use getpwuid_r() correctly, inside an allocation loop, as POSIX intended.
Diffstat (limited to 'src')
-rw-r--r--src/basic/user-util.c102
-rw-r--r--src/basic/user-util.h1
-rw-r--r--src/login/logind-dbus.c2
-rw-r--r--src/login/logind-utmp.c2
-rw-r--r--src/test/test-user-util.c53
5 files changed, 114 insertions, 46 deletions
diff --git a/src/basic/user-util.c b/src/basic/user-util.c
index ebeac99d31..b5e6ce8a8a 100644
--- a/src/basic/user-util.c
+++ b/src/basic/user-util.c
@@ -64,33 +64,6 @@ int parse_uid(const char *s, uid_t *ret) {
return 0;
}
-char *lookup_uid(uid_t uid) {
- long bufsize;
- char *name;
- _cleanup_free_ char *buf = NULL;
- struct passwd pwbuf, *pw = NULL;
-
- /* Shortcut things to avoid NSS lookups */
- if (uid == 0)
- return strdup("root");
-
- bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
- if (bufsize <= 0)
- bufsize = 4096;
-
- buf = malloc(bufsize);
- if (!buf)
- return NULL;
-
- if (getpwuid_r(uid, &pwbuf, buf, bufsize, &pw) == 0 && pw)
- return strdup(pw->pw_name);
-
- if (asprintf(&name, UID_FMT, uid) < 0)
- return NULL;
-
- return name;
-}
-
char* getlogname_malloc(void) {
uid_t uid;
struct stat st;
@@ -100,7 +73,7 @@ char* getlogname_malloc(void) {
else
uid = getuid();
- return lookup_uid(uid);
+ return uid_to_name(uid);
}
char *getusername_malloc(void) {
@@ -110,7 +83,7 @@ char *getusername_malloc(void) {
if (e)
return strdup(e);
- return lookup_uid(getuid());
+ return uid_to_name(getuid());
}
int get_user_creds(
@@ -219,37 +192,80 @@ int get_group_creds(const char **groupname, gid_t *gid) {
}
char* uid_to_name(uid_t uid) {
- struct passwd *p;
- char *r;
+ char *ret;
+ int r;
+ /* Shortcut things to avoid NSS lookups */
if (uid == 0)
return strdup("root");
- p = getpwuid(uid);
- if (p)
- return strdup(p->pw_name);
+ if (uid_is_valid(uid)) {
+ long bufsize;
+
+ bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
+ if (bufsize <= 0)
+ bufsize = 4096;
+
+ for (;;) {
+ struct passwd pwbuf, *pw = NULL;
+ _cleanup_free_ char *buf = NULL;
+
+ buf = malloc(bufsize);
+ if (!buf)
+ return NULL;
+
+ r = getpwuid_r(uid, &pwbuf, buf, (size_t) bufsize, &pw);
+ if (r == 0 && pw)
+ return strdup(pw->pw_name);
+ if (r != ERANGE)
+ break;
+
+ bufsize *= 2;
+ }
+ }
- if (asprintf(&r, UID_FMT, uid) < 0)
+ if (asprintf(&ret, UID_FMT, uid) < 0)
return NULL;
- return r;
+ return ret;
}
char* gid_to_name(gid_t gid) {
- struct group *p;
- char *r;
+ char *ret;
+ int r;
if (gid == 0)
return strdup("root");
- p = getgrgid(gid);
- if (p)
- return strdup(p->gr_name);
+ if (gid_is_valid(gid)) {
+ long bufsize;
+
+ bufsize = sysconf(_SC_GETGR_R_SIZE_MAX);
+ if (bufsize <= 0)
+ bufsize = 4096;
+
+ for (;;) {
+ struct group grbuf, *gr = NULL;
+ _cleanup_free_ char *buf = NULL;
+
+ buf = malloc(bufsize);
+ if (!buf)
+ return NULL;
+
+ r = getgrgid_r(gid, &grbuf, buf, (size_t) bufsize, &gr);
+ if (r == 0 && gr)
+ return strdup(gr->gr_name);
+ if (r != ERANGE)
+ break;
+
+ bufsize *= 2;
+ }
+ }
- if (asprintf(&r, GID_FMT, gid) < 0)
+ if (asprintf(&ret, GID_FMT, gid) < 0)
return NULL;
- return r;
+ return ret;
}
int in_gid(gid_t gid) {
diff --git a/src/basic/user-util.h b/src/basic/user-util.h
index 9263ede741..7995698f27 100644
--- a/src/basic/user-util.h
+++ b/src/basic/user-util.h
@@ -36,7 +36,6 @@ static inline int parse_gid(const char *s, gid_t *ret_gid) {
return parse_uid(s, (uid_t*) ret_gid);
}
-char* lookup_uid(uid_t uid);
char* getlogname_malloc(void);
char* getusername_malloc(void);
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index 6da1398b7d..61c2c9ba40 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -2028,7 +2028,7 @@ static int method_cancel_scheduled_shutdown(sd_bus_message *message, void *userd
}
utmp_wall("The system shutdown has been cancelled",
- lookup_uid(uid), tty, logind_wall_tty_filter, m);
+ uid_to_name(uid), tty, logind_wall_tty_filter, m);
}
return sd_bus_reply_method_return(message, "b", cancelled);
diff --git a/src/login/logind-utmp.c b/src/login/logind-utmp.c
index 80e461f2dc..9c766bcb25 100644
--- a/src/login/logind-utmp.c
+++ b/src/login/logind-utmp.c
@@ -96,7 +96,7 @@ static int warn_wall(Manager *m, usec_t n) {
return 0;
}
- utmp_wall(l, lookup_uid(m->scheduled_shutdown_uid),
+ utmp_wall(l, uid_to_name(m->scheduled_shutdown_uid),
m->scheduled_shutdown_tty, logind_wall_tty_filter, m);
return 1;
diff --git a/src/test/test-user-util.c b/src/test/test-user-util.c
new file mode 100644
index 0000000000..dfd2031998
--- /dev/null
+++ b/src/test/test-user-util.c
@@ -0,0 +1,53 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+ This file is part of systemd.
+
+ Copyright 2015 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "macro.h"
+#include "string-util.h"
+#include "user-util.h"
+#include "util.h"
+
+static void test_uid_to_name_one(uid_t uid, const char *name) {
+ _cleanup_free_ char *t = NULL;
+
+ assert_se(t = uid_to_name(uid));
+ assert_se(streq_ptr(t, name));
+}
+
+static void test_gid_to_name_one(gid_t gid, const char *name) {
+ _cleanup_free_ char *t = NULL;
+
+ assert_se(t = gid_to_name(gid));
+ assert_se(streq_ptr(t, name));
+}
+
+int main(int argc, char*argv[]) {
+
+ test_uid_to_name_one(0, "root");
+ test_uid_to_name_one(0xFFFF, "65535");
+ test_uid_to_name_one(0xFFFFFFFF, "4294967295");
+
+ test_gid_to_name_one(0, "root");
+ test_gid_to_name_one(TTY_GID, "tty");
+ test_gid_to_name_one(0xFFFF, "65535");
+ test_gid_to_name_one(0xFFFFFFFF, "4294967295");
+
+ return 0;
+}