Skip to content

Commit

Permalink
Merge pull request #12133 from marcusburghardt/pam_macros_variables
Browse files Browse the repository at this point in the history
Make PAM macros more flexible to variables
  • Loading branch information
jan-cerny authored Jul 16, 2024
2 parents 1fdade9 + c1e2d24 commit b8d9d10
Show file tree
Hide file tree
Showing 19 changed files with 61 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# packages = authselect
# platform = multi_platform_fedora,Oracle Linux 8,Oracle Linux 9,Red Hat Enterprise Linux 8,Red Hat Enterprise Linux 9

if authselect list-features minimal | grep -q with-silent-lastlog; then
if authselect list-features sssd | grep -q with-silent-lastlog; then
authselect select sssd --force
authselect disable-feature with-silent-lastlog
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# packages = authselect
# platform = multi_platform_fedora,Oracle Linux 8,Oracle Linux 9,Red Hat Enterprise Linux 8,Red Hat Enterprise Linux 9

if authselect list-features minimal | grep -q with-silent-lastlog; then
if authselect list-features sssd | grep -q with-silent-lastlog; then
authselect select sssd --force
authselect enable-feature with-silent-lastlog
else
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
pam_files=("password-auth" "system-auth")

authselect create-profile testingProfile --base-on minimal
authselect create-profile testingProfile --base-on sssd

CUSTOM_PROFILE_DIR="/etc/authselect/custom/testingProfile"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# platform = Oracle Linux 8,Oracle Linux 9,Red Hat Enterprise Linux 8,Red Hat Enterprise Linux 9,multi_platform_fedora
# variables = var_password_pam_remember=5,var_password_pam_remember_control_flag=requisite

if authselect list-features minimal | grep -q with-pwhistory; then
if authselect list-features sssd | grep -q with-pwhistory; then
authselect select sssd --force
authselect enable-feature with-pwhistory
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# platform = Oracle Linux 8,Oracle Linux 9,Red Hat Enterprise Linux 8,Red Hat Enterprise Linux 9,multi_platform_fedora
# variables = var_password_pam_remember=5,var_password_pam_remember_control_flag=requisite

if authselect list-features minimal | grep -q with-pwhistory; then
if authselect list-features sssd | grep -q with-pwhistory; then
authselect select sssd --force
authselect disable-feature with-pwhistory
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# platform = Oracle Linux 8,Oracle Linux 9,Red Hat Enterprise Linux 8,Red Hat Enterprise Linux 9,multi_platform_fedora
# variables = var_password_pam_remember=5,var_password_pam_remember_control_flag=requisite

if authselect list-features minimal | grep -q with-pwhistory; then
if authselect list-features sssd | grep -q with-pwhistory; then
# There is no easy way to skip this test scenario in systems with "with-pwhistory" feature.
# In these systems, if the controls of a existing feature are modified in authselect profiles,
# this impacts directly in the feature behaviour and is strongly not recommended. In any case,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# platform = Oracle Linux 8,Oracle Linux 9,Red Hat Enterprise Linux 8,Red Hat Enterprise Linux 9,multi_platform_fedora
# variables = var_password_pam_remember=5,var_password_pam_remember_control_flag=requisite

if authselect list-features minimal | grep -q with-pwhistory; then
if authselect list-features sssd | grep -q with-pwhistory; then
authselect select sssd --force
authselect enable-feature with-pwhistory
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# platform = Oracle Linux 8,Oracle Linux 9,Red Hat Enterprise Linux 8,Red Hat Enterprise Linux 9,multi_platform_fedora
# variables = var_password_pam_remember=5,var_password_pam_remember_control_flag=requisite

if authselect list-features minimal | grep -q with-pwhistory; then
if authselect list-features sssd | grep -q with-pwhistory; then
authselect select sssd --force
authselect disable-feature with-pwhistory
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# platform = Oracle Linux 8,Oracle Linux 9,Red Hat Enterprise Linux 8,Red Hat Enterprise Linux 9,multi_platform_fedora
# variables = var_password_pam_remember=5,var_password_pam_remember_control_flag=requisite

