7a8867abfa
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
127 lines
3.3 KiB
C
127 lines
3.3 KiB
C
/* SPDX-License-Identifier: LGPL-2.1+ */
|
|
|
|
#include "bus-util.h"
|
|
#include "dbus-util.h"
|
|
#include "parse-util.h"
|
|
#include "path-util.h"
|
|
#include "unit-printf.h"
|
|
#include "user-util.h"
|
|
#include "unit.h"
|
|
|
|
int bus_property_get_triggered_unit(
|
|
sd_bus *bus,
|
|
const char *path,
|
|
const char *interface,
|
|
const char *property,
|
|
sd_bus_message *reply,
|
|
void *userdata,
|
|
sd_bus_error *error) {
|
|
|
|
Unit *u = userdata, *trigger;
|
|
|
|
assert(bus);
|
|
assert(reply);
|
|
assert(u);
|
|
|
|
trigger = UNIT_TRIGGER(u);
|
|
|
|
return sd_bus_message_append(reply, "s", trigger ? trigger->id : NULL);
|
|
}
|
|
|
|
BUS_DEFINE_SET_TRANSIENT(mode_t, "u", uint32_t, mode_t, "%040o");
|
|
BUS_DEFINE_SET_TRANSIENT(unsigned, "u", uint32_t, unsigned, "%" PRIu32);
|
|
|
|
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(
|
|
Unit *u,
|
|
const char *name,
|
|
char **p,
|
|
sd_bus_message *message,
|
|
UnitWriteFlags flags,
|
|
sd_bus_error *error) {
|
|
|
|
const char *v;
|
|
int r;
|
|
|
|
assert(p);
|
|
|
|
r = sd_bus_message_read(message, "s", &v);
|
|
if (r < 0)
|
|
return r;
|
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
|
r = free_and_strdup(p, empty_to_null(v));
|
|
if (r < 0)
|
|
return r;
|
|
|
|
unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name,
|
|
"%s=%s", name, strempty(v));
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
int bus_set_transient_bool(
|
|
Unit *u,
|
|
const char *name,
|
|
bool *p,
|
|
sd_bus_message *message,
|
|
UnitWriteFlags flags,
|
|
sd_bus_error *error) {
|
|
|
|
int v, r;
|
|
|
|
assert(p);
|
|
|
|
r = sd_bus_message_read(message, "b", &v);
|
|
if (r < 0)
|
|
return r;
|
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
|
*p = v;
|
|
unit_write_settingf(u, flags, name, "%s=%s", name, yes_no(v));
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
int bus_set_transient_usec_internal(
|
|
Unit *u,
|
|
const char *name,
|
|
usec_t *p,
|
|
bool fix_0,
|
|
sd_bus_message *message,
|
|
UnitWriteFlags flags,
|
|
sd_bus_error *error) {
|
|
|
|
uint64_t v;
|
|
int r;
|
|
|
|
assert(p);
|
|
|
|
r = sd_bus_message_read(message, "t", &v);
|
|
if (r < 0)
|
|
return r;
|
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
|
char *n, ts[FORMAT_TIMESPAN_MAX];
|
|
|
|
if (fix_0)
|
|
*p = v != 0 ? v: USEC_INFINITY;
|
|
else
|
|
*p = v;
|
|
|
|
n = strndupa(name, strlen(name) - 4);
|
|
unit_write_settingf(u, flags, name, "%sSec=%s", n,
|
|
format_timespan(ts, sizeof(ts), v, USEC_PER_MSEC));
|
|
}
|
|
|
|
return 1;
|
|
}
|