]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
nss-systemd: if cannot open bus, then try to read user info directly (#6971)
authorYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 4 Oct 2017 17:29:36 +0000 (02:29 +0900)
committerLennart Poettering <lennart@poettering.net>
Wed, 4 Oct 2017 17:29:36 +0000 (19:29 +0200)
If sd_bus_open_system() fail, then try to read information about
dynamic users from /run/systemd/dynamic-uid.
This makes services can successfully call getpwuid() or their friends
even if dbus.service is not started yet.

Fixes #6967.

src/nss-systemd/nss-systemd.c

index dcb32e1e2babc5f3a7f8bc9d1fe0a5d25993579e..d856c4c165d06dd8802f4764256a6871f1444a5c 100644 (file)
@@ -116,7 +116,7 @@ enum nss_status _nss_systemd_getpwnam_r(
 
         uint32_t translated;
         size_t l;
-        int r;
+        int bypass, r;
 
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
 
@@ -146,23 +146,17 @@ enum nss_status _nss_systemd_getpwnam_r(
         if (getenv_bool_secure("SYSTEMD_NSS_DYNAMIC_BYPASS") > 0)
                 goto not_found;
 
-        if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS") > 0) {
-
-                /* Access the dynamic UID allocation directly if we are called from dbus-daemon, see above. */
-                r = direct_lookup_name(name, (uid_t*) &translated);
-                if (r == -ENOENT)
-                        goto not_found;
-                if (r < 0)
-                        goto fail;
-
-        } else {
+        bypass = getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS");
+        if (bypass <= 0) {
                 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
                 _cleanup_(sd_bus_message_unrefp) sd_bus_message* reply = NULL;
                 _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
 
                 r = sd_bus_open_system(&bus);
-                if (r < 0)
-                        goto fail;
+                if (r < 0) {
+                        bypass = 1;
+                        goto direct_lookup;
+                }
 
                 r = sd_bus_call_method(bus,
                                        "org.freedesktop.systemd1",
@@ -185,6 +179,16 @@ enum nss_status _nss_systemd_getpwnam_r(
                         goto fail;
         }
 
+direct_lookup:
+        if (bypass > 0) {
+                /* Access the dynamic UID allocation directly if we are called from dbus-daemon, see above. */
+                r = direct_lookup_name(name, (uid_t*) &translated);
+                if (r == -ENOENT)
+                        goto not_found;
+                if (r < 0)
+                        goto fail;
+        }
+
         l = strlen(name);
         if (buflen < l+1) {
                 *errnop = ERANGE;
@@ -225,7 +229,7 @@ enum nss_status _nss_systemd_getpwuid_r(
         _cleanup_free_ char *direct = NULL;
         const char *translated;
         size_t l;
-        int r;
+        int bypass, r;
 
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
 
@@ -252,20 +256,13 @@ enum nss_status _nss_systemd_getpwuid_r(
         if (getenv_bool_secure("SYSTEMD_NSS_DYNAMIC_BYPASS") > 0)
                 goto not_found;
 
-        if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS") > 0) {
-
-                r = direct_lookup_uid(uid, &direct);
-                if (r == -ENOENT)
-                        goto not_found;
-                if (r < 0)
-                        goto fail;
-
-                translated = direct;
-
-        } else {
+        bypass = getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS");
+        if (bypass <= 0) {
                 r = sd_bus_open_system(&bus);
-                if (r < 0)
-                        goto fail;
+                if (r < 0) {
+                        bypass = 1;
+                        goto direct_lookup;
+                }
 
                 r = sd_bus_call_method(bus,
                                        "org.freedesktop.systemd1",
@@ -288,6 +285,18 @@ enum nss_status _nss_systemd_getpwuid_r(
                         goto fail;
         }
 
+direct_lookup:
+        if (bypass > 0) {
+                r = direct_lookup_uid(uid, &direct);
+                if (r == -ENOENT)
+                        goto not_found;
+                if (r < 0)
+                        goto fail;
+
+                translated = direct;
+
+        }
+
         l = strlen(translated) + 1;
         if (buflen < l) {
                 *errnop = ERANGE;
@@ -324,7 +333,7 @@ enum nss_status _nss_systemd_getgrnam_r(
 
         uint32_t translated;
         size_t l;
-        int r;
+        int bypass, r;
 
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
 
@@ -351,23 +360,17 @@ enum nss_status _nss_systemd_getgrnam_r(
         if (getenv_bool_secure("SYSTEMD_NSS_DYNAMIC_BYPASS") > 0)
                 goto not_found;
 
-        if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS") > 0) {
-
-                /* Access the dynamic GID allocation directly if we are called from dbus-daemon, see above. */
-                r = direct_lookup_name(name, (uid_t*) &translated);
-                if (r == -ENOENT)
-                        goto not_found;
-                if (r < 0)
-                        goto fail;
-        } else {
-
+        bypass = getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS");
+        if (bypass <= 0) {
                 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
                 _cleanup_(sd_bus_message_unrefp) sd_bus_message* reply = NULL;
                 _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
 
                 r = sd_bus_open_system(&bus);
-                if (r < 0)
-                        goto fail;
+                if (r < 0) {
+                        bypass = 1;
+                        goto direct_lookup;
+                }
 
                 r = sd_bus_call_method(bus,
                                        "org.freedesktop.systemd1",
@@ -390,6 +393,16 @@ enum nss_status _nss_systemd_getgrnam_r(
                         goto fail;
         }
 
+direct_lookup:
+        if (bypass > 0) {
+                /* Access the dynamic GID allocation directly if we are called from dbus-daemon, see above. */
+                r = direct_lookup_name(name, (uid_t*) &translated);
+                if (r == -ENOENT)
+                        goto not_found;
+                if (r < 0)
+                        goto fail;
+        }
+
         l = sizeof(char*) + strlen(name) + 1;
         if (buflen < l) {
                 *errnop = ERANGE;
@@ -428,7 +441,7 @@ enum nss_status _nss_systemd_getgrgid_r(
         _cleanup_free_ char *direct = NULL;
         const char *translated;
         size_t l;
-        int r;
+        int bypass, r;
 
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
 
@@ -455,19 +468,13 @@ enum nss_status _nss_systemd_getgrgid_r(
         if (getenv_bool_secure("SYSTEMD_NSS_DYNAMIC_BYPASS") > 0)
                 goto not_found;
 
-        if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS") > 0) {
-
-                r = direct_lookup_uid(gid, &direct);
-                if (r == -ENOENT)
-                        goto not_found;
-                if (r < 0)
-                        goto fail;
-
-                translated = direct;
-        } else {
+        bypass = getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS");
+        if (bypass <= 0) {
                 r = sd_bus_open_system(&bus);
-                if (r < 0)
-                        goto fail;
+                if (r < 0) {
+                        bypass = 1;
+                        goto direct_lookup;
+                }
 
                 r = sd_bus_call_method(bus,
                                        "org.freedesktop.systemd1",
@@ -490,6 +497,18 @@ enum nss_status _nss_systemd_getgrgid_r(
                         goto fail;
         }
 
+direct_lookup:
+        if (bypass > 0) {
+
+                r = direct_lookup_uid(gid, &direct);
+                if (r == -ENOENT)
+                        goto not_found;
+                if (r < 0)
+                        goto fail;
+
+                translated = direct;
+        }
+
         l = sizeof(char*) + strlen(translated) + 1;
         if (buflen < l) {
                 *errnop = ERANGE;