]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
util: remove lookup_uid(), replace by uid_to_name()
authorLennart Poettering <lennart@poettering.net>
Sun, 25 Oct 2015 22:20:05 +0000 (23:20 +0100)
committerLennart Poettering <lennart@poettering.net>
Mon, 26 Oct 2015 00:24:38 +0000 (01:24 +0100)
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.

.gitignore
Makefile.am
src/basic/user-util.c
src/basic/user-util.h
src/login/logind-dbus.c
src/login/logind-utmp.c
src/test/test-user-util.c [new file with mode: 0644]

index b47bd1b2f2ec8d1154eaacbd3dc0dfe29e6b2d5e..0a32bae7a86c3a748b2c677060b064277d9ec208 100644 (file)
 /test-unaligned
 /test-unit-file
 /test-unit-name
+/test-user-util
 /test-utf8
 /test-util
 /test-verbs
index 69a2b732d0970d49d9d7285fc415fe86669d1474..6540402da9cda2b4239d7540fba0eb480160fd1c 100644 (file)
@@ -1414,6 +1414,7 @@ tests += \
        test-utf8 \
        test-ellipsize \
        test-util \
+       test-user-util \
        test-hostname-util \
        test-process-util \
        test-terminal-util \
@@ -1698,6 +1699,12 @@ test_util_SOURCES = \
 test_util_LDADD = \
        libshared.la
 
+test_user_util_SOURCES = \
+       src/test/test-user-util.c
+
+test_user_util_LDADD = \
+       libshared.la
+
 test_hostname_util_SOURCES = \
        src/test/test-hostname-util.c
 
index ebeac99d3121a7fc62b404320a7e9046071b77a4..b5e6ce8a8aa285636f821f8f956822e9fb42d544 100644 (file)
@@ -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) {
index 9263ede74166b135a0f620ea6efec31c942156d3..7995698f272e8c6fc3e8435ffd7b97a6415ac7f5 100644 (file)
@@ -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);
 
index 6da1398b7d4caee73cd9f00c4a4301d7d719d3b8..61c2c9ba409145cb5771d1de4ddf9a69bef9cd6c 100644 (file)
@@ -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);
index 80e461f2dc886bd9fd231916eb222b6c9f1bc23d..9c766bcb25efc6f0e2b4a139f86fc292421ac228 100644 (file)
@@ -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 (file)
index 0000000..dfd2031
--- /dev/null
@@ -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;
+}