From 41de9cc29ecb0357c6236691c47eb0cf15d2ebd8 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 12 Sep 2017 19:48:29 +0200 Subject: [PATCH] core: support specifier expansion in PassEnvironment= I can't come up with any usecase for this, but let's add this here, to match what we support for Environment=. It's kind surprising if we support specifier expansion for some environment related settings, but not for others. --- src/core/dbus-execute.c | 13 +++++++++---- src/core/load-fragment.c | 28 +++++++++++++++++++++------- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c index 2bcdd33..9515224 100644 --- a/src/core/dbus-execute.c +++ b/src/core/dbus-execute.c @@ -2000,13 +2000,17 @@ int bus_exec_context_set_transient_property( } else if (streq(name, "PassEnvironment")) { - _cleanup_strv_free_ char **l = NULL; + _cleanup_strv_free_ char **l = NULL, **q = NULL; r = sd_bus_message_read_strv(message, &l); if (r < 0) return r; - if (!strv_env_name_is_valid(l)) + r = unit_full_printf_strv(u, l, &q); + if (r < 0) + return r; + + if (!strv_env_name_is_valid(q)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid PassEnvironment= block."); if (mode != UNIT_CHECK) { @@ -2016,11 +2020,12 @@ int bus_exec_context_set_transient_property( } else { _cleanup_free_ char *joined = NULL; - r = strv_extend_strv(&c->pass_environment, l, true); + r = strv_extend_strv(&c->pass_environment, q, true); if (r < 0) return r; - joined = strv_join_quoted(c->pass_environment); + /* We write just the new settings out to file, with unresolved specifiers. */ + joined = strv_join_quoted(l); if (!joined) return -ENOMEM; diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index 14fd11f..696b417 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -2189,9 +2189,10 @@ int config_parse_pass_environ( void *userdata) { const char *whole_rvalue = rvalue; - char*** passenv = data; _cleanup_strv_free_ char **n = NULL; size_t nlen = 0, nbufsize = 0; + char*** passenv = data; + Unit *u = userdata; int r; assert(filename); @@ -2206,7 +2207,7 @@ int config_parse_pass_environ( } for (;;) { - _cleanup_free_ char *word = NULL; + _cleanup_free_ char *word = NULL, *k = NULL; r = extract_first_word(&rvalue, &word, NULL, EXTRACT_QUOTES); if (r == 0) @@ -2219,17 +2220,30 @@ int config_parse_pass_environ( break; } - if (!env_name_is_valid(word)) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Invalid environment name for %s, ignoring: %s", lvalue, word); + if (u) { + r = unit_full_printf(u, word, &k); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, + "Failed to resolve specifiers, ignoring: %s", word); + continue; + } + } else { + k = word; + word = NULL; + } + + if (!env_name_is_valid(k)) { + log_syntax(unit, LOG_ERR, filename, line, 0, + "Invalid environment name for %s, ignoring: %s", lvalue, k); continue; } if (!GREEDY_REALLOC(n, nbufsize, nlen + 2)) return log_oom(); - n[nlen++] = word; + + n[nlen++] = k; n[nlen] = NULL; - word = NULL; + k = NULL; } if (n) { -- 2.7.4