mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-12 09:17:44 +03:00
logind: implement basic version of AttachDevice() D-Bus call
This commit is contained in:
parent
4091baaaf4
commit
47a2669062
@ -214,6 +214,9 @@ dist_dbussystemservice_DATA = \
|
||||
src/org.freedesktop.login1.service
|
||||
|
||||
dist_udevrules_DATA = \
|
||||
src/70-uaccess.rules \
|
||||
src/71-seat.rules \
|
||||
src/73-seat-late.rules \
|
||||
src/99-systemd.rules
|
||||
|
||||
dbusinterface_DATA = \
|
||||
|
@ -12,13 +12,9 @@ SUBSYSTEM=="sound", KERNEL=="card*", TAG+="seat"
|
||||
SUBSYSTEM=="input", TAG+="seat"
|
||||
SUBSYSTEM=="graphics", KERNEL=="fb[0-9]*", TAG+="seat"
|
||||
SUBSYSTEM=="usb", ATTR{bDeviceClass}=="09", TAG+="seat"
|
||||
|
||||
SUBSYSTEM=="usb", ATTR{idVendor}=="2230", ATTR{idProduct}=="0001", ENV{ID_AUTOSEAT}="1"
|
||||
|
||||
IMPORT{parent}="ID_SEAT"
|
||||
|
||||
ENV{ID_AUTOSEAT}=="1", ENV{ID_SEAT}=="", ENV{ID_PATH}=="", IMPORT{program}="path_id %p"
|
||||
ENV{ID_AUTOSEAT}=="1", ENV{ID_SEAT}=="", ENV{ID_PATH}!="", ENV{ID_SEAT}="seat-$env{ID_PATH}"
|
||||
|
||||
ENV{ID_SEAT}!="", TAG+="$env{ID_SEAT}"
|
||||
TAG=="seat", ENV{ID_PATH}=="", IMPORT{program}="path_id %p"
|
||||
|
||||
LABEL="seat_end"
|
||||
|
16
src/73-seat-late.rules
Normal file
16
src/73-seat-late.rules
Normal file
@ -0,0 +1,16 @@
|
||||
# This file is part of systemd.
|
||||
#
|
||||
# systemd is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
ACTION=="remove", GOTO="seat_late_end"
|
||||
TAG!="seat", GOTO="seat_late_end"
|
||||
|
||||
ENV{ID_SEAT}=="", ENV{ID_AUTOSEAT}=="1", ENV{ID_PATH}!="", ENV{ID_SEAT}="seat-$env{ID_PATH}"
|
||||
ENV{ID_SEAT}=="", IMPORT{parent}="ID_SEAT"
|
||||
|
||||
ENV{ID_SEAT}!="", TAG+="$env{ID_SEAT}"
|
||||
|
||||
LABEL="seat_late_end"
|
@ -89,6 +89,11 @@
|
||||
" <arg name=\"b\" type=\"b\" direction=\"in\"/>\n" \
|
||||
" <arg name=\"interactive\" type=\"b\" direction=\"in\"/>\n" \
|
||||
" </method>\n" \
|
||||
" <method name=\"AttachDevice\">\n" \
|
||||
" <arg name=\"seat\" type=\"s\" direction=\"in\"/>\n" \
|
||||
" <arg name=\"sysfs\" type=\"s\" direction=\"in\"/>\n" \
|
||||
" <arg name=\"interactive\" type=\"b\" direction=\"in\"/>\n" \
|
||||
" </method>\n" \
|
||||
" <signal name=\"SessionNew\">\n" \
|
||||
" <arg name=\"id\" type=\"s\"/>\n" \
|
||||
" <arg name=\"path\" type=\"o\"/>\n" \
|
||||
@ -531,6 +536,67 @@ fail:
|
||||
return r;
|
||||
}
|
||||
|
||||
static bool device_has_tag(struct udev_device *d, const char *tag) {
|
||||
struct udev_list_entry *first, *item;
|
||||
|
||||
assert(d);
|
||||
assert(tag);
|
||||
|
||||
first = udev_device_get_tags_list_entry(d);
|
||||
udev_list_entry_foreach(item, first)
|
||||
if (streq(udev_list_entry_get_name(item), tag))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int attach_device(Manager *m, const char *seat, const char *sysfs) {
|
||||
struct udev_device *d;
|
||||
char *rule = NULL, *file = NULL;
|
||||
const char *path;
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
assert(seat);
|
||||
assert(sysfs);
|
||||
|
||||
d = udev_device_new_from_syspath(m->udev, sysfs);
|
||||
if (!d)
|
||||
return -ENODEV;
|
||||
|
||||
if (!device_has_tag(d, "seat")) {
|
||||
r = -ENODEV;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
path = udev_device_get_property_value(d, "ID_PATH");
|
||||
if (!path) {
|
||||
r = -ENODEV;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", path) < 0) {
|
||||
r = -ENOMEM;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (asprintf(&rule, "TAG==\"seat\", ID_PATH==\"%s\", ID_SEAT=\"%s\"", path, seat) < 0) {
|
||||
r = -ENOMEM;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
r = write_one_line_file(file, rule);
|
||||
|
||||
finish:
|
||||
free(rule);
|
||||
free(file);
|
||||
|
||||
if (d)
|
||||
udev_device_unref(d);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static DBusHandlerResult manager_message_handler(
|
||||
DBusConnection *connection,
|
||||
DBusMessage *message,
|
||||
@ -957,6 +1023,33 @@ static DBusHandlerResult manager_message_handler(
|
||||
if (!reply)
|
||||
goto oom;
|
||||
|
||||
} else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "AttachDevice")) {
|
||||
const char *sysfs, *seat;
|
||||
dbus_bool_t interactive;
|
||||
|
||||
if (!dbus_message_get_args(
|
||||
message,
|
||||
&error,
|
||||
DBUS_TYPE_STRING, &seat,
|
||||
DBUS_TYPE_STRING, &sysfs,
|
||||
DBUS_TYPE_BOOLEAN, &interactive,
|
||||
DBUS_TYPE_INVALID))
|
||||
return bus_send_error_reply(connection, message, &error, -EINVAL);
|
||||
|
||||
if (!path_startswith(sysfs, "/sys") || !seat_name_is_valid(seat))
|
||||
return bus_send_error_reply(connection, message, NULL, -EINVAL);
|
||||
|
||||
r = verify_polkit(connection, message, "org.freedesktop.login1.attach-device", interactive, &error);
|
||||
if (r < 0)
|
||||
return bus_send_error_reply(connection, message, &error, r);
|
||||
|
||||
r = attach_device(m, seat, sysfs);
|
||||
if (r < 0)
|
||||
return bus_send_error_reply(connection, message, NULL, -EINVAL);
|
||||
|
||||
reply = dbus_message_new_method_return(message);
|
||||
if (!reply)
|
||||
goto oom;
|
||||
|
||||
} else if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Introspectable", "Introspect")) {
|
||||
char *introspection = NULL;
|
||||
|
@ -38,6 +38,7 @@
|
||||
* direct client API
|
||||
* add configuration file
|
||||
* D-Bus method: AttachDevices(seat, devices[]);
|
||||
* use named pipes to detect when a session dies
|
||||
*
|
||||
* non-local X11 server
|
||||
* reboot/shutdown halt management
|
||||
|
@ -26,4 +26,14 @@
|
||||
</defaults>
|
||||
</action>
|
||||
|
||||
<action id="org.freedesktop.login1.attach-device">
|
||||
<description>Allow attaching devices to seats</description>
|
||||
<message>Authentication is required to allow attaching a device to a seat</message>
|
||||
<defaults>
|
||||
<allow_any>auth_admin_keep</allow_any>
|
||||
<allow_inactive>auth_admin_keep</allow_inactive>
|
||||
<allow_active>auth_admin_keep</allow_active>
|
||||
</defaults>
|
||||
</action>
|
||||
|
||||
</policyconfig>
|
||||
|
Loading…
Reference in New Issue
Block a user