From 39143f8bdd1a0fa65e95f57e0487457d33db07d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= Date: Wed, 17 Sep 2025 14:31:50 +0200 Subject: [PATCH] polkit: add build option to allow admin users not to type their password Add a build option to allow installing a Polkit rule that will grant permissions for admin users without asking for their password if they're in a local console. This shouldn't be encouraged, though. It's common practice that admin users has to introduce their password to make system-wide changes. The standard polkit policy, without this rule, is auth_admin_keep. This policy will ask for the password once and won't ask for it again for ~5 minutes, so it is not too unconvenient. Different distros use different group names for users with admin rights, typically 'sudo' or 'wheel'. The build option allows to define the desired group, or to leave it empty to not install the rule. However, until the previous commit it was allowed that local users (even non-admin) could do system-wide changes without introducing a password. This option allows to maintain the same behavior for admin users, keeping backwards compatibility so we avoid breaking existing scripts, for example. We cannot achieve the same for non-admin users because allowing them to create system-wide connection causes security vulnerabilities that cannot be fixed in any other way. --- data/meson.build | 11 ++++++++++- data/org.freedesktop.NetworkManager.rules.in | 17 +++++++++++++++++ meson.build | 7 +++++-- meson_options.txt | 1 + 4 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 data/org.freedesktop.NetworkManager.rules.in diff --git a/data/meson.build b/data/meson.build index afe1800b56..3e292cb2f4 100644 --- a/data/meson.build +++ b/data/meson.build @@ -60,8 +60,17 @@ if enable_polkit output: '@BASENAME@', po_dir: po_dir, install: true, - install_dir: polkit_gobject_policydir, + install_dir: polkit_policydir, ) + + if polkit_noauth_group != '' + configure_file( + input: 'org.freedesktop.NetworkManager.rules.in', + output: '@BASENAME@', + install_dir: polkit_rulesdir, + configuration: {'NM_POLKIT_NOAUTH_GROUP': polkit_noauth_group}, + ) + endif endif if enable_firewalld_zone diff --git a/data/org.freedesktop.NetworkManager.rules.in b/data/org.freedesktop.NetworkManager.rules.in new file mode 100644 index 0000000000..d6df0b323e --- /dev/null +++ b/data/org.freedesktop.NetworkManager.rules.in @@ -0,0 +1,17 @@ +// NetworkManager authorizations/policy for the @NM_POLKIT_NOAUTH_GROUP@ group. +// +// DO NOT EDIT THIS FILE, it will be overwritten on update. +// +// Allow users in the @NM_POLKIT_NOAUTH_GROUP@ group to create system-wide connections without being +// prompted for a password if they are in a local console. +// This is optional and is only recommended to maintain backwards compatibility +// in systems where it was already working in this way. It is discouraged +// otherwise. + +polkit.addRule(function(action, subject) { + if (action.id == "org.freedesktop.NetworkManager.settings.modify.system" && + subject.isInGroup("@NM_POLKIT_NOAUTH_GROUP@") && + subject.local) { + return polkit.Result.YES; + } +}); diff --git a/meson.build b/meson.build index 49f5b4214a..00a50cc64e 100644 --- a/meson.build +++ b/meson.build @@ -509,7 +509,8 @@ config_h.set10('WITH_TEAMDCTL', enable_teamdctl) enable_polkit = get_option('polkit') if enable_polkit # FIXME: policydir should be relative to `datadir`, not `prefix`. Fixed in https://gitlab.freedesktop.org/polkit/polkit/merge_requests/2 - polkit_gobject_policydir = dependency('polkit-gobject-1').get_variable(pkgconfig: 'policydir', pkgconfig_define: ['prefix', nm_prefix]) + polkit_policydir = dependency('polkit-gobject-1').get_variable(pkgconfig: 'policydir', pkgconfig_define: ['prefix', nm_prefix]) + polkit_rulesdir = join_paths(fs.parent(polkit_policydir), 'rules.d') endif config_auth_polkit_default = get_option('config_auth_polkit_default') @@ -524,6 +525,8 @@ if enable_modify_system error('modify_system=true is no longer allowed due to security reasons') endif +polkit_noauth_group = get_option('polkit_noauth_group') + polkit_agent_helper_1_path = get_option('polkit_agent_helper_1') foreach p : [ '/usr/libexec/polkit-agent-helper-1', '/usr/lib/polkit-1/polkit-agent-helper-1', @@ -1085,7 +1088,7 @@ output += ' dbus_conf_dir: ' + dbus_conf_dir + '\n' output += '\nPlatform:\n' output += ' session tracking: ' + ','.join(session_trackers) + '\n' output += ' suspend/resume: ' + suspend_resume + '\n' -output += ' policykit: ' + enable_polkit.to_string() + ' (default: ' + config_auth_polkit_default + ')\n' +output += ' policykit: ' + enable_polkit.to_string() + ' (default: ' + config_auth_polkit_default + ', noauth_group: "' + polkit_noauth_group + '")\n' output += ' polkit-agent-helper-1: ' + polkit_agent_helper_1_path + '\n' output += ' selinux: ' + enable_selinux.to_string() + '\n' output += ' systemd-journald: ' + enable_systemd_journal.to_string() + ' (default: logging.backend=' + config_logging_backend_default + ')\n' diff --git a/meson_options.txt b/meson_options.txt index 44d50c6a7a..6b5674443b 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -20,6 +20,7 @@ option('suspend_resume', type: 'combo', choices: ['systemd', 'elogind', 'console option('polkit', type: 'boolean', value: true, description: 'User auth-polkit configuration option.') option('config_auth_polkit_default', type: 'combo', choices: ['default', 'true', 'false', 'root-only'], value: 'default', description: 'Default value for configuration main.auth-polkit.') option('modify_system', type: 'boolean', value: false, description: 'Allow users to modify system connections (option no longer supported, don\'t use)') +option('polkit_noauth_group', type: 'string', value: '', description: 'Allow users of the selected group, typically sudo or wheel, to modify system connections without introducing a password (discouraged)') option('polkit_agent_helper_1', type: 'string', value: '', description: 'Path name to the polkit-agent-helper-1 binary from polkit') option('selinux', type: 'boolean', value: true, description: 'Build with SELinux') option('systemd_journal', type: 'boolean', value: true, description: 'Use systemd journal for logging')