1
0
mirror of https://github.com/systemd/systemd synced 2026-03-30 11:44:49 +02:00

Compare commits

...

13 Commits

Author SHA1 Message Date
Luca Boccassi
6cb76f9e95
Improve systemd-analyze man page and bash completion (#39778)
This updates example output in systemd-analyze's man page after the
tool's output was changed in a previous commit.

Additionally bash completion is added for `systemd-analyze filesystems`
and improved for `systemd-analyze calendar`.
2025-11-18 22:54:01 +00:00
Simon Barth
a049825708 shell-completion: bash: Add systemd-analyze calendar options
Add completion for the systemd-analyze calendar options --iterations and
--base-time.
2025-11-18 23:05:02 +01:00
Zbigniew Jędrzejewski-Szmek
c7c457b2fb
User and group error messages (#39783)
I'm using separate commit here because this changes are a bit finicky.
2025-11-18 19:39:57 +01:00
Zbigniew Jędrzejewski-Szmek
970c29b6b6 networkd: use STRERROR_{USER,GROUP} 2025-11-18 16:23:29 +01:00
Zbigniew Jędrzejewski-Szmek
29d26ebe9a nspawn,vmspawn: improve errors for unknown users and groups 2025-11-18 16:23:29 +01:00
Zbigniew Jędrzejewski-Szmek
f3f933ee92 login: use STREROR_USER helper 2025-11-18 16:23:29 +01:00
Zbigniew Jędrzejewski-Szmek
718578b96d creds: improve message about unknown user
Before:
$ build/systemd-creds --uid=asdf
Failed to resolve user 'asdf': No such process
Now:
$ build/systemd-creds --uid=asdf
Failed to resolve user 'asdf': Unknown user
2025-11-18 16:23:29 +01:00
Zbigniew Jędrzejewski-Szmek
a50fdf611c core: improve messages about unknown users and groups
$ sudo build/systemd-run --uid=asdf whoami
$ journalctl -e
(whoami)[1007784]: run-p1007782-i5200512.service: Failed to determine user credentials: No such process
(whoami)[1007784]: run-p1007782-i5200512.service: Failed at step USER spawning /usr/sbin/whoami: No such process
systemd[1]: run-p1007782-i5200512.service: Main process exited, code=exited, status=217/USER
systemd[1]: run-p1007782-i5200512.service: Failed with result 'exit-code'.

Now:
(whoami)[1013204]: run-p1013202-i5205932.service: Failed to determine credentials for user 'asdf': Unknown user
(whoami)[1013204]: run-p1013202-i5205932.service: Failed at step USER spawning /usr/sbin/whoami: Invalid argument
systemd[1]: run-p1013202-i5205932.service: Main process exited, code=exited, status=217/USER
systemd[1]: run-p1013202-i5205932.service: Failed with result 'exit-code'.
2025-11-18 16:23:29 +01:00
Zbigniew Jędrzejewski-Szmek
d92e47a093 run: improve log message for unknown user/group
Before:
$ sudo build/systemd-run --scope --uid=asdf whoami
Failed to resolve user asdf: No such process
Now:
$ sudo build/systemd-run --scope --uid=asdf whoami
Failed to resolve user 'asdf': Unknown user
2025-11-18 16:23:29 +01:00
Zbigniew Jędrzejewski-Szmek
f436664881 tmpfiles: improve error message for missing user/group
From a boot with a dracut initrd:
systemd-tmpfiles[242]: /usr/lib/tmpfiles.d/tpm2-tss-fapi.conf:2: Failed to resolve user 'tss': No such process
systemd-tmpfiles[242]: Failed to parse ACL "default:group:tss:rwx", ignoring: Invalid argument
systemd-tmpfiles[242]: /usr/lib/tmpfiles.d/tpm2-tss-fapi.conf:4: Failed to resolve user 'tss': No such process
systemd-tmpfiles[242]: Failed to parse ACL "default:group:tss:rwx", ignoring: Invalid argument
systemd-tmpfiles[242]: /usr/lib/tmpfiles.d/tpm2-tss-fapi.conf:6: Failed to resolve group 'tss': No such process
systemd-tmpfiles[242]: /usr/lib/tmpfiles.d/tpm2-tss-fapi.conf:7: Failed to resolve group 'tss': No such process
2025-11-18 16:23:29 +01:00
Zbigniew Jędrzejewski-Szmek
6e6e96f628 udev: define a generic helper to print messages about unknown users and groups
We cannot just use %m, because strerror returns a confusing error message
for ESRCH or ENOEXEC. udev code was doing a good job, but the error handling
was very verbose. Let's encapsulate the customized error messages in a
helper.

No functional change, except that the error messages have a slightly different
form now. The old messages were a bit better, but we don't have as much
flexibility in the new scheme. "Failed to resolve user 'foo': Unknown user"
should be good enough.
2025-11-18 16:23:29 +01:00
Simon Barth
62aba7c5cd shell-completion: bash: Add systemd-analyze filesystems 2025-11-17 23:40:58 +01:00
Simon Barth
ceb67d42f5 man: Fix systemd-analyze exit-status example output
The output of `systemd-analyze exit-status` changed in commit
e04ed6db6b44681b7a7876b9c4a1e6adaf877670, so that the exit-status class
for EXIT_SUCCESS and EXIT_FAILURE is "libc" instead of "glibc".

This commit makes the example output in the man-page match the actual
output again.
2025-11-17 23:37:46 +01:00
15 changed files with 113 additions and 62 deletions

View File

@ -464,7 +464,7 @@ $ eog targets.svg</programlisting>
<title><command>systemd-analyze exit-status <optional><replaceable>STATUS</replaceable>...</optional></command></title> <title><command>systemd-analyze exit-status <optional><replaceable>STATUS</replaceable>...</optional></command></title>
<para>This command prints a list of exit statuses along with their "class", i.e. the source of the <para>This command prints a list of exit statuses along with their "class", i.e. the source of the
definition (one of <literal>glibc</literal>, <literal>systemd</literal>, <literal>LSB</literal>, or definition (one of <literal>libc</literal>, <literal>systemd</literal>, <literal>LSB</literal>, or
<literal>BSD</literal>), see the Process Exit Codes section in <literal>BSD</literal>), see the Process Exit Codes section in
<citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>. <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
If no additional arguments are specified, all known statuses are shown. Otherwise, only the If no additional arguments are specified, all known statuses are shown. Otherwise, only the
@ -475,8 +475,8 @@ $ eog targets.svg</programlisting>
<programlisting>$ systemd-analyze exit-status 0 1 {63..65} <programlisting>$ systemd-analyze exit-status 0 1 {63..65}
NAME STATUS CLASS NAME STATUS CLASS
SUCCESS 0 glibc SUCCESS 0 libc
FAILURE 1 glibc FAILURE 1 libc
- 63 - - 63 -
USAGE 64 BSD USAGE 64 BSD
DATAERR 65 BSD DATAERR 65 BSD

View File

@ -56,6 +56,15 @@ __get_architectures() {
systemd-analyze --no-legend --no-pager architectures 2>/dev/null | { while read -r a b; do echo " $a"; done; } systemd-analyze --no-legend --no-pager architectures 2>/dev/null | { while read -r a b; do echo " $a"; done; }
} }
__get_filesystem_sets() {
local line
systemd-analyze filesystems --no-pager 2>/dev/null | while IFS= read -r line; do
if [[ $line == @* ]]; then
printf '%s\n' "$line"
fi
done
}
_systemd_analyze() { _systemd_analyze() {
local i verb comps mode local i verb comps mode
local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} words cword local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} words cword
@ -68,7 +77,7 @@ _systemd_analyze() {
) )
local -A VERBS=( local -A VERBS=(
[STANDALONE]='time blame unit-files unit-paths exit-status compare-versions calendar timestamp timespan pcrs nvpcrs srk has-tpm2 smbios11 chid image-policy' [STANDALONE]='time blame unit-files unit-paths exit-status compare-versions timestamp timespan pcrs nvpcrs srk has-tpm2 smbios11 chid image-policy'
[CRITICAL_CHAIN]='critical-chain' [CRITICAL_CHAIN]='critical-chain'
[DOT]='dot' [DOT]='dot'
[DUMP]='dump' [DUMP]='dump'
@ -86,6 +95,8 @@ _systemd_analyze() {
[TRANSIENT_SETTINGS]='transient-settings' [TRANSIENT_SETTINGS]='transient-settings'
[UNIT_SHELL]='unit-shell' [UNIT_SHELL]='unit-shell'
[UNIT_GDB]='unit-gdb' [UNIT_GDB]='unit-gdb'
[FILESYSTEMS]='filesystems'
[CALENDAR]='calendar'
) )
local CONFIGS='locale.conf systemd/bootchart.conf systemd/coredump.conf systemd/journald.conf local CONFIGS='locale.conf systemd/bootchart.conf systemd/coredump.conf systemd/journald.conf
@ -265,6 +276,18 @@ _systemd_analyze() {
else else
comps=$( __get_services $mode ) comps=$( __get_services $mode )
fi fi
elif __contains_word "$verb" ${VERBS[FILESYSTEMS]}; then
if [[ $cur = -* ]]; then
comps='--help --version --no-pager'
else
comps=$( __get_filesystem_sets )
fi
elif __contains_word "$verb" ${VERBS[CALENDAR]}; then
if [[ $cur = -* ]]; then
comps='--help --version --iterations --base-time'
fi
fi fi
COMPREPLY=( $(compgen -W '$comps' -- "$cur") ) COMPREPLY=( $(compgen -W '$comps' -- "$cur") )

View File

@ -9,8 +9,10 @@
#include <shadow.h> #include <shadow.h>
#include "basic-forward.h" #include "basic-forward.h"
#include "errno-util.h"
/* Users managed by systemd-homed. See https://systemd.io/UIDS-GIDS for details how this range fits into the rest of the world */ /* Users managed by systemd-homed. See https://systemd.io/UIDS-GIDS for details
* how this range fits into the rest of the world. */
#define HOME_UID_MIN ((uid_t) 60001) #define HOME_UID_MIN ((uid_t) 60001)
#define HOME_UID_MAX ((uid_t) 60513) #define HOME_UID_MAX ((uid_t) 60513)
@ -18,6 +20,19 @@
#define MAP_UID_MIN ((uid_t) 60514) #define MAP_UID_MIN ((uid_t) 60514)
#define MAP_UID_MAX ((uid_t) 60577) #define MAP_UID_MAX ((uid_t) 60577)
/* A helper to print an error message when user or group resolution fails.
* Note that we can't use ({ }) to define a temporary variable, so errnum is
* evaluated multiple times. */
#define STRERROR_USER(errnum) ((errnum) == -ESRCH ? "Unknown user" : (errnum) == -ENOEXEC ? "Not a system user" : STRERROR(errnum))
#define STRERROR_GROUP(errnum) ((errnum) == -ESRCH ? "Unknown group" : (errnum) == -ENOEXEC ? "Not a system group" : STRERROR(errnum))
static inline bool ERRNO_IS_NEG_BAD_ACCOUNT(intmax_t r) {
return IN_SET(r,
-ESRCH,
-ENOEXEC);
}
_DEFINE_ABS_WRAPPER(BAD_ACCOUNT);
bool uid_is_valid(uid_t uid) _const_; bool uid_is_valid(uid_t uid) _const_;
static inline bool gid_is_valid(gid_t gid) { static inline bool gid_is_valid(gid_t gid) {

View File

@ -2087,8 +2087,11 @@ static int build_environment(
assert(!c->user); assert(!c->user);
r = get_fixed_user("root", /* prefer_nss = */ false, &username, NULL, NULL, &home, &shell); r = get_fixed_user("root", /* prefer_nss = */ false, &username, NULL, NULL, &home, &shell);
if (r < 0) if (r < 0) {
return log_debug_errno(r, "Failed to determine user credentials for root: %m"); log_debug_errno(r, "Failed to determine credentials for user root: %s",
STRERROR_USER(r));
return ERRNO_IS_NEG_BAD_ACCOUNT(r) ? -EINVAL : r; /* Suppress confusing errno */
}
} }
bool set_user_login_env = exec_context_get_set_login_environment(c); bool set_user_login_env = exec_context_get_set_login_environment(c);
@ -5265,7 +5268,9 @@ int exec_invoke(
&username, &uid, &gid, &pwent_home, &shell); &username, &uid, &gid, &pwent_home, &shell);
if (r < 0) { if (r < 0) {
*exit_status = EXIT_USER; *exit_status = EXIT_USER;
return log_error_errno(r, "Failed to determine user credentials: %m"); log_error_errno(r, "Failed to determine credentials for user '%s': %s",
u, STRERROR_USER(r));
return ERRNO_IS_NEG_BAD_ACCOUNT(r) ? -EINVAL : r; /* Suppress confusing errno */
} }
} }
@ -5273,7 +5278,9 @@ int exec_invoke(
r = get_fixed_group(context->group, &groupname, &gid); r = get_fixed_group(context->group, &groupname, &gid);
if (r < 0) { if (r < 0) {
*exit_status = EXIT_GROUP; *exit_status = EXIT_GROUP;
return log_error_errno(r, "Failed to determine group credentials: %m"); log_error_errno(r, "Failed to determine credentials for group '%s': %s",
u, STRERROR_GROUP(r));
return ERRNO_IS_NEG_BAD_ACCOUNT(r) ? -EINVAL : r; /* Suppress confusing errno */
} }
} }
} }

