chiark / gitweb /
nss-systemd,user-util: add a way how synthesizing "nobody" can be turned off
authorLennart Poettering <lennart@poettering.net>
Wed, 10 Jan 2018 17:26:03 +0000 (18:26 +0100)
committerSven Eden <yamakuzure@gmx.net>
Wed, 30 May 2018 05:50:04 +0000 (07:50 +0200)
This is quite ugly, but provides us with an avenue for moving
distributions to define the "nobody" user properly without breaking legacy
systems that us the name for other stuff.

The idea is basically, that the distribution adopts the new definition
of "nobody" (and thus recompiles systemd with it) and then touches
/etc/systemd/dont-synthesize-nobody on legacy systems to turn off
possibly conflicting synthesizing of the nobody name by systemd.

src/basic/user-util.c
src/basic/user-util.h

index 3f364b3b3a8622b9b58737554e5f6a848c780b44..78effacf8a0d99fe33635997038b79e55b0a9226 100644 (file)
@@ -139,7 +139,8 @@ int get_user_creds(
                 return 0;
         }
 
-        if (STR_IN_SET(*username, NOBODY_USER_NAME, "65534")) {
+        if (synthesize_nobody() &&
+            STR_IN_SET(*username, NOBODY_USER_NAME, "65534")) {
                 *username = NOBODY_USER_NAME;
 
                 if (uid)
@@ -246,7 +247,8 @@ int get_group_creds(const char **groupname, gid_t *gid) {
                 return 0;
         }
 
-        if (STR_IN_SET(*groupname, NOBODY_GROUP_NAME, "65534")) {
+        if (synthesize_nobody() &&
+            STR_IN_SET(*groupname, NOBODY_GROUP_NAME, "65534")) {
                 *groupname = NOBODY_GROUP_NAME;
 
                 if (gid)
@@ -287,7 +289,8 @@ char* uid_to_name(uid_t uid) {
         /* Shortcut things to avoid NSS lookups */
         if (uid == 0)
                 return strdup("root");
-        if (uid == UID_NOBODY)
+        if (synthesize_nobody() &&
+            uid == UID_NOBODY)
                 return strdup(NOBODY_USER_NAME);
 
         if (uid_is_valid(uid)) {
@@ -327,7 +330,8 @@ char* gid_to_name(gid_t gid) {
 
         if (gid == 0)
                 return strdup("root");
-        if (gid == GID_NOBODY)
+        if (synthesize_nobody() &&
+            gid == GID_NOBODY)
                 return strdup(NOBODY_GROUP_NAME);
 
         if (gid_is_valid(gid)) {
@@ -432,7 +436,8 @@ int get_home_dir(char **_h) {
                 *_h = h;
                 return 0;
         }
-        if (u == UID_NOBODY) {
+        if (synthesize_nobody() &&
+            u == UID_NOBODY) {
                 h = strdup("/");
                 if (!h)
                         return -ENOMEM;
@@ -487,7 +492,8 @@ int get_shell(char **_s) {
                 *_s = s;
                 return 0;
         }
-        if (u == UID_NOBODY) {
+        if (synthesize_nobody() &&
+            u == UID_NOBODY) {
                 s = strdup("/sbin/nologin");
                 if (!s)
                         return -ENOMEM;
@@ -698,3 +704,24 @@ int maybe_setgroups(size_t size, const gid_t *list) {
 
         return 0;
 }
+
+bool synthesize_nobody(void) {
+
+#ifdef NOLEGACY
+        return true;
+#else
+        /* Returns true when we shall synthesize the "nobody" user (which we do by default). This can be turned off by
+         * touching /etc/systemd/dont-synthesize-nobody in order to provide upgrade compatibility with legacy systems
+         * that used the "nobody" user name and group name for other UIDs/GIDs than 65534.
+         *
+         * Note that we do not employ any kind of synchronization on the following caching variable. If the variable is
+         * accessed in multi-threaded programs in the worst case it might happen that we initialize twice, but that
+         * shouldn't matter as each initialization should come to the same result. */
+        static int cache = -1;
+
+        if (cache < 0)
+                cache = access("/etc/elogind/dont-synthesize-nobody", F_OK) < 0;
+
+        return cache;
+#endif
+}
index 8584989400979d2f169a4cbfd28a71e7aa528a6e..34816089764bff8e600ecc1384fd190ce7c91eef 100644 (file)
@@ -107,3 +107,5 @@ bool valid_gecos(const char *d);
 bool valid_home(const char *p);
 
 int maybe_setgroups(size_t size, const gid_t *list);
+
+bool synthesize_nobody(void);