diff --git a/linux_os/guide/system/accounts/accounts-restrictions/root_logins/use_pam_wheel_for_su/ansible/shared.yml b/linux_os/guide/system/accounts/accounts-restrictions/root_logins/use_pam_wheel_for_su/ansible/shared.yml
deleted file mode 100644
index b6f60d4bc946..000000000000
--- a/linux_os/guide/system/accounts/accounts-restrictions/root_logins/use_pam_wheel_for_su/ansible/shared.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-# platform = multi_platform_rhel,multi_platform_fedora,multi_platform_ol,multi_platform_rhv,multi_platform_sle,multi_platform_almalinux
-# reboot = false
-# strategy = restrict
-# complexity = low
-# disruption = low
-
-- name: "Restrict usage of su command only to members of wheel group"
- ansible.builtin.replace:
- path: "/etc/pam.d/su"
- regexp: '^[\s]*#[\s]*auth[\s]+required[\s]+pam_wheel\.so[\s]+use_uid$'
- replace: "auth required pam_wheel.so use_uid"
diff --git a/linux_os/guide/system/accounts/accounts-restrictions/root_logins/use_pam_wheel_for_su/bash/shared.sh b/linux_os/guide/system/accounts/accounts-restrictions/root_logins/use_pam_wheel_for_su/bash/shared.sh
deleted file mode 100644
index 5bd381d1210f..000000000000
--- a/linux_os/guide/system/accounts/accounts-restrictions/root_logins/use_pam_wheel_for_su/bash/shared.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-# platform = multi_platform_rhel,multi_platform_fedora,multi_platform_ol,multi_platform_rhv,multi_platform_sle,multi_platform_almalinux
-
-# uncomment the option if commented
-sed '/^[[:space:]]*#[[:space:]]*auth[[:space:]]\+required[[:space:]]\+pam_wheel\.so[[:space:]]\+use_uid$/s/^[[:space:]]*#//' -i /etc/pam.d/su
diff --git a/linux_os/guide/system/accounts/accounts-restrictions/root_logins/use_pam_wheel_for_su/oval/shared.xml b/linux_os/guide/system/accounts/accounts-restrictions/root_logins/use_pam_wheel_for_su/oval/shared.xml
deleted file mode 100644
index d7932de398fd..000000000000
--- a/linux_os/guide/system/accounts/accounts-restrictions/root_logins/use_pam_wheel_for_su/oval/shared.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-
grep pam_wheel /etc/pam.d/suThe output should contain the following line: -
auth required pam_wheel.so use_uid group={{{ xccdf_value("var_pam_wheel_group_for_su") }}}
+ auth required pam_wheel.so use_uid group={{{ xccdf_value("var_pam_wheel_group_for_su.var") }}}
warnings:
- general: |-
Note that ensure_pam_wheel_group_empty rule complements this requirement by
ensuring the referenced group exists and has no members.
+
+template:
+ name: pam_options
+ vars:
+ path: /etc/pam.d/su
+ type: auth
+ control_flag: required
+ module: pam_wheel.so
+ arguments:
+ - variable: group
+ variable_name: var_pam_wheel_group_for_su
+ operation: equals
+ datatype: string
+ - argument: use_uid
+ new_argument: use_uid
diff --git a/shared/templates/pam_options/ansible.template b/shared/templates/pam_options/ansible.template
index 5308b0625466..8da6a86a3fbc 100644
--- a/shared/templates/pam_options/ansible.template
+++ b/shared/templates/pam_options/ansible.template
@@ -10,13 +10,14 @@
# updated the Ansible pamd module to do that, we will need to use regexp
# for now.
-
-# declare the XCCDF vars if any
-{{% for arg in ARGUMENTS %}}
-{{% if arg['variable']|length %}}
-- (xccdf-var var_password_pam_{{{ arg['variable'] }}})
+{{% if product == 'sle16' %}}
+- name: Copy default /usr/lib/pam.d/{{ '{{{ PATH }}}' | basename }} to {{{ PATH }}}
+ ansible.builtin.copy:
+ src: /usr/lib/pam.d/{{ '{{{ PATH }}}' | basename }}
+ dest: {{{ PATH }}}
+ force: no
+ mode: '0644'
{{% endif %}}
-{{% endfor %}}
- name: Set control_flag fact
ansible.builtin.set_fact:
@@ -33,7 +34,7 @@
path: {{{ PATH }}}
line: '{{{ TYPE }}} {{{ CONTROL_FLAG }}} {{{ MODULE }}}'
state: present
- when: check_pam_module_result.stdout is defined and '"{{{ MODULE }}}" not in check_pam_module_result.stdout'
+ when: check_pam_module_result is not skipped and check_pam_module_result.stdout is defined and "{{{ MODULE }}}" not in check_pam_module_result.stdout
- name: Ensure '{{{ MODULE }}}' module has conforming control flag
ansible.builtin.lineinfile:
@@ -41,7 +42,7 @@
regexp: '^(\s*{{{ TYPE }}}\s+)\S+(\s+{{{ MODULE }}}\s+.*)'
line: '\g<1>{{{ CONTROL_FLAG }}}\g<2>'
backrefs: yes
- when: control_flag|length
+ when: check_pam_module_result is not skipped and control_flag|length
{{% for arg in ARGUMENTS %}}
# NOTE: if 'remove_argument' is present and set to some value, we assume
@@ -56,13 +57,22 @@
{{% elif arg['variable']|length %}}
# NOTE(gyee): if 'var' is used, user is meant to set the argument to a
# static value
+{{% if arg['variable_name'] %}}
+{{% set pam_variable_name = arg['variable_name'] %}}
+{{% else %}}
+{{% set pam_variable_name = "var_password_pam_" + arg['variable'] %}}
+{{% endif %}}
+{{{ ansible_instantiate_variables(pam_variable_name) }}}
+
+{{% set pam_variable_value = "{{ " + pam_variable_name + " }}" %}}
-- name: Ensure "{{{ MODULE }}}" module has argument "{{{ arg['variable'] }}}={{ var_password_pam_{{{ arg['variable'] }}} }}"
+- name: Ensure "{{{ MODULE }}}" module has argument "{{{ arg['variable'] }}}={{{ pam_variable_value }}}"
ansible.builtin.lineinfile:
path: {{{ PATH }}}
regexp: '^(\s*{{{ TYPE }}}\s+{{{ CONTROL_FLAG }}}\s+{{{ MODULE }}}(?:\s+\S+)*\s+{{{ arg['variable'] }}}=)(?:\S+)((\s+\S+)*\s*\\*\s*)$'
- line: '\g<1>{{ var_password_pam_{{{ arg['variable'] }}} }}\g<2>'
+ line: '\g<1>{{{ pam_variable_value }}}\g<2>'
backrefs: yes
+ when: check_pam_module_result is not skipped
- name: Check the presence of "{{{ arg['variable'] }}}" argument in "{{{ MODULE }}}" module
ansible.builtin.shell: |
@@ -74,9 +84,9 @@
ansible.builtin.lineinfile:
path: {{{ PATH }}}
regexp: '^(\s*{{{ TYPE }}}\s+{{{ CONTROL_FLAG }}}\s+{{{ MODULE }}})((\s+\S+)*\s*(\\)*$)'
- line: '\g<1> {{{ arg['variable'] }}}={{ var_password_pam_{{{ arg['variable'] }}} }}\g<2>'
+ line: '\g<1> {{{ arg['variable'] }}}={{{ pam_variable_value }}}\g<2>'
backrefs: yes
- when: check_pam_module_argument_result is not skipped and '"{{{ arg['variable'] }}}" not in check_pam_module_argument_result.stdout'
+ when: check_pam_module_argument_result is not skipped and "{{{ arg['variable'] }}}" not in check_pam_module_argument_result.stdout
{{% else %}}
- name: Set argument_value fact
ansible.builtin.set_fact:
@@ -102,6 +112,6 @@
regexp: '^(\s*{{{ TYPE }}}\s+{{{ CONTROL_FLAG }}}\s+{{{ MODULE }}})((\s+\S+)*\s*(\\)*$)'
line: '\g<1> {{{ arg['new_argument'] }}}\g<2>'
backrefs: yes
- when: check_pam_module_argument_result is not skipped and '"{{{ arg['argument'] }}}" not in check_pam_module_argument_result.stdout'
+ when: check_pam_module_argument_result is not skipped and "{{{ arg['argument'] }}}" not in check_pam_module_argument_result.stdout
{{% endif %}}
{{% endfor %}}
diff --git a/shared/templates/pam_options/bash.template b/shared/templates/pam_options/bash.template
index 49b717c6cb45..a3b4ca92863a 100644
--- a/shared/templates/pam_options/bash.template
+++ b/shared/templates/pam_options/bash.template
@@ -10,10 +10,22 @@ declare -a ARGS=()
declare -a NEW_ARGS=()
declare -a DEL_ARGS=()
+{{% if product == 'sle16' %}}
+PAM_DEFAULTS_FILE_NAME="/usr/lib/pam.d/$(basename "{{{ PATH }}}")"
+if ! [ -e "{{{ PATH }}}" ] ; then
+ cp "${PAM_DEFAULTS_FILE_NAME}" "{{{ PATH }}}"
+fi
+{{% endif %}}
+
{{% for arg in ARGUMENTS -%}}
{{% if arg['variable'] | length -%}}
-{{{ bash_instantiate_variables("var_password_pam_" + arg['variable']) }}}
-VALUES+=("${{{ "var_password_pam_" + arg['variable'] }}}")
+{{% if arg['variable_name'] %}}
+{{% set pam_variable_name = arg['variable_name'] %}}
+{{% else %}}
+{{% set pam_variable_name = "var_password_pam_" + arg['variable'] %}}
+{{% endif %}}
+{{{ bash_instantiate_variables(pam_variable_name) }}}
+VALUES+=("${{{ pam_variable_name }}}")
VALUE_NAMES+=("{{{ arg['variable'] }}}")
{{%- else %}}
VALUES+=("")
diff --git a/shared/templates/pam_options/oval.template b/shared/templates/pam_options/oval.template
index e517a837f463..9751c025adb6 100644
--- a/shared/templates/pam_options/oval.template
+++ b/shared/templates/pam_options/oval.template
@@ -4,22 +4,63 @@
{{% set MATCH_CONTROL_FLAG = '\S+' %}}
{{% endif %}}
+{{% if product == 'sle16' %}}
+{{% set PAM_VENDOR_FILE = "/usr/lib/pam.d/" + PATH.split('/') | last %}}
+{{% endif %}}
+