chiark / gitweb /
Move x-systemd-device.timeout handling from core to fstab-generator
[elogind.git] / src / core / dbus-manager.c
index 135d31465d0ad8b59829528ade1c84a84b38c92e..ffef0c7d05813b5c058eba116a3a92953c9df06f 100644 (file)
@@ -28,7 +28,7 @@
 #include "install.h"
 #include "selinux-access.h"
 #include "watchdog.h"
-#include "hwclock.h"
+#include "clock-util.h"
 #include "path-util.h"
 #include "virt.h"
 #include "architecture.h"
@@ -130,7 +130,7 @@ static int property_get_tainted(
         if (access("/proc/cgroups", F_OK) < 0)
                 e = stpcpy(e, "cgroups-missing:");
 
-        if (hwclock_is_localtime() > 0)
+        if (clock_is_localtime() > 0)
                 e = stpcpy(e, "local-hwclock:");
 
         /* remove the last ':' */
@@ -360,7 +360,7 @@ static int method_get_unit(sd_bus *bus, sd_bus_message *message, void *userdata,
         if (!u)
                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not loaded.", name);
 
-        r = selinux_unit_access_check(u, bus, message, "status", error);
+        r = selinux_unit_access_check(u, message, "status", error);
         if (r < 0)
                 return r;
 
@@ -404,7 +404,7 @@ static int method_get_unit_by_pid(sd_bus *bus, sd_bus_message *message, void *us
         if (!u)
                 return sd_bus_error_setf(error, BUS_ERROR_NO_UNIT_FOR_PID, "PID %u does not belong to any loaded unit.", pid);
 
-        r = selinux_unit_access_check(u, bus, message, "status", error);
+        r = selinux_unit_access_check(u, message, "status", error);
         if (r < 0)
                 return r;
 
@@ -434,7 +434,7 @@ static int method_load_unit(sd_bus *bus, sd_bus_message *message, void *userdata
         if (r < 0)
                 return r;
 
-        r = selinux_unit_access_check(u, bus, message, "status", error);
+        r = selinux_unit_access_check(u, message, "status", error);
         if (r < 0)
                 return r;
 
@@ -604,7 +604,7 @@ static int method_start_transient_unit(sd_bus *bus, sd_bus_message *message, voi
         if (mode < 0)
                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Job mode %s is invalid.", smode);
 
-        r = selinux_access_check(bus, message, "start", error);
+        r = selinux_access_check(message, "start", error);
         if (r < 0)
                 return r;
 
@@ -656,7 +656,7 @@ static int method_get_job(sd_bus *bus, sd_bus_message *message, void *userdata,
         if (!j)
                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
 
-        r = selinux_unit_access_check(j->unit, bus, message, "status", error);
+        r = selinux_unit_access_check(j->unit, message, "status", error);
         if (r < 0)
                 return r;
 
@@ -685,7 +685,7 @@ static int method_cancel_job(sd_bus *bus, sd_bus_message *message, void *userdat
         if (!j)
                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
 
-        r = selinux_unit_access_check(j->unit, bus, message, "stop", error);
+        r = selinux_unit_access_check(j->unit, message, "stop", error);
         if (r < 0)
                 return r;
 
@@ -702,7 +702,7 @@ static int method_clear_jobs(sd_bus *bus, sd_bus_message *message, void *userdat
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "reboot", error);
+        r = selinux_access_check(message, "reboot", error);
         if (r < 0)
                 return r;
 
@@ -719,7 +719,7 @@ static int method_reset_failed(sd_bus *bus, sd_bus_message *message, void *userd
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "reload", error);
+        r = selinux_access_check(message, "reload", error);
         if (r < 0)
                 return r;
 
@@ -728,7 +728,7 @@ static int method_reset_failed(sd_bus *bus, sd_bus_message *message, void *userd
         return sd_bus_reply_method_return(message, NULL);
 }
 
-static int method_list_units(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
+static int list_units_filtered(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error, char **states) {
         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
         Manager *m = userdata;
         const char *k;
@@ -740,7 +740,7 @@ static int method_list_units(sd_bus *bus, sd_bus_message *message, void *userdat
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "status", error);
+        r = selinux_access_check(message, "status", error);
         if (r < 0)
                 return r;
 
@@ -761,6 +761,12 @@ static int method_list_units(sd_bus *bus, sd_bus_message *message, void *userdat
 
                 following = unit_following(u);
 
+                if (!strv_isempty(states) &&
+                    !strv_contains(states, unit_load_state_to_string(u->load_state)) &&
+                    !strv_contains(states, unit_active_state_to_string(unit_active_state(u))) &&
+                    !strv_contains(states, unit_sub_state_to_string(u)))
+                        continue;
+
                 unit_path = unit_dbus_path(u);
                 if (!unit_path)
                         return -ENOMEM;
@@ -794,6 +800,21 @@ static int method_list_units(sd_bus *bus, sd_bus_message *message, void *userdat
         return sd_bus_send(bus, reply, NULL);
 }
 
+static int method_list_units(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
+        return list_units_filtered(bus, message, userdata, error, NULL);
+}
+
+static int method_list_units_filtered(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
+        _cleanup_strv_free_ char **states = NULL;
+        int r;
+
+        r = sd_bus_message_read_strv(message, &states);
+        if (r < 0)
+                return r;
+
+        return list_units_filtered(bus, message, userdata, error, states);
+}
+
 static int method_list_jobs(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
         Manager *m = userdata;
@@ -805,7 +826,7 @@ static int method_list_jobs(sd_bus *bus, sd_bus_message *message, void *userdata
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "status", error);
+        r = selinux_access_check(message, "status", error);
         if (r < 0)
                 return r;
 
@@ -855,7 +876,7 @@ static int method_subscribe(sd_bus *bus, sd_bus_message *message, void *userdata
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "status", error);
+        r = selinux_access_check(message, "status", error);
         if (r < 0)
                 return r;
 
@@ -888,7 +909,7 @@ static int method_unsubscribe(sd_bus *bus, sd_bus_message *message, void *userda
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "status", error);
+        r = selinux_access_check(message, "status", error);
         if (r < 0)
                 return r;
 
@@ -914,7 +935,7 @@ static int method_dump(sd_bus *bus, sd_bus_message *message, void *userdata, sd_
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "status", error);
+        r = selinux_access_check(message, "status", error);
         if (r < 0)
                 return r;
 
@@ -945,7 +966,7 @@ static int method_create_snapshot(sd_bus *bus, sd_bus_message *message, void *us
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "start", error);
+        r = selinux_access_check(message, "start", error);
         if (r < 0)
                 return r;
 
@@ -977,7 +998,7 @@ static int method_remove_snapshot(sd_bus *bus, sd_bus_message *message, void *us
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "stop", error);
+        r = selinux_access_check(message, "stop", error);
         if (r < 0)
                 return r;
 
@@ -1003,7 +1024,7 @@ static int method_reload(sd_bus *bus, sd_bus_message *message, void *userdata, s
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "reload", error);
+        r = selinux_access_check(message, "reload", error);
         if (r < 0)
                 return r;
 
@@ -1031,7 +1052,7 @@ static int method_reexecute(sd_bus *bus, sd_bus_message *message, void *userdata
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "reload", error);
+        r = selinux_access_check(message, "reload", error);
         if (r < 0)
                 return r;
 
@@ -1050,7 +1071,7 @@ static int method_exit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "halt", error);
+        r = selinux_access_check(message, "halt", error);
         if (r < 0)
                 return r;
 
@@ -1070,7 +1091,7 @@ static int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, s
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "reboot", error);
+        r = selinux_access_check(message, "reboot", error);
         if (r < 0)
                 return r;
 
@@ -1091,7 +1112,7 @@ static int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata,
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "halt", error);
+        r = selinux_access_check(message, "halt", error);
         if (r < 0)
                 return r;
 
@@ -1111,7 +1132,7 @@ static int method_halt(sd_bus *bus, sd_bus_message *message, void *userdata, sd_
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "halt", error);
+        r = selinux_access_check(message, "halt", error);
         if (r < 0)
                 return r;
 
@@ -1131,7 +1152,7 @@ static int method_kexec(sd_bus *bus, sd_bus_message *message, void *userdata, sd
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "reboot", error);
+        r = selinux_access_check(message, "reboot", error);
         if (r < 0)
                 return r;
 
@@ -1153,7 +1174,7 @@ static int method_switch_root(sd_bus *bus, sd_bus_message *message, void *userda
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "reboot", error);
+        r = selinux_access_check(message, "reboot", error);
         if (r < 0)
                 return r;
 
@@ -1170,7 +1191,7 @@ static int method_switch_root(sd_bus *bus, sd_bus_message *message, void *userda
         /* Safety check */
         if (isempty(init)) {
                 if (! path_is_os_tree(root))
-                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified switch root path %s does not seem to be an OS tree. /etc/os-release is missing.", root);
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified switch root path %s does not seem to be an OS tree. os-release file is missing.", root);
         } else {
                 _cleanup_free_ char *p = NULL;
 
@@ -1217,7 +1238,7 @@ static int method_set_environment(sd_bus *bus, sd_bus_message *message, void *us
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "reload", error);
+        r = selinux_access_check(message, "reload", error);
         if (r < 0)
                 return r;
 
@@ -1243,7 +1264,7 @@ static int method_unset_environment(sd_bus *bus, sd_bus_message *message, void *
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "reload", error);
+        r = selinux_access_check(message, "reload", error);
         if (r < 0)
                 return r;
 
@@ -1270,7 +1291,7 @@ static int method_unset_and_set_environment(sd_bus *bus, sd_bus_message *message
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "reload", error);
+        r = selinux_access_check(message, "reload", error);
         if (r < 0)
                 return r;
 
@@ -1306,7 +1327,7 @@ static int method_list_unit_files(sd_bus *bus, sd_bus_message *message, void *us
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "status", error);
+        r = selinux_access_check(message, "status", error);
         if (r < 0)
                 return r;
 
@@ -1357,7 +1378,7 @@ static int method_get_unit_file_state(sd_bus *bus, sd_bus_message *message, void
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "status", error);
+        r = selinux_access_check(message, "status", error);
         if (r < 0)
                 return r;
 
@@ -1384,7 +1405,7 @@ static int method_get_default_target(sd_bus *bus, sd_bus_message *message, void
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "status", error);
+        r = selinux_access_check(message, "status", error);
         if (r < 0)
                 return r;
 
@@ -1466,8 +1487,8 @@ fail:
 static int method_enable_unit_files_generic(
                 sd_bus *bus,
                 sd_bus_message *message,
-                Manager *m, const
-                char *verb,
+                Manager *m,
+                const char *verb,
                 int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes),
                 bool carries_install_info,
                 sd_bus_error *error) {
@@ -1489,23 +1510,23 @@ static int method_enable_unit_files_generic(
         if (r < 0)
                 return r;
 
+        r = sd_bus_message_read(message, "bb", &runtime, &force);
+        if (r < 0)
+                return r;
+
 #ifdef HAVE_SELINUX
         STRV_FOREACH(i, l) {
                 Unit *u;
 
                 u = manager_get_unit(m, *i);
                 if (u) {
-                        r = selinux_unit_access_check(u, bus, message, verb, error);
+                        r = selinux_unit_access_check(u, message, verb, error);
                         if (r < 0)
                                 return r;
                 }
         }
 #endif
 
-        r = sd_bus_message_read(message, "bb", &runtime, &force);
-        if (r < 0)
-                return r;
-
         scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
 
         r = call(scope, runtime, NULL, l, force, &changes, &n_changes);
@@ -1527,14 +1548,74 @@ static int method_link_unit_files(sd_bus *bus, sd_bus_message *message, void *us
         return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_link, false, error);
 }
 
+static int unit_file_preset_without_mode(UnitFileScope scope, bool runtime, const char *root_dir, char **files, bool force, UnitFileChange **changes, unsigned *n_changes) {
+        return unit_file_preset(scope, runtime, root_dir, files, UNIT_FILE_PRESET_FULL, force, changes, n_changes);
+}
+
 static int method_preset_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
-        return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_preset, true, error);
+        return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_preset_without_mode, true, error);
 }
 
 static int method_mask_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
         return method_enable_unit_files_generic(bus, message, userdata, "disable", unit_file_mask, false, error);
 }
 
+static int method_preset_unit_files_with_mode(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
+
+        _cleanup_strv_free_ char **l = NULL;
+#ifdef HAVE_SELINUX
+        char **i;
+#endif
+        UnitFileChange *changes = NULL;
+        unsigned n_changes = 0;
+        Manager *m = userdata;
+        UnitFilePresetMode mm;
+        UnitFileScope scope;
+        int runtime, force, r;
+        const char *mode;
+
+        assert(bus);
+        assert(message);
+        assert(m);
+
+        r = sd_bus_message_read_strv(message, &l);
+        if (r < 0)
+                return r;
+
+        r = sd_bus_message_read(message, "sbb", &mode, &runtime, &force);
+        if (r < 0)
+                return r;
+
+        if (isempty(mode))
+                mm = UNIT_FILE_PRESET_FULL;
+        else {
+                mm = unit_file_preset_mode_from_string(mode);
+                if (mm < 0)
+                        return -EINVAL;
+        }
+
+#ifdef HAVE_SELINUX
+        STRV_FOREACH(i, l) {
+                Unit *u;
+
+                u = manager_get_unit(m, *i);
+                if (u) {
+                        r = selinux_unit_access_check(u, message, "enable", error);
+                        if (r < 0)
+                                return r;
+                }
+        }
+#endif
+
+        scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
+
+        r = unit_file_preset(scope, runtime, NULL, l, mm, force, &changes, &n_changes);
+        if (r < 0)
+                return r;
+
+        return reply_unit_file_changes_and_free(m, bus, message, r, changes, n_changes);
+}
+
 static int method_disable_unit_files_generic(
                 sd_bus *bus,
                 sd_bus_message *message,
@@ -1553,7 +1634,7 @@ static int method_disable_unit_files_generic(
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, verb, error);
+        r = selinux_access_check(message, verb, error);
         if (r < 0)
                 return r;
 
@@ -1594,7 +1675,7 @@ static int method_set_default_target(sd_bus *bus, sd_bus_message *message, void
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "enable", error);
+        r = selinux_access_check(message, "enable", error);
         if (r < 0)
                 return r;
 
@@ -1611,6 +1692,44 @@ static int method_set_default_target(sd_bus *bus, sd_bus_message *message, void
         return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
 }
 
+static int method_preset_all_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
+        UnitFileChange *changes = NULL;
+        unsigned n_changes = 0;
+        Manager *m = userdata;
+        UnitFilePresetMode mm;
+        UnitFileScope scope;
+        const char *mode;
+        int force, runtime, r;
+
+        assert(bus);
+        assert(message);
+        assert(m);
+
+        r = selinux_access_check(message, "enable", error);
+        if (r < 0)
+                return r;
+
+        r = sd_bus_message_read(message, "sbb", &mode, &runtime, &force);
+        if (r < 0)
+                return r;
+
+        if (isempty(mode))
+                mm = UNIT_FILE_PRESET_FULL;
+        else {
+                mm = unit_file_preset_mode_from_string(mode);
+                if (mm < 0)
+                        return -EINVAL;
+        }
+
+        scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
+
+        r = unit_file_preset_all(scope, runtime, NULL, mm, force, &changes, &n_changes);
+        if (r < 0)
+                return r;
+
+        return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
+}
+
 const sd_bus_vtable bus_manager_vtable[] = {
         SD_BUS_VTABLE_START(0),
 
@@ -1670,6 +1789,7 @@ const sd_bus_vtable bus_manager_vtable[] = {
         SD_BUS_METHOD("ClearJobs", NULL, NULL, method_clear_jobs, 0),
         SD_BUS_METHOD("ResetFailed", NULL, NULL, method_reset_failed, 0),
         SD_BUS_METHOD("ListUnits", NULL, "a(ssssssouso)", method_list_units, SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("ListUnitsFiltered", "as", "a(ssssssouso)", method_list_units_filtered, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("ListJobs", NULL, "a(usssoo)", method_list_jobs, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("Subscribe", NULL, NULL, method_subscribe, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("Unsubscribe", NULL, NULL, method_unsubscribe, SD_BUS_VTABLE_UNPRIVILEGED),
@@ -1694,10 +1814,12 @@ const sd_bus_vtable bus_manager_vtable[] = {
         SD_BUS_METHOD("ReenableUnitFiles", "asbb", "ba(sss)", method_reenable_unit_files, 0),
         SD_BUS_METHOD("LinkUnitFiles", "asbb", "a(sss)", method_link_unit_files, 0),
         SD_BUS_METHOD("PresetUnitFiles", "asbb", "ba(sss)", method_preset_unit_files, 0),
+        SD_BUS_METHOD("PresetUnitFilesWithMode", "assbb", "ba(sss)", method_preset_unit_files_with_mode, 0),
         SD_BUS_METHOD("MaskUnitFiles", "asbb", "a(sss)", method_mask_unit_files, 0),
         SD_BUS_METHOD("UnmaskUnitFiles", "asb", "a(sss)", method_unmask_unit_files, 0),
         SD_BUS_METHOD("SetDefaultTarget", "sb", "a(sss)", method_set_default_target, 0),
         SD_BUS_METHOD("GetDefaultTarget", NULL, "s", method_get_default_target, SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("PresetAllUnitFiles", "sbb", "a(sss)", method_preset_all_unit_files, 0),
 
         SD_BUS_SIGNAL("UnitNew", "so", 0),
         SD_BUS_SIGNAL("UnitRemoved", "so", 0),