mirror of
https://github.com/systemd/systemd
synced 2026-03-13 08:34:47 +01:00
Compare commits
6 Commits
8fe50c025b
...
5276ef1548
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5276ef1548 | ||
|
|
30a1a29d4e | ||
|
|
563b5dedb7 | ||
|
|
753341a221 | ||
|
|
5a198ad6f8 | ||
|
|
87840e144b |
@ -1246,6 +1246,8 @@ node /org/freedesktop/login1/session/1 {
|
|||||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||||
readonly s RemoteUser = '...';
|
readonly s RemoteUser = '...';
|
||||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||||
|
readonly b ExtraDeviceAccess = ...;
|
||||||
|
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||||
readonly s Service = '...';
|
readonly s Service = '...';
|
||||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||||
readonly s Desktop = '...';
|
readonly s Desktop = '...';
|
||||||
@ -1348,6 +1350,8 @@ node /org/freedesktop/login1/session/1 {
|
|||||||
|
|
||||||
<variablelist class="dbus-property" generated="True" extra-ref="RemoteUser"/>
|
<variablelist class="dbus-property" generated="True" extra-ref="RemoteUser"/>
|
||||||
|
|
||||||
|
<variablelist class="dbus-property" generated="True" extra-ref="ExtraDeviceAccess"/>
|
||||||
|
|
||||||
<variablelist class="dbus-property" generated="True" extra-ref="Service"/>
|
<variablelist class="dbus-property" generated="True" extra-ref="Service"/>
|
||||||
|
|
||||||
<variablelist class="dbus-property" generated="True" extra-ref="Desktop"/>
|
<variablelist class="dbus-property" generated="True" extra-ref="Desktop"/>
|
||||||
@ -1537,6 +1541,10 @@ node /org/freedesktop/login1/session/1 {
|
|||||||
<para><varname>RemoteHost</varname> and <varname>RemoteUser</varname> encode the remote host and user
|
<para><varname>RemoteHost</varname> and <varname>RemoteUser</varname> encode the remote host and user
|
||||||
if this is a remote session, or an empty string otherwise.</para>
|
if this is a remote session, or an empty string otherwise.</para>
|
||||||
|
|
||||||
|
<para><varname>ExtraDeviceAccess</varname> encodes whether the session is granted access to additional
|
||||||
|
hardware devices, typically useful for for graphical, remote session. If true, the session is granted
|
||||||
|
access to all devices tagged with <literal>xaccess</literal> in udev.</para>
|
||||||
|
|
||||||
<para><varname>Service</varname> encodes the PAM service name that registered the session.</para>
|
<para><varname>Service</varname> encodes the PAM service name that registered the session.</para>
|
||||||
|
|
||||||
<para><varname>Desktop</varname> describes the desktop environment running in the session (if
|
<para><varname>Desktop</varname> describes the desktop environment running in the session (if
|
||||||
@ -1671,6 +1679,7 @@ node /org/freedesktop/login1/session/1 {
|
|||||||
<para><function>SetTTY()</function> was added in version 254.</para>
|
<para><function>SetTTY()</function> was added in version 254.</para>
|
||||||
<para><function>SetClass()</function> was added in version 256.</para>
|
<para><function>SetClass()</function> was added in version 256.</para>
|
||||||
<para><varname>LeaderPIDFDId</varname> was added in version 258.</para>
|
<para><varname>LeaderPIDFDId</varname> was added in version 258.</para>
|
||||||
|
<para><varname>ExtraDeviceAccess</varname> was added in version 260.</para>
|
||||||
</refsect2>
|
</refsect2>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
|
|||||||
@ -404,6 +404,17 @@
|
|||||||
|
|
||||||
<xi:include href="version-info.xml" xpointer="v258"/></listitem>
|
<xi:include href="version-info.xml" xpointer="v258"/></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>$XDG_SESSION_EXTRA_DEVICE_ACCESS</varname></term>
|
||||||
|
|
||||||
|
<listitem><para>Whether or not the session shall be granted additional hardware device access,
|
||||||
|
typically useful for graphical, remote session. If true, the session is granted access to all
|
||||||
|
devices tagged with <literal>xaccess</literal> in udev. Typically, rendering device nodes of
|
||||||
|
the GPU are tagged like this.</para>
|
||||||
|
|
||||||
|
<xi:include href="version-info.xml" xpointer="v260"/></listitem>
|
||||||
|
</varlistentry>
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
|
||||||
<para>If not set, <command>pam_systemd</command> will initialize
|
<para>If not set, <command>pam_systemd</command> will initialize
|
||||||
|
|||||||
@ -182,6 +182,25 @@
|
|||||||
<xi:include href="version-info.xml" xpointer="v235"/></listitem>
|
<xi:include href="version-info.xml" xpointer="v235"/></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term>Tag <literal>uaccess</literal></term>
|
||||||
|
|
||||||
|
<listitem><para>When set, access to this device is tied to an active seat.
|
||||||
|
As the session on the seat becomes active or inactive, access to the device
|
||||||
|
is updated accordingly.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term>Tag <literal>xaccess</literal></term>
|
||||||
|
|
||||||
|
<listitem><para>When set, access to this device is granted to sessions
|
||||||
|
created with <literal>ExtraDeviceAccess</literal>. This is typically useful
|
||||||
|
for graphical, remote sessions. As the <literal>ExtraDeviceAccess</literal>
|
||||||
|
sessions open and close, access to the device is updated accordingly.</para>
|
||||||
|
|
||||||
|
<xi:include href="version-info.xml" xpointer="v260"/></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>Property <varname>ID_SEAT</varname></term>
|
<term>Property <varname>ID_SEAT</varname></term>
|
||||||
|
|
||||||
|
|||||||
@ -34,6 +34,7 @@
|
|||||||
<refname>sd_session_get_remote_host</refname>
|
<refname>sd_session_get_remote_host</refname>
|
||||||
<refname>sd_session_get_remote_user</refname>
|
<refname>sd_session_get_remote_user</refname>
|
||||||
<refname>sd_session_get_leader</refname>
|
<refname>sd_session_get_leader</refname>
|
||||||
|
<refname>sd_session_has_extra_device_access</refname>
|
||||||
<refpurpose>Determine state of a specific session</refpurpose>
|
<refpurpose>Determine state of a specific session</refpurpose>
|
||||||
</refnamediv>
|
</refnamediv>
|
||||||
|
|
||||||
@ -140,6 +141,11 @@
|
|||||||
<paramdef>const char *<parameter>session</parameter></paramdef>
|
<paramdef>const char *<parameter>session</parameter></paramdef>
|
||||||
<paramdef>unsigned int *<parameter>vt</parameter></paramdef>
|
<paramdef>unsigned int *<parameter>vt</parameter></paramdef>
|
||||||
</funcprototype>
|
</funcprototype>
|
||||||
|
|
||||||
|
<funcprototype>
|
||||||
|
<funcdef>int <function>sd_session_has_extra_device_access</function></funcdef>
|
||||||
|
<paramdef>const char *<parameter>session</parameter></paramdef>
|
||||||
|
</funcprototype>
|
||||||
</funcsynopsis>
|
</funcsynopsis>
|
||||||
</refsynopsisdiv>
|
</refsynopsisdiv>
|
||||||
|
|
||||||
@ -274,6 +280,12 @@
|
|||||||
session identifier. This function will return an error if the seat
|
session identifier. This function will return an error if the seat
|
||||||
does not support VTs.</para>
|
does not support VTs.</para>
|
||||||
|
|
||||||
|
<para><function>sd_session_has_extra_device_access()</function> may
|
||||||
|
be used to determine whether the session is granted access to
|
||||||
|
additional hardware devices, typically useful for for graphical,
|
||||||
|
remote session. If true, the session is granted access to all
|
||||||
|
devices tagged with <literal>xaccess</literal> in udev.</para>
|
||||||
|
|
||||||
<para>If the <varname>session</varname> parameter of any of these
|
<para>If the <varname>session</varname> parameter of any of these
|
||||||
functions is passed as <constant>NULL</constant>, the operation is
|
functions is passed as <constant>NULL</constant>, the operation is
|
||||||
executed for the session the calling process is a member of, if
|
executed for the session the calling process is a member of, if
|
||||||
@ -284,9 +296,10 @@
|
|||||||
<title>Return Value</title>
|
<title>Return Value</title>
|
||||||
|
|
||||||
<para>If the test succeeds,
|
<para>If the test succeeds,
|
||||||
<function>sd_session_is_active()</function> and
|
<function>sd_session_is_active()</function>,
|
||||||
<function>sd_session_is_remote()</function> return a
|
<function>sd_session_is_remote()</function>, and
|
||||||
positive integer; if it fails, 0. On success,
|
<function>sd_session_has_extra_device_access()</function>
|
||||||
|
return a positive integer; if it fails, 0. On success,
|
||||||
<function>sd_session_get_state()</function>,
|
<function>sd_session_get_state()</function>,
|
||||||
<function>sd_session_get_uid()</function>,
|
<function>sd_session_get_uid()</function>,
|
||||||
<function>sd_session_get_username()</function>,
|
<function>sd_session_get_username()</function>,
|
||||||
@ -353,6 +366,7 @@
|
|||||||
<para><function>sd_session_get_username()</function>,
|
<para><function>sd_session_get_username()</function>,
|
||||||
<function>sd_session_get_start_time()</function>, and
|
<function>sd_session_get_start_time()</function>, and
|
||||||
<function>sd_session_get_leader()</function> were added in version 254.</para>
|
<function>sd_session_get_leader()</function> were added in version 254.</para>
|
||||||
|
<para><function>sd_session_has_extra_device_access()</function> was added in version 260.</para>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
<refsect1>
|
<refsect1>
|
||||||
|
|||||||
@ -46,7 +46,7 @@ SUBSYSTEM=="firewire", TEST=="units", ENV{IEEE1394_UNIT_FUNCTION_VIDEO}=="1", TA
|
|||||||
SUBSYSTEM=="drm", KERNEL=="card*", TAG+="uaccess"
|
SUBSYSTEM=="drm", KERNEL=="card*", TAG+="uaccess"
|
||||||
{% if GROUP_RENDER_UACCESS %}
|
{% if GROUP_RENDER_UACCESS %}
|
||||||
# DRI render nodes
|
# DRI render nodes
|
||||||
SUBSYSTEM=="drm", KERNEL=="renderD*", TAG+="uaccess"
|
SUBSYSTEM=="drm", KERNEL=="renderD*", TAG+="uaccess", TAG+="xaccess"
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if DEV_KVM_UACCESS %}
|
{% if DEV_KVM_UACCESS %}
|
||||||
# KVM
|
# KVM
|
||||||
|
|||||||
@ -14,7 +14,7 @@ ENV{ID_SEAT}=="", IMPORT{parent}="ID_SEAT"
|
|||||||
|
|
||||||
ENV{ID_SEAT}!="", TAG+="$env{ID_SEAT}"
|
ENV{ID_SEAT}!="", TAG+="$env{ID_SEAT}"
|
||||||
{% if HAVE_ACL %}
|
{% if HAVE_ACL %}
|
||||||
TAG=="uaccess", ENV{MAJOR}!="", RUN{builtin}+="uaccess"
|
TAG=="uaccess|xaccess", ENV{MAJOR}!="", RUN{builtin}+="uaccess"
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
LABEL="seat_late_end"
|
LABEL="seat_late_end"
|
||||||
|
|||||||
@ -697,6 +697,7 @@ int manager_default_environment(Manager *m) {
|
|||||||
"XDG_SESSION_CLASS",
|
"XDG_SESSION_CLASS",
|
||||||
"XDG_SESSION_TYPE",
|
"XDG_SESSION_TYPE",
|
||||||
"XDG_SESSION_DESKTOP",
|
"XDG_SESSION_DESKTOP",
|
||||||
|
"XDG_SESSION_EXTRA_DEVICE_ACCESS",
|
||||||
"XDG_SEAT",
|
"XDG_SEAT",
|
||||||
"XDG_VTNR");
|
"XDG_VTNR");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1085,3 +1085,8 @@ global:
|
|||||||
sd_event_get_exit_on_idle;
|
sd_event_get_exit_on_idle;
|
||||||
sd_varlink_is_connected;
|
sd_varlink_is_connected;
|
||||||
} LIBSYSTEMD_258;
|
} LIBSYSTEMD_258;
|
||||||
|
|
||||||
|
LIBSYSTEMD_260 {
|
||||||
|
global:
|
||||||
|
sd_session_has_extra_device_access;
|
||||||
|
} LIBSYSTEMD_259;
|
||||||
|
|||||||
@ -677,6 +677,25 @@ _public_ int sd_session_is_remote(const char *session) {
|
|||||||
return parse_boolean(s);
|
return parse_boolean(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_public_ int sd_session_has_extra_device_access(const char *session) {
|
||||||
|
_cleanup_free_ char *p = NULL, *s = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
r = file_of_session(session, &p);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = parse_env_file(/* f= */ NULL, p, "EXTRA_DEVICE_ACCESS", &s);
|
||||||
|
if (r == -ENOENT)
|
||||||
|
return -ENXIO;
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
if (isempty(s))
|
||||||
|
return -ENODATA;
|
||||||
|
|
||||||
|
return parse_boolean(s);
|
||||||
|
}
|
||||||
|
|
||||||
_public_ int sd_session_get_state(const char *session, char **ret_state) {
|
_public_ int sd_session_get_state(const char *session, char **ret_state) {
|
||||||
_cleanup_free_ char *p = NULL, *s = NULL;
|
_cleanup_free_ char *p = NULL, *s = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
|||||||
@ -898,6 +898,7 @@ int manager_create_session(
|
|||||||
bool remote,
|
bool remote,
|
||||||
const char *remote_user,
|
const char *remote_user,
|
||||||
const char *remote_host,
|
const char *remote_host,
|
||||||
|
bool extra_device_access,
|
||||||
Session **ret_session) {
|
Session **ret_session) {
|
||||||
|
|
||||||
bool mangle_class = false;
|
bool mangle_class = false;
|
||||||
@ -1004,6 +1005,7 @@ int manager_create_session(
|
|||||||
|
|
||||||
session->original_type = session->type = type;
|
session->original_type = session->type = type;
|
||||||
session->remote = remote;
|
session->remote = remote;
|
||||||
|
session->extra_device_access = extra_device_access;
|
||||||
session->vtnr = vtnr;
|
session->vtnr = vtnr;
|
||||||
session->class = class;
|
session->class = class;
|
||||||
|
|
||||||
@ -1227,6 +1229,7 @@ static int manager_create_session_by_bus(
|
|||||||
remote,
|
remote,
|
||||||
remote_user,
|
remote_user,
|
||||||
remote_host,
|
remote_host,
|
||||||
|
/* extra_device_access= */ false,
|
||||||
&session);
|
&session);
|
||||||
if (r == -EBUSY)
|
if (r == -EBUSY)
|
||||||
return sd_bus_error_set(error, BUS_ERROR_SESSION_BUSY, "Already running in a session or user slice");
|
return sd_bus_error_set(error, BUS_ERROR_SESSION_BUSY, "Already running in a session or user slice");
|
||||||
|
|||||||
@ -57,6 +57,7 @@ int manager_create_session(
|
|||||||
bool remote,
|
bool remote,
|
||||||
const char *remote_user,
|
const char *remote_user,
|
||||||
const char *remote_host,
|
const char *remote_host,
|
||||||
|
bool extra_device_access,
|
||||||
Session **ret_session);
|
Session **ret_session);
|
||||||
|
|
||||||
extern const BusObjectImplementation manager_object;
|
extern const BusObjectImplementation manager_object;
|
||||||
|
|||||||
@ -35,6 +35,7 @@
|
|||||||
#include "tmpfile-util.h"
|
#include "tmpfile-util.h"
|
||||||
#include "udev-util.h"
|
#include "udev-util.h"
|
||||||
#include "user-record.h"
|
#include "user-record.h"
|
||||||
|
#include "user-util.h"
|
||||||
|
|
||||||
int seat_new(Manager *m, const char *id, Seat **ret) {
|
int seat_new(Manager *m, const char *id, Seat **ret) {
|
||||||
_cleanup_(seat_freep) Seat *s = NULL;
|
_cleanup_(seat_freep) Seat *s = NULL;
|
||||||
@ -330,14 +331,15 @@ static int seat_trigger_devices(Seat *s) {
|
|||||||
static int static_node_acl(Seat *s) {
|
static int static_node_acl(Seat *s) {
|
||||||
#if HAVE_ACL
|
#if HAVE_ACL
|
||||||
int r, ret = 0;
|
int r, ret = 0;
|
||||||
uid_t uid;
|
_cleanup_set_free_ Set *uids = NULL;
|
||||||
|
|
||||||
assert(s);
|
assert(s);
|
||||||
|
|
||||||
if (s->active)
|
if (s->active) {
|
||||||
uid = s->active->user->user_record->uid;
|
r = set_ensure_put(&uids, NULL, UID_TO_PTR(s->active->user->user_record->uid));
|
||||||
else
|
if (r < 0)
|
||||||
uid = 0;
|
return log_oom();
|
||||||
|
}
|
||||||
|
|
||||||
_cleanup_closedir_ DIR *dir = opendir("/run/udev/static_node-tags/uaccess/");
|
_cleanup_closedir_ DIR *dir = opendir("/run/udev/static_node-tags/uaccess/");
|
||||||
if (!dir) {
|
if (!dir) {
|
||||||
@ -377,7 +379,7 @@ static int static_node_acl(Seat *s) {
|
|||||||
if (!ERRNO_IS_NEG_DEVICE_ABSENT_OR_EMPTY(r))
|
if (!ERRNO_IS_NEG_DEVICE_ABSENT_OR_EMPTY(r))
|
||||||
log_debug_errno(r, "Failed to check if '/run/udev/static_node-tags/uaccess/%s' points to a static device node, ignoring: %m", de->d_name);
|
log_debug_errno(r, "Failed to check if '/run/udev/static_node-tags/uaccess/%s' points to a static device node, ignoring: %m", de->d_name);
|
||||||
|
|
||||||
r = devnode_acl(fd, uid);
|
r = devnode_acl(fd, uids);
|
||||||
if (r >= 0 || r == -ENOENT)
|
if (r >= 0 || r == -ENOENT)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -385,11 +387,11 @@ static int static_node_acl(Seat *s) {
|
|||||||
_cleanup_free_ char *node = NULL;
|
_cleanup_free_ char *node = NULL;
|
||||||
(void) fd_get_path(fd, &node);
|
(void) fd_get_path(fd, &node);
|
||||||
|
|
||||||
if (uid != 0) {
|
if (!set_isempty(uids)) {
|
||||||
RET_GATHER(ret, log_debug_errno(r, "Failed to apply ACL on '%s': %m", node ?: de->d_name));
|
RET_GATHER(ret, log_debug_errno(r, "Failed to apply ACL on '%s': %m", node ?: de->d_name));
|
||||||
|
|
||||||
/* Better be safe than sorry and reset ACL */
|
/* Better be safe than sorry and reset ACL */
|
||||||
r = devnode_acl(fd, /* uid= */ 0);
|
r = devnode_acl(fd, /* uids= */ NULL);
|
||||||
if (r >= 0 || r == -ENOENT)
|
if (r >= 0 || r == -ENOENT)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -985,6 +985,7 @@ static const sd_bus_vtable session_vtable[] = {
|
|||||||
SD_BUS_PROPERTY("Remote", "b", bus_property_get_bool, offsetof(Session, remote), 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("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("RemoteUser", "s", NULL, offsetof(Session, remote_user), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
|
SD_BUS_PROPERTY("ExtraDeviceAccess", "b", bus_property_get_bool, offsetof(Session, extra_device_access), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
SD_BUS_PROPERTY("Service", "s", NULL, offsetof(Session, service), 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("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("Scope", "s", NULL, offsetof(Session, scope), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
|
|||||||
@ -9,6 +9,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "sd-bus.h"
|
#include "sd-bus.h"
|
||||||
|
#include "sd-device.h"
|
||||||
#include "sd-event.h"
|
#include "sd-event.h"
|
||||||
#include "sd-messages.h"
|
#include "sd-messages.h"
|
||||||
#include "sd-varlink.h"
|
#include "sd-varlink.h"
|
||||||
@ -18,6 +19,7 @@
|
|||||||
#include "bus-error.h"
|
#include "bus-error.h"
|
||||||
#include "bus-util.h"
|
#include "bus-util.h"
|
||||||
#include "daemon-util.h"
|
#include "daemon-util.h"
|
||||||
|
#include "device-util.h"
|
||||||
#include "devnum-util.h"
|
#include "devnum-util.h"
|
||||||
#include "env-file.h"
|
#include "env-file.h"
|
||||||
#include "errno-util.h"
|
#include "errno-util.h"
|
||||||
@ -276,6 +278,46 @@ static void session_save_devices(Session *s, FILE *f) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int trigger_xaccess(void) {
|
||||||
|
int r;
|
||||||
|
|
||||||
|
_cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
|
||||||
|
r = sd_device_enumerator_new(&e);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = sd_device_enumerator_add_match_tag(e, "xaccess");
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
FOREACH_DEVICE(e, d) {
|
||||||
|
/* Verify that the tag is still in place. */
|
||||||
|
r = sd_device_has_current_tag(d, "xaccess");
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
if (r == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* In case people mistag devices without nodes, we need to ignore this. */
|
||||||
|
r = sd_device_get_devname(d, NULL);
|
||||||
|
if (r == -ENOENT)
|
||||||
|
continue;
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
sd_id128_t uuid;
|
||||||
|
r = sd_device_trigger_with_uuid(d, SD_DEVICE_CHANGE, &uuid);
|
||||||
|
if (r < 0) {
|
||||||
|
log_device_debug_errno(d, r, "Failed to trigger 'change' event, ignoring: %m");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
log_device_debug(d, "Triggered synthetic event (ACTION=change, UUID=%s).", SD_ID128_TO_UUID_STRING(uuid));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int session_save(Session *s) {
|
int session_save(Session *s) {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
@ -307,12 +349,14 @@ int session_save(Session *s) {
|
|||||||
"IS_DISPLAY=%s\n"
|
"IS_DISPLAY=%s\n"
|
||||||
"STATE=%s\n"
|
"STATE=%s\n"
|
||||||
"REMOTE=%s\n"
|
"REMOTE=%s\n"
|
||||||
|
"EXTRA_DEVICE_ACCESS=%s\n"
|
||||||
"LEADER_FD_SAVED=%s\n",
|
"LEADER_FD_SAVED=%s\n",
|
||||||
s->user->user_record->uid,
|
s->user->user_record->uid,
|
||||||
one_zero(session_is_active(s)),
|
one_zero(session_is_active(s)),
|
||||||
one_zero(s->user->display == s),
|
one_zero(s->user->display == s),
|
||||||
session_state_to_string(session_get_state(s)),
|
session_state_to_string(session_get_state(s)),
|
||||||
one_zero(s->remote),
|
one_zero(s->remote),
|
||||||
|
one_zero(s->extra_device_access),
|
||||||
one_zero(s->leader_fd_saved));
|
one_zero(s->leader_fd_saved));
|
||||||
|
|
||||||
env_file_fputs_assignment(f, "USER=", s->user->user_record->user_name);
|
env_file_fputs_assignment(f, "USER=", s->user->user_record->user_name);
|
||||||
@ -453,6 +497,7 @@ static int session_load_leader(Session *s, uint64_t pidfdid) {
|
|||||||
|
|
||||||
int session_load(Session *s) {
|
int session_load(Session *s) {
|
||||||
_cleanup_free_ char *remote = NULL,
|
_cleanup_free_ char *remote = NULL,
|
||||||
|
*extra_device_access = NULL,
|
||||||
*seat = NULL,
|
*seat = NULL,
|
||||||
*tty_validity = NULL,
|
*tty_validity = NULL,
|
||||||
*vtnr = NULL,
|
*vtnr = NULL,
|
||||||
@ -479,6 +524,7 @@ int session_load(Session *s) {
|
|||||||
|
|
||||||
r = parse_env_file(NULL, s->state_file,
|
r = parse_env_file(NULL, s->state_file,
|
||||||
"REMOTE", &remote,
|
"REMOTE", &remote,
|
||||||
|
"EXTRA_DEVICE_ACCESS", &extra_device_access,
|
||||||
"SCOPE", &s->scope,
|
"SCOPE", &s->scope,
|
||||||
"SCOPE_JOB", &s->scope_job,
|
"SCOPE_JOB", &s->scope_job,
|
||||||
"FIFO", &fifo_path,
|
"FIFO", &fifo_path,
|
||||||
@ -539,6 +585,12 @@ int session_load(Session *s) {
|
|||||||
s->remote = k;
|
s->remote = k;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (extra_device_access) {
|
||||||
|
k = parse_boolean(extra_device_access);
|
||||||
|
if (k >= 0)
|
||||||
|
s->extra_device_access = k;
|
||||||
|
}
|
||||||
|
|
||||||
if (vtnr)
|
if (vtnr)
|
||||||
(void) safe_atou(vtnr, &s->vtnr);
|
(void) safe_atou(vtnr, &s->vtnr);
|
||||||
|
|
||||||
@ -863,6 +915,9 @@ int session_start(Session *s, sd_bus_message *properties, sd_bus_error *error) {
|
|||||||
if (s->seat)
|
if (s->seat)
|
||||||
(void) seat_save(s->seat);
|
(void) seat_save(s->seat);
|
||||||
|
|
||||||
|
if (s->extra_device_access)
|
||||||
|
(void) trigger_xaccess();
|
||||||
|
|
||||||
/* Send signals */
|
/* Send signals */
|
||||||
(void) session_send_signal(s, true);
|
(void) session_send_signal(s, true);
|
||||||
(void) user_send_changed(s->user, "Display");
|
(void) user_send_changed(s->user, "Display");
|
||||||
@ -953,6 +1008,9 @@ int session_stop(Session *s, bool force) {
|
|||||||
(void) session_save(s);
|
(void) session_save(s);
|
||||||
(void) user_save(s->user);
|
(void) user_save(s->user);
|
||||||
|
|
||||||
|
if (s->extra_device_access)
|
||||||
|
(void) trigger_xaccess();
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -121,6 +121,7 @@ typedef struct Session {
|
|||||||
char *remote_host;
|
char *remote_host;
|
||||||
char *service;
|
char *service;
|
||||||
char *desktop;
|
char *desktop;
|
||||||
|
bool extra_device_access;
|
||||||
|
|
||||||
char *scope;
|
char *scope;
|
||||||
char *scope_job;
|
char *scope_job;
|
||||||
|
|||||||
@ -145,6 +145,7 @@ typedef struct CreateSessionParameters {
|
|||||||
int remote;
|
int remote;
|
||||||
const char *remote_user;
|
const char *remote_user;
|
||||||
const char *remote_host;
|
const char *remote_host;
|
||||||
|
bool extra_device_access;
|
||||||
} CreateSessionParameters;
|
} CreateSessionParameters;
|
||||||
|
|
||||||
static void create_session_parameters_done(CreateSessionParameters *p) {
|
static void create_session_parameters_done(CreateSessionParameters *p) {
|
||||||
@ -169,6 +170,7 @@ static int vl_method_create_session(sd_varlink *link, sd_json_variant *parameter
|
|||||||
{ "Remote", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_tristate, offsetof(CreateSessionParameters, remote), 0 },
|
{ "Remote", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_tristate, offsetof(CreateSessionParameters, remote), 0 },
|
||||||
{ "RemoteUser", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, offsetof(CreateSessionParameters, remote_user), 0 },
|
{ "RemoteUser", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, offsetof(CreateSessionParameters, remote_user), 0 },
|
||||||
{ "RemoteHost", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, offsetof(CreateSessionParameters, remote_host), 0 },
|
{ "RemoteHost", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, offsetof(CreateSessionParameters, remote_host), 0 },
|
||||||
|
{ "ExtraDeviceAccess", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_stdbool, offsetof(CreateSessionParameters, extra_device_access), 0 },
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -178,6 +180,7 @@ static int vl_method_create_session(sd_varlink *link, sd_json_variant *parameter
|
|||||||
.class = _SESSION_CLASS_INVALID,
|
.class = _SESSION_CLASS_INVALID,
|
||||||
.type = _SESSION_TYPE_INVALID,
|
.type = _SESSION_TYPE_INVALID,
|
||||||
.remote = -1,
|
.remote = -1,
|
||||||
|
.extra_device_access = false,
|
||||||
};
|
};
|
||||||
|
|
||||||
r = sd_varlink_dispatch(link, parameters, dispatch_table, &p);
|
r = sd_varlink_dispatch(link, parameters, dispatch_table, &p);
|
||||||
@ -264,6 +267,7 @@ static int vl_method_create_session(sd_varlink *link, sd_json_variant *parameter
|
|||||||
p.remote,
|
p.remote,
|
||||||
p.remote_user,
|
p.remote_user,
|
||||||
p.remote_host,
|
p.remote_host,
|
||||||
|
p.extra_device_access,
|
||||||
&session);
|
&session);
|
||||||
if (r == -EBUSY)
|
if (r == -EBUSY)
|
||||||
return sd_varlink_error(link, "io.systemd.Login.AlreadySessionMember", /* parameters= */ NULL);
|
return sd_varlink_error(link, "io.systemd.Login.AlreadySessionMember", /* parameters= */ NULL);
|
||||||
|
|||||||
@ -814,6 +814,7 @@ typedef struct SessionContext {
|
|||||||
uint32_t vtnr;
|
uint32_t vtnr;
|
||||||
const char *tty;
|
const char *tty;
|
||||||
const char *display;
|
const char *display;
|
||||||
|
bool extra_device_access;
|
||||||
bool remote;
|
bool remote;
|
||||||
const char *remote_user;
|
const char *remote_user;
|
||||||
const char *remote_host;
|
const char *remote_host;
|
||||||
@ -1148,7 +1149,8 @@ static int register_session(
|
|||||||
JSON_BUILD_PAIR_STRING_NON_EMPTY("Display", c->display),
|
JSON_BUILD_PAIR_STRING_NON_EMPTY("Display", c->display),
|
||||||
SD_JSON_BUILD_PAIR_BOOLEAN("Remote", c->remote),
|
SD_JSON_BUILD_PAIR_BOOLEAN("Remote", c->remote),
|
||||||
JSON_BUILD_PAIR_STRING_NON_EMPTY("RemoteUser", c->remote_user),
|
JSON_BUILD_PAIR_STRING_NON_EMPTY("RemoteUser", c->remote_user),
|
||||||
JSON_BUILD_PAIR_STRING_NON_EMPTY("RemoteHost", c->remote_host));
|
JSON_BUILD_PAIR_STRING_NON_EMPTY("RemoteHost", c->remote_host),
|
||||||
|
JSON_BUILD_PAIR_CONDITION_BOOLEAN(c->extra_device_access, "ExtraDeviceAccess", c->extra_device_access));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return pam_syslog_errno(pamh, LOG_ERR, r,
|
return pam_syslog_errno(pamh, LOG_ERR, r,
|
||||||
"Failed to issue io.systemd.Login.CreateSession varlink call: %m");
|
"Failed to issue io.systemd.Login.CreateSession varlink call: %m");
|
||||||
@ -1315,6 +1317,10 @@ static int register_session(
|
|||||||
if (r != PAM_SUCCESS)
|
if (r != PAM_SUCCESS)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
r = update_environment(pamh, "XDG_SESSION_EXTRA_DEVICE_ACCESS", one_zero(c->extra_device_access));
|
||||||
|
if (r != PAM_SUCCESS)
|
||||||
|
return r;
|
||||||
|
|
||||||
r = update_environment(pamh, "XDG_SEAT", real_seat);
|
r = update_environment(pamh, "XDG_SEAT", real_seat);
|
||||||
if (r != PAM_SUCCESS)
|
if (r != PAM_SUCCESS)
|
||||||
return r;
|
return r;
|
||||||
@ -1781,6 +1787,7 @@ _public_ PAM_EXTERN int pam_sm_open_session(
|
|||||||
c.desktop = getenv_harder(pamh, "XDG_SESSION_DESKTOP", desktop_pam);
|
c.desktop = getenv_harder(pamh, "XDG_SESSION_DESKTOP", desktop_pam);
|
||||||
c.area = getenv_harder(pamh, "XDG_AREA", area_pam);
|
c.area = getenv_harder(pamh, "XDG_AREA", area_pam);
|
||||||
c.incomplete = getenv_harder_bool(pamh, "XDG_SESSION_INCOMPLETE", false);
|
c.incomplete = getenv_harder_bool(pamh, "XDG_SESSION_INCOMPLETE", false);
|
||||||
|
c.extra_device_access = getenv_harder_bool(pamh, "XDG_SESSION_EXTRA_DEVICE_ACCESS", false);
|
||||||
|
|
||||||
r = pam_get_data_many(
|
r = pam_get_data_many(
|
||||||
pamh,
|
pamh,
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
#include "errno-util.h"
|
#include "errno-util.h"
|
||||||
#include "extract-word.h"
|
#include "extract-word.h"
|
||||||
#include "fd-util.h"
|
#include "fd-util.h"
|
||||||
|
#include "set.h"
|
||||||
#include "string-util.h"
|
#include "string-util.h"
|
||||||
#include "strv.h"
|
#include "strv.h"
|
||||||
#include "user-util.h"
|
#include "user-util.h"
|
||||||
@ -80,8 +81,9 @@ int dlopen_libacl(void) {
|
|||||||
DLSYM_ARG(acl_to_any_text));
|
DLSYM_ARG(acl_to_any_text));
|
||||||
}
|
}
|
||||||
|
|
||||||
int devnode_acl(int fd, uid_t uid) {
|
int devnode_acl(int fd, const Set *uids) {
|
||||||
bool changed = false, found = false;
|
_cleanup_set_free_ Set *found = NULL;
|
||||||
|
bool changed = false;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(fd >= 0);
|
assert(fd >= 0);
|
||||||
@ -107,12 +109,12 @@ int devnode_acl(int fd, uid_t uid) {
|
|||||||
if (tag != ACL_USER)
|
if (tag != ACL_USER)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (uid > 0) {
|
if (!set_isempty(uids)) {
|
||||||
uid_t *u = sym_acl_get_qualifier(entry);
|
uid_t *u = sym_acl_get_qualifier(entry);
|
||||||
if (!u)
|
if (!u)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
if (*u == uid) {
|
if (set_contains(uids, UID_TO_PTR(*u))) {
|
||||||
acl_permset_t permset;
|
acl_permset_t permset;
|
||||||
if (sym_acl_get_permset(entry, &permset) < 0)
|
if (sym_acl_get_permset(entry, &permset) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
@ -132,7 +134,10 @@ int devnode_acl(int fd, uid_t uid) {
|
|||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
found = true;
|
r = set_ensure_put(&found, NULL, UID_TO_PTR(*u));
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -145,7 +150,16 @@ int devnode_acl(int fd, uid_t uid) {
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
if (!found && uid > 0) {
|
void *p;
|
||||||
|
SET_FOREACH(p, uids) {
|
||||||
|
uid_t uid = PTR_TO_UID(p);
|
||||||
|
|
||||||
|
if (uid == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (set_contains(found, UID_TO_PTR(uid)))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (sym_acl_create_entry(&acl, &entry) < 0)
|
if (sym_acl_create_entry(&acl, &entry) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
|
|||||||
@ -38,7 +38,7 @@ extern DLSYM_PROTOTYPE(acl_to_any_text);
|
|||||||
|
|
||||||
int dlopen_libacl(void);
|
int dlopen_libacl(void);
|
||||||
|
|
||||||
int devnode_acl(int fd, uid_t uid);
|
int devnode_acl(int fd, const Set *uids);
|
||||||
|
|
||||||
int calc_acl_mask_if_needed(acl_t *acl_p);
|
int calc_acl_mask_if_needed(acl_t *acl_p);
|
||||||
int add_base_acls_if_needed(acl_t *acl_p, const char *path);
|
int add_base_acls_if_needed(acl_t *acl_p, const char *path);
|
||||||
@ -89,7 +89,7 @@ static inline int dlopen_libacl(void) {
|
|||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int devnode_acl(int fd, uid_t uid) {
|
static inline int devnode_acl(int fd, const Set *uids) {
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -65,6 +65,10 @@ static SD_VARLINK_DEFINE_METHOD(
|
|||||||
SD_VARLINK_DEFINE_INPUT(RemoteUser, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
SD_VARLINK_DEFINE_INPUT(RemoteUser, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||||
SD_VARLINK_FIELD_COMMENT("Host name of the remote host"),
|
SD_VARLINK_FIELD_COMMENT("Host name of the remote host"),
|
||||||
SD_VARLINK_DEFINE_INPUT(RemoteHost, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
SD_VARLINK_DEFINE_INPUT(RemoteHost, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||||
|
SD_VARLINK_FIELD_COMMENT("If true this session is granted access to additional hardware devices, "
|
||||||
|
"typically useful for remote, graphical sessions. "
|
||||||
|
"This adds access for all devices tagged with \"xaccess\" in udev."),
|
||||||
|
SD_VARLINK_DEFINE_INPUT(ExtraDeviceAccess, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE),
|
||||||
SD_VARLINK_FIELD_COMMENT("The identifier string of the session of the user."),
|
SD_VARLINK_FIELD_COMMENT("The identifier string of the session of the user."),
|
||||||
SD_VARLINK_DEFINE_OUTPUT(Id, SD_VARLINK_STRING, 0),
|
SD_VARLINK_DEFINE_OUTPUT(Id, SD_VARLINK_STRING, 0),
|
||||||
SD_VARLINK_FIELD_COMMENT("The runtime path ($XDG_RUNTIME_DIR) of the user."),
|
SD_VARLINK_FIELD_COMMENT("The runtime path ($XDG_RUNTIME_DIR) of the user."),
|
||||||
|
|||||||
@ -150,6 +150,9 @@ int sd_session_is_active(const char *session);
|
|||||||
/* Return 1 if the session is remote. */
|
/* Return 1 if the session is remote. */
|
||||||
int sd_session_is_remote(const char *session);
|
int sd_session_is_remote(const char *session);
|
||||||
|
|
||||||
|
/* Return 1 if the session is granted extra device access. */
|
||||||
|
int sd_session_has_extra_device_access(const char *session);
|
||||||
|
|
||||||
/* Get state from session. Possible states: online, active, closing.
|
/* Get state from session. Possible states: online, active, closing.
|
||||||
* This function is a more generic version of sd_session_is_active(). */
|
* This function is a more generic version of sd_session_is_active(). */
|
||||||
int sd_session_get_state(const char *session, char **ret_state);
|
int sd_session_get_state(const char *session, char **ret_state);
|
||||||
|
|||||||
@ -3,15 +3,23 @@
|
|||||||
#include "sd-login.h"
|
#include "sd-login.h"
|
||||||
|
|
||||||
#include "acl-util.h"
|
#include "acl-util.h"
|
||||||
|
#include "alloc-util.h"
|
||||||
#include "device-util.h"
|
#include "device-util.h"
|
||||||
#include "errno-util.h"
|
#include "errno-util.h"
|
||||||
#include "fd-util.h"
|
#include "fd-util.h"
|
||||||
#include "login-util.h"
|
#include "login-util.h"
|
||||||
|
#include "set.h"
|
||||||
|
#include "string-util.h"
|
||||||
|
#include "strv.h"
|
||||||
#include "udev-builtin.h"
|
#include "udev-builtin.h"
|
||||||
|
#include "user-util.h"
|
||||||
|
|
||||||
static int builtin_uaccess(UdevEvent *event, int argc, char *argv[]) {
|
static int builtin_uaccess(UdevEvent *event, int argc, char *argv[]) {
|
||||||
sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev);
|
sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev);
|
||||||
int r, k;
|
_cleanup_strv_free_ char **sessions = NULL;
|
||||||
|
_cleanup_set_free_ Set *uids = NULL;
|
||||||
|
uid_t uid;
|
||||||
|
int r = 0, k;
|
||||||
|
|
||||||
if (event->event_mode != EVENT_UDEV_WORKER) {
|
if (event->event_mode != EVENT_UDEV_WORKER) {
|
||||||
log_device_debug(dev, "Running in test mode, skipping execution of 'uaccess' builtin command.");
|
log_device_debug(dev, "Running in test mode, skipping execution of 'uaccess' builtin command.");
|
||||||
@ -33,24 +41,62 @@ static int builtin_uaccess(UdevEvent *event, int argc, char *argv[]) {
|
|||||||
return ignore ? 0 : fd;
|
return ignore ? 0 : fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r = sd_device_has_tag(dev, "uaccess");
|
||||||
|
if (r < 0)
|
||||||
|
return log_device_error_errno(dev, r, "Failed to query uaccess tag: %m");
|
||||||
|
|
||||||
|
if (r > 0) {
|
||||||
const char *seat;
|
const char *seat;
|
||||||
r = device_get_seat(dev, &seat);
|
r = device_get_seat(dev, &seat);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_device_error_errno(dev, r, "Failed to get seat: %m");
|
return log_device_error_errno(dev, r, "Failed to get seat: %m");
|
||||||
|
|
||||||
uid_t uid;
|
|
||||||
r = sd_seat_get_active(seat, /* ret_session= */ NULL, &uid);
|
r = sd_seat_get_active(seat, /* ret_session= */ NULL, &uid);
|
||||||
if (r < 0) {
|
|
||||||
if (IN_SET(r, -ENXIO, -ENODATA))
|
if (IN_SET(r, -ENXIO, -ENODATA))
|
||||||
/* No active session on this seat */
|
/* No active session on this seat */
|
||||||
r = 0;
|
r = 0;
|
||||||
else
|
else if (r < 0)
|
||||||
log_device_error_errno(dev, r, "Failed to determine active user on seat %s: %m", seat);
|
log_device_error_errno(dev, r, "Failed to determine active user on seat %s, ignoring: %m", seat);
|
||||||
|
else {
|
||||||
goto reset;
|
if (set_ensure_put(&uids, NULL, UID_TO_PTR(uid)) < 0)
|
||||||
|
return log_oom();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r = devnode_acl(fd, uid);
|
r = sd_device_has_tag(dev, "xaccess");
|
||||||
|
if (r < 0)
|
||||||
|
return log_device_error_errno(dev, r, "Failed to query device xaccess tag: %m");
|
||||||
|
|
||||||
|
if (r > 0) {
|
||||||
|
r = sd_get_sessions(&sessions);
|
||||||
|
if (r < 0)
|
||||||
|
return log_device_error_errno(dev, r, "Failed to list sessions: %m");
|
||||||
|
|
||||||
|
STRV_FOREACH(s, sessions) {
|
||||||
|
_cleanup_free_ char *state = NULL;
|
||||||
|
if (sd_session_get_state(*s, &state) < 0) {
|
||||||
|
log_device_debug_errno(dev, r, "Failed to query state for session %s, ignoring: %m", *s);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (streq(state, "closing"))
|
||||||
|
continue;
|
||||||
|
r = sd_session_has_extra_device_access(*s);
|
||||||
|
if (r < 0) {
|
||||||
|
log_device_debug_errno(dev, r, "Failed to query extra device access for session %s, ignoring: %m", *s);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (r == 0)
|
||||||
|
continue;
|
||||||
|
if (sd_session_get_uid(*s, &uid) < 0) {
|
||||||
|
log_device_debug_errno(dev, r, "Failed to query uid for session %s, ignoring: %m", *s);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (set_ensure_put(&uids, NULL, UID_TO_PTR(uid)) < 0)
|
||||||
|
return log_oom();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
r = devnode_acl(fd, uids);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_device_full_errno(dev, r == -ENOENT ? LOG_DEBUG : LOG_ERR, r, "Failed to apply ACL: %m");
|
log_device_full_errno(dev, r == -ENOENT ? LOG_DEBUG : LOG_ERR, r, "Failed to apply ACL: %m");
|
||||||
goto reset;
|
goto reset;
|
||||||
@ -60,7 +106,7 @@ static int builtin_uaccess(UdevEvent *event, int argc, char *argv[]) {
|
|||||||
|
|
||||||
reset:
|
reset:
|
||||||
/* Better be safe than sorry and reset ACL */
|
/* Better be safe than sorry and reset ACL */
|
||||||
k = devnode_acl(fd, /* uid= */ 0);
|
k = devnode_acl(fd, /* uids= */ NULL);
|
||||||
if (k < 0)
|
if (k < 0)
|
||||||
RET_GATHER(r, log_device_full_errno(dev, k == -ENOENT ? LOG_DEBUG : LOG_ERR, k, "Failed to flush ACLs: %m"));
|
RET_GATHER(r, log_device_full_errno(dev, k == -ENOENT ? LOG_DEBUG : LOG_ERR, k, "Failed to flush ACLs: %m"));
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user