Merge pull request #12424 from poettering/logind-brightness

logind: add SetBrightness() bus call as minimal API for setting "leds" and "backlight" kernel class device brightness
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2019-06-12 14:28:09 +02:00 committed by GitHub
commit 58cf79c224
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 703 additions and 202 deletions

7
TODO
View File

@ -27,6 +27,13 @@ Features:
* when killing due to service watchdog timeout maybe detect whether target
process is under ptracing and then log loudly and continue instead.
* introduce a new group to own TPM devices
* make rfkill uaccess controllable by default, i.e. steal rule from
gnome-bluetooth and friends
* warn if udev rules files are marked executable (docker?)
* tweak journald context caching. In addition to caching per-process attributes
keyed by PID, cache per-cgroup attributes (i.e. the various xattrs we read)
keyed by cgroup path, and guarded by ctime changes. This should provide us

View File

@ -56,6 +56,7 @@ BUS_ERROR_MAP_ELF_REGISTER const sd_bus_error_map bus_common_errors[] = {
SD_BUS_ERROR_MAP(BUS_ERROR_OPERATION_IN_PROGRESS, EINPROGRESS),
SD_BUS_ERROR_MAP(BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, EOPNOTSUPP),
SD_BUS_ERROR_MAP(BUS_ERROR_SESSION_BUSY, EBUSY),
SD_BUS_ERROR_MAP(BUS_ERROR_NOT_YOUR_DEVICE, EPERM),
SD_BUS_ERROR_MAP(BUS_ERROR_AUTOMATIC_TIME_SYNC_ENABLED, EALREADY),
SD_BUS_ERROR_MAP(BUS_ERROR_NO_NTP_SUPPORT, EOPNOTSUPP),

View File

@ -51,6 +51,7 @@
#define BUS_ERROR_OPERATION_IN_PROGRESS "org.freedesktop.login1.OperationInProgress"
#define BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED "org.freedesktop.login1.SleepVerbNotSupported"
#define BUS_ERROR_SESSION_BUSY "org.freedesktop.login1.SessionBusy"
#define BUS_ERROR_NOT_YOUR_DEVICE "org.freedesktop.login1.NotYourDevice"
#define BUS_ERROR_AUTOMATIC_TIME_SYNC_ENABLED "org.freedesktop.timedate1.AutomaticTimeSyncEnabled"
#define BUS_ERROR_NO_NTP_SUPPORT "org.freedesktop.timedate1.NoNTPSupport"

View File

@ -14,6 +14,10 @@ SUBSYSTEM=="sound", KERNEL=="card*", TAG+="seat"
SUBSYSTEM=="input", KERNEL=="input*", TAG+="seat"
SUBSYSTEM=="graphics", KERNEL=="fb[0-9]*", TAG+="seat"
# Assign keyboard and LCD backlights to the seat
SUBSYSTEM=="leds", TAG+="seat"
SUBSYSTEM=="backlight", TAG+="seat"
# HyperV currently doesn't do DRM, hence we need to synthesize for HyperV's fb device instead
SUBSYSTEM=="graphics", KERNEL=="fb[0-9]", DRIVERS=="hyperv_fb", TAG+="master-of-seat"

View File

@ -846,23 +846,11 @@ static int show_session(int argc, char *argv[], void *userdata) {
(void) pager_open(arg_pager_flags);
if (argc <= 1) {
const char *session, *p = "/org/freedesktop/login1/session/self";
/* If no argument is specified inspect the manager itself */
if (properties)
/* If no argument is specified inspect the manager itself */
return show_properties(bus, "/org/freedesktop/login1", &new_line);
/* And in the pretty case, show data of the calling session */
session = getenv("XDG_SESSION_ID");
if (session) {
r = get_session_path(bus, session, &error, &path);
if (r < 0)
return log_error_errno(r, "Failed to get session path: %s", bus_error_message(&error, r));
p = path;
}
return print_session_status_info(bus, p, &new_line);
return print_session_status_info(bus, "/org/freedesktop/login1/session/auto", &new_line);
}
for (i = 1; i < argc; i++) {
@ -895,8 +883,7 @@ static int show_user(int argc, char *argv[], void *userdata) {
(void) pager_open(arg_pager_flags);
if (argc <= 1) {
/* If not argument is specified inspect the manager
* itself */
/* If no argument is specified inspect the manager itself */
if (properties)
return show_properties(bus, "/org/freedesktop/login1", &new_line);
@ -953,12 +940,11 @@ static int show_seat(int argc, char *argv[], void *userdata) {
(void) pager_open(arg_pager_flags);
if (argc <= 1) {
/* If not argument is specified inspect the manager
* itself */
/* If no argument is specified inspect the manager itself */
if (properties)
return show_properties(bus, "/org/freedesktop/login1", &new_line);
return print_seat_status_info(bus, "/org/freedesktop/login1/seat/self", &new_line);
return print_seat_status_info(bus, "/org/freedesktop/login1/seat/auto", &new_line);
}
for (i = 1; i < argc; i++) {
@ -1005,11 +991,8 @@ static int activate(int argc, char *argv[], void *userdata) {
polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
if (argc < 2) {
/* No argument? Let's either use $XDG_SESSION_ID (if specified), or an empty
* session name, in which case logind will try to guess our session. */
short_argv[0] = argv[0];
short_argv[1] = getenv("XDG_SESSION_ID") ?: (char*) "";
short_argv[1] = (char*) "";
short_argv[2] = NULL;
argv = short_argv;
@ -1030,7 +1013,7 @@ static int activate(int argc, char *argv[], void *userdata) {
&error, NULL,
"s", argv[i]);
if (r < 0)
return log_error_errno(r, "Failed to issue method call: %s", bus_error_message(&error, -r));
return log_error_errno(r, "Failed to issue method call: %s", bus_error_message(&error, r));
}
return 0;

View File

@ -8,6 +8,8 @@
#include "conf-parser.h"
#include "format-util.h"
#include "logind-action.h"
#include "logind-dbus.h"
#include "logind-session-dbus.h"
#include "process-util.h"
#include "sleep-config.h"
#include "special.h"

View File

@ -0,0 +1,256 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#include "bus-util.h"
#include "device-util.h"
#include "hash-funcs.h"
#include "logind-brightness.h"
#include "logind.h"
#include "process-util.h"
#include "stdio-util.h"
/* Brightness and LED devices tend to be very slow to write to (often being I2C and such). Writes to the
* sysfs attributes are synchronous, and hence will freeze our process on access. We can't really have that,
* hence we add some complexity: whenever we need to write to the brightness attribute, we do so in a forked
* off process, which terminates when it is done. Watching that process allows us to watch completion of the
* write operation.
*
* To make this even more complex: clients are likely to send us many write requests in a short time-frame
* (because they implement reactive brightness sliders on screen). Let's coalesce writes to make this
* efficient: whenever we get requests to change brightness while we are still writing to the brightness
* attribute, let's remember the request and restart a new one when the initial operation finished. When we
* get another request while one is ongoing and one is pending we'll replace the pending one with the new
* one.
*
* The bus messages are answered when the first write operation finishes that started either due to the
* request or due to a later request that overrode the requested one.
*
* Yes, this is complex, but I don't see an easier way if we want to be both efficient and still support
* completion notification. */
typedef struct BrightnessWriter {
Manager *manager;
sd_device *device;
char *path;
pid_t child;
uint32_t brightness;
bool again;
Set *current_messages;
Set *pending_messages;
sd_event_source* child_event_source;
} BrightnessWriter;
static void brightness_writer_free(BrightnessWriter *w) {
if (!w)
return;
if (w->manager && w->path)
(void) hashmap_remove_value(w->manager->brightness_writers, w->path, w);
sd_device_unref(w->device);
free(w->path);
set_free(w->current_messages);
set_free(w->pending_messages);
w->child_event_source = sd_event_source_unref(w->child_event_source);
free(w);
}
DEFINE_TRIVIAL_CLEANUP_FUNC(BrightnessWriter*, brightness_writer_free);
DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
brightness_writer_hash_ops,
char,
string_hash_func,
string_compare_func,
BrightnessWriter,
brightness_writer_free);
static void brightness_writer_reply(BrightnessWriter *w, int error) {
int r;
assert(w);
for (;;) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
m = set_steal_first(w->current_messages);
if (!m)
break;
if (error == 0)
r = sd_bus_reply_method_return(m, NULL);
else
r = sd_bus_reply_method_errnof(m, error, "Failed to write to brightness device: %m");
if (r < 0)
log_warning_errno(r, "Failed to send method reply, ignoring: %m");
}
}
static int brightness_writer_fork(BrightnessWriter *w);
static int on_brightness_writer_exit(sd_event_source *s, const siginfo_t *si, void *userdata) {
BrightnessWriter *w = userdata;
int r;
assert(s);
assert(si);
assert(w);
assert(si->si_pid == w->child);
w->child = 0;
w->child_event_source = sd_event_source_unref(w->child_event_source);
brightness_writer_reply(w,
si->si_code == CLD_EXITED &&
si->si_status == EXIT_SUCCESS ? 0 : -EPROTO);
if (w->again) {
/* Another request to change the brightness has been queued. Act on it, but make the pending
* messages the current ones. */
w->again = false;
set_free(w->current_messages);
w->current_messages = TAKE_PTR(w->pending_messages);
r = brightness_writer_fork(w);
if (r >= 0)
return 0;
brightness_writer_reply(w, r);
}
brightness_writer_free(w);
return 0;
}
static int brightness_writer_fork(BrightnessWriter *w) {
int r;
assert(w);
assert(w->manager);
assert(w->child == 0);
assert(!w->child_event_source);
r = safe_fork("(sd-bright)", FORK_DEATHSIG|FORK_NULL_STDIO|FORK_CLOSE_ALL_FDS|FORK_LOG, &w->child);
if (r < 0)
return r;
if (r == 0) {
char brs[DECIMAL_STR_MAX(uint32_t)+1];
/* Child */
xsprintf(brs, "%" PRIu32, w->brightness);
r = sd_device_set_sysattr_value(w->device, "brightness", brs);
if (r < 0) {
log_device_error_errno(w->device, r, "Failed to write brightness to device: %m");
_exit(EXIT_FAILURE);
}
_exit(EXIT_SUCCESS);
}
r = sd_event_add_child(w->manager->event, &w->child_event_source, w->child, WEXITED, on_brightness_writer_exit, w);
if (r < 0)
return log_error_errno(r, "Failed to watch brightness writer child " PID_FMT ": %m", w->child);
return 0;
}
static int set_add_message(Set **set, sd_bus_message *message) {
int r;
assert(set);
if (!message)
return 0;
r = sd_bus_message_get_expect_reply(message);
if (r <= 0)
return r;
r = set_ensure_allocated(set, &bus_message_hash_ops);
if (r < 0)
return r;
r = set_put(*set, message);
if (r < 0)
return r;
sd_bus_message_ref(message);
return 1;
}
int manager_write_brightness(
Manager *m,
sd_device *device,
uint32_t brightness,
sd_bus_message *message) {
_cleanup_(brightness_writer_freep) BrightnessWriter *w = NULL;
BrightnessWriter *existing;
const char *path;
int r;
assert(m);
assert(device);
r = sd_device_get_syspath(device, &path);
if (r < 0)
return log_device_error_errno(device, r, "Failed to get sysfs path for brightness device: %m");
existing = hashmap_get(m->brightness_writers, path);
if (existing) {
/* There's already a writer for this device. Let's update it with the new brightness, and add
* our message to the set of message to reply when done. */
r = set_add_message(&existing->pending_messages, message);
if (r < 0)
return log_error_errno(r, "Failed to add message to set: %m");
/* We overide any previously requested brightness here: we coalesce writes, and the newest
* requested brightness is the one we'll put into effect. */
existing->brightness = brightness;
existing->again = true; /* request another iteration of the writer when the current one is
* complete */
return 0;
}
r = hashmap_ensure_allocated(&m->brightness_writers, &brightness_writer_hash_ops);
if (r < 0)
return log_oom();
w = new(BrightnessWriter, 1);
if (!w)
return log_oom();
*w = (BrightnessWriter) {
.device = sd_device_ref(device),
.path = strdup(path),
.brightness = brightness,
};
if (!w->path)
return log_oom();
r = hashmap_put(m->brightness_writers, w->path, w);
if (r < 0)
return log_error_errno(r, "Failed to add brightness writer to hashmap: %m");
w->manager = m;
r = set_add_message(&w->current_messages, message);
if (r < 0)
return log_error_errno(r, "Failed to add message to set: %m");
r = brightness_writer_fork(w);
if (r < 0)
return r;
TAKE_PTR(w);
return 0;
}

View File

@ -0,0 +1,9 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
#include "sd-bus.h"
#include "sd-device.h"
#include "logind.h"
int manager_write_brightness(Manager *m, sd_device *device, uint32_t brightness, sd_bus_message *message);

View File

@ -27,6 +27,10 @@
#include "fileio.h"
#include "format-util.h"
#include "fs-util.h"
#include "logind-dbus.h"
#include "logind-seat-dbus.h"
#include "logind-session-dbus.h"
#include "logind-user-dbus.h"
#include "logind.h"
#include "missing_capability.h"
#include "mkdir.h"
@ -46,47 +50,78 @@
#include "utmp-wtmp.h"
#include "virt.h"
static int get_sender_session(Manager *m, sd_bus_message *message, sd_bus_error *error, Session **ret) {
static int get_sender_session(
Manager *m,
sd_bus_message *message,
bool consult_display,
sd_bus_error *error,
Session **ret) {
_cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
Session *session = NULL;
const char *name;
Session *session;
int r;
/* Get client login session. This is not what you are looking for these days,
* as apps may instead belong to a user service unit. This includes terminal
* emulators and hence command-line apps. */
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_SESSION|SD_BUS_CREDS_AUGMENT, &creds);
/* Acquire the sender's session. This first checks if the sending process is inside a session itself,
* and returns that. If not and 'consult_display' is true, this returns the display session of the
* owning user of the caller. */
r = sd_bus_query_sender_creds(message,
SD_BUS_CREDS_SESSION|SD_BUS_CREDS_AUGMENT|
(consult_display ? SD_BUS_CREDS_OWNER_UID : 0), &creds);
if (r < 0)
return r;
r = sd_bus_creds_get_session(creds, &name);
if (r == -ENXIO)
goto err_no_session;
if (r < 0)
return r;
if (r < 0) {
if (r != -ENXIO)
return r;
if (consult_display) {
uid_t uid;
r = sd_bus_creds_get_owner_uid(creds, &uid);
if (r < 0) {
if (r != -ENXIO)
return r;
} else {
User *user;
user = hashmap_get(m->users, UID_TO_PTR(uid));
if (user)
session = user->display;
}
}
} else
session = hashmap_get(m->sessions, name);
session = hashmap_get(m->sessions, name);
if (!session)
goto err_no_session;
return sd_bus_error_setf(error, BUS_ERROR_NO_SESSION_FOR_PID,
consult_display ?
"Caller does not belong to any known session and doesn't own any suitable session." :
"Caller does not belong to any known session.");
*ret = session;
return 0;
err_no_session:
return sd_bus_error_setf(error, BUS_ERROR_NO_SESSION_FOR_PID,
"Caller does not belong to any known session");
}
int manager_get_session_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Session **ret) {
int manager_get_session_from_creds(
Manager *m,
sd_bus_message *message,
const char *name,
sd_bus_error *error,
Session **ret) {
Session *session;
assert(m);
assert(message);
assert(ret);
if (isempty(name))
return get_sender_session(m, message, error, ret);
if (SEAT_IS_SELF(name)) /* the caller's own session */
return get_sender_session(m, message, false, error, ret);
if (SEAT_IS_AUTO(name)) /* The caller's own session if they have one, otherwise their user's display session */
return get_sender_session(m, message, true, error, ret);
session = hashmap_get(m->sessions, name);
if (!session)
@ -97,7 +132,6 @@ int manager_get_session_from_creds(Manager *m, sd_bus_message *message, const ch
}
static int get_sender_user(Manager *m, sd_bus_message *message, sd_bus_error *error, User **ret) {
_cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
uid_t uid;
User *user;
@ -109,21 +143,20 @@ static int get_sender_user(Manager *m, sd_bus_message *message, sd_bus_error *er
return r;
r = sd_bus_creds_get_owner_uid(creds, &uid);
if (r == -ENXIO)
goto err_no_user;
if (r < 0)
return r;
if (r < 0) {
if (r != -ENXIO)
return r;
user = NULL;
} else
user = hashmap_get(m->users, UID_TO_PTR(uid));
user = hashmap_get(m->users, UID_TO_PTR(uid));
if (!user)
goto err_no_user;
return sd_bus_error_setf(error, BUS_ERROR_NO_USER_FOR_PID,
"Caller does not belong to any logged in or lingering user");
*ret = user;
return 0;
err_no_user:
return sd_bus_error_setf(error, BUS_ERROR_NO_USER_FOR_PID,
"Caller does not belong to any logged in user or lingering user");
}
int manager_get_user_from_creds(Manager *m, sd_bus_message *message, uid_t uid, sd_bus_error *error, User **ret) {
@ -145,7 +178,13 @@ int manager_get_user_from_creds(Manager *m, sd_bus_message *message, uid_t uid,
return 0;
}
int manager_get_seat_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Seat **ret) {
int manager_get_seat_from_creds(
Manager *m,
sd_bus_message *message,
const char *name,
sd_bus_error *error,
Seat **ret) {
Seat *seat;
int r;
@ -153,16 +192,17 @@ int manager_get_seat_from_creds(Manager *m, sd_bus_message *message, const char
assert(message);
assert(ret);
if (isempty(name)) {
if (SEAT_IS_SELF(name) || SEAT_IS_AUTO(name)) {
Session *session;
r = manager_get_session_from_creds(m, message, NULL, error, &session);
/* Use these special seat names as session names */
r = manager_get_session_from_creds(m, message, name, error, &session);
if (r < 0)
return r;
seat = session->seat;
if (!seat)
return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "Session has no seat.");
return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "Session '%s' has no seat.", session->id);
} else {
seat = hashmap_get(m->seats, name);
if (!seat)
@ -809,11 +849,9 @@ static int method_create_session(sd_bus_message *message, void *userdata, sd_bus
if (asprintf(&id, "%"PRIu32, audit_id) < 0)
return -ENOMEM;
/* Wut? There's already a session by this name and we
* didn't find it above? Weird, then let's not trust
* the audit data and let's better register a new
* ID */
if (hashmap_get(m->sessions, id)) {
/* Wut? There's already a session by this name and we didn't find it above? Weird, then let's
* not trust the audit data and let's better register a new ID */
if (hashmap_contains(m->sessions, id)) {
log_warning("Existing logind session ID %s used by new audit session, ignoring.", id);
audit_id = AUDIT_SESSION_INVALID;
id = mfree(id);
@ -827,9 +865,13 @@ static int method_create_session(sd_bus_message *message, void *userdata, sd_bus
if (asprintf(&id, "c%lu", ++m->session_counter) < 0)
return -ENOMEM;
} while (hashmap_get(m->sessions, id));
} while (hashmap_contains(m->sessions, id));
}
/* The generated names should not clash with 'auto' or 'self' */
assert(!SESSION_IS_SELF(id));
assert(!SESSION_IS_AUTO(id));
/* If we are not watching utmp already, try again */
manager_reconnect_utmp(m);
@ -990,8 +1032,7 @@ static int method_activate_session_on_seat(sd_bus_message *message, void *userda
assert(message);
assert(m);
/* Same as ActivateSession() but refuses to work if
* the seat doesn't match */
/* Same as ActivateSession() but refuses to work if the seat doesn't match */
r = sd_bus_message_read(message, "ss", &session_name, &seat_name);
if (r < 0)
@ -1367,11 +1408,22 @@ static int method_attach_device(sd_bus_message *message, void *userdata, sd_bus_
if (r < 0)
return r;
if (!path_is_normalized(sysfs))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not normalized", sysfs);
if (!path_startswith(sysfs, "/sys"))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not in /sys", sysfs);
if (!seat_name_is_valid(seat))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat %s is not valid", seat);
if (SEAT_IS_SELF(seat) || SEAT_IS_AUTO(seat)) {
Seat *found;
r = manager_get_seat_from_creds(m, message, seat, error, &found);
if (r < 0)
return r;
seat = found->id;
} else if (!seat_name_is_valid(seat)) /* Note that a seat does not have to exist yet for this operation to succeed */
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat name %s is not valid", seat);
r = bus_verify_polkit_async(
message,

31
src/login/logind-dbus.h Normal file
View File

@ -0,0 +1,31 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
#include "sd-bus.h"
#include "logind.h"
#include "logind-session.h"
#include "logind-user.h"
int manager_get_session_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Session **ret);
int manager_get_user_from_creds(Manager *m, sd_bus_message *message, uid_t uid, sd_bus_error *error, User **ret);
int manager_get_seat_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Seat **ret);
int manager_dispatch_delayed(Manager *manager, bool timeout);
int bus_manager_shutdown_or_sleep_now_or_later(Manager *m, const char *unit_name, InhibitWhat w, sd_bus_error *error);
int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *error);
int match_unit_removed(sd_bus_message *message, void *userdata, sd_bus_error *error);
int match_properties_changed(sd_bus_message *message, void *userdata, sd_bus_error *error);
int match_reloading(sd_bus_message *message, void *userdata, sd_bus_error *error);
int manager_send_changed(Manager *manager, const char *property, ...) _sentinel_;
int manager_start_scope(Manager *manager, const char *scope, pid_t pid, const char *slice, const char *description, char **wants, char **after, const char *requires_mounts_for, sd_bus_message *more_properties, sd_bus_error *error, char **job);
int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job);
int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job);
int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *error);
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);

View File

@ -4,6 +4,7 @@
#include "alloc-util.h"
#include "logind-device.h"
#include "logind-seat-dbus.h"
#include "util.h"
Device* device_new(Manager *m, const char *sysfs, bool master) {

View File

@ -13,6 +13,7 @@
#include "fd-util.h"
#include "fileio.h"
#include "format-util.h"
#include "logind-dbus.h"
#include "logind-inhibit.h"
#include "mkdir.h"
#include "parse-util.h"

View File

@ -7,7 +7,10 @@
#include "bus-common-errors.h"
#include "bus-label.h"
#include "bus-util.h"
#include "logind-dbus.h"
#include "logind-seat-dbus.h"
#include "logind-seat.h"
#include "logind-session-dbus.h"
#include "logind.h"
#include "missing_capability.h"
#include "strv.h"
@ -255,7 +258,10 @@ const sd_bus_vtable seat_vtable[] = {
};
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;
const char *p;
Seat *seat;
int r;
@ -265,32 +271,25 @@ int seat_object_find(sd_bus *bus, const char *path, const char *interface, void
assert(found);
assert(m);
if (streq(path, "/org/freedesktop/login1/seat/self")) {
sd_bus_message *message;
p = startswith(path, "/org/freedesktop/login1/seat/");
if (!p)
return 0;
message = sd_bus_get_current_message(bus);
if (!message)
return 0;
e = bus_label_unescape(p);
if (!e)
return -ENOMEM;
r = manager_get_seat_from_creds(m, message, NULL, error, &seat);
if (r < 0)
return r;
} else {
_cleanup_free_ char *e = NULL;
const char *p;
message = sd_bus_get_current_message(bus);
if (!message)
return 0;
p = startswith(path, "/org/freedesktop/login1/seat/");
if (!p)
return 0;
e = bus_label_unescape(p);
if (!e)
return -ENOMEM;
seat = hashmap_get(m->seats, e);
if (!seat)
return 0;
r = manager_get_seat_from_creds(m, message, e, error, &seat);
if (r == -ENXIO) {
sd_bus_error_free(error);
return 0;
}
if (r < 0)
return r;
*found = seat;
return 1;
@ -335,25 +334,47 @@ int seat_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***
message = sd_bus_get_current_message(bus);
if (message) {
_cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
const char *name;
Session *session;
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_SESSION|SD_BUS_CREDS_AUGMENT, &creds);
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_SESSION|SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
if (r >= 0) {
bool may_auto = false;
const char *name;
r = sd_bus_creds_get_session(creds, &name);
if (r >= 0) {
Session *session;
session = hashmap_get(m->sessions, name);
if (session && session->seat) {
r = strv_extend(&l, "/org/freedesktop/login1/seat/self");
if (r < 0)
return r;
may_auto = true;
}
}
if (!may_auto) {
uid_t uid;
r = sd_bus_creds_get_owner_uid(creds, &uid);
if (r >= 0) {
User *user;
user = hashmap_get(m->users, UID_TO_PTR(uid));
may_auto = user && user->display && user->display->seat;
}
}
if (may_auto) {
r = strv_extend(&l, "/org/freedesktop/login1/seat/auto");
if (r < 0)
return r;
}
}
}
*nodes = TAKE_PTR(l);
return 1;
}

View File

@ -0,0 +1,17 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
#include "sd-bus.h"
#include "logind-seat.h"
extern const sd_bus_vtable seat_vtable[];
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);
int seat_send_changed(Seat *s, const char *properties, ...) _sentinel_;
int bus_seat_method_terminate(sd_bus_message *message, void *userdata, sd_bus_error *error);

View File

@ -13,7 +13,9 @@
#include "fileio.h"
#include "format-util.h"
#include "logind-acl.h"
#include "logind-seat-dbus.h"
#include "logind-seat.h"
#include "logind-session-dbus.h"
#include "mkdir.h"
#include "parse-util.h"
#include "stdio-util.h"

View File

@ -67,13 +67,10 @@ void seat_add_to_gc_queue(Seat *s);
bool seat_name_is_valid(const char *name);
extern const sd_bus_vtable seat_vtable[];
static inline bool SEAT_IS_SELF(const char *name) {
return isempty(name) || streq(name, "self");
}
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);
int seat_send_changed(Seat *s, const char *properties, ...) _sentinel_;
int bus_seat_method_terminate(sd_bus_message *message, void *userdata, sd_bus_error *error);
static inline bool SEAT_IS_AUTO(const char *name) {
return streq_ptr(name, "auto");
}

View File

@ -8,13 +8,20 @@
#include "bus-label.h"
#include "bus-util.h"
#include "fd-util.h"
#include "logind-brightness.h"
#include "logind-dbus.h"
#include "logind-seat-dbus.h"
#include "logind-session-dbus.h"
#include "logind-session-device.h"
#include "logind-session.h"
#include "logind-user-dbus.h"
#include "logind.h"
#include "missing_capability.h"
#include "path-util.h"
#include "signal-util.h"
#include "stat-util.h"
#include "strv.h"
#include "user-util.h"
#include "util.h"
static int property_get_user(
@ -479,6 +486,57 @@ static int method_pause_device_complete(sd_bus_message *message, void *userdata,
return sd_bus_reply_method_return(message, NULL);
}
static int method_set_brightness(sd_bus_message *message, void *userdata, sd_bus_error *error) {
_cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
_cleanup_(sd_device_unrefp) sd_device *d = NULL;
const char *subsystem, *name, *seat;
Session *s = userdata;
uint32_t brightness;
uid_t uid;
int r;
assert(message);
assert(s);
r = sd_bus_message_read(message, "ssu", &subsystem, &name, &brightness);
if (r < 0)
return r;
if (!STR_IN_SET(subsystem, "backlight", "leds"))
return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Subsystem type %s not supported, must be one of 'backlight' or 'leds'.", subsystem);
if (!filename_is_valid(name))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Not a valid device name %s, refusing.", name);
if (!s->seat)
return sd_bus_error_setf(error, BUS_ERROR_NOT_YOUR_DEVICE, "Your session has no seat, refusing.");
if (s->seat->active != s)
return sd_bus_error_setf(error, BUS_ERROR_NOT_YOUR_DEVICE, "Session is not in foreground, refusing.");
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
if (r < 0)
return r;
r = sd_bus_creds_get_euid(creds, &uid);
if (r < 0)
return r;
if (uid != 0 && uid != s->user->uid)
return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Only owner of session may change brightness.");
r = sd_device_new_from_subsystem_sysname(&d, subsystem, name);
if (r < 0)
return sd_bus_error_set_errnof(error, r, "Failed to open device %s:%s: %m", subsystem, name);
if (sd_device_get_property_value(d, "ID_SEAT", &seat) >= 0 && !streq_ptr(seat, s->seat->id))
return sd_bus_error_setf(error, BUS_ERROR_NOT_YOUR_DEVICE, "Device %s:%s does not belong to your seat %s, refusing.", subsystem, name, s->seat->id);
r = manager_write_brightness(s->manager, d, brightness, message);
if (r < 0)
return r;
return 1;
}
const sd_bus_vtable session_vtable[] = {
SD_BUS_VTABLE_START(0),
@ -519,6 +577,7 @@ const sd_bus_vtable session_vtable[] = {
SD_BUS_METHOD("TakeDevice", "uu", "hb", method_take_device, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("ReleaseDevice", "uu", NULL, method_release_device, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("PauseDeviceComplete", "uu", NULL, method_pause_device_complete, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("SetBrightness", "ssu", NULL, method_set_brightness, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_SIGNAL("PauseDevice", "uus", 0),
SD_BUS_SIGNAL("ResumeDevice", "uuh", 0),
@ -529,8 +588,11 @@ const sd_bus_vtable session_vtable[] = {
};
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;
Session *session;
const char *p;
int r;
assert(bus);
@ -539,32 +601,25 @@ int session_object_find(sd_bus *bus, const char *path, const char *interface, vo
assert(found);
assert(m);
if (streq(path, "/org/freedesktop/login1/session/self")) {
sd_bus_message *message;
p = startswith(path, "/org/freedesktop/login1/session/");
if (!p)
return 0;
message = sd_bus_get_current_message(bus);
if (!message)
return 0;
e = bus_label_unescape(p);
if (!e)
return -ENOMEM;
r = manager_get_session_from_creds(m, message, NULL, error, &session);
if (r < 0)
return r;
} else {
_cleanup_free_ char *e = NULL;
const char *p;
message = sd_bus_get_current_message(bus);
if (!message)
return 0;
p = startswith(path, "/org/freedesktop/login1/session/");
if (!p)
return 0;
e = bus_label_unescape(p);
if (!e)
return -ENOMEM;
session = hashmap_get(m->sessions, e);
if (!session)
return 0;
r = manager_get_session_from_creds(m, message, e, error, &session);
if (r == -ENXIO) {
sd_bus_error_free(error);
return 0;
}
if (r < 0)
return r;
*found = session;
return 1;
@ -609,10 +664,12 @@ int session_node_enumerator(sd_bus *bus, const char *path, void *userdata, char
message = sd_bus_get_current_message(bus);
if (message) {
_cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
const char *name;
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_SESSION|SD_BUS_CREDS_AUGMENT, &creds);
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_SESSION|SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
if (r >= 0) {
bool may_auto = false;
const char *name;
r = sd_bus_creds_get_session(creds, &name);
if (r >= 0) {
session = hashmap_get(m->sessions, name);
@ -620,13 +677,32 @@ int session_node_enumerator(sd_bus *bus, const char *path, void *userdata, char
r = strv_extend(&l, "/org/freedesktop/login1/session/self");
if (r < 0)
return r;
may_auto = true;
}
}
if (!may_auto) {
uid_t uid;
r = sd_bus_creds_get_owner_uid(creds, &uid);
if (r >= 0) {
User *user;
user = hashmap_get(m->users, UID_TO_PTR(uid));
may_auto = user && user->display;
}
}
if (may_auto) {
r = strv_extend(&l, "/org/freedesktop/login1/session/auto");
if (r < 0)
return r;
}
}
}
*nodes = TAKE_PTR(l);
return 1;
}

View File

@ -0,0 +1,23 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
#include "sd-bus.h"
#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);
char *session_bus_path(Session *s);
int session_send_signal(Session *s, bool new_session);
int session_send_changed(Session *s, const char *properties, ...) _sentinel_;
int session_send_lock(Session *s, bool lock);
int session_send_lock_all(Manager *m, bool lock);
int session_send_create_reply(Session *s, sd_bus_error *error);
int bus_session_method_activate(sd_bus_message *message, void *userdata, sd_bus_error *error);
int bus_session_method_lock(sd_bus_message *message, void *userdata, sd_bus_error *error);
int bus_session_method_terminate(sd_bus_message *message, void *userdata, sd_bus_error *error);
int bus_session_method_kill(sd_bus_message *message, void *userdata, sd_bus_error *error);

View File

@ -7,14 +7,15 @@
#include <sys/types.h>
#include "sd-device.h"
#include "sd-daemon.h"
#include "alloc-util.h"
#include "bus-util.h"
#include "fd-util.h"
#include "logind-session-dbus.h"
#include "logind-session-device.h"
#include "missing.h"
#include "parse-util.h"
#include "sd-daemon.h"
#include "util.h"
enum SessionDeviceNotifications {

View File

@ -22,7 +22,11 @@
#include "fileio.h"
#include "format-util.h"
#include "io-util.h"
#include "logind-dbus.h"
#include "logind-seat-dbus.h"
#include "logind-session-dbus.h"
#include "logind-session.h"
#include "logind-user-dbus.h"
#include "mkdir.h"
#include "parse-util.h"
#include "path-util.h"

View File

@ -7,6 +7,7 @@ typedef enum KillWho KillWho;
#include "list.h"
#include "login-util.h"
#include "logind-user.h"
#include "string-util.h"
typedef enum SessionState {
SESSION_OPENING, /* Session scope is being created */
@ -145,18 +146,6 @@ int session_kill(Session *s, KillWho who, int signo);
SessionState session_get_state(Session *u);
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);
char *session_bus_path(Session *s);
int session_send_signal(Session *s, bool new_session);
int session_send_changed(Session *s, const char *properties, ...) _sentinel_;
int session_send_lock(Session *s, bool lock);
int session_send_lock_all(Manager *m, bool lock);
int session_send_create_reply(Session *s, sd_bus_error *error);
const char* session_state_to_string(SessionState t) _const_;
SessionState session_state_from_string(const char *s) _pure_;
@ -179,7 +168,10 @@ bool session_is_controller(Session *s, const char *sender);
int session_set_controller(Session *s, const char *sender, bool force, bool prepare);
void session_drop_controller(Session *s);
int bus_session_method_activate(sd_bus_message *message, void *userdata, sd_bus_error *error);
int bus_session_method_lock(sd_bus_message *message, void *userdata, sd_bus_error *error);
int bus_session_method_terminate(sd_bus_message *message, void *userdata, sd_bus_error *error);
int bus_session_method_kill(sd_bus_message *message, void *userdata, sd_bus_error *error);
static inline bool SESSION_IS_SELF(const char *name) {
return isempty(name) || streq(name, "self");
}
static inline bool SESSION_IS_AUTO(const char *name) {
return streq_ptr(name, "auto");
}

View File

@ -6,6 +6,9 @@
#include "alloc-util.h"
#include "bus-util.h"
#include "format-util.h"
#include "logind-dbus.h"
#include "logind-session-dbus.h"
#include "logind-user-dbus.h"
#include "logind-user.h"
#include "logind.h"
#include "missing_capability.h"
@ -245,6 +248,10 @@ int user_object_find(sd_bus *bus, const char *path, const char *interface, void
return 0;
r = manager_get_user_from_creds(m, message, UID_INVALID, error, &user);
if (r == -ENXIO) {
sd_bus_error_free(error);
return 0;
}
if (r < 0)
return r;
} else {
@ -305,10 +312,11 @@ int user_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***
message = sd_bus_get_current_message(bus);
if (message) {
_cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
uid_t uid;
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
if (r >= 0) {
uid_t uid;
r = sd_bus_creds_get_owner_uid(creds, &uid);
if (r >= 0) {
user = hashmap_get(m->users, UID_TO_PTR(uid));

View File

@ -0,0 +1,17 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
#include "sd-bus.h"
#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);
char *user_bus_path(User *s);
int user_send_signal(User *u, bool new_user);
int user_send_changed(User *u, const char *properties, ...) _sentinel_;
int bus_user_method_terminate(sd_bus_message *message, void *userdata, sd_bus_error *error);
int bus_user_method_kill(sd_bus_message *message, void *userdata, sd_bus_error *error);

View File

@ -19,7 +19,9 @@
#include "hashmap.h"
#include "label.h"
#include "limits-util.h"
#include "logind-dbus.h"
#include "logind-user.h"
#include "logind-user-dbus.h"
#include "mkdir.h"
#include "parse-util.h"
#include "path-util.h"
@ -663,12 +665,12 @@ static bool elect_display_filter(Session *s) {
/* Return true if the session is a candidate for the users primary session or display. */
assert(s);
return s->class == SESSION_USER && s->started && !s->stopping;
return IN_SET(s->class, SESSION_USER, SESSION_GREETER) && s->started && !s->stopping;
}
static int elect_display_compare(Session *s1, Session *s2) {
/* Indexed by SessionType. Lower numbers mean more preferred. */
const int type_ranks[_SESSION_TYPE_MAX] = {
static const int type_ranks[_SESSION_TYPE_MAX] = {
[SESSION_UNSPECIFIED] = 0,
[SESSION_TTY] = -2,
[SESSION_X11] = -3,

View File

@ -69,18 +69,7 @@ int user_check_linger_file(User *u);
void user_elect_display(User *u);
void user_update_last_session_timer(User *u);
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);
char *user_bus_path(User *s);
int user_send_signal(User *u, bool new_user);
int user_send_changed(User *u, const char *properties, ...) _sentinel_;
const char* user_state_to_string(UserState s) _const_;
UserState user_state_from_string(const char *s) _pure_;
int bus_user_method_terminate(sd_bus_message *message, void *userdata, sd_bus_error *error);
int bus_user_method_kill(sd_bus_message *message, void *userdata, sd_bus_error *error);
CONFIG_PARSER_PROTOTYPE(config_parse_compat_user_tasks_max);

View File

@ -18,6 +18,10 @@
#include "fd-util.h"
#include "format-util.h"
#include "fs-util.h"
#include "logind-dbus.h"
#include "logind-seat-dbus.h"
#include "logind-session-dbus.h"
#include "logind-user-dbus.h"
#include "logind.h"
#include "main-func.h"
#include "parse-util.h"
@ -44,10 +48,9 @@ static int manager_new(Manager **ret) {
*m = (Manager) {
.console_active_fd = -1,
.reserve_vt_fd = -1,
.idle_action_not_before_usec = now(CLOCK_MONOTONIC),
};
m->idle_action_not_before_usec = now(CLOCK_MONOTONIC);
m->devices = hashmap_new(&string_hash_ops);
m->seats = hashmap_new(&string_hash_ops);
m->sessions = hashmap_new(&string_hash_ops);
@ -118,6 +121,7 @@ static Manager* manager_unref(Manager *m) {
hashmap_free(m->users);
hashmap_free(m->inhibitors);
hashmap_free(m->buttons);
hashmap_free(m->brightness_writers);
hashmap_free(m->user_units);
hashmap_free(m->session_units);
@ -1215,7 +1219,7 @@ static int run(int argc, char *argv[]) {
(void) mkdir_label("/run/systemd/users", 0755);
(void) mkdir_label("/run/systemd/sessions", 0755);
assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGHUP, SIGTERM, SIGINT, -1) >= 0);
assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGHUP, SIGTERM, SIGINT, SIGCHLD, -1) >= 0);
r = manager_new(&m);
if (r < 0)

View File

@ -31,6 +31,7 @@ struct Manager {
Hashmap *users;
Hashmap *inhibitors;
Hashmap *buttons;
Hashmap *brightness_writers;
LIST_HEAD(Seat, seat_gc_queue);
LIST_HEAD(Session, session_gc_queue);
@ -158,24 +159,6 @@ void manager_reconnect_utmp(Manager *m);
extern const sd_bus_vtable manager_vtable[];
int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *error);
int match_unit_removed(sd_bus_message *message, void *userdata, sd_bus_error *error);
int match_properties_changed(sd_bus_message *message, void *userdata, sd_bus_error *error);
int match_reloading(sd_bus_message *message, void *userdata, sd_bus_error *error);
int match_name_owner_changed(sd_bus_message *message, void *userdata, sd_bus_error *error);
int bus_manager_shutdown_or_sleep_now_or_later(Manager *m, const char *unit_name, InhibitWhat w, sd_bus_error *error);
int manager_send_changed(Manager *manager, const char *property, ...) _sentinel_;
int manager_start_scope(Manager *manager, const char *scope, pid_t pid, const char *slice, const char *description, char **wants, char **after, const char *requires_mounts_for, sd_bus_message *more_properties, sd_bus_error *error, char **job);
int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job);
int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job);
int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *error);
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);
/* gperf lookup function */
const struct ConfigPerfItem* logind_gperf_lookup(const char *key, GPERF_LEN_TYPE length);
@ -184,11 +167,5 @@ int manager_set_lid_switch_ignore(Manager *m, usec_t until);
CONFIG_PARSER_PROTOTYPE(config_parse_n_autovts);
CONFIG_PARSER_PROTOTYPE(config_parse_tmpfs_size);
int manager_get_session_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Session **ret);
int manager_get_user_from_creds(Manager *m, sd_bus_message *message, uid_t uid, sd_bus_error *error, User **ret);
int manager_get_seat_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Seat **ret);
int manager_setup_wall_message_timer(Manager *m);
bool logind_wall_tty_filter(const char *tty, void *userdata);
int manager_dispatch_delayed(Manager *manager, bool timeout);

View File

@ -12,29 +12,35 @@ logind_gperf_c = custom_target(
command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@'])
liblogind_core_sources = files('''
logind-core.c
logind-device.c
logind-device.h
logind-button.c
logind-button.h
logind-acl.h
logind-action.c
logind-action.h
logind-seat.c
logind-seat.h
logind-session.c
logind-session.h
logind-session-device.c
logind-session-device.h
logind-user.c
logind-user.h
logind-brightness.c
logind-brightness.h
logind-button.c
logind-button.h
logind-core.c
logind-dbus.c
logind-dbus.h
logind-device.c
logind-device.h
logind-inhibit.c
logind-inhibit.h
logind-dbus.c
logind-session-dbus.c
logind-seat-dbus.c
logind-seat-dbus.h
logind-seat.c
logind-seat.h
logind-session-dbus.c
logind-session-dbus.h
logind-session-device.c
logind-session-device.h
logind-session.c
logind-session.h
logind-user-dbus.c
logind-user-dbus.h
logind-user.c
logind-user.h
logind-utmp.c
logind-acl.h
'''.split())
liblogind_core_sources += [logind_gperf_c]

View File

@ -302,6 +302,10 @@
send_interface="org.freedesktop.login1.Session"
send_member="PauseDeviceComplete"/>
<allow send_destination="org.freedesktop.login1"
send_interface="org.freedesktop.login1.Session"
send_member="SetBrightness"/>
<allow send_destination="org.freedesktop.login1"
send_interface="org.freedesktop.login1.User"
send_member="Terminate"/>

View File

@ -1767,3 +1767,13 @@ int bus_reply_pair_array(sd_bus_message *m, char **l) {
return sd_bus_send(NULL, reply, NULL);
}
static void bus_message_unref_wrapper(void *m) {
sd_bus_message_unref(m);
}
const struct hash_ops bus_message_hash_ops = {
.hash = trivial_hash_func,
.compare = trivial_compare_func,
.free_value = bus_message_unref_wrapper,
};

View File

@ -179,3 +179,5 @@ static inline int bus_open_system_watch_bind(sd_bus **ret) {
}
int bus_reply_pair_array(sd_bus_message *m, char **l);
extern const struct hash_ops bus_message_hash_ops;

View File

@ -43,6 +43,7 @@ RestrictRealtime=yes
RestrictSUIDSGID=yes
RuntimeDirectory=systemd/sessions systemd/seats systemd/users systemd/inhibit systemd/shutdown
RuntimeDirectoryPreserve=yes
StateDirectory=systemd/linger
SystemCallArchitectures=native
SystemCallErrorNumber=EPERM
SystemCallFilter=@system-service