View File

@ -348,7 +348,9 @@ static int scope_enter_start_chown(Scope *s) {
r = get_user_creds(&user, &uid, &gid, NULL, NULL, 0); r = get_user_creds(&user, &uid, &gid, NULL, NULL, 0);
if (r < 0) { if (r < 0) {
log_unit_error_errno(UNIT(s), r, "Failed to resolve user \"%s\": %m", user); log_unit_error_errno(UNIT(s), r,
"Failed to resolve user '%s': %s",
user, STRERROR_USER(r));
_exit(EXIT_USER); _exit(EXIT_USER);
} }
} }
@ -358,7 +360,9 @@ static int scope_enter_start_chown(Scope *s) {
r = get_group_creds(&group, &gid, 0); r = get_group_creds(&group, &gid, 0);
if (r < 0) { if (r < 0) {
log_unit_error_errno(UNIT(s), r, "Failed to resolve group \"%s\": %m", group); log_unit_error_errno(UNIT(s), r,
"Failed to resolve group '%s': %s",
group, STRERROR_GROUP(r));
_exit(EXIT_GROUP); _exit(EXIT_GROUP);
} }
} }

View File

@ -2056,7 +2056,9 @@ static int socket_chown(Socket *s, PidRef *ret_pid) {
r = get_user_creds(&user, &uid, &gid, NULL, NULL, 0); r = get_user_creds(&user, &uid, &gid, NULL, NULL, 0);
if (r < 0) { if (r < 0) {
log_unit_error_errno(UNIT(s), r, "Failed to resolve user %s: %m", user); log_unit_error_errno(UNIT(s), r,
"Failed to resolve user '%s': %s",
user, STRERROR_USER(r));
_exit(EXIT_USER); _exit(EXIT_USER);
} }
} }
@ -2066,7 +2068,9 @@ static int socket_chown(Socket *s, PidRef *ret_pid) {
r = get_group_creds(&group, &gid, 0); r = get_group_creds(&group, &gid, 0);
if (r < 0) { if (r < 0) {
log_unit_error_errno(UNIT(s), r, "Failed to resolve group %s: %m", group); log_unit_error_errno(UNIT(s), r,
"Failed to resolve group '%s': %s",
group, STRERROR_GROUP(r));
_exit(EXIT_GROUP); _exit(EXIT_GROUP);
} }
} }

