nss-mymachines: drop support for UID/GID resolving

Now that we make the user/group name resolving available via userdb and
thus nss-systemd, we do not need the UID/GID resolving support in
nss-mymachines anymore. Let's drop it hence.

We keep the module around, since besides UID/GID resolving it also does
hostname resolving, which we care about. (One of those days we should
replace that by some Varlink logic between
nss-resolve/systemd-resolved.service too)

The hooks are kept in the NSS module, but they do not resolve anything
anymore, in order to keep compat at a maximum.
This commit is contained in:
Lennart Poettering 2020-07-07 21:58:12 +02:00
parent 4c2cf15751
commit 38ccb55731
9 changed files with 35 additions and 371 deletions

22
README
View File

@ -262,19 +262,19 @@ USERS AND GROUPS:
NSS: NSS:
systemd ships with four glibc NSS modules: systemd ships with four glibc NSS modules:
nss-myhostname resolves the local hostname to locally nss-myhostname resolves the local hostname to locally configured IP
configured IP addresses, as well as "localhost" to addresses, as well as "localhost" to 127.0.0.1/::1.
127.0.0.1/::1.
nss-resolve enables DNS resolution via the systemd-resolved nss-resolve enables DNS resolution via the systemd-resolved DNS/LLMNR
DNS/LLMNR caching stub resolver "systemd-resolved". caching stub resolver "systemd-resolved".
nss-mymachines enables resolution of all local containers registered nss-mymachines enables resolution of all local containers registered
with machined to their respective IP addresses. It also maps UID/GIDs with machined to their respective IP addresses.
ranges used by containers to useful names.
nss-systemd enables resolution of all dynamically allocated service nss-systemd enables resolution of users/group registered via the
users. (See the DynamicUser= setting in unit files.) User/Group Record Lookup API (https://systemd.io/USER_GROUP_API/),
including all dynamically allocated service users. (See the
DynamicUser= setting in unit files.)
To make use of these NSS modules, please add them to the "hosts:", To make use of these NSS modules, please add them to the "hosts:",
"passwd:" and "group:" lines in /etc/nsswitch.conf. The "resolve" "passwd:" and "group:" lines in /etc/nsswitch.conf. The "resolve"
@ -283,8 +283,8 @@ NSS:
The four modules should be used in the following order: The four modules should be used in the following order:
passwd: compat mymachines systemd passwd: compat systemd
group: compat mymachines systemd group: compat systemd
hosts: files mymachines resolve [!UNAVAIL=return] dns myhostname hosts: files mymachines resolve [!UNAVAIL=return] dns myhostname
SYSV INIT.D SCRIPTS: SYSV INIT.D SCRIPTS:

View File

@ -132,7 +132,7 @@ but downstreams are strongly advised against doing that.)
range is above the 16bit boundary. Moreover it's below the 31bit boundary, range is above the 16bit boundary. Moreover it's below the 31bit boundary,
as some broken code (specifically: the kernel's `devpts` file system) as some broken code (specifically: the kernel's `devpts` file system)
erroneously considers UIDs signed integers, and hence can't deal with values erroneously considers UIDs signed integers, and hence can't deal with values
above 2^31. The `nss-mymachines` glibc NSS module will synthesize user above 2^31. The `systemd-machined.service` service will synthesize user
database records for all UIDs assigned to a running container from this database records for all UIDs assigned to a running container from this
range. range.
@ -240,14 +240,14 @@ the artifacts the container manager persistently leaves in the system.
| 5 | `tty` group | `systemd` | `/etc/passwd` | | 5 | `tty` group | `systemd` | `/etc/passwd` |
| 6…999 | System users | Distributions | `/etc/passwd` | | 6…999 | System users | Distributions | `/etc/passwd` |
| 1000…60000 | Regular users | Distributions | `/etc/passwd` + LDAP/NIS/… | | 1000…60000 | Regular users | Distributions | `/etc/passwd` + LDAP/NIS/… |
| 60001…60513 | Human Users (homed) | `systemd` | `nss-systemd` | 60001…60513 | Human Users (homed) | `systemd` | `nss-systemd` |
| 60514…61183 | Unused | | | | 60514…61183 | Unused | | |
| 61184…65519 | Dynamic service users | `systemd` | `nss-systemd` | | 61184…65519 | Dynamic service users | `systemd` | `nss-systemd` |
| 65520…65533 | Unused | | | | 65520…65533 | Unused | | |
| 65534 | `nobody` user | Linux | `/etc/passwd` + `nss-systemd` | | 65534 | `nobody` user | Linux | `/etc/passwd` + `nss-systemd` |
| 65535 | 16bit `(uid_t) -1` | Linux | | | 65535 | 16bit `(uid_t) -1` | Linux | |
| 65536…524287 | Unused | | | | 65536…524287 | Unused | | |
| 524288…1879048191 | Container UID ranges | `systemd` | `nss-mymachines` | | 524288…1879048191 | Container UID ranges | `systemd` | `nss-systemd` |
| 1879048192…2147483647 | Unused | | | | 1879048192…2147483647 | Unused | | |
| 2147483648…4294967294 | HIC SVNT LEONES | | | | 2147483648…4294967294 | HIC SVNT LEONES | | |
| 4294967295 | 32bit `(uid_t) -1` | Linux | | | 4294967295 | 32bit `(uid_t) -1` | Linux | |

