chiark / gitweb /
mount: do not use -n when running in --user mode
[elogind.git] / src / core / load-fragment.c
index 786737da94bb7991e0fdc0704c72f686e8c1dc95..e9659ca344a7e95bd181388bddcee126f6cbf0a5 100644 (file)
 #include "bus-error.h"
 #include "errno-list.h"
 #include "af-list.h"
+#include "cap-list.h"
 
 #ifdef HAVE_SECCOMP
 #include "seccomp-util.h"
 #endif
 
-#if !defined(HAVE_SYSV_COMPAT) || !defined(HAVE_SECCOMP) || !defined(HAVE_PAM) || !defined(HAVE_SELINUX) || !defined(HAVE_SMACK) || !defined(HAVE_APPARMOR)
 int config_parse_warn_compat(
                 const char *unit,
                 const char *filename,
@@ -83,6 +83,10 @@ int config_parse_warn_compat(
                 log_syntax(unit, LOG_DEBUG, filename, line, EINVAL,
                            "Support for option %s= has been disabled at compile time and it is ignored", lvalue);
                 break;
+        case DISABLED_LEGACY:
+                log_syntax(unit, LOG_INFO, filename, line, EINVAL,
+                           "Support for option %s= has been removed and it is ignored", lvalue);
+                break;
         case DISABLED_EXPERIMENTAL:
                 log_syntax(unit, LOG_INFO, filename, line, EINVAL,
                            "Support for option %s= has not yet been enabled and it is ignored", lvalue);
@@ -91,7 +95,6 @@ int config_parse_warn_compat(
 
         return 0;
 }
-#endif
 
 int config_parse_unit_deps(const char *unit,
                            const char *filename,
@@ -535,8 +538,7 @@ int config_parse_exec(const char *unit,
 
         if (isempty(rvalue)) {
                 /* An empty assignment resets the list */
-                exec_command_free_list(*e);
-                *e = NULL;
+                *e = exec_command_free_list(*e);
                 return 0;
         }
 
@@ -545,9 +547,9 @@ int config_parse_exec(const char *unit,
          * overriding of argv[0]. */
         for (;;) {
                 int i;
-                const char *word, *state;
+                const char *word, *state, *reason;
                 size_t l;
-                bool honour_argv0 = false, ignore = false;
+                bool separate_argv0 = false, ignore = false;
 
                 path = NULL;
                 nce = NULL;
@@ -558,28 +560,23 @@ int config_parse_exec(const char *unit,
                 if (rvalue[0] == 0)
                         break;
 
-                for (i = 0; i < 2; i++) {
-                        if (rvalue[0] == '-' && !ignore) {
-                                ignore = true;
-                                rvalue ++;
-                        }
-
-                        if (rvalue[0] == '@' && !honour_argv0) {
-                                honour_argv0 = true;
-                                rvalue ++;
-                        }
-                }
-
-                if (*rvalue != '/') {
-                        log_syntax(unit, LOG_ERR, filename, line, EINVAL,
-                                   "Executable path is not absolute, ignoring: %s", rvalue);
-                        return 0;
-                }
-
                 k = 0;
                 FOREACH_WORD_QUOTED(word, l, rvalue, state) {
-                        if (strneq(word, ";", MAX(l, 1U)))
-                                goto found;
+                        if (k == 0) {
+                                for (i = 0; i < 2; i++) {
+                                        if (*word == '-' && !ignore) {
+                                                ignore = true;
+                                                word ++;
+                                        }
+
+                                        if (*word == '@' && !separate_argv0) {
+                                                separate_argv0 = true;
+                                                word ++;
+                                        }
+                                }
+                        } else
+                                if (strneq(word, ";", MAX(l, 1U)))
+                                        goto found;
 
                         k++;
                 }
@@ -590,58 +587,69 @@ int config_parse_exec(const char *unit,
                 }
 
         found:
-                n = new(char*, k + !honour_argv0);
+                n = new(char*, k + !separate_argv0);
                 if (!n)
                         return log_oom();
 
                 k = 0;
                 FOREACH_WORD_QUOTED(word, l, rvalue, state) {
-                        if (strneq(word, ";", MAX(l, 1U)))
-                                break;
-                        else if (strneq(word, "\\;", MAX(l, 1U)))
-                                word ++;
+                        char *c;
+                        unsigned skip;
 
-                        if (honour_argv0 && word == rvalue) {
-                                assert(!path);
+                        if (separate_argv0 ? path == NULL : k == 0) {
+                                /* first word, very special */
+                                skip = separate_argv0 + ignore;
 
-                                path = strndup(word, l);
-                                if (!path) {
-                                        r = log_oom();
-                                        goto fail;
-                                }
+                                /* skip special chars in the beginning */
+                                assert(skip < l);
 
-                                if (!utf8_is_valid(path)) {
-                                        log_invalid_utf8(unit, LOG_ERR, filename, line, EINVAL, rvalue);
-                                        r = 0;
-                                        goto fail;
-                                }
+                        } else if (strneq(word, ";", MAX(l, 1U)))
+                                /* new commandline */
+                                break;
 
-                        } else {
-                                char *c;
+                        else
+                                skip = strneq(word, "\\;", MAX(l, 1U));
 
-                                c = n[k++] = cunescape_length(word, l);
-                                if (!c) {
-                                        r = log_oom();
-                                        goto fail;
-                                }
+                        c = cunescape_length(word + skip, l - skip);
+                        if (!c) {
+                                r = log_oom();
+                                goto fail;
+                        }
 
-                                if (!utf8_is_valid(c)) {
-                                        log_invalid_utf8(unit, LOG_ERR, filename, line, EINVAL, rvalue);
-                                        r = 0;
-                                        goto fail;
-                                }
+                        if (!utf8_is_valid(c)) {
+                                log_invalid_utf8(unit, LOG_ERR, filename, line, EINVAL, rvalue);
+                                r = 0;
+                                goto fail;
                         }
+
+                        /* where to stuff this? */
+                        if (separate_argv0 && path == NULL)
+                                path = c;
+                        else
+                                n[k++] = c;
                 }
 
                 n[k] = NULL;
 
-                if (!n[0]) {
-                        log_syntax(unit, LOG_ERR, filename, line, EINVAL,
-                                   "Invalid command line, ignoring: %s", rvalue);
-                        r = 0;
-                        goto fail;
-                }
+                log_debug("path: %s", path ?: n[0]);
 
+                if (!n[0])
+                        reason = "Empty executable name or zeroeth argument";
+                else if (!string_is_safe(path ?: n[0]))
+                        reason = "Executable path contains special characters";
+                else if (!path_is_absolute(path ?: n[0]))
+                        reason = "Executable path is not absolute";
+                else if (endswith(path ?: n[0], "/"))
+                        reason = "Executable path specifies a directory";
+                else
+                        goto ok;
+
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                           "%s, ignoring: %s", reason, rvalue);
+                r = 0;
+                goto fail;
+
+ok:
                 if (!path) {
                         path = strdup(n[0]);
                         if (!path) {
@@ -650,8 +658,6 @@ int config_parse_exec(const char *unit,
                         }
                 }
 
-                assert(path_is_absolute(path));
-
                 nce = new0(ExecCommand, 1);
                 if (!nce) {
                         r = log_oom();
@@ -1038,17 +1044,15 @@ int config_parse_bounding_set(const char *unit,
 
         FOREACH_WORD_QUOTED(word, l, rvalue, state) {
                 _cleanup_free_ char *t = NULL;
-                int r;
-                cap_value_t cap;
+                int cap;
 
                 t = strndup(word, l);
                 if (!t)
                         return log_oom();
 
-                r = cap_from_name(t, &cap);
-                if (r < 0) {
-                        log_syntax(unit, LOG_ERR, filename, line, errno,
-                                   "Failed to parse capability in bounding set, ignoring: %s", t);
+                cap = capability_from_name(t);
+                if (cap < 0) {
+                        log_syntax(unit, LOG_ERR, filename, line, errno, "Failed to parse capability in bounding set, ignoring: %s", t);
                         continue;
                 }
 
@@ -2040,8 +2044,7 @@ int config_parse_unit_condition_path(
 
         if (isempty(rvalue)) {
                 /* Empty assignment resets the list */
-                condition_free_list(*list);
-                *list = NULL;
+                *list = condition_free_list(*list);
                 return 0;
         }
 
@@ -2098,8 +2101,7 @@ int config_parse_unit_condition_string(
 
         if (isempty(rvalue)) {
                 /* Empty assignment resets the list */
-                condition_free_list(*list);
-                *list = NULL;
+                *list = condition_free_list(*list);
                 return 0;
         }
 
@@ -2148,8 +2150,7 @@ int config_parse_unit_condition_null(
 
         if (isempty(rvalue)) {
                 /* Empty assignment resets the list */
-                condition_free_list(*list);
-                *list = NULL;
+                *list = condition_free_list(*list);
                 return 0;
         }
 
@@ -3065,7 +3066,7 @@ int config_parse_runtime_directory(
                 if (!n)
                         return log_oom();
 
-                if (!filename_is_safe(n)) {
+                if (!filename_is_valid(n)) {
                         log_syntax(unit, LOG_ERR, filename, line, EINVAL,
                                    "Runtime directory is not valid, ignoring assignment: %s", rvalue);
                         continue;
@@ -3585,7 +3586,7 @@ int unit_load_fragment(Unit *u) {
                 return r;
 
         /* Try to find an alias we can load this with */
-        if (u->load_state == UNIT_STUB)
+        if (u->load_state == UNIT_STUB) {
                 SET_FOREACH(t, u->names, i) {
 
                         if (t == u->id)
@@ -3598,6 +3599,7 @@ int unit_load_fragment(Unit *u) {
                         if (u->load_state != UNIT_STUB)
                                 break;
                 }
+        }
 
         /* And now, try looking for it under the suggested (originally linked) path */
         if (u->load_state == UNIT_STUB && u->fragment_path) {
@@ -3627,7 +3629,7 @@ int unit_load_fragment(Unit *u) {
                 if (r < 0)
                         return r;
 
-                if (u->load_state == UNIT_STUB)
+                if (u->load_state == UNIT_STUB) {
                         SET_FOREACH(t, u->names, i) {
                                 _cleanup_free_ char *z = NULL;
 
@@ -3645,6 +3647,7 @@ int unit_load_fragment(Unit *u) {
                                 if (u->load_state != UNIT_STUB)
                                         break;
                         }
+                }
         }
 
         return 0;