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)
  • Loading branch information
bluca committed Jul 6, 2024
1 parent 15352fa commit 0f51875
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 @@ -1064,7 +1064,7 @@ static int uid_is_ok(
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 @@ -1073,7 +1073,7 @@ static int uid_is_ok(
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 @@ -1179,7 +1179,7 @@ static int add_user(Context *c, 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 @@ -1301,15 +1301,15 @@ static int gid_is_ok(
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 @@ -1344,7 +1344,7 @@ static int get_gid_by_name(
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 0f51875

Please sign in to comment.