]> git.proxmox.com Git - systemd.git/blobdiff - src/basic/user-util.c
New upstream version 236
[systemd.git] / src / basic / user-util.c
index a691a0d3fc4ff1e8c08745f6c8fbcf7be1f1594a..abb0b76866a7bdd2043f28553547e892f29c6b19 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -116,15 +117,14 @@ int get_user_creds(
         assert(username);
         assert(*username);
 
-        /* We enforce some special rules for uid=0: in order to avoid
-         * NSS lookups for root we hardcode its data. */
+        /* We enforce some special rules for uid=0 and uid=65534: in order to avoid NSS lookups for root we hardcode
+         * their user record data. */
 
-        if (streq(*username, "root") || streq(*username, "0")) {
+        if (STR_IN_SET(*username, "root", "0")) {
                 *username = "root";
 
                 if (uid)
                         *uid = 0;
-
                 if (gid)
                         *gid = 0;
 
@@ -137,6 +137,23 @@ int get_user_creds(
                 return 0;
         }
 
+        if (STR_IN_SET(*username, NOBODY_USER_NAME, "65534")) {
+                *username = NOBODY_USER_NAME;
+
+                if (uid)
+                        *uid = UID_NOBODY;
+                if (gid)
+                        *gid = GID_NOBODY;
+
+                if (home)
+                        *home = "/";
+
+                if (shell)
+                        *shell = "/sbin/nologin";
+
+                return 0;
+        }
+
         if (parse_uid(*username, &u) >= 0) {
                 errno = 0;
                 p = getpwuid(u);
@@ -217,7 +234,7 @@ int get_group_creds(const char **groupname, gid_t *gid) {
         /* We enforce some special rules for gid=0: in order to avoid
          * NSS lookups for root we hardcode its data. */
 
-        if (streq(*groupname, "root") || streq(*groupname, "0")) {
+        if (STR_IN_SET(*groupname, "root", "0")) {
                 *groupname = "root";
 
                 if (gid)
@@ -226,6 +243,15 @@ int get_group_creds(const char **groupname, gid_t *gid) {
                 return 0;
         }
 
+        if (STR_IN_SET(*groupname, NOBODY_GROUP_NAME, "65534")) {
+                *groupname = NOBODY_GROUP_NAME;
+
+                if (gid)
+                        *gid = GID_NOBODY;
+
+                return 0;
+        }
+
         if (parse_gid(*groupname, &id) >= 0) {
                 errno = 0;
                 g = getgrgid(id);
@@ -257,6 +283,8 @@ char* uid_to_name(uid_t uid) {
         /* Shortcut things to avoid NSS lookups */
         if (uid == 0)
                 return strdup("root");
+        if (uid == UID_NOBODY)
+                return strdup(NOBODY_USER_NAME);
 
         if (uid_is_valid(uid)) {
                 long bufsize;
@@ -295,6 +323,8 @@ char* gid_to_name(gid_t gid) {
 
         if (gid == 0)
                 return strdup("root");
+        if (gid == GID_NOBODY)
+                return strdup(NOBODY_GROUP_NAME);
 
         if (gid_is_valid(gid)) {
                 long bufsize;
@@ -386,7 +416,7 @@ int get_home_dir(char **_h) {
                 return 0;
         }
 
-        /* Hardcode home directory for root to avoid NSS */
+        /* Hardcode home directory for root and nobody to avoid NSS */
         u = getuid();
         if (u == 0) {
                 h = strdup("/root");
@@ -396,6 +426,14 @@ int get_home_dir(char **_h) {
                 *_h = h;
                 return 0;
         }
+        if (u == UID_NOBODY) {
+                h = strdup("/");
+                if (!h)
+                        return -ENOMEM;
+
+                *_h = h;
+                return 0;
+        }
 
         /* Check the database... */
         errno = 0;
@@ -433,7 +471,7 @@ int get_shell(char **_s) {
                 return 0;
         }
 
-        /* Hardcode home directory for root to avoid NSS */
+        /* Hardcode shell for root and nobody to avoid NSS */
         u = getuid();
         if (u == 0) {
                 s = strdup("/bin/sh");
@@ -443,6 +481,14 @@ int get_shell(char **_s) {
                 *_s = s;
                 return 0;
         }
+        if (u == UID_NOBODY) {
+                s = strdup("/sbin/nologin");
+                if (!s)
+                        return -ENOMEM;
+
+                *_s = s;
+                return 0;
+        }
 
         /* Check the database... */
         errno = 0;
@@ -605,7 +651,7 @@ bool valid_home(const char *p) {
         if (!path_is_absolute(p))
                 return false;
 
-        if (!path_is_safe(p))
+        if (!path_is_normalized(p))
                 return false;
 
         /* Colons are used as field separators, and hence not OK */