View File

@ -1062,7 +1062,8 @@ static int parse_argv(int argc, char *argv[]) {
/* ret_shell= */ NULL, /* ret_shell= */ NULL,
/* flags= */ 0); /* flags= */ 0);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to resolve user '%s': %m", optarg); return log_error_errno(r, "Failed to resolve user '%s': %s",
optarg, STRERROR_USER(r));
} }
break; break;

View File

@ -348,10 +348,8 @@ static int run(int argc, char *argv[]) {
if (streq(verb, "start")) { if (streq(verb, "start")) {
_cleanup_(user_record_unrefp) UserRecord *ur = NULL; _cleanup_(user_record_unrefp) UserRecord *ur = NULL;
r = userdb_by_name(user, /* match= */ NULL, USERDB_PARSE_NUMERIC|USERDB_SUPPRESS_SHADOW, &ur); r = userdb_by_name(user, /* match= */ NULL, USERDB_PARSE_NUMERIC|USERDB_SUPPRESS_SHADOW, &ur);
if (r == -ESRCH)
return log_error_errno(r, "User '%s' does not exist: %m", user);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to resolve user '%s': %m", user); return log_error_errno(r, "Failed to resolve user '%s': %s", user, STRERROR_USER(r));
/* We do two things here: mount the per-user XDG_RUNTIME_DIR, and set up tmpfs quota on /tmp/ /* We do two things here: mount the per-user XDG_RUNTIME_DIR, and set up tmpfs quota on /tmp/
* and /dev/shm/. */ * and /dev/shm/. */

View File

@ -239,10 +239,9 @@ static int tuntap_verify(NetDev *netdev, const char *filename) {
r = userdb_by_name(t->user_name, &USERDB_MATCH_ROOT_AND_SYSTEM, r = userdb_by_name(t->user_name, &USERDB_MATCH_ROOT_AND_SYSTEM,
USERDB_SUPPRESS_SHADOW | USERDB_PARSE_NUMERIC, USERDB_SUPPRESS_SHADOW | USERDB_PARSE_NUMERIC,
&ur); &ur);
if (r == -ENOEXEC) if (r < 0)
log_netdev_warning_errno(netdev, r, "User %s is not a system user, ignoring.", t->user_name); log_netdev_warning_errno(netdev, r, "Cannot resolve user name '%s', ignoring: %s",
else if (r < 0) t->user_name, STRERROR_USER(r));
log_netdev_warning_errno(netdev, r, "Cannot resolve user name %s, ignoring: %m", t->user_name);
else else
t->uid = ur->uid; t->uid = ur->uid;
} }
@ -253,10 +252,9 @@ static int tuntap_verify(NetDev *netdev, const char *filename) {
r = groupdb_by_name(t->group_name, &USERDB_MATCH_ROOT_AND_SYSTEM, r = groupdb_by_name(t->group_name, &USERDB_MATCH_ROOT_AND_SYSTEM,
USERDB_SUPPRESS_SHADOW | USERDB_PARSE_NUMERIC, USERDB_SUPPRESS_SHADOW | USERDB_PARSE_NUMERIC,
&gr); &gr);
if (r == -ENOEXEC) if (r < 0)
log_netdev_warning_errno(netdev, r, "Group %s is not a system group, ignoring.", t->group_name); log_netdev_warning_errno(netdev, r, "Cannot resolve group name '%s', ignoring: %s",
else if (r < 0) t->group_name, STRERROR_GROUP(r));
log_netdev_warning_errno(netdev, r, "Cannot resolve group name %s, ignoring: %m", t->group_name);
else else
t->gid = gr->gid; t->gid = gr->gid;
} }

View File

@ -2748,7 +2748,8 @@ static int start_transient_scope(sd_bus *bus) {
r = get_group_creds(&arg_exec_group, &gid, 0); r = get_group_creds(&arg_exec_group, &gid, 0);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to resolve group %s: %m", arg_exec_group); return log_error_errno(r, "Failed to resolve group '%s': %s",
arg_exec_group, STRERROR_GROUP(r));
if (setresgid(gid, gid, gid) < 0) if (setresgid(gid, gid, gid) < 0)
return log_error_errno(errno, "Failed to change GID to " GID_FMT ": %m", gid); return log_error_errno(errno, "Failed to change GID to " GID_FMT ": %m", gid);
@ -2762,7 +2763,8 @@ static int start_transient_scope(sd_bus *bus) {
r = get_user_creds(&arg_exec_user, &uid, &gid, &home, &shell, r = get_user_creds(&arg_exec_user, &uid, &gid, &home, &shell,
USER_CREDS_CLEAN|USER_CREDS_SUPPRESS_PLACEHOLDER|USER_CREDS_PREFER_NSS); USER_CREDS_CLEAN|USER_CREDS_SUPPRESS_PLACEHOLDER|USER_CREDS_PREFER_NSS);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to resolve user %s: %m", arg_exec_user); return log_error_errno(r, "Failed to resolve user '%s': %s",
arg_exec_user, STRERROR_USER(r));
if (home) { if (home) {
r = strv_extendf(&user_env, "HOME=%s", home); r = strv_extendf(&user_env, "HOME=%s", home);

View File

@ -244,8 +244,10 @@ int machine_bind_user_prepare(
_cleanup_(group_record_unrefp) GroupRecord *g = NULL, *cg = NULL; _cleanup_(group_record_unrefp) GroupRecord *g = NULL, *cg = NULL;
r = userdb_by_name(*n, /* match= */ NULL, USERDB_DONT_SYNTHESIZE_INTRINSIC|USERDB_DONT_SYNTHESIZE_FOREIGN, &u); r = userdb_by_name(*n, /* match= */ NULL, USERDB_DONT_SYNTHESIZE_INTRINSIC|USERDB_DONT_SYNTHESIZE_FOREIGN, &u);
if (r == -ENOEXEC)
return log_error_errno(r, "User '%s' did not pass filter.", *n);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to resolve user '%s': %m", *n); return log_error_errno(r, "Failed to resolve user '%s': %s", *n, STRERROR_USER(r));
/* For now, let's refuse mapping the root/nobody users explicitly. The records we generate /* For now, let's refuse mapping the root/nobody users explicitly. The records we generate
* are strictly additive, nss-systemd is typically placed last in /etc/nsswitch.conf. Thus * are strictly additive, nss-systemd is typically placed last in /etc/nsswitch.conf. Thus
@ -266,8 +268,11 @@ int machine_bind_user_prepare(
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Cannot bind user with no UID, refusing."); return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Cannot bind user with no UID, refusing.");
r = groupdb_by_gid(user_record_gid(u), /* match= */ NULL, USERDB_DONT_SYNTHESIZE_INTRINSIC|USERDB_DONT_SYNTHESIZE_FOREIGN, &g); r = groupdb_by_gid(user_record_gid(u), /* match= */ NULL, USERDB_DONT_SYNTHESIZE_INTRINSIC|USERDB_DONT_SYNTHESIZE_FOREIGN, &g);
if (r == -ENOEXEC)
return log_error_errno(r, "Group of user '%s' did not pass filter.", u->user_name);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to resolve group of user '%s': %m", u->user_name); return log_error_errno(r, "Failed to resolve group of user '%s': %s",
u->user_name, STRERROR_GROUP(r));
/* We want to synthesize exactly one user + group from the host into the machine. This only /* We want to synthesize exactly one user + group from the host into the machine. This only
* makes sense if the user on the host has its own private group. We can't reasonably check * makes sense if the user on the host has its own private group. We can't reasonably check

View File

@ -932,7 +932,7 @@ int userdb_by_name(const char *name, const UserDBMatch *match, UserDBFlags flags
r = userdb_start_query(iterator, "io.systemd.UserDatabase.GetUserRecord", /* more= */ false, query, flags); r = userdb_start_query(iterator, "io.systemd.UserDatabase.GetUserRecord", /* more= */ false, query, flags);
if (r >= 0) { if (r >= 0) {
r = userdb_process(iterator, &ur, /* ret_group_record= */ NULL, /* ret_user_name= */ NULL, /* ret_group_name= */ NULL); r = userdb_process(iterator, &ur, /* ret_group_record= */ NULL, /* ret_user_name= */ NULL, /* ret_group_name= */ NULL);
if (r == -ENOEXEC) /* found a user matching UID or name, but not filter. In this case the if (r == -ENOEXEC) /* Found a user matching UID or name, but not filter. In this case the
* fallback paths below are pointless */ * fallback paths below are pointless */
return r; return r;
} }

View File

@ -3992,7 +3992,8 @@ static int parse_line(
missing_user_or_group = true; missing_user_or_group = true;
} else if (r < 0) { } else if (r < 0) {
*invalid_config = true; *invalid_config = true;
return log_syntax(NULL, LOG_ERR, fname, line, r, "Failed to resolve user '%s': %m", u); return log_syntax(NULL, LOG_ERR, fname, line, r,
"Failed to resolve user '%s': %s", u, STRERROR_USER(r));
} else } else
i.uid_set = true; i.uid_set = true;
} }
@ -4013,7 +4014,8 @@ static int parse_line(
missing_user_or_group = true; missing_user_or_group = true;
} else if (r < 0) { } else if (r < 0) {
*invalid_config = true; *invalid_config = true;
return log_syntax(NULL, LOG_ERR, fname, line, r, "Failed to resolve group '%s': %m", g); return log_syntax(NULL, LOG_ERR, fname, line, r,
"Failed to resolve group '%s': %s", g, STRERROR_GROUP(r));
} else } else
i.gid_set = true; i.gid_set = true;
} }

