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.
This commit is contained in:
Yu Watanabe
2017-07-18 14:34:52 +02:00
committed by Lennart Poettering
parent 5230e31918
commit 3536f49e8f
17 changed files with 286 additions and 96 deletions
+24 -3
View File
@@ -1681,12 +1681,33 @@
</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>StateDirectory=</varname></term>
<term><varname>CacheDirectory=</varname></term>
<term><varname>LogsDirectory=</varname></term>
<term><varname>ConfigurationDirectory=</varname></term>
<listitem><para>Takes a whitespace-separated list of directory names. If set, as similar to
<varname>RuntimeDirectory=</varname>, one or more directories including their parents by the specified names
will be created below <filename>/var/lib</filename>, <filename>/var/cache</filename>, <filename>/var/log</filename>,
or <filename>/etc</filename>, respectively, when the unit is started.
Unlike <varname>RuntimeDirectory=</varname>, the directories are not removed when the unit is stopped.
The lowest subdirectories will be owned by the user and group specified in <varname>User=</varname>
and <varname>Group=</varname>. The options imply <varname>ReadWritePaths=</varname>.
</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>RuntimeDirectoryMode=</varname></term>
<term><varname>StateDirectoryMode=</varname></term>
<term><varname>CacheDirectoryMode=</varname></term>
<term><varname>LogsDirectoryMode=</varname></term>
<term><varname>ConfigurationDirectoryMode=</varname></term>
<listitem><para>Specifies the access mode of the directories specified in
<varname>RuntimeDirectory=</varname> as an octal number. Defaults to
<constant>0755</constant>. See "Permissions" in
<varname>RuntimeDirectory=</varname>, <varname>StateDirectory=</varname>, <varname>CacheDirectory=</varname>,
<varname>LogsDirectory=</varname>, or <varname>ConfigurationDirectory=</varname>, respectively, as an octal number.
Defaults to <constant>0755</constant>. See "Permissions" in
<citerefentry project='man-pages'><refentrytitle>path_resolution</refentrytitle><manvolnum>7</manvolnum></citerefentry>
for a discussion of the meaning of permission bits.
</para></listitem>
@@ -1727,7 +1748,7 @@
services, so that they cannot be used to circumvent the restrictions of this option. Specifically, it is
recommended to combine this option with <varname>SystemCallArchitectures=native</varname> or similar. If
running in user mode, or in system mode, but without the <constant>CAP_SYS_ADMIN</constant> capability
(e.g. setting <varname>User=</varname>), <varname>NoNewPrivileges=yes</varname> is implied. </para></listitem>
(e.g. setting <varname>User=</varname>), <varname>NoNewPrivileges=yes</varname> is implied.</para></listitem>
</varlistentry>
<varlistentry>
+12
View File
@@ -151,6 +151,18 @@ const char* exit_status_to_string(int status, ExitStatusLevel level) {
case EXIT_KEYRING:
return "KEYRING";
case EXIT_STATE_DIRECTORY:
return "STATE_DIRECTORY";
case EXIT_CACHE_DIRECTORY:
return "CACHE_DIRECTORY";
case EXIT_LOGS_DIRECTORY:
return "LOGS_DIRECTORY";
case EXIT_CONFIGURATION_DIRECTORY:
return "CONFIGURATION_DIRECTORY";
}
}
+4
View File
@@ -83,6 +83,10 @@ enum {
EXIT_CHOWN,
EXIT_SMACK_PROCESS_LABEL,
EXIT_KEYRING,
EXIT_STATE_DIRECTORY,
EXIT_CACHE_DIRECTORY,
EXIT_LOGS_DIRECTORY, /* 240 */
EXIT_CONFIGURATION_DIRECTORY,
};
typedef enum ExitStatusLevel {
+34 -10
View File
@@ -851,9 +851,17 @@ const sd_bus_vtable bus_exec_vtable[] = {
SD_BUS_PROPERTY("SystemCallErrorNumber", "i", property_get_syscall_errno, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Personality", "s", property_get_personality, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("RestrictAddressFamilies", "(bas)", property_get_address_families, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("RuntimeDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, runtime_directory_mode), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("RuntimeDirectoryPreserve", "s", property_get_exec_preserve_mode, offsetof(ExecContext, runtime_directory_preserve_mode), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("RuntimeDirectory", "as", NULL, offsetof(ExecContext, runtime_directory), SD_BUS_VTABLE_PROPERTY_CONST),
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),
SD_BUS_PROPERTY("DataDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_STATE].mode), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("DataDirectory", "as", NULL, offsetof(ExecContext, directories[EXEC_DIRECTORY_STATE].paths), SD_BUS_VTABLE_PROPERTY_CONST),
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),
SD_BUS_PROPERTY("MemoryDenyWriteExecute", "b", bus_property_get_bool, offsetof(ExecContext, memory_deny_write_execute), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("RestrictRealtime", "b", bus_property_get_bool, offsetof(ExecContext, restrict_realtime), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("RestrictNamespaces", "t", bus_property_get_ulong, offsetof(ExecContext, restrict_namespaces), SD_BUS_VTABLE_PROPERTY_CONST),
@@ -1701,7 +1709,7 @@ int bus_exec_context_set_transient_property(
return 1;
} else if (streq(name, "RuntimeDirectoryMode")) {
} else if (STR_IN_SET(name, "RuntimeDirectoryMode", "StateDirectoryMode", "CacheDirectoryMode", "LogsDirectoryMode", "ConfigurationDirectoryMode")) {
mode_t m;
r = sd_bus_message_read(message, "u", &m);
@@ -1709,14 +1717,20 @@ int bus_exec_context_set_transient_property(
return r;
if (mode != UNIT_CHECK) {
c->runtime_directory_mode = m;
ExecDirectoryType i;
unit_write_drop_in_private_format(u, mode, name, "RuntimeDirectoryMode=%040o", m);
for (i = 0; i < _EXEC_DIRECTORY_MAX; i++)
if (startswith(name, exec_directory_type_to_string(i))) {
c->directories[i].mode = m;
break;
}
unit_write_drop_in_private_format(u, mode, name, "%s=%040o", name, m);
}
return 1;
} else if (streq(name, "RuntimeDirectory")) {
} else if (STR_IN_SET(name, "RuntimeDirectory", "StateDirectory", "CacheDirectory", "LogsDirectory", "ConfigurationDirectory")) {
_cleanup_strv_free_ char **l = NULL;
char **p;
@@ -1726,22 +1740,32 @@ int bus_exec_context_set_transient_property(
STRV_FOREACH(p, l) {
if (!filename_is_valid(*p))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Runtime directory is not valid %s", *p);
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s is not valid %s", name, *p);
}
if (mode != UNIT_CHECK) {
_cleanup_free_ char *joined = NULL;
char ***dirs = NULL;
ExecDirectoryType i;
for (i = 0; i < _EXEC_DIRECTORY_MAX; i++)
if (streq(name, exec_directory_type_to_string(i))) {
dirs = &c->directories[i].paths;
break;
}
assert(dirs);
if (strv_isempty(l)) {
c->runtime_directory = strv_free(c->runtime_directory);
*dirs = strv_free(*dirs);
unit_write_drop_in_private_format(u, mode, name, "%s=", name);
} else {
r = strv_extend_strv(&c->runtime_directory, l, true);
r = strv_extend_strv(dirs, l, true);
if (r < 0)
return -ENOMEM;
joined = strv_join_quoted(c->runtime_directory);
joined = strv_join_quoted(*dirs);
if (!joined)
return -ENOMEM;
+91 -34
View File
@@ -1839,39 +1839,68 @@ static int setup_private_users(uid_t uid, gid_t gid) {
return 0;
}
static int setup_runtime_directory(
static int setup_exec_directory(
const ExecContext *context,
const ExecParameters *params,
uid_t uid,
gid_t gid) {
gid_t gid,
bool manager_is_system,
ExecDirectoryType type,
int *exit_status) {
static const int exit_status_table[_EXEC_DIRECTORY_MAX] = {
[EXEC_DIRECTORY_RUNTIME] = EXIT_RUNTIME_DIRECTORY,
[EXEC_DIRECTORY_STATE] = EXIT_STATE_DIRECTORY,
[EXEC_DIRECTORY_CACHE] = EXIT_CACHE_DIRECTORY,
[EXEC_DIRECTORY_LOGS] = EXIT_LOGS_DIRECTORY,
[EXEC_DIRECTORY_CONFIGURATION] = EXIT_CONFIGURATION_DIRECTORY,
};
char **rt;
int r;
assert(context);
assert(params);
assert(type >= 0 && type < _EXEC_DIRECTORY_MAX);
assert(exit_status);
STRV_FOREACH(rt, context->runtime_directory) {
if (!params->prefix[type])
return 0;
if (manager_is_system) {
if (!uid_is_valid(uid))
uid = 0;
if (!gid_is_valid(gid))
gid = 0;
}
STRV_FOREACH(rt, context->directories[type].paths) {
_cleanup_free_ char *p;
p = strjoin(params->runtime_prefix, "/", *rt);
if (!p)
return -ENOMEM;
p = strjoin(params->prefix[type], "/", *rt);
if (!p) {
r = -ENOMEM;
goto fail;
}
r = mkdir_parents_label(p, 0755);
if (r < 0)
return r;
goto fail;
r = mkdir_p_label(p, context->runtime_directory_mode);
r = mkdir_p_label(p, context->directories[type].mode);
if (r < 0)
return r;
goto fail;
r = chmod_and_chown(p, context->runtime_directory_mode, uid, gid);
r = chmod_and_chown(p, context->directories[type].mode, uid, gid);
if (r < 0)
return r;
goto fail;
}
return 0;
fail:
*exit_status = exit_status_table[type];
return r;
}
static int setup_smack(
@@ -1917,29 +1946,40 @@ static int compile_read_write_paths(
_cleanup_strv_free_ char **l = NULL;
char **rt;
ExecDirectoryType i;
/* Compile the list of writable paths. This is the combination of
* the explicitly configured paths, plus all runtime directories. */
if (strv_isempty(context->read_write_paths) &&
strv_isempty(context->runtime_directory)) {
*ret = NULL; /* NOP if neither is set */
return 0;
if (strv_isempty(context->read_write_paths)) {
for (i = 0; i < _EXEC_DIRECTORY_MAX; i++)
if (!strv_isempty(context->directories[i].paths))
break;
if (i == _EXEC_DIRECTORY_MAX) {
*ret = NULL; /* NOP if neither is set */
return 0;
}
}
l = strv_copy(context->read_write_paths);
if (!l)
return -ENOMEM;
STRV_FOREACH(rt, context->runtime_directory) {
char *s;
for (i = 0; i < _EXEC_DIRECTORY_MAX; i++) {
if (!params->prefix[i])
continue;
s = strjoin(params->runtime_prefix, "/", *rt);
if (!s)
return -ENOMEM;
STRV_FOREACH(rt, context->directories[i].paths) {
char *s;
if (strv_consume(&l, s) < 0)
return -ENOMEM;
s = strjoin(params->prefix[i], "/", *rt);
if (!s)
return -ENOMEM;
if (strv_consume(&l, s) < 0)
return -ENOMEM;
}
}
*ret = l;
@@ -2269,6 +2309,7 @@ static int exec_child(
gid_t gid = GID_INVALID;
int i, r, ngids = 0;
unsigned n_fds;
ExecDirectoryType dt;
assert(unit);
assert(command);
@@ -2556,12 +2597,10 @@ static int exec_child(
}
}
if (!strv_isempty(context->runtime_directory) && params->runtime_prefix) {
r = setup_runtime_directory(context, params, uid, gid);
if (r < 0) {
*exit_status = EXIT_RUNTIME_DIRECTORY;
for (dt = 0; dt < _EXEC_DIRECTORY_MAX; dt++) {
r = setup_exec_directory(context, params, uid, gid, MANAGER_IS_SYSTEM(unit->manager), dt, exit_status);
if (r < 0)
return r;
}
}
r = build_environment(
@@ -3049,6 +3088,8 @@ int exec_spawn(Unit *unit,
}
void exec_context_init(ExecContext *c) {
ExecDirectoryType i;
assert(c);
c->umask = 0022;
@@ -3059,13 +3100,15 @@ void exec_context_init(ExecContext *c) {
c->ignore_sigpipe = true;
c->timer_slack_nsec = NSEC_INFINITY;
c->personality = PERSONALITY_INVALID;
c->runtime_directory_mode = 0755;
for (i = 0; i < _EXEC_DIRECTORY_MAX; i++)
c->directories[i].mode = 0755;
c->capability_bounding_set = CAP_ALL;
c->restrict_namespaces = NAMESPACE_FLAGS_ALL;
}
void exec_context_done(ExecContext *c) {
unsigned l;
ExecDirectoryType i;
assert(c);
@@ -3109,7 +3152,8 @@ void exec_context_done(ExecContext *c) {
c->syscall_archs = set_free(c->syscall_archs);
c->address_families = set_free(c->address_families);
c->runtime_directory = strv_free(c->runtime_directory);
for (i = 0; i < _EXEC_DIRECTORY_MAX; i++)
c->directories[i].paths = strv_free(c->directories[i].paths);
}
int exec_context_destroy_runtime_directory(ExecContext *c, const char *runtime_prefix) {
@@ -3120,7 +3164,7 @@ int exec_context_destroy_runtime_directory(ExecContext *c, const char *runtime_p
if (!runtime_prefix)
return 0;
STRV_FOREACH(i, c->runtime_directory) {
STRV_FOREACH(i, c->directories[EXEC_DIRECTORY_RUNTIME].paths) {
_cleanup_free_ char *p;
p = strjoin(runtime_prefix, "/", *i);
@@ -3376,6 +3420,7 @@ static void strv_fprintf(FILE *f, char **l) {
void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
char **e, **d;
unsigned i;
ExecDirectoryType dt;
int r;
assert(c);
@@ -3431,12 +3476,14 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
STRV_FOREACH(e, c->pass_environment)
fprintf(f, "%sPassEnvironment: %s\n", prefix, *e);
fprintf(f, "%sRuntimeDirectoryMode: %04o\n", prefix, c->runtime_directory_mode);
fprintf(f, "%sRuntimeDirectoryPreserve: %s\n", prefix, exec_preserve_mode_to_string(c->runtime_directory_preserve_mode));
STRV_FOREACH(d, c->runtime_directory)
fprintf(f, "%sRuntimeDirectory: %s\n", prefix, *d);
for (dt = 0; dt < _EXEC_DIRECTORY_MAX; dt++) {
fprintf(f, "%s%sMode: %04o\n", prefix, exec_directory_type_to_string(dt), c->directories[dt].mode);
STRV_FOREACH(d, c->directories[dt].paths)
fprintf(f, "%s%s: %s\n", prefix, exec_directory_type_to_string(dt), *d);
}
if (c->nice_set)
fprintf(f,
@@ -4185,3 +4232,13 @@ static const char* const exec_preserve_mode_table[_EXEC_PRESERVE_MODE_MAX] = {
};
DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(exec_preserve_mode, ExecPreserveMode, EXEC_PRESERVE_YES);
static const char* const exec_directory_type_table[_EXEC_DIRECTORY_MAX] = {
[EXEC_DIRECTORY_RUNTIME] = "RuntimeDirectory",
[EXEC_DIRECTORY_STATE] = "StateDirectory",
[EXEC_DIRECTORY_CACHE] = "CacheDirectory",
[EXEC_DIRECTORY_LOGS] = "LogsDirectory",
[EXEC_DIRECTORY_CONFIGURATION] = "ConfigurationDirectory",
};
DEFINE_STRING_TABLE_LOOKUP(exec_directory_type, ExecDirectoryType);
+20 -3
View File
@@ -108,6 +108,21 @@ struct ExecRuntime {
int netns_storage_socket[2];
};
typedef enum ExecDirectoryType {
EXEC_DIRECTORY_RUNTIME = 0,
EXEC_DIRECTORY_STATE,
EXEC_DIRECTORY_CACHE,
EXEC_DIRECTORY_LOGS,
EXEC_DIRECTORY_CONFIGURATION,
_EXEC_DIRECTORY_MAX,
_EXEC_DIRECTORY_INVALID = -1,
} ExecDirectoryType;
typedef struct ExecDirectory {
char **paths;
mode_t mode;
} ExecDirectory;
struct ExecContext {
char **environment;
char **environment_files;
@@ -217,9 +232,8 @@ struct ExecContext {
Set *address_families;
bool address_families_whitelist:1;
char **runtime_directory;
mode_t runtime_directory_mode;
ExecPreserveMode runtime_directory_preserve_mode;
ExecDirectory directories[_EXEC_DIRECTORY_MAX];
bool memory_deny_write_execute;
bool restrict_realtime;
@@ -265,7 +279,7 @@ struct ExecParameters {
CGroupMask cgroup_supported;
const char *cgroup_path;
const char *runtime_prefix;
char **prefix;
const char *confirm_spawn;
@@ -342,3 +356,6 @@ ExecUtmpMode exec_utmp_mode_from_string(const char *s) _pure_;
const char* exec_preserve_mode_to_string(ExecPreserveMode i) _const_;
ExecPreserveMode exec_preserve_mode_from_string(const char *s) _pure_;
const char* exec_directory_type_to_string(ExecDirectoryType i) _const_;
ExecDirectoryType exec_directory_type_from_string(const char *s) _pure_;
+10 -2
View File
@@ -104,9 +104,17 @@ $1.ProtectHome, config_parse_protect_home, 0,
$1.MountFlags, config_parse_exec_mount_flags, 0, offsetof($1, exec_context)
$1.MountAPIVFS, config_parse_bool, 0, offsetof($1, exec_context.mount_apivfs)
$1.Personality, config_parse_personality, 0, offsetof($1, exec_context.personality)
$1.RuntimeDirectoryMode, config_parse_mode, 0, offsetof($1, exec_context.runtime_directory_mode)
$1.RuntimeDirectoryPreserve, config_parse_runtime_preserve_mode, 0, offsetof($1, exec_context.runtime_directory_preserve_mode)
$1.RuntimeDirectory, config_parse_runtime_directory, 0, offsetof($1, exec_context.runtime_directory)
$1.RuntimeDirectoryMode, config_parse_mode, 0, offsetof($1, exec_context.directories[EXEC_DIRECTORY_RUNTIME].mode)
$1.RuntimeDirectory, config_parse_exec_directories, 0, offsetof($1, exec_context.directories[EXEC_DIRECTORY_RUNTIME].paths)
$1.DataDirectoryMode, config_parse_mode, 0, offsetof($1, exec_context.directories[EXEC_DIRECTORY_STATE].mode)
$1.DataDirectory, config_parse_exec_directories, 0, offsetof($1, exec_context.directories[EXEC_DIRECTORY_STATE].paths)
$1.CacheDirectoryMode, config_parse_mode, 0, offsetof($1, exec_context.directories[EXEC_DIRECTORY_CACHE].mode)
$1.CacheDirectory, config_parse_exec_directories, 0, offsetof($1, exec_context.directories[EXEC_DIRECTORY_CACHE].paths)
$1.LogsDirectoryMode, config_parse_mode, 0, offsetof($1, exec_context.directories[EXEC_DIRECTORY_LOGS].mode)
$1.LogsDirectory, config_parse_exec_directories, 0, offsetof($1, exec_context.directories[EXEC_DIRECTORY_LOGS].paths)
$1.ConfigurationDirectoryMode, config_parse_mode, 0, offsetof($1, exec_context.directories[EXEC_DIRECTORY_CONFIGURATION].mode)
$1.ConfigurationDirectory, config_parse_exec_directories, 0, offsetof($1, exec_context.directories[EXEC_DIRECTORY_CONFIGURATION].paths)
m4_ifdef(`HAVE_PAM',
`$1.PAMName, config_parse_unit_string_printf, 0, offsetof($1, exec_context.pam_name)',
`$1.PAMName, config_parse_warn_compat, DISABLED_CONFIGURATION, 0')
+2 -2
View File
@@ -3703,7 +3703,7 @@ int config_parse_job_mode_isolate(
DEFINE_CONFIG_PARSE_ENUM(config_parse_runtime_preserve_mode, exec_preserve_mode, ExecPreserveMode, "Failed to parse runtime directory preserve mode");
int config_parse_runtime_directory(
int config_parse_exec_directories(
const char *unit,
const char *filename,
unsigned line,
@@ -3754,7 +3754,7 @@ int config_parse_runtime_directory(
if (!path_is_safe(k) || path_is_absolute(k)) {
log_syntax(unit, LOG_ERR, filename, line, 0,
"Runtime directory is not valid, ignoring assignment: %s", rvalue);
"%s is not valid, ignoring assignment: %s", lvalue, rvalue);
continue;
}
+1 -1
View File
@@ -103,7 +103,7 @@ int config_parse_exec_apparmor_profile(const char *unit, const char *filename, u
int config_parse_exec_smack_process_label(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_address_families(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_runtime_preserve_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_runtime_directory(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_exec_directories(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_set_status(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_namespace_path_strv(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_no_new_privileges(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+57 -12
View File
@@ -36,6 +36,7 @@
#include "sd-daemon.h"
#include "sd-messages.h"
#include "sd-path.h"
#include "alloc-util.h"
#include "audit-fd.h"
@@ -52,6 +53,7 @@
#include "dirent-util.h"
#include "env-util.h"
#include "escape.h"
#include "execute.h"
#include "exec-util.h"
#include "exit-status.h"
#include "fd-util.h"
@@ -556,6 +558,48 @@ static int manager_default_environment(Manager *m) {
return 0;
}
static int manager_setup_prefix(Manager *m) {
struct table_entry {
uint64_t type;
const char *suffix;
};
static const struct table_entry paths_system[_EXEC_DIRECTORY_MAX] = {
[EXEC_DIRECTORY_RUNTIME] = { SD_PATH_SYSTEM_RUNTIME, NULL },
[EXEC_DIRECTORY_STATE] = { SD_PATH_SYSTEM_STATE_PRIVATE, NULL },
[EXEC_DIRECTORY_CACHE] = { SD_PATH_SYSTEM_STATE_CACHE, NULL },
[EXEC_DIRECTORY_LOGS] = { SD_PATH_SYSTEM_STATE_LOGS, NULL },
[EXEC_DIRECTORY_CONFIGURATION] = { SD_PATH_SYSTEM_CONFIGURATION, NULL },
};
static const struct table_entry paths_user[_EXEC_DIRECTORY_MAX] = {
[EXEC_DIRECTORY_RUNTIME] = { SD_PATH_USER_RUNTIME, NULL },
[EXEC_DIRECTORY_STATE] = { SD_PATH_USER_CONFIGURATION, NULL },
[EXEC_DIRECTORY_CACHE] = { SD_PATH_SYSTEM_STATE_CACHE, NULL },
[EXEC_DIRECTORY_LOGS] = { SD_PATH_SYSTEM_CONFIGURATION, "log" },
[EXEC_DIRECTORY_CONFIGURATION] = { SD_PATH_SYSTEM_CONFIGURATION, NULL },
};
const struct table_entry *p;
ExecDirectoryType i;
int r;
assert(m);
if (MANAGER_IS_SYSTEM(m))
p = paths_system;
else
p = paths_user;
for (i = 0; i < _EXEC_DIRECTORY_MAX; i++) {
r = sd_path_home(p[i].type, p[i].suffix, &m->prefix[i]);
if (r < 0)
return r;
}
return 0;
}
int manager_new(UnitFileScope scope, bool test_run, Manager **_m) {
Manager *m;
int r;
@@ -672,6 +716,10 @@ int manager_new(UnitFileScope scope, bool test_run, Manager **_m) {
m->taint_usr = dir_is_empty("/usr") > 0;
r = manager_setup_prefix(m);
if (r < 0)
goto fail;
*_m = m;
return 0;
@@ -692,7 +740,6 @@ static int manager_setup_notify(Manager *m) {
.sa.sa_family = AF_UNIX,
};
static const int one = 1;
const char *e;
/* First free all secondary fields */
m->notify_socket = mfree(m->notify_socket);
@@ -704,13 +751,7 @@ static int manager_setup_notify(Manager *m) {
fd_inc_rcvbuf(fd, NOTIFY_RCVBUF_SIZE);
e = manager_get_runtime_prefix(m);
if (!e) {
log_error("Failed to determine runtime prefix.");
return -EINVAL;
}
m->notify_socket = strappend(e, "/systemd/notify");
m->notify_socket = strappend(m->prefix[EXEC_DIRECTORY_RUNTIME], "/systemd/notify");
if (!m->notify_socket)
return log_oom();
@@ -3309,12 +3350,16 @@ Set *manager_get_units_requiring_mounts_for(Manager *m, const char *path) {
return hashmap_get(m->units_requiring_mounts_for, streq(p, "/") ? "" : p);
}
const char *manager_get_runtime_prefix(Manager *m) {
int manager_set_exec_params(Manager *m, ExecParameters *p) {
assert(m);
assert(p);
return MANAGER_IS_SYSTEM(m) ?
"/run" :
getenv("XDG_RUNTIME_DIR");
p->environment = m->environment;
p->confirm_spawn = manager_get_confirm_spawn(m);
p->cgroup_supported = m->cgroup_supported;
p->prefix = m->prefix;
return 0;
}
int manager_update_failed_units(Manager *m, Unit *u, bool failed) {
+4 -1
View File
@@ -316,6 +316,9 @@ struct Manager {
const char *invocation_log_format_string;
int first_boot; /* tri-state */
/* prefixes of e.g. RuntimeDirectory= */
char *prefix[_EXEC_DIRECTORY_MAX];
};
#define MANAGER_IS_SYSTEM(m) ((m)->unit_file_scope == UNIT_FILE_SYSTEM)
@@ -380,7 +383,7 @@ void manager_flip_auto_status(Manager *m, bool enable);
Set *manager_get_units_requiring_mounts_for(Manager *m, const char *path);
const char *manager_get_runtime_prefix(Manager *m);
int manager_set_exec_params(Manager *m, ExecParameters *p);
ManagerState manager_state(Manager *m);
+5 -5
View File
@@ -770,12 +770,12 @@ static int mount_spawn(Mount *m, ExecCommand *c, pid_t *_pid) {
if (r < 0)
return r;
exec_params.environment = UNIT(m)->manager->environment;
exec_params.confirm_spawn = manager_get_confirm_spawn(UNIT(m)->manager);
exec_params.cgroup_supported = UNIT(m)->manager->cgroup_supported;
r = manager_set_exec_params(UNIT(m)->manager, &exec_params);
if (r < 0)
return r;
exec_params.cgroup_path = UNIT(m)->cgroup_path;
exec_params.cgroup_delegate = m->cgroup_context.delegate;
exec_params.runtime_prefix = manager_get_runtime_prefix(UNIT(m)->manager);
r = exec_spawn(UNIT(m),
c,
@@ -808,7 +808,7 @@ static void mount_enter_dead(Mount *m, MountResult f) {
exec_runtime_destroy(m->exec_runtime);
m->exec_runtime = exec_runtime_unref(m->exec_runtime);
exec_context_destroy_runtime_directory(&m->exec_context, manager_get_runtime_prefix(UNIT(m)->manager));
exec_context_destroy_runtime_directory(&m->exec_context, UNIT(m)->manager->prefix[EXEC_DIRECTORY_RUNTIME]);
unit_unref_uid_gid(UNIT(m), true);
+6 -5
View File
@@ -1342,7 +1342,11 @@ static int service_spawn(
}
}
final_env = strv_env_merge(2, UNIT(s)->manager->environment, our_env, NULL);
r = manager_set_exec_params(UNIT(s)->manager, &exec_params);
if (r < 0)
return r;
final_env = strv_env_merge(2, exec_params.environment, our_env, NULL);
if (!final_env)
return -ENOMEM;
@@ -1359,11 +1363,8 @@ static int service_spawn(
exec_params.fd_names = fd_names;
exec_params.n_storage_fds = n_storage_fds;
exec_params.n_socket_fds = n_socket_fds;
exec_params.confirm_spawn = manager_get_confirm_spawn(UNIT(s)->manager);
exec_params.cgroup_supported = UNIT(s)->manager->cgroup_supported;
exec_params.cgroup_path = path;
exec_params.cgroup_delegate = s->cgroup_context.delegate;
exec_params.runtime_prefix = manager_get_runtime_prefix(UNIT(s)->manager);
exec_params.watchdog_usec = s->watchdog_usec;
exec_params.selinux_context_net = s->socket_fd_selinux_context_net;
if (s->type == SERVICE_IDLE)
@@ -1525,7 +1526,7 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart)
if (s->exec_context.runtime_directory_preserve_mode == EXEC_PRESERVE_NO ||
(s->exec_context.runtime_directory_preserve_mode == EXEC_PRESERVE_RESTART && !service_will_restart(s)))
/* Also, remove the runtime directory */
exec_context_destroy_runtime_directory(&s->exec_context, manager_get_runtime_prefix(UNIT(s)->manager));
exec_context_destroy_runtime_directory(&s->exec_context, UNIT(s)->manager->prefix[EXEC_DIRECTORY_RUNTIME]);
/* Get rid of the IPC bits of the user */
unit_unref_uid_gid(UNIT(s), true);
+6 -5
View File
@@ -1790,13 +1790,13 @@ static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) {
if (r < 0)
return r;
r = manager_set_exec_params(UNIT(s)->manager, &exec_params);
if (r < 0)
return r;
exec_params.argv = c->argv;
exec_params.environment = UNIT(s)->manager->environment;
exec_params.confirm_spawn = manager_get_confirm_spawn(UNIT(s)->manager);
exec_params.cgroup_supported = UNIT(s)->manager->cgroup_supported;
exec_params.cgroup_path = UNIT(s)->cgroup_path;
exec_params.cgroup_delegate = s->cgroup_context.delegate;
exec_params.runtime_prefix = manager_get_runtime_prefix(UNIT(s)->manager);
r = exec_spawn(UNIT(s),
c,
@@ -1814,6 +1814,7 @@ static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) {
return r;
*_pid = pid;
return 0;
}
@@ -1912,7 +1913,7 @@ static void socket_enter_dead(Socket *s, SocketResult f) {
exec_runtime_destroy(s->exec_runtime);
s->exec_runtime = exec_runtime_unref(s->exec_runtime);
exec_context_destroy_runtime_directory(&s->exec_context, manager_get_runtime_prefix(UNIT(s)->manager));
exec_context_destroy_runtime_directory(&s->exec_context, UNIT(s)->manager->prefix[EXEC_DIRECTORY_RUNTIME]);
unit_unref_uid_gid(UNIT(s), true);
+7 -6
View File
@@ -630,18 +630,18 @@ static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) {
r = unit_setup_dynamic_creds(UNIT(s));
if (r < 0)
return r;
goto fail;
r = swap_arm_timer(s, usec_add(now(CLOCK_MONOTONIC), s->timeout_usec));
if (r < 0)
goto fail;
exec_params.environment = UNIT(s)->manager->environment;
exec_params.confirm_spawn = manager_get_confirm_spawn(UNIT(s)->manager);
exec_params.cgroup_supported = UNIT(s)->manager->cgroup_supported;
r = manager_set_exec_params(UNIT(s)->manager, &exec_params);
if (r < 0)
goto fail;
exec_params.cgroup_path = UNIT(s)->cgroup_path;
exec_params.cgroup_delegate = s->cgroup_context.delegate;
exec_params.runtime_prefix = manager_get_runtime_prefix(UNIT(s)->manager);
r = exec_spawn(UNIT(s),
c,
@@ -664,6 +664,7 @@ static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) {
fail:
s->timer_event_source = sd_event_source_unref(s->timer_event_source);
return r;
}
@@ -678,7 +679,7 @@ static void swap_enter_dead(Swap *s, SwapResult f) {
exec_runtime_destroy(s->exec_runtime);
s->exec_runtime = exec_runtime_unref(s->exec_runtime);
exec_context_destroy_runtime_directory(&s->exec_context, manager_get_runtime_prefix(UNIT(s)->manager));
exec_context_destroy_runtime_directory(&s->exec_context, UNIT(s)->manager->prefix[EXEC_DIRECTORY_RUNTIME]);
unit_unref_uid_gid(UNIT(s), true);
+1 -5
View File
@@ -145,15 +145,11 @@ static int specifier_cgroup_slice(char specifier, void *data, void *userdata, ch
static int specifier_runtime(char specifier, void *data, void *userdata, char **ret) {
Unit *u = userdata;
const char *e;
char *n = NULL;
assert(u);
e = manager_get_runtime_prefix(u->manager);
if (!e)
return -EOPNOTSUPP;
n = strdup(e);
n = strdup(u->manager->prefix[EXEC_DIRECTORY_RUNTIME]);
if (!n)
return -ENOMEM;
+2 -2
View File
@@ -548,7 +548,7 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
r = sd_bus_message_close_container(m);
} else if (streq(field, "RuntimeDirectoryMode")) {
} else if (STR_IN_SET(field, "RuntimeDirectoryMode", "StateDirectoryMode", "CacheDirectoryMode", "LogsDirectoryMode", "ConfigurationDirectoryMode")) {
mode_t mode;
r = parse_mode(eq, &mode);
@@ -557,7 +557,7 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
r = sd_bus_message_append(m, "v", "u", mode);
} else if (streq(field, "RuntimeDirectory")) {
} else if (STR_IN_SET(field, "RuntimeDirectory", "StateDirectory", "CacheDirectory", "LogsDirectory", "ConfigurationDirectory")) {
const char *p;
r = sd_bus_message_open_container(m, 'v', "as");