if authselect list-features minimal | grep -q with-pwhistory; then
if authselect list-features sssd | grep -q with-pwhistory; then
# There is no easy way to skip this test scenario in systems with "with-pwhistory" feature.
# In these systems, if the controls of a existing feature are modified in authselect profiles,
# this impacts directly in the feature behaviour and is strongly not recommended. In any case,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# platform = Oracle Linux 8,Red Hat Enterprise Linux 8,Red Hat Enterprise Linux 9,multi_platform_fedora
# variables = var_password_pam_unix_remember=5

if authselect list-features minimal | grep -q with-pwhistory; then
if authselect list-features sssd | grep -q with-pwhistory; then
authselect select sssd --force
authselect enable-feature with-pwhistory
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# platform = Oracle Linux 8,Red Hat Enterprise Linux 8,Red Hat Enterprise Linux 9,multi_platform_fedora
# variables = var_password_pam_unix_remember=5

if authselect list-features minimal | grep -q with-pwhistory; then
if authselect list-features sssd | grep -q with-pwhistory; then
authselect select sssd --force
authselect disable-feature with-pwhistory
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ CUSTOM_PROFILE="custom/hardening"
authselect select $CUSTOM_PROFILE --force
CUSTOM_SYSTEM_AUTH="/etc/authselect/$CUSTOM_PROFILE/system-auth"

if ! authselect list-features minimal | grep -q with-pwhistory; then
if ! authselect list-features sssd | grep -q with-pwhistory; then
sed -i --follow-symlinks '/.*pam_pwhistory\.so/d' $CUSTOM_SYSTEM_AUTH
fi

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

pam_files=("password-auth" "system-auth")

authselect create-profile testingProfile --base-on minimal
authselect create-profile testingProfile --base-on sssd

CUSTOM_PROFILE_DIR="/etc/authselect/custom/testingProfile"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

pam_files=("password-auth" "system-auth")

authselect create-profile testingProfile --base-on minimal
authselect create-profile testingProfile --base-on sssd

