#include "path-util.h"
#include "process-util.h"
#include "selinux-util.h"
-#include "sleep-config.h"
+//#include "sleep-config.h"
//#include "special.h"
#include "strv.h"
#include "terminal-util.h"
return sd_bus_message_append(reply, "b", manager_is_docked_or_external_displays(m));
}
+static int property_get_current_sessions(
+ sd_bus *bus,
+ const char *path,
+ const char *interface,
+ const char *property,
+ sd_bus_message *reply,
+ void *userdata,
+ sd_bus_error *error) {
+
+ Manager *m = userdata;
+
+ assert(bus);
+ assert(reply);
+ assert(m);
+
+ return sd_bus_message_append(reply, "t", (uint64_t) hashmap_size(m->sessions));
+}
+
+static int property_get_current_inhibitors(
+ sd_bus *bus,
+ const char *path,
+ const char *interface,
+ const char *property,
+ sd_bus_message *reply,
+ void *userdata,
+ sd_bus_error *error) {
+
+ Manager *m = userdata;
+
+ assert(bus);
+ assert(reply);
+ assert(m);
+
+ return sd_bus_message_append(reply, "t", (uint64_t) hashmap_size(m->inhibitors));
+}
+
static int method_get_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
_cleanup_free_ char *p = NULL;
Manager *m = userdata;
m->seat0->positions[vtnr]->class != SESSION_GREETER)
return sd_bus_error_setf(error, BUS_ERROR_SESSION_BUSY, "Already occupied by a session");
+ if (hashmap_size(m->sessions) >= m->sessions_max)
+ return sd_bus_error_setf(error, SD_BUS_ERROR_LIMITS_EXCEEDED, "Maximum number of sessions (%" PRIu64 ") reached, refusing further sessions.", m->sessions_max);
+
audit_session_from_pid(leader, &audit_id);
if (audit_id > 0) {
/* Keep our session IDs and the audit session IDs in sync */
session->create_message = sd_bus_message_ref(message);
- /* Here upstream systemd starts cgroups and the user systemd,
- and arranges to reply asynchronously. We reply
- directly. */
+#if 0 /// UNNEEDED by elogind
+ /* Now, let's wait until the slice unit and stuff got
+ * created. We send the reply back from
+ * session_send_create_reply(). */
+#else
+ /* We reply directly. */
r = session_send_create_reply(session, NULL);
if (r < 0)
goto fail;
+#endif // 0
return 1;
static int method_set_user_linger(sd_bus_message *message, void *userdata, sd_bus_error *error) {
_cleanup_free_ char *cc = NULL;
Manager *m = userdata;
- int b, r;
+ int r, b, interactive;
struct passwd *pw;
const char *path;
uint32_t uid;
- int interactive;
+ bool self = false;
assert(message);
assert(m);
if (r < 0)
return r;
+ self = true;
+
} else if (!uid_is_valid(uid))
return -EINVAL;
r = bus_verify_polkit_async(
message,
CAP_SYS_ADMIN,
- "org.freedesktop.login1.set-user-linger",
+ self ? "org.freedesktop.login1.set-self-linger" : "org.freedesktop.login1.set-user-linger",
NULL,
interactive,
UID_INVALID,
log_info("Running in dry run, suppressing action.");
reset_scheduled_shutdown(m);
} else {
- r = sd_bus_call_method(
- m->bus,
- "org.freedesktop.systemd1",
- "/org/freedesktop/systemd1",
- "org.freedesktop.systemd1.Manager",
- "StartUnit",
- error,
- &reply,
- "ss", unit_name, "replace-irreversibly");
+ r = sd_bus_call_method(
+ m->bus,
+ "org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ "StartUnit",
+ error,
+ &reply,
+ "ss", unit_name, "replace-irreversibly");
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_read(reply, "o", &p);
+ if (r < 0)
+ return r;
+
+ c = strdup(p);
+ if (!c)
+ return -ENOMEM;
+
+ m->action_unit = unit_name;
+ free(m->action_job);
+ m->action_job = c;
+ m->action_what = w;
+ }
#else
r = shutdown_or_sleep(m, action);
/* no more pending actions, whether this failed or not */
m->pending_action = HANDLE_IGNORE;
m->action_what = 0;
-#endif // 0
- if (r < 0)
- return r;
-
-#if 0 /// elogind neither needs a dbus reply, nor supports systemd action jobs
- r = sd_bus_message_read(reply, "o", &p);
if (r < 0)
return r;
-
- c = strdup(p);
- if (!c)
- return -ENOMEM;
- }
-
- m->action_unit = unit_name;
- free(m->action_job);
- m->action_job = c;
- m->action_what = w;
#endif // 0
/* Make sure the lid switch is ignored for a while */
return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "There's already a shutdown or sleep operation in progress");
if (sleep_verb) {
- r = can_sleep(sleep_verb);
+ r = can_sleep(m, sleep_verb);
if (r < 0)
return r;
return 0;
fail:
- (void) unlink(temp_path);
- (void) unlink("/run/systemd/shutdown/scheduled");
+ (void) unlink(temp_path);
+ (void) unlink("/run/systemd/shutdown/scheduled");
return log_error_errno(r, "Failed to write information about scheduled shutdowns: %m");
}
assert(action_ignore_inhibit);
if (sleep_verb) {
- r = can_sleep(sleep_verb);
+ r = can_sleep(m, sleep_verb);
if (r < 0)
return r;
if (r == 0)
if (r < 0)
return r;
+ if (hashmap_size(m->inhibitors) >= m->inhibitors_max)
+ return sd_bus_error_setf(error, SD_BUS_ERROR_LIMITS_EXCEEDED, "Maximum number of inhibitors (%" PRIu64 ") reached, refusing further inhibitors.", m->inhibitors_max);
+
do {
id = mfree(id);
SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
SD_BUS_PROPERTY("ScheduledShutdown", "(st)", property_get_scheduled_shutdown, 0, 0),
SD_BUS_PROPERTY("Docked", "b", property_get_docked, 0, 0),
+ SD_BUS_PROPERTY("RemoveIPC", "b", bus_property_get_bool, offsetof(Manager, remove_ipc), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("RuntimeDirectorySize", "t", bus_property_get_size, offsetof(Manager, runtime_dir_size), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("InhibitorsMax", "t", NULL, offsetof(Manager, inhibitors_max), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("NCurrentInhibitors", "t", property_get_current_inhibitors, 0, 0),
+ SD_BUS_PROPERTY("SessionsMax", "t", NULL, offsetof(Manager, sessions_max), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("NCurrentSessions", "t", property_get_current_sessions, 0, 0),
+ SD_BUS_PROPERTY("UserTasksMax", "t", NULL, offsetof(Manager, user_tasks_max), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),