View File

@ -512,12 +512,10 @@ static int rule_resolve_user(UdevRuleLine *rule_line, const char *name, uid_t *r
r = userdb_by_name(name, &USERDB_MATCH_ROOT_AND_SYSTEM, r = userdb_by_name(name, &USERDB_MATCH_ROOT_AND_SYSTEM,
USERDB_SUPPRESS_SHADOW | USERDB_PARSE_NUMERIC | USERDB_SYNTHESIZE_NUMERIC, USERDB_SUPPRESS_SHADOW | USERDB_PARSE_NUMERIC | USERDB_SYNTHESIZE_NUMERIC,
&ur); &ur);
if (r == -ESRCH)
return log_line_error_errno(rule_line, r, "Unknown user '%s', ignoring.", name);
if (r == -ENOEXEC)
return log_line_error_errno(rule_line, r, "User '%s' is not a system user, ignoring.", name);
if (r < 0) if (r < 0)
return log_line_error_errno(rule_line, r, "Failed to resolve user '%s', ignoring: %m", name); return log_line_error_errno(rule_line, r,
"Failed to resolve user '%s', ignoring: %s",
name, STRERROR_USER(r));
_cleanup_free_ char *n = strdup(name); _cleanup_free_ char *n = strdup(name);
if (!n) if (!n)
@ -549,12 +547,10 @@ static int rule_resolve_group(UdevRuleLine *rule_line, const char *name, gid_t *
r = groupdb_by_name(name, &USERDB_MATCH_ROOT_AND_SYSTEM, r = groupdb_by_name(name, &USERDB_MATCH_ROOT_AND_SYSTEM,
USERDB_SUPPRESS_SHADOW | USERDB_PARSE_NUMERIC | USERDB_SYNTHESIZE_NUMERIC, USERDB_SUPPRESS_SHADOW | USERDB_PARSE_NUMERIC | USERDB_SYNTHESIZE_NUMERIC,
&gr); &gr);
if (r == -ESRCH)
return log_line_error_errno(rule_line, r, "Unknown group '%s', ignoring.", name);
if (r == -ENOEXEC)
return log_line_error_errno(rule_line, r, "Group '%s' is not a system group, ignoring.", name);
if (r < 0) if (r < 0)
return log_line_error_errno(rule_line, r, "Failed to resolve group '%s', ignoring: %m", name); return log_line_error_errno(rule_line, r,
"Failed to resolve group '%s', ignoring: %s",
name, STRERROR_GROUP(r));
_cleanup_free_ char *n = strdup(name); _cleanup_free_ char *n = strdup(name);
if (!n) if (!n)
@ -2681,12 +2677,10 @@ static int udev_rule_apply_token_to_event(
r = userdb_by_name(owner, &USERDB_MATCH_ROOT_AND_SYSTEM, r = userdb_by_name(owner, &USERDB_MATCH_ROOT_AND_SYSTEM,
USERDB_SUPPRESS_SHADOW | USERDB_PARSE_NUMERIC | USERDB_SYNTHESIZE_NUMERIC, USERDB_SUPPRESS_SHADOW | USERDB_PARSE_NUMERIC | USERDB_SYNTHESIZE_NUMERIC,
&ur); &ur);
if (r == -ESRCH) if (r < 0)
log_event_error_errno(event, token, r, "Unknown user \"%s\", ignoring.", owner); log_event_error_errno(event, token, r,
else if (r == -ENOEXEC) "Failed to resolve user \"%s\", ignoring: %s",
log_event_error(event, token, "User \"%s\" is not a system user, ignoring.", owner); owner, STRERROR_USER(r));
else if (r < 0)
log_event_error_errno(event, token, r, "Failed to resolve user \"%s\", ignoring: %m", owner);
else { else {
event->uid = ur->uid; event->uid = ur->uid;
log_event_debug(event, token, "Set owner: %s("UID_FMT")", owner, event->uid); log_event_debug(event, token, "Set owner: %s("UID_FMT")", owner, event->uid);
@ -2709,12 +2703,10 @@ static int udev_rule_apply_token_to_event(
r = groupdb_by_name(group, &USERDB_MATCH_ROOT_AND_SYSTEM, r = groupdb_by_name(group, &USERDB_MATCH_ROOT_AND_SYSTEM,
USERDB_SUPPRESS_SHADOW | USERDB_PARSE_NUMERIC | USERDB_SYNTHESIZE_NUMERIC, USERDB_SUPPRESS_SHADOW | USERDB_PARSE_NUMERIC | USERDB_SYNTHESIZE_NUMERIC,
&gr); &gr);
if (r == -ESRCH) if (r < 0)
log_event_error_errno(event, token, r, "Unknown group \"%s\", ignoring.", group); log_event_error_errno(event, token, r,
else if (r == -ENOEXEC) "Failed to resolve group \"%s\", ignoring: %s",
log_event_error(event, token, "Group \"%s\" is not a system group, ignoring.", group); group, STRERROR_GROUP(r));
else if (r < 0)
log_event_error_errno(event, token, r, "Failed to resolve group \"%s\", ignoring: %m", group);
else { else {
event->gid = gr->gid; event->gid = gr->gid;
log_event_debug(event, token, "Set group: %s("GID_FMT")", group, event->gid); log_event_debug(event, token, "Set group: %s("GID_FMT")", group, event->gid);

View File

@ -309,15 +309,15 @@ assert_0 "${rules}"
test_syntax_error 'OWNER=":nosuchuser:"' "Failed to resolve user ':nosuchuser:', ignoring: Invalid argument" test_syntax_error 'OWNER=":nosuchuser:"' "Failed to resolve user ':nosuchuser:', ignoring: Invalid argument"
# nonexistent user # nonexistent user
if ! getent passwd nosuchuser >/dev/null; then if ! getent passwd nosuchuser >/dev/null; then
test_syntax_error 'OWNER="nosuchuser"' "Unknown user 'nosuchuser', ignoring." test_syntax_error 'OWNER="nosuchuser"' "Failed to resolve user 'nosuchuser', ignoring: Unknown user"
fi fi
if ! getent passwd 12345 >/dev/null; then if ! getent passwd 12345 >/dev/null; then
test_syntax_error 'OWNER="12345"' "Unknown user '12345', ignoring." test_syntax_error 'OWNER="12345"' "Failed to resolve user '12345', ignoring: Unknown user"
fi fi
# regular user # regular user
if getent passwd testuser >/dev/null; then if getent passwd testuser >/dev/null; then
test_syntax_error 'OWNER="testuser"' "User 'testuser' is not a system user, ignoring." test_syntax_error 'OWNER="testuser"' "Failed to resolve user 'testuser', ignoring: Not a system user"
test_syntax_error "OWNER=\"$(id -u testuser)\"" "User '$(id -u testuser)' is not a system user, ignoring." test_syntax_error "OWNER=\"$(id -u testuser)\"" "Failed to resolve user '$(id -u testuser)', ignoring: Not a system user"
fi fi
test_syntax_error 'GROUP{a}="b"' 'Invalid attribute for GROUP.' test_syntax_error 'GROUP{a}="b"' 'Invalid attribute for GROUP.'
test_syntax_error 'GROUP-="b"' 'Invalid operator for GROUP.' test_syntax_error 'GROUP-="b"' 'Invalid operator for GROUP.'
@ -341,15 +341,15 @@ assert_0 "${rules}"
test_syntax_error 'GROUP=":nosuchgroup:"' "Failed to resolve group ':nosuchgroup:', ignoring: Invalid argument" test_syntax_error 'GROUP=":nosuchgroup:"' "Failed to resolve group ':nosuchgroup:', ignoring: Invalid argument"
# nonexistent group # nonexistent group
if ! getent group nosuchgroup >/dev/null; then if ! getent group nosuchgroup >/dev/null; then
test_syntax_error 'GROUP="nosuchgroup"' "Unknown group 'nosuchgroup', ignoring." test_syntax_error 'GROUP="nosuchgroup"' "Failed to resolve group 'nosuchgroup', ignoring: Unknown group"
fi fi
if ! getent group 12345 >/dev/null; then if ! getent group 12345 >/dev/null; then
test_syntax_error 'GROUP="12345"' "Unknown group '12345', ignoring." test_syntax_error 'GROUP="12345"' "Failed to resolve group '12345', ignoring: Unknown group"
fi fi
# regular group # regular group
if getent group testuser >/dev/null; then if getent group testuser >/dev/null; then
test_syntax_error 'GROUP="testuser"' "Group 'testuser' is not a system group, ignoring." test_syntax_error 'GROUP="testuser"' "Failed to resolve group 'testuser', ignoring: Not a system group"
test_syntax_error "GROUP=\"$(id -g testuser)\"" "Group '$(id -g testuser)' is not a system group, ignoring." test_syntax_error "GROUP=\"$(id -g testuser)\"" "Failed to resolve group '$(id -g testuser)', ignoring: Not a system group"
fi fi
test_syntax_error 'MODE{a}="b"' 'Invalid attribute for MODE.' test_syntax_error 'MODE{a}="b"' 'Invalid attribute for MODE.'
test_syntax_error 'MODE-="b"' 'Invalid operator for MODE.' test_syntax_error 'MODE-="b"' 'Invalid operator for MODE.'