View File

@ -1,7 +1,7 @@
# This file is part of systemd. # This file is part of systemd.
passwd: compat mymachines systemd passwd: compat systemd
group: compat [SUCCESS=merge] mymachines [SUCCESS=merge] systemd group: compat [SUCCESS=merge] systemd
shadow: compat shadow: compat
hosts: files mymachines resolve [!UNAVAIL=return] dns myhostname hosts: files mymachines resolve [!UNAVAIL=return] dns myhostname

View File

@ -82,8 +82,8 @@
<command>nss-myhostname</command> correctly:</para> <command>nss-myhostname</command> correctly:</para>
<!-- synchronize with other nss-* man pages and factory/etc/nsswitch.conf --> <!-- synchronize with other nss-* man pages and factory/etc/nsswitch.conf -->
<programlisting>passwd: compat mymachines systemd <programlisting>passwd: compat systemd
group: compat mymachines systemd group: compat systemd
shadow: compat shadow: compat
# Either (untrusted network): # Either (untrusted network):

View File

@ -39,22 +39,13 @@
Note that the name that is resolved is the one registered with <command>systemd-machined</command>, which Note that the name that is resolved is the one registered with <command>systemd-machined</command>, which
may be different than the hostname configured inside of the container.</para> may be different than the hostname configured inside of the container.</para>
<para>The module also provides name resolution for user and group identifiers mapped to containers. All names from <para>To activate the NSS module, add <literal>mymachines</literal> to the line starting with
the range allocated to a given container <replaceable>container</replaceable> are exposed on the host as <literal>hosts:</literal> in <filename>/etc/nsswitch.conf</filename>.</para>
<literal>vu-<replaceable>container</replaceable>-<replaceable>uid</replaceable></literal> and
<literal>vg-<replaceable>container</replaceable>-<replaceable>gid</replaceable></literal> (see example below). This
functionality only applies to containers using user namespacing (see the description of
<option>--private-users</option> in
<citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry>).</para>
<para>To activate the NSS module, add <literal>mymachines</literal> to the lines starting with
<literal>hosts:</literal>, <literal>passwd:</literal> and <literal>group:</literal> in
<filename>/etc/nsswitch.conf</filename>.</para>
<para>It is recommended to place <literal>mymachines</literal> after the <literal>files</literal> or <para>It is recommended to place <literal>mymachines</literal> after the <literal>files</literal> or
<literal>compat</literal> entry of the <filename>/etc/nsswitch.conf</filename> lines to make sure that its mappings <literal>compat</literal> entry of the <filename>/etc/nsswitch.conf</filename> line to make sure that its
are preferred over other resolvers such as DNS, but so that <filename>/etc/hosts</filename>, mappings are preferred over other resolvers such as DNS, but so that <filename>/etc/hosts</filename>
<filename>/etc/passwd</filename> and <filename>/etc/group</filename> based mappings take precedence.</para> based mappings take precedence.</para>
</refsect1> </refsect1>
<refsect1> <refsect1>
@ -64,8 +55,8 @@
<command>nss-mymachines</command> correctly:</para> <command>nss-mymachines</command> correctly:</para>
<!-- synchronize with other nss-* man pages and factory/etc/nsswitch.conf --> <!-- synchronize with other nss-* man pages and factory/etc/nsswitch.conf -->
<programlisting>passwd: compat <command>mymachines</command> systemd <programlisting>passwd: compat systemd
group: compat <command>mymachines</command> systemd group: compat systemd
shadow: compat shadow: compat
hosts: <command>mymachines</command> resolve [!UNAVAIL=return] myhostname files dns hosts: <command>mymachines</command> resolve [!UNAVAIL=return] myhostname files dns
@ -81,7 +72,7 @@ netgroup: nis</programlisting>
</refsect1> </refsect1>
<refsect1> <refsect1>
<title>Mappings provided by <filename>nss-mymachines</filename></title> <title>Example: Mappings provided by <filename>nss-mymachines</filename></title>
<para>The container <literal>rawhide</literal> is spawned using <para>The container <literal>rawhide</literal> is spawned using
<citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry>: <citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry>:
@ -96,29 +87,6 @@ $ machinectl --max-addresses=3
MACHINE CLASS SERVICE OS VERSION ADDRESSES MACHINE CLASS SERVICE OS VERSION ADDRESSES
rawhide container systemd-nspawn fedora 30 169.254.40.164 fe80::94aa:3aff:fe7b:d4b9 rawhide container systemd-nspawn fedora 30 169.254.40.164 fe80::94aa:3aff:fe7b:d4b9
$ getent passwd vu-rawhide-0 vu-rawhide-81
vu-rawhide-0:*:20119552:65534:vu-rawhide-0:/:/usr/sbin/nologin
vu-rawhide-81:*:20119633:65534:vu-rawhide-81:/:/usr/sbin/nologin
$ getent group vg-rawhide-0 vg-rawhide-81
vg-rawhide-0:*:20119552:
vg-rawhide-81:*:20119633:
$ ps -o user:15,pid,tty,command -e|grep '^vu-rawhide'
vu-rawhide-0 692 ? /usr/lib/systemd/systemd
vu-rawhide-0 731 ? /usr/lib/systemd/systemd-journald
vu-rawhide-192 734 ? /usr/lib/systemd/systemd-networkd
vu-rawhide-193 738 ? /usr/lib/systemd/systemd-resolved
vu-rawhide-0 742 ? /usr/lib/systemd/systemd-logind
vu-rawhide-81 744 ? /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
vu-rawhide-0 746 ? /usr/sbin/sshd -D ...
vu-rawhide-0 752 ? /usr/lib/systemd/systemd --user
vu-rawhide-0 753 ? (sd-pam)
vu-rawhide-0 1628 ? login -- zbyszek
vu-rawhide-1000 1630 ? /usr/lib/systemd/systemd --user
vu-rawhide-1000 1631 ? (sd-pam)
vu-rawhide-1000 1637 pts/8 -zsh
$ ping -c1 rawhide $ ping -c1 rawhide
PING rawhide(fe80::94aa:3aff:fe7b:d4b9%ve-rawhide (fe80::94aa:3aff:fe7b:d4b9%ve-rawhide)) 56 data bytes PING rawhide(fe80::94aa:3aff:fe7b:d4b9%ve-rawhide (fe80::94aa:3aff:fe7b:d4b9%ve-rawhide)) 56 data bytes
64 bytes from fe80::94aa:3aff:fe7b:d4b9%ve-rawhide (fe80::94aa:3aff:fe7b:d4b9%ve-rawhide): icmp_seq=1 ttl=64 time=0.045 ms 64 bytes from fe80::94aa:3aff:fe7b:d4b9%ve-rawhide (fe80::94aa:3aff:fe7b:d4b9%ve-rawhide): icmp_seq=1 ttl=64 time=0.045 ms

