diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2017-10-04 19:29:36 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2017-10-04 19:29:36 +0200 |
commit | 689ca202e7cc2d2818d64fa002d63cfd30add572 (patch) | |
tree | 9548aa66acf852916e8466843e78e907a663be2d /src/nss-systemd/nss-systemd.c | |
parent | Merge pull request #6974 from keszybz/clean-up-defines (diff) | |
download | systemd-689ca202e7cc2d2818d64fa002d63cfd30add572.tar.xz systemd-689ca202e7cc2d2818d64fa002d63cfd30add572.zip |
nss-systemd: if cannot open bus, then try to read user info directly (#6971)
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.
Diffstat (limited to 'src/nss-systemd/nss-systemd.c')
-rw-r--r-- | src/nss-systemd/nss-systemd.c | 125 |
1 files changed, 72 insertions, 53 deletions
diff --git a/src/nss-systemd/nss-systemd.c b/src/nss-systemd/nss-systemd.c index dcb32e1e2b..d856c4c165 100644 --- a/src/nss-systemd/nss-systemd.c +++ b/src/nss-systemd/nss-systemd.c @@ -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; |