From a69a649195e25ce6e0844c9ebe884b91b1d7cbc0 Mon Sep 17 00:00:00 2001 From: Tomas Barton Date: Wed, 29 Jun 2022 16:57:11 +0200 Subject: [PATCH 01/14] Support modifying sudoers Defaults --- README.md | 13 +++++++++++++ data/common.yaml | 5 +++++ data/os_family/Darwin.yaml | 3 +++ data/os_family/Debian.yaml | 4 ++++ data/os_family/RedHat.yaml | 3 +++ data/os_family/Suse.yaml | 1 + hiera.yaml | 13 +++++++++++++ manifests/init.pp | 1 + spec/classes/sudo_spec.rb | 32 +++++++++++++++++++++++++++++++- templates/sudoers.aix.erb | 6 ++++++ templates/sudoers.archlinux.erb | 6 ++++++ templates/sudoers.darwin.erb | 8 +++++++- templates/sudoers.debian.erb | 8 ++++++-- templates/sudoers.freebsd.erb | 6 ++++++ templates/sudoers.gentoo.erb | 6 ++++++ templates/sudoers.olddebian.erb | 7 +++++++ templates/sudoers.omnios.erb | 6 ++++++ templates/sudoers.openbsd.erb | 6 ++++++ templates/sudoers.rhel5.erb | 8 +++++++- templates/sudoers.rhel6.erb | 8 +++++++- templates/sudoers.rhel7.erb | 7 ++++++- templates/sudoers.rhel8.erb | 7 ++++++- templates/sudoers.smartos.erb | 6 ++++++ templates/sudoers.solaris.erb | 6 ++++++ templates/sudoers.suse.erb | 6 ++++++ templates/sudoers.ubuntu.erb | 8 ++++++-- 26 files changed, 180 insertions(+), 10 deletions(-) create mode 100644 data/common.yaml create mode 100644 data/os_family/Darwin.yaml create mode 100644 data/os_family/Debian.yaml create mode 100644 data/os_family/RedHat.yaml create mode 100644 data/os_family/Suse.yaml create mode 100644 hiera.yaml diff --git a/README.md b/README.md index c77543c..e739fba 100644 --- a/README.md +++ b/README.md @@ -189,6 +189,19 @@ sudo::configs: 'template' : "mymodule/bill.erb" ``` +##### Override sudoers defaults + +You can modify `Default_Entry` lines by passing a `Hash` to `sudo::defaults`, where the key is `Defaults` parameter name (see `man 5 sudoers` for more details): + +```yaml +sudo::defaults: + lecture: always + badpass_message: "Password is wrong, please try again" + passwd_tries: 5 + insults: + mailto: root@example.com +``` + ##### Set a custom name for the sudoers file In some edge cases, the automatically generated sudoers file name is insufficient. For example, when an application generates a sudoers file with a fixed file name, using this class with the purge option enabled will always delete the custom file and adding it manually will generate a file with the right content, but the wrong name. To solve this, you can use the ```sudo_file_name``` option to manually set the desired file name. diff --git a/data/common.yaml b/data/common.yaml new file mode 100644 index 0000000..6b38a55 --- /dev/null +++ b/data/common.yaml @@ -0,0 +1,5 @@ +--- +lookup_options: + sudo::defaults: + merge: + strategy: deep diff --git a/data/os_family/Darwin.yaml b/data/os_family/Darwin.yaml new file mode 100644 index 0000000..31c1efc --- /dev/null +++ b/data/os_family/Darwin.yaml @@ -0,0 +1,3 @@ +--- +sudo::defaults: + env_reset: \ No newline at end of file diff --git a/data/os_family/Debian.yaml b/data/os_family/Debian.yaml new file mode 100644 index 0000000..7f3e8b8 --- /dev/null +++ b/data/os_family/Debian.yaml @@ -0,0 +1,4 @@ +--- +sudo::defaults: + env_reset: + mail_badpass: \ No newline at end of file diff --git a/data/os_family/RedHat.yaml b/data/os_family/RedHat.yaml new file mode 100644 index 0000000..aa98e46 --- /dev/null +++ b/data/os_family/RedHat.yaml @@ -0,0 +1,3 @@ +--- +sudo::defaults: + env_reset: diff --git a/data/os_family/Suse.yaml b/data/os_family/Suse.yaml new file mode 100644 index 0000000..8d59faa --- /dev/null +++ b/data/os_family/Suse.yaml @@ -0,0 +1 @@ +--- {} \ No newline at end of file diff --git a/hiera.yaml b/hiera.yaml new file mode 100644 index 0000000..f8874bc --- /dev/null +++ b/hiera.yaml @@ -0,0 +1,13 @@ +--- +version: 5 + +defaults: + datadir: data + data_hash: yaml_data + +hierarchy: + - name: "osfamily" + paths: + - "os_family/%{facts.os.family}.yaml" + - name: 'common' + path: 'common.yaml' diff --git a/manifests/init.pp b/manifests/init.pp index 3261168..82f9761 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -149,6 +149,7 @@ Enum['absent','password','nopassword'] $wheel_config = $sudo::params::wheel_config, Optional[Array[String]] $sudoreplay_discard = undef, Hash $configs = {}, + Hash $defaults = {}, #$sudo::params::defaults, ) inherits sudo::params { case $enable { true: { diff --git a/spec/classes/sudo_spec.rb b/spec/classes/sudo_spec.rb index 533a80c..1faa071 100644 --- a/spec/classes/sudo_spec.rb +++ b/spec/classes/sudo_spec.rb @@ -14,7 +14,7 @@ it { is_expected.to compile.with_all_deps } end - unless os =~ %r{^(debian|ubuntu)} then + unless os =~ %r{^(debian|ubuntu)} context 'wheel_config is absent' do let :params do { @@ -48,6 +48,36 @@ it { is_expected.to contain_file('/etc/sudoers').with_content(%r{^%wheel\s+ALL=\(ALL\)\s+NOPASSWD:\s+ALL$}) } end end + + unless os =~ %r{^(gentoo|archlinux-rolling)} + context 'env_reset default is set' do + it { is_expected.to contain_file('/etc/sudoers').with_content(%r{^Defaults\s+env_reset$}) } + end + end + + if os =~ %r{^(debian|ubuntu)} + context 'mail_badpass default is set' do + it { is_expected.to contain_file('/etc/sudoers').with_content(%r{^Defaults\s+mail_badpass$}) } + end + end + + if os =~ %r{^(redhat)} + context '!visiblepw default is set' do + it { is_expected.to contain_file('/etc/sudoers').with_content(%r{^Defaults\s+!visiblepw$}) } + end + end + + context 'Modify passwd_tries default' do + let :params do + { + defaults: { + passwd_tries: '5', + } + } + end + + it { is_expected.to contain_file('/etc/sudoers').with_content(%r{^Defaults\s+passwd_tries=5$}) } + end end end diff --git a/templates/sudoers.aix.erb b/templates/sudoers.aix.erb index 6f9b2fd..4483207 100644 --- a/templates/sudoers.aix.erb +++ b/templates/sudoers.aix.erb @@ -63,6 +63,12 @@ # Defaults!/usr/bin/sudoreplay !log_output # Defaults!/usr/local/bin/sudoreplay !log_output # Defaults!/sbin/reboot !log_output +<% @defaults.sort.each do |k,v| -%> +Defaults <%= k -%> +<% if (!v.nil? and v != '')-%> +<%= "=#{v}" -%> +<% end %> +<% end -%> <% if @use_sudoreplay %> Defaults log_output diff --git a/templates/sudoers.archlinux.erb b/templates/sudoers.archlinux.erb index 4768ec0..2fed465 100644 --- a/templates/sudoers.archlinux.erb +++ b/templates/sudoers.archlinux.erb @@ -63,6 +63,12 @@ # Defaults!/usr/bin/sudoreplay !log_output # Defaults!/usr/local/bin/sudoreplay !log_output # Defaults!/sbin/reboot !log_output +<% @defaults.sort.each do |k,v| -%> +Defaults <%= k -%> +<% if (!v.nil? and v != '')-%> +<%= "=#{v}" -%> +<% end %> +<% end -%> <% if @use_sudoreplay %> Defaults log_output diff --git a/templates/sudoers.darwin.erb b/templates/sudoers.darwin.erb index d022ef2..e560c4b 100644 --- a/templates/sudoers.darwin.erb +++ b/templates/sudoers.darwin.erb @@ -16,7 +16,12 @@ # Cmnd alias specification # Defaults specification -Defaults env_reset +<% @defaults.sort.each do |k,v| -%> +Defaults <%= k -%> +<% if (!v.nil? and v != '')-%> +<%= "=#{v}" -%> +<% end %> +<% end -%> Defaults env_keep += "BLOCKSIZE" Defaults env_keep += "COLORFGBG COLORTERM" Defaults env_keep += "__CF_USER_TEXT_ENCODING" @@ -30,6 +35,7 @@ Defaults env_keep += "DISPLAY XAUTHORIZATION XAUTHORITY" Defaults env_keep += "EDITOR VISUAL" Defaults env_keep += "HOME MAIL" + <% if @use_sudoreplay %> Defaults log_output Defaults!/usr/bin/sudoreplay !log_output diff --git a/templates/sudoers.debian.erb b/templates/sudoers.debian.erb index b66e8a8..0f1bf46 100644 --- a/templates/sudoers.debian.erb +++ b/templates/sudoers.debian.erb @@ -1,7 +1,11 @@ # file managed by puppet (unless config_file_replace=false) # -Defaults env_reset -Defaults mail_badpass +<% @defaults.sort.each do |k,v| -%> +Defaults <%= k -%> +<% if (!v.nil? and v != '')-%> +<%= "=#{v}" -%> +<% end %> +<% end -%> Defaults secure_path="<%= @secure_path %>" <% if @use_sudoreplay %> diff --git a/templates/sudoers.freebsd.erb b/templates/sudoers.freebsd.erb index b940b2d..0d5d0f2 100644 --- a/templates/sudoers.freebsd.erb +++ b/templates/sudoers.freebsd.erb @@ -78,6 +78,12 @@ # Defaults!/usr/bin/sudoreplay !log_output # Defaults!/usr/local/bin/sudoreplay !log_output # Defaults!REBOOT !log_output +<% @defaults.sort.each do |k,v| -%> +Defaults <%= k -%> +<% if (!v.nil? and v != '')-%> +<%= "=#{v}" -%> +<% end %> +<% end -%> <% if @use_sudoreplay %> Defaults log_output diff --git a/templates/sudoers.gentoo.erb b/templates/sudoers.gentoo.erb index 8243047..a957719 100644 --- a/templates/sudoers.gentoo.erb +++ b/templates/sudoers.gentoo.erb @@ -64,6 +64,12 @@ # Defaults!/usr/bin/sudoreplay !log_output # Defaults!/usr/local/bin/sudoreplay !log_output # Defaults!REBOOT !log_output +<% @defaults.sort.each do |k,v| -%> +Defaults <%= k -%> +<% if (!v.nil? and v != '')-%> +<%= "=#{v}" -%> +<% end %> +<% end -%> <% if @use_sudoreplay %> Defaults log_output diff --git a/templates/sudoers.olddebian.erb b/templates/sudoers.olddebian.erb index da4be90..780e888 100644 --- a/templates/sudoers.olddebian.erb +++ b/templates/sudoers.olddebian.erb @@ -63,6 +63,13 @@ Defaults env_keep += "XAPPLRESDIR XFILESEARCHPATH XUSERFILESEARCHPATH" # Defaults!/usr/bin/sudoreplay !log_output # Defaults!/usr/local/bin/sudoreplay !log_output # Defaults!/sbin/reboot !log_output +<% @defaults.sort.each do |k,v| -%> +Defaults <%= k -%> +<% if (!v.nil? and v != '')-%> +<%= "=#{v}" -%> +<% end %> +<% end -%> + <% if @use_sudoreplay %> Defaults log_output Defaults!/usr/bin/sudoreplay !log_output diff --git a/templates/sudoers.omnios.erb b/templates/sudoers.omnios.erb index 48d0c13..98ba204 100644 --- a/templates/sudoers.omnios.erb +++ b/templates/sudoers.omnios.erb @@ -63,6 +63,12 @@ # Defaults!/usr/bin/sudoreplay !log_output # Defaults!/usr/local/bin/sudoreplay !log_output # Defaults!/sbin/reboot !log_output +<% @defaults.sort.each do |k,v| -%> +Defaults <%= k -%> +<% if (!v.nil? and v != '')-%> +<%= "=#{v}" -%> +<% end %> +<% end -%> <% if @use_sudoreplay %> Defaults log_output diff --git a/templates/sudoers.openbsd.erb b/templates/sudoers.openbsd.erb index 7e3b38d..ae9798f 100644 --- a/templates/sudoers.openbsd.erb +++ b/templates/sudoers.openbsd.erb @@ -32,6 +32,12 @@ Defaults:%wsrc env_keep +="SUBPACKAGE WRKOBJDIR SUDO_PORT_V1" # Uncomment to preserve the environment for users in group wheel #Defaults:%wheel !env_reset +<% @defaults.sort.each do |k,v| -%> +Defaults <%= k -%> +<% if (!v.nil? and v != '')-%> +<%= "=#{v}" -%> +<% end %> +<% end -%> <% if @use_sudoreplay %> Defaults log_output diff --git a/templates/sudoers.rhel5.erb b/templates/sudoers.rhel5.erb index ed4b7d8..ebf24be 100644 --- a/templates/sudoers.rhel5.erb +++ b/templates/sudoers.rhel5.erb @@ -56,7 +56,13 @@ # Defaults !visiblepw -Defaults env_reset +<% @defaults.sort.each do |k,v| -%> +Defaults <%= k -%> +<% if (!v.nil? and v != '')-%> +<%= "=#{v}" -%> +<% end %> +<% end -%> + Defaults env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR \ LS_COLORS MAIL PS1 PS2 QTDIR USERNAME \ LANG LC_ADDRESS LC_CTYPE LC_COLLATE LC_IDENTIFICATION \ diff --git a/templates/sudoers.rhel6.erb b/templates/sudoers.rhel6.erb index 63b4b71..5f4d22c 100644 --- a/templates/sudoers.rhel6.erb +++ b/templates/sudoers.rhel6.erb @@ -60,9 +60,15 @@ Defaults !visiblepw # Preserving HOME has security implications since many programs # use it when searching for configuration files. # +<% @defaults.sort.each do |k,v| -%> +Defaults <%= k -%> +<% if (!v.nil? and v != '')-%> +<%= "=#{v}" -%> +<% end %> +<% end -%> + Defaults always_set_home -Defaults env_reset Defaults env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS" Defaults env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE" Defaults env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES" diff --git a/templates/sudoers.rhel7.erb b/templates/sudoers.rhel7.erb index 5d24af7..a72f54f 100644 --- a/templates/sudoers.rhel7.erb +++ b/templates/sudoers.rhel7.erb @@ -63,9 +63,14 @@ Defaults !visiblepw # this option is only effective for configurations where either # env_reset is disabled or HOME is present in the env_keep list. # +<% @defaults.sort.each do |k,v| -%> +Defaults <%= k -%> +<% if (!v.nil? and v != '')-%> +<%= "=#{v}" -%> +<% end %> +<% end -%> Defaults always_set_home -Defaults env_reset Defaults env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS" Defaults env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE" Defaults env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES" diff --git a/templates/sudoers.rhel8.erb b/templates/sudoers.rhel8.erb index 5c477e7..335df6c 100644 --- a/templates/sudoers.rhel8.erb +++ b/templates/sudoers.rhel8.erb @@ -63,6 +63,12 @@ Defaults !visiblepw # this option is only effective for configurations where either # env_reset is disabled or HOME is present in the env_keep list. # +<% @defaults.sort.each do |k,v| -%> +Defaults <%= k -%> +<% if (!v.nil? and v != '')-%> +<%= "=#{v}" -%> +<% end %> +<% end -%> Defaults always_set_home Defaults match_group_by_gid @@ -74,7 +80,6 @@ Defaults match_group_by_gid # Disable this option for new behavior. Defaults always_query_group_plugin -Defaults env_reset Defaults env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS" Defaults env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE" Defaults env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES" diff --git a/templates/sudoers.smartos.erb b/templates/sudoers.smartos.erb index ef74acc..b64db6b 100644 --- a/templates/sudoers.smartos.erb +++ b/templates/sudoers.smartos.erb @@ -55,6 +55,12 @@ # Defaults!/usr/bin/sudoreplay !log_output # Defaults!/usr/local/bin/sudoreplay !log_output # Defaults!/sbin/reboot !log_output +<% @defaults.sort.each do |k,v| -%> +Defaults <%= k -%> +<% if (!v.nil? and v != '')-%> +<%= "=#{v}" -%> +<% end %> +<% end -%> <% if @use_sudoreplay %> Defaults log_output diff --git a/templates/sudoers.solaris.erb b/templates/sudoers.solaris.erb index 049150b..88afe93 100644 --- a/templates/sudoers.solaris.erb +++ b/templates/sudoers.solaris.erb @@ -63,6 +63,12 @@ # Defaults!/usr/bin/sudoreplay !log_output # Defaults!/usr/local/bin/sudoreplay !log_output # Defaults!/sbin/reboot !log_output +<% @defaults.sort.each do |k,v| -%> +Defaults <%= k -%> +<% if (!v.nil? and v != '')-%> +<%= "=#{v}" -%> +<% end %> +<% end -%> <% if @use_sudoreplay %> Defaults log_output diff --git a/templates/sudoers.suse.erb b/templates/sudoers.suse.erb index 62811a9..3661e2b 100644 --- a/templates/sudoers.suse.erb +++ b/templates/sudoers.suse.erb @@ -57,6 +57,12 @@ Defaults !insults # Defaults log_output # Defaults!/usr/bin/sudoreplay !log_output # Defaults!/sbin/reboot !log_output +<% @defaults.sort.each do |k,v| -%> +Defaults <%= k -%> +<% if (!v.nil? and v != '')-%> +<%= "=#{v}" -%> +<% end %> +<% end -%> <% if @use_sudoreplay %> Defaults log_output diff --git a/templates/sudoers.ubuntu.erb b/templates/sudoers.ubuntu.erb index fe953dc..f014311 100644 --- a/templates/sudoers.ubuntu.erb +++ b/templates/sudoers.ubuntu.erb @@ -7,8 +7,12 @@ # # See the man page for details on how to write a sudoers file. # -Defaults env_reset -Defaults mail_badpass +<% @defaults.sort.each do |k,v| -%> +Defaults <%= k -%> +<% if (!v.nil? and v != '')-%> +<%= "=#{v}" -%> +<% end %> +<% end -%> Defaults secure_path="<%= @secure_path %>" <% if @use_sudoreplay %> From a11099b0ea046dd21d5dbb54baaa43ecbdd05248 Mon Sep 17 00:00:00 2001 From: Brian Schonecker Date: Tue, 12 Jul 2022 14:37:12 -0400 Subject: [PATCH 02/14] Update RHEL7 template to more closely align with RHEL7 sudoers file. --- templates/sudoers.rhel7.erb | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/templates/sudoers.rhel7.erb b/templates/sudoers.rhel7.erb index a72f54f..4e9db9d 100644 --- a/templates/sudoers.rhel7.erb +++ b/templates/sudoers.rhel7.erb @@ -70,6 +70,15 @@ Defaults <%= k -%> <% end %> <% end -%> Defaults always_set_home +Defaults match_group_by_gid + +# Prior to version 1.8.15, groups listed in sudoers that were +# found in the system group database were passed to the group +# plugin, if any. Starting with 1.8.15, only groups of the fo +# %:group are resolved via the group plugin by default. +# We enable always_query_group_plugin to restore old behavior +# Disable this option for new behavior. +Defaults always_query_group_plugin Defaults env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS" Defaults env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE" From ca3c6841ce71189b1ff9b1e5e868cbffe640f5ae Mon Sep 17 00:00:00 2001 From: Tomas Barton Date: Mon, 18 Jul 2022 09:33:36 +0200 Subject: [PATCH 03/14] Remove hiera modifications --- data/common.yaml | 5 ----- data/os_family/Darwin.yaml | 3 --- data/os_family/Debian.yaml | 4 ---- data/os_family/RedHat.yaml | 3 --- data/os_family/Suse.yaml | 1 - hiera.yaml | 13 ------------- manifests/init.pp | 2 +- manifests/params.pp | 18 ++++++++++++++++++ 8 files changed, 19 insertions(+), 30 deletions(-) delete mode 100644 data/common.yaml delete mode 100644 data/os_family/Darwin.yaml delete mode 100644 data/os_family/Debian.yaml delete mode 100644 data/os_family/RedHat.yaml delete mode 100644 data/os_family/Suse.yaml delete mode 100644 hiera.yaml diff --git a/data/common.yaml b/data/common.yaml deleted file mode 100644 index 6b38a55..0000000 --- a/data/common.yaml +++ /dev/null @@ -1,5 +0,0 @@ ---- -lookup_options: - sudo::defaults: - merge: - strategy: deep diff --git a/data/os_family/Darwin.yaml b/data/os_family/Darwin.yaml deleted file mode 100644 index 31c1efc..0000000 --- a/data/os_family/Darwin.yaml +++ /dev/null @@ -1,3 +0,0 @@ ---- -sudo::defaults: - env_reset: \ No newline at end of file diff --git a/data/os_family/Debian.yaml b/data/os_family/Debian.yaml deleted file mode 100644 index 7f3e8b8..0000000 --- a/data/os_family/Debian.yaml +++ /dev/null @@ -1,4 +0,0 @@ ---- -sudo::defaults: - env_reset: - mail_badpass: \ No newline at end of file diff --git a/data/os_family/RedHat.yaml b/data/os_family/RedHat.yaml deleted file mode 100644 index aa98e46..0000000 --- a/data/os_family/RedHat.yaml +++ /dev/null @@ -1,3 +0,0 @@ ---- -sudo::defaults: - env_reset: diff --git a/data/os_family/Suse.yaml b/data/os_family/Suse.yaml deleted file mode 100644 index 8d59faa..0000000 --- a/data/os_family/Suse.yaml +++ /dev/null @@ -1 +0,0 @@ ---- {} \ No newline at end of file diff --git a/hiera.yaml b/hiera.yaml deleted file mode 100644 index f8874bc..0000000 --- a/hiera.yaml +++ /dev/null @@ -1,13 +0,0 @@ ---- -version: 5 - -defaults: - datadir: data - data_hash: yaml_data - -hierarchy: - - name: "osfamily" - paths: - - "os_family/%{facts.os.family}.yaml" - - name: 'common' - path: 'common.yaml' diff --git a/manifests/init.pp b/manifests/init.pp index 82f9761..6658376 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -149,7 +149,7 @@ Enum['absent','password','nopassword'] $wheel_config = $sudo::params::wheel_config, Optional[Array[String]] $sudoreplay_discard = undef, Hash $configs = {}, - Hash $defaults = {}, #$sudo::params::defaults, + Hash $defaults = $sudo::params::defaults, ) inherits sudo::params { case $enable { true: { diff --git a/manifests/params.pp b/manifests/params.pp index 61437b8..b69212e 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -33,6 +33,10 @@ $config_dir_keepme = false $package_provider = undef $wheel_config = 'absent' + $defaults = { + 'env_reset' => undef, + 'mail_badpass' => undef, + } } 'RedHat': { $package = 'sudo' @@ -80,6 +84,9 @@ $config_file_group = 'root' $config_dir_keepme = false $package_provider = undef + $defaults = { + 'env_reset' => undef, + } } 'Suse': { $package = 'sudo' @@ -95,6 +102,7 @@ $config_dir_keepme = false $package_provider = undef $wheel_config = 'absent' + $defaults = {} } 'Solaris': { case $facts['os']['name'] { @@ -166,6 +174,7 @@ } } } + $defaults = {} } 'FreeBSD': { $package = 'security/sudo' @@ -181,6 +190,7 @@ $config_dir_keepme = true $package_provider = undef $wheel_config = 'absent' + $defaults = {} } 'OpenBSD': { if (versioncmp($::kernelversion, '5.8') < 0) { @@ -199,6 +209,7 @@ $config_dir_keepme = false $package_provider = undef $wheel_config = 'absent' + $defaults = {} } 'AIX': { $package = 'sudo' @@ -214,6 +225,7 @@ $config_dir_keepme = false $package_provider = 'rpm' $wheel_config = 'absent' + $defaults = {} } 'Darwin': { $package = undef @@ -229,6 +241,9 @@ $config_dir_keepme = false $package_provider = undef $wheel_config = 'absent' + $defaults = { + 'env_reset' => undef, + } } default: { case $facts['os']['name'] { @@ -246,6 +261,7 @@ $config_dir_keepme = false $package_provider = undef $wheel_config = 'absent' + $defaults = {} } /^(Arch|Manjaro)(.{0}|linux)$/: { $package = 'sudo' @@ -261,6 +277,7 @@ $config_dir_keepme = false $package_provider = undef $wheel_config = 'absent' + $defaults = {} } 'Amazon': { $package = 'sudo' @@ -288,6 +305,7 @@ $config_dir_keepme = false $package_provider = undef $wheel_config = 'absent' + $defaults = {} } default: { fail("Unsupported platform: ${facts['os']['family']}/${facts['os']['name']}") From 9ea0a1427b11b49b16cb302a4634c280368f6133 Mon Sep 17 00:00:00 2001 From: Tomas Barton Date: Mon, 18 Jul 2022 11:53:37 +0200 Subject: [PATCH 04/14] Use custom ruby function to format defaults --- README.md | 12 ++++-- lib/puppet/functions/sudo/defaults.rb | 61 +++++++++++++++++++++++++++ manifests/init.pp | 2 +- manifests/params.pp | 4 +- spec/classes/sudo_spec.rb | 19 ++++++++- spec/functions/defaults_spec.rb | 12 ++++++ templates/sudoers.aix.erb | 7 +-- templates/sudoers.archlinux.erb | 7 +-- templates/sudoers.darwin.erb | 7 +-- templates/sudoers.debian.erb | 7 +-- templates/sudoers.freebsd.erb | 7 +-- templates/sudoers.gentoo.erb | 7 +-- templates/sudoers.olddebian.erb | 7 +-- templates/sudoers.omnios.erb | 7 +-- templates/sudoers.openbsd.erb | 7 +-- templates/sudoers.rhel5.erb | 7 +-- templates/sudoers.rhel6.erb | 7 +-- templates/sudoers.rhel7.erb | 7 +-- templates/sudoers.rhel8.erb | 7 +-- templates/sudoers.smartos.erb | 7 +-- templates/sudoers.solaris.erb | 7 +-- templates/sudoers.suse.erb | 7 +-- templates/sudoers.ubuntu.erb | 7 +-- types/defaults.pp | 7 +++ types/defaults_operator.pp | 1 + 25 files changed, 128 insertions(+), 109 deletions(-) create mode 100644 lib/puppet/functions/sudo/defaults.rb create mode 100644 spec/functions/defaults_spec.rb create mode 100644 types/defaults.pp create mode 100644 types/defaults_operator.pp diff --git a/README.md b/README.md index e739fba..f52cf84 100644 --- a/README.md +++ b/README.md @@ -195,11 +195,15 @@ You can modify `Default_Entry` lines by passing a `Hash` to `sudo::defaults`, wh ```yaml sudo::defaults: - lecture: always - badpass_message: "Password is wrong, please try again" - passwd_tries: 5 + lecture: + value: always + badpass_message: + value: "Password is wrong, please try again" + passwd_tries: + value: 5 insults: - mailto: root@example.com + mailto: + value: root@example.com ``` ##### Set a custom name for the sudoers file diff --git a/lib/puppet/functions/sudo/defaults.rb b/lib/puppet/functions/sudo/defaults.rb new file mode 100644 index 0000000..3af178d --- /dev/null +++ b/lib/puppet/functions/sudo/defaults.rb @@ -0,0 +1,61 @@ +# Formats sudoers defaults config see https://linux.die.net/man/5/sudoers +# +# Default_Type ::= 'Defaults' | +# 'Defaults' '@' Host_List | +# 'Defaults' ':' User_List | +# 'Defaults' '!' Cmnd_List | +# 'Defaults' '>' Runas_List +# +# Default_Entry ::= Default_Type Parameter_List +# +# Parameter_List ::= Parameter | +# Parameter ',' Parameter_List +# +# Parameter ::= Parameter '=' Value | +# Parameter '+=' Value | +# Parameter '-=' Value | +# '!'* Parameter +# +# The function is passed an Array of Tuples +# e.g. [["env_reset", nil]] +# [["mailto", {"value" => root}]] +Puppet::Functions.create_function(:'sudo::defaults') do + def defaults(*args) + res = '' + unless args.nil? + args.each do |tuple| + if tuple.size == 2 + res.concat(defaults_entry(tuple[0], tuple[1])) + else + raise "Unsupported number of arguments #{args.size}: #{args.inspect}" + end + end + else + raise "Unsupported number of arguments #{args.size}: #{args.inspect}" + end + + res + end + + def defaults_entry(key, config) + entry = "Defaults\t#{key}" + + unless config.nil? + if config.key? 'list' + entry.concat("#{config['list']}") + end + + operator = '=' + if config.key? 'operator' + operator = config['operator'] + end + + if config.key? 'value' + entry.concat("#{operator}#{config['value']}") + end + end + + + entry.concat("\n") + end +end \ No newline at end of file diff --git a/manifests/init.pp b/manifests/init.pp index 6658376..65a36ab 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -149,7 +149,7 @@ Enum['absent','password','nopassword'] $wheel_config = $sudo::params::wheel_config, Optional[Array[String]] $sudoreplay_discard = undef, Hash $configs = {}, - Hash $defaults = $sudo::params::defaults, + Sudo::Defaults $defaults = $sudo::params::defaults, ) inherits sudo::params { case $enable { true: { diff --git a/manifests/params.pp b/manifests/params.pp index b69212e..488d871 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -174,7 +174,9 @@ } } } - $defaults = {} + $defaults = { + 'env_reset' => undef, + } } 'FreeBSD': { $package = 'security/sudo' diff --git a/spec/classes/sudo_spec.rb b/spec/classes/sudo_spec.rb index 1faa071..8de7526 100644 --- a/spec/classes/sudo_spec.rb +++ b/spec/classes/sudo_spec.rb @@ -71,13 +71,30 @@ let :params do { defaults: { - passwd_tries: '5', + passwd_tries: { + value: 5, + } } } end it { is_expected.to contain_file('/etc/sudoers').with_content(%r{^Defaults\s+passwd_tries=5$}) } end + + context 'Modify env_keep default' do + let :params do + { + defaults: { + env_keep: { + operator: '+=', + value: 'SOME_VAR', + } + } + } + end + + it { is_expected.to contain_file('/etc/sudoers').with_content(%r{^Defaults\s+env_keep\+=SOME_VAR$}) } + end end end diff --git a/spec/functions/defaults_spec.rb b/spec/functions/defaults_spec.rb new file mode 100644 index 0000000..02f4578 --- /dev/null +++ b/spec/functions/defaults_spec.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'sudo::defaults' do + it { is_expected.to run.with_params(['mailto', {'value' => 'root'}] + ).and_return("Defaults\tmailto=root\n") } + it { is_expected.to run.with_params(['env_reset', nil] + ).and_return("Defaults\tenv_reset\n") } + + it { is_expected.to run.with_params(nil).and_raise_error(StandardError) } +end diff --git a/templates/sudoers.aix.erb b/templates/sudoers.aix.erb index 4483207..546aca2 100644 --- a/templates/sudoers.aix.erb +++ b/templates/sudoers.aix.erb @@ -63,12 +63,7 @@ # Defaults!/usr/bin/sudoreplay !log_output # Defaults!/usr/local/bin/sudoreplay !log_output # Defaults!/sbin/reboot !log_output -<% @defaults.sort.each do |k,v| -%> -Defaults <%= k -%> -<% if (!v.nil? and v != '')-%> -<%= "=#{v}" -%> -<% end %> -<% end -%> +<%= scope.call_function('sudo::defaults', @defaults) -%> <% if @use_sudoreplay %> Defaults log_output diff --git a/templates/sudoers.archlinux.erb b/templates/sudoers.archlinux.erb index 2fed465..a9e3e19 100644 --- a/templates/sudoers.archlinux.erb +++ b/templates/sudoers.archlinux.erb @@ -63,12 +63,7 @@ # Defaults!/usr/bin/sudoreplay !log_output # Defaults!/usr/local/bin/sudoreplay !log_output # Defaults!/sbin/reboot !log_output -<% @defaults.sort.each do |k,v| -%> -Defaults <%= k -%> -<% if (!v.nil? and v != '')-%> -<%= "=#{v}" -%> -<% end %> -<% end -%> +<%= scope.call_function('sudo::defaults', @defaults) -%> <% if @use_sudoreplay %> Defaults log_output diff --git a/templates/sudoers.darwin.erb b/templates/sudoers.darwin.erb index e560c4b..9bcb956 100644 --- a/templates/sudoers.darwin.erb +++ b/templates/sudoers.darwin.erb @@ -16,12 +16,7 @@ # Cmnd alias specification # Defaults specification -<% @defaults.sort.each do |k,v| -%> -Defaults <%= k -%> -<% if (!v.nil? and v != '')-%> -<%= "=#{v}" -%> -<% end %> -<% end -%> +<%= scope.call_function('sudo::defaults', @defaults) -%> Defaults env_keep += "BLOCKSIZE" Defaults env_keep += "COLORFGBG COLORTERM" Defaults env_keep += "__CF_USER_TEXT_ENCODING" diff --git a/templates/sudoers.debian.erb b/templates/sudoers.debian.erb index 0f1bf46..56a8a72 100644 --- a/templates/sudoers.debian.erb +++ b/templates/sudoers.debian.erb @@ -1,11 +1,6 @@ # file managed by puppet (unless config_file_replace=false) # -<% @defaults.sort.each do |k,v| -%> -Defaults <%= k -%> -<% if (!v.nil? and v != '')-%> -<%= "=#{v}" -%> -<% end %> -<% end -%> +<%= scope.call_function('sudo::defaults', @defaults) -%> Defaults secure_path="<%= @secure_path %>" <% if @use_sudoreplay %> diff --git a/templates/sudoers.freebsd.erb b/templates/sudoers.freebsd.erb index 0d5d0f2..fd0ad30 100644 --- a/templates/sudoers.freebsd.erb +++ b/templates/sudoers.freebsd.erb @@ -78,12 +78,7 @@ # Defaults!/usr/bin/sudoreplay !log_output # Defaults!/usr/local/bin/sudoreplay !log_output # Defaults!REBOOT !log_output -<% @defaults.sort.each do |k,v| -%> -Defaults <%= k -%> -<% if (!v.nil? and v != '')-%> -<%= "=#{v}" -%> -<% end %> -<% end -%> +<%= scope.call_function('sudo::defaults', @defaults) -%> <% if @use_sudoreplay %> Defaults log_output diff --git a/templates/sudoers.gentoo.erb b/templates/sudoers.gentoo.erb index a957719..c8e0bcd 100644 --- a/templates/sudoers.gentoo.erb +++ b/templates/sudoers.gentoo.erb @@ -64,12 +64,7 @@ # Defaults!/usr/bin/sudoreplay !log_output # Defaults!/usr/local/bin/sudoreplay !log_output # Defaults!REBOOT !log_output -<% @defaults.sort.each do |k,v| -%> -Defaults <%= k -%> -<% if (!v.nil? and v != '')-%> -<%= "=#{v}" -%> -<% end %> -<% end -%> +<%= scope.call_function('sudo::defaults', @defaults) -%> <% if @use_sudoreplay %> Defaults log_output diff --git a/templates/sudoers.olddebian.erb b/templates/sudoers.olddebian.erb index 780e888..8c95161 100644 --- a/templates/sudoers.olddebian.erb +++ b/templates/sudoers.olddebian.erb @@ -63,12 +63,7 @@ Defaults env_keep += "XAPPLRESDIR XFILESEARCHPATH XUSERFILESEARCHPATH" # Defaults!/usr/bin/sudoreplay !log_output # Defaults!/usr/local/bin/sudoreplay !log_output # Defaults!/sbin/reboot !log_output -<% @defaults.sort.each do |k,v| -%> -Defaults <%= k -%> -<% if (!v.nil? and v != '')-%> -<%= "=#{v}" -%> -<% end %> -<% end -%> +<%= scope.call_function('sudo::defaults', @defaults) -%> <% if @use_sudoreplay %> Defaults log_output diff --git a/templates/sudoers.omnios.erb b/templates/sudoers.omnios.erb index 98ba204..2663dcc 100644 --- a/templates/sudoers.omnios.erb +++ b/templates/sudoers.omnios.erb @@ -63,12 +63,7 @@ # Defaults!/usr/bin/sudoreplay !log_output # Defaults!/usr/local/bin/sudoreplay !log_output # Defaults!/sbin/reboot !log_output -<% @defaults.sort.each do |k,v| -%> -Defaults <%= k -%> -<% if (!v.nil? and v != '')-%> -<%= "=#{v}" -%> -<% end %> -<% end -%> +<%= scope.call_function('sudo::defaults', @defaults) -%> <% if @use_sudoreplay %> Defaults log_output diff --git a/templates/sudoers.openbsd.erb b/templates/sudoers.openbsd.erb index ae9798f..ed4b2f1 100644 --- a/templates/sudoers.openbsd.erb +++ b/templates/sudoers.openbsd.erb @@ -32,12 +32,7 @@ Defaults:%wsrc env_keep +="SUBPACKAGE WRKOBJDIR SUDO_PORT_V1" # Uncomment to preserve the environment for users in group wheel #Defaults:%wheel !env_reset -<% @defaults.sort.each do |k,v| -%> -Defaults <%= k -%> -<% if (!v.nil? and v != '')-%> -<%= "=#{v}" -%> -<% end %> -<% end -%> +<%= scope.call_function('sudo::defaults', @defaults) -%> <% if @use_sudoreplay %> Defaults log_output diff --git a/templates/sudoers.rhel5.erb b/templates/sudoers.rhel5.erb index ebf24be..2a43303 100644 --- a/templates/sudoers.rhel5.erb +++ b/templates/sudoers.rhel5.erb @@ -56,12 +56,7 @@ # Defaults !visiblepw -<% @defaults.sort.each do |k,v| -%> -Defaults <%= k -%> -<% if (!v.nil? and v != '')-%> -<%= "=#{v}" -%> -<% end %> -<% end -%> +<%= scope.call_function('sudo::defaults', @defaults) -%> Defaults env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR \ LS_COLORS MAIL PS1 PS2 QTDIR USERNAME \ diff --git a/templates/sudoers.rhel6.erb b/templates/sudoers.rhel6.erb index 5f4d22c..2ea642d 100644 --- a/templates/sudoers.rhel6.erb +++ b/templates/sudoers.rhel6.erb @@ -60,12 +60,7 @@ Defaults !visiblepw # Preserving HOME has security implications since many programs # use it when searching for configuration files. # -<% @defaults.sort.each do |k,v| -%> -Defaults <%= k -%> -<% if (!v.nil? and v != '')-%> -<%= "=#{v}" -%> -<% end %> -<% end -%> +<%= scope.call_function('sudo::defaults', @defaults) -%> Defaults always_set_home diff --git a/templates/sudoers.rhel7.erb b/templates/sudoers.rhel7.erb index 4e9db9d..2bbe8da 100644 --- a/templates/sudoers.rhel7.erb +++ b/templates/sudoers.rhel7.erb @@ -63,12 +63,7 @@ Defaults !visiblepw # this option is only effective for configurations where either # env_reset is disabled or HOME is present in the env_keep list. # -<% @defaults.sort.each do |k,v| -%> -Defaults <%= k -%> -<% if (!v.nil? and v != '')-%> -<%= "=#{v}" -%> -<% end %> -<% end -%> +<%= scope.call_function('sudo::defaults', @defaults) -%> Defaults always_set_home Defaults match_group_by_gid diff --git a/templates/sudoers.rhel8.erb b/templates/sudoers.rhel8.erb index 335df6c..15c58e6 100644 --- a/templates/sudoers.rhel8.erb +++ b/templates/sudoers.rhel8.erb @@ -63,12 +63,7 @@ Defaults !visiblepw # this option is only effective for configurations where either # env_reset is disabled or HOME is present in the env_keep list. # -<% @defaults.sort.each do |k,v| -%> -Defaults <%= k -%> -<% if (!v.nil? and v != '')-%> -<%= "=#{v}" -%> -<% end %> -<% end -%> +<%= scope.call_function('sudo::defaults', @defaults) -%> Defaults always_set_home Defaults match_group_by_gid diff --git a/templates/sudoers.smartos.erb b/templates/sudoers.smartos.erb index b64db6b..7455da1 100644 --- a/templates/sudoers.smartos.erb +++ b/templates/sudoers.smartos.erb @@ -55,12 +55,7 @@ # Defaults!/usr/bin/sudoreplay !log_output # Defaults!/usr/local/bin/sudoreplay !log_output # Defaults!/sbin/reboot !log_output -<% @defaults.sort.each do |k,v| -%> -Defaults <%= k -%> -<% if (!v.nil? and v != '')-%> -<%= "=#{v}" -%> -<% end %> -<% end -%> +<%= scope.call_function('sudo::defaults', @defaults) -%> <% if @use_sudoreplay %> Defaults log_output diff --git a/templates/sudoers.solaris.erb b/templates/sudoers.solaris.erb index 88afe93..4ed5770 100644 --- a/templates/sudoers.solaris.erb +++ b/templates/sudoers.solaris.erb @@ -63,12 +63,7 @@ # Defaults!/usr/bin/sudoreplay !log_output # Defaults!/usr/local/bin/sudoreplay !log_output # Defaults!/sbin/reboot !log_output -<% @defaults.sort.each do |k,v| -%> -Defaults <%= k -%> -<% if (!v.nil? and v != '')-%> -<%= "=#{v}" -%> -<% end %> -<% end -%> +<%= scope.call_function('sudo::defaults', @defaults) -%> <% if @use_sudoreplay %> Defaults log_output diff --git a/templates/sudoers.suse.erb b/templates/sudoers.suse.erb index 3661e2b..1c222f6 100644 --- a/templates/sudoers.suse.erb +++ b/templates/sudoers.suse.erb @@ -57,12 +57,7 @@ Defaults !insults # Defaults log_output # Defaults!/usr/bin/sudoreplay !log_output # Defaults!/sbin/reboot !log_output -<% @defaults.sort.each do |k,v| -%> -Defaults <%= k -%> -<% if (!v.nil? and v != '')-%> -<%= "=#{v}" -%> -<% end %> -<% end -%> +<%= scope.call_function('sudo::defaults', @defaults) -%> <% if @use_sudoreplay %> Defaults log_output diff --git a/templates/sudoers.ubuntu.erb b/templates/sudoers.ubuntu.erb index f014311..34e4158 100644 --- a/templates/sudoers.ubuntu.erb +++ b/templates/sudoers.ubuntu.erb @@ -7,12 +7,7 @@ # # See the man page for details on how to write a sudoers file. # -<% @defaults.sort.each do |k,v| -%> -Defaults <%= k -%> -<% if (!v.nil? and v != '')-%> -<%= "=#{v}" -%> -<% end %> -<% end -%> +<%= scope.call_function('sudo::defaults', @defaults) -%> Defaults secure_path="<%= @secure_path %>" <% if @use_sudoreplay %> diff --git a/types/defaults.pp b/types/defaults.pp new file mode 100644 index 0000000..cfb4445 --- /dev/null +++ b/types/defaults.pp @@ -0,0 +1,7 @@ +# sudo defaults +type Sudo::Defaults = Hash[String, Variant[Struct[{ + Optional[list] => String, + Optional[operator] => Sudo::Defaults_operator, + Optional[value] => Variant[String,Numeric], + }], Undef] + ] \ No newline at end of file diff --git a/types/defaults_operator.pp b/types/defaults_operator.pp new file mode 100644 index 0000000..1ca235c --- /dev/null +++ b/types/defaults_operator.pp @@ -0,0 +1 @@ +type Sudo::Defaults_operator = Enum['=','+=','-=','!'] \ No newline at end of file From 50fe032f1dd969727f8749a2f99e0f789afa832e Mon Sep 17 00:00:00 2001 From: Tomas Barton Date: Mon, 18 Jul 2022 13:14:35 +0200 Subject: [PATCH 05/14] Fix rubocop offenses --- lib/puppet/functions/sudo/defaults.rb | 31 +++++++++------------------ spec/functions/defaults_spec.rb | 10 +++++---- types/defaults.pp | 2 +- types/defaults_operator.pp | 2 +- 4 files changed, 18 insertions(+), 27 deletions(-) diff --git a/lib/puppet/functions/sudo/defaults.rb b/lib/puppet/functions/sudo/defaults.rb index 3af178d..35c4c9e 100644 --- a/lib/puppet/functions/sudo/defaults.rb +++ b/lib/puppet/functions/sudo/defaults.rb @@ -22,16 +22,12 @@ Puppet::Functions.create_function(:'sudo::defaults') do def defaults(*args) res = '' - unless args.nil? - args.each do |tuple| - if tuple.size == 2 - res.concat(defaults_entry(tuple[0], tuple[1])) - else - raise "Unsupported number of arguments #{args.size}: #{args.inspect}" - end - end - else - raise "Unsupported number of arguments #{args.size}: #{args.inspect}" + raise "Unsupported number of arguments #{args.size}: #{args.inspect}" if args.nil? + + args.each do |tuple| + raise "Unsupported number of arguments #{args.size}: #{args.inspect}" unless tuple.size == 2 + + res.concat(defaults_entry(tuple[0], tuple[1])) end res @@ -41,21 +37,14 @@ def defaults_entry(key, config) entry = "Defaults\t#{key}" unless config.nil? - if config.key? 'list' - entry.concat("#{config['list']}") - end + entry.concat((config['list']).to_s) if config.key? 'list' operator = '=' - if config.key? 'operator' - operator = config['operator'] - end + operator = config['operator'] if config.key? 'operator' - if config.key? 'value' - entry.concat("#{operator}#{config['value']}") - end + entry.concat("#{operator}#{config['value']}") if config.key? 'value' end - entry.concat("\n") end -end \ No newline at end of file +end diff --git a/spec/functions/defaults_spec.rb b/spec/functions/defaults_spec.rb index 02f4578..be21e8e 100644 --- a/spec/functions/defaults_spec.rb +++ b/spec/functions/defaults_spec.rb @@ -3,10 +3,12 @@ require 'spec_helper' describe 'sudo::defaults' do - it { is_expected.to run.with_params(['mailto', {'value' => 'root'}] - ).and_return("Defaults\tmailto=root\n") } - it { is_expected.to run.with_params(['env_reset', nil] - ).and_return("Defaults\tenv_reset\n") } + it { + is_expected.to run.with_params(['mailto', { 'value' => 'root' }]).and_return("Defaults\tmailto=root\n") + } + it { + is_expected.to run.with_params(['env_reset', nil]).and_return("Defaults\tenv_reset\n") + } it { is_expected.to run.with_params(nil).and_raise_error(StandardError) } end diff --git a/types/defaults.pp b/types/defaults.pp index cfb4445..5f20a2d 100644 --- a/types/defaults.pp +++ b/types/defaults.pp @@ -4,4 +4,4 @@ Optional[operator] => Sudo::Defaults_operator, Optional[value] => Variant[String,Numeric], }], Undef] - ] \ No newline at end of file + ] diff --git a/types/defaults_operator.pp b/types/defaults_operator.pp index 1ca235c..ffbe598 100644 --- a/types/defaults_operator.pp +++ b/types/defaults_operator.pp @@ -1 +1 @@ -type Sudo::Defaults_operator = Enum['=','+=','-=','!'] \ No newline at end of file +type Sudo::Defaults_operator = Enum['=','+=','-=','!'] From f1c6264e6db3bd00fc39c37e725ee4cfa6912b37 Mon Sep 17 00:00:00 2001 From: Tomas Barton Date: Mon, 18 Jul 2022 13:22:17 +0200 Subject: [PATCH 06/14] Include defaults as last line on all platforms --- templates/sudoers.aix.erb | 2 +- templates/sudoers.archlinux.erb | 2 +- templates/sudoers.darwin.erb | 2 +- templates/sudoers.debian.erb | 3 +-- templates/sudoers.freebsd.erb | 2 +- templates/sudoers.gentoo.erb | 2 +- templates/sudoers.olddebian.erb | 2 +- templates/sudoers.omnios.erb | 2 +- templates/sudoers.openbsd.erb | 2 +- templates/sudoers.rhel5.erb | 3 +-- templates/sudoers.rhel6.erb | 2 +- templates/sudoers.rhel7.erb | 2 +- templates/sudoers.rhel8.erb | 2 +- templates/sudoers.smartos.erb | 2 +- templates/sudoers.solaris.erb | 2 +- templates/sudoers.suse.erb | 2 +- templates/sudoers.ubuntu.erb | 2 +- 17 files changed, 17 insertions(+), 19 deletions(-) diff --git a/templates/sudoers.aix.erb b/templates/sudoers.aix.erb index 546aca2..7b399b3 100644 --- a/templates/sudoers.aix.erb +++ b/templates/sudoers.aix.erb @@ -63,7 +63,6 @@ # Defaults!/usr/bin/sudoreplay !log_output # Defaults!/usr/local/bin/sudoreplay !log_output # Defaults!/sbin/reboot !log_output -<%= scope.call_function('sudo::defaults', @defaults) -%> <% if @use_sudoreplay %> Defaults log_output @@ -106,3 +105,4 @@ root ALL=(ALL) ALL <% @extra_include_dirs.each do |include_dir| -%> #includedir <%= include_dir %> <% end if @extra_include_dirs -%> +<%= scope.call_function('sudo::defaults', @defaults) -%> diff --git a/templates/sudoers.archlinux.erb b/templates/sudoers.archlinux.erb index a9e3e19..c863049 100644 --- a/templates/sudoers.archlinux.erb +++ b/templates/sudoers.archlinux.erb @@ -63,7 +63,6 @@ # Defaults!/usr/bin/sudoreplay !log_output # Defaults!/usr/local/bin/sudoreplay !log_output # Defaults!/sbin/reboot !log_output -<%= scope.call_function('sudo::defaults', @defaults) -%> <% if @use_sudoreplay %> Defaults log_output @@ -105,3 +104,4 @@ root ALL=(ALL) ALL <% @extra_include_dirs.each do |include_dir| -%> #includedir <%= include_dir %> <% end if @extra_include_dirs -%> +<%= scope.call_function('sudo::defaults', @defaults) -%> diff --git a/templates/sudoers.darwin.erb b/templates/sudoers.darwin.erb index 9bcb956..bd06b23 100644 --- a/templates/sudoers.darwin.erb +++ b/templates/sudoers.darwin.erb @@ -16,7 +16,6 @@ # Cmnd alias specification # Defaults specification -<%= scope.call_function('sudo::defaults', @defaults) -%> Defaults env_keep += "BLOCKSIZE" Defaults env_keep += "COLORFGBG COLORTERM" Defaults env_keep += "__CF_USER_TEXT_ENCODING" @@ -62,3 +61,4 @@ root ALL=(ALL) ALL <% @extra_include_dirs.each do |include_dir| -%> #includedir <%= include_dir %> <% end if @extra_include_dirs -%> +<%= scope.call_function('sudo::defaults', @defaults) -%> diff --git a/templates/sudoers.debian.erb b/templates/sudoers.debian.erb index 56a8a72..39a76f2 100644 --- a/templates/sudoers.debian.erb +++ b/templates/sudoers.debian.erb @@ -1,6 +1,5 @@ # file managed by puppet (unless config_file_replace=false) # -<%= scope.call_function('sudo::defaults', @defaults) -%> Defaults secure_path="<%= @secure_path %>" <% if @use_sudoreplay %> @@ -27,4 +26,4 @@ root ALL=(ALL:ALL) ALL <% @extra_include_dirs.each do |include_dir| -%> #includedir <%= include_dir %> <% end if @extra_include_dirs -%> - +<%= scope.call_function('sudo::defaults', @defaults) -%> diff --git a/templates/sudoers.freebsd.erb b/templates/sudoers.freebsd.erb index fd0ad30..115fd62 100644 --- a/templates/sudoers.freebsd.erb +++ b/templates/sudoers.freebsd.erb @@ -78,7 +78,6 @@ # Defaults!/usr/bin/sudoreplay !log_output # Defaults!/usr/local/bin/sudoreplay !log_output # Defaults!REBOOT !log_output -<%= scope.call_function('sudo::defaults', @defaults) -%> <% if @use_sudoreplay %> Defaults log_output @@ -121,3 +120,4 @@ root ALL=(ALL) ALL <% @extra_include_dirs.each do |include_dir| -%> #includedir <%= include_dir %> <% end if @extra_include_dirs -%> +<%= scope.call_function('sudo::defaults', @defaults) -%> diff --git a/templates/sudoers.gentoo.erb b/templates/sudoers.gentoo.erb index c8e0bcd..c79baa5 100644 --- a/templates/sudoers.gentoo.erb +++ b/templates/sudoers.gentoo.erb @@ -64,7 +64,6 @@ # Defaults!/usr/bin/sudoreplay !log_output # Defaults!/usr/local/bin/sudoreplay !log_output # Defaults!REBOOT !log_output -<%= scope.call_function('sudo::defaults', @defaults) -%> <% if @use_sudoreplay %> Defaults log_output @@ -107,3 +106,4 @@ root ALL=(ALL) ALL <% @extra_include_dirs.each do |include_dir| -%> #includedir <%= include_dir %> <% end if @extra_include_dirs -%> +<%= scope.call_function('sudo::defaults', @defaults) -%> diff --git a/templates/sudoers.olddebian.erb b/templates/sudoers.olddebian.erb index 8c95161..26cb02b 100644 --- a/templates/sudoers.olddebian.erb +++ b/templates/sudoers.olddebian.erb @@ -63,7 +63,6 @@ Defaults env_keep += "XAPPLRESDIR XFILESEARCHPATH XUSERFILESEARCHPATH" # Defaults!/usr/bin/sudoreplay !log_output # Defaults!/usr/local/bin/sudoreplay !log_output # Defaults!/sbin/reboot !log_output -<%= scope.call_function('sudo::defaults', @defaults) -%> <% if @use_sudoreplay %> Defaults log_output @@ -107,3 +106,4 @@ root ALL=(ALL) ALL <% @extra_include_dirs.each do |include_dir| -%> #includedir <%= include_dir %> <% end if @extra_include_dirs -%> +<%= scope.call_function('sudo::defaults', @defaults) -%> diff --git a/templates/sudoers.omnios.erb b/templates/sudoers.omnios.erb index 2663dcc..9077716 100644 --- a/templates/sudoers.omnios.erb +++ b/templates/sudoers.omnios.erb @@ -63,7 +63,6 @@ # Defaults!/usr/bin/sudoreplay !log_output # Defaults!/usr/local/bin/sudoreplay !log_output # Defaults!/sbin/reboot !log_output -<%= scope.call_function('sudo::defaults', @defaults) -%> <% if @use_sudoreplay %> Defaults log_output @@ -106,3 +105,4 @@ root ALL=(ALL) ALL <% @extra_include_dirs.each do |include_dir| -%> #includedir <%= include_dir %> <% end if @extra_include_dirs -%> +<%= scope.call_function('sudo::defaults', @defaults) -%> diff --git a/templates/sudoers.openbsd.erb b/templates/sudoers.openbsd.erb index ed4b2f1..5294d84 100644 --- a/templates/sudoers.openbsd.erb +++ b/templates/sudoers.openbsd.erb @@ -32,7 +32,6 @@ Defaults:%wsrc env_keep +="SUBPACKAGE WRKOBJDIR SUDO_PORT_V1" # Uncomment to preserve the environment for users in group wheel #Defaults:%wheel !env_reset -<%= scope.call_function('sudo::defaults', @defaults) -%> <% if @use_sudoreplay %> Defaults log_output @@ -68,3 +67,4 @@ root ALL=(ALL) SETENV: ALL <% @extra_include_dirs.each do |include_dir| -%> #includedir <%= include_dir %> <% end if @extra_include_dirs -%> +<%= scope.call_function('sudo::defaults', @defaults) -%> diff --git a/templates/sudoers.rhel5.erb b/templates/sudoers.rhel5.erb index 2a43303..d7da2c6 100644 --- a/templates/sudoers.rhel5.erb +++ b/templates/sudoers.rhel5.erb @@ -56,8 +56,6 @@ # Defaults !visiblepw -<%= scope.call_function('sudo::defaults', @defaults) -%> - Defaults env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR \ LS_COLORS MAIL PS1 PS2 QTDIR USERNAME \ LANG LC_ADDRESS LC_CTYPE LC_COLLATE LC_IDENTIFICATION \ @@ -99,3 +97,4 @@ root ALL=(ALL) ALL <% @extra_include_dirs.each do |include_dir| -%> #includedir <%= include_dir %> <% end if @extra_include_dirs -%> +<%= scope.call_function('sudo::defaults', @defaults) -%> diff --git a/templates/sudoers.rhel6.erb b/templates/sudoers.rhel6.erb index 2ea642d..6b31d04 100644 --- a/templates/sudoers.rhel6.erb +++ b/templates/sudoers.rhel6.erb @@ -60,7 +60,6 @@ Defaults !visiblepw # Preserving HOME has security implications since many programs # use it when searching for configuration files. # -<%= scope.call_function('sudo::defaults', @defaults) -%> Defaults always_set_home @@ -124,3 +123,4 @@ root ALL=(ALL) ALL <% @extra_include_dirs.each do |include_dir| -%> #includedir <%= include_dir %> <% end if @extra_include_dirs -%> +<%= scope.call_function('sudo::defaults', @defaults) -%> diff --git a/templates/sudoers.rhel7.erb b/templates/sudoers.rhel7.erb index 2bbe8da..e5042ec 100644 --- a/templates/sudoers.rhel7.erb +++ b/templates/sudoers.rhel7.erb @@ -63,7 +63,6 @@ Defaults !visiblepw # this option is only effective for configurations where either # env_reset is disabled or HOME is present in the env_keep list. # -<%= scope.call_function('sudo::defaults', @defaults) -%> Defaults always_set_home Defaults match_group_by_gid @@ -135,3 +134,4 @@ root ALL=(ALL) ALL <% @extra_include_dirs.each do |include_dir| -%> #includedir <%= include_dir %> <% end if @extra_include_dirs -%> +<%= scope.call_function('sudo::defaults', @defaults) -%> diff --git a/templates/sudoers.rhel8.erb b/templates/sudoers.rhel8.erb index 15c58e6..266d936 100644 --- a/templates/sudoers.rhel8.erb +++ b/templates/sudoers.rhel8.erb @@ -63,7 +63,6 @@ Defaults !visiblepw # this option is only effective for configurations where either # env_reset is disabled or HOME is present in the env_keep list. # -<%= scope.call_function('sudo::defaults', @defaults) -%> Defaults always_set_home Defaults match_group_by_gid @@ -135,3 +134,4 @@ root ALL=(ALL) ALL <% @extra_include_dirs.each do |include_dir| -%> #includedir <%= include_dir %> <% end if @extra_include_dirs -%> +<%= scope.call_function('sudo::defaults', @defaults) -%> diff --git a/templates/sudoers.smartos.erb b/templates/sudoers.smartos.erb index 7455da1..5b96d18 100644 --- a/templates/sudoers.smartos.erb +++ b/templates/sudoers.smartos.erb @@ -55,7 +55,6 @@ # Defaults!/usr/bin/sudoreplay !log_output # Defaults!/usr/local/bin/sudoreplay !log_output # Defaults!/sbin/reboot !log_output -<%= scope.call_function('sudo::defaults', @defaults) -%> <% if @use_sudoreplay %> Defaults log_output @@ -99,3 +98,4 @@ root ALL=(ALL) ALL <% @extra_include_dirs.each do |include_dir| -%> #includedir <%= include_dir %> <% end if @extra_include_dirs -%> +<%= scope.call_function('sudo::defaults', @defaults) -%> diff --git a/templates/sudoers.solaris.erb b/templates/sudoers.solaris.erb index 4ed5770..1cfd373 100644 --- a/templates/sudoers.solaris.erb +++ b/templates/sudoers.solaris.erb @@ -63,7 +63,6 @@ # Defaults!/usr/bin/sudoreplay !log_output # Defaults!/usr/local/bin/sudoreplay !log_output # Defaults!/sbin/reboot !log_output -<%= scope.call_function('sudo::defaults', @defaults) -%> <% if @use_sudoreplay %> Defaults log_output @@ -105,3 +104,4 @@ Defaults!<%= command %> !log_output <% @extra_include_dirs.each do |include_dir| -%> #includedir <%= include_dir %> <% end if @extra_include_dirs -%> +<%= scope.call_function('sudo::defaults', @defaults) -%> diff --git a/templates/sudoers.suse.erb b/templates/sudoers.suse.erb index 1c222f6..7a8360c 100644 --- a/templates/sudoers.suse.erb +++ b/templates/sudoers.suse.erb @@ -57,7 +57,6 @@ Defaults !insults # Defaults log_output # Defaults!/usr/bin/sudoreplay !log_output # Defaults!/sbin/reboot !log_output -<%= scope.call_function('sudo::defaults', @defaults) -%> <% if @use_sudoreplay %> Defaults log_output @@ -99,3 +98,4 @@ root ALL=(ALL) ALL <% @extra_include_dirs.each do |include_dir| -%> #includedir <%= include_dir %> <% end if @extra_include_dirs -%> +<%= scope.call_function('sudo::defaults', @defaults) -%> diff --git a/templates/sudoers.ubuntu.erb b/templates/sudoers.ubuntu.erb index 34e4158..29a88eb 100644 --- a/templates/sudoers.ubuntu.erb +++ b/templates/sudoers.ubuntu.erb @@ -7,7 +7,6 @@ # # See the man page for details on how to write a sudoers file. # -<%= scope.call_function('sudo::defaults', @defaults) -%> Defaults secure_path="<%= @secure_path %>" <% if @use_sudoreplay %> @@ -41,3 +40,4 @@ root ALL=(ALL:ALL) ALL <% @extra_include_dirs.each do |include_dir| -%> #includedir <%= include_dir %> <% end if @extra_include_dirs -%> +<%= scope.call_function('sudo::defaults', @defaults) -%> From 0fe75f19a35ad56734b4f1d7ba3b3ca04225a521 Mon Sep 17 00:00:00 2001 From: Tomas Barton Date: Mon, 18 Jul 2022 13:31:38 +0200 Subject: [PATCH 07/14] Quote strings --- lib/puppet/functions/sudo/defaults.rb | 6 +++++- spec/classes/sudo_spec.rb | 16 +++++++++++++++- spec/functions/defaults_spec.rb | 2 +- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/lib/puppet/functions/sudo/defaults.rb b/lib/puppet/functions/sudo/defaults.rb index 35c4c9e..4f2b9f9 100644 --- a/lib/puppet/functions/sudo/defaults.rb +++ b/lib/puppet/functions/sudo/defaults.rb @@ -42,7 +42,11 @@ def defaults_entry(key, config) operator = '=' operator = config['operator'] if config.key? 'operator' - entry.concat("#{operator}#{config['value']}") if config.key? 'value' + if config.key? 'value' + val = config['value'].is_a?(String) ? "\"#{config['value']}\"" : config['value'] + + entry.concat("#{operator}#{val}") + end end entry.concat("\n") diff --git a/spec/classes/sudo_spec.rb b/spec/classes/sudo_spec.rb index 8de7526..4344009 100644 --- a/spec/classes/sudo_spec.rb +++ b/spec/classes/sudo_spec.rb @@ -93,7 +93,21 @@ } end - it { is_expected.to contain_file('/etc/sudoers').with_content(%r{^Defaults\s+env_keep\+=SOME_VAR$}) } + it { is_expected.to contain_file('/etc/sudoers').with_content(%r{^Defaults\s+env_keep\+="SOME_VAR"$}) } + end + + context 'Escape strings' do + let :params do + { + defaults: { + badpass_message: { + value: 'Password is wrong, please try again', + } + } + } + end + + it { is_expected.to contain_file('/etc/sudoers').with_content(%r{^Defaults\s+badpass_message="Password is wrong, please try again"$}) } end end end diff --git a/spec/functions/defaults_spec.rb b/spec/functions/defaults_spec.rb index be21e8e..f8b9de5 100644 --- a/spec/functions/defaults_spec.rb +++ b/spec/functions/defaults_spec.rb @@ -4,7 +4,7 @@ describe 'sudo::defaults' do it { - is_expected.to run.with_params(['mailto', { 'value' => 'root' }]).and_return("Defaults\tmailto=root\n") + is_expected.to run.with_params(['mailto', { 'value' => 'root' }]).and_return("Defaults\tmailto=\"root\"\n") } it { is_expected.to run.with_params(['env_reset', nil]).and_return("Defaults\tenv_reset\n") From c9fb1b47077fbc7dff7b9560fc45a210a96837f4 Mon Sep 17 00:00:00 2001 From: Tomas Barton Date: Tue, 19 Jul 2022 10:53:34 +0200 Subject: [PATCH 08/14] Try to fix offenses --- lib/puppet/functions/sudo/defaults.rb | 2 ++ spec/functions/defaults_spec.rb | 1 + 2 files changed, 3 insertions(+) diff --git a/lib/puppet/functions/sudo/defaults.rb b/lib/puppet/functions/sudo/defaults.rb index 4f2b9f9..511592e 100644 --- a/lib/puppet/functions/sudo/defaults.rb +++ b/lib/puppet/functions/sudo/defaults.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: false + # Formats sudoers defaults config see https://linux.die.net/man/5/sudoers # # Default_Type ::= 'Defaults' | diff --git a/spec/functions/defaults_spec.rb b/spec/functions/defaults_spec.rb index f8b9de5..5254f76 100644 --- a/spec/functions/defaults_spec.rb +++ b/spec/functions/defaults_spec.rb @@ -6,6 +6,7 @@ it { is_expected.to run.with_params(['mailto', { 'value' => 'root' }]).and_return("Defaults\tmailto=\"root\"\n") } + it { is_expected.to run.with_params(['env_reset', nil]).and_return("Defaults\tenv_reset\n") } From 11b7c62e16a7283740f20acf5b09b7781a593e4d Mon Sep 17 00:00:00 2001 From: Steffen Zieger Date: Tue, 19 Jul 2022 18:52:01 +0200 Subject: [PATCH 09/14] Fix newly introduced test The test was referencing a defaults line which won't be there with the changes here. --- spec/classes/sudo_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/classes/sudo_spec.rb b/spec/classes/sudo_spec.rb index 35bdeaf..ee2feb1 100644 --- a/spec/classes/sudo_spec.rb +++ b/spec/classes/sudo_spec.rb @@ -66,7 +66,7 @@ } end - it { is_expected.to contain_file('/etc/sudoers').with_content(%r{.*Defaults\s+env_reset.*}) } + it { is_expected.to contain_file('/etc/sudoers').with_content(%r{.*#\s+Host\s+alias\s+specification.*}) } end unless os =~ %r{^(debian|ubuntu)} From 9fb6ccb07c6374dbf579c302fce4b329d98791e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Laudrel?= Date: Thu, 1 Feb 2024 13:11:03 +0100 Subject: [PATCH 10/14] add package_manage param --- REFERENCE.md | 9 +++++++++ manifests/init.pp | 6 +++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/REFERENCE.md b/REFERENCE.md index aee139d..20f2877 100644 --- a/REFERENCE.md +++ b/REFERENCE.md @@ -43,6 +43,7 @@ The following parameters are available in the `sudo` class: * [`enable`](#-sudo--enable) * [`package`](#-sudo--package) +* [`package_manage`](#-sudo--package_manage) * [`package_ldap`](#-sudo--package_ldap) * [`package_ensure`](#-sudo--package_ensure) * [`package_source`](#-sudo--package_source) @@ -89,6 +90,14 @@ what you're doing. Default value: `$sudo::params::package` +##### `package_manage` + +Data type: `Boolean` + +Whether or not to manage the sudo package. + +Default value: `true` + ##### `package_ldap` Data type: `Optional[String[1]]` diff --git a/manifests/init.pp b/manifests/init.pp index 2177a45..396b7c6 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -9,6 +9,9 @@ # Only set this, if your platform is not supported or you know, # what you're doing. # +# @param package_manage +# Whether or not to manage the sudo package. +# # @param package_ldap # Name of the package with ldap support, if ldap_enable is set. # @@ -117,6 +120,7 @@ class sudo ( Boolean $enable = true, Optional[String[1]] $package = $sudo::params::package, + Boolean $package_manage = true, Optional[String[1]] $package_ldap = $sudo::params::package_ldap, String[1] $package_ensure = $sudo::params::package_ensure, Optional[String[1]] $package_source = $sudo::params::package_source, @@ -169,7 +173,7 @@ } default: { fail('no $ldap_enable is set') } } - if $package_real { + if $package_real and $package_manage { class { 'sudo::package': package => $package_real, package_ensure => $package_ensure, From c03db9f18d4573d3278e94ed717c50834c07be09 Mon Sep 17 00:00:00 2001 From: Patrick Emery Date: Fri, 29 Mar 2024 23:16:11 -0400 Subject: [PATCH 11/14] Add support for RedHat 9 --- manifests/params.pp | 7 +- templates/sudoers.rhel9.erb | 137 ++++++++++++++++++++++++++++++++++++ 2 files changed, 143 insertions(+), 1 deletion(-) create mode 100644 templates/sudoers.rhel9.erb diff --git a/manifests/params.pp b/manifests/params.pp index 3565a24..e83cd14 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -75,8 +75,13 @@ $secure_path = '/sbin:/bin:/usr/sbin:/usr/bin:/opt/puppetlabs/bin' $wheel_config = 'password' } + /^9/: { + $content_template = "${content_base}sudoers.rhel9.erb" + $secure_path = '/sbin:/bin:/usr/sbin:/usr/bin:/opt/puppetlabs/bin' + $wheel_config = 'password' + } default: { - $content_template = "${content_base}sudoers.rhel8.erb" + $content_template = "${content_base}sudoers.rhel9.erb" $secure_path = '/sbin:/bin:/usr/sbin:/usr/bin:/opt/puppetlabs/bin' $wheel_config = 'password' } diff --git a/templates/sudoers.rhel9.erb b/templates/sudoers.rhel9.erb new file mode 100644 index 0000000..5c477e7 --- /dev/null +++ b/templates/sudoers.rhel9.erb @@ -0,0 +1,137 @@ +# file managed by puppet (unless config_file_replace=false) +# +## Sudoers allows particular users to run various commands as +## the root user, without needing the root password. +## +## Examples are provided at the bottom of the file for collections +## of related commands, which can then be delegated out to particular +## users or groups. +## +## This file must be edited with the 'visudo' command. + +## Host Aliases +## Groups of machines. You may prefer to use hostnames (perhaps using +## wildcards for entire domains) or IP addresses instead. +# Host_Alias FILESERVERS = fs1, fs2 +# Host_Alias MAILSERVERS = smtp, smtp2 + +## User Aliases +## These aren't often necessary, as you can use regular groups +## (ie, from files, LDAP, NIS, etc) in this file - just use %groupname +## rather than USERALIAS +# User_Alias ADMINS = jsmith, mikem + + +## Command Aliases +## These are groups of related commands... + +## Networking +# Cmnd_Alias NETWORKING = /sbin/route, /sbin/ifconfig, /bin/ping, /sbin/dhclient, /usr/bin/net, /sbin/iptables, /usr/bin/rfcomm, /usr/bin/wvdial, /sbin/iwconfig, /sbin/mii-tool + +## Installation and management of software +# Cmnd_Alias SOFTWARE = /bin/rpm, /usr/bin/up2date, /usr/bin/yum + +## Services +# Cmnd_Alias SERVICES = /sbin/service, /sbin/chkconfig, /usr/bin/systemctl start, /usr/bin/systemctl stop, /usr/bin/systemctl reload, /usr/bin/systemctl restart, /usr/bin/systemctl status, /usr/bin/systemctl enable, /usr/bin/systemctl disable + +## Updating the locate database +# Cmnd_Alias LOCATE = /usr/bin/updatedb + +## Storage +# Cmnd_Alias STORAGE = /sbin/fdisk, /sbin/sfdisk, /sbin/parted, /sbin/partprobe, /bin/mount, /bin/umount + +## Delegating permissions +# Cmnd_Alias DELEGATING = /usr/sbin/visudo, /bin/chown, /bin/chmod, /bin/chgrp + +## Processes +# Cmnd_Alias PROCESSES = /bin/nice, /bin/kill, /usr/bin/kill, /usr/bin/killall + +## Drivers +# Cmnd_Alias DRIVERS = /sbin/modprobe + +# Defaults specification + +# +# Refuse to run if unable to disable echo on the tty. +# +Defaults !visiblepw + +# +# Preserving HOME has security implications since many programs +# use it when searching for configuration files. Note that HOME +# is already set when the the env_reset option is enabled, so +# this option is only effective for configurations where either +# env_reset is disabled or HOME is present in the env_keep list. +# +Defaults always_set_home +Defaults match_group_by_gid + +# Prior to version 1.8.15, groups listed in sudoers that were not +# found in the system group database were passed to the group +# plugin, if any. Starting with 1.8.15, only groups of the form +# %:group are resolved via the group plugin by default. +# We enable always_query_group_plugin to restore old behavior. +# Disable this option for new behavior. +Defaults always_query_group_plugin + +Defaults env_reset +Defaults env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS" +Defaults env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE" +Defaults env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES" +Defaults env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE" +Defaults env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY" + +<% if @use_sudoreplay %> +Defaults log_output +Defaults!/usr/bin/sudoreplay !log_output +<% if @sudoreplay_discard %> +<% @sudoreplay_discard.each do |command| -%> +Defaults!<%= command %> !log_output +<% end -%> +<% end -%> +<% end -%> + +# +# Adding HOME to env_keep may enable a user to run unrestricted +# commands via sudo. +# +# Defaults env_keep += "HOME" + +Defaults secure_path = <%= @secure_path %> + +## Next comes the main part: which users can run what software on +## which machines (the sudoers file can be shared between multiple +## systems). +## Syntax: +## +## user MACHINE=COMMANDS +## +## The COMMANDS section may have other options added to it. +## +## Allow root to run any commands anywhere +root ALL=(ALL) ALL + +## Allows members of the 'sys' group to run networking, software, +## service management apps and more. +# %sys ALL = NETWORKING, SOFTWARE, SERVICES, STORAGE, DELEGATING, PROCESSES, LOCATE, DRIVERS + +## Allows people in group wheel to run all commands +<%- if @wheel_config != 'password' %># <% end -%> +%wheel ALL=(ALL) ALL + +## Same thing without a password +<%- if @wheel_config != 'nopassword' %># <% end -%> +%wheel ALL=(ALL) NOPASSWD: ALL + +## Allows members of the users group to mount and unmount the +## cdrom as root +# %users ALL=/sbin/mount /mnt/cdrom, /sbin/umount /mnt/cdrom + +## Allows members of the users group to shutdown this system +# %users localhost=/sbin/shutdown -h now + +## Read drop-in files from /etc/sudoers.d (the # here does not mean a comment) +#includedir <%= @config_dir %> +<% @extra_include_dirs.each do |include_dir| -%> +#includedir <%= include_dir %> +<% end if @extra_include_dirs -%> From 4720ba4ae0315e32c0f460a7ba6084c27b24ccb8 Mon Sep 17 00:00:00 2001 From: Steffen Zieger Date: Mon, 13 May 2024 14:50:35 +0200 Subject: [PATCH 12/14] remove purge_ignore example from README, as it is not working as documented --- README.md | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/README.md b/README.md index c9a0b04..06cdcc6 100644 --- a/README.md +++ b/README.md @@ -39,31 +39,6 @@ If this is not what you're expecting, set `purge` and/or `config_file_replace` t } ``` -#### Selective Purge of sudoers.d Directory -A combination of `prefix`, `suffix` and `purge_ignore` can be used to purge only files that puppet previously created. -If `suffix` is specified all puppet created sudoers.d entries will have this suffix apprended to -the thier file name. If `prefix` is specified all puppet created sudoers.d entries will have this prefix -prepended. A ruby glob can be used as `ignore` to ignore all files that do not have -this suffix. - -```puppet - class{'sudo': - suffix => '_puppet', - purge_ignore => '*[!_puppet]', - } -``` - -or - -```puppet - class{'sudo': - prefix => 'puppet_', - purge_ignore => '[!puppet_]*', - } -``` - -Due to limitations in ruby glob the prefix and ignore is recommended. - #### Leave current sudo config as it is ```puppet class { 'sudo': From 32d3d6bb717381d88aeff77e410efe987a1c9729 Mon Sep 17 00:00:00 2001 From: Steffen Zieger Date: Mon, 13 May 2024 17:01:33 +0200 Subject: [PATCH 13/14] use sudo::defaults in rhel9 template, fix tests --- REFERENCE.md | 100 ++++++++++++++++++++++++++ lib/puppet/functions/sudo/defaults.rb | 5 ++ manifests/init.pp | 2 +- spec/classes/sudo_spec.rb | 16 +++-- templates/sudoers.rhel9.erb | 2 +- types/defaults_operator.pp | 1 + 6 files changed, 117 insertions(+), 9 deletions(-) diff --git a/REFERENCE.md b/REFERENCE.md index 20f2877..2353e9f 100644 --- a/REFERENCE.md +++ b/REFERENCE.md @@ -23,6 +23,15 @@ rpm. so we add a dependencies to the ldap module. * [`sudo::conf`](#sudo--conf): Manages sudo configuration snippets +### Functions + +* [`sudo::defaults`](#sudo--defaults): Formats sudoers defaults config see https://linux.die.net/man/5/sudoers Default_Type ::= 'Defaults' | 'Defaults' '@ + +### Data types + +* [`Sudo::Defaults`](#Sudo--Defaults): sudo defaults +* [`Sudo::Defaults_operator`](#Sudo--Defaults_operator): custom datatype that validates sudo defaults operators + ## Classes ### `sudo` @@ -71,6 +80,7 @@ The following parameters are available in the `sudo` class: * [`wheel_config`](#-sudo--wheel_config) * [`sudoreplay_discard`](#-sudo--sudoreplay_discard) * [`configs`](#-sudo--configs) +* [`defaults`](#-sudo--defaults) ##### `enable` @@ -335,6 +345,14 @@ A hash of sudo::conf's Default value: `{}` +##### `defaults` + +Data type: `Sudo::Defaults` + + + +Default value: `$sudo::params::defaults` + ### `sudo::allow` This class allows you to take complete advantage of automatic parameter @@ -506,3 +524,85 @@ Path to use for executing the sudo syntax check Default value: `'/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'` +## Functions + +### `sudo::defaults` + +Type: Ruby 4.x API + +Formats sudoers defaults config see https://linux.die.net/man/5/sudoers + + Default_Type ::= 'Defaults' | + 'Defaults' '@' Host_List | + 'Defaults' ':' User_List | + 'Defaults' '!' Cmnd_List | + 'Defaults' '>' Runas_List + + Default_Entry ::= Default_Type Parameter_List + + Parameter_List ::= Parameter | + Parameter ',' Parameter_List + + Parameter ::= Parameter '=' Value | + Parameter '+=' Value | + Parameter '-=' Value | + '!'* Parameter + +The function is passed an Array of Tuples +e.g. [["env_reset", nil]] + [["mailto", {"value" => root}]] + +#### `sudo::defaults(Any *$args)` + +Formats sudoers defaults config see https://linux.die.net/man/5/sudoers + + Default_Type ::= 'Defaults' | + 'Defaults' '@' Host_List | + 'Defaults' ':' User_List | + 'Defaults' '!' Cmnd_List | + 'Defaults' '>' Runas_List + + Default_Entry ::= Default_Type Parameter_List + + Parameter_List ::= Parameter | + Parameter ',' Parameter_List + + Parameter ::= Parameter '=' Value | + Parameter '+=' Value | + Parameter '-=' Value | + '!'* Parameter + +The function is passed an Array of Tuples +e.g. [["env_reset", nil]] + [["mailto", {"value" => root}]] + +Returns: `String` + +##### `*args` + +Data type: `Any` + + + +## Data types + +### `Sudo::Defaults` + +sudo defaults + +Alias of + +```puppet +Hash[String, Variant[Struct[{ + Optional[list] => String, + Optional[operator] => Sudo::Defaults_operator, + Optional[value] => Variant[String,Numeric], + }], Undef]] +``` + +### `Sudo::Defaults_operator` + +custom datatype that validates sudo defaults operators + +Alias of `Enum['=', '+=', '-=', '!']` + diff --git a/lib/puppet/functions/sudo/defaults.rb b/lib/puppet/functions/sudo/defaults.rb index 511592e..1fd66d1 100644 --- a/lib/puppet/functions/sudo/defaults.rb +++ b/lib/puppet/functions/sudo/defaults.rb @@ -22,6 +22,11 @@ # e.g. [["env_reset", nil]] # [["mailto", {"value" => root}]] Puppet::Functions.create_function(:'sudo::defaults') do + dispatch :defaults do + repeated_param 'Any', :args + return_type 'String' + end + def defaults(*args) res = '' raise "Unsupported number of arguments #{args.size}: #{args.inspect}" if args.nil? diff --git a/manifests/init.pp b/manifests/init.pp index 224b72f..ec7dfd3 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -148,7 +148,7 @@ Enum['absent','password','nopassword'] $wheel_config = $sudo::params::wheel_config, Optional[Array[String[1]]] $sudoreplay_discard = undef, Hash $configs = {}, - Sudo::Defaults $defaults = $sudo::params::defaults, + Sudo::Defaults $defaults = $sudo::params::defaults, ) inherits sudo::params { case $enable { true: { diff --git a/spec/classes/sudo_spec.rb b/spec/classes/sudo_spec.rb index ee2feb1..a8d527d 100644 --- a/spec/classes/sudo_spec.rb +++ b/spec/classes/sudo_spec.rb @@ -39,14 +39,16 @@ it { is_expected.to compile.and_raise_error(%r{'content' \(deprecated\) and 'content_string' are mutually exclusive}) } end - context 'with deprecated content set' do - let :params do - { - content: 'sudo/sudoers.ubuntu.erb' - } - end + unless os =~ %r{^(gentoo|archlinux-rolling)} + context 'with deprecated content set' do + let :params do + { + content: 'sudo/sudoers.ubuntu.erb' + } + end - it { is_expected.to contain_file('/etc/sudoers').with_content(%r{.*Defaults\s+env_reset.*}) } + it { is_expected.to contain_file('/etc/sudoers').with_content(%r{.*Defaults\s+env_reset.*}) } + end end context 'with content_string set' do diff --git a/templates/sudoers.rhel9.erb b/templates/sudoers.rhel9.erb index 5c477e7..266d936 100644 --- a/templates/sudoers.rhel9.erb +++ b/templates/sudoers.rhel9.erb @@ -74,7 +74,6 @@ Defaults match_group_by_gid # Disable this option for new behavior. Defaults always_query_group_plugin -Defaults env_reset Defaults env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS" Defaults env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE" Defaults env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES" @@ -135,3 +134,4 @@ root ALL=(ALL) ALL <% @extra_include_dirs.each do |include_dir| -%> #includedir <%= include_dir %> <% end if @extra_include_dirs -%> +<%= scope.call_function('sudo::defaults', @defaults) -%> diff --git a/types/defaults_operator.pp b/types/defaults_operator.pp index ffbe598..452efa6 100644 --- a/types/defaults_operator.pp +++ b/types/defaults_operator.pp @@ -1 +1,2 @@ +# @summary custom datatype that validates sudo defaults operators type Sudo::Defaults_operator = Enum['=','+=','-=','!'] From 82c3e27d5e58500a1ab3a38194395b07919053d4 Mon Sep 17 00:00:00 2001 From: Steffen Zieger Date: Mon, 13 May 2024 19:24:40 +0200 Subject: [PATCH 14/14] Remove parameters from README.md, mention REFERENCE.md, fixes #197 --- README.md | 26 ++------------------------ 1 file changed, 2 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index f5493a0..2547e59 100644 --- a/README.md +++ b/README.md @@ -205,30 +205,8 @@ sudo::conf { "foreman-proxy": ## sudo class parameters -| Parameter | Type | Default | Description | -| :-------------- | :------ |:----------- | :---------- | -| enable | boolean | true | Set this to remove or purge all sudoers configs | -| package | string | OS specific | Set package name _(for unsupported platforms)_ | -| package_ensure | string | present | latest, absent, or a specific package version | -| package_source | string | OS specific | Set package source _(for unsupported platforms)_ | -| purge | boolean | true | Purge unmanaged files from config_dir | -| purge_ignore | string | undef | Files excluded from purging in config_dir | -| config_file | string | OS specific | Set config_file _(for unsupported platforms)_ | -| config_file_replace | boolean | true | Replace config file with module config file | -| includedirsudoers | boolean | OS specific | Add #includedir /etc/sudoers.d with augeas | -| config_dir | string | OS specific | Set config_dir _(for unsupported platforms)_ | -| content | string | OS specific | Alternate content file location | -| ldap_enable | boolean | false | Add support to LDAP | -| configs | hash | {} | A hash of sudo::conf's | +See REFERENCE.md ## sudo::conf class / sudo::configs hash parameters -| Parameter | Type | Default | Description | -| :-------------- | :----- |:----------- | :---------- | -| ensure | string | present | present or absent | -| priority | number | 10 | file name prefix | -| content | string | undef | content of configuration snippet | -| source | string | undef | source of configuration snippet | -| template | string | undef | template of configuration snippet | -| sudo_config_dir | string | OS Specific | configuration snippet directory _(for unsupported platforms)_ | -| sudo_file_name | string | undef | custom file name for sudo file in sudoers directory | +See REFERENCE.md