Merge pull request #15473 from keszybz/bus-introspection
This commit is contained in:
@@ -1133,7 +1133,6 @@ const UnitVTable automount_vtable = {
|
||||
|
||||
.reset_failed = automount_reset_failed,
|
||||
|
||||
.bus_vtable = bus_automount_vtable,
|
||||
.bus_set_property = bus_automount_set_property,
|
||||
|
||||
.shutdown = automount_shutdown,
|
||||
|
||||
@@ -140,6 +140,58 @@ const sd_bus_vtable bus_job_vtable[] = {
|
||||
SD_BUS_VTABLE_END
|
||||
};
|
||||
|
||||
static int bus_job_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
|
||||
Manager *m = userdata;
|
||||
Job *j;
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
assert(path);
|
||||
assert(interface);
|
||||
assert(found);
|
||||
assert(m);
|
||||
|
||||
r = manager_get_job_from_dbus_path(m, path, &j);
|
||||
if (r < 0)
|
||||
return 0;
|
||||
|
||||
*found = j;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int bus_job_enumerate(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
Manager *m = userdata;
|
||||
unsigned k = 0;
|
||||
Iterator i;
|
||||
Job *j;
|
||||
|
||||
l = new0(char*, hashmap_size(m->jobs)+1);
|
||||
if (!l)
|
||||
return -ENOMEM;
|
||||
|
||||
HASHMAP_FOREACH(j, m->jobs, i) {
|
||||
l[k] = job_dbus_path(j);
|
||||
if (!l[k])
|
||||
return -ENOMEM;
|
||||
|
||||
k++;
|
||||
}
|
||||
|
||||
assert(hashmap_size(m->jobs) == k);
|
||||
|
||||
*nodes = TAKE_PTR(l);
|
||||
|
||||
return k;
|
||||
}
|
||||
|
||||
const BusObjectImplementation job_object = {
|
||||
"/org/freedesktop/systemd1/job",
|
||||
"org.freedesktop.systemd1.Job",
|
||||
.fallback_vtables = BUS_FALLBACK_VTABLES({bus_job_vtable, bus_job_find}),
|
||||
.node_enumerator = bus_job_enumerate,
|
||||
};
|
||||
|
||||
static int send_new_signal(sd_bus *bus, void *userdata) {
|
||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
|
||||
_cleanup_free_ char *p = NULL;
|
||||
|
||||
+2
-1
@@ -2,11 +2,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "sd-bus.h"
|
||||
#include "sd-bus-vtable.h"
|
||||
|
||||
#include "unit.h"
|
||||
#include "bus-util.h"
|
||||
|
||||
extern const sd_bus_vtable bus_job_vtable[];
|
||||
extern const BusObjectImplementation job_object;
|
||||
|
||||
int bus_job_method_cancel(sd_bus_message *message, void *job, sd_bus_error *error);
|
||||
int bus_job_method_get_waiting_jobs(sd_bus_message *message, void *userdata, sd_bus_error *error);
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "sd-bus.h"
|
||||
#include "sd-bus-vtable.h"
|
||||
|
||||
#include "unit.h"
|
||||
|
||||
|
||||
+143
-101
@@ -274,25 +274,6 @@ static int mac_selinux_filter(sd_bus_message *message, void *userdata, sd_bus_er
|
||||
}
|
||||
#endif
|
||||
|
||||
static int bus_job_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
|
||||
Manager *m = userdata;
|
||||
Job *j;
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
assert(path);
|
||||
assert(interface);
|
||||
assert(found);
|
||||
assert(m);
|
||||
|
||||
r = manager_get_job_from_dbus_path(m, path, &j);
|
||||
if (r < 0)
|
||||
return 0;
|
||||
|
||||
*found = j;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int find_unit(Manager *m, sd_bus *bus, const char *path, Unit **unit, sd_bus_error *error) {
|
||||
Unit *u = NULL; /* just to appease gcc, initialization is not really necessary */
|
||||
int r;
|
||||
@@ -472,32 +453,6 @@ static int bus_kill_context_find(sd_bus *bus, const char *path, const char *inte
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int bus_job_enumerate(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
Manager *m = userdata;
|
||||
unsigned k = 0;
|
||||
Iterator i;
|
||||
Job *j;
|
||||
|
||||
l = new0(char*, hashmap_size(m->jobs)+1);
|
||||
if (!l)
|
||||
return -ENOMEM;
|
||||
|
||||
HASHMAP_FOREACH(j, m->jobs, i) {
|
||||
l[k] = job_dbus_path(j);
|
||||
if (!l[k])
|
||||
return -ENOMEM;
|
||||
|
||||
k++;
|
||||
}
|
||||
|
||||
assert(hashmap_size(m->jobs) == k);
|
||||
|
||||
*nodes = TAKE_PTR(l);
|
||||
|
||||
return k;
|
||||
}
|
||||
|
||||
static int bus_unit_enumerate(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
Manager *m = userdata;
|
||||
@@ -522,8 +477,147 @@ static int bus_unit_enumerate(sd_bus *bus, const char *path, void *userdata, cha
|
||||
return k;
|
||||
}
|
||||
|
||||
static const BusObjectImplementation unit_object = {
|
||||
"/org/freedesktop/systemd1/unit",
|
||||
"org.freedesktop.systemd1.Unit",
|
||||
.fallback_vtables = BUS_FALLBACK_VTABLES(
|
||||
{ bus_unit_vtable, bus_unit_find }),
|
||||
.node_enumerator = bus_unit_enumerate,
|
||||
};
|
||||
|
||||
static const BusObjectImplementation bus_automount_object = {
|
||||
"/org/freedesktop/systemd1/unit",
|
||||
"org.freedesktop.systemd1.Automount",
|
||||
.fallback_vtables = BUS_FALLBACK_VTABLES(
|
||||
{ bus_automount_vtable, bus_unit_interface_find }),
|
||||
};
|
||||
|
||||
static const BusObjectImplementation bus_device_object = {
|
||||
"/org/freedesktop/systemd1/unit",
|
||||
"org.freedesktop.systemd1.Device",
|
||||
.fallback_vtables = BUS_FALLBACK_VTABLES(
|
||||
{ bus_device_vtable, bus_unit_interface_find }),
|
||||
};
|
||||
|
||||
static const BusObjectImplementation bus_mount_object = {
|
||||
"/org/freedesktop/systemd1/unit",
|
||||
"org.freedesktop.systemd1.Mount",
|
||||
.fallback_vtables = BUS_FALLBACK_VTABLES(
|
||||
{ bus_mount_vtable, bus_unit_interface_find },
|
||||
{ bus_unit_cgroup_vtable, bus_unit_cgroup_find },
|
||||
{ bus_cgroup_vtable, bus_cgroup_context_find },
|
||||
{ bus_exec_vtable, bus_exec_context_find },
|
||||
{ bus_kill_vtable, bus_kill_context_find }),
|
||||
};
|
||||
|
||||
static const BusObjectImplementation bus_path_object = {
|
||||
"/org/freedesktop/systemd1/unit",
|
||||
"org.freedesktop.systemd1.Path",
|
||||
.fallback_vtables = BUS_FALLBACK_VTABLES(
|
||||
{ bus_path_vtable, bus_unit_interface_find }),
|
||||
};
|
||||
|
||||
static const BusObjectImplementation bus_scope_object = {
|
||||
"/org/freedesktop/systemd1/unit",
|
||||
"org.freedesktop.systemd1.Scope",
|
||||
.fallback_vtables = BUS_FALLBACK_VTABLES(
|
||||
{ bus_scope_vtable, bus_unit_interface_find },
|
||||
{ bus_unit_cgroup_vtable, bus_unit_cgroup_find },
|
||||
{ bus_cgroup_vtable, bus_cgroup_context_find },
|
||||
{ bus_kill_vtable, bus_kill_context_find }),
|
||||
};
|
||||
|
||||
static const BusObjectImplementation bus_service_object = {
|
||||
"/org/freedesktop/systemd1/unit",
|
||||
"org.freedesktop.systemd1.Service",
|
||||
.fallback_vtables = BUS_FALLBACK_VTABLES(
|
||||
{ bus_service_vtable, bus_unit_interface_find },
|
||||
{ bus_unit_cgroup_vtable, bus_unit_cgroup_find },
|
||||
{ bus_cgroup_vtable, bus_cgroup_context_find },
|
||||
{ bus_exec_vtable, bus_exec_context_find },
|
||||
{ bus_kill_vtable, bus_kill_context_find }),
|
||||
};
|
||||
|
||||
static const BusObjectImplementation bus_slice_object = {
|
||||
"/org/freedesktop/systemd1/unit",
|
||||
"org.freedesktop.systemd1.Slice",
|
||||
.fallback_vtables = BUS_FALLBACK_VTABLES(
|
||||
{ bus_slice_vtable, bus_unit_interface_find },
|
||||
{ bus_unit_cgroup_vtable, bus_unit_cgroup_find },
|
||||
{ bus_cgroup_vtable, bus_cgroup_context_find }),
|
||||
};
|
||||
|
||||
static const BusObjectImplementation bus_socket_object = {
|
||||
"/org/freedesktop/systemd1/unit",
|
||||
"org.freedesktop.systemd1.Socket",
|
||||
.fallback_vtables = BUS_FALLBACK_VTABLES(
|
||||
{ bus_socket_vtable, bus_unit_interface_find },
|
||||
{ bus_unit_cgroup_vtable, bus_unit_cgroup_find },
|
||||
{ bus_cgroup_vtable, bus_cgroup_context_find },
|
||||
{ bus_exec_vtable, bus_exec_context_find },
|
||||
{ bus_kill_vtable, bus_kill_context_find }),
|
||||
};
|
||||
|
||||
static const BusObjectImplementation bus_swap_object = {
|
||||
"/org/freedesktop/systemd1/unit",
|
||||
"org.freedesktop.systemd1.Swap",
|
||||
.fallback_vtables = BUS_FALLBACK_VTABLES(
|
||||
{ bus_swap_vtable, bus_unit_interface_find },
|
||||
{ bus_unit_cgroup_vtable, bus_unit_cgroup_find },
|
||||
{ bus_cgroup_vtable, bus_cgroup_context_find },
|
||||
{ bus_exec_vtable, bus_exec_context_find },
|
||||
{ bus_kill_vtable, bus_kill_context_find }),
|
||||
};
|
||||
|
||||
static const BusObjectImplementation bus_target_object = {
|
||||
"/org/freedesktop/systemd1/unit",
|
||||
"org.freedesktop.systemd1.Target",
|
||||
.fallback_vtables = BUS_FALLBACK_VTABLES(
|
||||
{ bus_target_vtable, bus_unit_interface_find }),
|
||||
};
|
||||
|
||||
static const BusObjectImplementation bus_timer_object = {
|
||||
"/org/freedesktop/systemd1/unit",
|
||||
"org.freedesktop.systemd1.Timer",
|
||||
.fallback_vtables = BUS_FALLBACK_VTABLES(
|
||||
{ bus_timer_vtable, bus_unit_interface_find }),
|
||||
};
|
||||
|
||||
static const BusObjectImplementation bus_manager_object = {
|
||||
"/org/freedesktop/systemd1",
|
||||
"org.freedesktop.systemd1.Manager",
|
||||
.vtables = BUS_VTABLES(bus_manager_vtable),
|
||||
.children = BUS_IMPLEMENTATIONS(
|
||||
&job_object,
|
||||
&unit_object,
|
||||
&bus_automount_object,
|
||||
&bus_device_object,
|
||||
&bus_mount_object,
|
||||
&bus_path_object,
|
||||
&bus_scope_object,
|
||||
&bus_service_object,
|
||||
&bus_slice_object,
|
||||
&bus_socket_object,
|
||||
&bus_swap_object,
|
||||
&bus_target_object,
|
||||
&bus_timer_object),
|
||||
};
|
||||
|
||||
static const BusObjectImplementation manager_log_control_object = {
|
||||
"/org/freedesktop/LogControl1",
|
||||
"org.freedesktop.LogControl1",
|
||||
.vtables = BUS_VTABLES(bus_manager_log_control_vtable),
|
||||
};
|
||||
|
||||
int bus_manager_introspect_implementations(FILE *out, const char *pattern) {
|
||||
return bus_introspect_implementations(
|
||||
out,
|
||||
pattern,
|
||||
BUS_IMPLEMENTATIONS(&bus_manager_object,
|
||||
&manager_log_control_object));
|
||||
}
|
||||
|
||||
static int bus_setup_api_vtables(Manager *m, sd_bus *bus) {
|
||||
UnitType t;
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
@@ -535,63 +629,11 @@ static int bus_setup_api_vtables(Manager *m, sd_bus *bus) {
|
||||
return log_error_errno(r, "Failed to add SELinux access filter: %m");
|
||||
#endif
|
||||
|
||||
r = sd_bus_add_object_vtable(bus, NULL, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", bus_manager_vtable, m);
|
||||
r = bus_add_implementation(bus, &bus_manager_object, m);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to register Manager vtable: %m");
|
||||
return r;
|
||||
|
||||
r = sd_bus_add_object_vtable(bus, NULL, "/org/freedesktop/LogControl1", "org.freedesktop.LogControl1", bus_manager_log_control_vtable, m);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to register service API vtable: %m");
|
||||
|
||||
r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/job", "org.freedesktop.systemd1.Job", bus_job_vtable, bus_job_find, m);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to register Job vtable: %m");
|
||||
|
||||
r = sd_bus_add_node_enumerator(bus, NULL, "/org/freedesktop/systemd1/job", bus_job_enumerate, m);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to add job enumerator: %m");
|
||||
|
||||
r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", "org.freedesktop.systemd1.Unit", bus_unit_vtable, bus_unit_find, m);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to register Unit vtable: %m");
|
||||
|
||||
r = sd_bus_add_node_enumerator(bus, NULL, "/org/freedesktop/systemd1/unit", bus_unit_enumerate, m);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to add job enumerator: %m");
|
||||
|
||||
for (t = 0; t < _UNIT_TYPE_MAX; t++) {
|
||||
const char *interface;
|
||||
|
||||
assert_se(interface = unit_dbus_interface_from_type(t));
|
||||
|
||||
r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", interface, unit_vtable[t]->bus_vtable, bus_unit_interface_find, m);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to register type specific vtable for %s: %m", interface);
|
||||
|
||||
if (unit_vtable[t]->cgroup_context_offset > 0) {
|
||||
r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", interface, bus_unit_cgroup_vtable, bus_unit_cgroup_find, m);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to register control group unit vtable for %s: %m", interface);
|
||||
|
||||
r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", interface, bus_cgroup_vtable, bus_cgroup_context_find, m);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to register control group vtable for %s: %m", interface);
|
||||
}
|
||||
|
||||
if (unit_vtable[t]->exec_context_offset > 0) {
|
||||
r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", interface, bus_exec_vtable, bus_exec_context_find, m);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to register execute vtable for %s: %m", interface);
|
||||
}
|
||||
|
||||
if (unit_vtable[t]->kill_context_offset > 0) {
|
||||
r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", interface, bus_kill_vtable, bus_kill_context_find, m);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to register kill vtable for %s: %m", interface);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return bus_add_implementation(bus, &manager_log_control_object, m);
|
||||
}
|
||||
|
||||
static int bus_setup_disconnected_match(Manager *m, sd_bus *bus) {
|
||||
|
||||
@@ -33,3 +33,4 @@ int bus_forward_agent_released(Manager *m, const char *path);
|
||||
uint64_t manager_bus_n_queued_write(Manager *m);
|
||||
|
||||
void dump_bus_properties(FILE *f);
|
||||
int bus_manager_introspect_implementations(FILE *out, const char *pattern);
|
||||
|
||||
@@ -1081,8 +1081,6 @@ const UnitVTable device_vtable = {
|
||||
.active_state = device_active_state,
|
||||
.sub_state_to_string = device_sub_state_to_string,
|
||||
|
||||
.bus_vtable = bus_device_vtable,
|
||||
|
||||
.following = device_following,
|
||||
.following_set = device_following_set,
|
||||
|
||||
|
||||
+21
-2
@@ -93,8 +93,11 @@ static enum {
|
||||
ACTION_TEST,
|
||||
ACTION_DUMP_CONFIGURATION_ITEMS,
|
||||
ACTION_DUMP_BUS_PROPERTIES,
|
||||
ACTION_BUS_INTROSPECT,
|
||||
} arg_action = ACTION_RUN;
|
||||
|
||||
static const char *arg_bus_introspect = NULL;
|
||||
|
||||
/* Those variables are initialized to 0 automatically, so we avoid uninitialized memory access.
|
||||
* Real defaults are assigned in reset_arguments() below. */
|
||||
static char *arg_default_unit;
|
||||
@@ -729,6 +732,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
ARG_VERSION,
|
||||
ARG_DUMP_CONFIGURATION_ITEMS,
|
||||
ARG_DUMP_BUS_PROPERTIES,
|
||||
ARG_BUS_INTROSPECT,
|
||||
ARG_DUMP_CORE,
|
||||
ARG_CRASH_CHVT,
|
||||
ARG_CRASH_SHELL,
|
||||
@@ -758,6 +762,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
{ "version", no_argument, NULL, ARG_VERSION },
|
||||
{ "dump-configuration-items", no_argument, NULL, ARG_DUMP_CONFIGURATION_ITEMS },
|
||||
{ "dump-bus-properties", no_argument, NULL, ARG_DUMP_BUS_PROPERTIES },
|
||||
{ "bus-introspect", required_argument, NULL, ARG_BUS_INTROSPECT },
|
||||
{ "dump-core", optional_argument, NULL, ARG_DUMP_CORE },
|
||||
{ "crash-chvt", required_argument, NULL, ARG_CRASH_CHVT },
|
||||
{ "crash-shell", optional_argument, NULL, ARG_CRASH_SHELL },
|
||||
@@ -885,6 +890,11 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
arg_action = ACTION_DUMP_BUS_PROPERTIES;
|
||||
break;
|
||||
|
||||
case ARG_BUS_INTROSPECT:
|
||||
arg_bus_introspect = optarg;
|
||||
arg_action = ACTION_BUS_INTROSPECT;
|
||||
break;
|
||||
|
||||
case ARG_DUMP_CORE:
|
||||
if (!optarg)
|
||||
arg_dump_core = true;
|
||||
@@ -1033,7 +1043,9 @@ static int help(void) {
|
||||
return log_oom();
|
||||
|
||||
printf("%s [OPTIONS...]\n\n"
|
||||
"Starts up and maintains the system or user services.\n\n"
|
||||
"%sStarts and monitors system and user services.%s\n\n"
|
||||
"This program takes no positional arguments.\n\n"
|
||||
"%sOptions%s:\n"
|
||||
" -h --help Show this help\n"
|
||||
" --version Show version\n"
|
||||
" --test Determine initial transaction, dump it and exit\n"
|
||||
@@ -1042,6 +1054,7 @@ static int help(void) {
|
||||
" --no-pager Do not pipe output into a pager\n"
|
||||
" --dump-configuration-items Dump understood unit configuration items\n"
|
||||
" --dump-bus-properties Dump exposed bus properties\n"
|
||||
" --bus-introspect=PATH Write XML introspection data\n"
|
||||
" --unit=UNIT Set default unit\n"
|
||||
" --dump-core[=BOOL] Dump core on crash\n"
|
||||
" --crash-vt=NR Change to specified VT on crash\n"
|
||||
@@ -1058,6 +1071,8 @@ static int help(void) {
|
||||
" --default-standard-error= Set default standard error output for services\n"
|
||||
"\nSee the %s for details.\n"
|
||||
, program_invocation_short_name
|
||||
, ansi_highlight(), ansi_normal()
|
||||
, ansi_underline(), ansi_normal()
|
||||
, link
|
||||
);
|
||||
|
||||
@@ -2611,7 +2626,7 @@ int main(int argc, char *argv[]) {
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
|
||||
if (IN_SET(arg_action, ACTION_TEST, ACTION_HELP, ACTION_DUMP_CONFIGURATION_ITEMS, ACTION_DUMP_BUS_PROPERTIES))
|
||||
if (IN_SET(arg_action, ACTION_TEST, ACTION_HELP, ACTION_DUMP_CONFIGURATION_ITEMS, ACTION_DUMP_BUS_PROPERTIES, ACTION_BUS_INTROSPECT))
|
||||
(void) pager_open(arg_pager_flags);
|
||||
|
||||
if (arg_action != ACTION_RUN)
|
||||
@@ -2631,6 +2646,10 @@ int main(int argc, char *argv[]) {
|
||||
dump_bus_properties(stdout);
|
||||
retval = EXIT_SUCCESS;
|
||||
goto finish;
|
||||
} else if (arg_action == ACTION_BUS_INTROSPECT) {
|
||||
r = bus_manager_introspect_implementations(stdout, arg_bus_introspect);
|
||||
retval = r >= 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
assert_se(IN_SET(arg_action, ACTION_RUN, ACTION_TEST));
|
||||
|
||||
@@ -2110,7 +2110,6 @@ const UnitVTable mount_vtable = {
|
||||
|
||||
.control_pid = mount_control_pid,
|
||||
|
||||
.bus_vtable = bus_mount_vtable,
|
||||
.bus_set_property = bus_mount_set_property,
|
||||
.bus_commit_properties = bus_mount_commit_properties,
|
||||
|
||||
|
||||
@@ -830,6 +830,5 @@ const UnitVTable path_vtable = {
|
||||
|
||||
.reset_failed = path_reset_failed,
|
||||
|
||||
.bus_vtable = bus_path_vtable,
|
||||
.bus_set_property = bus_path_set_property,
|
||||
};
|
||||
|
||||
@@ -652,7 +652,6 @@ const UnitVTable scope_vtable = {
|
||||
|
||||
.notify_cgroup_empty = scope_notify_cgroup_empty_event,
|
||||
|
||||
.bus_vtable = bus_scope_vtable,
|
||||
.bus_set_property = bus_scope_set_property,
|
||||
.bus_commit_properties = bus_scope_commit_properties,
|
||||
|
||||
|
||||
@@ -4484,7 +4484,6 @@ const UnitVTable service_vtable = {
|
||||
|
||||
.bus_name_owner_change = service_bus_name_owner_change,
|
||||
|
||||
.bus_vtable = bus_service_vtable,
|
||||
.bus_set_property = bus_service_set_property,
|
||||
.bus_commit_properties = bus_service_commit_properties,
|
||||
|
||||
|
||||
@@ -458,7 +458,6 @@ const UnitVTable slice_vtable = {
|
||||
.active_state = slice_active_state,
|
||||
.sub_state_to_string = slice_sub_state_to_string,
|
||||
|
||||
.bus_vtable = bus_slice_vtable,
|
||||
.bus_set_property = bus_slice_set_property,
|
||||
.bus_commit_properties = bus_slice_commit_properties,
|
||||
|
||||
|
||||
@@ -3462,7 +3462,6 @@ const UnitVTable socket_vtable = {
|
||||
|
||||
.control_pid = socket_control_pid,
|
||||
|
||||
.bus_vtable = bus_socket_vtable,
|
||||
.bus_set_property = bus_socket_set_property,
|
||||
.bus_commit_properties = bus_socket_commit_properties,
|
||||
|
||||
|
||||
@@ -1655,7 +1655,6 @@ const UnitVTable swap_vtable = {
|
||||
|
||||
.control_pid = swap_control_pid,
|
||||
|
||||
.bus_vtable = bus_swap_vtable,
|
||||
.bus_set_property = bus_swap_set_property,
|
||||
.bus_commit_properties = bus_swap_commit_properties,
|
||||
|
||||
|
||||
@@ -207,8 +207,6 @@ const UnitVTable target_vtable = {
|
||||
.active_state = target_active_state,
|
||||
.sub_state_to_string = target_sub_state_to_string,
|
||||
|
||||
.bus_vtable = bus_target_vtable,
|
||||
|
||||
.status_message_formats = {
|
||||
.finished_start_job = {
|
||||
[JOB_DONE] = "Reached target %s.",
|
||||
|
||||
@@ -925,6 +925,5 @@ const UnitVTable timer_vtable = {
|
||||
.time_change = timer_time_change,
|
||||
.timezone_change = timer_timezone_change,
|
||||
|
||||
.bus_vtable = bus_timer_vtable,
|
||||
.bus_set_property = bus_timer_set_property,
|
||||
};
|
||||
|
||||
@@ -600,9 +600,6 @@ typedef struct UnitVTable {
|
||||
* of this type will immediately fail. */
|
||||
bool (*supported)(void);
|
||||
|
||||
/* The bus vtable */
|
||||
const sd_bus_vtable *bus_vtable;
|
||||
|
||||
/* The strings to print in status messages */
|
||||
UnitStatusMessageFormats status_message_formats;
|
||||
|
||||
|
||||
+103
-27
@@ -712,38 +712,13 @@ int bus_home_method_release(
|
||||
/* We map a uid_t as uint32_t bus property, let's ensure this is safe. */
|
||||
assert_cc(sizeof(uid_t) == sizeof(uint32_t));
|
||||
|
||||
const sd_bus_vtable home_vtable[] = {
|
||||
SD_BUS_VTABLE_START(0),
|
||||
SD_BUS_PROPERTY("UserName", "s", NULL, offsetof(Home, user_name), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("UID", "u", NULL, offsetof(Home, uid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("UnixRecord", "(suusss)", property_get_unix_record, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("State", "s", property_get_state, 0, 0),
|
||||
SD_BUS_PROPERTY("UserRecord", "(sb)", property_get_user_record, 0, SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION|SD_BUS_VTABLE_SENSITIVE),
|
||||
SD_BUS_METHOD("Activate", "s", NULL, bus_home_method_activate, SD_BUS_VTABLE_SENSITIVE),
|
||||
SD_BUS_METHOD("Deactivate", NULL, NULL, bus_home_method_deactivate, 0),
|
||||
SD_BUS_METHOD("Unregister", NULL, NULL, bus_home_method_unregister, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("Realize", "s", NULL, bus_home_method_realize, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
|
||||
SD_BUS_METHOD("Remove", NULL, NULL, bus_home_method_remove, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("Fixate", "s", NULL, bus_home_method_fixate, SD_BUS_VTABLE_SENSITIVE),
|
||||
SD_BUS_METHOD("Authenticate", "s", NULL, bus_home_method_authenticate, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
|
||||
SD_BUS_METHOD("Update", "s", NULL, bus_home_method_update, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
|
||||
SD_BUS_METHOD("Resize", "ts", NULL, bus_home_method_resize, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
|
||||
SD_BUS_METHOD("ChangePassword", "ss", NULL, bus_home_method_change_password, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
|
||||
SD_BUS_METHOD("Lock", NULL, NULL, bus_home_method_lock, 0),
|
||||
SD_BUS_METHOD("Unlock", "s", NULL, bus_home_method_unlock, SD_BUS_VTABLE_SENSITIVE),
|
||||
SD_BUS_METHOD("Acquire", "sb", "h", bus_home_method_acquire, SD_BUS_VTABLE_SENSITIVE),
|
||||
SD_BUS_METHOD("Ref", "b", "h", bus_home_method_ref, 0),
|
||||
SD_BUS_METHOD("Release", NULL, NULL, bus_home_method_release, 0),
|
||||
SD_BUS_VTABLE_END
|
||||
};
|
||||
|
||||
int bus_home_path(Home *h, char **ret) {
|
||||
assert(ret);
|
||||
|
||||
return sd_bus_path_encode("/org/freedesktop/home1/home", h->user_name, ret);
|
||||
}
|
||||
|
||||
int bus_home_object_find(
|
||||
static int bus_home_object_find(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
@@ -772,7 +747,7 @@ int bus_home_object_find(
|
||||
return 1;
|
||||
}
|
||||
|
||||
int bus_home_node_enumerator(
|
||||
static int bus_home_node_enumerator(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
void *userdata,
|
||||
@@ -802,6 +777,107 @@ int bus_home_node_enumerator(
|
||||
return 1;
|
||||
}
|
||||
|
||||
const sd_bus_vtable home_vtable[] = {
|
||||
SD_BUS_VTABLE_START(0),
|
||||
|
||||
SD_BUS_PROPERTY("UserName", "s",
|
||||
NULL, offsetof(Home, user_name),
|
||||
SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("UID", "u",
|
||||
NULL, offsetof(Home, uid),
|
||||
SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("UnixRecord", "(suusss)",
|
||||
property_get_unix_record, 0,
|
||||
SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("State", "s",
|
||||
property_get_state, 0,
|
||||
0),
|
||||
SD_BUS_PROPERTY("UserRecord", "(sb)",
|
||||
property_get_user_record, 0,
|
||||
SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION|SD_BUS_VTABLE_SENSITIVE),
|
||||
|
||||
SD_BUS_METHOD_WITH_NAMES("Activate",
|
||||
"s",
|
||||
SD_BUS_PARAM(user_record),
|
||||
NULL,,
|
||||
bus_home_method_activate,
|
||||
SD_BUS_VTABLE_SENSITIVE),
|
||||
SD_BUS_METHOD("Deactivate", NULL, NULL, bus_home_method_deactivate, 0),
|
||||
SD_BUS_METHOD("Unregister", NULL, NULL, bus_home_method_unregister, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("Realize",
|
||||
"s",
|
||||
SD_BUS_PARAM(user_record),
|
||||
NULL,,
|
||||
bus_home_method_realize,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
|
||||
|
||||
SD_BUS_METHOD("Remove", NULL, NULL, bus_home_method_remove, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("Fixate",
|
||||
"s",
|
||||
SD_BUS_PARAM(user_record),
|
||||
NULL,,
|
||||
bus_home_method_fixate,
|
||||
SD_BUS_VTABLE_SENSITIVE),
|
||||
SD_BUS_METHOD_WITH_NAMES("Authenticate",
|
||||
"s",
|
||||
SD_BUS_PARAM(user_record),
|
||||
NULL,,
|
||||
bus_home_method_authenticate,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
|
||||
SD_BUS_METHOD_WITH_NAMES("Update",
|
||||
"s",
|
||||
SD_BUS_PARAM(user_record),
|
||||
NULL,,
|
||||
bus_home_method_update,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
|
||||
SD_BUS_METHOD_WITH_NAMES("Resize",
|
||||
"ts",
|
||||
SD_BUS_PARAM(size)
|
||||
SD_BUS_PARAM(user_record),
|
||||
NULL,,
|
||||
bus_home_method_resize,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
|
||||
SD_BUS_METHOD_WITH_NAMES("ChangePassword",
|
||||
"ss",
|
||||
SD_BUS_PARAM(new_user_record)
|
||||
SD_BUS_PARAM(old_user_record),
|
||||
NULL,,
|
||||
bus_home_method_change_password,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
|
||||
SD_BUS_METHOD("Lock", NULL, NULL, bus_home_method_lock, 0),
|
||||
SD_BUS_METHOD_WITH_NAMES("Unlock",
|
||||
"s",
|
||||
SD_BUS_PARAM(user_record),
|
||||
NULL,,
|
||||
bus_home_method_unlock,
|
||||
SD_BUS_VTABLE_SENSITIVE),
|
||||
SD_BUS_METHOD_WITH_NAMES("Acquire",
|
||||
"sb",
|
||||
SD_BUS_PARAM(user_record)
|
||||
SD_BUS_PARAM(please_suspend),
|
||||
"h",
|
||||
SD_BUS_PARAM(send_fd),
|
||||
bus_home_method_acquire,
|
||||
SD_BUS_VTABLE_SENSITIVE),
|
||||
SD_BUS_METHOD_WITH_NAMES("Ref",
|
||||
"b",
|
||||
SD_BUS_PARAM(please_suspend),
|
||||
"h",
|
||||
SD_BUS_PARAM(send_fd),
|
||||
bus_home_method_ref,
|
||||
0),
|
||||
SD_BUS_METHOD("Release", NULL, NULL, bus_home_method_release, 0),
|
||||
SD_BUS_VTABLE_END
|
||||
};
|
||||
|
||||
const BusObjectImplementation home_object = {
|
||||
"/org/freedesktop/home1/home",
|
||||
"org.freedesktop.home1.Home",
|
||||
.fallback_vtables = BUS_FALLBACK_VTABLES({home_vtable, bus_home_object_find}),
|
||||
.node_enumerator = bus_home_node_enumerator,
|
||||
.manager = true,
|
||||
};
|
||||
|
||||
static int on_deferred_change(sd_event_source *s, void *userdata) {
|
||||
_cleanup_free_ char *path = NULL;
|
||||
Home *h = userdata;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "sd-bus.h"
|
||||
|
||||
#include "bus-util.h"
|
||||
#include "homed-home.h"
|
||||
|
||||
int bus_home_client_is_trusted(Home *h, sd_bus_message *message);
|
||||
@@ -25,12 +26,9 @@ int bus_home_method_acquire(sd_bus_message *message, void *userdata, sd_bus_erro
|
||||
int bus_home_method_ref(sd_bus_message *message, void *userdata, sd_bus_error *error);
|
||||
int bus_home_method_release(sd_bus_message *message, void *userdata, sd_bus_error *error);
|
||||
|
||||
extern const sd_bus_vtable home_vtable[];
|
||||
extern const BusObjectImplementation home_object;
|
||||
|
||||
int bus_home_path(Home *h, char **ret);
|
||||
|
||||
int bus_home_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error);
|
||||
int bus_home_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error);
|
||||
|
||||
int bus_home_emit_change(Home *h);
|
||||
int bus_home_emit_remove(Home *h);
|
||||
|
||||
+203
-30
@@ -600,44 +600,210 @@ static int method_lock_all_homes(sd_bus_message *message, void *userdata, sd_bus
|
||||
return sd_bus_reply_method_return(message, NULL);
|
||||
}
|
||||
|
||||
const sd_bus_vtable manager_vtable[] = {
|
||||
static const sd_bus_vtable manager_vtable[] = {
|
||||
SD_BUS_VTABLE_START(0),
|
||||
|
||||
SD_BUS_PROPERTY("AutoLogin", "a(sso)", property_get_auto_login, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
|
||||
SD_BUS_METHOD("GetHomeByName", "s", "usussso", method_get_home_by_name, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("GetHomeByUID", "u", "ssussso", method_get_home_by_uid, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("GetUserRecordByName", "s", "sbo", method_get_user_record_by_name, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
|
||||
SD_BUS_METHOD("GetUserRecordByUID", "u", "sbo", method_get_user_record_by_uid, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
|
||||
SD_BUS_METHOD("ListHomes", NULL, "a(susussso)", method_list_homes, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("GetHomeByName",
|
||||
"s",
|
||||
SD_BUS_PARAM(user_name),
|
||||
"usussso",
|
||||
SD_BUS_PARAM(uid)
|
||||
SD_BUS_PARAM(home_state)
|
||||
SD_BUS_PARAM(gid)
|
||||
SD_BUS_PARAM(real_name)
|
||||
SD_BUS_PARAM(home_directory)
|
||||
SD_BUS_PARAM(shell)
|
||||
SD_BUS_PARAM(bus_path),
|
||||
method_get_home_by_name,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("GetHomeByUID",
|
||||
"u",
|
||||
SD_BUS_PARAM(uid),
|
||||
"ssussso",
|
||||
SD_BUS_PARAM(user_name)
|
||||
SD_BUS_PARAM(home_state)
|
||||
SD_BUS_PARAM(gid)
|
||||
SD_BUS_PARAM(real_name)
|
||||
SD_BUS_PARAM(home_directory)
|
||||
SD_BUS_PARAM(shell)
|
||||
SD_BUS_PARAM(bus_path),
|
||||
method_get_home_by_uid,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("GetUserRecordByName",
|
||||
"s",
|
||||
SD_BUS_PARAM(user_name),
|
||||
"sbo",
|
||||
SD_BUS_PARAM(user_record)
|
||||
SD_BUS_PARAM(incomplete)
|
||||
SD_BUS_PARAM(bus_path),
|
||||
method_get_user_record_by_name,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
|
||||
SD_BUS_METHOD_WITH_NAMES("GetUserRecordByUID",
|
||||
"u",
|
||||
SD_BUS_PARAM(uid),
|
||||
"sbo",
|
||||
SD_BUS_PARAM(user_record)
|
||||
SD_BUS_PARAM(incomplete)
|
||||
SD_BUS_PARAM(bus_path),
|
||||
method_get_user_record_by_uid,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
|
||||
SD_BUS_METHOD_WITH_NAMES("ListHomes",
|
||||
NULL,,
|
||||
"a(susussso)",
|
||||
SD_BUS_PARAM(home_areas),
|
||||
method_list_homes,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
|
||||
/* The following methods directly execute an operation on a home area, without ref-counting, queueing
|
||||
* or anything, and are accessible through homectl. */
|
||||
SD_BUS_METHOD("ActivateHome", "ss", NULL, method_activate_home, SD_BUS_VTABLE_SENSITIVE),
|
||||
SD_BUS_METHOD("DeactivateHome", "s", NULL, method_deactivate_home, 0),
|
||||
SD_BUS_METHOD("RegisterHome", "s", NULL, method_register_home, SD_BUS_VTABLE_UNPRIVILEGED), /* Add JSON record to homed, but don't create actual $HOME */
|
||||
SD_BUS_METHOD("UnregisterHome", "s", NULL, method_unregister_home, SD_BUS_VTABLE_UNPRIVILEGED), /* Remove JSON record from homed, but don't remove actual $HOME */
|
||||
SD_BUS_METHOD("CreateHome", "s", NULL, method_create_home, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), /* Add JSON record, and create $HOME for it */
|
||||
SD_BUS_METHOD("RealizeHome", "ss", NULL, method_realize_home, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), /* Create $HOME for already registered JSON entry */
|
||||
SD_BUS_METHOD("RemoveHome", "s", NULL, method_remove_home, SD_BUS_VTABLE_UNPRIVILEGED), /* Remove JSON record and remove $HOME */
|
||||
SD_BUS_METHOD("FixateHome", "ss", NULL, method_fixate_home, SD_BUS_VTABLE_SENSITIVE), /* Investigate $HOME and propagate contained JSON record into our database */
|
||||
SD_BUS_METHOD("AuthenticateHome", "ss", NULL, method_authenticate_home, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), /* Just check credentials */
|
||||
SD_BUS_METHOD("UpdateHome", "s", NULL, method_update_home, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), /* Update JSON record of existing user */
|
||||
SD_BUS_METHOD("ResizeHome", "sts", NULL, method_resize_home, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
|
||||
SD_BUS_METHOD("ChangePasswordHome", "sss", NULL, method_change_password_home, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
|
||||
SD_BUS_METHOD("LockHome", "s", NULL, method_lock_home, 0), /* Prepare active home for system suspend: flush out passwords, suspend access */
|
||||
SD_BUS_METHOD("UnlockHome", "ss", NULL, method_unlock_home, SD_BUS_VTABLE_SENSITIVE), /* Make $HOME usable after system resume again */
|
||||
SD_BUS_METHOD_WITH_NAMES("ActivateHome",
|
||||
"ss",
|
||||
SD_BUS_PARAM(user_name)
|
||||
SD_BUS_PARAM(user_record),
|
||||
NULL,,
|
||||
method_activate_home,
|
||||
SD_BUS_VTABLE_SENSITIVE),
|
||||
SD_BUS_METHOD_WITH_NAMES("DeactivateHome",
|
||||
"s",
|
||||
SD_BUS_PARAM(user_name),
|
||||
NULL,,
|
||||
method_deactivate_home,
|
||||
0),
|
||||
|
||||
/* The following methods implement ref-counted activation, and are what the PAM module calls (and
|
||||
* what "homectl with" runs). In contrast to the methods above which fail if an operation is already
|
||||
* being executed on a home directory, these ones will queue the request, and are thus more
|
||||
* reliable. Moreover, they are a bit smarter: AcquireHome() will fixate, activate, unlock, or
|
||||
* authenticate depending on the state of the home, so that the end result is always the same
|
||||
* (i.e. the home directory is accessible), and we always validate the specified passwords. RefHome()
|
||||
* will not authenticate, and thus only works if home is already active. */
|
||||
SD_BUS_METHOD("AcquireHome", "ssb", "h", method_acquire_home, SD_BUS_VTABLE_SENSITIVE),
|
||||
SD_BUS_METHOD("RefHome", "sb", "h", method_ref_home, 0),
|
||||
SD_BUS_METHOD("ReleaseHome", "s", NULL, method_release_home, 0),
|
||||
/* Add the JSON record to homed, but don't create actual $HOME */
|
||||
SD_BUS_METHOD_WITH_NAMES("RegisterHome",
|
||||
"s",
|
||||
SD_BUS_PARAM(home_record),
|
||||
NULL,,
|
||||
method_register_home,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
|
||||
/* Remove the JSON record from homed, but don't remove actual $HOME */
|
||||
SD_BUS_METHOD_WITH_NAMES("UnregisterHome",
|
||||
"s",
|
||||
SD_BUS_PARAM(user_name),
|
||||
NULL,,
|
||||
method_unregister_home,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
|
||||
/* Add JSON record, and create $HOME for it */
|
||||
SD_BUS_METHOD_WITH_NAMES("CreateHome",
|
||||
"s",
|
||||
SD_BUS_PARAM(home_record),
|
||||
NULL,,
|
||||
method_create_home,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
|
||||
|
||||
/* Create $HOME for already registered JSON entry */
|
||||
SD_BUS_METHOD_WITH_NAMES("RealizeHome",
|
||||
"ss",
|
||||
SD_BUS_PARAM(user_name)
|
||||
SD_BUS_PARAM(user_record),
|
||||
NULL,,
|
||||
method_realize_home,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
|
||||
|
||||
/* Remove the JSON record and remove $HOME */
|
||||
SD_BUS_METHOD_WITH_NAMES("RemoveHome",
|
||||
"s",
|
||||
SD_BUS_PARAM(user_name),
|
||||
NULL,,
|
||||
method_remove_home,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
|
||||
/* Investigate $HOME and propagate contained JSON record into our database */
|
||||
SD_BUS_METHOD_WITH_NAMES("FixateHome",
|
||||
"ss",
|
||||
SD_BUS_PARAM(user_name)
|
||||
SD_BUS_PARAM(user_record),
|
||||
NULL,,
|
||||
method_fixate_home,
|
||||
SD_BUS_VTABLE_SENSITIVE),
|
||||
|
||||
/* Just check credentials */
|
||||
SD_BUS_METHOD_WITH_NAMES("AuthenticateHome",
|
||||
"ss",
|
||||
SD_BUS_PARAM(user_name)
|
||||
SD_BUS_PARAM(user_record),
|
||||
NULL,,
|
||||
method_authenticate_home,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
|
||||
|
||||
/* Update the JSON record of existing user */
|
||||
SD_BUS_METHOD_WITH_NAMES("UpdateHome",
|
||||
"s",
|
||||
SD_BUS_PARAM(user_record),
|
||||
NULL,,
|
||||
method_update_home,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
|
||||
|
||||
SD_BUS_METHOD_WITH_NAMES("ResizeHome",
|
||||
"sts",
|
||||
SD_BUS_PARAM(user_name)
|
||||
SD_BUS_PARAM(size)
|
||||
SD_BUS_PARAM(user_record),
|
||||
NULL,,
|
||||
method_resize_home,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
|
||||
|
||||
SD_BUS_METHOD_WITH_NAMES("ChangePasswordHome",
|
||||
"sss",
|
||||
SD_BUS_PARAM(user_name)
|
||||
SD_BUS_PARAM(new_user_record)
|
||||
SD_BUS_PARAM(old_user_record),
|
||||
NULL,,
|
||||
method_change_password_home,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
|
||||
|
||||
/* Prepare active home for system suspend: flush out passwords, suspend access */
|
||||
SD_BUS_METHOD_WITH_NAMES("LockHome",
|
||||
"s",
|
||||
SD_BUS_PARAM(user_name),
|
||||
NULL,,
|
||||
method_lock_home,
|
||||
0),
|
||||
|
||||
/* Make $HOME usable after system resume again */
|
||||
SD_BUS_METHOD_WITH_NAMES("UnlockHome",
|
||||
"ss",
|
||||
SD_BUS_PARAM(user_name)
|
||||
SD_BUS_PARAM(user_record),
|
||||
NULL,,
|
||||
method_unlock_home,
|
||||
SD_BUS_VTABLE_SENSITIVE),
|
||||
|
||||
/* The following methods implement ref-counted activation, and are what the PAM module and "homectl
|
||||
* with" use. In contrast to the methods above which fail if an operation is already being executed
|
||||
* on a home directory, these ones will queue the request, and are thus more reliable. Moreover,
|
||||
* they are a bit smarter: AcquireHome() will fixate, activate, unlock, or authenticate depending on
|
||||
* the state of the home area, so that the end result is always the same (i.e. the home directory is
|
||||
* accessible), and we always validate the specified passwords. RefHome() will not authenticate, and
|
||||
* thus only works if the home area is already active. */
|
||||
SD_BUS_METHOD_WITH_NAMES("AcquireHome",
|
||||
"ssb",
|
||||
SD_BUS_PARAM(user_name)
|
||||
SD_BUS_PARAM(user_record)
|
||||
SD_BUS_PARAM(please_suspend),
|
||||
"h",
|
||||
SD_BUS_PARAM(send_fd),
|
||||
method_acquire_home,
|
||||
SD_BUS_VTABLE_SENSITIVE),
|
||||
SD_BUS_METHOD_WITH_NAMES("RefHome",
|
||||
"sb",
|
||||
SD_BUS_PARAM(user_name)
|
||||
SD_BUS_PARAM(please_suspend),
|
||||
"h",
|
||||
SD_BUS_PARAM(send_fd),
|
||||
method_ref_home,
|
||||
0),
|
||||
SD_BUS_METHOD_WITH_NAMES("ReleaseHome",
|
||||
"s",
|
||||
SD_BUS_PARAM(user_name),
|
||||
NULL,,
|
||||
method_release_home,
|
||||
0),
|
||||
|
||||
/* An operation that acts on all homes that allow it */
|
||||
SD_BUS_METHOD("LockAllHomes", NULL, NULL, method_lock_all_homes, 0),
|
||||
@@ -645,6 +811,13 @@ const sd_bus_vtable manager_vtable[] = {
|
||||
SD_BUS_VTABLE_END
|
||||
};
|
||||
|
||||
const BusObjectImplementation manager_object = {
|
||||
"/org/freedesktop/home1",
|
||||
"org.freedesktop.home1.Manager",
|
||||
.vtables = BUS_VTABLES(manager_vtable),
|
||||
.children = BUS_IMPLEMENTATIONS(&home_object),
|
||||
};
|
||||
|
||||
static int on_deferred_auto_login(sd_event_source *s, void *userdata) {
|
||||
Manager *m = userdata;
|
||||
int r;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
#include "sd-bus.h"
|
||||
#include "bus-util.h"
|
||||
|
||||
extern const sd_bus_vtable manager_vtable[];
|
||||
extern const BusObjectImplementation manager_object;
|
||||
|
||||
@@ -879,23 +879,7 @@ static int manager_connect_bus(Manager *m) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to connect to system bus: %m");
|
||||
|
||||
r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/home1", "org.freedesktop.home1.Manager", manager_vtable, m);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to add manager object vtable: %m");
|
||||
|
||||
r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/home1/home", "org.freedesktop.home1.Home", home_vtable, bus_home_object_find, m);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to add image object vtable: %m");
|
||||
|
||||
r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/home1/home", bus_home_node_enumerator, m);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to add image enumerator: %m");
|
||||
|
||||
r = sd_bus_add_object_manager(m->bus, NULL, "/org/freedesktop/home1/home");
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to add object manager: %m");
|
||||
|
||||
r = bus_log_control_api_register(m->bus);
|
||||
r = bus_add_implementation(m->bus, &manager_object, m);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
+11
-3
@@ -3,10 +3,13 @@
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "bus-log-control-api.h"
|
||||
#include "daemon-util.h"
|
||||
#include "homed-manager.h"
|
||||
#include "homed-manager-bus.h"
|
||||
#include "log.h"
|
||||
#include "main-func.h"
|
||||
#include "service-util.h"
|
||||
#include "signal-util.h"
|
||||
|
||||
static int run(int argc, char *argv[]) {
|
||||
@@ -16,10 +19,15 @@ static int run(int argc, char *argv[]) {
|
||||
|
||||
log_setup_service();
|
||||
|
||||
umask(0022);
|
||||
r = service_parse_argv("systemd-homed.service",
|
||||
"A service to create, remove, change or inspect home areas.",
|
||||
BUS_IMPLEMENTATIONS(&manager_object,
|
||||
&log_control_object),
|
||||
argc, argv);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
if (argc != 1)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "This program takes no arguments.");
|
||||
umask(0022);
|
||||
|
||||
if (setenv("SYSTEMD_BYPASS_USERDB", "io.systemd.Home", 1) < 0)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to set $SYSTEMD_BYPASS_USERDB: %m");
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "parse-util.h"
|
||||
#include "path-util.h"
|
||||
#include "selinux-util.h"
|
||||
#include "service-util.h"
|
||||
#include "signal-util.h"
|
||||
#include "strv.h"
|
||||
#include "user-util.h"
|
||||
@@ -739,6 +740,12 @@ static const sd_bus_vtable hostname_vtable[] = {
|
||||
SD_BUS_VTABLE_END,
|
||||
};
|
||||
|
||||
static const BusObjectImplementation manager_object = {
|
||||
"/org/freedesktop/hostname1",
|
||||
"org.freedesktop.hostname1",
|
||||
.vtables = BUS_VTABLES(hostname_vtable),
|
||||
};
|
||||
|
||||
static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) {
|
||||
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
|
||||
int r;
|
||||
@@ -751,9 +758,9 @@ static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to get system bus connection: %m");
|
||||
|
||||
r = sd_bus_add_object_vtable(bus, NULL, "/org/freedesktop/hostname1", "org.freedesktop.hostname1", hostname_vtable, c);
|
||||
r = bus_add_implementation(bus, &manager_object, c);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to register object: %m");
|
||||
return r;
|
||||
|
||||
r = bus_log_control_api_register(bus);
|
||||
if (r < 0)
|
||||
@@ -780,14 +787,17 @@ static int run(int argc, char *argv[]) {
|
||||
|
||||
log_setup_service();
|
||||
|
||||
r = service_parse_argv("systemd-hostnamed.service",
|
||||
"Manage the system hostname and related metadata.",
|
||||
BUS_IMPLEMENTATIONS(&manager_object,
|
||||
&log_control_object),
|
||||
argc, argv);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
umask(0022);
|
||||
mac_selinux_init();
|
||||
|
||||
if (argc != 1) {
|
||||
log_error("This program takes no arguments.");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, -1) >= 0);
|
||||
|
||||
r = sd_event_default(&event);
|
||||
|
||||
+118
-81
@@ -8,6 +8,7 @@
|
||||
#include "alloc-util.h"
|
||||
#include "bus-common-errors.h"
|
||||
#include "bus-log-control-api.h"
|
||||
#include "bus-util.h"
|
||||
#include "bus-polkit.h"
|
||||
#include "def.h"
|
||||
#include "fd-util.h"
|
||||
@@ -22,6 +23,7 @@
|
||||
#include "path-util.h"
|
||||
#include "process-util.h"
|
||||
#include "signal-util.h"
|
||||
#include "service-util.h"
|
||||
#include "socket-util.h"
|
||||
#include "stat-util.h"
|
||||
#include "string-table.h"
|
||||
@@ -488,11 +490,13 @@ static int transfer_start(Transfer *t) {
|
||||
|
||||
t->stdin_fd = safe_close(t->stdin_fd);
|
||||
|
||||
r = sd_event_add_child(t->manager->event, &t->pid_event_source, t->pid, WEXITED, transfer_on_pid, t);
|
||||
r = sd_event_add_child(t->manager->event, &t->pid_event_source,
|
||||
t->pid, WEXITED, transfer_on_pid, t);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_event_add_io(t->manager->event, &t->log_event_source, t->log_fd, EPOLLIN, transfer_on_log, t);
|
||||
r = sd_event_add_io(t->manager->event, &t->log_event_source,
|
||||
t->log_fd, EPOLLIN, transfer_on_log, t);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -657,7 +661,8 @@ static int manager_new(Manager **ret) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_event_add_io(m->event, &m->notify_event_source, m->notify_fd, EPOLLIN, manager_on_notify, m);
|
||||
r = sd_event_add_io(m->event, &m->notify_event_source,
|
||||
m->notify_fd, EPOLLIN, manager_on_notify, m);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -718,13 +723,15 @@ static int method_import_tar_or_raw(sd_bus_message *msg, void *userdata, sd_bus_
|
||||
return -EINVAL;
|
||||
|
||||
if (!machine_name_is_valid(local))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Local name %s is invalid", local);
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
|
||||
"Local name %s is invalid", local);
|
||||
|
||||
r = setup_machine_directory(error);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
type = streq_ptr(sd_bus_message_get_member(msg), "ImportTar") ? TRANSFER_IMPORT_TAR : TRANSFER_IMPORT_RAW;
|
||||
type = streq_ptr(sd_bus_message_get_member(msg), "ImportTar") ?
|
||||
TRANSFER_IMPORT_TAR : TRANSFER_IMPORT_RAW;
|
||||
|
||||
r = transfer_new(m, &t);
|
||||
if (r < 0)
|
||||
@@ -786,7 +793,8 @@ static int method_import_fs(sd_bus_message *msg, void *userdata, sd_bus_error *e
|
||||
return r;
|
||||
|
||||
if (!machine_name_is_valid(local))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Local name %s is invalid", local);
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
|
||||
"Local name %s is invalid", local);
|
||||
|
||||
r = setup_machine_directory(error);
|
||||
if (r < 0)
|
||||
@@ -850,7 +858,8 @@ static int method_export_tar_or_raw(sd_bus_message *msg, void *userdata, sd_bus_
|
||||
return r;
|
||||
|
||||
if (!machine_name_is_valid(local))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Local name %s is invalid", local);
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
|
||||
"Local name %s is invalid", local);
|
||||
|
||||
if (fstat(fd, &st) < 0)
|
||||
return -errno;
|
||||
@@ -858,7 +867,8 @@ static int method_export_tar_or_raw(sd_bus_message *msg, void *userdata, sd_bus_
|
||||
if (!S_ISREG(st.st_mode) && !S_ISFIFO(st.st_mode))
|
||||
return -EINVAL;
|
||||
|
||||
type = streq_ptr(sd_bus_message_get_member(msg), "ExportTar") ? TRANSFER_EXPORT_TAR : TRANSFER_EXPORT_RAW;
|
||||
type = streq_ptr(sd_bus_message_get_member(msg), "ExportTar") ?
|
||||
TRANSFER_EXPORT_TAR : TRANSFER_EXPORT_RAW;
|
||||
|
||||
r = transfer_new(m, &t);
|
||||
if (r < 0)
|
||||
@@ -922,28 +932,33 @@ static int method_pull_tar_or_raw(sd_bus_message *msg, void *userdata, sd_bus_er
|
||||
return r;
|
||||
|
||||
if (!http_url_is_valid(remote))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "URL %s is invalid", remote);
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
|
||||
"URL %s is invalid", remote);
|
||||
|
||||
if (isempty(local))
|
||||
local = NULL;
|
||||
else if (!machine_name_is_valid(local))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Local name %s is invalid", local);
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
|
||||
"Local name %s is invalid", local);
|
||||
|
||||
if (isempty(verify))
|
||||
v = IMPORT_VERIFY_SIGNATURE;
|
||||
else
|
||||
v = import_verify_from_string(verify);
|
||||
if (v < 0)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown verification mode %s", verify);
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
|
||||
"Unknown verification mode %s", verify);
|
||||
|
||||
r = setup_machine_directory(error);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
type = streq_ptr(sd_bus_message_get_member(msg), "PullTar") ? TRANSFER_PULL_TAR : TRANSFER_PULL_RAW;
|
||||
type = streq_ptr(sd_bus_message_get_member(msg), "PullTar") ?
|
||||
TRANSFER_PULL_TAR : TRANSFER_PULL_RAW;
|
||||
|
||||
if (manager_find(m, type, remote))
|
||||
return sd_bus_error_setf(error, BUS_ERROR_TRANSFER_IN_PROGRESS, "Transfer for %s already in progress.", remote);
|
||||
return sd_bus_error_setf(error, BUS_ERROR_TRANSFER_IN_PROGRESS,
|
||||
"Transfer for %s already in progress.", remote);
|
||||
|
||||
r = transfer_new(m, &t);
|
||||
if (r < 0)
|
||||
@@ -1103,6 +1118,73 @@ static int property_get_progress(
|
||||
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_type, transfer_type, TransferType);
|
||||
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_verify, import_verify, ImportVerify);
|
||||
|
||||
static int transfer_object_find(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
void *userdata,
|
||||
void **found,
|
||||
sd_bus_error *error) {
|
||||
|
||||
Manager *m = userdata;
|
||||
Transfer *t;
|
||||
const char *p;
|
||||
uint32_t id;
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
assert(path);
|
||||
assert(interface);
|
||||
assert(found);
|
||||
assert(m);
|
||||
|
||||
p = startswith(path, "/org/freedesktop/import1/transfer/_");
|
||||
if (!p)
|
||||
return 0;
|
||||
|
||||
r = safe_atou32(p, &id);
|
||||
if (r < 0 || id == 0)
|
||||
return 0;
|
||||
|
||||
t = hashmap_get(m->transfers, UINT32_TO_PTR(id));
|
||||
if (!t)
|
||||
return 0;
|
||||
|
||||
*found = t;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int transfer_node_enumerator(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
void *userdata,
|
||||
char ***nodes,
|
||||
sd_bus_error *error) {
|
||||
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
Manager *m = userdata;
|
||||
Transfer *t;
|
||||
unsigned k = 0;
|
||||
Iterator i;
|
||||
|
||||
l = new0(char*, hashmap_size(m->transfers) + 1);
|
||||
if (!l)
|
||||
return -ENOMEM;
|
||||
|
||||
HASHMAP_FOREACH(t, m->transfers, i) {
|
||||
|
||||
l[k] = strdup(t->object_path);
|
||||
if (!l[k])
|
||||
return -ENOMEM;
|
||||
|
||||
k++;
|
||||
}
|
||||
|
||||
*nodes = TAKE_PTR(l);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const sd_bus_vtable transfer_vtable[] = {
|
||||
SD_BUS_VTABLE_START(0),
|
||||
|
||||
@@ -1124,6 +1206,13 @@ static const sd_bus_vtable transfer_vtable[] = {
|
||||
SD_BUS_VTABLE_END,
|
||||
};
|
||||
|
||||
static const BusObjectImplementation transfer_object = {
|
||||
"/org/freedesktop/import1/transfer",
|
||||
"org.freedesktop.import1.Transfer",
|
||||
.fallback_vtables = BUS_FALLBACK_VTABLES({transfer_vtable, transfer_object_find}),
|
||||
.node_enumerator = transfer_node_enumerator,
|
||||
};
|
||||
|
||||
static const sd_bus_vtable manager_vtable[] = {
|
||||
SD_BUS_VTABLE_START(0),
|
||||
|
||||
@@ -1230,76 +1319,21 @@ static const sd_bus_vtable manager_vtable[] = {
|
||||
SD_BUS_VTABLE_END,
|
||||
};
|
||||
|
||||
static int transfer_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
|
||||
Manager *m = userdata;
|
||||
Transfer *t;
|
||||
const char *p;
|
||||
uint32_t id;
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
assert(path);
|
||||
assert(interface);
|
||||
assert(found);
|
||||
assert(m);
|
||||
|
||||
p = startswith(path, "/org/freedesktop/import1/transfer/_");
|
||||
if (!p)
|
||||
return 0;
|
||||
|
||||
r = safe_atou32(p, &id);
|
||||
if (r < 0 || id == 0)
|
||||
return 0;
|
||||
|
||||
t = hashmap_get(m->transfers, UINT32_TO_PTR(id));
|
||||
if (!t)
|
||||
return 0;
|
||||
|
||||
*found = t;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int transfer_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
Manager *m = userdata;
|
||||
Transfer *t;
|
||||
unsigned k = 0;
|
||||
Iterator i;
|
||||
|
||||
l = new0(char*, hashmap_size(m->transfers) + 1);
|
||||
if (!l)
|
||||
return -ENOMEM;
|
||||
|
||||
HASHMAP_FOREACH(t, m->transfers, i) {
|
||||
|
||||
l[k] = strdup(t->object_path);
|
||||
if (!l[k])
|
||||
return -ENOMEM;
|
||||
|
||||
k++;
|
||||
}
|
||||
|
||||
*nodes = TAKE_PTR(l);
|
||||
|
||||
return 1;
|
||||
}
|
||||
static const BusObjectImplementation manager_object = {
|
||||
"/org/freedesktop/import1",
|
||||
"org.freedesktop.import1.Manager",
|
||||
.vtables = BUS_VTABLES(manager_vtable),
|
||||
.children = BUS_IMPLEMENTATIONS(&transfer_object),
|
||||
};
|
||||
|
||||
static int manager_add_bus_objects(Manager *m) {
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
|
||||
r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/import1", "org.freedesktop.import1.Manager", manager_vtable, m);
|
||||
r = bus_add_implementation(m->bus, &manager_object, m);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to register object: %m");
|
||||
|
||||
r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/import1/transfer", "org.freedesktop.import1.Transfer", transfer_vtable, transfer_object_find, m);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to register object: %m");
|
||||
|
||||
r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/import1/transfer", transfer_node_enumerator, m);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to add transfer enumerator: %m");
|
||||
return r;
|
||||
|
||||
r = bus_log_control_api_register(m->bus);
|
||||
if (r < 0)
|
||||
@@ -1340,12 +1374,15 @@ static int run(int argc, char *argv[]) {
|
||||
|
||||
log_setup_service();
|
||||
|
||||
umask(0022);
|
||||
r = service_parse_argv("systemd-importd.service",
|
||||
"VM and container image import and export service.",
|
||||
BUS_IMPLEMENTATIONS(&manager_object,
|
||||
&log_control_object),
|
||||
argc, argv);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
if (argc != 1) {
|
||||
log_error("This program takes no arguments.");
|
||||
return -EINVAL;
|
||||
}
|
||||
umask(0022);
|
||||
|
||||
assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGCHLD, -1) >= 0);
|
||||
|
||||
|
||||
@@ -10,6 +10,63 @@
|
||||
#include "memory-util.h"
|
||||
#include "string-util.h"
|
||||
|
||||
#define BUS_INTROSPECT_DOCTYPE \
|
||||
"<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\"\n" \
|
||||
"\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n"
|
||||
|
||||
#define BUS_INTROSPECT_INTERFACE_PEER \
|
||||
" <interface name=\"org.freedesktop.DBus.Peer\">\n" \
|
||||
" <method name=\"Ping\"/>\n" \
|
||||
" <method name=\"GetMachineId\">\n" \
|
||||
" <arg type=\"s\" name=\"machine_uuid\" direction=\"out\"/>\n" \
|
||||
" </method>\n" \
|
||||
" </interface>\n"
|
||||
|
||||
#define BUS_INTROSPECT_INTERFACE_INTROSPECTABLE \
|
||||
" <interface name=\"org.freedesktop.DBus.Introspectable\">\n" \
|
||||
" <method name=\"Introspect\">\n" \
|
||||
" <arg name=\"data\" type=\"s\" direction=\"out\"/>\n" \
|
||||
" </method>\n" \
|
||||
" </interface>\n"
|
||||
|
||||
#define BUS_INTROSPECT_INTERFACE_PROPERTIES \
|
||||
" <interface name=\"org.freedesktop.DBus.Properties\">\n" \
|
||||
" <method name=\"Get\">\n" \
|
||||
" <arg name=\"interface\" direction=\"in\" type=\"s\"/>\n" \
|
||||
" <arg name=\"property\" direction=\"in\" type=\"s\"/>\n" \
|
||||
" <arg name=\"value\" direction=\"out\" type=\"v\"/>\n" \
|
||||
" </method>\n" \
|
||||
" <method name=\"GetAll\">\n" \
|
||||
" <arg name=\"interface\" direction=\"in\" type=\"s\"/>\n" \
|
||||
" <arg name=\"properties\" direction=\"out\" type=\"a{sv}\"/>\n" \
|
||||
" </method>\n" \
|
||||
" <method name=\"Set\">\n" \
|
||||
" <arg name=\"interface\" direction=\"in\" type=\"s\"/>\n" \
|
||||
" <arg name=\"property\" direction=\"in\" type=\"s\"/>\n" \
|
||||
" <arg name=\"value\" direction=\"in\" type=\"v\"/>\n" \
|
||||
" </method>\n" \
|
||||
" <signal name=\"PropertiesChanged\">\n" \
|
||||
" <arg type=\"s\" name=\"interface\"/>\n" \
|
||||
" <arg type=\"a{sv}\" name=\"changed_properties\"/>\n" \
|
||||
" <arg type=\"as\" name=\"invalidated_properties\"/>\n" \
|
||||
" </signal>\n" \
|
||||
" </interface>\n"
|
||||
|
||||
#define BUS_INTROSPECT_INTERFACE_OBJECT_MANAGER \
|
||||
" <interface name=\"org.freedesktop.DBus.ObjectManager\">\n" \
|
||||
" <method name=\"GetManagedObjects\">\n" \
|
||||
" <arg type=\"a{oa{sa{sv}}}\" name=\"object_paths_interfaces_and_properties\" direction=\"out\"/>\n" \
|
||||
" </method>\n" \
|
||||
" <signal name=\"InterfacesAdded\">\n" \
|
||||
" <arg type=\"o\" name=\"object_path\"/>\n" \
|
||||
" <arg type=\"a{sa{sv}}\" name=\"interfaces_and_properties\"/>\n" \
|
||||
" </signal>\n" \
|
||||
" <signal name=\"InterfacesRemoved\">\n" \
|
||||
" <arg type=\"o\" name=\"object_path\"/>\n" \
|
||||
" <arg type=\"as\" name=\"interfaces\"/>\n" \
|
||||
" </signal>\n" \
|
||||
" </interface>\n"
|
||||
|
||||
int introspect_begin(struct introspect *i, bool trusted) {
|
||||
assert(i);
|
||||
|
||||
@@ -40,12 +97,27 @@ int introspect_write_default_interfaces(struct introspect *i, bool object_manage
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_interface_name(struct introspect *intro, const char *interface_name) {
|
||||
if (streq_ptr(intro->interface_name, interface_name))
|
||||
return 0;
|
||||
|
||||
if (intro->interface_name)
|
||||
fputs(" </interface>\n", intro->f);
|
||||
|
||||
if (interface_name)
|
||||
fprintf(intro->f, " <interface name=\"%s\">\n", interface_name);
|
||||
|
||||
return free_and_strdup(&intro->interface_name, interface_name);
|
||||
}
|
||||
|
||||
int introspect_write_child_nodes(struct introspect *i, Set *s, const char *prefix) {
|
||||
char *node;
|
||||
|
||||
assert(i);
|
||||
assert(prefix);
|
||||
|
||||
assert_se(set_interface_name(i, NULL) >= 0);
|
||||
|
||||
while ((node = set_steal_first(s))) {
|
||||
const char *e;
|
||||
|
||||
@@ -115,13 +187,23 @@ static int introspect_write_arguments(struct introspect *i, const char *signatur
|
||||
}
|
||||
}
|
||||
|
||||
int introspect_write_interface(struct introspect *i, const sd_bus_vtable *v) {
|
||||
int introspect_write_interface(
|
||||
struct introspect *i,
|
||||
const char *interface_name,
|
||||
const sd_bus_vtable *v) {
|
||||
|
||||
const sd_bus_vtable *vtable = v;
|
||||
const char *names = "";
|
||||
int r;
|
||||
|
||||
assert(i);
|
||||
assert(interface_name);
|
||||
assert(v);
|
||||
|
||||
r = set_interface_name(i, interface_name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
for (; v->type != _SD_BUS_VTABLE_END; v = bus_vtable_next(vtable, v)) {
|
||||
|
||||
/* Ignore methods, signals and properties that are
|
||||
@@ -178,6 +260,8 @@ int introspect_finish(struct introspect *i, char **ret) {
|
||||
|
||||
assert(i);
|
||||
|
||||
assert_se(set_interface_name(i, NULL) >= 0);
|
||||
|
||||
fputs("</node>\n", i->f);
|
||||
|
||||
r = fflush_and_check(i->f);
|
||||
@@ -196,5 +280,6 @@ void introspect_free(struct introspect *i) {
|
||||
/* Normally introspect_finish() does all the work, this is just a backup for error paths */
|
||||
|
||||
safe_fclose(i->f);
|
||||
free(i->interface_name);
|
||||
free(i->introspection);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
struct introspect {
|
||||
FILE *f;
|
||||
char *interface_name;
|
||||
char *introspection;
|
||||
size_t size;
|
||||
bool trusted;
|
||||
@@ -17,6 +18,9 @@ struct introspect {
|
||||
int introspect_begin(struct introspect *i, bool trusted);
|
||||
int introspect_write_default_interfaces(struct introspect *i, bool object_manager);
|
||||
int introspect_write_child_nodes(struct introspect *i, Set *s, const char *prefix);
|
||||
int introspect_write_interface(struct introspect *i, const sd_bus_vtable *v);
|
||||
int introspect_write_interface(
|
||||
struct introspect *i,
|
||||
const char *interface_name,
|
||||
const sd_bus_vtable *v);
|
||||
int introspect_finish(struct introspect *i, char **ret);
|
||||
void introspect_free(struct introspect *i);
|
||||
|
||||
@@ -827,10 +827,10 @@ static int property_get_all_callbacks_run(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
found_interface = !iface ||
|
||||
streq(iface, "org.freedesktop.DBus.Properties") ||
|
||||
streq(iface, "org.freedesktop.DBus.Peer") ||
|
||||
streq(iface, "org.freedesktop.DBus.Introspectable");
|
||||
found_interface = !iface || STR_IN_SET(iface,
|
||||
"org.freedesktop.DBus.Properties",
|
||||
"org.freedesktop.DBus.Peer",
|
||||
"org.freedesktop.DBus.Introspectable");
|
||||
|
||||
LIST_FOREACH(vtables, c, first) {
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
@@ -939,7 +939,6 @@ int introspect_path(
|
||||
sd_bus_error *error) {
|
||||
|
||||
_cleanup_set_free_free_ Set *s = NULL;
|
||||
const char *previous_interface = NULL;
|
||||
_cleanup_(introspect_free) struct introspect intro = {};
|
||||
struct node_vtable *c;
|
||||
bool empty;
|
||||
@@ -984,23 +983,11 @@ int introspect_path(
|
||||
if (c->vtable[0].flags & SD_BUS_VTABLE_HIDDEN)
|
||||
continue;
|
||||
|
||||
if (!streq_ptr(previous_interface, c->interface)) {
|
||||
if (previous_interface)
|
||||
fputs(" </interface>\n", intro.f);
|
||||
|
||||
fprintf(intro.f, " <interface name=\"%s\">\n", c->interface);
|
||||
}
|
||||
|
||||
r = introspect_write_interface(&intro, c->vtable);
|
||||
r = introspect_write_interface(&intro, c->interface, c->vtable);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
previous_interface = c->interface;
|
||||
}
|
||||
|
||||
if (previous_interface)
|
||||
fputs(" </interface>\n", intro.f);
|
||||
|
||||
if (empty) {
|
||||
/* Nothing?, let's see if we exist at all, and if not
|
||||
* refuse to do anything */
|
||||
|
||||
@@ -103,60 +103,3 @@ enum {
|
||||
BUS_START_REPLY_SUCCESS = 1,
|
||||
BUS_START_REPLY_ALREADY_RUNNING = 2,
|
||||
};
|
||||
|
||||
#define BUS_INTROSPECT_DOCTYPE \
|
||||
"<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\"\n" \
|
||||
"\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n"
|
||||
|
||||
#define BUS_INTROSPECT_INTERFACE_PEER \
|
||||
" <interface name=\"org.freedesktop.DBus.Peer\">\n" \
|
||||
" <method name=\"Ping\"/>\n" \
|
||||
" <method name=\"GetMachineId\">\n" \
|
||||
" <arg type=\"s\" name=\"machine_uuid\" direction=\"out\"/>\n" \
|
||||
" </method>\n" \
|
||||
" </interface>\n"
|
||||
|
||||
#define BUS_INTROSPECT_INTERFACE_INTROSPECTABLE \
|
||||
" <interface name=\"org.freedesktop.DBus.Introspectable\">\n" \
|
||||
" <method name=\"Introspect\">\n" \
|
||||
" <arg name=\"data\" type=\"s\" direction=\"out\"/>\n" \
|
||||
" </method>\n" \
|
||||
" </interface>\n"
|
||||
|
||||
#define BUS_INTROSPECT_INTERFACE_PROPERTIES \
|
||||
" <interface name=\"org.freedesktop.DBus.Properties\">\n" \
|
||||
" <method name=\"Get\">\n" \
|
||||
" <arg name=\"interface\" direction=\"in\" type=\"s\"/>\n" \
|
||||
" <arg name=\"property\" direction=\"in\" type=\"s\"/>\n" \
|
||||
" <arg name=\"value\" direction=\"out\" type=\"v\"/>\n" \
|
||||
" </method>\n" \
|
||||
" <method name=\"GetAll\">\n" \
|
||||
" <arg name=\"interface\" direction=\"in\" type=\"s\"/>\n" \
|
||||
" <arg name=\"properties\" direction=\"out\" type=\"a{sv}\"/>\n" \
|
||||
" </method>\n" \
|
||||
" <method name=\"Set\">\n" \
|
||||
" <arg name=\"interface\" direction=\"in\" type=\"s\"/>\n" \
|
||||
" <arg name=\"property\" direction=\"in\" type=\"s\"/>\n" \
|
||||
" <arg name=\"value\" direction=\"in\" type=\"v\"/>\n" \
|
||||
" </method>\n" \
|
||||
" <signal name=\"PropertiesChanged\">\n" \
|
||||
" <arg type=\"s\" name=\"interface\"/>\n" \
|
||||
" <arg type=\"a{sv}\" name=\"changed_properties\"/>\n" \
|
||||
" <arg type=\"as\" name=\"invalidated_properties\"/>\n" \
|
||||
" </signal>\n" \
|
||||
" </interface>\n"
|
||||
|
||||
#define BUS_INTROSPECT_INTERFACE_OBJECT_MANAGER \
|
||||
" <interface name=\"org.freedesktop.DBus.ObjectManager\">\n" \
|
||||
" <method name=\"GetManagedObjects\">\n" \
|
||||
" <arg type=\"a{oa{sa{sv}}}\" name=\"object_paths_interfaces_and_properties\" direction=\"out\"/>\n" \
|
||||
" </method>\n" \
|
||||
" <signal name=\"InterfacesAdded\">\n" \
|
||||
" <arg type=\"o\" name=\"object_path\"/>\n" \
|
||||
" <arg type=\"a{sa{sv}}\" name=\"interfaces_and_properties\"/>\n" \
|
||||
" </signal>\n" \
|
||||
" <signal name=\"InterfacesRemoved\">\n" \
|
||||
" <arg type=\"o\" name=\"object_path\"/>\n" \
|
||||
" <arg type=\"as\" name=\"interfaces\"/>\n" \
|
||||
" </signal>\n" \
|
||||
" </interface>\n"
|
||||
|
||||
@@ -14,11 +14,11 @@ static void test_manual_introspection(const sd_bus_vtable vtable[]) {
|
||||
|
||||
assert_se(introspect_begin(&intro, false) >= 0);
|
||||
|
||||
fprintf(intro.f, " <interface name=\"org.foo\">\n");
|
||||
assert_se(introspect_write_interface(&intro, vtable) >= 0);
|
||||
fputs(" </interface>\n", intro.f);
|
||||
|
||||
assert_se(introspect_write_interface(&intro, "org.foo", vtable) >= 0);
|
||||
/* write again to check if output looks OK for a different interface */
|
||||
assert_se(introspect_write_interface(&intro, "org.foo.bar", vtable) >= 0);
|
||||
assert_se(introspect_finish(&intro, &s) == 0);
|
||||
|
||||
fputs(s, stdout);
|
||||
fputs("\n", stdout);
|
||||
}
|
||||
|
||||
+17
-5
@@ -25,6 +25,7 @@
|
||||
#include "missing_capability.h"
|
||||
#include "path-util.h"
|
||||
#include "selinux-util.h"
|
||||
#include "service-util.h"
|
||||
#include "signal-util.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
@@ -709,6 +710,12 @@ static const sd_bus_vtable locale_vtable[] = {
|
||||
SD_BUS_VTABLE_END
|
||||
};
|
||||
|
||||
static const BusObjectImplementation manager_object = {
|
||||
"/org/freedesktop/locale1",
|
||||
"org.freedesktop.locale1",
|
||||
.vtables = BUS_VTABLES(locale_vtable),
|
||||
};
|
||||
|
||||
static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) {
|
||||
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
|
||||
int r;
|
||||
@@ -721,9 +728,9 @@ static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to get system bus connection: %m");
|
||||
|
||||
r = sd_bus_add_object_vtable(bus, NULL, "/org/freedesktop/locale1", "org.freedesktop.locale1", locale_vtable, c);
|
||||
r = bus_add_implementation(bus, &manager_object, c);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to register object: %m");
|
||||
return r;
|
||||
|
||||
r = bus_log_control_api_register(bus);
|
||||
if (r < 0)
|
||||
@@ -754,12 +761,17 @@ static int run(int argc, char *argv[]) {
|
||||
|
||||
log_setup_service();
|
||||
|
||||
r = service_parse_argv("systemd-localed.service",
|
||||
"Manage system locale settings and key mappings.",
|
||||
BUS_IMPLEMENTATIONS(&manager_object,
|
||||
&log_control_object),
|
||||
argc, argv);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
umask(0022);
|
||||
mac_selinux_init();
|
||||
|
||||
if (argc != 1)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "This program takes no arguments.");
|
||||
|
||||
assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, -1) >= 0);
|
||||
|
||||
r = sd_event_default(&event);
|
||||
|
||||
+10
-1
@@ -3322,7 +3322,7 @@ fail:
|
||||
return r;
|
||||
}
|
||||
|
||||
const sd_bus_vtable manager_vtable[] = {
|
||||
static const sd_bus_vtable manager_vtable[] = {
|
||||
SD_BUS_VTABLE_START(0),
|
||||
|
||||
SD_BUS_WRITABLE_PROPERTY("EnableWallMessages", "b", NULL, NULL, offsetof(Manager, enable_wall_messages), 0),
|
||||
@@ -3754,6 +3754,15 @@ const sd_bus_vtable manager_vtable[] = {
|
||||
SD_BUS_VTABLE_END
|
||||
};
|
||||
|
||||
const BusObjectImplementation manager_object = {
|
||||
"/org/freedesktop/login1",
|
||||
"org.freedesktop.login1.Manager",
|
||||
.vtables = BUS_VTABLES(manager_vtable),
|
||||
.children = BUS_IMPLEMENTATIONS(&seat_object,
|
||||
&session_object,
|
||||
&user_object),
|
||||
};
|
||||
|
||||
static int session_jobs_reply(Session *s, uint32_t jid, const char *unit, const char *result) {
|
||||
assert(s);
|
||||
assert(unit);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "sd-bus.h"
|
||||
|
||||
#include "bus-util.h"
|
||||
#include "logind.h"
|
||||
#include "logind-session.h"
|
||||
#include "logind-user.h"
|
||||
@@ -29,3 +30,5 @@ int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *err
|
||||
int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error);
|
||||
int manager_unit_is_active(Manager *manager, const char *unit, sd_bus_error *error);
|
||||
int manager_job_is_active(Manager *manager, const char *path, sd_bus_error *error);
|
||||
|
||||
extern const BusObjectImplementation manager_object;
|
||||
|
||||
@@ -291,41 +291,7 @@ static int method_switch_to_previous(sd_bus_message *message, void *userdata, sd
|
||||
return sd_bus_reply_method_return(message, NULL);
|
||||
}
|
||||
|
||||
const sd_bus_vtable seat_vtable[] = {
|
||||
SD_BUS_VTABLE_START(0),
|
||||
|
||||
SD_BUS_PROPERTY("Id", "s", NULL, offsetof(Seat, id), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("ActiveSession", "(so)", property_get_active_session, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("CanMultiSession", "b", property_get_const_true, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
|
||||
SD_BUS_PROPERTY("CanTTY", "b", property_get_can_tty, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("CanGraphical", "b", property_get_can_graphical, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("Sessions", "a(so)", property_get_sessions, 0, 0),
|
||||
SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
|
||||
SD_BUS_METHOD("Terminate", NULL, NULL, bus_seat_method_terminate, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
|
||||
SD_BUS_METHOD_WITH_NAMES("ActivateSession",
|
||||
"s",
|
||||
SD_BUS_PARAM(session_id),
|
||||
NULL,,
|
||||
method_activate_session,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("SwitchTo",
|
||||
"u",
|
||||
SD_BUS_PARAM(vtnr),
|
||||
NULL,,
|
||||
method_switch_to,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
|
||||
SD_BUS_METHOD("SwitchToNext", NULL, NULL, method_switch_to_next, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("SwitchToPrevious", NULL, NULL, method_switch_to_previous, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
|
||||
SD_BUS_VTABLE_END
|
||||
};
|
||||
|
||||
int seat_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
|
||||
static int seat_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
|
||||
_cleanup_free_ char *e = NULL;
|
||||
sd_bus_message *message;
|
||||
Manager *m = userdata;
|
||||
@@ -373,7 +339,7 @@ char *seat_bus_path(Seat *s) {
|
||||
return strjoin("/org/freedesktop/login1/seat/", t);
|
||||
}
|
||||
|
||||
int seat_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
|
||||
static int seat_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
sd_bus_message *message;
|
||||
Manager *m = userdata;
|
||||
@@ -478,3 +444,44 @@ int seat_send_changed(Seat *s, const char *properties, ...) {
|
||||
|
||||
return sd_bus_emit_properties_changed_strv(s->manager->bus, p, "org.freedesktop.login1.Seat", l);
|
||||
}
|
||||
|
||||
static const sd_bus_vtable seat_vtable[] = {
|
||||
SD_BUS_VTABLE_START(0),
|
||||
|
||||
SD_BUS_PROPERTY("Id", "s", NULL, offsetof(Seat, id), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("ActiveSession", "(so)", property_get_active_session, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("CanMultiSession", "b", property_get_const_true, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
|
||||
SD_BUS_PROPERTY("CanTTY", "b", property_get_can_tty, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("CanGraphical", "b", property_get_can_graphical, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("Sessions", "a(so)", property_get_sessions, 0, 0),
|
||||
SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
|
||||
SD_BUS_METHOD("Terminate", NULL, NULL, bus_seat_method_terminate, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
|
||||
SD_BUS_METHOD_WITH_NAMES("ActivateSession",
|
||||
"s",
|
||||
SD_BUS_PARAM(session_id),
|
||||
NULL,,
|
||||
method_activate_session,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("SwitchTo",
|
||||
"u",
|
||||
SD_BUS_PARAM(vtnr),
|
||||
NULL,,
|
||||
method_switch_to,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
|
||||
SD_BUS_METHOD("SwitchToNext", NULL, NULL, method_switch_to_next, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("SwitchToPrevious", NULL, NULL, method_switch_to_previous, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
|
||||
SD_BUS_VTABLE_END
|
||||
};
|
||||
|
||||
const BusObjectImplementation seat_object = {
|
||||
"/org/freedesktop/login1/seat",
|
||||
"org.freedesktop.login1.Seat",
|
||||
.fallback_vtables = BUS_FALLBACK_VTABLES({seat_vtable, seat_object_find}),
|
||||
.node_enumerator = seat_node_enumerator,
|
||||
};
|
||||
|
||||
@@ -4,11 +4,10 @@
|
||||
#include "sd-bus.h"
|
||||
|
||||
#include "logind-seat.h"
|
||||
#include "bus-util.h"
|
||||
|
||||
extern const sd_bus_vtable seat_vtable[];
|
||||
extern const BusObjectImplementation seat_object;
|
||||
|
||||
int seat_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error);
|
||||
int seat_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error);
|
||||
char *seat_bus_path(Seat *s);
|
||||
|
||||
int seat_send_signal(Seat *s, bool new_seat);
|
||||
|
||||
+143
-136
@@ -581,141 +581,7 @@ static int method_set_brightness(sd_bus_message *message, void *userdata, sd_bus
|
||||
return 1;
|
||||
}
|
||||
|
||||
const sd_bus_vtable session_vtable[] = {
|
||||
SD_BUS_VTABLE_START(0),
|
||||
|
||||
SD_BUS_PROPERTY("Id", "s", NULL, offsetof(Session, id), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("User", "(uo)", property_get_user, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Name", "s", property_get_name, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
BUS_PROPERTY_DUAL_TIMESTAMP("Timestamp", offsetof(Session, timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("VTNr", "u", NULL, offsetof(Session, vtnr), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Seat", "(so)", property_get_seat, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("TTY", "s", NULL, offsetof(Session, tty), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Display", "s", NULL, offsetof(Session, display), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Remote", "b", bus_property_get_bool, offsetof(Session, remote), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("RemoteHost", "s", NULL, offsetof(Session, remote_host), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("RemoteUser", "s", NULL, offsetof(Session, remote_user), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Service", "s", NULL, offsetof(Session, service), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Desktop", "s", NULL, offsetof(Session, desktop), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Scope", "s", NULL, offsetof(Session, scope), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Leader", "u", bus_property_get_pid, offsetof(Session, leader), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Audit", "u", NULL, offsetof(Session, audit_id), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Type", "s", property_get_type, offsetof(Session, type), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("Class", "s", property_get_class, offsetof(Session, class), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Active", "b", property_get_active, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("State", "s", property_get_state, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("LockedHint", "b", property_get_locked_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
|
||||
SD_BUS_METHOD("Terminate",
|
||||
NULL,
|
||||
NULL,
|
||||
bus_session_method_terminate,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("Activate",
|
||||
NULL,
|
||||
NULL,
|
||||
bus_session_method_activate,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("Lock",
|
||||
NULL,
|
||||
NULL,
|
||||
bus_session_method_lock,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("Unlock",
|
||||
NULL,
|
||||
NULL,
|
||||
bus_session_method_lock,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("SetIdleHint",
|
||||
"b",
|
||||
SD_BUS_PARAM(idle),
|
||||
NULL,,
|
||||
method_set_idle_hint,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("SetLockedHint",
|
||||
"b",
|
||||
SD_BUS_PARAM(locked),
|
||||
NULL,,
|
||||
method_set_locked_hint,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("Kill",
|
||||
"si",
|
||||
SD_BUS_PARAM(who)
|
||||
SD_BUS_PARAM(signal_number),
|
||||
NULL,,
|
||||
bus_session_method_kill,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("TakeControl",
|
||||
"b",
|
||||
SD_BUS_PARAM(force),
|
||||
NULL,,
|
||||
method_take_control,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("ReleaseControl",
|
||||
NULL,
|
||||
NULL,
|
||||
method_release_control,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("SetType",
|
||||
"s",
|
||||
SD_BUS_PARAM(type),
|
||||
NULL,,
|
||||
method_set_type,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("TakeDevice",
|
||||
"uu",
|
||||
SD_BUS_PARAM(major)
|
||||
SD_BUS_PARAM(minor),
|
||||
"hb",
|
||||
SD_BUS_PARAM(fd)
|
||||
SD_BUS_PARAM(inactive),
|
||||
method_take_device,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("ReleaseDevice",
|
||||
"uu",
|
||||
SD_BUS_PARAM(major)
|
||||
SD_BUS_PARAM(minor),
|
||||
NULL,,
|
||||
method_release_device,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("PauseDeviceComplete",
|
||||
"uu",
|
||||
SD_BUS_PARAM(major)
|
||||
SD_BUS_PARAM(minor),
|
||||
NULL,,
|
||||
method_pause_device_complete,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("SetBrightness",
|
||||
"ssu",
|
||||
SD_BUS_PARAM(subsystem)
|
||||
SD_BUS_PARAM(name)
|
||||
SD_BUS_PARAM(brightness),
|
||||
NULL,,
|
||||
method_set_brightness,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
|
||||
SD_BUS_SIGNAL_WITH_NAMES("PauseDevice",
|
||||
"uus",
|
||||
SD_BUS_PARAM(major)
|
||||
SD_BUS_PARAM(minor)
|
||||
SD_BUS_PARAM(type),
|
||||
0),
|
||||
SD_BUS_SIGNAL_WITH_NAMES("ResumeDevice",
|
||||
"uuh",
|
||||
SD_BUS_PARAM(major)
|
||||
SD_BUS_PARAM(minor)
|
||||
SD_BUS_PARAM(fd),
|
||||
0),
|
||||
SD_BUS_SIGNAL("Lock", NULL, 0),
|
||||
SD_BUS_SIGNAL("Unlock", NULL, 0),
|
||||
|
||||
SD_BUS_VTABLE_END
|
||||
};
|
||||
|
||||
int session_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
|
||||
static int session_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
|
||||
_cleanup_free_ char *e = NULL;
|
||||
sd_bus_message *message;
|
||||
Manager *m = userdata;
|
||||
@@ -763,7 +629,7 @@ char *session_bus_path(Session *s) {
|
||||
return strjoin("/org/freedesktop/login1/session/", t);
|
||||
}
|
||||
|
||||
int session_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
|
||||
static int session_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
sd_bus_message *message;
|
||||
Manager *m = userdata;
|
||||
@@ -964,3 +830,144 @@ int session_send_create_reply(Session *s, sd_bus_error *error) {
|
||||
(uint32_t) s->vtnr,
|
||||
false);
|
||||
}
|
||||
|
||||
static const sd_bus_vtable session_vtable[] = {
|
||||
SD_BUS_VTABLE_START(0),
|
||||
|
||||
SD_BUS_PROPERTY("Id", "s", NULL, offsetof(Session, id), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("User", "(uo)", property_get_user, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Name", "s", property_get_name, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
BUS_PROPERTY_DUAL_TIMESTAMP("Timestamp", offsetof(Session, timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("VTNr", "u", NULL, offsetof(Session, vtnr), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Seat", "(so)", property_get_seat, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("TTY", "s", NULL, offsetof(Session, tty), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Display", "s", NULL, offsetof(Session, display), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Remote", "b", bus_property_get_bool, offsetof(Session, remote), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("RemoteHost", "s", NULL, offsetof(Session, remote_host), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("RemoteUser", "s", NULL, offsetof(Session, remote_user), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Service", "s", NULL, offsetof(Session, service), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Desktop", "s", NULL, offsetof(Session, desktop), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Scope", "s", NULL, offsetof(Session, scope), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Leader", "u", bus_property_get_pid, offsetof(Session, leader), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Audit", "u", NULL, offsetof(Session, audit_id), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Type", "s", property_get_type, offsetof(Session, type), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("Class", "s", property_get_class, offsetof(Session, class), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Active", "b", property_get_active, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("State", "s", property_get_state, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("LockedHint", "b", property_get_locked_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
|
||||
SD_BUS_METHOD("Terminate",
|
||||
NULL,
|
||||
NULL,
|
||||
bus_session_method_terminate,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("Activate",
|
||||
NULL,
|
||||
NULL,
|
||||
bus_session_method_activate,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("Lock",
|
||||
NULL,
|
||||
NULL,
|
||||
bus_session_method_lock,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("Unlock",
|
||||
NULL,
|
||||
NULL,
|
||||
bus_session_method_lock,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("SetIdleHint",
|
||||
"b",
|
||||
SD_BUS_PARAM(idle),
|
||||
NULL,,
|
||||
method_set_idle_hint,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("SetLockedHint",
|
||||
"b",
|
||||
SD_BUS_PARAM(locked),
|
||||
NULL,,
|
||||
method_set_locked_hint,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("Kill",
|
||||
"si",
|
||||
SD_BUS_PARAM(who)
|
||||
SD_BUS_PARAM(signal_number),
|
||||
NULL,,
|
||||
bus_session_method_kill,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("TakeControl",
|
||||
"b",
|
||||
SD_BUS_PARAM(force),
|
||||
NULL,,
|
||||
method_take_control,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("ReleaseControl",
|
||||
NULL,
|
||||
NULL,
|
||||
method_release_control,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("SetType",
|
||||
"s",
|
||||
SD_BUS_PARAM(type),
|
||||
NULL,,
|
||||
method_set_type,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("TakeDevice",
|
||||
"uu",
|
||||
SD_BUS_PARAM(major)
|
||||
SD_BUS_PARAM(minor),
|
||||
"hb",
|
||||
SD_BUS_PARAM(fd)
|
||||
SD_BUS_PARAM(inactive),
|
||||
method_take_device,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("ReleaseDevice",
|
||||
"uu",
|
||||
SD_BUS_PARAM(major)
|
||||
SD_BUS_PARAM(minor),
|
||||
NULL,,
|
||||
method_release_device,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("PauseDeviceComplete",
|
||||
"uu",
|
||||
SD_BUS_PARAM(major)
|
||||
SD_BUS_PARAM(minor),
|
||||
NULL,,
|
||||
method_pause_device_complete,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("SetBrightness",
|
||||
"ssu",
|
||||
SD_BUS_PARAM(subsystem)
|
||||
SD_BUS_PARAM(name)
|
||||
SD_BUS_PARAM(brightness),
|
||||
NULL,,
|
||||
method_set_brightness,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
|
||||
SD_BUS_SIGNAL_WITH_NAMES("PauseDevice",
|
||||
"uus",
|
||||
SD_BUS_PARAM(major)
|
||||
SD_BUS_PARAM(minor)
|
||||
SD_BUS_PARAM(type),
|
||||
0),
|
||||
SD_BUS_SIGNAL_WITH_NAMES("ResumeDevice",
|
||||
"uuh",
|
||||
SD_BUS_PARAM(major)
|
||||
SD_BUS_PARAM(minor)
|
||||
SD_BUS_PARAM(fd),
|
||||
0),
|
||||
SD_BUS_SIGNAL("Lock", NULL, 0),
|
||||
SD_BUS_SIGNAL("Unlock", NULL, 0),
|
||||
|
||||
SD_BUS_VTABLE_END
|
||||
};
|
||||
|
||||
const BusObjectImplementation session_object = {
|
||||
"/org/freedesktop/login1/session",
|
||||
"org.freedesktop.login1.Session",
|
||||
.fallback_vtables = BUS_FALLBACK_VTABLES({session_vtable, session_object_find}),
|
||||
.node_enumerator = session_node_enumerator,
|
||||
};
|
||||
|
||||
@@ -5,9 +5,8 @@
|
||||
|
||||
#include "logind-session.h"
|
||||
|
||||
extern const sd_bus_vtable session_vtable[];
|
||||
int session_node_enumerator(sd_bus *bus, const char *path,void *userdata, char ***nodes, sd_bus_error *error);
|
||||
int session_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error);
|
||||
extern const BusObjectImplementation session_object;
|
||||
|
||||
char *session_bus_path(Session *s);
|
||||
|
||||
int session_send_signal(Session *s, bool new_session);
|
||||
|
||||
@@ -258,36 +258,7 @@ int bus_user_method_kill(sd_bus_message *message, void *userdata, sd_bus_error *
|
||||
return sd_bus_reply_method_return(message, NULL);
|
||||
}
|
||||
|
||||
const sd_bus_vtable user_vtable[] = {
|
||||
SD_BUS_VTABLE_START(0),
|
||||
|
||||
SD_BUS_PROPERTY("UID", "u", property_get_uid, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("GID", "u", property_get_gid, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Name", "s", property_get_name, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
BUS_PROPERTY_DUAL_TIMESTAMP("Timestamp", offsetof(User, timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("RuntimePath", "s", NULL, offsetof(User, runtime_path), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Service", "s", NULL, offsetof(User, service), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Slice", "s", NULL, offsetof(User, slice), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Display", "(so)", property_get_display, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("State", "s", property_get_state, 0, 0),
|
||||
SD_BUS_PROPERTY("Sessions", "a(so)", property_get_sessions, 0, 0),
|
||||
SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("Linger", "b", property_get_linger, 0, 0),
|
||||
|
||||
SD_BUS_METHOD("Terminate", NULL, NULL, bus_user_method_terminate, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("Kill",
|
||||
"i",
|
||||
SD_BUS_PARAM(signal_number),
|
||||
NULL,,
|
||||
bus_user_method_kill,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
|
||||
SD_BUS_VTABLE_END
|
||||
};
|
||||
|
||||
int user_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
|
||||
static int user_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
|
||||
Manager *m = userdata;
|
||||
uid_t uid;
|
||||
User *user;
|
||||
@@ -342,7 +313,7 @@ char *user_bus_path(User *u) {
|
||||
return s;
|
||||
}
|
||||
|
||||
int user_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
|
||||
static int user_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
sd_bus_message *message;
|
||||
Manager *m = userdata;
|
||||
@@ -391,6 +362,42 @@ int user_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const sd_bus_vtable user_vtable[] = {
|
||||
SD_BUS_VTABLE_START(0),
|
||||
|
||||
SD_BUS_PROPERTY("UID", "u", property_get_uid, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("GID", "u", property_get_gid, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Name", "s", property_get_name, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
BUS_PROPERTY_DUAL_TIMESTAMP("Timestamp", offsetof(User, timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("RuntimePath", "s", NULL, offsetof(User, runtime_path), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Service", "s", NULL, offsetof(User, service), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Slice", "s", NULL, offsetof(User, slice), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Display", "(so)", property_get_display, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("State", "s", property_get_state, 0, 0),
|
||||
SD_BUS_PROPERTY("Sessions", "a(so)", property_get_sessions, 0, 0),
|
||||
SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("Linger", "b", property_get_linger, 0, 0),
|
||||
|
||||
SD_BUS_METHOD("Terminate", NULL, NULL, bus_user_method_terminate, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD_WITH_NAMES("Kill",
|
||||
"i",
|
||||
SD_BUS_PARAM(signal_number),
|
||||
NULL,,
|
||||
bus_user_method_kill,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
|
||||
SD_BUS_VTABLE_END
|
||||
};
|
||||
|
||||
const BusObjectImplementation user_object = {
|
||||
"/org/freedesktop/login1/user",
|
||||
"org.freedesktop.login1.User",
|
||||
.fallback_vtables = BUS_FALLBACK_VTABLES({user_vtable, user_object_find}),
|
||||
.node_enumerator = user_node_enumerator,
|
||||
};
|
||||
|
||||
int user_send_signal(User *u, bool new_user) {
|
||||
_cleanup_free_ char *p = NULL;
|
||||
|
||||
|
||||
@@ -5,9 +5,8 @@
|
||||
|
||||
#include "logind-user.h"
|
||||
|
||||
extern const sd_bus_vtable user_vtable[];
|
||||
int user_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error);
|
||||
int user_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error);
|
||||
extern const BusObjectImplementation user_object;
|
||||
|
||||
char *user_bus_path(User *s);
|
||||
|
||||
int user_send_signal(User *u, bool new_user);
|
||||
|
||||
+13
-33
@@ -27,6 +27,7 @@
|
||||
#include "parse-util.h"
|
||||
#include "process-util.h"
|
||||
#include "selinux-util.h"
|
||||
#include "service-util.h"
|
||||
#include "signal-util.h"
|
||||
#include "strv.h"
|
||||
#include "terminal-util.h"
|
||||
@@ -623,33 +624,13 @@ static int manager_connect_bus(Manager *m) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to connect to system bus: %m");
|
||||
|
||||
r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/login1", "org.freedesktop.login1.Manager", manager_vtable, m);
|
||||
r = bus_add_implementation(m->bus, &manager_object, m);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to add manager object vtable: %m");
|
||||
return r;
|
||||
|
||||
r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/login1/seat", "org.freedesktop.login1.Seat", seat_vtable, seat_object_find, m);
|
||||
r = bus_log_control_api_register(m->bus);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to add seat object vtable: %m");
|
||||
|
||||
r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/login1/seat", seat_node_enumerator, m);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to add seat enumerator: %m");
|
||||
|
||||
r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/login1/session", "org.freedesktop.login1.Session", session_vtable, session_object_find, m);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to add session object vtable: %m");
|
||||
|
||||
r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/login1/session", session_node_enumerator, m);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to add session enumerator: %m");
|
||||
|
||||
r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/login1/user", "org.freedesktop.login1.User", user_vtable, user_object_find, m);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to add user object vtable: %m");
|
||||
|
||||
r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/login1/user", user_node_enumerator, m);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to add user enumerator: %m");
|
||||
return r;
|
||||
|
||||
r = sd_bus_match_signal_async(
|
||||
m->bus,
|
||||
@@ -707,10 +688,6 @@ static int manager_connect_bus(Manager *m) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to enable subscription: %m");
|
||||
|
||||
r = bus_log_control_api_register(m->bus);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_request_name_async(m->bus, NULL, "org.freedesktop.login1", 0, NULL, NULL);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to request name: %m");
|
||||
@@ -1201,12 +1178,15 @@ static int run(int argc, char *argv[]) {
|
||||
log_set_facility(LOG_AUTH);
|
||||
log_setup_service();
|
||||
|
||||
umask(0022);
|
||||
r = service_parse_argv("systemd-logind.service",
|
||||
"Manager for user logins and devices and privileged operations.",
|
||||
BUS_IMPLEMENTATIONS(&manager_object,
|
||||
&log_control_object),
|
||||
argc, argv);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
if (argc != 1) {
|
||||
log_error("This program takes no arguments.");
|
||||
return -EINVAL;
|
||||
}
|
||||
umask(0022);
|
||||
|
||||
r = mac_selinux_init();
|
||||
if (r < 0)
|
||||
|
||||
@@ -157,8 +157,6 @@ int manager_read_utmp(Manager *m);
|
||||
void manager_connect_utmp(Manager *m);
|
||||
void manager_reconnect_utmp(Manager *m);
|
||||
|
||||
extern const sd_bus_vtable manager_vtable[];
|
||||
|
||||
/* gperf lookup function */
|
||||
const struct ConfigPerfItem* logind_gperf_lookup(const char *key, GPERF_LEN_TYPE length);
|
||||
|
||||
|
||||
+33
-26
@@ -354,30 +354,6 @@ int bus_image_method_get_os_release(
|
||||
return bus_reply_pair_array(message, image->os_release);
|
||||
}
|
||||
|
||||
const sd_bus_vtable image_vtable[] = {
|
||||
SD_BUS_VTABLE_START(0),
|
||||
SD_BUS_PROPERTY("Name", "s", NULL, offsetof(Image, name), 0),
|
||||
SD_BUS_PROPERTY("Path", "s", NULL, offsetof(Image, path), 0),
|
||||
SD_BUS_PROPERTY("Type", "s", property_get_type, offsetof(Image, type), 0),
|
||||
SD_BUS_PROPERTY("ReadOnly", "b", bus_property_get_bool, offsetof(Image, read_only), 0),
|
||||
SD_BUS_PROPERTY("CreationTimestamp", "t", NULL, offsetof(Image, crtime), 0),
|
||||
SD_BUS_PROPERTY("ModificationTimestamp", "t", NULL, offsetof(Image, mtime), 0),
|
||||
SD_BUS_PROPERTY("Usage", "t", NULL, offsetof(Image, usage), 0),
|
||||
SD_BUS_PROPERTY("Limit", "t", NULL, offsetof(Image, limit), 0),
|
||||
SD_BUS_PROPERTY("UsageExclusive", "t", NULL, offsetof(Image, usage_exclusive), 0),
|
||||
SD_BUS_PROPERTY("LimitExclusive", "t", NULL, offsetof(Image, limit_exclusive), 0),
|
||||
SD_BUS_METHOD("Remove", NULL, NULL, bus_image_method_remove, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("Rename", "s", NULL, bus_image_method_rename, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("Clone", "sb", NULL, bus_image_method_clone, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("MarkReadOnly", "b", NULL, bus_image_method_mark_read_only, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("SetLimit", "t", NULL, bus_image_method_set_limit, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("GetHostname", NULL, "s", bus_image_method_get_hostname, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("GetMachineID", NULL, "ay", bus_image_method_get_machine_id, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("GetMachineInfo", NULL, "a{ss}", bus_image_method_get_machine_info, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("GetOSRelease", NULL, "a{ss}", bus_image_method_get_os_release, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_VTABLE_END
|
||||
};
|
||||
|
||||
static int image_flush_cache(sd_event_source *s, void *userdata) {
|
||||
Manager *m = userdata;
|
||||
|
||||
@@ -388,7 +364,7 @@ static int image_flush_cache(sd_event_source *s, void *userdata) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int image_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
|
||||
static int image_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
|
||||
_cleanup_free_ char *e = NULL;
|
||||
Manager *m = userdata;
|
||||
Image *image = NULL;
|
||||
@@ -462,7 +438,7 @@ char *image_bus_path(const char *name) {
|
||||
return strjoin("/org/freedesktop/machine1/image/", e);
|
||||
}
|
||||
|
||||
int image_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
|
||||
static int image_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
|
||||
_cleanup_hashmap_free_ Hashmap *images = NULL;
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
Image *image;
|
||||
@@ -497,3 +473,34 @@ int image_node_enumerator(sd_bus *bus, const char *path, void *userdata, char **
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
const sd_bus_vtable image_vtable[] = {
|
||||
SD_BUS_VTABLE_START(0),
|
||||
SD_BUS_PROPERTY("Name", "s", NULL, offsetof(Image, name), 0),
|
||||
SD_BUS_PROPERTY("Path", "s", NULL, offsetof(Image, path), 0),
|
||||
SD_BUS_PROPERTY("Type", "s", property_get_type, offsetof(Image, type), 0),
|
||||
SD_BUS_PROPERTY("ReadOnly", "b", bus_property_get_bool, offsetof(Image, read_only), 0),
|
||||
SD_BUS_PROPERTY("CreationTimestamp", "t", NULL, offsetof(Image, crtime), 0),
|
||||
SD_BUS_PROPERTY("ModificationTimestamp", "t", NULL, offsetof(Image, mtime), 0),
|
||||
SD_BUS_PROPERTY("Usage", "t", NULL, offsetof(Image, usage), 0),
|
||||
SD_BUS_PROPERTY("Limit", "t", NULL, offsetof(Image, limit), 0),
|
||||
SD_BUS_PROPERTY("UsageExclusive", "t", NULL, offsetof(Image, usage_exclusive), 0),
|
||||
SD_BUS_PROPERTY("LimitExclusive", "t", NULL, offsetof(Image, limit_exclusive), 0),
|
||||
SD_BUS_METHOD("Remove", NULL, NULL, bus_image_method_remove, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("Rename", "s", NULL, bus_image_method_rename, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("Clone", "sb", NULL, bus_image_method_clone, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("MarkReadOnly", "b", NULL, bus_image_method_mark_read_only, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("SetLimit", "t", NULL, bus_image_method_set_limit, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("GetHostname", NULL, "s", bus_image_method_get_hostname, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("GetMachineID", NULL, "ay", bus_image_method_get_machine_id, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("GetMachineInfo", NULL, "a{ss}", bus_image_method_get_machine_info, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("GetOSRelease", NULL, "a{ss}", bus_image_method_get_os_release, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_VTABLE_END
|
||||
};
|
||||
|
||||
const BusObjectImplementation image_object = {
|
||||
"/org/freedesktop/machine1/image",
|
||||
"org.freedesktop.machine1.Image",
|
||||
.fallback_vtables = BUS_FALLBACK_VTABLES({image_vtable, image_object_find}),
|
||||
.node_enumerator = image_node_enumerator,
|
||||
};
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
#include "bus-util.h"
|
||||
#include "machined.h"
|
||||
|
||||
extern const sd_bus_vtable image_vtable[];
|
||||
extern const BusObjectImplementation image_object;
|
||||
|
||||
char *image_bus_path(const char *name);
|
||||
|
||||
int image_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error);
|
||||
int image_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error);
|
||||
|
||||
int bus_image_method_remove(sd_bus_message *message, void *userdata, sd_bus_error *error);
|
||||
int bus_image_method_rename(sd_bus_message *message, void *userdata, sd_bus_error *error);
|
||||
int bus_image_method_clone(sd_bus_message *message, void *userdata, sd_bus_error *error);
|
||||
|
||||
+99
-92
@@ -1321,7 +1321,99 @@ int bus_machine_method_get_uid_shift(sd_bus_message *message, void *userdata, sd
|
||||
return sd_bus_reply_method_return(message, "u", (uint32_t) shift);
|
||||
}
|
||||
|
||||
const sd_bus_vtable machine_vtable[] = {
|
||||
static int machine_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
|
||||
Manager *m = userdata;
|
||||
Machine *machine;
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
assert(path);
|
||||
assert(interface);
|
||||
assert(found);
|
||||
assert(m);
|
||||
|
||||
if (streq(path, "/org/freedesktop/machine1/machine/self")) {
|
||||
_cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
|
||||
sd_bus_message *message;
|
||||
pid_t pid;
|
||||
|
||||
message = sd_bus_get_current_message(bus);
|
||||
if (!message)
|
||||
return 0;
|
||||
|
||||
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_creds_get_pid(creds, &pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = manager_get_machine_by_pid(m, pid, &machine);
|
||||
if (r <= 0)
|
||||
return 0;
|
||||
} else {
|
||||
_cleanup_free_ char *e = NULL;
|
||||
const char *p;
|
||||
|
||||
p = startswith(path, "/org/freedesktop/machine1/machine/");
|
||||
if (!p)
|
||||
return 0;
|
||||
|
||||
e = bus_label_unescape(p);
|
||||
if (!e)
|
||||
return -ENOMEM;
|
||||
|
||||
machine = hashmap_get(m->machines, e);
|
||||
if (!machine)
|
||||
return 0;
|
||||
}
|
||||
|
||||
*found = machine;
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *machine_bus_path(Machine *m) {
|
||||
_cleanup_free_ char *e = NULL;
|
||||
|
||||
assert(m);
|
||||
|
||||
e = bus_label_escape(m->name);
|
||||
if (!e)
|
||||
return NULL;
|
||||
|
||||
return strjoin("/org/freedesktop/machine1/machine/", e);
|
||||
}
|
||||
|
||||
static int machine_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
Machine *machine = NULL;
|
||||
Manager *m = userdata;
|
||||
Iterator i;
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
assert(path);
|
||||
assert(nodes);
|
||||
|
||||
HASHMAP_FOREACH(machine, m->machines, i) {
|
||||
char *p;
|
||||
|
||||
p = machine_bus_path(machine);
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
|
||||
r = strv_consume(&l, p);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
*nodes = TAKE_PTR(l);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const sd_bus_vtable machine_vtable[] = {
|
||||
SD_BUS_VTABLE_START(0),
|
||||
SD_BUS_PROPERTY("Name", "s", NULL, offsetof(Machine, name), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Id", "ay", bus_property_get_id128, offsetof(Machine, id), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
@@ -1423,97 +1515,12 @@ const sd_bus_vtable machine_vtable[] = {
|
||||
SD_BUS_VTABLE_END
|
||||
};
|
||||
|
||||
int machine_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
|
||||
Manager *m = userdata;
|
||||
Machine *machine;
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
assert(path);
|
||||
assert(interface);
|
||||
assert(found);
|
||||
assert(m);
|
||||
|
||||
if (streq(path, "/org/freedesktop/machine1/machine/self")) {
|
||||
_cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
|
||||
sd_bus_message *message;
|
||||
pid_t pid;
|
||||
|
||||
message = sd_bus_get_current_message(bus);
|
||||
if (!message)
|
||||
return 0;
|
||||
|
||||
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_creds_get_pid(creds, &pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = manager_get_machine_by_pid(m, pid, &machine);
|
||||
if (r <= 0)
|
||||
return 0;
|
||||
} else {
|
||||
_cleanup_free_ char *e = NULL;
|
||||
const char *p;
|
||||
|
||||
p = startswith(path, "/org/freedesktop/machine1/machine/");
|
||||
if (!p)
|
||||
return 0;
|
||||
|
||||
e = bus_label_unescape(p);
|
||||
if (!e)
|
||||
return -ENOMEM;
|
||||
|
||||
machine = hashmap_get(m->machines, e);
|
||||
if (!machine)
|
||||
return 0;
|
||||
}
|
||||
|
||||
*found = machine;
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *machine_bus_path(Machine *m) {
|
||||
_cleanup_free_ char *e = NULL;
|
||||
|
||||
assert(m);
|
||||
|
||||
e = bus_label_escape(m->name);
|
||||
if (!e)
|
||||
return NULL;
|
||||
|
||||
return strjoin("/org/freedesktop/machine1/machine/", e);
|
||||
}
|
||||
|
||||
int machine_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
Machine *machine = NULL;
|
||||
Manager *m = userdata;
|
||||
Iterator i;
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
assert(path);
|
||||
assert(nodes);
|
||||
|
||||
HASHMAP_FOREACH(machine, m->machines, i) {
|
||||
char *p;
|
||||
|
||||
p = machine_bus_path(machine);
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
|
||||
r = strv_consume(&l, p);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
*nodes = TAKE_PTR(l);
|
||||
|
||||
return 1;
|
||||
}
|
||||
const BusObjectImplementation machine_object = {
|
||||
"/org/freedesktop/machine1/machine",
|
||||
"org.freedesktop.machine1.Machine",
|
||||
.fallback_vtables = BUS_FALLBACK_VTABLES({machine_vtable, machine_object_find}),
|
||||
.node_enumerator = machine_node_enumerator,
|
||||
};
|
||||
|
||||
int machine_send_signal(Machine *m, bool new_machine) {
|
||||
_cleanup_free_ char *p = NULL;
|
||||
|
||||
@@ -3,13 +3,12 @@
|
||||
|
||||
#include "sd-bus.h"
|
||||
|
||||
#include "bus-util.h"
|
||||
#include "machine.h"
|
||||
|
||||
extern const sd_bus_vtable machine_vtable[];
|
||||
extern const BusObjectImplementation machine_object;
|
||||
|
||||
char *machine_bus_path(Machine *s);
|
||||
int machine_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error);
|
||||
int machine_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error);
|
||||
|
||||
int bus_machine_method_unregister(sd_bus_message *message, void *userdata, sd_bus_error *error);
|
||||
int bus_machine_method_terminate(sd_bus_message *message, void *userdata, sd_bus_error *error);
|
||||
|
||||
@@ -1440,6 +1440,14 @@ const sd_bus_vtable manager_vtable[] = {
|
||||
SD_BUS_VTABLE_END
|
||||
};
|
||||
|
||||
const BusObjectImplementation manager_object = {
|
||||
"/org/freedesktop/machine1",
|
||||
"org.freedesktop.machine1.Manager",
|
||||
.vtables = BUS_VTABLES(manager_vtable),
|
||||
.children = BUS_IMPLEMENTATIONS( &machine_object,
|
||||
&image_object ),
|
||||
};
|
||||
|
||||
int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
||||
const char *path, *result, *unit;
|
||||
Manager *m = userdata;
|
||||
|
||||
+11
-23
@@ -22,6 +22,7 @@
|
||||
#include "machined.h"
|
||||
#include "main-func.h"
|
||||
#include "process-util.h"
|
||||
#include "service-util.h"
|
||||
#include "signal-util.h"
|
||||
#include "special.h"
|
||||
|
||||
@@ -188,25 +189,9 @@ static int manager_connect_bus(Manager *m) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to connect to system bus: %m");
|
||||
|
||||
r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/machine1", "org.freedesktop.machine1.Manager", manager_vtable, m);
|
||||
r = bus_add_implementation(m->bus, &manager_object, m);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to add manager object vtable: %m");
|
||||
|
||||
r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/machine1/machine", "org.freedesktop.machine1.Machine", machine_vtable, machine_object_find, m);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to add machine object vtable: %m");
|
||||
|
||||
r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/machine1/machine", machine_node_enumerator, m);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to add machine enumerator: %m");
|
||||
|
||||
r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/machine1/image", "org.freedesktop.machine1.Image", image_vtable, image_object_find, m);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to add image object vtable: %m");
|
||||
|
||||
r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/machine1/image", image_node_enumerator, m);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to add image enumerator: %m");
|
||||
return r;
|
||||
|
||||
r = sd_bus_match_signal_async(
|
||||
m->bus,
|
||||
@@ -357,12 +342,15 @@ static int run(int argc, char *argv[]) {
|
||||
log_set_facility(LOG_AUTH);
|
||||
log_setup_service();
|
||||
|
||||
umask(0022);
|
||||
r = service_parse_argv("systemd-machined.service",
|
||||
"Manage registrations of local VMs and containers.",
|
||||
BUS_IMPLEMENTATIONS(&manager_object,
|
||||
&log_control_object),
|
||||
argc, argv);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
if (argc != 1) {
|
||||
log_error("This program takes no arguments.");
|
||||
return -EINVAL;
|
||||
}
|
||||
umask(0022);
|
||||
|
||||
/* Always create the directories people can create inotify watches in. Note that some applications might check
|
||||
* for the existence of /run/systemd/machines/ to determine whether machined is available, so please always
|
||||
|
||||
@@ -42,7 +42,7 @@ struct Manager {
|
||||
int manager_add_machine(Manager *m, const char *name, Machine **_machine);
|
||||
int manager_get_machine_by_pid(Manager *m, pid_t pid, Machine **machine);
|
||||
|
||||
extern const sd_bus_vtable manager_vtable[];
|
||||
extern const BusObjectImplementation manager_object;
|
||||
|
||||
int match_reloading(sd_bus_message *message, void *userdata, sd_bus_error *error);
|
||||
int match_unit_removed(sd_bus_message *message, void *userdata, sd_bus_error *error);
|
||||
|
||||
+10
-18
@@ -1970,6 +1970,14 @@ static const sd_bus_vtable resolve_vtable[] = {
|
||||
SD_BUS_VTABLE_END,
|
||||
};
|
||||
|
||||
const BusObjectImplementation manager_object = {
|
||||
"/org/freedesktop/resolve1",
|
||||
"org.freedesktop.resolve1.Manager",
|
||||
.vtables = BUS_VTABLES(resolve_vtable),
|
||||
.children = BUS_IMPLEMENTATIONS(&link_object,
|
||||
&dnssd_object),
|
||||
};
|
||||
|
||||
static int match_prepare_for_sleep(sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
|
||||
Manager *m = userdata;
|
||||
int b, r;
|
||||
@@ -2004,25 +2012,9 @@ int manager_connect_bus(Manager *m) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to connect to system bus: %m");
|
||||
|
||||
r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/resolve1", "org.freedesktop.resolve1.Manager", resolve_vtable, m);
|
||||
r = bus_add_implementation(m->bus, &manager_object, m);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to register object: %m");
|
||||
|
||||
r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/resolve1/link", "org.freedesktop.resolve1.Link", link_vtable, link_object_find, m);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to register link objects: %m");
|
||||
|
||||
r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/resolve1/link", link_node_enumerator, m);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to register link enumerator: %m");
|
||||
|
||||
r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/resolve1/dnssd", "org.freedesktop.resolve1.DnssdService", dnssd_vtable, dnssd_object_find, m);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to register dnssd objects: %m");
|
||||
|
||||
r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/resolve1/dnssd", dnssd_node_enumerator, m);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to register dnssd enumerator: %m");
|
||||
return r;
|
||||
|
||||
r = bus_log_control_api_register(m->bus);
|
||||
if (r < 0)
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
#include "bus-util.h"
|
||||
#include "resolved-manager.h"
|
||||
|
||||
extern const BusObjectImplementation manager_object;
|
||||
|
||||
int manager_connect_bus(Manager *m);
|
||||
int _manager_send_changed(Manager *manager, const char *property, ...) _sentinel_;
|
||||
#define manager_send_changed(manager, ...) _manager_send_changed(manager, __VA_ARGS__, NULL)
|
||||
|
||||
@@ -62,16 +62,7 @@ int bus_dnssd_method_unregister(sd_bus_message *message, void *userdata, sd_bus_
|
||||
return sd_bus_reply_method_return(message, NULL);
|
||||
}
|
||||
|
||||
const sd_bus_vtable dnssd_vtable[] = {
|
||||
SD_BUS_VTABLE_START(0),
|
||||
|
||||
SD_BUS_METHOD("Unregister", NULL, NULL, bus_dnssd_method_unregister, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_SIGNAL("Conflicted", NULL, 0),
|
||||
|
||||
SD_BUS_VTABLE_END
|
||||
};
|
||||
|
||||
int dnssd_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
|
||||
static int dnssd_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
|
||||
_cleanup_free_ char *name = NULL;
|
||||
Manager *m = userdata;
|
||||
DnssdService *service;
|
||||
@@ -95,7 +86,7 @@ int dnssd_object_find(sd_bus *bus, const char *path, const char *interface, void
|
||||
return 1;
|
||||
}
|
||||
|
||||
int dnssd_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
|
||||
static int dnssd_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
Manager *m = userdata;
|
||||
DnssdService *service;
|
||||
@@ -127,3 +118,19 @@ int dnssd_node_enumerator(sd_bus *bus, const char *path, void *userdata, char **
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const sd_bus_vtable dnssd_vtable[] = {
|
||||
SD_BUS_VTABLE_START(0),
|
||||
|
||||
SD_BUS_METHOD("Unregister", NULL, NULL, bus_dnssd_method_unregister, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_SIGNAL("Conflicted", NULL, 0),
|
||||
|
||||
SD_BUS_VTABLE_END
|
||||
};
|
||||
|
||||
const BusObjectImplementation dnssd_object = {
|
||||
"/org/freedesktop/resolve1/dnssd",
|
||||
"org.freedesktop.resolve1.DnssdService",
|
||||
.fallback_vtables = BUS_FALLBACK_VTABLES({dnssd_vtable, dnssd_object_find}),
|
||||
.node_enumerator = dnssd_node_enumerator,
|
||||
};
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
|
||||
#include "sd-bus.h"
|
||||
|
||||
extern const sd_bus_vtable dnssd_vtable[];
|
||||
#include "bus-util.h"
|
||||
|
||||
int dnssd_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error);
|
||||
int dnssd_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error);
|
||||
extern const BusObjectImplementation dnssd_object;
|
||||
|
||||
int bus_dnssd_method_unregister(sd_bus_message *message, void *userdata, sd_bus_error *error);
|
||||
|
||||
@@ -682,7 +682,82 @@ int bus_link_method_revert(sd_bus_message *message, void *userdata, sd_bus_error
|
||||
return sd_bus_reply_method_return(message, NULL);
|
||||
}
|
||||
|
||||
const sd_bus_vtable link_vtable[] = {
|
||||
static int link_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
|
||||
_cleanup_free_ char *e = NULL;
|
||||
Manager *m = userdata;
|
||||
Link *link;
|
||||
int ifindex, r;
|
||||
|
||||
assert(bus);
|
||||
assert(path);
|
||||
assert(interface);
|
||||
assert(found);
|
||||
assert(m);
|
||||
|
||||
r = sd_bus_path_decode(path, "/org/freedesktop/resolve1/link", &e);
|
||||
if (r <= 0)
|
||||
return 0;
|
||||
|
||||
ifindex = parse_ifindex(e);
|
||||
if (ifindex < 0)
|
||||
return 0;
|
||||
|
||||
link = hashmap_get(m->links, INT_TO_PTR(ifindex));
|
||||
if (!link)
|
||||
return 0;
|
||||
|
||||
*found = link;
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *link_bus_path(const Link *link) {
|
||||
char *p, ifindex[DECIMAL_STR_MAX(link->ifindex)];
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
|
||||
xsprintf(ifindex, "%i", link->ifindex);
|
||||
|
||||
r = sd_bus_path_encode("/org/freedesktop/resolve1/link", ifindex, &p);
|
||||
if (r < 0)
|
||||
return NULL;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
static int link_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
Manager *m = userdata;
|
||||
Link *link;
|
||||
Iterator i;
|
||||
unsigned c = 0;
|
||||
|
||||
assert(bus);
|
||||
assert(path);
|
||||
assert(m);
|
||||
assert(nodes);
|
||||
|
||||
l = new0(char*, hashmap_size(m->links) + 1);
|
||||
if (!l)
|
||||
return -ENOMEM;
|
||||
|
||||
HASHMAP_FOREACH(link, m->links, i) {
|
||||
char *p;
|
||||
|
||||
p = link_bus_path(link);
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
|
||||
l[c++] = p;
|
||||
}
|
||||
|
||||
l[c] = NULL;
|
||||
*nodes = TAKE_PTR(l);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const sd_bus_vtable link_vtable[] = {
|
||||
SD_BUS_VTABLE_START(0),
|
||||
|
||||
SD_BUS_PROPERTY("ScopesMask", "t", property_get_scopes_mask, 0, 0),
|
||||
@@ -746,77 +821,9 @@ const sd_bus_vtable link_vtable[] = {
|
||||
SD_BUS_VTABLE_END
|
||||
};
|
||||
|
||||
int link_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
|
||||
_cleanup_free_ char *e = NULL;
|
||||
Manager *m = userdata;
|
||||
Link *link;
|
||||
int ifindex, r;
|
||||
|
||||
assert(bus);
|
||||
assert(path);
|
||||
assert(interface);
|
||||
assert(found);
|
||||
assert(m);
|
||||
|
||||
r = sd_bus_path_decode(path, "/org/freedesktop/resolve1/link", &e);
|
||||
if (r <= 0)
|
||||
return 0;
|
||||
|
||||
ifindex = parse_ifindex(e);
|
||||
if (ifindex < 0)
|
||||
return 0;
|
||||
|
||||
link = hashmap_get(m->links, INT_TO_PTR(ifindex));
|
||||
if (!link)
|
||||
return 0;
|
||||
|
||||
*found = link;
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *link_bus_path(const Link *link) {
|
||||
char *p, ifindex[DECIMAL_STR_MAX(link->ifindex)];
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
|
||||
xsprintf(ifindex, "%i", link->ifindex);
|
||||
|
||||
r = sd_bus_path_encode("/org/freedesktop/resolve1/link", ifindex, &p);
|
||||
if (r < 0)
|
||||
return NULL;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
int link_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
Manager *m = userdata;
|
||||
Link *link;
|
||||
Iterator i;
|
||||
unsigned c = 0;
|
||||
|
||||
assert(bus);
|
||||
assert(path);
|
||||
assert(m);
|
||||
assert(nodes);
|
||||
|
||||
l = new0(char*, hashmap_size(m->links) + 1);
|
||||
if (!l)
|
||||
return -ENOMEM;
|
||||
|
||||
HASHMAP_FOREACH(link, m->links, i) {
|
||||
char *p;
|
||||
|
||||
p = link_bus_path(link);
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
|
||||
l[c++] = p;
|
||||
}
|
||||
|
||||
l[c] = NULL;
|
||||
*nodes = TAKE_PTR(l);
|
||||
|
||||
return 1;
|
||||
}
|
||||
const BusObjectImplementation link_object = {
|
||||
"/org/freedesktop/resolve1/link",
|
||||
"org.freedesktop.resolve1.Link",
|
||||
.fallback_vtables = BUS_FALLBACK_VTABLES({link_vtable, link_object_find}),
|
||||
.node_enumerator = link_node_enumerator,
|
||||
};
|
||||
|
||||
@@ -3,13 +3,12 @@
|
||||
|
||||
#include "sd-bus.h"
|
||||
|
||||
#include "bus-util.h"
|
||||
#include "resolved-link.h"
|
||||
|
||||
extern const sd_bus_vtable link_vtable[];
|
||||
extern const BusObjectImplementation link_object;
|
||||
|
||||
int link_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error);
|
||||
char *link_bus_path(const Link *link);
|
||||
int link_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error);
|
||||
|
||||
int bus_link_method_set_dns_servers(sd_bus_message *message, void *userdata, sd_bus_error *error);
|
||||
int bus_link_method_set_domains(sd_bus_message *message, void *userdata, sd_bus_error *error);
|
||||
|
||||
+10
-2
@@ -7,14 +7,17 @@
|
||||
#include "sd-daemon.h"
|
||||
#include "sd-event.h"
|
||||
|
||||
#include "bus-log-control-api.h"
|
||||
#include "capability-util.h"
|
||||
#include "daemon-util.h"
|
||||
#include "main-func.h"
|
||||
#include "mkdir.h"
|
||||
#include "resolved-bus.h"
|
||||
#include "resolved-conf.h"
|
||||
#include "resolved-manager.h"
|
||||
#include "resolved-resolv-conf.h"
|
||||
#include "selinux-util.h"
|
||||
#include "service-util.h"
|
||||
#include "signal-util.h"
|
||||
#include "user-util.h"
|
||||
|
||||
@@ -25,8 +28,13 @@ static int run(int argc, char *argv[]) {
|
||||
|
||||
log_setup_service();
|
||||
|
||||
if (argc != 1)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "This program takes no arguments.");
|
||||
r = service_parse_argv("systemd-resolved.service",
|
||||
"Provide name resolution with caching using DNS, mDNS, LLMNR.",
|
||||
BUS_IMPLEMENTATIONS(&manager_object,
|
||||
&log_control_object),
|
||||
argc, argv);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
umask(0022);
|
||||
|
||||
|
||||
@@ -107,17 +107,8 @@ static const sd_bus_vtable log_control_vtable[] = {
|
||||
SD_BUS_VTABLE_END,
|
||||
};
|
||||
|
||||
int bus_log_control_api_register(sd_bus *bus) {
|
||||
int r;
|
||||
|
||||
r = sd_bus_add_object_vtable(
|
||||
bus,
|
||||
NULL,
|
||||
"/org/freedesktop/LogControl1",
|
||||
"org.freedesktop.LogControl1",
|
||||
log_control_vtable, NULL);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to register service API object: %m");
|
||||
|
||||
return 0;
|
||||
}
|
||||
const BusObjectImplementation log_control_object = {
|
||||
"/org/freedesktop/LogControl1",
|
||||
"org.freedesktop.LogControl1",
|
||||
.vtables = BUS_VTABLES(log_control_vtable),
|
||||
};
|
||||
|
||||
@@ -2,7 +2,12 @@
|
||||
|
||||
#include "sd-bus.h"
|
||||
|
||||
int bus_log_control_api_register(sd_bus *bus);
|
||||
#include "bus-util.h"
|
||||
|
||||
extern const BusObjectImplementation log_control_object;
|
||||
static inline int bus_log_control_api_register(sd_bus *bus) {
|
||||
return bus_add_implementation(bus, &log_control_object, NULL);
|
||||
}
|
||||
|
||||
int bus_property_get_log_level(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
|
||||
int bus_property_set_log_level(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *value, void *userdata, sd_bus_error *error);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "bus-internal.h"
|
||||
#include "bus-introspect.h"
|
||||
#include "bus-label.h"
|
||||
#include "bus-message.h"
|
||||
#include "bus-util.h"
|
||||
@@ -1549,3 +1550,171 @@ int bus_message_new_method_call(
|
||||
|
||||
return sd_bus_message_new_method_call(bus, m, locator->destination, locator->path, locator->interface, member);
|
||||
}
|
||||
|
||||
int bus_add_implementation(sd_bus *bus, const BusObjectImplementation *impl, void *userdata) {
|
||||
int r;
|
||||
|
||||
log_debug("Registering bus object implementation for path=%s iface=%s", impl->path, impl->interface);
|
||||
|
||||
for (const sd_bus_vtable **p = impl->vtables; p && *p; p++) {
|
||||
r = sd_bus_add_object_vtable(bus, NULL,
|
||||
impl->path,
|
||||
impl->interface,
|
||||
*p,
|
||||
userdata);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to register bus path %s with interface %s: %m",
|
||||
impl->path,
|
||||
impl->interface);
|
||||
}
|
||||
|
||||
for (const BusObjectVtablePair *p = impl->fallback_vtables; p && p->vtable; p++) {
|
||||
r = sd_bus_add_fallback_vtable(bus, NULL,
|
||||
impl->path,
|
||||
impl->interface,
|
||||
p->vtable,
|
||||
p->object_find,
|
||||
userdata);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to register bus path %s with interface %s: %m",
|
||||
impl->path,
|
||||
impl->interface);
|
||||
}
|
||||
|
||||
if (impl->node_enumerator) {
|
||||
r = sd_bus_add_node_enumerator(bus, NULL,
|
||||
impl->path,
|
||||
impl->node_enumerator,
|
||||
userdata);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to add node enumerator for %s: %m",
|
||||
impl->path);
|
||||
}
|
||||
|
||||
for (size_t i = 0; impl->children && impl->children[i]; i++) {
|
||||
r = bus_add_implementation(bus, impl->children[i], userdata);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const BusObjectImplementation* find_implementation(
|
||||
const char *pattern,
|
||||
const BusObjectImplementation* const* bus_objects) {
|
||||
|
||||
for (size_t i = 0; bus_objects && bus_objects[i]; i++) {
|
||||
const BusObjectImplementation *impl = bus_objects[i];
|
||||
|
||||
if (STR_IN_SET(pattern, impl->path, impl->interface))
|
||||
return impl;
|
||||
|
||||
impl = find_implementation(pattern, impl->children);
|
||||
if (impl)
|
||||
return impl;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int bus_introspect_implementation(
|
||||
struct introspect *intro,
|
||||
const BusObjectImplementation *impl) {
|
||||
int r;
|
||||
|
||||
for (const sd_bus_vtable **p = impl->vtables; p && *p; p++) {
|
||||
r = introspect_write_interface(intro, impl->interface, *p);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to write introspection data: %m");
|
||||
}
|
||||
|
||||
for (const BusObjectVtablePair *p = impl->fallback_vtables; p && p->vtable; p++) {
|
||||
r = introspect_write_interface(intro, impl->interface, p->vtable);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to write introspection data: %m");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void list_paths(
|
||||
FILE *out,
|
||||
const BusObjectImplementation* const* bus_objects) {
|
||||
|
||||
for (size_t i = 0; bus_objects[i]; i++) {
|
||||
fprintf(out, "%s\t%s\n", bus_objects[i]->path, bus_objects[i]->interface);
|
||||
if (bus_objects[i]->children)
|
||||
list_paths(out, bus_objects[i]->children);
|
||||
}
|
||||
}
|
||||
|
||||
int bus_introspect_implementations(
|
||||
FILE *out,
|
||||
const char *pattern,
|
||||
const BusObjectImplementation* const* bus_objects) {
|
||||
|
||||
const BusObjectImplementation *impl, *main_impl = NULL;
|
||||
_cleanup_free_ char *s = NULL;
|
||||
int r;
|
||||
|
||||
if (streq(pattern, "list")) {
|
||||
list_paths(out, bus_objects);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct introspect intro = {};
|
||||
bool is_interface = interface_name_is_valid(pattern);
|
||||
|
||||
impl = find_implementation(pattern, bus_objects);
|
||||
if (!impl)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(ENOENT),
|
||||
"%s %s not found",
|
||||
is_interface ? "Interface" : "Object path",
|
||||
pattern);
|
||||
|
||||
/* We use trusted=false here to get all the @org.freedesktop.systemd1.Privileged annotations. */
|
||||
r = introspect_begin(&intro, false);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to write introspection data: %m");
|
||||
|
||||
r = introspect_write_default_interfaces(&intro, impl->manager);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to write introspection data: %m");
|
||||
|
||||
/* Check if there is a non-fallback path that applies to the given interface, also
|
||||
* print it. This is useful in the case of units: o.fd.systemd1.Service is declared
|
||||
* as a fallback vtable for o/fd/systemd1/unit, and we also want to print
|
||||
* o.fd.systemd1.Unit, which is the non-fallback implementation. */
|
||||
if (impl->fallback_vtables && is_interface)
|
||||
main_impl = find_implementation(impl->path, bus_objects);
|
||||
|
||||
if (main_impl)
|
||||
bus_introspect_implementation(&intro, main_impl);
|
||||
|
||||
if (impl != main_impl)
|
||||
bus_introspect_implementation(&intro, impl);
|
||||
|
||||
_cleanup_set_free_free_ Set *nodes = NULL;
|
||||
|
||||
for (size_t i = 0; impl->children && impl->children[i]; i++) {
|
||||
r = set_ensure_allocated(&nodes, &string_hash_ops);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
r = set_put_strdup(nodes, impl->children[i]->path);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
r = introspect_write_child_nodes(&intro, nodes, impl->path);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = introspect_finish(&intro, &s);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to write introspection data: %m");
|
||||
|
||||
fputs(s, out);
|
||||
return 0;
|
||||
}
|
||||
|
||||
+30
-3
@@ -23,11 +23,32 @@ typedef enum BusTransport {
|
||||
} BusTransport;
|
||||
|
||||
typedef struct BusLocator {
|
||||
const char *destination;
|
||||
const char *path;
|
||||
const char *interface;
|
||||
const char *destination;
|
||||
const char *path;
|
||||
const char *interface;
|
||||
} BusLocator;
|
||||
|
||||
typedef struct BusObjectImplementation BusObjectImplementation;
|
||||
|
||||
typedef struct BusObjectVtablePair {
|
||||
const sd_bus_vtable *vtable;
|
||||
sd_bus_object_find_t object_find;
|
||||
} BusObjectVtablePair;
|
||||
|
||||
struct BusObjectImplementation {
|
||||
const char *path;
|
||||
const char *interface;
|
||||
const sd_bus_vtable **vtables;
|
||||
const BusObjectVtablePair *fallback_vtables;
|
||||
sd_bus_node_enumerator_t node_enumerator;
|
||||
bool manager;
|
||||
const BusObjectImplementation **children;
|
||||
};
|
||||
|
||||
#define BUS_VTABLES(...) ((const sd_bus_vtable* []){ __VA_ARGS__, NULL })
|
||||
#define BUS_FALLBACK_VTABLES(...) ((const BusObjectVtablePair[]) { __VA_ARGS__, {} })
|
||||
#define BUS_IMPLEMENTATIONS(...) ((const BusObjectImplementation* []) { __VA_ARGS__, NULL })
|
||||
|
||||
typedef int (*bus_property_set_t) (sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata);
|
||||
|
||||
struct bus_properties_map {
|
||||
@@ -199,3 +220,9 @@ int bus_set_property(sd_bus *bus, const BusLocator *locator, const char *member,
|
||||
int bus_match_signal(sd_bus *bus, sd_bus_slot **ret, const BusLocator *locator, const char *member, sd_bus_message_handler_t callback, void *userdata);
|
||||
int bus_match_signal_async(sd_bus *bus, sd_bus_slot **ret, const BusLocator *locator, const char *member, sd_bus_message_handler_t callback, sd_bus_message_handler_t install_callback, void *userdata);
|
||||
int bus_message_new_method_call(sd_bus *bus, sd_bus_message **m, const BusLocator *locator, const char *member);
|
||||
|
||||
int bus_add_implementation(sd_bus *bus, const BusObjectImplementation *impl, void *userdata);
|
||||
int bus_introspect_implementations(
|
||||
FILE *out,
|
||||
const char *pattern,
|
||||
const BusObjectImplementation* const* bus_objects);
|
||||
|
||||
@@ -184,6 +184,8 @@ shared_sources = files('''
|
||||
securebits-util.h
|
||||
serialize.c
|
||||
serialize.h
|
||||
service-util.c
|
||||
service-util.h
|
||||
sleep-config.c
|
||||
sleep-config.h
|
||||
socket-netlink.c
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "pretty-print.h"
|
||||
#include "service-util.h"
|
||||
#include "terminal-util.h"
|
||||
#include "util.h"
|
||||
|
||||
static int help(const char *program_path, const char *service, const char *description, bool bus_introspect) {
|
||||
_cleanup_free_ char *link = NULL;
|
||||
int r;
|
||||
|
||||
r = terminal_urlify_man(service, "8", &link);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
printf("%s [OPTIONS...]\n\n"
|
||||
"%s%s%s\n\n"
|
||||
"This program takes no positional arguments.\n\n"
|
||||
"%sOptions%s:\n"
|
||||
" -h --help Show this help\n"
|
||||
" --version Show package version\n"
|
||||
" --bus-introspect=PATH Write D-Bus XML introspection data\n"
|
||||
"\nSee the %s for details.\n"
|
||||
, program_path
|
||||
, ansi_highlight(), description, ansi_normal()
|
||||
, ansi_underline(), ansi_normal()
|
||||
, link
|
||||
);
|
||||
|
||||
return 0; /* No further action */
|
||||
}
|
||||
|
||||
int service_parse_argv(
|
||||
const char *service,
|
||||
const char *description,
|
||||
const BusObjectImplementation* const* bus_objects,
|
||||
int argc, char *argv[]) {
|
||||
|
||||
enum {
|
||||
ARG_VERSION = 0x100,
|
||||
ARG_BUS_INTROSPECT,
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "version", no_argument, NULL, ARG_VERSION },
|
||||
{ "bus-introspect", required_argument, NULL, ARG_BUS_INTROSPECT },
|
||||
{}
|
||||
};
|
||||
|
||||
int c;
|
||||
|
||||
assert(argc >= 0);
|
||||
assert(argv);
|
||||
|
||||
while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
|
||||
switch(c) {
|
||||
|
||||
case 'h':
|
||||
return help(argv[0], service, description, bus_objects);
|
||||
|
||||
case ARG_VERSION:
|
||||
return version();
|
||||
|
||||
case ARG_BUS_INTROSPECT:
|
||||
return bus_introspect_implementations(
|
||||
stdout,
|
||||
optarg,
|
||||
bus_objects);
|
||||
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
|
||||
default:
|
||||
assert_not_reached("Unknown option code.");
|
||||
}
|
||||
|
||||
if (optind < argc)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"This program takes no arguments.");
|
||||
|
||||
return 1; /* Further action */
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
#include "bus-util.h"
|
||||
|
||||
int service_parse_argv(
|
||||
const char *service,
|
||||
const char *description,
|
||||
const BusObjectImplementation* const* bus_objects,
|
||||
int argc, char *argv[]);
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "bus-error.h"
|
||||
#include "bus-log-control-api.h"
|
||||
#include "bus-polkit.h"
|
||||
#include "bus-util.h"
|
||||
#include "clock-util.h"
|
||||
#include "conf-files.h"
|
||||
#include "def.h"
|
||||
@@ -28,6 +29,7 @@
|
||||
#include "missing_capability.h"
|
||||
#include "path-util.h"
|
||||
#include "selinux-util.h"
|
||||
#include "service-util.h"
|
||||
#include "signal-util.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
@@ -1085,6 +1087,12 @@ static const sd_bus_vtable timedate_vtable[] = {
|
||||
SD_BUS_VTABLE_END,
|
||||
};
|
||||
|
||||
const BusObjectImplementation manager_object = {
|
||||
"/org/freedesktop/timedate1",
|
||||
"org.freedesktop.timedate1",
|
||||
.vtables = BUS_VTABLES(timedate_vtable),
|
||||
};
|
||||
|
||||
static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) {
|
||||
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
|
||||
int r;
|
||||
@@ -1097,9 +1105,9 @@ static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to get system bus connection: %m");
|
||||
|
||||
r = sd_bus_add_object_vtable(bus, NULL, "/org/freedesktop/timedate1", "org.freedesktop.timedate1", timedate_vtable, c);
|
||||
r = bus_add_implementation(bus, &manager_object, c);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to register object: %m");
|
||||
return r;
|
||||
|
||||
r = bus_log_control_api_register(bus);
|
||||
if (r < 0)
|
||||
@@ -1126,10 +1134,15 @@ static int run(int argc, char *argv[]) {
|
||||
|
||||
log_setup_service();
|
||||
|
||||
umask(0022);
|
||||
r = service_parse_argv("systemd-timedated.service",
|
||||
"Manage the system clock and timezone and NTP enablement.",
|
||||
BUS_IMPLEMENTATIONS(&manager_object,
|
||||
&log_control_object),
|
||||
argc, argv);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
if (argc != 1)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "This program takes no arguments.");
|
||||
umask(0022);
|
||||
|
||||
assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, -1) >= 0);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user