user-util: rework how we validate user names
This reworks the user validation infrastructure. There are now two modes. In regular mode we are strict and test against a strict set of valid chars. And in "relaxed" mode we just filter out some really obvious, dangerous stuff. i.e. strict is whitelisting what is OK, but "relaxed" is blacklisting what is really not OK. The idea is that we use strict mode whenver we allocate a new user (i.e. in sysusers.d or homed), while "relaxed" mode is when we process users registered elsewhere, (i.e. userdb, logind, …) The requirements on user name validity vary wildly. SSSD thinks its fine to embedd "@" for example, while the suggested NAME_REGEX field on Debian does not even allow uppercase chars… This effectively liberaralizes a lot what we expect from usernames. The code that warns about questionnable user names is now optional and only used at places such as unit file parsing, so that it doesn't show up on every userdb query, but only when processing configuration files that know better. Fixes: #15149 #15090
This commit is contained in:
@@ -1204,10 +1204,10 @@ int bus_exec_context_set_transient_property(
|
||||
flags |= UNIT_PRIVATE;
|
||||
|
||||
if (streq(name, "User"))
|
||||
return bus_set_transient_user_compat(u, name, &c->user, message, flags, error);
|
||||
return bus_set_transient_user_relaxed(u, name, &c->user, message, flags, error);
|
||||
|
||||
if (streq(name, "Group"))
|
||||
return bus_set_transient_user_compat(u, name, &c->group, message, flags, error);
|
||||
return bus_set_transient_user_relaxed(u, name, &c->group, message, flags, error);
|
||||
|
||||
if (streq(name, "TTYPath"))
|
||||
return bus_set_transient_path(u, name, &c->tty_path, message, flags, error);
|
||||
@@ -1392,7 +1392,7 @@ int bus_exec_context_set_transient_property(
|
||||
return r;
|
||||
|
||||
STRV_FOREACH(p, l)
|
||||
if (!isempty(*p) && !valid_user_group_name_or_id_compat(*p))
|
||||
if (!isempty(*p) && !valid_user_group_name(*p, VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX|VALID_USER_WARN))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
|
||||
"Invalid supplementary group names");
|
||||
|
||||
|
||||
@@ -1643,7 +1643,7 @@ static int method_lookup_dynamic_user_by_name(sd_bus_message *message, void *use
|
||||
|
||||
if (!MANAGER_IS_SYSTEM(m))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Dynamic users are only supported in the system instance.");
|
||||
if (!valid_user_group_name(name))
|
||||
if (!valid_user_group_name(name, VALID_USER_RELAX))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "User name invalid: %s", name);
|
||||
|
||||
r = dynamic_user_lookup_name(m, name, &uid);
|
||||
|
||||
@@ -278,10 +278,10 @@ static int bus_socket_set_transient_property(
|
||||
return bus_set_transient_fdname(u, name, &s->fdname, message, flags, error);
|
||||
|
||||
if (streq(name, "SocketUser"))
|
||||
return bus_set_transient_user_compat(u, name, &s->user, message, flags, error);
|
||||
return bus_set_transient_user_relaxed(u, name, &s->user, message, flags, error);
|
||||
|
||||
if (streq(name, "SocketGroup"))
|
||||
return bus_set_transient_user_compat(u, name, &s->group, message, flags, error);
|
||||
return bus_set_transient_user_relaxed(u, name, &s->group, message, flags, error);
|
||||
|
||||
if (streq(name, "BindIPv6Only"))
|
||||
return bus_set_transient_bind_ipv6_only(u, name, &s->bind_ipv6_only, message, flags, error);
|
||||
|
||||
@@ -30,7 +30,12 @@ int bus_property_get_triggered_unit(
|
||||
|
||||
BUS_DEFINE_SET_TRANSIENT(mode_t, "u", uint32_t, mode_t, "%040o");
|
||||
BUS_DEFINE_SET_TRANSIENT(unsigned, "u", uint32_t, unsigned, "%" PRIu32);
|
||||
BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(user_compat, valid_user_group_name_or_id_compat);
|
||||
|
||||
static inline bool valid_user_group_name_or_id_relaxed(const char *u) {
|
||||
return valid_user_group_name(u, VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX);
|
||||
}
|
||||
|
||||
BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(user_relaxed, valid_user_group_name_or_id_relaxed);
|
||||
BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(path, path_is_absolute);
|
||||
|
||||
int bus_set_transient_string(
|
||||
|
||||
@@ -236,7 +236,7 @@ int bus_property_get_triggered_unit(sd_bus *bus, const char *path, const char *i
|
||||
|
||||
int bus_set_transient_mode_t(Unit *u, const char *name, mode_t *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
|
||||
int bus_set_transient_unsigned(Unit *u, const char *name, unsigned *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
|
||||
int bus_set_transient_user_compat(Unit *u, const char *name, char **p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
|
||||
int bus_set_transient_user_relaxed(Unit *u, const char *name, char **p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
|
||||
int bus_set_transient_path(Unit *u, const char *name, char **p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
|
||||
int bus_set_transient_string(Unit *u, const char *name, char **p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
|
||||
int bus_set_transient_bool(Unit *u, const char *name, bool *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
|
||||
|
||||
@@ -116,7 +116,7 @@ static int dynamic_user_acquire(Manager *m, const char *name, DynamicUser** ret)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!valid_user_group_name_or_id(name))
|
||||
if (!valid_user_group_name(name, VALID_USER_ALLOW_NUMERIC))
|
||||
return -EINVAL;
|
||||
|
||||
if (socketpair(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0, storage_socket) < 0)
|
||||
|
||||
@@ -2068,7 +2068,7 @@ int config_parse_user_group_compat(
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
if (!valid_user_group_name_or_id_compat(k)) {
|
||||
if (!valid_user_group_name(k, VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX|VALID_USER_WARN)) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid user/group name or numeric ID: %s", k);
|
||||
return -ENOEXEC;
|
||||
}
|
||||
@@ -2122,7 +2122,7 @@ int config_parse_user_group_strv_compat(
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
if (!valid_user_group_name_or_id_compat(k)) {
|
||||
if (!valid_user_group_name(k, VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX|VALID_USER_WARN)) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid user/group name or numeric ID: %s", k);
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
+1
-1
@@ -4287,7 +4287,7 @@ static int user_from_unit_name(Unit *u, char **ret) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (valid_user_group_name(n)) {
|
||||
if (valid_user_group_name(n, 0)) {
|
||||
*ret = TAKE_PTR(n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user