diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2022-03-09 22:29:19 +0100 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2022-03-29 16:17:56 +0200 |
commit | 172e9cc3ee3dcca288d04c744984a9a3b2a0d008 (patch) | |
tree | 146359ba4b1d7203810ae6a130bca8b046442502 /src/tmpfiles/tmpfiles.c | |
parent | shared/install: move scope into InstallContext (diff) | |
download | systemd-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.c | 53 |
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) { |