CUSTOM_PROFILE_DIR="/etc/authselect/custom/testingProfile"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
{{% for cfile in configuration_files %}}
{{{ ansible_remove_pam_module_option_configuration(pam_file='/etc/pam.d/' ~ cfile,
group='password',
control=".*",
control="",
module='pam_pwquality.so',
option='retry') }}}
{{% endfor %}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
{{% for cfile in configuration_files %}}
{{{ bash_remove_pam_module_option_configuration(pam_file='/etc/pam.d/' ~ cfile,
group='password',
control=".*",
control="",
module='pam_pwquality.so',
option='retry') }}}
{{% endfor %}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ configuration_files=("system-auth")


{{% if product in ['ol8', 'ol9', 'rhel8', 'rhel9'] %}}
authselect create-profile testingProfile --base-on minimal
authselect create-profile testingProfile --base-on sssd

for file in ${configuration_files[@]}; do
sed -i --follow-symlinks "/pam_pwquality\.so/d" \
Expand Down
44 changes: 28 additions & 16 deletions shared/macros/10-ansible.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -948,7 +948,7 @@ The following macro remediates Audit syscall rule in :code:`/etc/audit/audit.rul

- name: '{{{ rule_title }}} - Collect the Available authselect Features'
ansible.builtin.command:
cmd: authselect list-features minimal
cmd: authselect list-features sssd
register: result_authselect_available_features
changed_when: false
when:
Expand Down Expand Up @@ -990,7 +990,7 @@ The following macro remediates Audit syscall rule in :code:`/etc/audit/audit.rul

- name: '{{{ rule_title }}} - Collect the available authselect features'
ansible.builtin.command:
cmd: authselect list-features minimal
cmd: authselect list-features sssd
register: result_authselect_available_features
changed_when: false
when:
Expand Down Expand Up @@ -1421,10 +1421,14 @@ Part of the grub2_bootloader_argument_absent template.

#}}
{{%- macro ansible_ensure_pam_module_line(pam_file, group, control, module, after_match='') -%}}
- name: '{{{ rule_title }}} - Define a fact for control already filtered in case filters are used'
ansible.builtin.set_fact:
pam_module_control: '{{{ control }}}'

- name: '{{{ rule_title }}} - Check if expected PAM module line is present in {{{ pam_file }}}'
ansible.builtin.lineinfile:
path: "{{{ pam_file }}}"
regexp: ^\s*{{{ group }}}\s+{{ '{{{ control }}}' | regex_escape() }}\s+{{{ module }}}\s*.*
regexp: ^\s*{{{ group }}}\s+{{ pam_module_control | regex_escape() }}\s+{{{ module }}}\s*.*
state: absent
check_mode: yes
changed_when: false
Expand All @@ -1445,7 +1449,7 @@ Part of the grub2_bootloader_argument_absent template.
ansible.builtin.replace:
dest: "{{{ pam_file }}}"
regexp: '^(\s*{{{ group }}}\s+).*(\b{{{ module }}}.*)'
replace: '\1{{{ control }}} \2'
replace: '\1{{ pam_module_control }} \2'
register: result_pam_module_edit
when:
- result_pam_line_other_control_present.found == 1
Expand All @@ -1456,7 +1460,7 @@ Part of the grub2_bootloader_argument_absent template.
{{%- if after_match != '' %}}
insertafter: {{{ after_match }}}
{{%- endif %}}
line: {{{ group }}} {{{ control }}} {{{ module }}}
line: "{{{ group }}} {{ pam_module_control }} {{{ module }}}"
register: result_pam_module_add
when:
- result_pam_line_other_control_present.found == 0 or result_pam_line_other_control_present.found > 1
Expand Down Expand Up @@ -1496,40 +1500,44 @@ Part of the grub2_bootloader_argument_absent template.
{{%- macro ansible_ensure_pam_module_option(pam_file, group, control, module, option, value='', after_match='') -%}}
{{{ ansible_ensure_pam_module_line(pam_file, group, control, module, after_match) }}}

- name: '{{{ rule_title }}} - Define a fact for control already filtered in case filters are used'
ansible.builtin.set_fact:
pam_module_control: '{{{ control }}}'

- name: '{{{ rule_title }}} - Check if the required PAM module option is present in {{{ pam_file }}}'
ansible.builtin.lineinfile:
path: "{{{ pam_file }}}"
regexp: ^\s*{{{ group }}}\s+{{ '{{{ control }}}' | regex_escape() }}\s+{{{ module }}}\s*.*\s{{{ option }}}\b
regexp: ^\s*{{{ group }}}\s+{{ pam_module_control | regex_escape() }}\s+{{{ module }}}\s*.*\s{{{ option }}}\b
state: absent
check_mode: true
changed_when: false
register: result_pam_module_{{{ option }}}_option_present
register: result_pam_module_{{{ rule_id }}}_option_present

- name: '{{{ rule_title }}} - Ensure the "{{{ option }}}" PAM option for "{{{ module }}}" is included in {{{ pam_file }}}'
ansible.builtin.lineinfile:
path: "{{{ pam_file }}}"
backrefs: true
regexp: ^(\s*{{{ group }}}\s+{{ '{{{ control }}}' | regex_escape() }}\s+{{{ module }}}.*)
regexp: ^(\s*{{{ group }}}\s+{{ pam_module_control | regex_escape() }}\s+{{{ module }}}.*)
{{%- if value == '' %}}
line: \1 {{{ option }}}
{{%- else %}}
line: \1 {{{ option }}}={{{ value }}}
{{%- endif %}}
state: present
register: result_pam_{{{ option }}}_add
register: result_pam_{{{ rule_id }}}_add
when:
- result_pam_module_{{{ option }}}_option_present.found == 0
- result_pam_module_{{{ rule_id }}}_option_present.found == 0

{{%- if value != '' %}}
- name: '{{{ rule_title }}} - Ensure the required value for "{{{ option }}}" PAM option from "{{{ module }}}" in {{{ pam_file }}}'
ansible.builtin.lineinfile:
path: "{{{ pam_file }}}"
backrefs: true
regexp: ^(\s*{{{ group }}}\s+{{ '{{{ control }}}' | regex_escape() }}\s+{{{ module }}}\s+.*)({{{ option }}})=[0-9a-zA-Z]+\s*(.*)
regexp: ^(\s*{{{ group }}}\s+{{ pam_module_control | regex_escape() }}\s+{{{ module }}}\s+.*)({{{ option }}})=[0-9a-zA-Z]+\s*(.*)
line: \1\2={{{ value }}} \3
register: result_pam_{{{ option }}}_edit
register: result_pam_{{{ rule_id }}}_edit
when:
- result_pam_module_{{{ option }}}_option_present.found > 0
- result_pam_module_{{{ rule_id }}}_option_present.found > 0
{{%- endif %}}
{{%- endmacro -%}}

Expand All @@ -1550,13 +1558,17 @@ Part of the grub2_bootloader_argument_absent template.

#}}
{{%- macro ansible_remove_pam_module_option(pam_file, group, control, module, option) -%}}
- name: '{{{ rule_title }}} - Define a fact for control already filtered in case filters are used'
ansible.builtin.set_fact:
pam_module_control: '{{{ control }}}'

- name: '{{{ rule_title }}} - Ensure the "{{{ option }}}" option from "{{{ module }}}" is not present in {{{ pam_file }}}'
ansible.builtin.replace:
dest: "{{{ pam_file }}}"
{{%- if control == '' %}}
regexp: (.*{{{ group }}}.*{{{ module }}}.*)\b{{{ option }}}\b=?[0-9a-zA-Z]*(.*)
{{%- else %}}
regexp: (.*{{{ group }}}.*{{ '{{{ control }}}' | regex_escape() }}.*{{{ module }}}.*)\b{{{ option }}}\b=?[0-9a-zA-Z]*(.*)
regexp: (.*{{{ group }}}.*{{ pam_module_control | regex_escape() }}.*{{{ module }}}.*)\b{{{ option }}}\b=?[0-9a-zA-Z]*(.*)
{{%- endif %}}
replace: '\1\2'
register: result_pam_option_removal
Expand Down Expand Up @@ -1729,8 +1741,8 @@ Part of the grub2_bootloader_argument_absent template.
when:
- result_authselect_present.stat.exists
- >-
(result_pam_{{{ option }}}_add is defined and result_pam_{{{ option }}}_add.changed)
or (result_pam_{{{ option }}}_edit is defined and result_pam_{{{ option }}}_edit.changed)
(result_pam_{{{ rule_id }}}_add is defined and result_pam_{{{ rule_id }}}_add.changed)
or (result_pam_{{{ rule_id }}}_edit is defined and result_pam_{{{ rule_id }}}_edit.changed)
when:
- result_pam_file_present.stat.exists
{{%- endmacro -%}}
Expand Down
32 changes: 16 additions & 16 deletions shared/macros/10-bash.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -893,7 +893,7 @@ PAM_FILE_PATH="/etc/authselect/$CURRENT_PROFILE/$PAM_FILE_NAME"
#}}
{{%- macro bash_pam_lastlog_enable_showfailed(pam_file, control, after_match='') -%}}
if [ -f /usr/bin/authselect ]; then
if authselect list-features minimal | grep -q with-silent-lastlog; then
if authselect list-features sssd | grep -q with-silent-lastlog; then
{{{ bash_disable_authselect_feature('with-silent-lastlog') | indent(8) }}}
else
{{# the following macro ensures the PAM_FILE_PATH variable is properly set #}}
Expand Down Expand Up @@ -926,7 +926,7 @@ fi
#}}
{{%- macro bash_pam_pwhistory_enable(pam_file, control, after_match='') -%}}
if [ -f /usr/bin/authselect ]; then
if authselect list-features minimal | grep -q with-pwhistory; then
if authselect list-features sssd | grep -q with-pwhistory; then
{{{ bash_enable_authselect_feature('with-pwhistory') | indent(8) }}}
else
{{# the following macro ensures the PAM_FILE_PATH variable is properly set #}}
Expand Down Expand Up @@ -2158,22 +2158,22 @@ fi

#}}
{{%- macro bash_ensure_pam_module_line(pam_file, group, control, module, after_match='') -%}}
if ! grep -qP '^\s*{{{ group }}}\s+'"{{{ control }}}"'\s+{{{ module }}}\s*.*' "{{{ pam_file }}}"; then
if ! grep -qP "^\s*{{{ group }}}\s+{{{ control }}}\s+{{{ module }}}\s*.*" "{{{ pam_file }}}"; then
# Line matching group + control + module was not found. Check group + module.
if [ "$(grep -cP '^\s*{{{ group }}}\s+.*\s+{{{ module }}}\s*' "{{{ pam_file }}}")" -eq 1 ]; then
# The control is updated only if one single line matches.
sed -i -E --follow-symlinks 's/^(\s*{{{ group }}}\s+).*(\b{{{ module }}}.*)/\1'"{{{ control }}}"' \2/' "{{{ pam_file }}}"
sed -i -E --follow-symlinks "s/^(\s*{{{ group }}}\s+).*(\b{{{ module }}}.*)/\1{{{ control }}} \2/" "{{{ pam_file }}}"
else
{{%- if after_match == '' %}}
echo '{{{ group }}} '"{{{ control }}}"' {{{ module }}}' >> "{{{ pam_file }}}"
echo "{{{ group }}} {{{ control }}} {{{ module }}}" >> "{{{ pam_file }}}"
{{%- elif after_match == 'BOF' %}}
sed -i --follow-symlinks '1i {{{ group }}} '"{{{ control }}}"' {{{ module }}}' "{{{ pam_file }}}"
sed -i --follow-symlinks "1i {{{ group }}} {{{ control }}} {{{ module }}}" "{{{ pam_file }}}"
{{%- else %}}
LAST_MATCH_LINE=$(grep -nP "{{{ after_match }}}" "{{{ pam_file }}}" | tail -n 1 | cut -d: -f 1)
if [ ! -z $LAST_MATCH_LINE ]; then
sed -i --follow-symlinks $LAST_MATCH_LINE' a {{{ group }}} '"{{{ control }}}"' {{{ module }}}' "{{{ pam_file }}}"
sed -i --follow-symlinks $LAST_MATCH_LINE" a {{{ group }}} {{{ control }}} {{{ module }}}" "{{{ pam_file }}}"
else
echo '{{{ group }}} '"{{{ control }}}"' {{{ module }}}' >> "{{{ pam_file }}}"
echo "{{{ group }}} {{{ control }}} {{{ module }}}" >> "{{{ pam_file }}}"
fi
{{%- endif %}}
fi
Expand Down Expand Up @@ -2203,17 +2203,17 @@ fi
{{%- macro bash_ensure_pam_module_option(pam_file, group, control, module, option, value='', after_match='') -%}}
{{{ bash_ensure_pam_module_line(pam_file, group, control, module, after_match) }}}
# Check the option
if ! grep -qP '^\s*{{{ group }}}\s+'"{{{ control }}}"'\s+{{{ module }}}\s*.*\s{{{ option }}}\b' "{{{ pam_file }}}"; then
if ! grep -qP "^\s*{{{ group }}}\s+{{{ control }}}\s+{{{ module }}}\s*.*\s{{{ option }}}\b" "{{{ pam_file }}}"; then
{{%- if value == '' %}}
sed -i -E --follow-symlinks '/\s*{{{ group }}}\s+'"{{{ control }}}"'\s+{{{ module }}}.*/ s/$/ {{{ option }}}/' "{{{ pam_file }}}"
sed -i -E --follow-symlinks "/\s*{{{ group }}}\s+{{{ control }}}\s+{{{ module }}}.*/ s/$/ {{{ option }}}/" "{{{ pam_file }}}"
{{%- else %}}
sed -i -E --follow-symlinks '/\s*{{{ group }}}\s+'"{{{ control }}}"'\s+{{{ module }}}.*/ s/$/ {{{ option }}}='"{{{ value }}}"'/' "{{{ pam_file }}}"
sed -i -E --follow-symlinks "/\s*{{{ group }}}\s+{{{ control }}}\s+{{{ module }}}.*/ s/$/ {{{ option }}}={{{ value }}}/" "{{{ pam_file }}}"
{{%- endif %}}
{{%- if value == '' %}}
fi
{{%- else %}}
else
sed -i -E --follow-symlinks 's/(\s*{{{ group }}}\s+'"{{{ control }}}"'\s+{{{ module }}}\s+.*)('"{{{ option }}}"'=)[[:alnum:]]+\s*(.*)/\1\2'"{{{ value }}}"' \3/' "{{{ pam_file }}}"
sed -i -E --follow-symlinks "s/(\s*{{{ group }}}\s+{{{ control }}}\s+{{{ module }}}\s+.*)({{{ option }}}=)[[:alnum:]]+\s*(.*)/\1\2{{{ value }}} \3/" "{{{ pam_file }}}"
fi
{{%- endif %}}
{{%- endmacro -%}}
Expand All @@ -2236,11 +2236,11 @@ fi
#}}
{{%- macro bash_remove_pam_module_option(pam_file, group, control, module, option) -%}}
{{%- if control == '' %}}
if grep -qP '^\s*{{{ group }}}\s.*\b{{{ module }}}\s.*\b{{{ option }}}\b' "{{{ pam_file }}}"; then
sed -i -E --follow-symlinks 's/(.*{{{ group }}}.*{{{ module }}}.*)\b{{{ option }}}\b=?[[:alnum:]]*(.*)/\1\2/g' "{{{ pam_file }}}"
if grep -qP "^\s*{{{ group }}}\s.*\b{{{ module }}}\s.*\b{{{ option }}}\b" "{{{ pam_file }}}"; then
sed -i -E --follow-symlinks "s/(.*{{{ group }}}.*{{{ module }}}.*)\b{{{ option }}}\b=?[[:alnum:]]*(.*)/\1\2/g" "{{{ pam_file }}}"
{{%- else %}}
if grep -qP '^\s*{{{ group }}}\s+'"{{{ control }}}"'\s+{{{ module }}}\s.*\b{{{ option }}}\b' "{{{ pam_file }}}"; then
sed -i -E --follow-symlinks 's/(.*{{{ group }}}.*'"{{{ control }}}"'.*{{{ module }}}.*)\s{{{ option }}}=?[[:alnum:]]*(.*)/\1\2/g' "{{{ pam_file }}}"
if grep -qP "^\s*{{{ group }}}\s+{{{ control }}}\s+{{{ module }}}\s.*\b{{{ option }}}\b" "{{{ pam_file }}}"; then
sed -i -E --follow-symlinks "s/(.*{{{ group }}}.*{{{ control }}}.*{{{ module }}}.*)\s{{{ option }}}=?[[:alnum:]]*(.*)/\1\2/g" "{{{ pam_file }}}"
{{%- endif %}}
fi
{{%- endmacro -%}}
Expand Down

0 comments on commit b8d9d10

Please sign in to comment.