core: support specifier expansion in PassEnvironment=
authorLennart Poettering <lennart@poettering.net>
Tue, 12 Sep 2017 17:48:29 +0000 (19:48 +0200)
committerLennart Poettering <lennart@poettering.net>
Thu, 14 Sep 2017 13:17:40 +0000 (15:17 +0200)
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
src/core/load-fragment.c

index 2bcdd33..9515224 100644 (file)
@@ -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;
 
index 14fd11f..696b417 100644 (file)
@@ -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) {