]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sysusers: handle NSS errors gracefully
authorLuca Boccassi <bluca@debian.org>
Thu, 4 Jul 2024 09:23:04 +0000 (10:23 +0100)
committerLennart Poettering <lennart@poettering.net>
Thu, 4 Jul 2024 14:43:51 +0000 (16:43 +0200)
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.

src/sysusers/sysusers.c
test/units/TEST-74-AUX-UTILS.sysusers.sh [new file with mode: 0755]

index b3fde5097e338f6a50a645ead99a41099d906d41..da97f333deec9c88e18c618bad5687845d09c065 100644 (file)
@@ -1042,7 +1042,7 @@ static int uid_is_ok(
                 if (r >= 0)
                         return 0;
                 if (r != -ESRCH)
-                        return r;
+                        log_warning_errno(r, "Unexpected failure while looking up UID '" UID_FMT "' via NSS, assuming it doesn't exist: %m", uid);
 
                 if (check_with_gid) {
                         r = getgrgid_malloc((gid_t) uid, &g);
@@ -1050,7 +1050,7 @@ static int uid_is_ok(
                                 if (!streq(g->gr_name, name))
                                         return 0;
                         } else if (r != -ESRCH)
-                                return r;
+                                log_warning_errno(r, "Unexpected failure while looking up GID '" GID_FMT "' via NSS, assuming it doesn't exist: %m", uid);
                 }
         }
 
@@ -1155,7 +1155,7 @@ static int add_user(Context *c, Item *i) {
                         return 0;
                 }
                 if (r != -ESRCH)
-                        return log_error_errno(r, "Failed to check if user %s already exists: %m", i->name);
+                        log_warning_errno(r, "Unexpected failure while looking up user '%s' via NSS, assuming it doesn't exist: %m", i->name);
         }
 
         /* Try to use the suggested numeric UID */
@@ -1275,14 +1275,14 @@ static int gid_is_ok(
                 if (r >= 0)
                         return 0;
                 if (r != -ESRCH)
-                        return r;
+                        log_warning_errno(r, "Unexpected failure while looking up GID '" GID_FMT "' via NSS, assuming it doesn't exist: %m", gid);
 
                 if (check_with_uid) {
                         r = getpwuid_malloc(gid, /* ret= */ NULL);
                         if (r >= 0)
                                 return 0;
                         if (r != -ESRCH)
-                                return r;
+                                log_warning_errno(r, "Unexpected failure while looking up GID '" GID_FMT "' via NSS, assuming it doesn't exist: %m", gid);
                 }
         }
 
@@ -1317,7 +1317,7 @@ static int get_gid_by_name(
                         return 0;
                 }
                 if (r != -ESRCH)
-                        return log_error_errno(r, "Failed to check if group %s already exists: %m", name);
+                        log_warning_errno(r, "Unexpected failure while looking up group '%s' via NSS, assuming it doesn't exist: %m", name);
         }
 
         return -ENOENT;
diff --git a/test/units/TEST-74-AUX-UTILS.sysusers.sh b/test/units/TEST-74-AUX-UTILS.sysusers.sh
new file mode 100755 (executable)
index 0000000..dcd2993
--- /dev/null
@@ -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