2017-11-18 17:09:20 +01:00
|
|
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
2010-04-18 03:08:16 +02:00
|
|
|
/***
|
|
|
|
This file is part of systemd.
|
|
|
|
|
|
|
|
Copyright 2010 Lennart Poettering
|
|
|
|
|
|
|
|
systemd is free software; you can redistribute it and/or modify it
|
2012-04-12 00:20:58 +02:00
|
|
|
under the terms of the GNU Lesser General Public License as published by
|
|
|
|
the Free Software Foundation; either version 2.1 of the License, or
|
2010-04-18 03:08:16 +02:00
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
systemd is distributed in the hope that it will be useful, but
|
|
|
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
2012-04-12 00:20:58 +02:00
|
|
|
Lesser General Public License for more details.
|
2010-04-18 03:08:16 +02:00
|
|
|
|
2012-04-12 00:20:58 +02:00
|
|
|
You should have received a copy of the GNU Lesser General Public License
|
2010-04-18 03:08:16 +02:00
|
|
|
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
***/
|
|
|
|
|
2010-07-04 16:44:58 +02:00
|
|
|
#include <sys/prctl.h>
|
2010-04-18 03:08:16 +02:00
|
|
|
|
2017-10-03 10:41:51 +02:00
|
|
|
#if HAVE_SECCOMP
|
2014-02-13 00:24:00 +01:00
|
|
|
#include <seccomp.h>
|
|
|
|
#endif
|
|
|
|
|
2015-10-25 13:14:12 +01:00
|
|
|
#include "af-list.h"
|
2015-10-27 03:01:06 +01:00
|
|
|
#include "alloc-util.h"
|
2013-11-19 21:12:59 +01:00
|
|
|
#include "bus-util.h"
|
2017-08-07 17:37:02 +02:00
|
|
|
#include "cap-list.h"
|
core: implement /run/systemd/units/-based path for passing unit info from PID 1 to journald
And let's make use of it to implement two new unit settings with it:
1. LogLevelMax= is a new per-unit setting that may be used to configure
log priority filtering: set it to LogLevelMax=notice and only
messages of level "notice" and lower (i.e. more important) will be
processed, all others are dropped.
2. LogExtraFields= is a new per-unit setting for configuring per-unit
journal fields, that are implicitly included in every log record
generated by the unit's processes. It takes field/value pairs in the
form of FOO=BAR.
Also, related to this, one exisiting unit setting is ported to this new
facility:
3. The invocation ID is now pulled from /run/systemd/units/ instead of
cgroupfs xattrs. This substantially relaxes requirements of systemd
on the kernel version and the privileges it runs with (specifically,
cgroupfs xattrs are not available in containers, since they are
stored in kernel memory, and hence are unsafe to permit to lesser
privileged code).
/run/systemd/units/ is a new directory, which contains a number of files
and symlinks encoding the above information. PID 1 creates and manages
these files, and journald reads them from there.
Note that this is supposed to be a direct path between PID 1 and the
journal only, due to the special runtime environment the journal runs
in. Normally, today we shouldn't introduce new interfaces that (mis-)use
a file system as IPC framework, and instead just an IPC system, but this
is very hard to do between the journal and PID 1, as long as the IPC
system is a subject PID 1 manages, and itself a client to the journal.
This patch cleans up a couple of types used in journal code:
specifically we switch to size_t for a couple of memory-sizing values,
as size_t is the right choice for everything that is memory.
Fixes: #4089
Fixes: #3041
Fixes: #4441
2017-11-02 19:43:32 +01:00
|
|
|
#include "capability-util.h"
|
2015-10-25 13:14:12 +01:00
|
|
|
#include "dbus-execute.h"
|
2014-02-05 02:02:00 +01:00
|
|
|
#include "env-util.h"
|
2017-08-07 17:37:02 +02:00
|
|
|
#include "errno-list.h"
|
2017-11-22 15:03:51 +01:00
|
|
|
#include "escape.h"
|
2015-10-25 13:14:12 +01:00
|
|
|
#include "execute.h"
|
|
|
|
#include "fd-util.h"
|
|
|
|
#include "fileio.h"
|
2017-10-27 11:33:05 +02:00
|
|
|
#include "hexdecoct.h"
|
core: implement /run/systemd/units/-based path for passing unit info from PID 1 to journald
And let's make use of it to implement two new unit settings with it:
1. LogLevelMax= is a new per-unit setting that may be used to configure
log priority filtering: set it to LogLevelMax=notice and only
messages of level "notice" and lower (i.e. more important) will be
processed, all others are dropped.
2. LogExtraFields= is a new per-unit setting for configuring per-unit
journal fields, that are implicitly included in every log record
generated by the unit's processes. It takes field/value pairs in the
form of FOO=BAR.
Also, related to this, one exisiting unit setting is ported to this new
facility:
3. The invocation ID is now pulled from /run/systemd/units/ instead of
cgroupfs xattrs. This substantially relaxes requirements of systemd
on the kernel version and the privileges it runs with (specifically,
cgroupfs xattrs are not available in containers, since they are
stored in kernel memory, and hence are unsafe to permit to lesser
privileged code).
/run/systemd/units/ is a new directory, which contains a number of files
and symlinks encoding the above information. PID 1 creates and manages
these files, and journald reads them from there.
Note that this is supposed to be a direct path between PID 1 and the
journal only, due to the special runtime environment the journal runs
in. Normally, today we shouldn't introduce new interfaces that (mis-)use
a file system as IPC framework, and instead just an IPC system, but this
is very hard to do between the journal and PID 1, as long as the IPC
system is a subject PID 1 manages, and itself a client to the journal.
This patch cleans up a couple of types used in journal code:
specifically we switch to size_t for a couple of memory-sizing values,
as size_t is the right choice for everything that is memory.
Fixes: #4089
Fixes: #3041
Fixes: #4441
2017-11-02 19:43:32 +01:00
|
|
|
#include "io-util.h"
|
2015-10-25 13:14:12 +01:00
|
|
|
#include "ioprio.h"
|
core: implement /run/systemd/units/-based path for passing unit info from PID 1 to journald
And let's make use of it to implement two new unit settings with it:
1. LogLevelMax= is a new per-unit setting that may be used to configure
log priority filtering: set it to LogLevelMax=notice and only
messages of level "notice" and lower (i.e. more important) will be
processed, all others are dropped.
2. LogExtraFields= is a new per-unit setting for configuring per-unit
journal fields, that are implicitly included in every log record
generated by the unit's processes. It takes field/value pairs in the
form of FOO=BAR.
Also, related to this, one exisiting unit setting is ported to this new
facility:
3. The invocation ID is now pulled from /run/systemd/units/ instead of
cgroupfs xattrs. This substantially relaxes requirements of systemd
on the kernel version and the privileges it runs with (specifically,
cgroupfs xattrs are not available in containers, since they are
stored in kernel memory, and hence are unsafe to permit to lesser
privileged code).
/run/systemd/units/ is a new directory, which contains a number of files
and symlinks encoding the above information. PID 1 creates and manages
these files, and journald reads them from there.
Note that this is supposed to be a direct path between PID 1 and the
journal only, due to the special runtime environment the journal runs
in. Normally, today we shouldn't introduce new interfaces that (mis-)use
a file system as IPC framework, and instead just an IPC system, but this
is very hard to do between the journal and PID 1, as long as the IPC
system is a subject PID 1 manages, and itself a client to the journal.
This patch cleans up a couple of types used in journal code:
specifically we switch to size_t for a couple of memory-sizing values,
as size_t is the right choice for everything that is memory.
Fixes: #4089
Fixes: #3041
Fixes: #4441
2017-11-02 19:43:32 +01:00
|
|
|
#include "journal-util.h"
|
2015-10-25 13:14:12 +01:00
|
|
|
#include "missing.h"
|
2016-11-22 20:19:08 +01:00
|
|
|
#include "mount-util.h"
|
2014-06-03 23:41:44 +02:00
|
|
|
#include "namespace.h"
|
2015-10-26 16:18:16 +01:00
|
|
|
#include "parse-util.h"
|
2014-12-22 19:45:32 +01:00
|
|
|
#include "path-util.h"
|
2015-10-27 14:24:58 +01:00
|
|
|
#include "process-util.h"
|
2015-10-26 19:40:43 +01:00
|
|
|
#include "rlimit-util.h"
|
2017-10-03 10:41:51 +02:00
|
|
|
#if HAVE_SECCOMP
|
2014-02-13 00:24:00 +01:00
|
|
|
#include "seccomp-util.h"
|
|
|
|
#endif
|
2017-08-07 17:37:02 +02:00
|
|
|
#include "securebits-util.h"
|
2017-11-22 15:03:51 +01:00
|
|
|
#include "specifier.h"
|
2015-10-26 16:18:16 +01:00
|
|
|
#include "strv.h"
|
2015-10-27 00:40:25 +01:00
|
|
|
#include "syslog-util.h"
|
2017-06-26 11:26:59 +02:00
|
|
|
#include "unit-printf.h"
|
2016-07-14 19:17:18 +02:00
|
|
|
#include "user-util.h"
|
2015-10-26 16:18:16 +01:00
|
|
|
#include "utf8.h"
|
2014-02-13 00:24:00 +01:00
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_exec_output, exec_output, ExecOutput);
|
|
|
|
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_input, exec_input, ExecInput);
|
2011-03-04 03:44:43 +01:00
|
|
|
|
2015-08-23 13:14:04 +02:00
|
|
|
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_utmp_mode, exec_utmp_mode, ExecUtmpMode);
|
2017-07-17 09:22:25 +02:00
|
|
|
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_preserve_mode, exec_preserve_mode, ExecPreserveMode);
|
2017-09-14 21:19:05 +02:00
|
|
|
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_keyring_mode, exec_keyring_mode, ExecKeyringMode);
|
2017-07-17 09:22:25 +02:00
|
|
|
|
2014-06-04 18:07:55 +02:00
|
|
|
static BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_protect_home, protect_home, ProtectHome);
|
|
|
|
static BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_protect_system, protect_system, ProtectSystem);
|
2014-06-03 23:41:44 +02:00
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
static int property_get_environment_files(
|
|
|
|
sd_bus *bus,
|
|
|
|
const char *path,
|
|
|
|
const char *interface,
|
|
|
|
const char *property,
|
|
|
|
sd_bus_message *reply,
|
2013-11-21 19:34:37 +01:00
|
|
|
void *userdata,
|
|
|
|
sd_bus_error *error) {
|
2011-03-04 03:44:43 +01:00
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
ExecContext *c = userdata;
|
|
|
|
char **j;
|
|
|
|
int r;
|
2011-03-04 03:44:43 +01:00
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
assert(bus);
|
|
|
|
assert(reply);
|
|
|
|
assert(c);
|
|
|
|
|
|
|
|
r = sd_bus_message_open_container(reply, 'a', "(sb)");
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
2011-03-04 03:44:43 +01:00
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
STRV_FOREACH(j, c->environment_files) {
|
|
|
|
const char *fn = *j;
|
2011-03-04 03:44:43 +01:00
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
r = sd_bus_message_append(reply, "(sb)", fn[0] == '-' ? fn + 1 : fn, fn[0] == '-');
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
2011-03-04 03:44:43 +01:00
|
|
|
}
|
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
return sd_bus_message_close_container(reply);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int property_get_oom_score_adjust(
|
|
|
|
sd_bus *bus,
|
|
|
|
const char *path,
|
|
|
|
const char *interface,
|
|
|
|
const char *property,
|
|
|
|
sd_bus_message *reply,
|
2013-11-21 19:34:37 +01:00
|
|
|
void *userdata,
|
|
|
|
sd_bus_error *error) {
|
2013-11-19 21:12:59 +01:00
|
|
|
|
|
|
|
|
|
|
|
ExecContext *c = userdata;
|
2010-07-04 16:44:58 +02:00
|
|
|
int32_t n;
|
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
assert(bus);
|
|
|
|
assert(reply);
|
2010-07-04 16:44:58 +02:00
|
|
|
assert(c);
|
|
|
|
|
2010-08-31 01:33:39 +02:00
|
|
|
if (c->oom_score_adjust_set)
|
|
|
|
n = c->oom_score_adjust;
|
2010-07-04 16:44:58 +02:00
|
|
|
else {
|
2013-07-25 17:36:01 +02:00
|
|
|
_cleanup_free_ char *t = NULL;
|
2010-07-04 16:44:58 +02:00
|
|
|
|
|
|
|
n = 0;
|
2013-11-19 21:12:59 +01:00
|
|
|
if (read_one_line_file("/proc/self/oom_score_adj", &t) >= 0)
|
2015-10-26 16:41:43 +01:00
|
|
|
safe_atoi32(t, &n);
|
2010-07-04 16:44:58 +02:00
|
|
|
}
|
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
return sd_bus_message_append(reply, "i", n);
|
2010-07-04 16:44:58 +02:00
|
|
|
}
|
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
static int property_get_nice(
|
|
|
|
sd_bus *bus,
|
|
|
|
const char *path,
|
|
|
|
const char *interface,
|
|
|
|
const char *property,
|
|
|
|
sd_bus_message *reply,
|
2013-11-21 19:34:37 +01:00
|
|
|
void *userdata,
|
|
|
|
sd_bus_error *error) {
|
2013-11-19 21:12:59 +01:00
|
|
|
|
|
|
|
|
|
|
|
ExecContext *c = userdata;
|
2010-07-04 16:44:58 +02:00
|
|
|
int32_t n;
|
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
assert(bus);
|
|
|
|
assert(reply);
|
2010-07-04 16:44:58 +02:00
|
|
|
assert(c);
|
|
|
|
|
|
|
|
if (c->nice_set)
|
|
|
|
n = c->nice;
|
2013-11-19 21:12:59 +01:00
|
|
|
else {
|
|
|
|
errno = 0;
|
2010-07-04 16:44:58 +02:00
|
|
|
n = getpriority(PRIO_PROCESS, 0);
|
2016-01-11 20:31:14 +01:00
|
|
|
if (errno > 0)
|
2013-11-19 21:12:59 +01:00
|
|
|
n = 0;
|
|
|
|
}
|
2010-07-04 16:44:58 +02:00
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
return sd_bus_message_append(reply, "i", n);
|
2010-07-04 16:44:58 +02:00
|
|
|
}
|
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
static int property_get_ioprio(
|
|
|
|
sd_bus *bus,
|
|
|
|
const char *path,
|
|
|
|
const char *interface,
|
|
|
|
const char *property,
|
|
|
|
sd_bus_message *reply,
|
2013-11-21 19:34:37 +01:00
|
|
|
void *userdata,
|
|
|
|
sd_bus_error *error) {
|
2013-11-19 21:12:59 +01:00
|
|
|
|
|
|
|
|
|
|
|
ExecContext *c = userdata;
|
2010-07-04 16:44:58 +02:00
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
assert(bus);
|
|
|
|
assert(reply);
|
2010-07-04 16:44:58 +02:00
|
|
|
assert(c);
|
|
|
|
|
2017-06-26 17:40:08 +02:00
|
|
|
return sd_bus_message_append(reply, "i", exec_context_get_effective_ioprio(c));
|
|
|
|
}
|
2010-07-04 16:44:58 +02:00
|
|
|
|
2017-06-26 17:40:08 +02:00
|
|
|
static int property_get_ioprio_class(
|
|
|
|
sd_bus *bus,
|
|
|
|
const char *path,
|
|
|
|
const char *interface,
|
|
|
|
const char *property,
|
|
|
|
sd_bus_message *reply,
|
|
|
|
void *userdata,
|
|
|
|
sd_bus_error *error) {
|
|
|
|
|
|
|
|
|
|
|
|
ExecContext *c = userdata;
|
|
|
|
|
|
|
|
assert(bus);
|
|
|
|
assert(reply);
|
|
|
|
assert(c);
|
|
|
|
|
|
|
|
return sd_bus_message_append(reply, "i", IOPRIO_PRIO_CLASS(exec_context_get_effective_ioprio(c)));
|
|
|
|
}
|
|
|
|
|
|
|
|
static int property_get_ioprio_priority(
|
|
|
|
sd_bus *bus,
|
|
|
|
const char *path,
|
|
|
|
const char *interface,
|
|
|
|
const char *property,
|
|
|
|
sd_bus_message *reply,
|
|
|
|
void *userdata,
|
|
|
|
sd_bus_error *error) {
|
|
|
|
|
|
|
|
|
|
|
|
ExecContext *c = userdata;
|
|
|
|
|
|
|
|
assert(bus);
|
|
|
|
assert(reply);
|
|
|
|
assert(c);
|
|
|
|
|
|
|
|
return sd_bus_message_append(reply, "i", IOPRIO_PRIO_DATA(exec_context_get_effective_ioprio(c)));
|
2010-07-04 16:44:58 +02:00
|
|
|
}
|
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
static int property_get_cpu_sched_policy(
|
|
|
|
sd_bus *bus,
|
|
|
|
const char *path,
|
|
|
|
const char *interface,
|
|
|
|
const char *property,
|
|
|
|
sd_bus_message *reply,
|
2013-11-21 19:34:37 +01:00
|
|
|
void *userdata,
|
|
|
|
sd_bus_error *error) {
|
2013-11-19 21:12:59 +01:00
|
|
|
|
|
|
|
ExecContext *c = userdata;
|
2010-07-04 16:44:58 +02:00
|
|
|
int32_t n;
|
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
assert(bus);
|
|
|
|
assert(reply);
|
2010-07-04 16:44:58 +02:00
|
|
|
assert(c);
|
|
|
|
|
|
|
|
if (c->cpu_sched_set)
|
|
|
|
n = c->cpu_sched_policy;
|
2013-11-19 21:12:59 +01:00
|
|
|
else {
|
2010-07-04 16:44:58 +02:00
|
|
|
n = sched_getscheduler(0);
|
2013-11-19 21:12:59 +01:00
|
|
|
if (n < 0)
|
|
|
|
n = SCHED_OTHER;
|
|
|
|
}
|
2010-07-04 16:44:58 +02:00
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
return sd_bus_message_append(reply, "i", n);
|
2010-07-04 16:44:58 +02:00
|
|
|
}
|
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
static int property_get_cpu_sched_priority(
|
|
|
|
sd_bus *bus,
|
|
|
|
const char *path,
|
|
|
|
const char *interface,
|
|
|
|
const char *property,
|
|
|
|
sd_bus_message *reply,
|
2013-11-21 19:34:37 +01:00
|
|
|
void *userdata,
|
|
|
|
sd_bus_error *error) {
|
2013-11-19 21:12:59 +01:00
|
|
|
|
|
|
|
ExecContext *c = userdata;
|
2010-07-04 16:44:58 +02:00
|
|
|
int32_t n;
|
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
assert(bus);
|
|
|
|
assert(reply);
|
2010-07-04 16:44:58 +02:00
|
|
|
assert(c);
|
|
|
|
|
|
|
|
if (c->cpu_sched_set)
|
|
|
|
n = c->cpu_sched_priority;
|
|
|
|
else {
|
2013-03-25 00:59:00 +01:00
|
|
|
struct sched_param p = {};
|
2010-07-04 16:44:58 +02:00
|
|
|
|
|
|
|
if (sched_getparam(0, &p) >= 0)
|
|
|
|
n = p.sched_priority;
|
2013-03-25 00:45:16 +01:00
|
|
|
else
|
|
|
|
n = 0;
|
2010-07-04 16:44:58 +02:00
|
|
|
}
|
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
return sd_bus_message_append(reply, "i", n);
|
2010-07-04 16:44:58 +02:00
|
|
|
}
|
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
static int property_get_cpu_affinity(
|
|
|
|
sd_bus *bus,
|
|
|
|
const char *path,
|
|
|
|
const char *interface,
|
|
|
|
const char *property,
|
|
|
|
sd_bus_message *reply,
|
2013-11-21 19:34:37 +01:00
|
|
|
void *userdata,
|
|
|
|
sd_bus_error *error) {
|
2010-07-04 16:44:58 +02:00
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
ExecContext *c = userdata;
|
2010-07-04 16:44:58 +02:00
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
assert(bus);
|
|
|
|
assert(reply);
|
|
|
|
assert(c);
|
2010-07-04 16:44:58 +02:00
|
|
|
|
|
|
|
if (c->cpuset)
|
2013-11-19 21:12:59 +01:00
|
|
|
return sd_bus_message_append_array(reply, 'y', c->cpuset, CPU_ALLOC_SIZE(c->cpuset_ncpus));
|
2010-07-04 16:44:58 +02:00
|
|
|
else
|
2013-11-19 21:12:59 +01:00
|
|
|
return sd_bus_message_append_array(reply, 'y', NULL, 0);
|
2010-07-04 16:44:58 +02:00
|
|
|
}
|
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
static int property_get_timer_slack_nsec(
|
|
|
|
sd_bus *bus,
|
|
|
|
const char *path,
|
|
|
|
const char *interface,
|
|
|
|
const char *property,
|
|
|
|
sd_bus_message *reply,
|
2013-11-21 19:34:37 +01:00
|
|
|
void *userdata,
|
|
|
|
sd_bus_error *error) {
|
2013-11-19 21:12:59 +01:00
|
|
|
|
|
|
|
ExecContext *c = userdata;
|
2010-07-04 16:44:58 +02:00
|
|
|
uint64_t u;
|
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
assert(bus);
|
|
|
|
assert(reply);
|
2010-07-04 16:44:58 +02:00
|
|
|
assert(c);
|
|
|
|
|
2014-07-29 12:23:31 +02:00
|
|
|
if (c->timer_slack_nsec != NSEC_INFINITY)
|
2010-07-04 21:12:10 +02:00
|
|
|
u = (uint64_t) c->timer_slack_nsec;
|
2010-07-04 16:44:58 +02:00
|
|
|
else
|
|
|
|
u = (uint64_t) prctl(PR_GET_TIMERSLACK);
|
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
return sd_bus_message_append(reply, "t", u);
|
2010-07-04 16:44:58 +02:00
|
|
|
}
|
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
static int property_get_capability_bounding_set(
|
|
|
|
sd_bus *bus,
|
|
|
|
const char *path,
|
|
|
|
const char *interface,
|
|
|
|
const char *property,
|
|
|
|
sd_bus_message *reply,
|
2013-11-21 19:34:37 +01:00
|
|
|
void *userdata,
|
|
|
|
sd_bus_error *error) {
|
2011-03-18 03:13:15 +01:00
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
ExecContext *c = userdata;
|
|
|
|
|
|
|
|
assert(bus);
|
|
|
|
assert(reply);
|
2011-03-18 03:13:15 +01:00
|
|
|
assert(c);
|
|
|
|
|
2016-01-07 23:00:04 +01:00
|
|
|
return sd_bus_message_append(reply, "t", c->capability_bounding_set);
|
2011-03-18 03:13:15 +01:00
|
|
|
}
|
|
|
|
|
2015-12-31 13:54:44 +01:00
|
|
|
static int property_get_ambient_capabilities(
|
|
|
|
sd_bus *bus,
|
|
|
|
const char *path,
|
|
|
|
const char *interface,
|
|
|
|
const char *property,
|
|
|
|
sd_bus_message *reply,
|
|
|
|
void *userdata,
|
|
|
|
sd_bus_error *error) {
|
|
|
|
|
|
|
|
ExecContext *c = userdata;
|
|
|
|
|
|
|
|
assert(bus);
|
|
|
|
assert(reply);
|
|
|
|
assert(c);
|
|
|
|
|
|
|
|
return sd_bus_message_append(reply, "t", c->capability_ambient_set);
|
|
|
|
}
|
|
|
|
|
2016-02-12 23:29:57 +01:00
|
|
|
static int property_get_empty_string(
|
2013-11-19 21:12:59 +01:00
|
|
|
sd_bus *bus,
|
|
|
|
const char *path,
|
|
|
|
const char *interface,
|
|
|
|
const char *property,
|
|
|
|
sd_bus_message *reply,
|
2013-11-21 19:34:37 +01:00
|
|
|
void *userdata,
|
|
|
|
sd_bus_error *error) {
|
2013-11-19 21:12:59 +01:00
|
|
|
|
|
|
|
assert(bus);
|
|
|
|
assert(reply);
|
2010-07-04 16:44:58 +02:00
|
|
|
|
2016-02-12 23:29:57 +01:00
|
|
|
return sd_bus_message_append(reply, "s", "");
|
2010-07-04 16:44:58 +02:00
|
|
|
}
|
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
static int property_get_syscall_filter(
|
|
|
|
sd_bus *bus,
|
|
|
|
const char *path,
|
|
|
|
const char *interface,
|
|
|
|
const char *property,
|
|
|
|
sd_bus_message *reply,
|
2013-11-21 19:34:37 +01:00
|
|
|
void *userdata,
|
|
|
|
sd_bus_error *error) {
|
2010-07-04 16:44:58 +02:00
|
|
|
|
2014-02-12 18:28:21 +01:00
|
|
|
ExecContext *c = userdata;
|
|
|
|
_cleanup_strv_free_ char **l = NULL;
|
2014-02-13 00:24:00 +01:00
|
|
|
int r;
|
|
|
|
|
2017-10-03 10:41:51 +02:00
|
|
|
#if HAVE_SECCOMP
|
2014-02-12 18:28:21 +01:00
|
|
|
Iterator i;
|
2017-11-11 13:35:49 +01:00
|
|
|
void *id, *val;
|
2014-02-12 18:44:40 +01:00
|
|
|
#endif
|
2014-02-12 18:28:21 +01:00
|
|
|
|
|
|
|
assert(bus);
|
|
|
|
assert(reply);
|
|
|
|
assert(c);
|
|
|
|
|
2014-02-13 00:24:00 +01:00
|
|
|
r = sd_bus_message_open_container(reply, 'r', "bas");
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
r = sd_bus_message_append(reply, "b", c->syscall_whitelist);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
2017-10-03 10:41:51 +02:00
|
|
|
#if HAVE_SECCOMP
|
2017-11-11 13:35:49 +01:00
|
|
|
HASHMAP_FOREACH_KEY(val, id, c->syscall_filter, i) {
|
|
|
|
_cleanup_free_ char *name = NULL;
|
|
|
|
const char *e = NULL;
|
|
|
|
char *s;
|
|
|
|
int num = PTR_TO_INT(val);
|
2014-02-12 18:28:21 +01:00
|
|
|
|
|
|
|
name = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, PTR_TO_INT(id) - 1);
|
|
|
|
if (!name)
|
|
|
|
continue;
|
|
|
|
|
2017-11-11 13:35:49 +01:00
|
|
|
if (num >= 0) {
|
|
|
|
e = errno_to_name(num);
|
|
|
|
if (e) {
|
|
|
|
s = strjoin(name, ":", e);
|
|
|
|
if (!s)
|
|
|
|
return -ENOMEM;
|
|
|
|
} else {
|
|
|
|
r = asprintf(&s, "%s:%d", name, num);
|
|
|
|
if (r < 0)
|
|
|
|
return -ENOMEM;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
s = name;
|
|
|
|
name = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
r = strv_consume(&l, s);
|
2014-03-04 15:20:51 +01:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
2014-02-12 18:28:21 +01:00
|
|
|
}
|
2014-02-12 18:44:40 +01:00
|
|
|
#endif
|
2014-02-12 18:28:21 +01:00
|
|
|
|
|
|
|
strv_sort(l);
|
|
|
|
|
2014-02-13 00:24:00 +01:00
|
|
|
r = sd_bus_message_append_strv(reply, l);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
2014-02-12 18:28:21 +01:00
|
|
|
|
2014-02-13 00:24:00 +01:00
|
|
|
return sd_bus_message_close_container(reply);
|
|
|
|
}
|
2014-02-12 18:28:21 +01:00
|
|
|
|
2014-02-13 00:24:00 +01:00
|
|
|
static int property_get_syscall_archs(
|
|
|
|
sd_bus *bus,
|
|
|
|
const char *path,
|
|
|
|
const char *interface,
|
|
|
|
const char *property,
|
|
|
|
sd_bus_message *reply,
|
|
|
|
void *userdata,
|
|
|
|
sd_bus_error *error) {
|
|
|
|
|
|
|
|
ExecContext *c = userdata;
|
|
|
|
_cleanup_strv_free_ char **l = NULL;
|
|
|
|
int r;
|
|
|
|
|
2017-10-03 10:41:51 +02:00
|
|
|
#if HAVE_SECCOMP
|
2014-02-13 00:24:00 +01:00
|
|
|
Iterator i;
|
|
|
|
void *id;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
assert(bus);
|
|
|
|
assert(reply);
|
|
|
|
assert(c);
|
2014-02-12 18:28:21 +01:00
|
|
|
|
2017-10-03 10:41:51 +02:00
|
|
|
#if HAVE_SECCOMP
|
2014-02-13 00:24:00 +01:00
|
|
|
SET_FOREACH(id, c->syscall_archs, i) {
|
|
|
|
const char *name;
|
|
|
|
|
|
|
|
name = seccomp_arch_to_string(PTR_TO_UINT32(id) - 1);
|
|
|
|
if (!name)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
r = strv_extend(&l, name);
|
|
|
|
if (r < 0)
|
|
|
|
return -ENOMEM;
|
2014-02-12 18:28:21 +01:00
|
|
|
}
|
2014-02-13 00:24:00 +01:00
|
|
|
#endif
|
|
|
|
|
|
|
|
strv_sort(l);
|
|
|
|
|
|
|
|
r = sd_bus_message_append_strv(reply, l);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
2014-02-12 18:28:21 +01:00
|
|
|
|
2014-02-13 00:24:00 +01:00
|
|
|
return 0;
|
2014-02-12 18:28:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static int property_get_syscall_errno(
|
|
|
|
sd_bus *bus,
|
|
|
|
const char *path,
|
|
|
|
const char *interface,
|
|
|
|
const char *property,
|
|
|
|
sd_bus_message *reply,
|
|
|
|
void *userdata,
|
|
|
|
sd_bus_error *error) {
|
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
ExecContext *c = userdata;
|
2010-07-04 16:44:58 +02:00
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
assert(bus);
|
|
|
|
assert(reply);
|
|
|
|
assert(c);
|
2010-07-04 16:44:58 +02:00
|
|
|
|
2014-02-12 18:28:21 +01:00
|
|
|
return sd_bus_message_append(reply, "i", (int32_t) c->syscall_errno);
|
2013-11-19 21:12:59 +01:00
|
|
|
}
|
2010-07-04 16:44:58 +02:00
|
|
|
|
2014-02-17 16:52:52 +01:00
|
|
|
static int property_get_selinux_context(
|
|
|
|
sd_bus *bus,
|
|
|
|
const char *path,
|
|
|
|
const char *interface,
|
|
|
|
const char *property,
|
|
|
|
sd_bus_message *reply,
|
|
|
|
void *userdata,
|
|
|
|
sd_bus_error *error) {
|
|
|
|
|
|
|
|
ExecContext *c = userdata;
|
|
|
|
|
|
|
|
assert(bus);
|
|
|
|
assert(reply);
|
|
|
|
assert(c);
|
|
|
|
|
|
|
|
return sd_bus_message_append(reply, "(bs)", c->selinux_context_ignore, c->selinux_context);
|
|
|
|
}
|
|
|
|
|
2014-02-20 16:19:44 +01:00
|
|
|
static int property_get_apparmor_profile(
|
|
|
|
sd_bus *bus,
|
|
|
|
const char *path,
|
|
|
|
const char *interface,
|
|
|
|
const char *property,
|
|
|
|
sd_bus_message *reply,
|
|
|
|
void *userdata,
|
|
|
|
sd_bus_error *error) {
|
|
|
|
|
|
|
|
ExecContext *c = userdata;
|
|
|
|
|
|
|
|
assert(bus);
|
|
|
|
assert(reply);
|
|
|
|
assert(c);
|
|
|
|
|
|
|
|
return sd_bus_message_append(reply, "(bs)", c->apparmor_profile_ignore, c->apparmor_profile);
|
|
|
|
}
|
|
|
|
|
2014-11-24 12:46:20 +01:00
|
|
|
static int property_get_smack_process_label(
|
|
|
|
sd_bus *bus,
|
|
|
|
const char *path,
|
|
|
|
const char *interface,
|
|
|
|
const char *property,
|
|
|
|
sd_bus_message *reply,
|
|
|
|
void *userdata,
|
|
|
|
sd_bus_error *error) {
|
|
|
|
|
|
|
|
ExecContext *c = userdata;
|
|
|
|
|
|
|
|
assert(bus);
|
|
|
|
assert(reply);
|
|
|
|
assert(c);
|
|
|
|
|
|
|
|
return sd_bus_message_append(reply, "(bs)", c->smack_process_label_ignore, c->smack_process_label);
|
|
|
|
}
|
|
|
|
|
2014-02-19 02:15:24 +01:00
|
|
|
static int property_get_personality(
|
|
|
|
sd_bus *bus,
|
|
|
|
const char *path,
|
|
|
|
const char *interface,
|
|
|
|
const char *property,
|
|
|
|
sd_bus_message *reply,
|
|
|
|
void *userdata,
|
|
|
|
sd_bus_error *error) {
|
|
|
|
|
|
|
|
ExecContext *c = userdata;
|
|
|
|
|
|
|
|
assert(bus);
|
|
|
|
assert(reply);
|
|
|
|
assert(c);
|
|
|
|
|
|
|
|
return sd_bus_message_append(reply, "s", personality_to_string(c->personality));
|
|
|
|
}
|
|
|
|
|
2014-02-25 20:37:03 +01:00
|
|
|
static int property_get_address_families(
|
|
|
|
sd_bus *bus,
|
|
|
|
const char *path,
|
|
|
|
const char *interface,
|
|
|
|
const char *property,
|
|
|
|
sd_bus_message *reply,
|
|
|
|
void *userdata,
|
|
|
|
sd_bus_error *error) {
|
|
|
|
|
|
|
|
ExecContext *c = userdata;
|
|
|
|
_cleanup_strv_free_ char **l = NULL;
|
|
|
|
Iterator i;
|
|
|
|
void *af;
|
|
|
|
int r;
|
|
|
|
|
|
|
|
assert(bus);
|
|
|
|
assert(reply);
|
|
|
|
assert(c);
|
|
|
|
|
|
|
|
r = sd_bus_message_open_container(reply, 'r', "bas");
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
r = sd_bus_message_append(reply, "b", c->address_families_whitelist);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
SET_FOREACH(af, c->address_families, i) {
|
|
|
|
const char *name;
|
|
|
|
|
|
|
|
name = af_to_name(PTR_TO_INT(af));
|
|
|
|
if (!name)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
r = strv_extend(&l, name);
|
|
|
|
if (r < 0)
|
|
|
|
return -ENOMEM;
|
|
|
|
}
|
|
|
|
|
|
|
|
strv_sort(l);
|
|
|
|
|
|
|
|
r = sd_bus_message_append_strv(reply, l);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
return sd_bus_message_close_container(reply);
|
|
|
|
}
|
|
|
|
|
2015-09-23 19:46:23 +02:00
|
|
|
static int property_get_working_directory(
|
|
|
|
sd_bus *bus,
|
|
|
|
const char *path,
|
|
|
|
const char *interface,
|
|
|
|
const char *property,
|
|
|
|
sd_bus_message *reply,
|
|
|
|
void *userdata,
|
|
|
|
sd_bus_error *error) {
|
|
|
|
|
|
|
|
ExecContext *c = userdata;
|
|
|
|
const char *wd;
|
|
|
|
|
|
|
|
assert(bus);
|
|
|
|
assert(reply);
|
|
|
|
assert(c);
|
|
|
|
|
|
|
|
if (c->working_directory_home)
|
|
|
|
wd = "~";
|
|
|
|
else
|
|
|
|
wd = c->working_directory;
|
|
|
|
|
|
|
|
if (c->working_directory_missing_ok)
|
|
|
|
wd = strjoina("!", wd);
|
|
|
|
|
|
|
|
return sd_bus_message_append(reply, "s", wd);
|
|
|
|
}
|
|
|
|
|
2015-10-11 06:57:17 +02:00
|
|
|
static int property_get_syslog_level(
|
|
|
|
sd_bus *bus,
|
|
|
|
const char *path,
|
|
|
|
const char *interface,
|
|
|
|
const char *property,
|
|
|
|
sd_bus_message *reply,
|
|
|
|
void *userdata,
|
|
|
|
sd_bus_error *error) {
|
|
|
|
|
|
|
|
ExecContext *c = userdata;
|
|
|
|
|
|
|
|
assert(bus);
|
|
|
|
assert(reply);
|
|
|
|
assert(c);
|
|
|
|
|
|
|
|
return sd_bus_message_append(reply, "i", LOG_PRI(c->syslog_priority));
|
|
|
|
}
|
|
|
|
|
|
|
|
static int property_get_syslog_facility(
|
|
|
|
sd_bus *bus,
|
|
|
|
const char *path,
|
|
|
|
const char *interface,
|
|
|
|
const char *property,
|
|
|
|
sd_bus_message *reply,
|
|
|
|
void *userdata,
|
|
|
|
sd_bus_error *error) {
|
|
|
|
|
|
|
|
ExecContext *c = userdata;
|
|
|
|
|
|
|
|
assert(bus);
|
|
|
|
assert(reply);
|
|
|
|
assert(c);
|
|
|
|
|
|
|
|
return sd_bus_message_append(reply, "i", LOG_FAC(c->syslog_priority));
|
|
|
|
}
|
|
|
|
|
2017-10-27 14:57:12 +02:00
|
|
|
static int property_get_stdio_fdname(
|
2016-10-18 02:05:49 +02:00
|
|
|
sd_bus *bus,
|
|
|
|
const char *path,
|
|
|
|
const char *interface,
|
|
|
|
const char *property,
|
|
|
|
sd_bus_message *reply,
|
|
|
|
void *userdata,
|
|
|
|
sd_bus_error *error) {
|
|
|
|
|
|
|
|
ExecContext *c = userdata;
|
2017-10-27 14:57:12 +02:00
|
|
|
int fileno;
|
2016-10-18 02:05:49 +02:00
|
|
|
|
|
|
|
assert(bus);
|
|
|
|
assert(c);
|
|
|
|
assert(property);
|
|
|
|
assert(reply);
|
|
|
|
|
2017-10-27 14:57:12 +02:00
|
|
|
if (streq(property, "StandardInputFileDescriptorName"))
|
|
|
|
fileno = STDIN_FILENO;
|
|
|
|
else if (streq(property, "StandardOutputFileDescriptorName"))
|
|
|
|
fileno = STDOUT_FILENO;
|
|
|
|
else {
|
|
|
|
assert(streq(property, "StandardErrorFileDescriptorName"));
|
|
|
|
fileno = STDERR_FILENO;
|
|
|
|
}
|
2016-10-18 02:05:49 +02:00
|
|
|
|
2017-10-27 14:57:12 +02:00
|
|
|
return sd_bus_message_append(reply, "s", exec_context_fdname(c, fileno));
|
2016-10-18 02:05:49 +02:00
|
|
|
}
|
|
|
|
|
2017-10-27 11:33:05 +02:00
|
|
|
static int property_get_input_data(
|
2016-10-18 02:05:49 +02:00
|
|
|
sd_bus *bus,
|
|
|
|
const char *path,
|
|
|
|
const char *interface,
|
|
|
|
const char *property,
|
|
|
|
sd_bus_message *reply,
|
|
|
|
void *userdata,
|
|
|
|
sd_bus_error *error) {
|
|
|
|
|
|
|
|
ExecContext *c = userdata;
|
|
|
|
|
|
|
|
assert(bus);
|
|
|
|
assert(c);
|
|
|
|
assert(property);
|
|
|
|
assert(reply);
|
|
|
|
|
2017-10-27 11:33:05 +02:00
|
|
|
return sd_bus_message_append_array(reply, 'y', c->stdin_data, c->stdin_data_size);
|
2016-10-18 02:05:49 +02:00
|
|
|
}
|
|
|
|
|
2016-11-23 22:21:40 +01:00
|
|
|
static int property_get_bind_paths(
|
|
|
|
sd_bus *bus,
|
|
|
|
const char *path,
|
|
|
|
const char *interface,
|
|
|
|
const char *property,
|
|
|
|
sd_bus_message *reply,
|
|
|
|
void *userdata,
|
|
|
|
sd_bus_error *error) {
|
|
|
|
|
|
|
|
ExecContext *c = userdata;
|
|
|
|
unsigned i;
|
|
|
|
bool ro;
|
|
|
|
int r;
|
|
|
|
|
|
|
|
assert(bus);
|
|
|
|
assert(c);
|
|
|
|
assert(property);
|
|
|
|
assert(reply);
|
|
|
|
|
|
|
|
ro = !!strstr(property, "ReadOnly");
|
|
|
|
|
|
|
|
r = sd_bus_message_open_container(reply, 'a', "(ssbt)");
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
for (i = 0; i < c->n_bind_mounts; i++) {
|
|
|
|
|
|
|
|
if (ro != c->bind_mounts[i].read_only)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
r = sd_bus_message_append(
|
|
|
|
reply, "(ssbt)",
|
|
|
|
c->bind_mounts[i].source,
|
|
|
|
c->bind_mounts[i].destination,
|
|
|
|
c->bind_mounts[i].ignore_enoent,
|
2017-04-10 13:20:17 +02:00
|
|
|
c->bind_mounts[i].recursive ? (uint64_t) MS_REC : (uint64_t) 0);
|
2016-11-23 22:21:40 +01:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
return sd_bus_message_close_container(reply);
|
|
|
|
}
|
|
|
|
|
core: implement /run/systemd/units/-based path for passing unit info from PID 1 to journald
And let's make use of it to implement two new unit settings with it:
1. LogLevelMax= is a new per-unit setting that may be used to configure
log priority filtering: set it to LogLevelMax=notice and only
messages of level "notice" and lower (i.e. more important) will be
processed, all others are dropped.
2. LogExtraFields= is a new per-unit setting for configuring per-unit
journal fields, that are implicitly included in every log record
generated by the unit's processes. It takes field/value pairs in the
form of FOO=BAR.
Also, related to this, one exisiting unit setting is ported to this new
facility:
3. The invocation ID is now pulled from /run/systemd/units/ instead of
cgroupfs xattrs. This substantially relaxes requirements of systemd
on the kernel version and the privileges it runs with (specifically,
cgroupfs xattrs are not available in containers, since they are
stored in kernel memory, and hence are unsafe to permit to lesser
privileged code).
/run/systemd/units/ is a new directory, which contains a number of files
and symlinks encoding the above information. PID 1 creates and manages
these files, and journald reads them from there.
Note that this is supposed to be a direct path between PID 1 and the
journal only, due to the special runtime environment the journal runs
in. Normally, today we shouldn't introduce new interfaces that (mis-)use
a file system as IPC framework, and instead just an IPC system, but this
is very hard to do between the journal and PID 1, as long as the IPC
system is a subject PID 1 manages, and itself a client to the journal.
This patch cleans up a couple of types used in journal code:
specifically we switch to size_t for a couple of memory-sizing values,
as size_t is the right choice for everything that is memory.
Fixes: #4089
Fixes: #3041
Fixes: #4441
2017-11-02 19:43:32 +01:00
|
|
|
static int property_get_log_extra_fields(
|
|
|
|
sd_bus *bus,
|
|
|
|
const char *path,
|
|
|
|
const char *interface,
|
|
|
|
const char *property,
|
|
|
|
sd_bus_message *reply,
|
|
|
|
void *userdata,
|
|
|
|
sd_bus_error *error) {
|
|
|
|
|
|
|
|
ExecContext *c = userdata;
|
|
|
|
size_t i;
|
|
|
|
int r;
|
|
|
|
|
|
|
|
assert(bus);
|
|
|
|
assert(c);
|
|
|
|
assert(property);
|
|
|
|
assert(reply);
|
|
|
|
|
|
|
|
r = sd_bus_message_open_container(reply, 'a', "ay");
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
for (i = 0; i < c->n_log_extra_fields; i++) {
|
|
|
|
r = sd_bus_message_append_array(reply, 'y', c->log_extra_fields[i].iov_base, c->log_extra_fields[i].iov_len);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
return sd_bus_message_close_container(reply);
|
|
|
|
}
|
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
const sd_bus_vtable bus_exec_vtable[] = {
|
|
|
|
SD_BUS_VTABLE_START(0),
|
2013-12-22 02:24:05 +01:00
|
|
|
SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(ExecContext, environment), SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("EnvironmentFiles", "a(sb)", property_get_environment_files, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
2015-09-07 08:06:53 +02:00
|
|
|
SD_BUS_PROPERTY("PassEnvironment", "as", NULL, offsetof(ExecContext, pass_environment), SD_BUS_VTABLE_PROPERTY_CONST),
|
2017-09-10 12:16:44 +02:00
|
|
|
SD_BUS_PROPERTY("UnsetEnvironment", "as", NULL, offsetof(ExecContext, unset_environment), SD_BUS_VTABLE_PROPERTY_CONST),
|
2013-12-22 02:24:05 +01:00
|
|
|
SD_BUS_PROPERTY("UMask", "u", bus_property_get_mode, offsetof(ExecContext, umask), SD_BUS_VTABLE_PROPERTY_CONST),
|
2015-10-12 07:16:05 +02:00
|
|
|
SD_BUS_PROPERTY("LimitCPU", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CPU]), SD_BUS_VTABLE_PROPERTY_CONST),
|
2015-11-28 17:49:13 +01:00
|
|
|
SD_BUS_PROPERTY("LimitCPUSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CPU]), SD_BUS_VTABLE_PROPERTY_CONST),
|
2015-10-12 07:16:05 +02:00
|
|
|
SD_BUS_PROPERTY("LimitFSIZE", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_FSIZE]), SD_BUS_VTABLE_PROPERTY_CONST),
|
2015-11-28 17:49:13 +01:00
|
|
|
SD_BUS_PROPERTY("LimitFSIZESoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_FSIZE]), SD_BUS_VTABLE_PROPERTY_CONST),
|
2015-10-12 07:16:05 +02:00
|
|
|
SD_BUS_PROPERTY("LimitDATA", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_DATA]), SD_BUS_VTABLE_PROPERTY_CONST),
|
2015-11-28 17:49:13 +01:00
|
|
|
SD_BUS_PROPERTY("LimitDATASoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_DATA]), SD_BUS_VTABLE_PROPERTY_CONST),
|
2015-10-12 07:16:05 +02:00
|
|
|
SD_BUS_PROPERTY("LimitSTACK", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_STACK]), SD_BUS_VTABLE_PROPERTY_CONST),
|
2015-11-28 17:49:13 +01:00
|
|
|
SD_BUS_PROPERTY("LimitSTACKSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_STACK]), SD_BUS_VTABLE_PROPERTY_CONST),
|
2015-10-12 07:16:05 +02:00
|
|
|
SD_BUS_PROPERTY("LimitCORE", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CORE]), SD_BUS_VTABLE_PROPERTY_CONST),
|
2015-11-28 17:49:13 +01:00
|
|
|
SD_BUS_PROPERTY("LimitCORESoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CORE]), SD_BUS_VTABLE_PROPERTY_CONST),
|
2015-10-12 07:16:05 +02:00
|
|
|
SD_BUS_PROPERTY("LimitRSS", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RSS]), SD_BUS_VTABLE_PROPERTY_CONST),
|
2015-11-28 17:49:13 +01:00
|
|
|
SD_BUS_PROPERTY("LimitRSSSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RSS]), SD_BUS_VTABLE_PROPERTY_CONST),
|
2015-10-12 07:16:05 +02:00
|
|
|
SD_BUS_PROPERTY("LimitNOFILE", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NOFILE]), SD_BUS_VTABLE_PROPERTY_CONST),
|
2015-11-28 17:49:13 +01:00
|
|
|
SD_BUS_PROPERTY("LimitNOFILESoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NOFILE]), SD_BUS_VTABLE_PROPERTY_CONST),
|
2015-10-12 07:16:05 +02:00
|
|
|
SD_BUS_PROPERTY("LimitAS", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_AS]), SD_BUS_VTABLE_PROPERTY_CONST),
|
2015-11-28 17:49:13 +01:00
|
|
|
SD_BUS_PROPERTY("LimitASSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_AS]), SD_BUS_VTABLE_PROPERTY_CONST),
|
2015-10-12 07:16:05 +02:00
|
|
|
SD_BUS_PROPERTY("LimitNPROC", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NPROC]), SD_BUS_VTABLE_PROPERTY_CONST),
|
2015-11-28 17:49:13 +01:00
|
|
|
SD_BUS_PROPERTY("LimitNPROCSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NPROC]), SD_BUS_VTABLE_PROPERTY_CONST),
|
2015-10-12 07:16:05 +02:00
|
|
|
SD_BUS_PROPERTY("LimitMEMLOCK", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MEMLOCK]), SD_BUS_VTABLE_PROPERTY_CONST),
|
2015-11-28 17:49:13 +01:00
|
|
|
SD_BUS_PROPERTY("LimitMEMLOCKSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MEMLOCK]), SD_BUS_VTABLE_PROPERTY_CONST),
|
2015-10-12 07:16:05 +02:00
|
|
|
SD_BUS_PROPERTY("LimitLOCKS", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_LOCKS]), SD_BUS_VTABLE_PROPERTY_CONST),
|
2015-11-28 17:49:13 +01:00
|
|
|
SD_BUS_PROPERTY("LimitLOCKSSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_LOCKS]), SD_BUS_VTABLE_PROPERTY_CONST),
|
2015-10-12 07:16:05 +02:00
|
|
|
SD_BUS_PROPERTY("LimitSIGPENDING", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_SIGPENDING]), SD_BUS_VTABLE_PROPERTY_CONST),
|
2015-11-28 17:49:13 +01:00
|
|
|
SD_BUS_PROPERTY("LimitSIGPENDINGSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_SIGPENDING]), SD_BUS_VTABLE_PROPERTY_CONST),
|
2015-10-12 07:16:05 +02:00
|
|
|
SD_BUS_PROPERTY("LimitMSGQUEUE", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MSGQUEUE]), SD_BUS_VTABLE_PROPERTY_CONST),
|
2015-11-28 17:49:13 +01:00
|
|
|
SD_BUS_PROPERTY("LimitMSGQUEUESoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MSGQUEUE]), SD_BUS_VTABLE_PROPERTY_CONST),
|
2015-10-12 07:16:05 +02:00
|
|
|
SD_BUS_PROPERTY("LimitNICE", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NICE]), SD_BUS_VTABLE_PROPERTY_CONST),
|
2015-11-28 17:49:13 +01:00
|
|
|
SD_BUS_PROPERTY("LimitNICESoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NICE]), SD_BUS_VTABLE_PROPERTY_CONST),
|
2015-10-12 07:16:05 +02:00
|
|
|
SD_BUS_PROPERTY("LimitRTPRIO", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTPRIO]), SD_BUS_VTABLE_PROPERTY_CONST),
|
2015-11-28 17:49:13 +01:00
|
|
|
SD_BUS_PROPERTY("LimitRTPRIOSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTPRIO]), SD_BUS_VTABLE_PROPERTY_CONST),
|
2015-10-12 07:16:05 +02:00
|
|
|
SD_BUS_PROPERTY("LimitRTTIME", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
|
2015-11-28 17:49:13 +01:00
|
|
|
SD_BUS_PROPERTY("LimitRTTIMESoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
|
2015-09-23 19:46:23 +02:00
|
|
|
SD_BUS_PROPERTY("WorkingDirectory", "s", property_get_working_directory, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
2013-12-22 02:24:05 +01:00
|
|
|
SD_BUS_PROPERTY("RootDirectory", "s", NULL, offsetof(ExecContext, root_directory), SD_BUS_VTABLE_PROPERTY_CONST),
|
2016-12-23 14:26:05 +01:00
|
|
|
SD_BUS_PROPERTY("RootImage", "s", NULL, offsetof(ExecContext, root_image), SD_BUS_VTABLE_PROPERTY_CONST),
|
2013-12-22 02:24:05 +01:00
|
|
|
SD_BUS_PROPERTY("OOMScoreAdjust", "i", property_get_oom_score_adjust, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("Nice", "i", property_get_nice, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
2017-06-26 17:40:08 +02:00
|
|
|
SD_BUS_PROPERTY("IOSchedulingClass", "i", property_get_ioprio_class, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("IOSchedulingPriority", "i", property_get_ioprio_priority, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
2013-12-22 02:24:05 +01:00
|
|
|
SD_BUS_PROPERTY("CPUSchedulingPolicy", "i", property_get_cpu_sched_policy, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("CPUSchedulingPriority", "i", property_get_cpu_sched_priority, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("CPUAffinity", "ay", property_get_cpu_affinity, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("TimerSlackNSec", "t", property_get_timer_slack_nsec, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("CPUSchedulingResetOnFork", "b", bus_property_get_bool, offsetof(ExecContext, cpu_sched_reset_on_fork), SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("NonBlocking", "b", bus_property_get_bool, offsetof(ExecContext, non_blocking), SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("StandardInput", "s", property_get_exec_input, offsetof(ExecContext, std_input), SD_BUS_VTABLE_PROPERTY_CONST),
|
2017-10-27 14:57:12 +02:00
|
|
|
SD_BUS_PROPERTY("StandardInputFileDescriptorName", "s", property_get_stdio_fdname, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
2017-10-27 11:33:05 +02:00
|
|
|
SD_BUS_PROPERTY("StandardInputData", "ay", property_get_input_data, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
2013-12-22 02:24:05 +01:00
|
|
|
SD_BUS_PROPERTY("StandardOutput", "s", bus_property_get_exec_output, offsetof(ExecContext, std_output), SD_BUS_VTABLE_PROPERTY_CONST),
|
2017-10-27 14:57:12 +02:00
|
|
|
SD_BUS_PROPERTY("StandardOutputFileDescriptorName", "s", property_get_stdio_fdname, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
2013-12-22 02:24:05 +01:00
|
|
|
SD_BUS_PROPERTY("StandardError", "s", bus_property_get_exec_output, offsetof(ExecContext, std_error), SD_BUS_VTABLE_PROPERTY_CONST),
|
2017-10-27 14:57:12 +02:00
|
|
|
SD_BUS_PROPERTY("StandardErrorFileDescriptorName", "s", property_get_stdio_fdname, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
2013-12-22 02:24:05 +01:00
|
|
|
SD_BUS_PROPERTY("TTYPath", "s", NULL, offsetof(ExecContext, tty_path), SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("TTYReset", "b", bus_property_get_bool, offsetof(ExecContext, tty_reset), SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("TTYVHangup", "b", bus_property_get_bool, offsetof(ExecContext, tty_vhangup), SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("TTYVTDisallocate", "b", bus_property_get_bool, offsetof(ExecContext, tty_vt_disallocate), SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("SyslogPriority", "i", bus_property_get_int, offsetof(ExecContext, syslog_priority), SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("SyslogIdentifier", "s", NULL, offsetof(ExecContext, syslog_identifier), SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("SyslogLevelPrefix", "b", bus_property_get_bool, offsetof(ExecContext, syslog_level_prefix), SD_BUS_VTABLE_PROPERTY_CONST),
|
2015-10-11 06:57:17 +02:00
|
|
|
SD_BUS_PROPERTY("SyslogLevel", "i", property_get_syslog_level, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("SyslogFacility", "i", property_get_syslog_facility, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
core: implement /run/systemd/units/-based path for passing unit info from PID 1 to journald
And let's make use of it to implement two new unit settings with it:
1. LogLevelMax= is a new per-unit setting that may be used to configure
log priority filtering: set it to LogLevelMax=notice and only
messages of level "notice" and lower (i.e. more important) will be
processed, all others are dropped.
2. LogExtraFields= is a new per-unit setting for configuring per-unit
journal fields, that are implicitly included in every log record
generated by the unit's processes. It takes field/value pairs in the
form of FOO=BAR.
Also, related to this, one exisiting unit setting is ported to this new
facility:
3. The invocation ID is now pulled from /run/systemd/units/ instead of
cgroupfs xattrs. This substantially relaxes requirements of systemd
on the kernel version and the privileges it runs with (specifically,
cgroupfs xattrs are not available in containers, since they are
stored in kernel memory, and hence are unsafe to permit to lesser
privileged code).
/run/systemd/units/ is a new directory, which contains a number of files
and symlinks encoding the above information. PID 1 creates and manages
these files, and journald reads them from there.
Note that this is supposed to be a direct path between PID 1 and the
journal only, due to the special runtime environment the journal runs
in. Normally, today we shouldn't introduce new interfaces that (mis-)use
a file system as IPC framework, and instead just an IPC system, but this
is very hard to do between the journal and PID 1, as long as the IPC
system is a subject PID 1 manages, and itself a client to the journal.
This patch cleans up a couple of types used in journal code:
specifically we switch to size_t for a couple of memory-sizing values,
as size_t is the right choice for everything that is memory.
Fixes: #4089
Fixes: #3041
Fixes: #4441
2017-11-02 19:43:32 +01:00
|
|
|
SD_BUS_PROPERTY("LogLevelMax", "i", bus_property_get_int, offsetof(ExecContext, log_level_max), SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("LogExtraFields", "aay", property_get_log_extra_fields, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
2013-12-22 02:24:05 +01:00
|
|
|
SD_BUS_PROPERTY("SecureBits", "i", bus_property_get_int, offsetof(ExecContext, secure_bits), SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("CapabilityBoundingSet", "t", property_get_capability_bounding_set, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
2015-12-31 13:54:44 +01:00
|
|
|
SD_BUS_PROPERTY("AmbientCapabilities", "t", property_get_ambient_capabilities, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
2013-12-22 02:24:05 +01:00
|
|
|
SD_BUS_PROPERTY("User", "s", NULL, offsetof(ExecContext, user), SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("Group", "s", NULL, offsetof(ExecContext, group), SD_BUS_VTABLE_PROPERTY_CONST),
|
2016-07-14 12:37:28 +02:00
|
|
|
SD_BUS_PROPERTY("DynamicUser", "b", bus_property_get_bool, offsetof(ExecContext, dynamic_user), SD_BUS_VTABLE_PROPERTY_CONST),
|
2016-08-01 19:24:40 +02:00
|
|
|
SD_BUS_PROPERTY("RemoveIPC", "b", bus_property_get_bool, offsetof(ExecContext, remove_ipc), SD_BUS_VTABLE_PROPERTY_CONST),
|
2013-12-22 02:24:05 +01:00
|
|
|
SD_BUS_PROPERTY("SupplementaryGroups", "as", NULL, offsetof(ExecContext, supplementary_groups), SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("PAMName", "s", NULL, offsetof(ExecContext, pam_name), SD_BUS_VTABLE_PROPERTY_CONST),
|
2016-07-07 11:17:00 +02:00
|
|
|
SD_BUS_PROPERTY("ReadWritePaths", "as", NULL, offsetof(ExecContext, read_write_paths), SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("ReadOnlyPaths", "as", NULL, offsetof(ExecContext, read_only_paths), SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("InaccessiblePaths", "as", NULL, offsetof(ExecContext, inaccessible_paths), SD_BUS_VTABLE_PROPERTY_CONST),
|
2013-12-22 02:24:05 +01:00
|
|
|
SD_BUS_PROPERTY("MountFlags", "t", bus_property_get_ulong, offsetof(ExecContext, mount_flags), SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("PrivateTmp", "b", bus_property_get_bool, offsetof(ExecContext, private_tmp), SD_BUS_VTABLE_PROPERTY_CONST),
|
2014-01-20 19:54:51 +01:00
|
|
|
SD_BUS_PROPERTY("PrivateDevices", "b", bus_property_get_bool, offsetof(ExecContext, private_devices), SD_BUS_VTABLE_PROPERTY_CONST),
|
2016-08-22 18:43:59 +02:00
|
|
|
SD_BUS_PROPERTY("ProtectKernelTunables", "b", bus_property_get_bool, offsetof(ExecContext, protect_kernel_tunables), SD_BUS_VTABLE_PROPERTY_CONST),
|
2016-10-12 13:31:21 +02:00
|
|
|
SD_BUS_PROPERTY("ProtectKernelModules", "b", bus_property_get_bool, offsetof(ExecContext, protect_kernel_modules), SD_BUS_VTABLE_PROPERTY_CONST),
|
2016-08-22 18:43:59 +02:00
|
|
|
SD_BUS_PROPERTY("ProtectControlGroups", "b", bus_property_get_bool, offsetof(ExecContext, protect_control_groups), SD_BUS_VTABLE_PROPERTY_CONST),
|
2016-08-03 18:44:51 +02:00
|
|
|
SD_BUS_PROPERTY("PrivateNetwork", "b", bus_property_get_bool, offsetof(ExecContext, private_network), SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("PrivateUsers", "b", bus_property_get_bool, offsetof(ExecContext, private_users), SD_BUS_VTABLE_PROPERTY_CONST),
|
2014-06-04 18:07:55 +02:00
|
|
|
SD_BUS_PROPERTY("ProtectHome", "s", bus_property_get_protect_home, offsetof(ExecContext, protect_home), SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("ProtectSystem", "s", bus_property_get_protect_system, offsetof(ExecContext, protect_system), SD_BUS_VTABLE_PROPERTY_CONST),
|
2013-12-22 02:24:05 +01:00
|
|
|
SD_BUS_PROPERTY("SameProcessGroup", "b", bus_property_get_bool, offsetof(ExecContext, same_pgrp), SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("UtmpIdentifier", "s", NULL, offsetof(ExecContext, utmp_id), SD_BUS_VTABLE_PROPERTY_CONST),
|
2015-08-23 13:14:04 +02:00
|
|
|
SD_BUS_PROPERTY("UtmpMode", "s", property_get_exec_utmp_mode, offsetof(ExecContext, utmp_mode), SD_BUS_VTABLE_PROPERTY_CONST),
|
2014-02-17 16:52:52 +01:00
|
|
|
SD_BUS_PROPERTY("SELinuxContext", "(bs)", property_get_selinux_context, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
2014-02-20 16:19:44 +01:00
|
|
|
SD_BUS_PROPERTY("AppArmorProfile", "(bs)", property_get_apparmor_profile, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
2014-11-24 12:46:20 +01:00
|
|
|
SD_BUS_PROPERTY("SmackProcessLabel", "(bs)", property_get_smack_process_label, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
2013-12-22 02:24:05 +01:00
|
|
|
SD_BUS_PROPERTY("IgnoreSIGPIPE", "b", bus_property_get_bool, offsetof(ExecContext, ignore_sigpipe), SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("NoNewPrivileges", "b", bus_property_get_bool, offsetof(ExecContext, no_new_privileges), SD_BUS_VTABLE_PROPERTY_CONST),
|
2014-02-13 00:24:00 +01:00
|
|
|
SD_BUS_PROPERTY("SystemCallFilter", "(bas)", property_get_syscall_filter, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("SystemCallArchitectures", "as", property_get_syscall_archs, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
2014-02-12 18:28:21 +01:00
|
|
|
SD_BUS_PROPERTY("SystemCallErrorNumber", "i", property_get_syscall_errno, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
2014-02-19 02:15:24 +01:00
|
|
|
SD_BUS_PROPERTY("Personality", "s", property_get_personality, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
2017-07-04 14:48:18 +02:00
|
|
|
SD_BUS_PROPERTY("LockPersonality", "b", bus_property_get_bool, offsetof(ExecContext, lock_personality), SD_BUS_VTABLE_PROPERTY_CONST),
|
2014-02-25 20:37:03 +01:00
|
|
|
SD_BUS_PROPERTY("RestrictAddressFamilies", "(bas)", property_get_address_families, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
2017-07-17 09:22:25 +02:00
|
|
|
SD_BUS_PROPERTY("RuntimeDirectoryPreserve", "s", property_get_exec_preserve_mode, offsetof(ExecContext, runtime_directory_preserve_mode), SD_BUS_VTABLE_PROPERTY_CONST),
|
core: add {State,Cache,Log,Configuration}Directory= (#6384)
This introduces {State,Cache,Log,Configuration}Directory= those are
similar to RuntimeDirectory=. They create the directories under
/var/lib, /var/cache/, /var/log, or /etc, respectively, with the mode
specified in {State,Cache,Log,Configuration}DirectoryMode=.
This also fixes #6391.
2017-07-18 14:34:52 +02:00
|
|
|
SD_BUS_PROPERTY("RuntimeDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_RUNTIME].mode), SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("RuntimeDirectory", "as", NULL, offsetof(ExecContext, directories[EXEC_DIRECTORY_RUNTIME].paths), SD_BUS_VTABLE_PROPERTY_CONST),
|
2017-07-21 14:29:59 +02:00
|
|
|
SD_BUS_PROPERTY("StateDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_STATE].mode), SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("StateDirectory", "as", NULL, offsetof(ExecContext, directories[EXEC_DIRECTORY_STATE].paths), SD_BUS_VTABLE_PROPERTY_CONST),
|
core: add {State,Cache,Log,Configuration}Directory= (#6384)
This introduces {State,Cache,Log,Configuration}Directory= those are
similar to RuntimeDirectory=. They create the directories under
/var/lib, /var/cache/, /var/log, or /etc, respectively, with the mode
specified in {State,Cache,Log,Configuration}DirectoryMode=.
This also fixes #6391.
2017-07-18 14:34:52 +02:00
|
|
|
SD_BUS_PROPERTY("CacheDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_CACHE].mode), SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("CacheDirectory", "as", NULL, offsetof(ExecContext, directories[EXEC_DIRECTORY_CACHE].paths), SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("LogsDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_LOGS].mode), SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("LogsDirectory", "as", NULL, offsetof(ExecContext, directories[EXEC_DIRECTORY_LOGS].paths), SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("ConfigurationDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_CONFIGURATION].mode), SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("ConfigurationDirectory", "as", NULL, offsetof(ExecContext, directories[EXEC_DIRECTORY_CONFIGURATION].paths), SD_BUS_VTABLE_PROPERTY_CONST),
|
2016-06-03 17:58:18 +02:00
|
|
|
SD_BUS_PROPERTY("MemoryDenyWriteExecute", "b", bus_property_get_bool, offsetof(ExecContext, memory_deny_write_execute), SD_BUS_VTABLE_PROPERTY_CONST),
|
2016-06-23 01:45:45 +02:00
|
|
|
SD_BUS_PROPERTY("RestrictRealtime", "b", bus_property_get_bool, offsetof(ExecContext, restrict_realtime), SD_BUS_VTABLE_PROPERTY_CONST),
|
2016-11-14 08:24:41 +01:00
|
|
|
SD_BUS_PROPERTY("RestrictNamespaces", "t", bus_property_get_ulong, offsetof(ExecContext, restrict_namespaces), SD_BUS_VTABLE_PROPERTY_CONST),
|
2016-11-23 22:21:40 +01:00
|
|
|
SD_BUS_PROPERTY("BindPaths", "a(ssbt)", property_get_bind_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("BindReadOnlyPaths", "a(ssbt)", property_get_bind_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
2016-12-22 23:34:35 +01:00
|
|
|
SD_BUS_PROPERTY("MountAPIVFS", "b", bus_property_get_bool, offsetof(ExecContext, mount_apivfs), SD_BUS_VTABLE_PROPERTY_CONST),
|
2017-09-14 21:19:05 +02:00
|
|
|
SD_BUS_PROPERTY("KeyringMode", "s", property_get_exec_keyring_mode, offsetof(ExecContext, keyring_mode), SD_BUS_VTABLE_PROPERTY_CONST),
|
2017-06-26 17:40:08 +02:00
|
|
|
|
|
|
|
/* Obsolete/redundant properties: */
|
|
|
|
SD_BUS_PROPERTY("Capabilities", "s", property_get_empty_string, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
|
|
|
|
SD_BUS_PROPERTY("ReadWriteDirectories", "as", NULL, offsetof(ExecContext, read_write_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
|
|
|
|
SD_BUS_PROPERTY("ReadOnlyDirectories", "as", NULL, offsetof(ExecContext, read_only_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
|
|
|
|
SD_BUS_PROPERTY("InaccessibleDirectories", "as", NULL, offsetof(ExecContext, inaccessible_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
|
|
|
|
SD_BUS_PROPERTY("IOScheduling", "i", property_get_ioprio, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
|
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
SD_BUS_VTABLE_END
|
|
|
|
};
|
2010-07-04 16:44:58 +02:00
|
|
|
|
2013-11-25 16:59:51 +01:00
|
|
|
static int append_exec_command(sd_bus_message *reply, ExecCommand *c) {
|
|
|
|
int r;
|
|
|
|
|
|
|
|
assert(reply);
|
|
|
|
assert(c);
|
|
|
|
|
|
|
|
if (!c->path)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
r = sd_bus_message_open_container(reply, 'r', "sasbttttuii");
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
r = sd_bus_message_append(reply, "s", c->path);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
r = sd_bus_message_append_strv(reply, c->argv);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
r = sd_bus_message_append(reply, "bttttuii",
|
2017-08-01 10:16:42 +02:00
|
|
|
!!(c->flags & EXEC_COMMAND_IGNORE_FAILURE),
|
2013-11-25 16:59:51 +01:00
|
|
|
c->exec_status.start_timestamp.realtime,
|
|
|
|
c->exec_status.start_timestamp.monotonic,
|
|
|
|
c->exec_status.exit_timestamp.realtime,
|
|
|
|
c->exec_status.exit_timestamp.monotonic,
|
|
|
|
(uint32_t) c->exec_status.pid,
|
|
|
|
(int32_t) c->exec_status.code,
|
|
|
|
(int32_t) c->exec_status.status);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
return sd_bus_message_close_container(reply);
|
|
|
|
}
|
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
int bus_property_get_exec_command(
|
|
|
|
sd_bus *bus,
|
|
|
|
const char *path,
|
|
|
|
const char *interface,
|
|
|
|
const char *property,
|
|
|
|
sd_bus_message *reply,
|
2013-11-21 19:34:37 +01:00
|
|
|
void *userdata,
|
|
|
|
sd_bus_error *ret_error) {
|
2010-07-04 20:38:14 +02:00
|
|
|
|
2013-11-25 16:59:51 +01:00
|
|
|
ExecCommand *c = (ExecCommand*) userdata;
|
2013-11-19 21:12:59 +01:00
|
|
|
int r;
|
2010-07-04 20:38:14 +02:00
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
assert(bus);
|
|
|
|
assert(reply);
|
2010-07-04 20:38:14 +02:00
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
r = sd_bus_message_open_container(reply, 'a', "(sasbttttuii)");
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
2010-07-04 20:38:14 +02:00
|
|
|
|
2013-11-25 16:59:51 +01:00
|
|
|
r = append_exec_command(reply, c);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
2010-07-04 20:38:14 +02:00
|
|
|
|
2013-11-25 16:59:51 +01:00
|
|
|
return sd_bus_message_close_container(reply);
|
|
|
|
}
|
2013-11-19 21:12:59 +01:00
|
|
|
|
2013-11-25 16:59:51 +01:00
|
|
|
int bus_property_get_exec_command_list(
|
|
|
|
sd_bus *bus,
|
|
|
|
const char *path,
|
|
|
|
const char *interface,
|
|
|
|
const char *property,
|
|
|
|
sd_bus_message *reply,
|
|
|
|
void *userdata,
|
|
|
|
sd_bus_error *ret_error) {
|
2013-11-19 21:12:59 +01:00
|
|
|
|
2013-11-25 16:59:51 +01:00
|
|
|
ExecCommand *c = *(ExecCommand**) userdata;
|
|
|
|
int r;
|
2013-11-19 21:12:59 +01:00
|
|
|
|
2013-11-25 16:59:51 +01:00
|
|
|
assert(bus);
|
|
|
|
assert(reply);
|
|
|
|
|
|
|
|
r = sd_bus_message_open_container(reply, 'a', "(sasbttttuii)");
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
2013-11-19 21:12:59 +01:00
|
|
|
|
2013-11-25 16:59:51 +01:00
|
|
|
LIST_FOREACH(command, c, c) {
|
|
|
|
r = append_exec_command(reply, c);
|
2013-11-19 21:12:59 +01:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
2010-07-04 20:38:14 +02:00
|
|
|
}
|
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
return sd_bus_message_close_container(reply);
|
2012-07-17 04:17:53 +02:00
|
|
|
}
|
2014-02-05 02:02:00 +01:00
|
|
|
|
|
|
|
int bus_exec_context_set_transient_property(
|
|
|
|
Unit *u,
|
|
|
|
ExecContext *c,
|
|
|
|
const char *name,
|
|
|
|
sd_bus_message *message,
|
2017-11-22 15:03:51 +01:00
|
|
|
UnitWriteFlags flags,
|
2014-02-05 02:02:00 +01:00
|
|
|
sd_bus_error *error) {
|
|
|
|
|
2016-02-01 21:37:28 +01:00
|
|
|
const char *soft = NULL;
|
|
|
|
int r, ri;
|
2014-02-05 02:02:00 +01:00
|
|
|
|
|
|
|
assert(u);
|
|
|
|
assert(c);
|
|
|
|
assert(name);
|
|
|
|
assert(message);
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
flags |= UNIT_PRIVATE;
|
|
|
|
|
2014-02-05 02:02:00 +01:00
|
|
|
if (streq(name, "User")) {
|
|
|
|
const char *uu;
|
|
|
|
|
|
|
|
r = sd_bus_message_read(message, "s", &uu);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
2016-07-14 19:17:18 +02:00
|
|
|
if (!isempty(uu) && !valid_user_group_name_or_id(uu))
|
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid user name: %s", uu);
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2016-05-20 22:36:22 +02:00
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
r = free_and_strdup(&c->user, empty_to_null(uu));
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
2014-02-05 02:02:00 +01:00
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "User=%s", uu);
|
2014-02-05 02:02:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
} else if (streq(name, "Group")) {
|
|
|
|
const char *gg;
|
|
|
|
|
|
|
|
r = sd_bus_message_read(message, "s", &gg);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
2016-07-14 19:17:18 +02:00
|
|
|
if (!isempty(gg) && !valid_user_group_name_or_id(gg))
|
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid group name: %s", gg);
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2016-05-20 22:36:22 +02:00
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
r = free_and_strdup(&c->group, empty_to_null(gg));
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
2014-02-05 02:02:00 +01:00
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "Group=%s", gg);
|
2014-02-05 02:02:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
2017-08-07 17:37:02 +02:00
|
|
|
|
|
|
|
} else if (streq(name, "SupplementaryGroups")) {
|
|
|
|
_cleanup_strv_free_ char **l = NULL;
|
|
|
|
char **p;
|
|
|
|
|
|
|
|
r = sd_bus_message_read_strv(message, &l);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
STRV_FOREACH(p, l) {
|
|
|
|
if (!isempty(*p) && !valid_user_group_name_or_id(*p))
|
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid supplementary group names");
|
|
|
|
}
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2017-08-07 17:37:02 +02:00
|
|
|
if (strv_length(l) == 0) {
|
|
|
|
c->supplementary_groups = strv_free(c->supplementary_groups);
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags, name, "%s=", name);
|
2017-08-07 17:37:02 +02:00
|
|
|
} else {
|
|
|
|
_cleanup_free_ char *joined = NULL;
|
|
|
|
|
|
|
|
r = strv_extend_strv(&c->supplementary_groups, l, true);
|
|
|
|
if (r < 0)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
joined = strv_join(c->supplementary_groups, " ");
|
|
|
|
if (!joined)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, joined);
|
2017-08-07 17:37:02 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
2015-10-09 14:37:50 +02:00
|
|
|
} else if (streq(name, "SyslogIdentifier")) {
|
|
|
|
const char *id;
|
2014-02-05 02:02:00 +01:00
|
|
|
|
2015-10-09 14:37:50 +02:00
|
|
|
r = sd_bus_message_read(message, "s", &id);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2016-05-20 22:36:22 +02:00
|
|
|
|
|
|
|
if (isempty(id))
|
|
|
|
c->syslog_identifier = mfree(c->syslog_identifier);
|
|
|
|
else if (free_and_strdup(&c->syslog_identifier, id) < 0)
|
|
|
|
return -ENOMEM;
|
2015-10-09 14:37:50 +02:00
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "SyslogIdentifier=%s", id);
|
2015-10-09 14:37:50 +02:00
|
|
|
}
|
|
|
|
|
2015-10-11 05:37:50 +02:00
|
|
|
return 1;
|
|
|
|
} else if (streq(name, "SyslogLevel")) {
|
2017-06-26 17:41:54 +02:00
|
|
|
int32_t level;
|
2015-10-11 05:37:50 +02:00
|
|
|
|
|
|
|
r = sd_bus_message_read(message, "i", &level);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
2015-10-14 18:30:35 +02:00
|
|
|
if (!log_level_is_valid(level))
|
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Log level value out of range");
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2015-10-11 05:37:50 +02:00
|
|
|
c->syslog_priority = (c->syslog_priority & LOG_FACMASK) | level;
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags, name, "SyslogLevel=%i", level);
|
2015-10-11 05:37:50 +02:00
|
|
|
}
|
|
|
|
|
2015-10-11 05:55:41 +02:00
|
|
|
return 1;
|
|
|
|
} else if (streq(name, "SyslogFacility")) {
|
2017-06-26 17:41:54 +02:00
|
|
|
int32_t facility;
|
2015-10-11 05:55:41 +02:00
|
|
|
|
|
|
|
r = sd_bus_message_read(message, "i", &facility);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
2015-10-14 18:30:35 +02:00
|
|
|
if (!log_facility_unshifted_is_valid(facility))
|
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Log facility value out of range");
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2015-10-11 05:55:41 +02:00
|
|
|
c->syslog_priority = (facility << 3) | LOG_PRI(c->syslog_priority);
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags, name, "SyslogFacility=%i", facility);
|
2015-10-11 05:55:41 +02:00
|
|
|
}
|
|
|
|
|
2017-08-07 17:37:02 +02:00
|
|
|
return 1;
|
core: implement /run/systemd/units/-based path for passing unit info from PID 1 to journald
And let's make use of it to implement two new unit settings with it:
1. LogLevelMax= is a new per-unit setting that may be used to configure
log priority filtering: set it to LogLevelMax=notice and only
messages of level "notice" and lower (i.e. more important) will be
processed, all others are dropped.
2. LogExtraFields= is a new per-unit setting for configuring per-unit
journal fields, that are implicitly included in every log record
generated by the unit's processes. It takes field/value pairs in the
form of FOO=BAR.
Also, related to this, one exisiting unit setting is ported to this new
facility:
3. The invocation ID is now pulled from /run/systemd/units/ instead of
cgroupfs xattrs. This substantially relaxes requirements of systemd
on the kernel version and the privileges it runs with (specifically,
cgroupfs xattrs are not available in containers, since they are
stored in kernel memory, and hence are unsafe to permit to lesser
privileged code).
/run/systemd/units/ is a new directory, which contains a number of files
and symlinks encoding the above information. PID 1 creates and manages
these files, and journald reads them from there.
Note that this is supposed to be a direct path between PID 1 and the
journal only, due to the special runtime environment the journal runs
in. Normally, today we shouldn't introduce new interfaces that (mis-)use
a file system as IPC framework, and instead just an IPC system, but this
is very hard to do between the journal and PID 1, as long as the IPC
system is a subject PID 1 manages, and itself a client to the journal.
This patch cleans up a couple of types used in journal code:
specifically we switch to size_t for a couple of memory-sizing values,
as size_t is the right choice for everything that is memory.
Fixes: #4089
Fixes: #3041
Fixes: #4441
2017-11-02 19:43:32 +01:00
|
|
|
|
|
|
|
} else if (streq(name, "LogLevelMax")) {
|
|
|
|
int32_t level;
|
|
|
|
|
|
|
|
r = sd_bus_message_read(message, "i", &level);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
if (!log_level_is_valid(level))
|
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Maximum log level value out of range");
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
core: implement /run/systemd/units/-based path for passing unit info from PID 1 to journald
And let's make use of it to implement two new unit settings with it:
1. LogLevelMax= is a new per-unit setting that may be used to configure
log priority filtering: set it to LogLevelMax=notice and only
messages of level "notice" and lower (i.e. more important) will be
processed, all others are dropped.
2. LogExtraFields= is a new per-unit setting for configuring per-unit
journal fields, that are implicitly included in every log record
generated by the unit's processes. It takes field/value pairs in the
form of FOO=BAR.
Also, related to this, one exisiting unit setting is ported to this new
facility:
3. The invocation ID is now pulled from /run/systemd/units/ instead of
cgroupfs xattrs. This substantially relaxes requirements of systemd
on the kernel version and the privileges it runs with (specifically,
cgroupfs xattrs are not available in containers, since they are
stored in kernel memory, and hence are unsafe to permit to lesser
privileged code).
/run/systemd/units/ is a new directory, which contains a number of files
and symlinks encoding the above information. PID 1 creates and manages
these files, and journald reads them from there.
Note that this is supposed to be a direct path between PID 1 and the
journal only, due to the special runtime environment the journal runs
in. Normally, today we shouldn't introduce new interfaces that (mis-)use
a file system as IPC framework, and instead just an IPC system, but this
is very hard to do between the journal and PID 1, as long as the IPC
system is a subject PID 1 manages, and itself a client to the journal.
This patch cleans up a couple of types used in journal code:
specifically we switch to size_t for a couple of memory-sizing values,
as size_t is the right choice for everything that is memory.
Fixes: #4089
Fixes: #3041
Fixes: #4441
2017-11-02 19:43:32 +01:00
|
|
|
c->log_level_max = level;
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags, name, "LogLevelMax=%i", level);
|
core: implement /run/systemd/units/-based path for passing unit info from PID 1 to journald
And let's make use of it to implement two new unit settings with it:
1. LogLevelMax= is a new per-unit setting that may be used to configure
log priority filtering: set it to LogLevelMax=notice and only
messages of level "notice" and lower (i.e. more important) will be
processed, all others are dropped.
2. LogExtraFields= is a new per-unit setting for configuring per-unit
journal fields, that are implicitly included in every log record
generated by the unit's processes. It takes field/value pairs in the
form of FOO=BAR.
Also, related to this, one exisiting unit setting is ported to this new
facility:
3. The invocation ID is now pulled from /run/systemd/units/ instead of
cgroupfs xattrs. This substantially relaxes requirements of systemd
on the kernel version and the privileges it runs with (specifically,
cgroupfs xattrs are not available in containers, since they are
stored in kernel memory, and hence are unsafe to permit to lesser
privileged code).
/run/systemd/units/ is a new directory, which contains a number of files
and symlinks encoding the above information. PID 1 creates and manages
these files, and journald reads them from there.
Note that this is supposed to be a direct path between PID 1 and the
journal only, due to the special runtime environment the journal runs
in. Normally, today we shouldn't introduce new interfaces that (mis-)use
a file system as IPC framework, and instead just an IPC system, but this
is very hard to do between the journal and PID 1, as long as the IPC
system is a subject PID 1 manages, and itself a client to the journal.
This patch cleans up a couple of types used in journal code:
specifically we switch to size_t for a couple of memory-sizing values,
as size_t is the right choice for everything that is memory.
Fixes: #4089
Fixes: #3041
Fixes: #4441
2017-11-02 19:43:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
} else if (streq(name, "LogExtraFields")) {
|
|
|
|
size_t n = 0;
|
|
|
|
|
|
|
|
r = sd_bus_message_enter_container(message, 'a', "ay");
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
_cleanup_free_ void *copy = NULL;
|
|
|
|
struct iovec *t;
|
|
|
|
const char *eq;
|
|
|
|
const void *p;
|
|
|
|
size_t sz;
|
|
|
|
|
|
|
|
/* Note that we expect a byte array for each field, instead of a string. That's because on the
|
|
|
|
* lower-level journal fields can actually contain binary data and are not restricted to text,
|
|
|
|
* and we should not "lose precision" in our types on the way. That said, I am pretty sure
|
|
|
|
* actually encoding binary data as unit metadata is not a good idea. Hence we actually refuse
|
|
|
|
* any actual binary data, and only accept UTF-8. This allows us to eventually lift this
|
|
|
|
* limitation, should a good, valid usecase arise. */
|
|
|
|
|
|
|
|
r = sd_bus_message_read_array(message, 'y', &p, &sz);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
if (r == 0)
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (memchr(p, 0, sz))
|
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Journal field contains zero byte");
|
|
|
|
|
|
|
|
eq = memchr(p, '=', sz);
|
|
|
|
if (!eq)
|
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Journal field contains no '=' character");
|
|
|
|
if (!journal_field_valid(p, eq - (const char*) p, false))
|
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Journal field invalid");
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
core: implement /run/systemd/units/-based path for passing unit info from PID 1 to journald
And let's make use of it to implement two new unit settings with it:
1. LogLevelMax= is a new per-unit setting that may be used to configure
log priority filtering: set it to LogLevelMax=notice and only
messages of level "notice" and lower (i.e. more important) will be
processed, all others are dropped.
2. LogExtraFields= is a new per-unit setting for configuring per-unit
journal fields, that are implicitly included in every log record
generated by the unit's processes. It takes field/value pairs in the
form of FOO=BAR.
Also, related to this, one exisiting unit setting is ported to this new
facility:
3. The invocation ID is now pulled from /run/systemd/units/ instead of
cgroupfs xattrs. This substantially relaxes requirements of systemd
on the kernel version and the privileges it runs with (specifically,
cgroupfs xattrs are not available in containers, since they are
stored in kernel memory, and hence are unsafe to permit to lesser
privileged code).
/run/systemd/units/ is a new directory, which contains a number of files
and symlinks encoding the above information. PID 1 creates and manages
these files, and journald reads them from there.
Note that this is supposed to be a direct path between PID 1 and the
journal only, due to the special runtime environment the journal runs
in. Normally, today we shouldn't introduce new interfaces that (mis-)use
a file system as IPC framework, and instead just an IPC system, but this
is very hard to do between the journal and PID 1, as long as the IPC
system is a subject PID 1 manages, and itself a client to the journal.
This patch cleans up a couple of types used in journal code:
specifically we switch to size_t for a couple of memory-sizing values,
as size_t is the right choice for everything that is memory.
Fixes: #4089
Fixes: #3041
Fixes: #4441
2017-11-02 19:43:32 +01:00
|
|
|
t = realloc_multiply(c->log_extra_fields, sizeof(struct iovec), c->n_log_extra_fields+1);
|
|
|
|
if (!t)
|
|
|
|
return -ENOMEM;
|
|
|
|
c->log_extra_fields = t;
|
|
|
|
}
|
|
|
|
|
|
|
|
copy = malloc(sz + 1);
|
|
|
|
if (!copy)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
memcpy(copy, p, sz);
|
|
|
|
((uint8_t*) copy)[sz] = 0;
|
|
|
|
|
|
|
|
if (!utf8_is_valid(copy))
|
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Journal field is not valid UTF-8");
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
core: implement /run/systemd/units/-based path for passing unit info from PID 1 to journald
And let's make use of it to implement two new unit settings with it:
1. LogLevelMax= is a new per-unit setting that may be used to configure
log priority filtering: set it to LogLevelMax=notice and only
messages of level "notice" and lower (i.e. more important) will be
processed, all others are dropped.
2. LogExtraFields= is a new per-unit setting for configuring per-unit
journal fields, that are implicitly included in every log record
generated by the unit's processes. It takes field/value pairs in the
form of FOO=BAR.
Also, related to this, one exisiting unit setting is ported to this new
facility:
3. The invocation ID is now pulled from /run/systemd/units/ instead of
cgroupfs xattrs. This substantially relaxes requirements of systemd
on the kernel version and the privileges it runs with (specifically,
cgroupfs xattrs are not available in containers, since they are
stored in kernel memory, and hence are unsafe to permit to lesser
privileged code).
/run/systemd/units/ is a new directory, which contains a number of files
and symlinks encoding the above information. PID 1 creates and manages
these files, and journald reads them from there.
Note that this is supposed to be a direct path between PID 1 and the
journal only, due to the special runtime environment the journal runs
in. Normally, today we shouldn't introduce new interfaces that (mis-)use
a file system as IPC framework, and instead just an IPC system, but this
is very hard to do between the journal and PID 1, as long as the IPC
system is a subject PID 1 manages, and itself a client to the journal.
This patch cleans up a couple of types used in journal code:
specifically we switch to size_t for a couple of memory-sizing values,
as size_t is the right choice for everything that is memory.
Fixes: #4089
Fixes: #3041
Fixes: #4441
2017-11-02 19:43:32 +01:00
|
|
|
c->log_extra_fields[c->n_log_extra_fields++] = IOVEC_MAKE(copy, sz);
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS|UNIT_ESCAPE_C, name, "LogExtraFields=%s", (char*) copy);
|
core: implement /run/systemd/units/-based path for passing unit info from PID 1 to journald
And let's make use of it to implement two new unit settings with it:
1. LogLevelMax= is a new per-unit setting that may be used to configure
log priority filtering: set it to LogLevelMax=notice and only
messages of level "notice" and lower (i.e. more important) will be
processed, all others are dropped.
2. LogExtraFields= is a new per-unit setting for configuring per-unit
journal fields, that are implicitly included in every log record
generated by the unit's processes. It takes field/value pairs in the
form of FOO=BAR.
Also, related to this, one exisiting unit setting is ported to this new
facility:
3. The invocation ID is now pulled from /run/systemd/units/ instead of
cgroupfs xattrs. This substantially relaxes requirements of systemd
on the kernel version and the privileges it runs with (specifically,
cgroupfs xattrs are not available in containers, since they are
stored in kernel memory, and hence are unsafe to permit to lesser
privileged code).
/run/systemd/units/ is a new directory, which contains a number of files
and symlinks encoding the above information. PID 1 creates and manages
these files, and journald reads them from there.
Note that this is supposed to be a direct path between PID 1 and the
journal only, due to the special runtime environment the journal runs
in. Normally, today we shouldn't introduce new interfaces that (mis-)use
a file system as IPC framework, and instead just an IPC system, but this
is very hard to do between the journal and PID 1, as long as the IPC
system is a subject PID 1 manages, and itself a client to the journal.
This patch cleans up a couple of types used in journal code:
specifically we switch to size_t for a couple of memory-sizing values,
as size_t is the right choice for everything that is memory.
Fixes: #4089
Fixes: #3041
Fixes: #4441
2017-11-02 19:43:32 +01:00
|
|
|
|
|
|
|
copy = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
n++;
|
|
|
|
}
|
|
|
|
|
|
|
|
r = sd_bus_message_exit_container(message);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags) && n == 0) {
|
core: implement /run/systemd/units/-based path for passing unit info from PID 1 to journald
And let's make use of it to implement two new unit settings with it:
1. LogLevelMax= is a new per-unit setting that may be used to configure
log priority filtering: set it to LogLevelMax=notice and only
messages of level "notice" and lower (i.e. more important) will be
processed, all others are dropped.
2. LogExtraFields= is a new per-unit setting for configuring per-unit
journal fields, that are implicitly included in every log record
generated by the unit's processes. It takes field/value pairs in the
form of FOO=BAR.
Also, related to this, one exisiting unit setting is ported to this new
facility:
3. The invocation ID is now pulled from /run/systemd/units/ instead of
cgroupfs xattrs. This substantially relaxes requirements of systemd
on the kernel version and the privileges it runs with (specifically,
cgroupfs xattrs are not available in containers, since they are
stored in kernel memory, and hence are unsafe to permit to lesser
privileged code).
/run/systemd/units/ is a new directory, which contains a number of files
and symlinks encoding the above information. PID 1 creates and manages
these files, and journald reads them from there.
Note that this is supposed to be a direct path between PID 1 and the
journal only, due to the special runtime environment the journal runs
in. Normally, today we shouldn't introduce new interfaces that (mis-)use
a file system as IPC framework, and instead just an IPC system, but this
is very hard to do between the journal and PID 1, as long as the IPC
system is a subject PID 1 manages, and itself a client to the journal.
This patch cleans up a couple of types used in journal code:
specifically we switch to size_t for a couple of memory-sizing values,
as size_t is the right choice for everything that is memory.
Fixes: #4089
Fixes: #3041
Fixes: #4441
2017-11-02 19:43:32 +01:00
|
|
|
exec_context_free_log_extra_fields(c);
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_setting(u, flags, name, "LogExtraFields=");
|
core: implement /run/systemd/units/-based path for passing unit info from PID 1 to journald
And let's make use of it to implement two new unit settings with it:
1. LogLevelMax= is a new per-unit setting that may be used to configure
log priority filtering: set it to LogLevelMax=notice and only
messages of level "notice" and lower (i.e. more important) will be
processed, all others are dropped.
2. LogExtraFields= is a new per-unit setting for configuring per-unit
journal fields, that are implicitly included in every log record
generated by the unit's processes. It takes field/value pairs in the
form of FOO=BAR.
Also, related to this, one exisiting unit setting is ported to this new
facility:
3. The invocation ID is now pulled from /run/systemd/units/ instead of
cgroupfs xattrs. This substantially relaxes requirements of systemd
on the kernel version and the privileges it runs with (specifically,
cgroupfs xattrs are not available in containers, since they are
stored in kernel memory, and hence are unsafe to permit to lesser
privileged code).
/run/systemd/units/ is a new directory, which contains a number of files
and symlinks encoding the above information. PID 1 creates and manages
these files, and journald reads them from there.
Note that this is supposed to be a direct path between PID 1 and the
journal only, due to the special runtime environment the journal runs
in. Normally, today we shouldn't introduce new interfaces that (mis-)use
a file system as IPC framework, and instead just an IPC system, but this
is very hard to do between the journal and PID 1, as long as the IPC
system is a subject PID 1 manages, and itself a client to the journal.
This patch cleans up a couple of types used in journal code:
specifically we switch to size_t for a couple of memory-sizing values,
as size_t is the right choice for everything that is memory.
Fixes: #4089
Fixes: #3041
Fixes: #4441
2017-11-02 19:43:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
2017-08-07 17:37:02 +02:00
|
|
|
} else if (streq(name, "SecureBits")) {
|
|
|
|
int n;
|
|
|
|
|
|
|
|
r = sd_bus_message_read(message, "i", &n);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
if (!secure_bits_is_valid(n))
|
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid secure bits");
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2017-08-07 17:37:02 +02:00
|
|
|
_cleanup_free_ char *str = NULL;
|
|
|
|
|
|
|
|
c->secure_bits = n;
|
|
|
|
r = secure_bits_to_string_alloc(n, &str);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags, name, "SecureBits=%s", str);
|
2017-08-07 17:37:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
} else if (STR_IN_SET(name, "CapabilityBoundingSet", "AmbientCapabilities")) {
|
|
|
|
uint64_t n;
|
|
|
|
|
|
|
|
r = sd_bus_message_read(message, "t", &n);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2017-08-07 17:37:02 +02:00
|
|
|
_cleanup_free_ char *str = NULL;
|
|
|
|
|
|
|
|
if (streq(name, "CapabilityBoundingSet"))
|
|
|
|
c->capability_bounding_set = n;
|
|
|
|
else /* "AmbientCapabilities" */
|
|
|
|
c->capability_ambient_set = n;
|
|
|
|
|
|
|
|
r = capability_set_to_string_alloc(n, &str);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags, name, "%s=%s", name, str);
|
2017-08-07 17:37:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
} else if (streq(name, "Personality")) {
|
|
|
|
const char *s;
|
|
|
|
unsigned long p;
|
|
|
|
|
|
|
|
r = sd_bus_message_read(message, "s", &s);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
p = personality_from_string(s);
|
|
|
|
if (p == PERSONALITY_INVALID)
|
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid personality");
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2017-08-07 17:37:02 +02:00
|
|
|
c->personality = p;
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags, name, "%s=%s", name, s);
|
2017-08-07 17:37:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
2017-10-03 10:41:51 +02:00
|
|
|
#if HAVE_SECCOMP
|
2017-08-07 17:37:02 +02:00
|
|
|
|
|
|
|
} else if (streq(name, "SystemCallFilter")) {
|
|
|
|
int whitelist;
|
2017-10-19 15:40:04 +02:00
|
|
|
_cleanup_strv_free_ char **l = NULL;
|
2017-08-07 17:37:02 +02:00
|
|
|
|
|
|
|
r = sd_bus_message_enter_container(message, 'r', "bas");
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
r = sd_bus_message_read(message, "b", &whitelist);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
r = sd_bus_message_read_strv(message, &l);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
r = sd_bus_message_exit_container(message);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2017-08-07 17:37:02 +02:00
|
|
|
_cleanup_free_ char *joined = NULL;
|
|
|
|
|
|
|
|
if (strv_length(l) == 0) {
|
|
|
|
c->syscall_whitelist = false;
|
2017-11-11 13:35:49 +01:00
|
|
|
c->syscall_filter = hashmap_free(c->syscall_filter);
|
2017-08-07 17:37:02 +02:00
|
|
|
} else {
|
|
|
|
char **s;
|
|
|
|
|
|
|
|
c->syscall_whitelist = whitelist;
|
|
|
|
|
2017-11-11 13:35:49 +01:00
|
|
|
r = hashmap_ensure_allocated(&c->syscall_filter, NULL);
|
2017-08-07 17:37:02 +02:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
STRV_FOREACH(s, l) {
|
2017-11-11 13:35:49 +01:00
|
|
|
_cleanup_free_ char *n = NULL;
|
|
|
|
int e;
|
|
|
|
|
|
|
|
r = parse_syscall_and_errno(*s, &n, &e);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
if (*n == '@') {
|
2017-08-07 17:37:02 +02:00
|
|
|
const SyscallFilterSet *set;
|
|
|
|
const char *i;
|
|
|
|
|
2017-11-11 13:35:49 +01:00
|
|
|
set = syscall_filter_set_find(n);
|
2017-08-07 17:37:02 +02:00
|
|
|
if (!set)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
NULSTR_FOREACH(i, set->value) {
|
|
|
|
int id;
|
|
|
|
|
|
|
|
id = seccomp_syscall_resolve_name(i);
|
|
|
|
if (id == __NR_SCMP_ERROR)
|
|
|
|
return -EINVAL;
|
|
|
|
|
2017-11-11 13:35:49 +01:00
|
|
|
r = hashmap_put(c->syscall_filter, INT_TO_PTR(id + 1), INT_TO_PTR(e));
|
2017-08-07 17:37:02 +02:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
int id;
|
|
|
|
|
2017-11-11 13:35:49 +01:00
|
|
|
id = seccomp_syscall_resolve_name(n);
|
2017-08-07 17:37:02 +02:00
|
|
|
if (id == __NR_SCMP_ERROR)
|
|
|
|
return -EINVAL;
|
|
|
|
|
2017-11-11 13:35:49 +01:00
|
|
|
r = hashmap_put(c->syscall_filter, INT_TO_PTR(id + 1), INT_TO_PTR(e));
|
2017-08-07 17:37:02 +02:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
joined = strv_join(l, " ");
|
|
|
|
if (!joined)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags, name, "SystemCallFilter=%s%s", whitelist ? "" : "~", joined);
|
2017-08-07 17:37:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
} else if (streq(name, "SystemCallArchitectures")) {
|
|
|
|
_cleanup_strv_free_ char **l = NULL;
|
|
|
|
|
|
|
|
r = sd_bus_message_read_strv(message, &l);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2017-08-07 17:37:02 +02:00
|
|
|
_cleanup_free_ char *joined = NULL;
|
|
|
|
|
|
|
|
if (strv_length(l) == 0)
|
|
|
|
c->syscall_archs = set_free(c->syscall_archs);
|
|
|
|
else {
|
|
|
|
char **s;
|
|
|
|
|
|
|
|
r = set_ensure_allocated(&c->syscall_archs, NULL);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
STRV_FOREACH(s, l) {
|
|
|
|
uint32_t a;
|
|
|
|
|
|
|
|
r = seccomp_arch_from_string(*s, &a);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
r = set_put(c->syscall_archs, UINT32_TO_PTR(a + 1));
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
joined = strv_join(l, " ");
|
|
|
|
if (!joined)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags, name, "%s=%s", name, joined);
|
2017-08-07 17:37:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
} else if (streq(name, "SystemCallErrorNumber")) {
|
|
|
|
int32_t n;
|
|
|
|
|
|
|
|
r = sd_bus_message_read(message, "i", &n);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
2017-11-11 13:40:20 +01:00
|
|
|
if (n <= 0 || n > ERRNO_MAX)
|
2017-08-07 17:37:02 +02:00
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid SystemCallErrorNumber");
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2017-08-07 17:37:02 +02:00
|
|
|
c->syscall_errno = n;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags, name, "SystemCallErrorNumber=%d", n);
|
2017-08-07 17:37:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
} else if (streq(name, "RestrictAddressFamilies")) {
|
|
|
|
int whitelist;
|
2017-10-19 15:40:04 +02:00
|
|
|
_cleanup_strv_free_ char **l = NULL;
|
2017-08-07 17:37:02 +02:00
|
|
|
|
|
|
|
r = sd_bus_message_enter_container(message, 'r', "bas");
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
r = sd_bus_message_read(message, "b", &whitelist);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
r = sd_bus_message_read_strv(message, &l);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
r = sd_bus_message_exit_container(message);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2017-08-07 17:37:02 +02:00
|
|
|
_cleanup_free_ char *joined = NULL;
|
|
|
|
|
|
|
|
if (strv_length(l) == 0) {
|
|
|
|
c->address_families_whitelist = false;
|
|
|
|
c->address_families = set_free(c->address_families);
|
|
|
|
} else {
|
|
|
|
char **s;
|
|
|
|
|
|
|
|
c->address_families_whitelist = whitelist;
|
|
|
|
|
|
|
|
r = set_ensure_allocated(&c->address_families, NULL);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
STRV_FOREACH(s, l) {
|
|
|
|
int af;
|
|
|
|
|
|
|
|
af = af_from_name(*s);
|
|
|
|
if (af <= 0)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
r = set_put(c->address_families, INT_TO_PTR(af));
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
joined = strv_join(l, " ");
|
|
|
|
if (!joined)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags, name, "RestrictAddressFamilies=%s%s", whitelist ? "" : "~", joined);
|
2017-08-07 17:37:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
} else if (streq(name, "CPUSchedulingPolicy")) {
|
|
|
|
int32_t n;
|
|
|
|
|
|
|
|
r = sd_bus_message_read(message, "i", &n);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
if (!sched_policy_is_valid(n))
|
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid CPU scheduling policy");
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2017-08-07 17:37:02 +02:00
|
|
|
_cleanup_free_ char *str = NULL;
|
|
|
|
|
|
|
|
c->cpu_sched_policy = n;
|
|
|
|
r = sched_policy_to_string_alloc(n, &str);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags, name, "CPUSchedulingPolicy=%s", str);
|
2017-08-07 17:37:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
} else if (streq(name, "CPUSchedulingPriority")) {
|
|
|
|
int32_t n;
|
|
|
|
|
|
|
|
r = sd_bus_message_read(message, "i", &n);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
if (!ioprio_priority_is_valid(n))
|
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid CPU scheduling priority");
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2017-08-07 17:37:02 +02:00
|
|
|
c->cpu_sched_priority = n;
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags, name, "CPUSchedulingPriority=%i", n);
|
2017-08-07 17:37:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
} else if (streq(name, "CPUAffinity")) {
|
|
|
|
const void *a;
|
|
|
|
size_t n = 0;
|
|
|
|
|
|
|
|
r = sd_bus_message_read_array(message, 'y', &a, &n);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2017-08-07 17:37:02 +02:00
|
|
|
if (n == 0) {
|
|
|
|
c->cpuset = mfree(c->cpuset);
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags, name, "%s=", name);
|
2017-08-07 17:37:02 +02:00
|
|
|
} else {
|
|
|
|
_cleanup_free_ char *str = NULL;
|
|
|
|
uint8_t *l;
|
|
|
|
size_t allocated = 0, len = 0, i;
|
|
|
|
|
|
|
|
c->cpuset = (cpu_set_t*) memdup(a, sizeof(cpu_set_t) * n);
|
|
|
|
if (c->cpuset)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
l = (uint8_t*) a;
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
_cleanup_free_ char *p = NULL;
|
|
|
|
size_t add;
|
|
|
|
|
|
|
|
r = asprintf(&p, "%hhi", l[i]);
|
|
|
|
if (r < 0)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
add = strlen(p);
|
|
|
|
|
|
|
|
if (GREEDY_REALLOC(str, allocated, len + add + 2))
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
strcpy(mempcpy(str + len, p, add), " ");
|
|
|
|
len += add + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (len != 0)
|
|
|
|
str[len - 1] = '\0';
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags, name, "%s=%s", name, str);
|
2017-08-07 17:37:02 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-09 14:37:50 +02:00
|
|
|
return 1;
|
2014-02-05 02:02:00 +01:00
|
|
|
} else if (streq(name, "Nice")) {
|
2017-06-26 17:41:54 +02:00
|
|
|
int32_t n;
|
2014-02-05 02:02:00 +01:00
|
|
|
|
|
|
|
r = sd_bus_message_read(message, "i", &n);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
2016-08-05 11:17:08 +02:00
|
|
|
if (!nice_is_valid(n))
|
2014-02-05 02:02:00 +01:00
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Nice value out of range");
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2014-02-05 02:02:00 +01:00
|
|
|
c->nice = n;
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags, name, "Nice=%i", n);
|
2014-02-05 02:02:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
2017-06-26 17:40:08 +02:00
|
|
|
} else if (streq(name, "IOSchedulingClass")) {
|
|
|
|
int32_t q;
|
|
|
|
|
|
|
|
r = sd_bus_message_read(message, "i", &q);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
if (!ioprio_class_is_valid(q))
|
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid IO scheduling class: %i", q);
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2017-06-26 17:40:08 +02:00
|
|
|
_cleanup_free_ char *s = NULL;
|
|
|
|
|
|
|
|
r = ioprio_class_to_string_alloc(q, &s);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
c->ioprio = IOPRIO_PRIO_VALUE(q, IOPRIO_PRIO_DATA(c->ioprio));
|
|
|
|
c->ioprio_set = true;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags, name, "IOSchedulingClass=%s", s);
|
2017-06-26 17:40:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
} else if (streq(name, "IOSchedulingPriority")) {
|
|
|
|
int32_t p;
|
|
|
|
|
|
|
|
r = sd_bus_message_read(message, "i", &p);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
if (!ioprio_priority_is_valid(p))
|
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid IO scheduling priority: %i", p);
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2017-06-26 17:40:08 +02:00
|
|
|
c->ioprio = IOPRIO_PRIO_VALUE(IOPRIO_PRIO_CLASS(c->ioprio), p);
|
|
|
|
c->ioprio_set = true;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags, name, "IOSchedulingPriority=%i", p);
|
2017-06-26 17:40:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
2016-12-23 14:26:05 +01:00
|
|
|
} else if (STR_IN_SET(name, "TTYPath", "RootDirectory", "RootImage")) {
|
2015-09-23 09:45:50 +02:00
|
|
|
const char *s;
|
2014-12-22 19:45:32 +01:00
|
|
|
|
2015-09-23 09:45:50 +02:00
|
|
|
r = sd_bus_message_read(message, "s", &s);
|
2014-12-22 19:45:32 +01:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
2015-09-23 09:45:50 +02:00
|
|
|
if (!path_is_absolute(s))
|
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s takes an absolute path", name);
|
2014-12-22 19:45:32 +01:00
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2015-09-23 19:46:23 +02:00
|
|
|
if (streq(name, "TTYPath"))
|
|
|
|
r = free_and_strdup(&c->tty_path, s);
|
2016-12-23 14:26:05 +01:00
|
|
|
else if (streq(name, "RootImage"))
|
|
|
|
r = free_and_strdup(&c->root_image, s);
|
2015-09-23 19:46:23 +02:00
|
|
|
else {
|
|
|
|
assert(streq(name, "RootDirectory"));
|
|
|
|
r = free_and_strdup(&c->root_directory, s);
|
2015-09-23 09:45:50 +02:00
|
|
|
}
|
2015-09-23 19:46:23 +02:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
2014-12-22 19:45:32 +01:00
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, s);
|
2014-12-22 19:45:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
2015-09-23 19:46:23 +02:00
|
|
|
} else if (streq(name, "WorkingDirectory")) {
|
|
|
|
const char *s;
|
|
|
|
bool missing_ok;
|
|
|
|
|
|
|
|
r = sd_bus_message_read(message, "s", &s);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
if (s[0] == '-') {
|
|
|
|
missing_ok = true;
|
|
|
|
s++;
|
|
|
|
} else
|
|
|
|
missing_ok = false;
|
|
|
|
|
|
|
|
if (!streq(s, "~") && !path_is_absolute(s))
|
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "WorkingDirectory= expects an absolute path or '~'");
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2015-09-23 19:46:23 +02:00
|
|
|
if (streq(s, "~")) {
|
|
|
|
c->working_directory = mfree(c->working_directory);
|
|
|
|
c->working_directory_home = true;
|
|
|
|
} else {
|
|
|
|
r = free_and_strdup(&c->working_directory, s);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
c->working_directory_home = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
c->working_directory_missing_ok = missing_ok;
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "WorkingDirectory=%s%s", missing_ok ? "-" : "", s);
|
2015-09-23 19:46:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
2014-12-22 19:45:32 +01:00
|
|
|
} else if (streq(name, "StandardInput")) {
|
|
|
|
const char *s;
|
|
|
|
ExecInput p;
|
|
|
|
|
|
|
|
r = sd_bus_message_read(message, "s", &s);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
p = exec_input_from_string(s);
|
|
|
|
if (p < 0)
|
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid standard input name");
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2014-12-22 19:45:32 +01:00
|
|
|
c->std_input = p;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags, name, "StandardInput=%s", exec_input_to_string(p));
|
2014-12-22 19:45:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
} else if (streq(name, "StandardOutput")) {
|
|
|
|
const char *s;
|
|
|
|
ExecOutput p;
|
|
|
|
|
|
|
|
r = sd_bus_message_read(message, "s", &s);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
p = exec_output_from_string(s);
|
|
|
|
if (p < 0)
|
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid standard output name");
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2014-12-22 19:45:32 +01:00
|
|
|
c->std_output = p;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags, name, "StandardOutput=%s", exec_output_to_string(p));
|
2014-12-22 19:45:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
} else if (streq(name, "StandardError")) {
|
|
|
|
const char *s;
|
|
|
|
ExecOutput p;
|
|
|
|
|
|
|
|
r = sd_bus_message_read(message, "s", &s);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
p = exec_output_from_string(s);
|
|
|
|
if (p < 0)
|
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid standard error name");
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2014-12-22 19:45:32 +01:00
|
|
|
c->std_error = p;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags, name, "StandardError=%s", exec_output_to_string(p));
|
2014-12-22 19:45:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
2016-10-18 02:05:49 +02:00
|
|
|
} else if (STR_IN_SET(name,
|
|
|
|
"StandardInputFileDescriptorName", "StandardOutputFileDescriptorName", "StandardErrorFileDescriptorName")) {
|
|
|
|
const char *s;
|
|
|
|
|
|
|
|
r = sd_bus_message_read(message, "s", &s);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
2017-10-27 16:08:11 +02:00
|
|
|
if (isempty(s))
|
|
|
|
s = NULL;
|
|
|
|
else if (!fdname_is_valid(s))
|
2016-10-18 02:05:49 +02:00
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid file descriptor name");
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2017-10-27 14:57:12 +02:00
|
|
|
|
2016-10-18 02:05:49 +02:00
|
|
|
if (streq(name, "StandardInputFileDescriptorName")) {
|
2017-10-27 16:08:11 +02:00
|
|
|
r = free_and_strdup(c->stdio_fdname + STDIN_FILENO, s);
|
2016-10-18 02:05:49 +02:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
2017-10-27 14:57:12 +02:00
|
|
|
|
2017-10-27 16:08:11 +02:00
|
|
|
c->std_input = EXEC_INPUT_NAMED_FD;
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardInput=fd:%s", exec_context_fdname(c, STDIN_FILENO));
|
2017-10-27 14:57:12 +02:00
|
|
|
|
2016-10-18 02:05:49 +02:00
|
|
|
} else if (streq(name, "StandardOutputFileDescriptorName")) {
|
2017-10-27 16:08:11 +02:00
|
|
|
r = free_and_strdup(c->stdio_fdname + STDOUT_FILENO, s);
|
2016-10-18 02:05:49 +02:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
2017-10-27 14:57:12 +02:00
|
|
|
|
2016-10-18 02:05:49 +02:00
|
|
|
c->std_output = EXEC_OUTPUT_NAMED_FD;
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardOutput=fd:%s", exec_context_fdname(c, STDOUT_FILENO));
|
2017-10-27 16:08:11 +02:00
|
|
|
|
|
|
|
} else {
|
|
|
|
assert(streq(name, "StandardErrorFileDescriptorName"));
|
2017-10-27 14:57:12 +02:00
|
|
|
|
2016-10-18 02:05:49 +02:00
|
|
|
r = free_and_strdup(&c->stdio_fdname[STDERR_FILENO], s);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
2017-10-27 14:57:12 +02:00
|
|
|
|
2016-10-18 02:05:49 +02:00
|
|
|
c->std_error = EXEC_OUTPUT_NAMED_FD;
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardError=fd:%s", exec_context_fdname(c, STDERR_FILENO));
|
2016-10-18 02:05:49 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
2017-10-27 16:09:57 +02:00
|
|
|
} else if (STR_IN_SET(name, "StandardInputFile", "StandardOutputFile", "StandardErrorFile")) {
|
|
|
|
const char *s;
|
|
|
|
|
|
|
|
r = sd_bus_message_read(message, "s", &s);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
if (!path_is_absolute(s))
|
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not absolute", s);
|
2017-10-27 16:28:15 +02:00
|
|
|
if (!path_is_normalized(s))
|
2017-10-27 16:09:57 +02:00
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not normalized", s);
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2017-10-27 16:09:57 +02:00
|
|
|
|
|
|
|
if (streq(name, "StandardInputFile")) {
|
|
|
|
r = free_and_strdup(&c->stdio_file[STDIN_FILENO], s);
|
2016-10-18 02:05:49 +02:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
2017-10-27 16:09:57 +02:00
|
|
|
|
|
|
|
c->std_input = EXEC_INPUT_FILE;
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardInput=file:%s", s);
|
2017-10-27 16:09:57 +02:00
|
|
|
|
|
|
|
} else if (streq(name, "StandardOutputFile")) {
|
|
|
|
r = free_and_strdup(&c->stdio_file[STDOUT_FILENO], s);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
c->std_output = EXEC_OUTPUT_FILE;
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardOutput=file:%s", s);
|
2017-10-27 16:09:57 +02:00
|
|
|
|
|
|
|
} else {
|
|
|
|
assert(streq(name, "StandardErrorFile"));
|
|
|
|
|
|
|
|
r = free_and_strdup(&c->stdio_file[STDERR_FILENO], s);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
c->std_error = EXEC_OUTPUT_FILE;
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardError=file:%s", s);
|
2017-10-27 16:09:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
2017-10-27 11:33:05 +02:00
|
|
|
} else if (streq(name, "StandardInputData")) {
|
|
|
|
const void *p;
|
|
|
|
size_t sz;
|
|
|
|
|
|
|
|
r = sd_bus_message_read_array(message, 'y', &p, &sz);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2017-10-27 11:33:05 +02:00
|
|
|
_cleanup_free_ char *encoded = NULL;
|
|
|
|
|
|
|
|
if (sz == 0) {
|
|
|
|
c->stdin_data = mfree(c->stdin_data);
|
|
|
|
c->stdin_data_size = 0;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags, name, "StandardInputData=");
|
2017-10-27 11:33:05 +02:00
|
|
|
} else {
|
|
|
|
void *q;
|
|
|
|
ssize_t n;
|
|
|
|
|
|
|
|
if (c->stdin_data_size + sz < c->stdin_data_size || /* check for overflow */
|
|
|
|
c->stdin_data_size + sz > EXEC_STDIN_DATA_MAX)
|
|
|
|
return -E2BIG;
|
|
|
|
|
|
|
|
n = base64mem(p, sz, &encoded);
|
|
|
|
if (n < 0)
|
|
|
|
return (int) n;
|
|
|
|
|
|
|
|
q = realloc(c->stdin_data, c->stdin_data_size + sz);
|
|
|
|
if (!q)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
memcpy((uint8_t*) q + c->stdin_data_size, p, sz);
|
|
|
|
|
|
|
|
c->stdin_data = q;
|
|
|
|
c->stdin_data_size += sz;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags, name, "StandardInputData=%s", encoded);
|
2016-10-18 02:05:49 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
2015-09-10 16:45:28 +02:00
|
|
|
} else if (STR_IN_SET(name,
|
2017-08-07 17:37:02 +02:00
|
|
|
"IgnoreSIGPIPE", "TTYVHangup", "TTYReset", "TTYVTDisallocate",
|
2016-08-03 18:44:51 +02:00
|
|
|
"PrivateTmp", "PrivateDevices", "PrivateNetwork", "PrivateUsers",
|
2016-07-14 12:37:28 +02:00
|
|
|
"NoNewPrivileges", "SyslogLevelPrefix", "MemoryDenyWriteExecute",
|
2016-08-22 18:43:59 +02:00
|
|
|
"RestrictRealtime", "DynamicUser", "RemoveIPC", "ProtectKernelTunables",
|
2017-08-07 17:37:02 +02:00
|
|
|
"ProtectKernelModules", "ProtectControlGroups", "MountAPIVFS",
|
2017-08-09 20:52:54 +02:00
|
|
|
"CPUSchedulingResetOnFork", "NonBlocking", "LockPersonality")) {
|
2015-08-23 13:19:21 +02:00
|
|
|
int b;
|
|
|
|
|
|
|
|
r = sd_bus_message_read(message, "b", &b);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2015-09-10 16:45:28 +02:00
|
|
|
if (streq(name, "IgnoreSIGPIPE"))
|
|
|
|
c->ignore_sigpipe = b;
|
|
|
|
else if (streq(name, "TTYVHangup"))
|
|
|
|
c->tty_vhangup = b;
|
|
|
|
else if (streq(name, "TTYReset"))
|
|
|
|
c->tty_reset = b;
|
2017-08-07 17:37:02 +02:00
|
|
|
else if (streq(name, "TTYVTDisallocate"))
|
|
|
|
c->tty_vt_disallocate = b;
|
2015-09-10 16:45:28 +02:00
|
|
|
else if (streq(name, "PrivateTmp"))
|
|
|
|
c->private_tmp = b;
|
|
|
|
else if (streq(name, "PrivateDevices"))
|
|
|
|
c->private_devices = b;
|
|
|
|
else if (streq(name, "PrivateNetwork"))
|
|
|
|
c->private_network = b;
|
2016-08-03 18:44:51 +02:00
|
|
|
else if (streq(name, "PrivateUsers"))
|
|
|
|
c->private_users = b;
|
2015-09-10 16:45:28 +02:00
|
|
|
else if (streq(name, "NoNewPrivileges"))
|
|
|
|
c->no_new_privileges = b;
|
2015-10-09 14:17:41 +02:00
|
|
|
else if (streq(name, "SyslogLevelPrefix"))
|
|
|
|
c->syslog_level_prefix = b;
|
2016-06-03 17:58:18 +02:00
|
|
|
else if (streq(name, "MemoryDenyWriteExecute"))
|
|
|
|
c->memory_deny_write_execute = b;
|
2016-06-23 01:45:45 +02:00
|
|
|
else if (streq(name, "RestrictRealtime"))
|
|
|
|
c->restrict_realtime = b;
|
2016-07-14 12:37:28 +02:00
|
|
|
else if (streq(name, "DynamicUser"))
|
|
|
|
c->dynamic_user = b;
|
2016-08-01 19:24:40 +02:00
|
|
|
else if (streq(name, "RemoveIPC"))
|
|
|
|
c->remove_ipc = b;
|
2016-08-22 18:43:59 +02:00
|
|
|
else if (streq(name, "ProtectKernelTunables"))
|
|
|
|
c->protect_kernel_tunables = b;
|
2016-10-12 13:31:21 +02:00
|
|
|
else if (streq(name, "ProtectKernelModules"))
|
|
|
|
c->protect_kernel_modules = b;
|
2016-08-22 18:43:59 +02:00
|
|
|
else if (streq(name, "ProtectControlGroups"))
|
|
|
|
c->protect_control_groups = b;
|
2016-12-22 23:34:35 +01:00
|
|
|
else if (streq(name, "MountAPIVFS"))
|
|
|
|
c->mount_apivfs = b;
|
2017-08-07 17:37:02 +02:00
|
|
|
else if (streq(name, "CPUSchedulingResetOnFork"))
|
|
|
|
c->cpu_sched_reset_on_fork = b;
|
|
|
|
else if (streq(name, "NonBlocking"))
|
|
|
|
c->non_blocking = b;
|
2017-08-09 20:52:54 +02:00
|
|
|
else if (streq(name, "LockPersonality"))
|
|
|
|
c->lock_personality = b;
|
2015-09-10 16:45:28 +02:00
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags, name, "%s=%s", name, yes_no(b));
|
2015-08-23 13:19:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
} else if (streq(name, "UtmpIdentifier")) {
|
|
|
|
const char *id;
|
|
|
|
|
|
|
|
r = sd_bus_message_read(message, "s", &id);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
|
|
|
|
|
|
|
r = free_and_strdup(&c->utmp_id, empty_to_null(id));
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
2015-08-23 13:19:21 +02:00
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "UtmpIdentifier=%s", strempty(id));
|
2015-08-23 13:19:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
} else if (streq(name, "UtmpMode")) {
|
|
|
|
const char *s;
|
|
|
|
ExecUtmpMode m;
|
|
|
|
|
|
|
|
r = sd_bus_message_read(message, "s", &s);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
m = exec_utmp_mode_from_string(s);
|
|
|
|
if (m < 0)
|
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid utmp mode");
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2015-08-23 13:19:21 +02:00
|
|
|
c->utmp_mode = m;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags, name, "UtmpMode=%s", exec_utmp_mode_to_string(m));
|
2015-08-23 13:19:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
} else if (streq(name, "PAMName")) {
|
|
|
|
const char *n;
|
|
|
|
|
|
|
|
r = sd_bus_message_read(message, "s", &n);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2015-08-23 13:19:21 +02:00
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
r = free_and_strdup(&c->pam_name, empty_to_null(n));
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "PAMName=%s", strempty(n));
|
2015-08-23 13:19:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
2014-02-05 02:02:00 +01:00
|
|
|
} else if (streq(name, "Environment")) {
|
|
|
|
|
core: drop specifier expansion when parsing transient dbus properties
Specifier expansion (much like C escape handling) should be a helper for
writing unit files, but should be nothing we do on programatic APIs. For
those, the client can do the necessary replacements anyway, and we
really should be careful with doing such string processing of data we
get via lower level programmatic APIs.
We currently do specifier expansion only for the env var transient unit
APIs, no other properties do this. Let's remove it here too, to be fully
systematic.
Yes, in a way this is API breakage, but then again this API isn't
documented yet, and an outlier, hence let's clear this up now, before it
is too late.
2017-11-21 17:32:01 +01:00
|
|
|
_cleanup_strv_free_ char **l = NULL;
|
2014-02-05 02:02:00 +01:00
|
|
|
|
|
|
|
r = sd_bus_message_read_strv(message, &l);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
core: drop specifier expansion when parsing transient dbus properties
Specifier expansion (much like C escape handling) should be a helper for
writing unit files, but should be nothing we do on programatic APIs. For
those, the client can do the necessary replacements anyway, and we
really should be careful with doing such string processing of data we
get via lower level programmatic APIs.
We currently do specifier expansion only for the env var transient unit
APIs, no other properties do this. Let's remove it here too, to be fully
systematic.
Yes, in a way this is API breakage, but then again this API isn't
documented yet, and an outlier, hence let's clear this up now, before it
is too late.
2017-11-21 17:32:01 +01:00
|
|
|
if (!strv_env_is_valid(l))
|
2017-09-12 20:07:30 +02:00
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment block.");
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
core: drop specifier expansion when parsing transient dbus properties
Specifier expansion (much like C escape handling) should be a helper for
writing unit files, but should be nothing we do on programatic APIs. For
those, the client can do the necessary replacements anyway, and we
really should be careful with doing such string processing of data we
get via lower level programmatic APIs.
We currently do specifier expansion only for the env var transient unit
APIs, no other properties do this. Let's remove it here too, to be fully
systematic.
Yes, in a way this is API breakage, but then again this API isn't
documented yet, and an outlier, hence let's clear this up now, before it
is too late.
2017-11-21 17:32:01 +01:00
|
|
|
if (strv_length(l) == 0) {
|
2015-10-20 04:04:10 +02:00
|
|
|
c->environment = strv_free(c->environment);
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_setting(u, flags, name, "Environment=");
|
2015-10-20 04:04:10 +02:00
|
|
|
} else {
|
2017-06-26 11:26:59 +02:00
|
|
|
_cleanup_free_ char *joined = NULL;
|
|
|
|
char **e;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
joined = unit_concat_strv(l, UNIT_ESCAPE_SPECIFIERS|UNIT_ESCAPE_C);
|
|
|
|
if (!joined)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
core: drop specifier expansion when parsing transient dbus properties
Specifier expansion (much like C escape handling) should be a helper for
writing unit files, but should be nothing we do on programatic APIs. For
those, the client can do the necessary replacements anyway, and we
really should be careful with doing such string processing of data we
get via lower level programmatic APIs.
We currently do specifier expansion only for the env var transient unit
APIs, no other properties do this. Let's remove it here too, to be fully
systematic.
Yes, in a way this is API breakage, but then again this API isn't
documented yet, and an outlier, hence let's clear this up now, before it
is too late.
2017-11-21 17:32:01 +01:00
|
|
|
e = strv_env_merge(2, c->environment, l);
|
2015-10-20 04:04:10 +02:00
|
|
|
if (!e)
|
|
|
|
return -ENOMEM;
|
2014-02-05 02:02:00 +01:00
|
|
|
|
2015-10-20 04:04:10 +02:00
|
|
|
strv_free(c->environment);
|
|
|
|
c->environment = e;
|
2014-02-05 02:02:00 +01:00
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags, name, "Environment=%s", joined);
|
2015-10-20 04:04:10 +02:00
|
|
|
}
|
2014-02-05 02:02:00 +01:00
|
|
|
}
|
|
|
|
|
2014-03-05 03:49:00 +01:00
|
|
|
return 1;
|
|
|
|
|
2017-09-10 12:16:44 +02:00
|
|
|
} else if (streq(name, "UnsetEnvironment")) {
|
|
|
|
|
core: drop specifier expansion when parsing transient dbus properties
Specifier expansion (much like C escape handling) should be a helper for
writing unit files, but should be nothing we do on programatic APIs. For
those, the client can do the necessary replacements anyway, and we
really should be careful with doing such string processing of data we
get via lower level programmatic APIs.
We currently do specifier expansion only for the env var transient unit
APIs, no other properties do this. Let's remove it here too, to be fully
systematic.
Yes, in a way this is API breakage, but then again this API isn't
documented yet, and an outlier, hence let's clear this up now, before it
is too late.
2017-11-21 17:32:01 +01:00
|
|
|
_cleanup_strv_free_ char **l = NULL;
|
2017-09-10 12:16:44 +02:00
|
|
|
|
|
|
|
r = sd_bus_message_read_strv(message, &l);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
core: drop specifier expansion when parsing transient dbus properties
Specifier expansion (much like C escape handling) should be a helper for
writing unit files, but should be nothing we do on programatic APIs. For
those, the client can do the necessary replacements anyway, and we
really should be careful with doing such string processing of data we
get via lower level programmatic APIs.
We currently do specifier expansion only for the env var transient unit
APIs, no other properties do this. Let's remove it here too, to be fully
systematic.
Yes, in a way this is API breakage, but then again this API isn't
documented yet, and an outlier, hence let's clear this up now, before it
is too late.
2017-11-21 17:32:01 +01:00
|
|
|
if (!strv_env_name_or_assignment_is_valid(l))
|
2017-09-10 12:16:44 +02:00
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid UnsetEnvironment= list.");
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
core: drop specifier expansion when parsing transient dbus properties
Specifier expansion (much like C escape handling) should be a helper for
writing unit files, but should be nothing we do on programatic APIs. For
those, the client can do the necessary replacements anyway, and we
really should be careful with doing such string processing of data we
get via lower level programmatic APIs.
We currently do specifier expansion only for the env var transient unit
APIs, no other properties do this. Let's remove it here too, to be fully
systematic.
Yes, in a way this is API breakage, but then again this API isn't
documented yet, and an outlier, hence let's clear this up now, before it
is too late.
2017-11-21 17:32:01 +01:00
|
|
|
if (strv_length(l) == 0) {
|
2017-09-10 12:16:44 +02:00
|
|
|
c->unset_environment = strv_free(c->unset_environment);
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_setting(u, flags, name, "UnsetEnvironment=");
|
2017-09-10 12:16:44 +02:00
|
|
|
} else {
|
|
|
|
_cleanup_free_ char *joined = NULL;
|
|
|
|
char **e;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
joined = unit_concat_strv(l, UNIT_ESCAPE_SPECIFIERS|UNIT_ESCAPE_C);
|
|
|
|
if (!joined)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
core: drop specifier expansion when parsing transient dbus properties
Specifier expansion (much like C escape handling) should be a helper for
writing unit files, but should be nothing we do on programatic APIs. For
those, the client can do the necessary replacements anyway, and we
really should be careful with doing such string processing of data we
get via lower level programmatic APIs.
We currently do specifier expansion only for the env var transient unit
APIs, no other properties do this. Let's remove it here too, to be fully
systematic.
Yes, in a way this is API breakage, but then again this API isn't
documented yet, and an outlier, hence let's clear this up now, before it
is too late.
2017-11-21 17:32:01 +01:00
|
|
|
e = strv_env_merge(2, c->unset_environment, l);
|
2017-09-10 12:16:44 +02:00
|
|
|
if (!e)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
strv_free(c->unset_environment);
|
|
|
|
c->unset_environment = e;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags, name, "UnsetEnvironment=%s", joined);
|
2017-09-10 12:16:44 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
2015-10-15 11:57:28 +02:00
|
|
|
} else if (streq(name, "TimerSlackNSec")) {
|
|
|
|
|
|
|
|
nsec_t n;
|
|
|
|
|
|
|
|
r = sd_bus_message_read(message, "t", &n);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2015-10-15 11:57:28 +02:00
|
|
|
c->timer_slack_nsec = n;
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags, name, "TimerSlackNSec=" NSEC_FMT, n);
|
2015-10-15 11:57:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
2015-10-17 21:58:29 +02:00
|
|
|
} else if (streq(name, "OOMScoreAdjust")) {
|
|
|
|
int oa;
|
|
|
|
|
|
|
|
r = sd_bus_message_read(message, "i", &oa);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
if (!oom_score_adjust_is_valid(oa))
|
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "OOM score adjust value out of range");
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2015-10-17 21:58:29 +02:00
|
|
|
c->oom_score_adjust = oa;
|
|
|
|
c->oom_score_adjust_set = true;
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags, name, "OOMScoreAdjust=%i", oa);
|
2015-10-17 21:58:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
2015-10-19 21:57:01 +02:00
|
|
|
} else if (streq(name, "EnvironmentFiles")) {
|
|
|
|
|
|
|
|
_cleanup_free_ char *joined = NULL;
|
|
|
|
_cleanup_fclose_ FILE *f = NULL;
|
2017-01-25 03:53:50 +01:00
|
|
|
_cleanup_strv_free_ char **l = NULL;
|
2015-10-19 21:57:01 +02:00
|
|
|
size_t size = 0;
|
2015-10-19 23:43:19 +02:00
|
|
|
char **i;
|
2015-10-19 21:57:01 +02:00
|
|
|
|
|
|
|
r = sd_bus_message_enter_container(message, 'a', "(sb)");
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
f = open_memstream(&joined, &size);
|
|
|
|
if (!f)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
fputs("EnvironmentFile=\n", f);
|
|
|
|
|
|
|
|
STRV_FOREACH(i, c->environment_files) {
|
|
|
|
_cleanup_free_ char *q = NULL;
|
|
|
|
|
|
|
|
q = specifier_escape(*i);
|
|
|
|
if (!q)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
fprintf(f, "EnvironmentFile=%s\n", q);
|
|
|
|
}
|
2015-10-19 21:57:01 +02:00
|
|
|
|
|
|
|
while ((r = sd_bus_message_enter_container(message, 'r', "sb")) > 0) {
|
|
|
|
const char *path;
|
|
|
|
int b;
|
|
|
|
|
|
|
|
r = sd_bus_message_read(message, "sb", &path, &b);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
r = sd_bus_message_exit_container(message);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
2016-11-23 22:21:40 +01:00
|
|
|
if (!path_is_absolute(path))
|
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not absolute.", path);
|
2015-10-19 21:57:01 +02:00
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
|
|
|
_cleanup_free_ char *q = NULL;
|
2017-08-31 10:02:33 +02:00
|
|
|
char *buf;
|
2015-10-19 21:57:01 +02:00
|
|
|
|
2016-10-23 17:43:27 +02:00
|
|
|
buf = strjoin(b ? "-" : "", path);
|
2015-10-19 23:43:19 +02:00
|
|
|
if (!buf)
|
2015-10-19 21:57:01 +02:00
|
|
|
return -ENOMEM;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
q = specifier_escape(buf);
|
|
|
|
if (!q) {
|
|
|
|
free(buf);
|
|
|
|
return -ENOMEM;
|
|
|
|
}
|
|
|
|
|
|
|
|
fprintf(f, "EnvironmentFile=%s\n", q);
|
2015-10-19 21:57:01 +02:00
|
|
|
|
2015-10-19 23:43:19 +02:00
|
|
|
r = strv_consume(&l, buf);
|
2015-10-19 21:57:01 +02:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
2015-10-22 02:02:17 +02:00
|
|
|
r = sd_bus_message_exit_container(message);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
2015-10-19 23:43:19 +02:00
|
|
|
r = fflush_and_check(f);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
2015-10-19 21:57:01 +02:00
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2015-10-19 23:43:19 +02:00
|
|
|
if (strv_isempty(l)) {
|
|
|
|
c->environment_files = strv_free(c->environment_files);
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_setting(u, flags, name, "EnvironmentFile=");
|
2015-10-19 23:43:19 +02:00
|
|
|
} else {
|
|
|
|
r = strv_extend_strv(&c->environment_files, l, true);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_setting(u, flags, name, joined);
|
2015-10-19 23:43:19 +02:00
|
|
|
}
|
|
|
|
}
|
2015-10-19 21:57:01 +02:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
2015-09-07 08:06:53 +02:00
|
|
|
} else if (streq(name, "PassEnvironment")) {
|
|
|
|
|
core: drop specifier expansion when parsing transient dbus properties
Specifier expansion (much like C escape handling) should be a helper for
writing unit files, but should be nothing we do on programatic APIs. For
those, the client can do the necessary replacements anyway, and we
really should be careful with doing such string processing of data we
get via lower level programmatic APIs.
We currently do specifier expansion only for the env var transient unit
APIs, no other properties do this. Let's remove it here too, to be fully
systematic.
Yes, in a way this is API breakage, but then again this API isn't
documented yet, and an outlier, hence let's clear this up now, before it
is too late.
2017-11-21 17:32:01 +01:00
|
|
|
_cleanup_strv_free_ char **l = NULL;
|
2015-09-07 08:06:53 +02:00
|
|
|
|
|
|
|
r = sd_bus_message_read_strv(message, &l);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
core: drop specifier expansion when parsing transient dbus properties
Specifier expansion (much like C escape handling) should be a helper for
writing unit files, but should be nothing we do on programatic APIs. For
those, the client can do the necessary replacements anyway, and we
really should be careful with doing such string processing of data we
get via lower level programmatic APIs.
We currently do specifier expansion only for the env var transient unit
APIs, no other properties do this. Let's remove it here too, to be fully
systematic.
Yes, in a way this is API breakage, but then again this API isn't
documented yet, and an outlier, hence let's clear this up now, before it
is too late.
2017-11-21 17:32:01 +01:00
|
|
|
if (!strv_env_name_is_valid(l))
|
2017-09-10 12:16:44 +02:00
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid PassEnvironment= block.");
|
2015-09-07 08:06:53 +02:00
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2015-09-07 08:06:53 +02:00
|
|
|
if (strv_isempty(l)) {
|
|
|
|
c->pass_environment = strv_free(c->pass_environment);
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_setting(u, flags, name, "PassEnvironment=");
|
2015-09-07 08:06:53 +02:00
|
|
|
} else {
|
|
|
|
_cleanup_free_ char *joined = NULL;
|
|
|
|
|
2017-09-12 19:48:29 +02:00
|
|
|
/* We write just the new settings out to file, with unresolved specifiers. */
|
2017-11-22 15:03:51 +01:00
|
|
|
joined = unit_concat_strv(l, UNIT_ESCAPE_SPECIFIERS);
|
2015-09-07 08:06:53 +02:00
|
|
|
if (!joined)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags, name, "PassEnvironment=%s", joined);
|
2015-09-07 08:06:53 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
2016-07-07 11:17:00 +02:00
|
|
|
} else if (STR_IN_SET(name, "ReadWriteDirectories", "ReadOnlyDirectories", "InaccessibleDirectories",
|
|
|
|
"ReadWritePaths", "ReadOnlyPaths", "InaccessiblePaths")) {
|
2015-10-20 21:57:04 +02:00
|
|
|
_cleanup_strv_free_ char **l = NULL;
|
|
|
|
char ***dirs;
|
|
|
|
char **p;
|
|
|
|
|
|
|
|
r = sd_bus_message_read_strv(message, &l);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
STRV_FOREACH(p, l) {
|
2016-12-23 01:16:43 +01:00
|
|
|
const char *i = *p;
|
|
|
|
size_t offset;
|
|
|
|
|
|
|
|
if (!utf8_is_valid(i))
|
2015-10-20 21:57:04 +02:00
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s", name);
|
|
|
|
|
2016-12-23 01:16:43 +01:00
|
|
|
offset = i[0] == '-';
|
|
|
|
offset += i[offset] == '+';
|
|
|
|
if (!path_is_absolute(i + offset))
|
2015-10-20 21:57:04 +02:00
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s", name);
|
|
|
|
}
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2016-07-06 09:48:58 +02:00
|
|
|
if (STR_IN_SET(name, "ReadWriteDirectories", "ReadWritePaths"))
|
|
|
|
dirs = &c->read_write_paths;
|
|
|
|
else if (STR_IN_SET(name, "ReadOnlyDirectories", "ReadOnlyPaths"))
|
|
|
|
dirs = &c->read_only_paths;
|
|
|
|
else /* "InaccessiblePaths" */
|
|
|
|
dirs = &c->inaccessible_paths;
|
2015-10-20 21:57:04 +02:00
|
|
|
|
|
|
|
if (strv_length(l) == 0) {
|
|
|
|
*dirs = strv_free(*dirs);
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags, name, "%s=", name);
|
2015-10-20 21:57:04 +02:00
|
|
|
} else {
|
2017-11-22 15:03:51 +01:00
|
|
|
_cleanup_free_ char *joined = NULL;
|
2015-10-20 21:57:04 +02:00
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
joined = unit_concat_strv(l, UNIT_ESCAPE_SPECIFIERS);
|
2015-10-20 21:57:04 +02:00
|
|
|
if (!joined)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
r = strv_extend_strv(dirs, l, true);
|
|
|
|
if (r < 0)
|
|
|
|
return -ENOMEM;
|
2015-10-20 21:57:04 +02:00
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags, name, "%s=%s", name, joined);
|
|
|
|
}
|
2015-10-20 21:57:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
2015-10-25 00:48:33 +02:00
|
|
|
} else if (streq(name, "ProtectSystem")) {
|
|
|
|
const char *s;
|
|
|
|
ProtectSystem ps;
|
|
|
|
|
|
|
|
r = sd_bus_message_read(message, "s", &s);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
r = parse_boolean(s);
|
|
|
|
if (r > 0)
|
|
|
|
ps = PROTECT_SYSTEM_YES;
|
|
|
|
else if (r == 0)
|
|
|
|
ps = PROTECT_SYSTEM_NO;
|
|
|
|
else {
|
|
|
|
ps = protect_system_from_string(s);
|
|
|
|
if (ps < 0)
|
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Failed to parse protect system value");
|
|
|
|
}
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2015-10-25 00:48:33 +02:00
|
|
|
c->protect_system = ps;
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags, name, "%s=%s", name, s);
|
2015-10-25 00:48:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
2015-10-26 01:20:49 +01:00
|
|
|
} else if (streq(name, "ProtectHome")) {
|
|
|
|
const char *s;
|
|
|
|
ProtectHome ph;
|
|
|
|
|
|
|
|
r = sd_bus_message_read(message, "s", &s);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
r = parse_boolean(s);
|
|
|
|
if (r > 0)
|
|
|
|
ph = PROTECT_HOME_YES;
|
|
|
|
else if (r == 0)
|
|
|
|
ph = PROTECT_HOME_NO;
|
|
|
|
else {
|
|
|
|
ph = protect_home_from_string(s);
|
|
|
|
if (ph < 0)
|
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Failed to parse protect home value");
|
|
|
|
}
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2015-10-26 01:20:49 +01:00
|
|
|
c->protect_home = ph;
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags, name, "%s=%s", name, s);
|
2015-10-26 01:20:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
2017-09-14 21:19:05 +02:00
|
|
|
} else if (streq(name, "KeyringMode")) {
|
|
|
|
|
|
|
|
const char *s;
|
|
|
|
ExecKeyringMode m;
|
|
|
|
|
|
|
|
r = sd_bus_message_read(message, "s", &s);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
m = exec_keyring_mode_from_string(s);
|
|
|
|
if (m < 0)
|
2017-09-16 08:45:02 +02:00
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid keyring mode");
|
2017-09-14 21:19:05 +02:00
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2017-09-14 21:19:05 +02:00
|
|
|
c->keyring_mode = m;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags, name, "KeyringMode=%s", exec_keyring_mode_to_string(m));
|
2017-09-14 21:19:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
2017-07-17 09:22:25 +02:00
|
|
|
} else if (streq(name, "RuntimeDirectoryPreserve")) {
|
|
|
|
const char *s;
|
|
|
|
ExecPreserveMode m;
|
|
|
|
|
|
|
|
r = sd_bus_message_read(message, "s", &s);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
m = exec_preserve_mode_from_string(s);
|
|
|
|
if (m < 0)
|
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid preserve mode");
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2017-07-17 09:22:25 +02:00
|
|
|
c->runtime_directory_preserve_mode = m;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags, name, "RuntimeDirectoryPreserve=%s", exec_preserve_mode_to_string(m));
|
2017-07-17 09:22:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
2017-08-07 17:37:02 +02:00
|
|
|
} else if (STR_IN_SET(name, "RuntimeDirectoryMode", "StateDirectoryMode", "CacheDirectoryMode", "LogsDirectoryMode", "ConfigurationDirectoryMode", "UMask")) {
|
2017-07-17 09:22:25 +02:00
|
|
|
mode_t m;
|
|
|
|
|
|
|
|
r = sd_bus_message_read(message, "u", &m);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
core: add {State,Cache,Log,Configuration}Directory= (#6384)
This introduces {State,Cache,Log,Configuration}Directory= those are
similar to RuntimeDirectory=. They create the directories under
/var/lib, /var/cache/, /var/log, or /etc, respectively, with the mode
specified in {State,Cache,Log,Configuration}DirectoryMode=.
This also fixes #6391.
2017-07-18 14:34:52 +02:00
|
|
|
ExecDirectoryType i;
|
2017-07-17 09:22:25 +02:00
|
|
|
|
2017-08-07 17:37:02 +02:00
|
|
|
if (streq(name, "UMask"))
|
|
|
|
c->umask = m;
|
|
|
|
else
|
2017-09-28 16:58:43 +02:00
|
|
|
for (i = 0; i < _EXEC_DIRECTORY_TYPE_MAX; i++)
|
2017-08-07 17:37:02 +02:00
|
|
|
if (startswith(name, exec_directory_type_to_string(i))) {
|
|
|
|
c->directories[i].mode = m;
|
|
|
|
break;
|
|
|
|
}
|
core: add {State,Cache,Log,Configuration}Directory= (#6384)
This introduces {State,Cache,Log,Configuration}Directory= those are
similar to RuntimeDirectory=. They create the directories under
/var/lib, /var/cache/, /var/log, or /etc, respectively, with the mode
specified in {State,Cache,Log,Configuration}DirectoryMode=.
This also fixes #6391.
2017-07-18 14:34:52 +02:00
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags, name, "%s=%040o", name, m);
|
2017-07-17 09:22:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
core: add {State,Cache,Log,Configuration}Directory= (#6384)
This introduces {State,Cache,Log,Configuration}Directory= those are
similar to RuntimeDirectory=. They create the directories under
/var/lib, /var/cache/, /var/log, or /etc, respectively, with the mode
specified in {State,Cache,Log,Configuration}DirectoryMode=.
This also fixes #6391.
2017-07-18 14:34:52 +02:00
|
|
|
} else if (STR_IN_SET(name, "RuntimeDirectory", "StateDirectory", "CacheDirectory", "LogsDirectory", "ConfigurationDirectory")) {
|
2015-10-27 02:56:42 +01:00
|
|
|
_cleanup_strv_free_ char **l = NULL;
|
|
|
|
char **p;
|
|
|
|
|
|
|
|
r = sd_bus_message_read_strv(message, &l);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
STRV_FOREACH(p, l) {
|
2017-10-27 16:28:15 +02:00
|
|
|
if (!path_is_normalized(*p) || path_is_absolute(*p))
|
2017-10-02 10:50:07 +02:00
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= path is not valid: %s", name, *p);
|
2015-10-27 02:56:42 +01:00
|
|
|
}
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
core: add {State,Cache,Log,Configuration}Directory= (#6384)
This introduces {State,Cache,Log,Configuration}Directory= those are
similar to RuntimeDirectory=. They create the directories under
/var/lib, /var/cache/, /var/log, or /etc, respectively, with the mode
specified in {State,Cache,Log,Configuration}DirectoryMode=.
This also fixes #6391.
2017-07-18 14:34:52 +02:00
|
|
|
char ***dirs = NULL;
|
|
|
|
ExecDirectoryType i;
|
|
|
|
|
2017-09-28 16:58:43 +02:00
|
|
|
for (i = 0; i < _EXEC_DIRECTORY_TYPE_MAX; i++)
|
core: add {State,Cache,Log,Configuration}Directory= (#6384)
This introduces {State,Cache,Log,Configuration}Directory= those are
similar to RuntimeDirectory=. They create the directories under
/var/lib, /var/cache/, /var/log, or /etc, respectively, with the mode
specified in {State,Cache,Log,Configuration}DirectoryMode=.
This also fixes #6391.
2017-07-18 14:34:52 +02:00
|
|
|
if (streq(name, exec_directory_type_to_string(i))) {
|
|
|
|
dirs = &c->directories[i].paths;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(dirs);
|
2015-10-27 02:56:42 +01:00
|
|
|
|
|
|
|
if (strv_isempty(l)) {
|
core: add {State,Cache,Log,Configuration}Directory= (#6384)
This introduces {State,Cache,Log,Configuration}Directory= those are
similar to RuntimeDirectory=. They create the directories under
/var/lib, /var/cache/, /var/log, or /etc, respectively, with the mode
specified in {State,Cache,Log,Configuration}DirectoryMode=.
This also fixes #6391.
2017-07-18 14:34:52 +02:00
|
|
|
*dirs = strv_free(*dirs);
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags, name, "%s=", name);
|
2015-10-27 02:56:42 +01:00
|
|
|
} else {
|
2017-11-22 15:03:51 +01:00
|
|
|
_cleanup_free_ char *joined = NULL;
|
|
|
|
|
core: add {State,Cache,Log,Configuration}Directory= (#6384)
This introduces {State,Cache,Log,Configuration}Directory= those are
similar to RuntimeDirectory=. They create the directories under
/var/lib, /var/cache/, /var/log, or /etc, respectively, with the mode
specified in {State,Cache,Log,Configuration}DirectoryMode=.
This also fixes #6391.
2017-07-18 14:34:52 +02:00
|
|
|
r = strv_extend_strv(dirs, l, true);
|
2015-10-27 02:56:42 +01:00
|
|
|
if (r < 0)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
joined = unit_concat_strv(l, UNIT_ESCAPE_SPECIFIERS);
|
2015-10-27 02:56:42 +01:00
|
|
|
if (!joined)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags, name, "%s=%s", name, joined);
|
2015-10-27 02:56:42 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
2016-05-20 15:09:14 +02:00
|
|
|
} else if (streq(name, "SELinuxContext")) {
|
|
|
|
const char *s;
|
|
|
|
r = sd_bus_message_read(message, "s", &s);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2016-05-20 16:20:00 +02:00
|
|
|
if (isempty(s))
|
|
|
|
c->selinux_context = mfree(c->selinux_context);
|
|
|
|
else if (free_and_strdup(&c->selinux_context, s) < 0)
|
|
|
|
return -ENOMEM;
|
2016-05-20 15:09:14 +02:00
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, strempty(s));
|
2016-05-20 15:09:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
2017-08-07 17:37:02 +02:00
|
|
|
|
|
|
|
} else if (STR_IN_SET(name, "AppArmorProfile", "SmackProcessLabel")) {
|
|
|
|
int ignore;
|
|
|
|
const char *s;
|
|
|
|
|
|
|
|
r = sd_bus_message_enter_container(message, 'r', "bs");
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
r = sd_bus_message_read(message, "bs", &ignore, &s);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2017-08-07 17:37:02 +02:00
|
|
|
char **p;
|
|
|
|
bool *b;
|
|
|
|
|
|
|
|
if (streq(name, "AppArmorProfile")) {
|
|
|
|
p = &c->apparmor_profile;
|
|
|
|
b = &c->apparmor_profile_ignore;
|
|
|
|
} else { /* "SmackProcessLabel" */
|
|
|
|
p = &c->smack_process_label;
|
|
|
|
b = &c->smack_process_label_ignore;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isempty(s)) {
|
|
|
|
*p = mfree(*p);
|
|
|
|
*b = false;
|
|
|
|
} else {
|
|
|
|
if (free_and_strdup(p, s) < 0)
|
|
|
|
return -ENOMEM;
|
|
|
|
*b = ignore;
|
|
|
|
}
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s%s", name, ignore ? "-" : "", strempty(s));
|
2017-08-07 17:37:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
2016-11-02 03:25:19 +01:00
|
|
|
} else if (streq(name, "RestrictNamespaces")) {
|
2017-11-22 15:03:51 +01:00
|
|
|
uint64_t rf;
|
2016-05-20 15:09:14 +02:00
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
r = sd_bus_message_read(message, "t", &rf);
|
2016-11-02 03:25:19 +01:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
2017-11-22 15:03:51 +01:00
|
|
|
if ((rf & NAMESPACE_FLAGS_ALL) != rf)
|
2016-11-02 03:25:19 +01:00
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown namespace types");
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2016-11-02 03:25:19 +01:00
|
|
|
_cleanup_free_ char *s = NULL;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
r = namespace_flag_to_string_many(rf, &s);
|
2016-11-02 03:25:19 +01:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
c->restrict_namespaces = rf;
|
|
|
|
unit_write_settingf(u, flags, name, "%s=%s", name, s);
|
2016-11-02 03:25:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
2016-11-22 20:19:08 +01:00
|
|
|
} else if (streq(name, "MountFlags")) {
|
2017-11-22 15:03:51 +01:00
|
|
|
uint64_t fl;
|
2016-11-22 20:19:08 +01:00
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
r = sd_bus_message_read(message, "t", &fl);
|
2016-11-22 20:19:08 +01:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!IN_SET(fl, 0, MS_SHARED, MS_PRIVATE, MS_SLAVE))
|
2016-11-22 20:19:08 +01:00
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown mount propagation flags");
|
2016-02-01 21:37:28 +01:00
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
|
|
|
c->mount_flags = fl;
|
2016-11-22 20:19:08 +01:00
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags, name, "%s=%s", name, mount_propagation_flags_to_string(fl));
|
2016-11-22 20:19:08 +01:00
|
|
|
}
|
|
|
|
|
2016-11-23 22:21:40 +01:00
|
|
|
return 1;
|
|
|
|
} else if (STR_IN_SET(name, "BindPaths", "BindReadOnlyPaths")) {
|
|
|
|
unsigned empty = true;
|
|
|
|
|
|
|
|
r = sd_bus_message_enter_container(message, 'a', "(ssbt)");
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
while ((r = sd_bus_message_enter_container(message, 'r', "ssbt")) > 0) {
|
|
|
|
const char *source, *destination;
|
|
|
|
int ignore_enoent;
|
|
|
|
uint64_t mount_flags;
|
|
|
|
|
|
|
|
r = sd_bus_message_read(message, "ssbt", &source, &destination, &ignore_enoent, &mount_flags);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
r = sd_bus_message_exit_container(message);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
if (!path_is_absolute(source))
|
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Source path %s is not absolute.", source);
|
|
|
|
if (!path_is_absolute(destination))
|
2017-01-31 19:04:01 +01:00
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Destination path %s is not absolute.", destination);
|
2016-11-23 22:21:40 +01:00
|
|
|
if (!IN_SET(mount_flags, 0, MS_REC))
|
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown mount flags.");
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2016-11-23 22:21:40 +01:00
|
|
|
r = bind_mount_add(&c->bind_mounts, &c->n_bind_mounts,
|
|
|
|
&(BindMount) {
|
|
|
|
.source = strdup(source),
|
|
|
|
.destination = strdup(destination),
|
|
|
|
.read_only = !!strstr(name, "ReadOnly"),
|
|
|
|
.recursive = !!(mount_flags & MS_REC),
|
|
|
|
.ignore_enoent = ignore_enoent,
|
|
|
|
});
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(
|
|
|
|
u, flags|UNIT_ESCAPE_SPECIFIERS, name,
|
2016-11-23 22:21:40 +01:00
|
|
|
"%s=%s%s:%s:%s",
|
|
|
|
name,
|
|
|
|
ignore_enoent ? "-" : "",
|
|
|
|
source,
|
|
|
|
destination,
|
|
|
|
(mount_flags & MS_REC) ? "rbind" : "norbind");
|
|
|
|
}
|
|
|
|
|
|
|
|
empty = false;
|
|
|
|
}
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
r = sd_bus_message_exit_container(message);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
if (empty) {
|
|
|
|
bind_mount_free_many(c->bind_mounts, c->n_bind_mounts);
|
|
|
|
c->bind_mounts = NULL;
|
|
|
|
c->n_bind_mounts = 0;
|
2017-11-22 15:03:51 +01:00
|
|
|
|
|
|
|
unit_write_settingf(u, flags, name, "%s=", name);
|
2016-11-23 22:21:40 +01:00
|
|
|
}
|
|
|
|
|
2016-11-22 20:19:08 +01:00
|
|
|
return 1;
|
|
|
|
}
|
2016-11-23 22:21:40 +01:00
|
|
|
|
2016-02-01 21:37:28 +01:00
|
|
|
ri = rlimit_from_string(name);
|
|
|
|
if (ri < 0) {
|
|
|
|
soft = endswith(name, "Soft");
|
|
|
|
if (soft) {
|
|
|
|
const char *n;
|
|
|
|
|
|
|
|
n = strndupa(name, soft - name);
|
|
|
|
ri = rlimit_from_string(n);
|
|
|
|
if (ri >= 0)
|
|
|
|
name = n;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ri >= 0) {
|
2014-03-05 03:49:00 +01:00
|
|
|
uint64_t rl;
|
|
|
|
rlim_t x;
|
|
|
|
|
|
|
|
r = sd_bus_message_read(message, "t", &rl);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
if (rl == (uint64_t) -1)
|
|
|
|
x = RLIM_INFINITY;
|
|
|
|
else {
|
|
|
|
x = (rlim_t) rl;
|
|
|
|
|
|
|
|
if ((uint64_t) x != rl)
|
|
|
|
return -ERANGE;
|
|
|
|
}
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2016-02-01 21:37:28 +01:00
|
|
|
_cleanup_free_ char *f = NULL;
|
|
|
|
struct rlimit nl;
|
|
|
|
|
|
|
|
if (c->rlimit[ri]) {
|
|
|
|
nl = *c->rlimit[ri];
|
|
|
|
|
|
|
|
if (soft)
|
|
|
|
nl.rlim_cur = x;
|
|
|
|
else
|
|
|
|
nl.rlim_max = x;
|
|
|
|
} else
|
|
|
|
/* When the resource limit is not initialized yet, then assign the value to both fields */
|
|
|
|
nl = (struct rlimit) {
|
|
|
|
.rlim_cur = x,
|
|
|
|
.rlim_max = x,
|
|
|
|
};
|
|
|
|
|
|
|
|
r = rlimit_format(&nl, &f);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
2014-03-05 03:49:00 +01:00
|
|
|
|
2016-02-01 21:37:28 +01:00
|
|
|
if (c->rlimit[ri])
|
|
|
|
*c->rlimit[ri] = nl;
|
|
|
|
else {
|
|
|
|
c->rlimit[ri] = newdup(struct rlimit, &nl, 1);
|
|
|
|
if (!c->rlimit[ri])
|
2014-03-05 03:49:00 +01:00
|
|
|
return -ENOMEM;
|
|
|
|
}
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
unit_write_settingf(u, flags, name, "%s=%s", name, f);
|
2014-03-05 03:49:00 +01:00
|
|
|
}
|
|
|
|
|
2014-02-05 02:02:00 +01:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|