summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/basic/user-util.c173
-rw-r--r--src/basic/user-util.h11
-rw-r--r--src/core/execute.c6
-rw-r--r--src/core/socket.c4
-rw-r--r--src/coredump/coredump.c2
-rw-r--r--src/login/loginctl.c8
-rw-r--r--src/login/logind-core.c2
-rw-r--r--src/login/user-runtime-dir.c4
-rw-r--r--src/mount/mount-tool.c2
-rw-r--r--src/network/netdev/tuntap.c6
-rw-r--r--src/network/networkd.c2
-rw-r--r--src/notify/notify.c2
-rw-r--r--src/resolve/resolved.c2
-rw-r--r--src/run/run.c4
-rw-r--r--src/shared/condition.c2
-rw-r--r--src/test/test-acl-util.c2
-rw-r--r--src/test/test-ipcrm.c2
-rw-r--r--src/test/test-user-util.c4
-rw-r--r--src/timesync/timesyncd.c2
-rw-r--r--src/tmpfiles/tmpfiles.c4
-rw-r--r--src/udev/udev-rules.c8
21 files changed, 146 insertions, 106 deletions
diff --git a/src/basic/user-util.c b/src/basic/user-util.c
index a562a397c7..b6185597de 100644
--- a/src/basic/user-util.c
+++ b/src/basic/user-util.c
@@ -87,17 +87,31 @@ char *getusername_malloc(void) {
return uid_to_name(getuid());
}
-int get_user_creds(
+static inline bool is_nologin_shell(const char *shell) {
+
+ return PATH_IN_SET(shell,
+ /* 'nologin' is the friendliest way to disable logins for a user account. It prints a nice
+ * message and exits. Different distributions place the binary at different places though,
+ * hence let's list them all. */
+ "/bin/nologin",
+ "/sbin/nologin",
+ "/usr/bin/nologin",
+ "/usr/sbin/nologin",
+ /* 'true' and 'false' work too for the same purpose, but are less friendly as they don't do
+ * any message printing. Different distributions place the binary at various places but at
+ * least not in the 'sbin' directory. */
+ "/bin/false",
+ "/usr/bin/false",
+ "/bin/true",
+ "/usr/bin/true");
+}
+
+static int synthesize_user_creds(
const char **username,
uid_t *uid, gid_t *gid,
const char **home,
- const char **shell) {
-
- struct passwd *p;
- uid_t u;
-
- assert(username);
- assert(*username);
+ const char **shell,
+ UserCredsFlags flags) {
/* We enforce some special rules for uid=0 and uid=65534: in order to avoid NSS lookups for root we hardcode
* their user record data. */
@@ -129,32 +143,85 @@ int get_user_creds(
*gid = GID_NOBODY;
if (home)
- *home = "/";
+ *home = FLAGS_SET(flags, USER_CREDS_CLEAN) ? NULL : "/";
if (shell)
- *shell = "/sbin/nologin";
+ *shell = FLAGS_SET(flags, USER_CREDS_CLEAN) ? NULL : "/sbin/nologin";
return 0;
}
+ return -ENOMEDIUM;
+}
+
+int get_user_creds(
+ const char **username,
+ uid_t *uid, gid_t *gid,
+ const char **home,
+ const char **shell,
+ UserCredsFlags flags) {
+
+ uid_t u = UID_INVALID;
+ struct passwd *p;
+ int r;
+
+ assert(username);
+ assert(*username);
+
+ if (!FLAGS_SET(flags, USER_CREDS_SYNTHESIZE_FALLBACK) ||
+ (!home && !shell)) {
+
+ /* So here's the deal: normally, we'll try to synthesize all records we can synthesize, and override
+ * the user database with that. However, if the user specifies USER_CREDS_SYNTHESIZE_FALLBACK then the
+ * user database will override the synthetic records instead — except if the user is only interested in
+ * the UID and/or GID (but not the home directory, or the shell), in which case we'll always override
+ * the user database (i.e. the USER_CREDS_SYNTHESIZE_FALLBACK flag has no effect in this case). Why?
+ * Simply because there are valid usecase where the user might change the home directory or the shell
+ * of the relevant users, but changing the UID/GID mappings for them is something we explicitly don't
+ * support. */
+
+ r = synthesize_user_creds(username, uid, gid, home, shell, flags);
+ if (r >= 0)
+ return 0;
+ if (r != -ENOMEDIUM) /* not a username we can synthesize */
+ return r;
+ }
+
if (parse_uid(*username, &u) >= 0) {
errno = 0;
p = getpwuid(u);
- /* If there are multiple users with the same id, make
- * sure to leave $USER to the configured value instead
- * of the first occurrence in the database. However if
- * the uid was configured by a numeric uid, then let's
- * pick the real username from /etc/passwd. */
+ /* If there are multiple users with the same id, make sure to leave $USER to the configured value
+ * instead of the first occurrence in the database. However if the uid was configured by a numeric uid,
+ * then let's pick the real username from /etc/passwd. */
if (p)
*username = p->pw_name;
+ else if (FLAGS_SET(flags, USER_CREDS_ALLOW_MISSING) && !gid && !home && !shell) {
+
+ /* If the specified user is a numeric UID and it isn't in the user database, and the caller
+ * passed USER_CREDS_ALLOW_MISSING and was only interested in the UID, then juts return that
+ * and don't complain. */
+
+ if (uid)
+ *uid = u;
+
+ return 0;
+ }
} else {
errno = 0;
p = getpwnam(*username);
}
+ if (!p) {
+ r = errno > 0 ? -errno : -ESRCH;
- if (!p)
- return errno > 0 ? -errno : -ESRCH;
+ /* If the user requested that we only synthesize as fallback, do so now */
+ if (FLAGS_SET(flags, USER_CREDS_SYNTHESIZE_FALLBACK)) {
+ if (synthesize_user_creds(username, uid, gid, home, shell, flags) >= 0)
+ return 0;
+ }
+
+ return r;
+ }
if (uid) {
if (!uid_is_valid(p->pw_uid))
@@ -170,66 +237,30 @@ int get_user_creds(
*gid = p->pw_gid;
}
- if (home)
- *home = p->pw_dir;
-
- if (shell)
- *shell = p->pw_shell;
-
- return 0;
-}
-
-static inline bool is_nologin_shell(const char *shell) {
-
- return PATH_IN_SET(shell,
- /* 'nologin' is the friendliest way to disable logins for a user account. It prints a nice
- * message and exits. Different distributions place the binary at different places though,
- * hence let's list them all. */
- "/bin/nologin",
- "/sbin/nologin",
- "/usr/bin/nologin",
- "/usr/sbin/nologin",
- /* 'true' and 'false' work too for the same purpose, but are less friendly as they don't do
- * any message printing. Different distributions place the binary at various places but at
- * least not in the 'sbin' directory. */
- "/bin/false",
- "/usr/bin/false",
- "/bin/true",
- "/usr/bin/true");
-}
-
-int get_user_creds_clean(
- const char **username,
- uid_t *uid, gid_t *gid,
- const char **home,
- const char **shell) {
-
- int r;
-
- /* Like get_user_creds(), but resets home/shell to NULL if they don't contain anything relevant. */
-
- r = get_user_creds(username, uid, gid, home, shell);
- if (r < 0)
- return r;
-
- if (shell &&
- (isempty(*shell) || is_nologin_shell(*shell)))
- *shell = NULL;
+ if (home) {
+ if (FLAGS_SET(flags, USER_CREDS_CLEAN) && empty_or_root(p->pw_dir))
+ *home = NULL;
+ else
+ *home = p->pw_dir;
+ }
- if (home && empty_or_root(*home))
- *home = NULL;
+ if (shell) {
+ if (FLAGS_SET(flags, USER_CREDS_CLEAN) && (isempty(p->pw_shell) || is_nologin_shell(p->pw_shell)))
+ *shell = NULL;
+ else
+ *shell = p->pw_shell;
+ }
return 0;
}
-int get_group_creds(const char **groupname, gid_t *gid) {
+int get_group_creds(const char **groupname, gid_t *gid, UserCredsFlags flags) {
struct group *g;
gid_t id;
assert(groupname);
- /* We enforce some special rules for gid=0: in order to avoid
- * NSS lookups for root we hardcode its data. */
+ /* We enforce some special rules for gid=0: in order to avoid NSS lookups for root we hardcode its data. */
if (STR_IN_SET(*groupname, "root", "0")) {
*groupname = "root";
@@ -256,6 +287,12 @@ int get_group_creds(const char **groupname, gid_t *gid) {
if (g)
*groupname = g->gr_name;
+ else if (FLAGS_SET(flags, USER_CREDS_ALLOW_MISSING)) {
+ if (gid)
+ *gid = id;
+
+ return 0;
+ }
} else {
errno = 0;
g = getgrnam(*groupname);
@@ -391,7 +428,7 @@ int in_group(const char *name) {
int r;
gid_t gid;
- r = get_group_creds(&name, &gid);
+ r = get_group_creds(&name, &gid, 0);
if (r < 0)
return r;
diff --git a/src/basic/user-util.h b/src/basic/user-util.h
index b2f198c89b..a18f4d6f1a 100644
--- a/src/basic/user-util.h
+++ b/src/basic/user-util.h
@@ -25,9 +25,14 @@ static inline int parse_gid(const char *s, gid_t *ret_gid) {
char* getlogname_malloc(void);
char* getusername_malloc(void);
-int get_user_creds(const char **username, uid_t *uid, gid_t *gid, const char **home, const char **shell);
-int get_user_creds_clean(const char **username, uid_t *uid, gid_t *gid, const char **home, const char **shell);
-int get_group_creds(const char **groupname, gid_t *gid);
+typedef enum UserCredsFlags {
+ USER_CREDS_SYNTHESIZE_FALLBACK = 1 << 0, /* if set, only synthesize user records if database lacks them. Normally we bypass the userdb entirely for the records we can synthesize */
+ USER_CREDS_ALLOW_MISSING = 1 << 1, /* if a numeric UID string is resolved, be OK if there's no record for it */
+ USER_CREDS_CLEAN = 1 << 2, /* try to clean up shell and home fields with invalid data */
+} UserCredsFlags;
+
+int get_user_creds(const char **username, uid_t *uid, gid_t *gid, const char **home, const char **shell, UserCredsFlags flags);
+int get_group_creds(const char **groupname, gid_t *gid, UserCredsFlags flags);
char* uid_to_name(uid_t uid);
char* gid_to_name(gid_t gid);
diff --git a/src/core/execute.c b/src/core/execute.c
index a35dbac9ef..8867278f4e 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -921,7 +921,7 @@ static int get_fixed_user(const ExecContext *c, const char **user,
* (i.e. are "/" or "/bin/nologin"). */
name = c->user;
- r = get_user_creds_clean(&name, uid, gid, home, shell);
+ r = get_user_creds(&name, uid, gid, home, shell, USER_CREDS_CLEAN);
if (r < 0)
return r;
@@ -939,7 +939,7 @@ static int get_fixed_group(const ExecContext *c, const char **group, gid_t *gid)
return 0;
name = c->group;
- r = get_group_creds(&name, gid);
+ r = get_group_creds(&name, gid, 0);
if (r < 0)
return r;
@@ -1011,7 +1011,7 @@ static int get_supplementary_groups(const ExecContext *c, const char *user,
return -E2BIG;
g = *i;
- r = get_group_creds(&g, l_gids+k);
+ r = get_group_creds(&g, l_gids+k, 0);
if (r < 0)
return r;
diff --git a/src/core/socket.c b/src/core/socket.c
index aedbf51a4c..aa370e7369 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -1934,7 +1934,7 @@ static int socket_chown(Socket *s, pid_t *_pid) {
if (!isempty(s->user)) {
const char *user = s->user;
- r = get_user_creds(&user, &uid, &gid, NULL, NULL);
+ r = get_user_creds(&user, &uid, &gid, NULL, NULL, 0);
if (r < 0) {
log_unit_error_errno(UNIT(s), r, "Failed to resolve user %s: %m", user);
_exit(EXIT_USER);
@@ -1944,7 +1944,7 @@ static int socket_chown(Socket *s, pid_t *_pid) {
if (!isempty(s->group)) {
const char *group = s->group;
- r = get_group_creds(&group, &gid);
+ r = get_group_creds(&group, &gid, 0);
if (r < 0) {
log_unit_error_errno(UNIT(s), r, "Failed to resolve group %s: %m", group);
_exit(EXIT_GROUP);
diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c
index 20a1cbdd45..31274ee602 100644
--- a/src/coredump/coredump.c
+++ b/src/coredump/coredump.c
@@ -672,7 +672,7 @@ static int change_uid_gid(const char *context[]) {
if (uid <= SYSTEM_UID_MAX) {
const char *user = "systemd-coredump";
- r = get_user_creds(&user, &uid, &gid, NULL, NULL);
+ r = get_user_creds(&user, &uid, &gid, NULL, NULL, 0);
if (r < 0) {
log_warning_errno(r, "Cannot resolve %s user. Proceeding to dump core as root: %m", user);
uid = gid = 0;
diff --git a/src/login/loginctl.c b/src/login/loginctl.c
index be55fdbfd8..ad957f0baa 100644
--- a/src/login/loginctl.c
+++ b/src/login/loginctl.c
@@ -912,7 +912,7 @@ static int show_user(int argc, char *argv[], void *userdata) {
const char *path = NULL;
uid_t uid;
- r = get_user_creds((const char**) (argv+i), &uid, NULL, NULL, NULL);
+ r = get_user_creds((const char**) (argv+i), &uid, NULL, NULL, NULL, 0);
if (r < 0)
return log_error_errno(r, "Failed to look up user %s: %m", argv[i]);
@@ -1108,7 +1108,7 @@ static int enable_linger(int argc, char *argv[], void *userdata) {
if (isempty(argv[i]))
uid = UID_INVALID;
else {
- r = get_user_creds((const char**) (argv+i), &uid, NULL, NULL, NULL);
+ r = get_user_creds((const char**) (argv+i), &uid, NULL, NULL, NULL, 0);
if (r < 0)
return log_error_errno(r, "Failed to look up user %s: %m", argv[i]);
}
@@ -1143,7 +1143,7 @@ static int terminate_user(int argc, char *argv[], void *userdata) {
for (i = 1; i < argc; i++) {
uid_t uid;
- r = get_user_creds((const char**) (argv+i), &uid, NULL, NULL, NULL);
+ r = get_user_creds((const char**) (argv+i), &uid, NULL, NULL, NULL, 0);
if (r < 0)
return log_error_errno(r, "Failed to look up user %s: %m", argv[i]);
@@ -1180,7 +1180,7 @@ static int kill_user(int argc, char *argv[], void *userdata) {
for (i = 1; i < argc; i++) {
uid_t uid;
- r = get_user_creds((const char**) (argv+i), &uid, NULL, NULL, NULL);
+ r = get_user_creds((const char**) (argv+i), &uid, NULL, NULL, NULL, 0);
if (r < 0)
return log_error_errno(r, "Failed to look up user %s: %m", argv[i]);
diff --git a/src/login/logind-core.c b/src/login/logind-core.c
index dbae4bf5af..dc728f76d5 100644
--- a/src/login/logind-core.c
+++ b/src/login/logind-core.c
@@ -152,7 +152,7 @@ int manager_add_user_by_name(Manager *m, const char *name, User **_user) {
assert(m);
assert(name);
- r = get_user_creds(&name, &uid, &gid, NULL, NULL);
+ r = get_user_creds(&name, &uid, &gid, NULL, NULL, 0);
if (r < 0)
return r;
diff --git a/src/login/user-runtime-dir.c b/src/login/user-runtime-dir.c
index 51b864c9f8..9f2c594a05 100644
--- a/src/login/user-runtime-dir.c
+++ b/src/login/user-runtime-dir.c
@@ -117,7 +117,7 @@ static int do_mount(const char *user) {
gid_t gid;
int r;
- r = get_user_creds(&user, &uid, &gid, NULL, NULL);
+ r = get_user_creds(&user, &uid, &gid, NULL, NULL, 0);
if (r < 0)
return log_error_errno(r,
r == -ESRCH ? "No such user \"%s\"" :
@@ -141,7 +141,7 @@ static int do_umount(const char *user) {
/* The user may be already removed. So, first try to parse the string by parse_uid(),
* and if it fails, fallback to get_user_creds().*/
if (parse_uid(user, &uid) < 0) {
- r = get_user_creds(&user, &uid, NULL, NULL, NULL);
+ r = get_user_creds(&user, &uid, NULL, NULL, NULL, 0);
if (r < 0)
return log_error_errno(r,
r == -ESRCH ? "No such user \"%s\"" :
diff --git a/src/mount/mount-tool.c b/src/mount/mount-tool.c
index 64c1efdb1c..5c96fd84ef 100644
--- a/src/mount/mount-tool.c
+++ b/src/mount/mount-tool.c
@@ -212,7 +212,7 @@ static int parse_argv(int argc, char *argv[]) {
case ARG_OWNER: {
const char *user = optarg;
- r = get_user_creds(&user, &arg_uid, &arg_gid, NULL, NULL);
+ r = get_user_creds(&user, &arg_uid, &arg_gid, NULL, NULL, 0);
if (r < 0)
return log_error_errno(r,
r == -EBADMSG ? "UID or GID of user %s are invalid."
diff --git a/src/network/netdev/tuntap.c b/src/network/netdev/tuntap.c
index c97478b2a4..951138d257 100644
--- a/src/network/netdev/tuntap.c
+++ b/src/network/netdev/tuntap.c
@@ -75,10 +75,9 @@ static int netdev_tuntap_add(NetDev *netdev, struct ifreq *ifr) {
assert(t);
if (t->user_name) {
-
user = t->user_name;
- r = get_user_creds(&user, &uid, NULL, NULL, NULL);
+ r = get_user_creds(&user, &uid, NULL, NULL, NULL, USER_CREDS_ALLOW_MISSING);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Cannot resolve user name %s: %m", t->user_name);
@@ -87,10 +86,9 @@ static int netdev_tuntap_add(NetDev *netdev, struct ifreq *ifr) {
}
if (t->group_name) {
-
group = t->group_name;
- r = get_group_creds(&group, &gid);
+ r = get_group_creds(&group, &gid, USER_CREDS_ALLOW_MISSING);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Cannot resolve group name %s: %m", t->group_name);
diff --git a/src/network/networkd.c b/src/network/networkd.c
index d2467b70ce..8f7b5b74fd 100644
--- a/src/network/networkd.c
+++ b/src/network/networkd.c
@@ -28,7 +28,7 @@ int main(int argc, char *argv[]) {
goto out;
}
- r = get_user_creds(&user, &uid, &gid, NULL, NULL);
+ r = get_user_creds(&user, &uid, &gid, NULL, NULL, 0);
if (r < 0) {
log_error_errno(r, "Cannot resolve user name %s: %m", user);
goto out;
diff --git a/src/notify/notify.c b/src/notify/notify.c
index e928094d9a..3d607c778a 100644
--- a/src/notify/notify.c
+++ b/src/notify/notify.c
@@ -103,7 +103,7 @@ static int parse_argv(int argc, char *argv[]) {
case ARG_UID: {
const char *u = optarg;
- r = get_user_creds(&u, &arg_uid, &arg_gid, NULL, NULL);
+ r = get_user_creds(&u, &arg_uid, &arg_gid, NULL, NULL, 0);
if (r == -ESRCH) /* If the user doesn't exist, then accept it anyway as numeric */
r = parse_uid(u, &arg_uid);
if (r < 0)
diff --git a/src/resolve/resolved.c b/src/resolve/resolved.c
index 6ff56bc974..d4d6cba201 100644
--- a/src/resolve/resolved.c
+++ b/src/resolve/resolved.c
@@ -37,7 +37,7 @@ int main(int argc, char *argv[]) {
goto finish;
}
- r = get_user_creds(&user, &uid, &gid, NULL, NULL);
+ r = get_user_creds(&user, &uid, &gid, NULL, NULL, 0);
if (r < 0) {
log_error_errno(r, "Cannot resolve user name %s: %m", user);
goto finish;
diff --git a/src/run/run.c b/src/run/run.c
index 2910fcb272..effbbb62cc 100644
--- a/src/run/run.c
+++ b/src/run/run.c
@@ -1232,7 +1232,7 @@ static int start_transient_scope(
if (arg_exec_group) {
gid_t gid;
- r = get_group_creds(&arg_exec_group, &gid);
+ r = get_group_creds(&arg_exec_group, &gid, 0);
if (r < 0)
return log_error_errno(r, "Failed to resolve group %s: %m", arg_exec_group);
@@ -1245,7 +1245,7 @@ static int start_transient_scope(
uid_t uid;
gid_t gid;
- r = get_user_creds_clean(&arg_exec_user, &uid, &gid, &home, &shell);
+ r = get_user_creds(&arg_exec_user, &uid, &gid, &home, &shell, USER_CREDS_CLEAN|USER_CREDS_SYNTHESIZE_FALLBACK);
if (r < 0)
return log_error_errno(r, "Failed to resolve user %s: %m", arg_exec_user);
diff --git a/src/shared/condition.c b/src/shared/condition.c
index 2969a89b4e..d0b17fe7ff 100644
--- a/src/shared/condition.c
+++ b/src/shared/condition.c
@@ -219,7 +219,7 @@ static int condition_test_user(Condition *c) {
return streq(c->parameter, "root");
u = c->parameter;
- r = get_user_creds(&u, &id, NULL, NULL, NULL);
+ r = get_user_creds(&u, &id, NULL, NULL, NULL, USER_CREDS_ALLOW_MISSING);
if (r < 0)
return 0;
diff --git a/src/test/test-acl-util.c b/src/test/test-acl-util.c
index 81eb40444b..a8d413533e 100644
--- a/src/test/test-acl-util.c
+++ b/src/test/test-acl-util.c
@@ -32,7 +32,7 @@ static void test_add_acls_for_user(void) {
if (getuid() == 0) {
const char *nobody = NOBODY_USER_NAME;
- r = get_user_creds(&nobody, &uid, NULL, NULL, NULL);
+ r = get_user_creds(&nobody, &uid, NULL, NULL, NULL, 0);
if (r < 0)
uid = 0;
} else
diff --git a/src/test/test-ipcrm.c b/src/test/test-ipcrm.c
index 106c29951e..6cdf48a490 100644
--- a/src/test/test-ipcrm.c
+++ b/src/test/test-ipcrm.c
@@ -9,7 +9,7 @@ int main(int argc, char *argv[]) {
int r;
const char* name = argv[1] ?: NOBODY_USER_NAME;
- r = get_user_creds(&name, &uid, NULL, NULL, NULL);
+ r = get_user_creds(&name, &uid, NULL, NULL, NULL, 0);
if (r < 0) {
log_full_errno(r == -ESRCH ? LOG_NOTICE : LOG_ERR,
r, "Failed to resolve \"%s\": %m", name);
diff --git a/src/test/test-user-util.c b/src/test/test-user-util.c
index c1428fab02..b291aa0f04 100644
--- a/src/test/test-user-util.c
+++ b/src/test/test-user-util.c
@@ -159,7 +159,7 @@ static void test_get_user_creds_one(const char *id, const char *name, uid_t uid,
log_info("/* %s(\"%s\", \"%s\", "UID_FMT", "GID_FMT", \"%s\", \"%s\") */",
__func__, id, name, uid, gid, home, shell);
- r = get_user_creds(&id, &ruid, &rgid, &rhome, &rshell);
+ r = get_user_creds(&id, &ruid, &rgid, &rhome, &rshell, 0);
log_info_errno(r, "got \"%s\", "UID_FMT", "GID_FMT", \"%s\", \"%s\": %m",
id, ruid, rgid, strnull(rhome), strnull(rshell));
if (!synthesize_nobody() && streq(name, NOBODY_USER_NAME)) {
@@ -180,7 +180,7 @@ static void test_get_group_creds_one(const char *id, const char *name, gid_t gid
log_info("/* %s(\"%s\", \"%s\", "GID_FMT") */", __func__, id, name, gid);
- r = get_group_creds(&id, &rgid);
+ r = get_group_creds(&id, &rgid, 0);
log_info_errno(r, "got \"%s\", "GID_FMT": %m", id, rgid);
if (!synthesize_nobody() && streq(name, NOBODY_GROUP_NAME)) {
log_info("(skipping detailed tests because nobody is not synthesized)");
diff --git a/src/timesync/timesyncd.c b/src/timesync/timesyncd.c
index 987cded009..9a43c6193b 100644
--- a/src/timesync/timesyncd.c
+++ b/src/timesync/timesyncd.c
@@ -107,7 +107,7 @@ int main(int argc, char *argv[]) {
gid = getegid();
if (uid_current == 0) {
- r = get_user_creds(&user, &uid, &gid, NULL, NULL);
+ r = get_user_creds(&user, &uid, &gid, NULL, NULL, 0);
if (r < 0) {
log_error_errno(r, "Cannot resolve user name %s: %m", user);
goto finish;
diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
index cfd9044c5b..c62d026852 100644
--- a/src/tmpfiles/tmpfiles.c
+++ b/src/tmpfiles/tmpfiles.c
@@ -2704,7 +2704,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer, bool
if (!isempty(user) && !streq(user, "-")) {
const char *u = user;
- r = get_user_creds(&u, &i.uid, NULL, NULL, NULL);
+ r = get_user_creds(&u, &i.uid, NULL, NULL, NULL, USER_CREDS_ALLOW_MISSING);
if (r < 0) {
*invalid_config = true;
return log_error_errno(r, "[%s:%u] Unknown user '%s'.", fname, line, user);
@@ -2716,7 +2716,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer, bool
if (!isempty(group) && !streq(group, "-")) {
const char *g = group;
- r = get_group_creds(&g, &i.gid);
+ r = get_group_creds(&g, &i.gid, USER_CREDS_ALLOW_MISSING);
if (r < 0) {
*invalid_config = true;
log_error("[%s:%u] Unknown group '%s'.", fname, line, group);
diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c
index f9eff70295..58ce71c794 100644
--- a/src/udev/udev-rules.c
+++ b/src/udev/udev-rules.c
@@ -481,7 +481,7 @@ static uid_t add_uid(struct udev_rules *rules, const char *owner) {
return uid;
}
}
- r = get_user_creds(&owner, &uid, NULL, NULL, NULL);
+ r = get_user_creds(&owner, &uid, NULL, NULL, NULL, USER_CREDS_ALLOW_MISSING);
if (r < 0)
log_unknown_owner(r, "user", owner);
@@ -524,7 +524,7 @@ static gid_t add_gid(struct udev_rules *rules, const char *group) {
return gid;
}
}
- r = get_group_creds(&group, &gid);
+ r = get_group_creds(&group, &gid, USER_CREDS_ALLOW_MISSING);
if (r < 0)
log_unknown_owner(r, "group", group);
@@ -2110,7 +2110,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules,
event->owner_final = true;
udev_event_apply_format(event, rules_str(rules, cur->key.value_off), owner, sizeof(owner), false);
event->owner_set = true;
- r = get_user_creds(&ow, &event->uid, NULL, NULL, NULL);
+ r = get_user_creds(&ow, &event->uid, NULL, NULL, NULL, USER_CREDS_ALLOW_MISSING);
if (r < 0) {
log_unknown_owner(r, "user", owner);
event->uid = 0;
@@ -2131,7 +2131,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules,
event->group_final = true;
udev_event_apply_format(event, rules_str(rules, cur->key.value_off), group, sizeof(group), false);
event->group_set = true;
- r = get_group_creds(&gr, &event->gid);
+ r = get_group_creds(&gr, &event->gid, USER_CREDS_ALLOW_MISSING);
if (r < 0) {
log_unknown_owner(r, "group", group);
event->gid = 0;