summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2016-07-14 19:19:49 +0200
committerLennart Poettering <lennart@poettering.net>2016-07-22 15:53:45 +0200
commit409093fe10685ed55915ef256f09cdf144b6528b (patch)
treea1cf99e3f7bece318f7c12e53c2703938d8a8178
parent6f3e79859d91aecb3a75097b69fb9cba086b2cb1 (diff)
nss: add new "nss-systemd" NSS module for mapping dynamic users
With this NSS module all dynamic service users will be resolvable via NSS like any real user.
-rw-r--r--Makefile-man.am7
-rw-r--r--Makefile.am21
-rw-r--r--README21
-rw-r--r--man/nss-myhostname.xml5
-rw-r--r--man/nss-mymachines.xml5
-rw-r--r--man/nss-resolve.xml7
-rw-r--r--man/nss-systemd.xml107
-rw-r--r--src/core/execute.c6
l---------src/nss-systemd/Makefile1
-rw-r--r--src/nss-systemd/nss-systemd.c332
-rw-r--r--src/nss-systemd/nss-systemd.sym17
11 files changed, 515 insertions, 14 deletions
diff --git a/Makefile-man.am b/Makefile-man.am
index 8ab733360d..3ac1906a4a 100644
--- a/Makefile-man.am
+++ b/Makefile-man.am
@@ -23,6 +23,7 @@ MANPAGES += \
man/localtime.5 \
man/machine-id.5 \
man/machine-info.5 \
+ man/nss-systemd.8 \
man/os-release.5 \
man/sd-bus-errors.3 \
man/sd-bus.3 \
@@ -255,6 +256,7 @@ MANPAGES_ALIAS += \
man/SD_WARNING.3 \
man/init.1 \
man/journald.conf.d.5 \
+ man/libnss_systemd.so.2.8 \
man/poweroff.8 \
man/reboot.8 \
man/sd_bus_creds_get_audit_login_uid.3 \
@@ -587,6 +589,7 @@ man/SD_NOTICE.3: man/sd-daemon.3
man/SD_WARNING.3: man/sd-daemon.3
man/init.1: man/systemd.1
man/journald.conf.d.5: man/journald.conf.5
+man/libnss_systemd.so.2.8: man/nss-systemd.8
man/poweroff.8: man/halt.8
man/reboot.8: man/halt.8
man/sd_bus_creds_get_audit_login_uid.3: man/sd_bus_creds_get_pid.3
@@ -1071,6 +1074,9 @@ man/init.html: man/systemd.html
man/journald.conf.d.html: man/journald.conf.html
$(html-alias)
+man/libnss_systemd.so.2.html: man/nss-systemd.html
+ $(html-alias)
+
man/poweroff.html: man/halt.html
$(html-alias)
@@ -2519,6 +2525,7 @@ EXTRA_DIST += \
man/nss-myhostname.xml \
man/nss-mymachines.xml \
man/nss-resolve.xml \
+ man/nss-systemd.xml \
man/os-release.xml \
man/pam_systemd.xml \
man/resolved.conf.xml \
diff --git a/Makefile.am b/Makefile.am
index 3d5ce1e2c3..a4241122d5 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -5002,6 +5002,27 @@ manual_tests += \
test-nss
# ------------------------------------------------------------------------------
+libnss_systemd_la_SOURCES = \
+ src/nss-systemd/nss-systemd.sym \
+ src/nss-systemd/nss-systemd.c
+
+libnss_systemd_la_LDFLAGS = \
+ $(AM_LDFLAGS) \
+ -module \
+ -export-dynamic \
+ -avoid-version \
+ -shared \
+ -shrext .so.2 \
+ -Wl,--version-script=$(top_srcdir)/src/nss-systemd/nss-systemd.sym
+
+libnss_systemd_la_LIBADD = \
+ libsystemd-internal.la \
+ libbasic.la
+
+lib_LTLIBRARIES += \
+ libnss_systemd.la
+
+# ------------------------------------------------------------------------------
if HAVE_MYHOSTNAME
libnss_myhostname_la_SOURCES = \
src/nss-myhostname/nss-myhostname.sym \
diff --git a/README b/README
index ca8993cb12..19c15a70b0 100644
--- a/README
+++ b/README
@@ -201,7 +201,7 @@ USERS AND GROUPS:
"systemd-coredump" system user and group to exist.
NSS:
- systemd ships with three NSS modules:
+ systemd ships with four glibc NSS modules:
nss-myhostname resolves the local hostname to locally
configured IP addresses, as well as "localhost" to
@@ -210,15 +210,22 @@ NSS:
nss-resolve enables DNS resolution via the systemd-resolved
DNS/LLMNR caching stub resolver "systemd-resolved".
- nss-mymachines enables resolution of all local containers
- registered with machined to their respective IP addresses.
+ nss-mymachines enables resolution of all local containers registered
+ with machined to their respective IP addresses. It also maps UID/GIDs
+ ranges used by containers to useful names.
- To make use of these NSS modules, please add them to the
- "hosts: " line in /etc/nsswitch.conf. The "resolve" module
- should replace the glibc "dns" module in this file.
+ nss-systemd enables resolution of all dynamically allocated service
+ users. (See the DynamicUser= setting in unit files.)
- The three modules should be used in the following order:
+ To make use of these NSS modules, please add them to the "hosts:",
+ "passwd:" and "group:" lines in /etc/nsswitch.conf. The "resolve"
+ module should replace the glibc "dns" module in this file (and don't
+ worry, it chain-loads the "dns" module if it can't talk to resolved).
+ The four modules should be used in the following order:
+
+ passwd: compat mymachines systemd
+ group: compat mymachines systemd
hosts: files mymachines resolve myhostname
SYSV INIT.D SCRIPTS:
diff --git a/man/nss-myhostname.xml b/man/nss-myhostname.xml
index a920ec334f..b1daaba02b 100644
--- a/man/nss-myhostname.xml
+++ b/man/nss-myhostname.xml
@@ -106,8 +106,8 @@
<para>Here is an example <filename>/etc/nsswitch.conf</filename> file that enables
<command>nss-myhostname</command> correctly:</para>
-<programlisting>passwd: compat mymachines
-group: compat mymachines
+<programlisting>passwd: compat mymachines systemd
+group: compat mymachines systemd
shadow: compat
hosts: files mymachines resolve <command>myhostname</command>
@@ -138,6 +138,7 @@ netgroup: nis</programlisting>
<title>See Also</title>
<para>
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>nss-systemd</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>nss-resolve</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>nss-mymachines</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry project='man-pages'><refentrytitle>nsswitch.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
diff --git a/man/nss-mymachines.xml b/man/nss-mymachines.xml
index ec047449bf..a70119e256 100644
--- a/man/nss-mymachines.xml
+++ b/man/nss-mymachines.xml
@@ -82,8 +82,8 @@
<para>Here is an example <filename>/etc/nsswitch.conf</filename> file that enables
<command>nss-mymachines</command> correctly:</para>
- <programlisting>passwd: compat <command>mymachines</command>
-group: compat <command>mymachines</command>
+ <programlisting>passwd: compat <command>mymachines</command> systemd
+group: compat <command>mymachines</command> systemd
shadow: compat
hosts: files <command>mymachines</command> resolve myhostname
@@ -103,6 +103,7 @@ netgroup: nis</programlisting>
<para>
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-machined.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>nss-systemd</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>nss-resolve</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>nss-myhostname</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry project='man-pages'><refentrytitle>nsswitch.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
diff --git a/man/nss-resolve.xml b/man/nss-resolve.xml
index d9e56453e8..e6cc1d982a 100644
--- a/man/nss-resolve.xml
+++ b/man/nss-resolve.xml
@@ -81,8 +81,8 @@
<para>Here is an example <filename>/etc/nsswitch.conf</filename> file that enables <command>nss-resolve</command>
correctly:</para>
-<programlisting>passwd: compat mymachines
-group: compat mymachines
+<programlisting>passwd: compat mymachines systemd
+group: compat mymachines systemd
shadow: compat
hosts: files mymachines <command>resolve</command> myhostname
@@ -102,8 +102,9 @@ netgroup: nis</programlisting>
<para>
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-resolved</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>nss-mymachines</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>nss-systemd</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>nss-myhostname</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>nss-mymachines</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry project='man-pages'><refentrytitle>nsswitch.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
</para>
</refsect1>
diff --git a/man/nss-systemd.xml b/man/nss-systemd.xml
new file mode 100644
index 0000000000..4228372e51
--- /dev/null
+++ b/man/nss-systemd.xml
@@ -0,0 +1,107 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+ This file is part of systemd.
+
+ Copyright 2016 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="nss-systemd">
+
+ <refentryinfo>
+ <title>nss-systemd</title>
+ <productname>systemd</productname>
+
+ <authorgroup>
+ <author>
+ <contrib>Developer</contrib>
+ <firstname>Lennart</firstname>
+ <surname>Poettering</surname>
+ <email>lennart@poettering.net</email>
+ </author>
+ </authorgroup>
+ </refentryinfo>
+
+ <refmeta>
+ <refentrytitle>nss-systemd</refentrytitle>
+ <manvolnum>8</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>nss-systemd</refname>
+ <refname>libnss_systemd.so.2</refname>
+ <refpurpose>Provide UNIX user and group name resolution for dynamic users and groups.</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <para><filename>libnss_systemd.so.2</filename></para>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para><command>nss-systemd</command> is a plug-in module for the GNU Name Service Switch (NSS) functionality of the
+ GNU C Library (<command>glibc</command>), providing UNIX user and group name resolution for dynamic users and
+ groups allocated through the <varname>DynamicUser=</varname> option in systemd unit files. See
+ <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry> for details on
+ this option.</para>
+
+ <para>To activate the NSS module, add <literal>systemd</literal> to the lines starting with
+ <literal>passwd:</literal> and <literal>group:</literal> in <filename>/etc/nsswitch.conf</filename>.</para>
+
+ <para>It is recommended to place <literal>systemd</literal> after the <literal>files</literal> or
+ <literal>compat</literal> entry of the <filename>/etc/nsswitch.conf</filename> lines so that
+ <filename>/etc/passwd</filename> and <filename>/etc/group</filename> based mappings take precedence.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Example</title>
+
+ <para>Here is an example <filename>/etc/nsswitch.conf</filename> file that enables
+ <command>nss-systemd</command> correctly:</para>
+
+ <programlisting>passwd: compat mymachines <command>systemd</command>
+group: compat mymachines <command>systemd</command>
+shadow: compat
+
+hosts: files mymachines resolve myhostname
+networks: files
+
+protocols: db files
+services: db files
+ethers: db files
+rpc: db files
+
+netgroup: nis</programlisting>
+
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+ <para>
+ <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>nss-resolve</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>nss-myhostname</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>nss-mymachines</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry project='man-pages'><refentrytitle>nsswitch.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+ <citerefentry project='man-pages'><refentrytitle>getent</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/src/core/execute.c b/src/core/execute.c
index c186f2a705..26e9cd5339 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -1670,6 +1670,12 @@ static int exec_child(
if (context->dynamic_user && dcreds) {
+ /* Make sure we bypass our own NSS module for any NSS checks */
+ if (putenv((char*) "SYSTEMD_NSS_DYNAMIC_BYPASS=1") != 0) {
+ *exit_status = EXIT_USER;
+ return -errno;
+ }
+
r = dynamic_creds_realize(dcreds, &uid, &gid);
if (r < 0) {
*exit_status = EXIT_USER;
diff --git a/src/nss-systemd/Makefile b/src/nss-systemd/Makefile
new file mode 120000
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/nss-systemd/Makefile
@@ -0,0 +1 @@
+../Makefile \ No newline at end of file
diff --git a/src/nss-systemd/nss-systemd.c b/src/nss-systemd/nss-systemd.c
new file mode 100644
index 0000000000..e7a4393bb0
--- /dev/null
+++ b/src/nss-systemd/nss-systemd.c
@@ -0,0 +1,332 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2016 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <nss.h>
+
+#include "sd-bus.h"
+
+#include "bus-common-errors.h"
+#include "env-util.h"
+#include "macro.h"
+#include "nss-util.h"
+#include "signal-util.h"
+#include "user-util.h"
+#include "util.h"
+
+NSS_GETPW_PROTOTYPES(systemd);
+NSS_GETGR_PROTOTYPES(systemd);
+
+enum nss_status _nss_systemd_getpwnam_r(
+ const char *name,
+ struct passwd *pwd,
+ char *buffer, size_t buflen,
+ int *errnop) {
+
+ _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;
+ uint32_t translated;
+ size_t l;
+ int r;
+
+ BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
+
+ assert(name);
+ assert(pwd);
+
+ /* Make sure that we don't go in circles when allocating a dynamic UID by checking our own database */
+ if (getenv_bool("SYSTEMD_NSS_DYNAMIC_BYPASS") > 0)
+ goto not_found;
+
+ r = sd_bus_open_system(&bus);
+ if (r < 0)
+ goto fail;
+
+ r = sd_bus_call_method(bus,
+ "org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ "LookupDynamicUserByName",
+ &error,
+ &reply,
+ "s",
+ name);
+ if (r < 0) {
+ if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_DYNAMIC_USER))
+ goto not_found;
+
+ goto fail;
+ }
+
+ r = sd_bus_message_read(reply, "u", &translated);
+ if (r < 0)
+ goto fail;
+
+ l = strlen(name);
+ if (buflen < l+1) {
+ *errnop = ENOMEM;
+ return NSS_STATUS_TRYAGAIN;
+ }
+
+ memcpy(buffer, name, l+1);
+
+ pwd->pw_name = buffer;
+ pwd->pw_uid = (uid_t) translated;
+ pwd->pw_gid = (uid_t) translated;
+ pwd->pw_gecos = (char*) "Dynamic User";
+ pwd->pw_passwd = (char*) "*"; /* locked */
+ pwd->pw_dir = (char*) "/";
+ pwd->pw_shell = (char*) "/sbin/nologin";
+
+ *errnop = 0;
+ return NSS_STATUS_SUCCESS;
+
+not_found:
+ *errnop = 0;
+ return NSS_STATUS_NOTFOUND;
+
+fail:
+ *errnop = -r;
+ return NSS_STATUS_UNAVAIL;
+}
+
+enum nss_status _nss_systemd_getpwuid_r(
+ uid_t uid,
+ struct passwd *pwd,
+ char *buffer, size_t buflen,
+ int *errnop) {
+
+ _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;
+ const char *translated;
+ size_t l;
+ int r;
+
+ BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
+
+ if (!uid_is_valid(uid)) {
+ r = -EINVAL;
+ goto fail;
+ }
+
+ if (uid <= SYSTEM_UID_MAX)
+ goto not_found;
+
+ if (getenv_bool("SYSTEMD_NSS_DYNAMIC_BYPASS") > 0)
+ goto not_found;
+
+ r = sd_bus_open_system(&bus);
+ if (r < 0)
+ goto fail;
+
+ r = sd_bus_call_method(bus,
+ "org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ "LookupDynamicUserByUID",
+ &error,
+ &reply,
+ "u",
+ (uint32_t) uid);
+ if (r < 0) {
+ if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_DYNAMIC_USER))
+ goto not_found;
+
+ goto fail;
+ }
+
+ r = sd_bus_message_read(reply, "s", &translated);
+ if (r < 0)
+ goto fail;
+
+ l = strlen(translated) + 1;
+ if (buflen < l) {
+ *errnop = ENOMEM;
+ return NSS_STATUS_TRYAGAIN;
+ }
+
+ memcpy(buffer, translated, l);
+
+ pwd->pw_name = buffer;
+ pwd->pw_uid = uid;
+ pwd->pw_gid = uid;
+ pwd->pw_gecos = (char*) "Dynamic User";
+ pwd->pw_passwd = (char*) "*"; /* locked */
+ pwd->pw_dir = (char*) "/";
+ pwd->pw_shell = (char*) "/sbin/nologin";
+
+ *errnop = 0;
+ return NSS_STATUS_SUCCESS;
+
+not_found:
+ *errnop = 0;
+ return NSS_STATUS_NOTFOUND;
+
+fail:
+ *errnop = -r;
+ return NSS_STATUS_UNAVAIL;
+}
+
+enum nss_status _nss_systemd_getgrnam_r(
+ const char *name,
+ struct group *gr,
+ char *buffer, size_t buflen,
+ int *errnop) {
+
+ _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;
+ uint32_t translated;
+ size_t l;
+ int r;
+
+ BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
+
+ assert(name);
+ assert(gr);
+
+ if (getenv_bool("SYSTEMD_NSS_DYNAMIC_BYPASS") > 0)
+ goto not_found;
+
+ r = sd_bus_open_system(&bus);
+ if (r < 0)
+ goto fail;
+
+ r = sd_bus_call_method(bus,
+ "org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ "LookupDynamicUserByName",
+ &error,
+ &reply,
+ "s",
+ name);
+ if (r < 0) {
+ if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_DYNAMIC_USER))
+ goto not_found;
+
+ goto fail;
+ }
+
+ r = sd_bus_message_read(reply, "u", &translated);
+ if (r < 0)
+ goto fail;
+
+ l = sizeof(char*) + strlen(name) + 1;
+ if (buflen < l) {
+ *errnop = ENOMEM;
+ return NSS_STATUS_TRYAGAIN;
+ }
+
+ memzero(buffer, sizeof(char*));
+ strcpy(buffer + sizeof(char*), name);
+
+ gr->gr_name = buffer + sizeof(char*);
+ gr->gr_gid = (gid_t) translated;
+ gr->gr_passwd = (char*) "*"; /* locked */
+ gr->gr_mem = (char**) buffer;
+
+ *errnop = 0;
+ return NSS_STATUS_SUCCESS;
+
+not_found:
+ *errnop = 0;
+ return NSS_STATUS_NOTFOUND;
+
+fail:
+ *errnop = -r;
+ return NSS_STATUS_UNAVAIL;
+}
+
+enum nss_status _nss_systemd_getgrgid_r(
+ gid_t gid,
+ struct group *gr,
+ char *buffer, size_t buflen,
+ int *errnop) {
+
+ _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;
+ const char *translated;
+ size_t l;
+ int r;
+
+ BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
+
+ if (!gid_is_valid(gid)) {
+ r = -EINVAL;
+ goto fail;
+ }
+
+ if (gid <= SYSTEM_GID_MAX)
+ goto not_found;
+
+ if (getenv_bool("SYSTEMD_NSS_DYNAMIC_BYPASS") > 0)
+ goto not_found;
+
+ r = sd_bus_open_system(&bus);
+ if (r < 0)
+ goto fail;
+
+ r = sd_bus_call_method(bus,
+ "org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ "LookupDynamicUserByUID",
+ &error,
+ &reply,
+ "u",
+ (uint32_t) gid);
+ if (r < 0) {
+ if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_DYNAMIC_USER))
+ goto not_found;
+
+ goto fail;
+ }
+
+ r = sd_bus_message_read(reply, "s", &translated);
+ if (r < 0)
+ goto fail;
+
+ l = sizeof(char*) + strlen(translated) + 1;
+ if (buflen < l) {
+ *errnop = ENOMEM;
+ return NSS_STATUS_TRYAGAIN;
+ }
+
+ memzero(buffer, sizeof(char*));
+ strcpy(buffer + sizeof(char*), translated);
+
+ gr->gr_name = buffer + sizeof(char*);
+ gr->gr_gid = gid;
+ gr->gr_passwd = (char*) "*"; /* locked */
+ gr->gr_mem = (char**) buffer;
+
+ *errnop = 0;
+ return NSS_STATUS_SUCCESS;
+
+not_found:
+ *errnop = 0;
+ return NSS_STATUS_NOTFOUND;
+
+fail:
+ *errnop = -r;
+ return NSS_STATUS_UNAVAIL;
+}
diff --git a/src/nss-systemd/nss-systemd.sym b/src/nss-systemd/nss-systemd.sym
new file mode 100644
index 0000000000..955078788a
--- /dev/null
+++ b/src/nss-systemd/nss-systemd.sym
@@ -0,0 +1,17 @@
+/***
+ This file is part of systemd.
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+***/
+
+{
+global:
+ _nss_systemd_getpwnam_r;
+ _nss_systemd_getpwuid_r;
+ _nss_systemd_getgrnam_r;
+ _nss_systemd_getgrgid_r;
+local: *;
+};