]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
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)
committerLennart Poettering <lennart@poettering.net>
Wed, 10 Jan 2018 17:26:03 +0000 (18:26 +0100)
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
src/nss-systemd/nss-systemd.c

index b99775c18fa72c8c5a7edd816911339beb33d1c9..17a9b5a8f1309237649de1dbcee0fed9dcaddb1b 100644 (file)
@@ -137,7 +137,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)
@@ -243,7 +244,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)
@@ -283,7 +285,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)) {
@@ -323,7 +326,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)) {
@@ -427,7 +431,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;
@@ -482,7 +487,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;
@@ -690,3 +696,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/systemd/dont-synthesize-nobody", F_OK) < 0;
+
+        return cache;
+#endif
+}
index 79adf91ee9b63a50de0cae39a43c1e1213488aff..5f0391f2b85b14d4e3c4fc024418e40a0db4bb84 100644 (file)
@@ -97,3 +97,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);
index cc641e16154f461eaa90590e15505f32d443d3fd..f75405d2e55705ff4be3f0fba782f12524b9922e 100644 (file)
@@ -136,7 +136,8 @@ enum nss_status _nss_systemd_getpwnam_r(
                         *errnop = 0;
                         return NSS_STATUS_SUCCESS;
                 }
-                if (streq(name, nobody_passwd.pw_name)) {
+                if (synthesize_nobody() &&
+                    streq(name, nobody_passwd.pw_name)) {
                         *pwd = nobody_passwd;
                         *errnop = 0;
                         return NSS_STATUS_SUCCESS;
@@ -244,7 +245,8 @@ enum nss_status _nss_systemd_getpwuid_r(
                         *errnop = 0;
                         return NSS_STATUS_SUCCESS;
                 }
-                if (uid == nobody_passwd.pw_uid) {
+                if (synthesize_nobody() &&
+                    uid == nobody_passwd.pw_uid) {
                         *pwd = nobody_passwd;
                         *errnop = 0;
                         return NSS_STATUS_SUCCESS;
@@ -351,7 +353,8 @@ enum nss_status _nss_systemd_getgrnam_r(
                         *errnop = 0;
                         return NSS_STATUS_SUCCESS;
                 }
-                if (streq(name, nobody_group.gr_name)) {
+                if (synthesize_nobody() &&
+                    streq(name, nobody_group.gr_name)) {
                         *gr = nobody_group;
                         *errnop = 0;
                         return NSS_STATUS_SUCCESS;
@@ -456,7 +459,8 @@ enum nss_status _nss_systemd_getgrgid_r(
                         *errnop = 0;
                         return NSS_STATUS_SUCCESS;
                 }
-                if (gid == nobody_group.gr_gid) {
+                if (synthesize_nobody() &&
+                    gid == nobody_group.gr_gid) {
                         *gr = nobody_group;
                         *errnop = 0;
                         return NSS_STATUS_SUCCESS;