Skip to content

Commit

Permalink
sysusers: handle NSS errors gracefully
Browse files Browse the repository at this point in the history
If the io.systemd.DynamicUser or io.systemd.Machine files exist,
but nothing is listening on them, the nss-systemd module returns
ECONNREFUSED and systemd-sysusers fails to creat the user/group.

This is problematic when ran by packaging scripts, as the package
assumes that after this has run, the user/group exist and can
be used. adduser does not fail in the same situation.

Change sysusers to print a loud warning but otherwise continue
when NSS returns an error.

(cherry picked from commit fc9938d6f8e7081df5420bf88bf98f683b1391c0)
(cherry picked from commit abba1e6bc29b7e07354ca23906c6f485ba245a1a)
(cherry picked from commit 0f51875)
(cherry picked from commit dffa62c)
(cherry picked from commit af2eb43)
  • Loading branch information
bluca committed Jul 6, 2024
1 parent 0e8ec38 commit abd96fd
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 6 deletions.
12 changes: 6 additions & 6 deletions src/sysusers/sysusers.c
Original file line number Diff line number Diff line change
Expand Up @@ -978,7 +978,7 @@ static int uid_is_ok(uid_t uid, const char *name, bool check_with_gid) {
if (p)
return 0;
if (!IN_SET(errno, 0, ENOENT))
return -errno;
log_warning_errno(errno, "Unexpected failure while looking up UID '" UID_FMT "' via NSS, assuming it doesn't exist: %m", uid);

if (check_with_gid) {
errno = 0;
Expand All @@ -987,7 +987,7 @@ static int uid_is_ok(uid_t uid, const char *name, bool check_with_gid) {
if (!streq(g->gr_name, name))
return 0;
} else if (!IN_SET(errno, 0, ENOENT))
return -errno;
log_warning_errno(errno, "Unexpected failure while looking up GID '" GID_FMT "' via NSS, assuming it doesn't exist: %m", uid);
}
}

Expand Down Expand Up @@ -1092,7 +1092,7 @@ static int add_user(Item *i) {
return 0;
}
if (!errno_is_not_exists(errno))
return log_error_errno(errno, "Failed to check if user %s already exists: %m", i->name);
log_warning_errno(errno, "Unexpected failure while looking up user '%s' via NSS, assuming it doesn't exist: %m", i->name);
}

/* Try to use the suggested numeric UID */
Expand Down Expand Up @@ -1198,15 +1198,15 @@ static int gid_is_ok(gid_t gid, bool check_with_uid) {
if (g)
return 0;
if (!IN_SET(errno, 0, ENOENT))
return -errno;
log_warning_errno(errno, "Unexpected failure while looking up GID '" GID_FMT "' via NSS, assuming it doesn't exist: %m", gid);

if (check_with_uid) {
errno = 0;
p = getpwuid((uid_t) gid);
if (p)
return 0;
if (!IN_SET(errno, 0, ENOENT))
return -errno;
log_warning_errno(errno, "Unexpected failure while looking up GID '" GID_FMT "' via NSS, assuming it doesn't exist: %m", gid);
}
}

Expand Down Expand Up @@ -1236,7 +1236,7 @@ static int get_gid_by_name(const char *name, gid_t *gid) {
return 0;
}
if (!errno_is_not_exists(errno))
return log_error_errno(errno, "Failed to check if group %s already exists: %m", name);
log_warning_errno(errno, "Unexpected failure while looking up group '%s' via NSS, assuming it doesn't exist: %m", name);
}

return -ENOENT;
Expand Down
24 changes: 24 additions & 0 deletions test/units/TEST-74-AUX-UTILS.sysusers.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: LGPL-2.1-or-later
set -eux
set -o pipefail

# shellcheck source=test/units/util.sh
. "$(dirname "$0")"/util.sh

at_exit() {
set +e
userdel -r foobarbaz
umount /run/systemd/userdb/
}

# Check that we indeed run under root to make the rest of the test work
[[ "$(id -u)" -eq 0 ]]

trap at_exit EXIT

# Ensure that a non-responsive NSS socket doesn't make sysusers fail
mount -t tmpfs tmpfs /run/systemd/userdb/
touch /run/systemd/userdb/io.systemd.DynamicUser
echo 'u foobarbaz' | SYSTEMD_LOG_LEVEL=debug systemd-sysusers -
grep -q foobarbaz /etc/passwd

0 comments on commit abd96fd

Please sign in to comment.