From 43b9b2053c68c0bd95fb73430349e970b41beec3 Mon Sep 17 00:00:00 2001 From: Frantisek Sumsal Date: Thu, 17 Mar 2022 16:31:07 +0100 Subject: [PATCH] core: add %d specifier for the $CREDENTIALS_DIRECTORY Resolves: #22549 --- man/systemd.unit.xml | 5 +++++ src/core/unit-printf.c | 16 ++++++++++++++++ src/test/test-execute.c | 1 + .../exec-specifier-credentials-dir.service | 12 ++++++++++++ test/test-execute/exec-specifier.service | 1 + 5 files changed, 35 insertions(+) create mode 100644 test/test-execute/exec-specifier-credentials-dir.service diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index 8f2f6497470..c0c98a0e88a 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -1975,6 +1975,11 @@ Cache directory root This is either /var/cache (for the system manager) or the path $XDG_CACHE_HOME resolves to (for user managers). + + %d + Credentials directory + This is the value of the $CREDENTIALS_DIRECTORY environment variable if available. See section "Credentials" in systemd.exec5 for more information. + %E Configuration directory root diff --git a/src/core/unit-printf.c b/src/core/unit-printf.c index 7b23c6662f3..4a86a3c0d6c 100644 --- a/src/core/unit-printf.c +++ b/src/core/unit-printf.c @@ -148,6 +148,20 @@ static int specifier_special_directory(char specifier, const void *data, const c return 0; } +static int specifier_credentials_dir(char specifier, const void *data, const char *root, const void *userdata, char **ret) { + const Unit *u = ASSERT_PTR(userdata); + char *d; + + assert(ret); + + d = strjoin(u->manager->prefix[EXEC_DIRECTORY_RUNTIME], "/credentials/", u->id); + if (!d) + return -ENOMEM; + + *ret = d; + return 0; +} + int unit_name_printf(const Unit *u, const char* format, char **ret) { /* * This will use the passed string as format string and replace the following specifiers (which should all be @@ -191,6 +205,7 @@ int unit_full_printf_full(const Unit *u, const char *format, size_t max_length, * %R: the root of this systemd's instance tree (deprecated) * * %C: the cache directory root (e.g. /var/cache or $XDG_CACHE_HOME) + * %d: the credentials directory ($CREDENTIALS_DIRECTORY) * %E: the configuration directory root (e.g. /etc or $XDG_CONFIG_HOME) * %L: the log directory root (e.g. /var/log or $XDG_CONFIG_HOME/log) * %S: the state directory root (e.g. /var/lib or $XDG_CONFIG_HOME) @@ -227,6 +242,7 @@ int unit_full_printf_full(const Unit *u, const char *format, size_t max_length, { 'R', specifier_cgroup_root, NULL }, { 'C', specifier_special_directory, UINT_TO_PTR(EXEC_DIRECTORY_CACHE) }, + { 'd', specifier_credentials_dir, NULL }, { 'E', specifier_special_directory, UINT_TO_PTR(EXEC_DIRECTORY_CONFIGURATION) }, { 'L', specifier_special_directory, UINT_TO_PTR(EXEC_DIRECTORY_LOGS) }, { 'S', specifier_special_directory, UINT_TO_PTR(EXEC_DIRECTORY_STATE) }, diff --git a/src/test/test-execute.c b/src/test/test-execute.c index 49629c6bc25..8e18bbdb013 100644 --- a/src/test/test-execute.c +++ b/src/test/test-execute.c @@ -1086,6 +1086,7 @@ static void test_exec_specifier(Manager *m) { test(m, "exec-specifier.service", 0, CLD_EXITED); test(m, "exec-specifier@foo-bar.service", 0, CLD_EXITED); test(m, "exec-specifier-interpolation.service", 0, CLD_EXITED); + test(m, "exec-specifier-credentials-dir.service", 0, CLD_EXITED); } static void test_exec_standardinput(Manager *m) { diff --git a/test/test-execute/exec-specifier-credentials-dir.service b/test/test-execute/exec-specifier-credentials-dir.service new file mode 100644 index 00000000000..818619acaa7 --- /dev/null +++ b/test/test-execute/exec-specifier-credentials-dir.service @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later +[Unit] +Description=Test for specifiers + +[Service] +Type=oneshot +Environment=TOP_SECRET=%d/very_top_secret +# Test if the specifier is resolved correctly both before and after LoadCredential= +ExecStart=test %d/very_top_secret = "${CREDENTIALS_DIRECTORY}/very_top_secret" +LoadCredential=very_top_secret +ExecStart=test %d/very_top_secret = "${CREDENTIALS_DIRECTORY}/very_top_secret" +ExecStart=sh -c 'test %d/very_top_secret = "$TOP_SECRET"' diff --git a/test/test-execute/exec-specifier.service b/test/test-execute/exec-specifier.service index 190ebe93e6e..ae8b2428bc8 100644 --- a/test/test-execute/exec-specifier.service +++ b/test/test-execute/exec-specifier.service @@ -20,6 +20,7 @@ ExecStart=test %L = /var/log ExecStart=test %E = /etc ExecStart=test %T = /tmp ExecStart=test %V = /var/tmp +ExecStart=test %d = %t/credentials/%n ExecStart=sh -c 'test %u = $$(id -un)' ExecStart=sh -c 'test %U = $$(id -u)' ExecStart=sh -c 'test %g = $$(id -gn)' -- 2.47.3