From d14b9ace0c3e8e9b4e481aa6fed7f86c4d081c75 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Fri, 2 Oct 2026 16:55:18 +0200 Subject: [PATCH] specifier: return -EUNATCH for user and group specifiers in global scope %u, %U, %g and %G have nothing to resolve to in the global scope, and failed with -EINVAL. Install code already treats -EUNATCH as "cannot resolve specifiers": it is listed in ERRNO_IS_NEG_UNIT_ISSUE() and install_change_dump_error() turns it into a proper message. With -EINVAL, "systemctl --global enable" of a unit using these specifiers only reported "Invalid argument". Return -EUNATCH instead, like the machine-id and os-release specifiers already do when their source is missing. Only the install code uses these specifiers in the global scope. (cherry picked from commit 03ce9bcff23d07751dc6911c7963e3bde9e780c2) --- src/shared/specifier.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/shared/specifier.c b/src/shared/specifier.c index 9d2066899f..7905d78aab 100644 --- a/src/shared/specifier.c +++ b/src/shared/specifier.c @@ -304,7 +304,7 @@ int specifier_group_name(char specifier, const void *data, const char *root, con assert(ret); if (scope == RUNTIME_SCOPE_GLOBAL) - return -EINVAL; + return -EUNATCH; t = gid_to_name(scope == RUNTIME_SCOPE_USER ? getgid() : 0); if (!t) @@ -321,7 +321,7 @@ int specifier_group_id(char specifier, const void *data, const char *root, const assert(ret); if (scope == RUNTIME_SCOPE_GLOBAL) - return -EINVAL; + return -EUNATCH; gid = scope == RUNTIME_SCOPE_USER ? getgid() : 0; @@ -339,7 +339,7 @@ int specifier_user_name(char specifier, const void *data, const char *root, cons assert(ret); if (scope == RUNTIME_SCOPE_GLOBAL) - return -EINVAL; + return -EUNATCH; uid = scope == RUNTIME_SCOPE_USER ? getuid() : 0; @@ -365,7 +365,7 @@ int specifier_user_id(char specifier, const void *data, const char *root, const assert(ret); if (scope == RUNTIME_SCOPE_GLOBAL) - return -EINVAL; + return -EUNATCH; uid = scope == RUNTIME_SCOPE_USER ? getuid() : 0;