diff options
author | Lennart Poettering <lennart@poettering.net> | 2016-05-04 18:57:15 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2016-05-05 22:50:09 +0200 |
commit | 183e0738427b83667512276a3e8c10274c0824cc (patch) | |
tree | cc0267b812b7b5d70694468cc25e51c96c588880 /src/login | |
parent | 37818090c99871577c0cfd8171901eb7e2050be9 (diff) |
logind: enforce a limit on current user sessions
We really should put limits on all resources we manage, hence add one to the
number of concurrent sessions, too. This was previously unbounded, hence set a
relatively high limit of 8K by default.
Note that most PAM setups will actually invoke pam_systemd prefixed with "-",
so that the return code of pam_systemd is ignored, and the login attempt
succeeds anyway. On systems like this the session will be created but is not
tracked by systemd.
Diffstat (limited to 'src/login')
-rw-r--r-- | src/login/logind-dbus.c | 23 | ||||
-rw-r--r-- | src/login/logind-gperf.gperf | 1 | ||||
-rw-r--r-- | src/login/logind.c | 1 | ||||
-rw-r--r-- | src/login/logind.conf.in | 1 | ||||
-rw-r--r-- | src/login/logind.h | 1 |
5 files changed, 27 insertions, 0 deletions
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); |