diff options
Diffstat (limited to 'src/basic/user-util.c')
-rw-r--r-- | src/basic/user-util.c | 62 |
1 files changed, 54 insertions, 8 deletions
diff --git a/src/basic/user-util.c b/src/basic/user-util.c index d9cc580d8..ee42b10cb 100644 --- a/src/basic/user-util.c +++ b/src/basic/user-util.c @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ /*** This file is part of systemd. @@ -118,15 +119,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; @@ -139,6 +139,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); @@ -220,7 +237,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) @@ -229,6 +246,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); @@ -261,6 +287,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; @@ -299,6 +327,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; @@ -391,7 +421,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"); @@ -401,6 +431,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; @@ -438,7 +476,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"); @@ -448,6 +486,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; @@ -613,7 +659,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 */ |