summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--man/logind.conf.xml9
-rw-r--r--src/login/logind-dbus.c23
-rw-r--r--src/login/logind-gperf.gperf1
-rw-r--r--src/login/logind.c1
-rw-r--r--src/login/logind.conf.in1
-rw-r--r--src/login/logind.h1
6 files changed, 36 insertions, 0 deletions
diff --git a/man/logind.conf.xml b/man/logind.conf.xml
index 6ba35414be..405dcf9041 100644
--- a/man/logind.conf.xml
+++ b/man/logind.conf.xml
@@ -297,6 +297,15 @@
</varlistentry>
<varlistentry>
+ <term><varname>SessionsMax=</varname></term>
+
+ <listitem><para>Controls the maximum number of concurrent user sessions to manage. Defaults to 8192
+ (8K). Depending on how the <filename>pam_systemd.so</filename> module is included in the PAM stack
+ configuration, further login sessions will either be refused, or permitted but not tracked by
+ <filename>systemd-logind</filename>.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><varname>UserTasksMax=</varname></term>
<listitem><para>Sets the maximum number of OS tasks each user
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index a281f99a34..5067e5d1a8 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -265,6 +265,24 @@ static int property_get_docked(
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 method_get_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
_cleanup_free_ char *p = NULL;
Manager *m = userdata;
@@ -725,6 +743,9 @@ static int method_create_session(sd_bus_message *message, void *userdata, sd_bus
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 */
@@ -2512,6 +2533,8 @@ const sd_bus_vtable manager_vtable[] = {
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("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_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),
diff --git a/src/login/logind-gperf.gperf b/src/login/logind-gperf.gperf
index 8552c464cc..1d57681260 100644
--- a/src/login/logind-gperf.gperf
+++ b/src/login/logind-gperf.gperf
@@ -34,4 +34,5 @@ Login.IdleAction, config_parse_handle_action, 0, offsetof(Manag
Login.IdleActionSec, config_parse_sec, 0, offsetof(Manager, idle_action_usec)
Login.RuntimeDirectorySize, config_parse_tmpfs_size, 0, offsetof(Manager, runtime_dir_size)
Login.RemoveIPC, config_parse_bool, 0, offsetof(Manager, remove_ipc)
+Login.SessionsMax, config_parse_uint64, 0, offsetof(Manager, sessions_max)
Login.UserTasksMax, config_parse_uint64, 0, offsetof(Manager, user_tasks_max)
diff --git a/src/login/logind.c b/src/login/logind.c
index a48e2fc61e..39f53cab36 100644
--- a/src/login/logind.c
+++ b/src/login/logind.c
@@ -63,6 +63,7 @@ static void manager_reset_config(Manager *m) {
m->runtime_dir_size = PAGE_ALIGN((size_t) (physical_memory() / 10)); /* 10% */
m->user_tasks_max = UINT64_C(12288);
+ m->sessions_max = UINT64_C(8192);
m->kill_user_processes = KILL_USER_PROCESSES;
diff --git a/src/login/logind.conf.in b/src/login/logind.conf.in
index 3c96def45d..6284218625 100644
--- a/src/login/logind.conf.in
+++ b/src/login/logind.conf.in
@@ -32,4 +32,5 @@
#IdleActionSec=30min
#RuntimeDirectorySize=10%
#RemoveIPC=yes
+#SessionsMax=8192
#UserTasksMax=12288
diff --git a/src/login/logind.h b/src/login/logind.h
index 6748af3c07..23c3e2963a 100644
--- a/src/login/logind.h
+++ b/src/login/logind.h
@@ -133,6 +133,7 @@ struct Manager {
size_t runtime_dir_size;
uint64_t user_tasks_max;
+ uint64_t sessions_max;
};
int manager_add_device(Manager *m, const char *sysfs, bool master, Device **_device);