View File

@ -63,8 +63,8 @@
correctly:</para> correctly:</para>
<!-- synchronize with other nss-* man pages and factory/etc/nsswitch.conf --> <!-- synchronize with other nss-* man pages and factory/etc/nsswitch.conf -->
<programlisting>passwd: compat mymachines systemd <programlisting>passwd: compat systemd
group: compat mymachines systemd group: compat systemd
shadow: compat shadow: compat
hosts: mymachines <command>resolve [!UNAVAIL=return]</command> myhostname files dns hosts: mymachines <command>resolve [!UNAVAIL=return]</command> myhostname files dns

View File

@ -61,8 +61,8 @@
<command>nss-systemd</command> correctly:</para> <command>nss-systemd</command> correctly:</para>
<!-- synchronize with other nss-* man pages and factory/etc/nsswitch.conf --> <!-- synchronize with other nss-* man pages and factory/etc/nsswitch.conf -->
<programlisting>passwd: compat mymachines <command>systemd</command> <programlisting>passwd: compat <command>systemd</command>
group: compat [SUCCESS=merge] mymachines [SUCCESS=merge] <command>systemd</command> group: compat [SUCCESS=merge] <command>systemd</command>
shadow: compat shadow: compat
hosts: mymachines resolve [!UNAVAIL=return] myhostname files dns hosts: mymachines resolve [!UNAVAIL=return] myhostname files dns

