summaryrefslogtreecommitdiffstats
path: root/src/tmpfiles/tmpfiles.c
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2022-03-09 22:29:19 +0100
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2022-03-29 16:17:56 +0200
commit172e9cc3ee3dcca288d04c744984a9a3b2a0d008 (patch)
tree146359ba4b1d7203810ae6a130bca8b046442502 /src/tmpfiles/tmpfiles.c
parentshared/install: move scope into InstallContext (diff)
downloadsystemd-172e9cc3ee3dcca288d04c744984a9a3b2a0d008.tar.xz
systemd-172e9cc3ee3dcca288d04c744984a9a3b2a0d008.zip
shared/specifier: fix %u/%U/%g/%G when called as unprivileged user
We would resolve those specifiers to the calling user/group. This is mostly OK when done in the manager, because the manager generally operates as root in system mode, and a non-root in user mode. It would still be wrong if called with --test though. But in systemctl, this would be generally wrong, since we can call 'systemctl --system' as a normal user, either for testing or even for actual operation with '--root=…'. When operating in --global mode, %u/%U/%g/%G should return an error. The information whether we're operating in system mode, user mode, or global mode is passed as the data pointer to specifier_group_name(), specifier_user_name(), specifier_group_id(), specifier_user_id(). We can't use userdata, because it's already used for other things.
Diffstat (limited to 'src/tmpfiles/tmpfiles.c')
-rw-r--r--src/tmpfiles/tmpfiles.c53
1 files changed, 26 insertions, 27 deletions
diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
index f0190f9b4c..17b9c6ab9a 100644
--- a/src/tmpfiles/tmpfiles.c
+++ b/src/tmpfiles/tmpfiles.c
@@ -204,31 +204,6 @@ STATIC_DESTRUCTOR_REGISTER(arg_image, freep);
static int specifier_machine_id_safe(char specifier, const void *data, const char *root, const void *userdata, char **ret);
static int specifier_directory(char specifier, const void *data, const char *root, const void *userdata, char **ret);
-static const Specifier specifier_table[] = {
- { 'a', specifier_architecture, NULL },
- { 'b', specifier_boot_id, NULL },
- { 'B', specifier_os_build_id, NULL },
- { 'H', specifier_host_name, NULL },
- { 'l', specifier_short_host_name, NULL },
- { 'm', specifier_machine_id_safe, NULL },
- { 'o', specifier_os_id, NULL },
- { 'v', specifier_kernel_release, NULL },
- { 'w', specifier_os_version_id, NULL },
- { 'W', specifier_os_variant_id, NULL },
-
- { 'h', specifier_user_home, NULL },
-
- { 'C', specifier_directory, UINT_TO_PTR(DIRECTORY_CACHE) },
- { 'L', specifier_directory, UINT_TO_PTR(DIRECTORY_LOGS) },
- { 'S', specifier_directory, UINT_TO_PTR(DIRECTORY_STATE) },
- { 't', specifier_directory, UINT_TO_PTR(DIRECTORY_RUNTIME) },
-
- COMMON_CREDS_SPECIFIERS,
-
- COMMON_TMP_SPECIFIERS,
- {}
-};
-
static int specifier_machine_id_safe(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
int r;
@@ -2737,7 +2712,7 @@ static bool should_include_path(const char *path) {
return false;
}
-static int specifier_expansion_from_arg(Item *i) {
+static int specifier_expansion_from_arg(const Specifier *specifier_table, Item *i) {
int r;
assert(i);
@@ -2944,6 +2919,30 @@ static int parse_line(
assert(line >= 1);
assert(buffer);
+ const Specifier specifier_table[] = {
+ { 'a', specifier_architecture, NULL },
+ { 'b', specifier_boot_id, NULL },
+ { 'B', specifier_os_build_id, NULL },
+ { 'H', specifier_host_name, NULL },
+ { 'l', specifier_short_host_name, NULL },
+ { 'm', specifier_machine_id_safe, NULL },
+ { 'o', specifier_os_id, NULL },
+ { 'v', specifier_kernel_release, NULL },
+ { 'w', specifier_os_version_id, NULL },
+ { 'W', specifier_os_variant_id, NULL },
+
+ { 'h', specifier_user_home, NULL },
+
+ { 'C', specifier_directory, UINT_TO_PTR(DIRECTORY_CACHE) },
+ { 'L', specifier_directory, UINT_TO_PTR(DIRECTORY_LOGS) },
+ { 'S', specifier_directory, UINT_TO_PTR(DIRECTORY_STATE) },
+ { 't', specifier_directory, UINT_TO_PTR(DIRECTORY_RUNTIME) },
+
+ COMMON_CREDS_SPECIFIERS(arg_user ? UNIT_FILE_USER : UNIT_FILE_SYSTEM),
+ COMMON_TMP_SPECIFIERS,
+ {}
+ };
+
r = extract_many_words(
&buffer,
NULL,
@@ -3148,7 +3147,7 @@ static int parse_line(
if (!should_include_path(i.path))
return 0;
- r = specifier_expansion_from_arg(&i);
+ r = specifier_expansion_from_arg(specifier_table, &i);
if (r == -ENXIO)
return log_unresolvable_specifier(fname, line);
if (r < 0) {