Add a virtual setting to enable passwordless sudo for admins

This commit is contained in:
Alexandre Aubin 2022-12-07 19:24:50 +01:00
parent 7e88230cd1
commit 75cb3cb2bd
3 changed files with 24 additions and 9 deletions

View file

@ -393,6 +393,7 @@
"firewall_reloaded": "Firewall reloaded",
"firewall_rules_cmd_failed": "Some firewall rule commands have failed. More info in log.",
"global_settings_reset_success": "Reset global settings",
"global_settings_setting_passwordless_sudo": "Allow admins to use 'sudo' without re-typing their passwords",
"global_settings_setting_admin_strength": "Admin password strength requirements",
"global_settings_setting_admin_strength_help": "These requirements are only enforced when initializing or changing the password",
"global_settings_setting_backup_compress_tar_archives": "Compress backups",

View file

@ -22,6 +22,11 @@ name = "Security"
choices.4 = "ditto, but also require at least 12 chars"
default = "1"
[security.password.passwordless_sudo]
type = "boolean"
# The actual value is dynamically computed by checking the sudoOption of cn=admins,ou=sudo
default = false
[security.ssh]
name = "SSH"
[security.ssh.ssh_compatibility]

View file

@ -120,6 +120,7 @@ class SettingsConfigPanel(ConfigPanel):
entity_type = "global"
save_path_tpl = SETTINGS_PATH
save_mode = "diff"
virtual_settings = ["root_password", "root_password_confirm", "passwordless_sudo"]
def __init__(self, config_path=None, save_path=None, creation=False):
super().__init__("settings")
@ -128,17 +129,12 @@ class SettingsConfigPanel(ConfigPanel):
root_password = self.new_values.pop("root_password", None)
root_password_confirm = self.new_values.pop("root_password_confirm", None)
passwordless_sudo = self.new_values.pop("passwordless_sudo", None)
if "root_password" in self.values:
del self.values["root_password"]
if "root_password_confirm" in self.values:
del self.values["root_password_confirm"]
if "root_password" in self.new_values:
del self.new_values["root_password"]
if "root_password_confirm" in self.new_values:
del self.new_values["root_password_confirm"]
self.values = {k: v for k, v in self.values.items() if k not in self.virtual_settings}
self.new_values = {k: v for k, v in self.new_values.items() if k not in self.virtual_settings}
assert "root_password" not in self.future_values
assert all(v not in self.future_values for v in self.virtual_settings)
if root_password and root_password.strip():
@ -149,6 +145,11 @@ class SettingsConfigPanel(ConfigPanel):
tools_rootpw(root_password, check_strength=True)
if passwordless_sudo is not None:
from yunohost.utils.ldap import _get_ldap_interface
ldap = _get_ldap_interface()
ldap.update("cn=admins,ou=sudo", {"sudoOption": ["!authenticate"] if passwordless_sudo else []})
super()._apply()
settings = {
@ -172,6 +173,14 @@ class SettingsConfigPanel(ConfigPanel):
self.values["root_password"] = ""
self.values["root_password_confirm"] = ""
# Specific logic for virtual setting "passwordless_sudo"
try:
from yunohost.utils.ldap import _get_ldap_interface
ldap = _get_ldap_interface()
self.values["passwordless_sudo"] = "!authenticate" in ldap.search("ou=sudo", "cn=admins", ["sudoOption"])[0].get("sudoOption", [])
except:
self.values["passwordless_sudo"] = False
def get(self, key="", mode="classic"):
result = super().get(key=key, mode=mode)