]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
systemctl: refuse to edit masked units (#8602)
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 28 Mar 2018 15:25:04 +0000 (17:25 +0200)
committerLennart Poettering <lennart@poettering.net>
Wed, 28 Mar 2018 15:25:04 +0000 (17:25 +0200)
Note: in check_triggering_units 'path' will be allocated twice. This is a
conscious choice, this way the implementation is simpler and not worth
optimizing.

Fixes #8519.

src/systemctl/systemctl.c

index 42fbb35541bbfd6663dfa1b07ce82e51ed96ad0d..9bad0362e1d92f30c7d3df926e30e39d76f7d74a 100644 (file)
@@ -2657,23 +2657,12 @@ static int get_state_one_unit(sd_bus *bus, const char *name, UnitActiveState *ac
         return 0;
 }
 
-static int check_triggering_units(
-                sd_bus *bus,
-                const char *name) {
-
+static int unit_is_masked(sd_bus *bus, const char *name) {
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
-        _cleanup_free_ char *path = NULL, *n = NULL, *load_state = NULL;
-        _cleanup_strv_free_ char **triggered_by = NULL;
-        bool print_warning_label = true;
-        UnitActiveState active_state;
-        char **i;
+        _cleanup_free_ char *path = NULL, *load_state = NULL;
         int r;
 
-        r = unit_name_mangle(name, 0, &n);
-        if (r < 0)
-                return log_error_errno(r, "Failed to mangle unit name: %m");
-
-        path = unit_dbus_path_from_name(n);
+        path = unit_dbus_path_from_name(name);
         if (!path)
                 return log_oom();
 
@@ -2686,10 +2675,31 @@ static int check_triggering_units(
                         &error,
                         &load_state);
         if (r < 0)
-                return log_error_errno(r, "Failed to get load state of %s: %s", n, bus_error_message(&error, r));
+                return log_error_errno(r, "Failed to get load state of %s: %s", name, bus_error_message(&error, r));
 
-        if (streq(load_state, "masked"))
-                return 0;
+        return streq(load_state, "masked");
+}
+
+static int check_triggering_units(sd_bus *bus, const char *name) {
+        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+        _cleanup_free_ char *n = NULL, *path = NULL;
+        _cleanup_strv_free_ char **triggered_by = NULL;
+        bool print_warning_label = true;
+        UnitActiveState active_state;
+        char **i;
+        int r;
+
+        r = unit_name_mangle(name, 0, &n);
+        if (r < 0)
+                return log_error_errno(r, "Failed to mangle unit name: %m");
+
+        r = unit_is_masked(bus, n);
+        if (r != 0)
+                return r < 0 ? r : 0;
+
+        path = unit_dbus_path_from_name(n);
+        if (!path)
+                return log_oom();
 
         r = sd_bus_get_property_strv(
                         bus,
@@ -6972,6 +6982,17 @@ static int edit(int argc, char *argv[], void *userdata) {
         if (r < 0)
                 return log_error_errno(r, "Failed to expand names: %m");
 
+        STRV_FOREACH(tmp, names) {
+                r = unit_is_masked(bus, *tmp);
+                if (r < 0)
+                        return r;
+
+                if (r > 0) {
+                        log_error("Cannot edit %s: unit is masked.", *tmp);
+                        return -EINVAL;
+                }
+        }
+
         r = find_paths_to_edit(bus, names, &paths);
         if (r < 0)
                 return r;
@@ -6984,8 +7005,8 @@ static int edit(int argc, char *argv[], void *userdata) {
                 goto end;
 
         STRV_FOREACH_PAIR(original, tmp, paths) {
-                /* If the temporary file is empty we ignore it.  It's
-                 * useful if the user wants to cancel its modification
+                /* If the temporary file is empty we ignore it.
+                 * This allows the user to cancel the modification.
                  */
                 if (null_or_empty_path(*tmp)) {
                         log_warning("Editing \"%s\" canceled: temporary file is empty.", *original);