View File

@ -4636,7 +4636,7 @@ static int run_container(
if (!barrier_place_and_sync(&barrier)) /* #5 */ if (!barrier_place_and_sync(&barrier)) /* #5 */
return log_error_errno(SYNTHETIC_ERRNO(ESRCH), "Child died too early."); return log_error_errno(SYNTHETIC_ERRNO(ESRCH), "Child died too early.");
/* At this point we have made use of the UID we picked, and thus nss-mymachines /* At this point we have made use of the UID we picked, and thus nss-systemd/systemd-machined.service
* will make them appear in getpwuid(), thus we can release the /etc/passwd lock. */ * will make them appear in getpwuid(), thus we can release the /etc/passwd lock. */
etc_passwd_lock = safe_close(etc_passwd_lock); etc_passwd_lock = safe_close(etc_passwd_lock);

View File

@ -19,15 +19,11 @@
#include "nss-util.h" #include "nss-util.h"
#include "signal-util.h" #include "signal-util.h"
#include "string-util.h" #include "string-util.h"
#include "user-util.h"
NSS_GETHOSTBYNAME_PROTOTYPES(mymachines); NSS_GETHOSTBYNAME_PROTOTYPES(mymachines);
NSS_GETPW_PROTOTYPES(mymachines); NSS_GETPW_PROTOTYPES(mymachines);
NSS_GETGR_PROTOTYPES(mymachines); NSS_GETGR_PROTOTYPES(mymachines);
#define HOST_UID_LIMIT ((uid_t) UINT32_C(0x10000))
#define HOST_GID_LIMIT ((gid_t) UINT32_C(0x10000))
static int count_addresses(sd_bus_message *m, int af, unsigned *ret) { static int count_addresses(sd_bus_message *m, int af, unsigned *ret) {
unsigned c = 0; unsigned c = 0;
int r; int r;
@ -402,94 +398,7 @@ enum nss_status _nss_mymachines_getpwnam_r(
char *buffer, size_t buflen, char *buffer, size_t buflen,
int *errnop) { int *errnop) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; return NSS_STATUS_NOTFOUND;
_cleanup_(sd_bus_message_unrefp) sd_bus_message* reply = NULL;
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
const char *p, *e, *machine;
uint32_t mapped;
uid_t uid;
size_t l;
int r;
PROTECT_ERRNO;
BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
assert(name);
assert(pwd);
p = startswith(name, "vu-");
if (!p)
return NSS_STATUS_NOTFOUND;
e = strrchr(p, '-');
if (!e || e == p)
return NSS_STATUS_NOTFOUND;
if (e - p > HOST_NAME_MAX - 1) /* -1 for the last dash */
return NSS_STATUS_NOTFOUND;
r = parse_uid(e + 1, &uid);
if (r < 0)
return NSS_STATUS_NOTFOUND;
machine = strndupa(p, e - p);
if (!machine_name_is_valid(machine))
return NSS_STATUS_NOTFOUND;
if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS") > 0)
/* Make sure we can't deadlock if we are invoked by dbus-daemon. This way, it won't be able to resolve
* these UIDs, but that should be unproblematic as containers should never be able to connect to a bus
* running on the host. */
return NSS_STATUS_NOTFOUND;
if (avoid_deadlock()) {
r = -EDEADLK;
goto fail;
}
r = sd_bus_open_system(&bus);
if (r < 0)
goto fail;
r = bus_call_method(bus, bus_machine_mgr, "MapFromMachineUser", &error, &reply, "su", machine, (uint32_t) uid);
if (r < 0) {
if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_USER_MAPPING))
return NSS_STATUS_NOTFOUND;
goto fail;
}
r = sd_bus_message_read(reply, "u", &mapped);
if (r < 0)
goto fail;
/* Refuse to work if the mapped address is in the host UID range, or if there was no mapping at all. */
if (mapped < HOST_UID_LIMIT || mapped == uid)
return NSS_STATUS_NOTFOUND;
l = strlen(name);
if (buflen < l+1) {
UNPROTECT_ERRNO;
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
memcpy(buffer, name, l+1);
pwd->pw_name = buffer;
pwd->pw_uid = mapped;
pwd->pw_gid = GID_NOBODY;
pwd->pw_gecos = buffer;
pwd->pw_passwd = (char*) "*"; /* locked */
pwd->pw_dir = (char*) "/";
pwd->pw_shell = (char*) NOLOGIN;
return NSS_STATUS_SUCCESS;
fail:
UNPROTECT_ERRNO;
*errnop = -r;
return NSS_STATUS_UNAVAIL;
} }
enum nss_status _nss_mymachines_getpwuid_r( enum nss_status _nss_mymachines_getpwuid_r(
@ -498,162 +407,16 @@ enum nss_status _nss_mymachines_getpwuid_r(
char *buffer, size_t buflen, char *buffer, size_t buflen,
int *errnop) { int *errnop) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; return NSS_STATUS_NOTFOUND;
_cleanup_(sd_bus_message_unrefp) sd_bus_message* reply = NULL;
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
const char *machine;
uint32_t mapped;
int r;
PROTECT_ERRNO;
BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
if (!uid_is_valid(uid))
return NSS_STATUS_NOTFOUND;
/* We consider all uids < 65536 host uids */
if (uid < HOST_UID_LIMIT)
return NSS_STATUS_NOTFOUND;
if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS") > 0)
return NSS_STATUS_NOTFOUND;
if (avoid_deadlock()) {
r = -EDEADLK;
goto fail;
}
r = sd_bus_open_system(&bus);
if (r < 0)
goto fail;
r = bus_call_method(bus, bus_machine_mgr, "MapToMachineUser", &error, &reply, "u", (uint32_t) uid);
if (r < 0) {
if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_USER_MAPPING))
return NSS_STATUS_NOTFOUND;
goto fail;
}
r = sd_bus_message_read(reply, "sou", &machine, NULL, &mapped);
if (r < 0)
goto fail;
if (mapped == uid)
return NSS_STATUS_NOTFOUND;
if (snprintf(buffer, buflen, "vu-%s-" UID_FMT, machine, (uid_t) mapped) >= (int) buflen) {
UNPROTECT_ERRNO;
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
pwd->pw_name = buffer;
pwd->pw_uid = uid;
pwd->pw_gid = GID_NOBODY;
pwd->pw_gecos = buffer;
pwd->pw_passwd = (char*) "*"; /* locked */
pwd->pw_dir = (char*) "/";
pwd->pw_shell = (char*) NOLOGIN;
return NSS_STATUS_SUCCESS;
fail:
UNPROTECT_ERRNO;
*errnop = -r;
return NSS_STATUS_UNAVAIL;
} }
#pragma GCC diagnostic ignored "-Wsizeof-pointer-memaccess"
enum nss_status _nss_mymachines_getgrnam_r( enum nss_status _nss_mymachines_getgrnam_r(
const char *name, const char *name,
struct group *gr, struct group *gr,
char *buffer, size_t buflen, char *buffer, size_t buflen,
int *errnop) { int *errnop) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; return NSS_STATUS_NOTFOUND;
_cleanup_(sd_bus_message_unrefp) sd_bus_message* reply = NULL;
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
const char *p, *e, *machine;
uint32_t mapped;
uid_t gid;
size_t l;
int r;
PROTECT_ERRNO;
BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
assert(name);
assert(gr);
p = startswith(name, "vg-");
if (!p)
return NSS_STATUS_NOTFOUND;
e = strrchr(p, '-');
if (!e || e == p)
return NSS_STATUS_NOTFOUND;
if (e - p > HOST_NAME_MAX - 1) /* -1 for the last dash */
return NSS_STATUS_NOTFOUND;
r = parse_gid(e + 1, &gid);
if (r < 0)
return NSS_STATUS_NOTFOUND;
machine = strndupa(p, e - p);
if (!machine_name_is_valid(machine))
return NSS_STATUS_NOTFOUND;
if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS") > 0)
return NSS_STATUS_NOTFOUND;
if (avoid_deadlock()) {
r = -EDEADLK;
goto fail;
}
r = sd_bus_open_system(&bus);
if (r < 0)
goto fail;
r = bus_call_method(bus, bus_machine_mgr, "MapFromMachineGroup", &error, &reply, "su", machine, (uint32_t) gid);
if (r < 0) {
if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_GROUP_MAPPING))
return NSS_STATUS_NOTFOUND;
goto fail;
}
r = sd_bus_message_read(reply, "u", &mapped);
if (r < 0)
goto fail;
if (mapped < HOST_GID_LIMIT || mapped == gid)
return NSS_STATUS_NOTFOUND;
l = sizeof(char*) + strlen(name) + 1;
if (buflen < l) {
UNPROTECT_ERRNO;
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
memzero(buffer, sizeof(char*));
strcpy(buffer + sizeof(char*), name);
gr->gr_name = buffer + sizeof(char*);
gr->gr_gid = mapped;
gr->gr_passwd = (char*) "*"; /* locked */
gr->gr_mem = (char**) buffer;
return NSS_STATUS_SUCCESS;
fail:
UNPROTECT_ERRNO;
*errnop = -r;
return NSS_STATUS_UNAVAIL;
} }
enum nss_status _nss_mymachines_getgrgid_r( enum nss_status _nss_mymachines_getgrgid_r(
@ -662,72 +425,5 @@ enum nss_status _nss_mymachines_getgrgid_r(
char *buffer, size_t buflen, char *buffer, size_t buflen,
int *errnop) { int *errnop) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; return NSS_STATUS_NOTFOUND;
_cleanup_(sd_bus_message_unrefp) sd_bus_message* reply = NULL;
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
const char *machine;
uint32_t mapped;
int r;
PROTECT_ERRNO;
BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
if (!gid_is_valid(gid))
return NSS_STATUS_NOTFOUND;
/* We consider all gids < 65536 host gids */
if (gid < HOST_GID_LIMIT)
return NSS_STATUS_NOTFOUND;
if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS") > 0)
return NSS_STATUS_NOTFOUND;
if (avoid_deadlock()) {
r = -EDEADLK;
goto fail;
}
r = sd_bus_open_system(&bus);
if (r < 0)
goto fail;
r = bus_call_method(bus, bus_machine_mgr, "MapToMachineGroup", &error, &reply, "u", (uint32_t) gid);
if (r < 0) {
if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_GROUP_MAPPING))
return NSS_STATUS_NOTFOUND;
goto fail;
}
r = sd_bus_message_read(reply, "sou", &machine, NULL, &mapped);
if (r < 0)
goto fail;
if (mapped == gid)
return NSS_STATUS_NOTFOUND;
if (buflen < sizeof(char*) + 1) {
UNPROTECT_ERRNO;
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
memzero(buffer, sizeof(char*));
if (snprintf(buffer + sizeof(char*), buflen - sizeof(char*), "vg-%s-" GID_FMT, machine, (gid_t) mapped) >= (int) buflen) {
UNPROTECT_ERRNO;
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
gr->gr_name = buffer + sizeof(char*);
gr->gr_gid = gid;
gr->gr_passwd = (char*) "*"; /* locked */
gr->gr_mem = (char**) buffer;
return NSS_STATUS_SUCCESS;
fail:
UNPROTECT_ERRNO;
*errnop = -r;
return NSS_STATUS_UNAVAIL;
} }