summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/templates/login/limits.j25
-rw-r--r--interface-definitions/system-login.xml.in13
-rwxr-xr-xsmoketest/scripts/cli/test_system_login.py23
-rwxr-xr-xsrc/conf_mode/system-login.py14
4 files changed, 53 insertions, 2 deletions
diff --git a/data/templates/login/limits.j2 b/data/templates/login/limits.j2
new file mode 100644
index 000000000..5e2c11f35
--- /dev/null
+++ b/data/templates/login/limits.j2
@@ -0,0 +1,5 @@
+# Generated by /usr/libexec/vyos/conf_mode/system-login.py
+
+{% if max_login_session is vyos_defined %}
+* - maxsyslogins {{ max_login_session }}
+{% endif %}
diff --git a/interface-definitions/system-login.xml.in b/interface-definitions/system-login.xml.in
index b00741ffe..258913929 100644
--- a/interface-definitions/system-login.xml.in
+++ b/interface-definitions/system-login.xml.in
@@ -225,6 +225,19 @@
#include <include/interface/vrf.xml.i>
</children>
</node>
+ <leafNode name="max-login-session">
+ <properties>
+ <help>Maximum number of all login sessions</help>
+ <valueHelp>
+ <format>u32:1-65536</format>
+ <description>Maximum number of all login sessions</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-65536"/>
+ </constraint>
+ <constraintErrorMessage>Maximum logins must be between 1 and 65536</constraintErrorMessage>
+ </properties>
+ </leafNode>
<leafNode name="timeout">
<properties>
<help>Session timeout</help>
diff --git a/smoketest/scripts/cli/test_system_login.py b/smoketest/scripts/cli/test_system_login.py
index 6006fe0f6..a1d2ba2ad 100755
--- a/smoketest/scripts/cli/test_system_login.py
+++ b/smoketest/scripts/cli/test_system_login.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2022 VyOS maintainers and contributors
+# Copyright (C) 2019-2023 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -264,5 +264,26 @@ class TestSystemLogin(VyOSUnitTestSHIM.TestCase):
tmp = re.findall(r'group:\s+mapname\s+files', nsswitch_conf)
self.assertTrue(tmp)
+ def test_system_login_max_login_session(self):
+ max_logins = '2'
+ timeout = '600'
+
+ self.cli_set(base_path + ['max-login-session', max_logins])
+
+ # 'max-login-session' must be only with 'timeout' option
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+
+ self.cli_set(base_path + ['timeout', timeout])
+
+ self.cli_commit()
+
+ security_limits = read_file('/etc/security/limits.d/10-vyos.conf')
+ self.assertIn(f'* - maxsyslogins {max_logins}', security_limits)
+
+ self.cli_delete(base_path + ['timeout'])
+ self.cli_delete(base_path + ['max-login-session'])
+
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/src/conf_mode/system-login.py b/src/conf_mode/system-login.py
index d15fe399d..fbb013cf3 100755
--- a/src/conf_mode/system-login.py
+++ b/src/conf_mode/system-login.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2022 VyOS maintainers and contributors
+# Copyright (C) 2020-2023 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -40,6 +40,7 @@ from vyos import airbag
airbag.enable()
autologout_file = "/etc/profile.d/autologout.sh"
+limits_file = "/etc/security/limits.d/10-vyos.conf"
radius_config_file = "/etc/pam_radius_auth.conf"
# LOGIN_TIMEOUT from /etc/loign.defs minus 10 sec
@@ -164,6 +165,9 @@ def verify(login):
if ipv6_count > 1:
raise ConfigError('Only one IPv6 source-address can be set!')
+ if 'max_login_session' in login and 'timeout' not in login:
+ raise ConfigError('"login timeout" must be configured!')
+
return None
@@ -226,6 +230,14 @@ def generate(login):
if os.path.isfile(radius_config_file):
os.unlink(radius_config_file)
+ # /etc/security/limits.d/10-vyos.conf
+ if 'max_login_session' in login:
+ render(limits_file, 'login/limits.j2', login,
+ permission=0o644, user='root', group='root')
+ else:
+ if os.path.isfile(limits_file):
+ os.unlink(limits_file)
+
if 'timeout' in login:
render(autologout_file, 'login/autologout.j2', login,
permission=0o755, user='root', group='root')