Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,14 @@ vuldiscussion: |-
When operating systems provide the capability to escalate a functional capability, it is critical the user re-authenticate.

platform: package[pam]

template:
name: pam_options
vars:
path: /etc/pam.d/su
type: auth
control_flag: required
module: pam_wheel.so
arguments:
- argument: use_uid
new_argument: use_uid

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,24 @@ ocil: |-
Run the following command to check if the line is present:
<pre>grep pam_wheel /etc/pam.d/su</pre>
The output should contain the following line:
<pre>auth required pam_wheel.so use_uid group={{{ xccdf_value("var_pam_wheel_group_for_su") }}}</pre>
<pre>auth required pam_wheel.so use_uid group={{{ xccdf_value("var_pam_wheel_group_for_su.var") }}}</pre>

warnings:
- general: |-
Note that <tt>ensure_pam_wheel_group_empty</tt> 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
36 changes: 23 additions & 13 deletions shared/templates/pam_options/ansible.template
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -33,15 +34,15 @@
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:
path: {{{ PATH }}}
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
Expand All @@ -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: |
Expand All @@ -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:
Expand All @@ -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 %}}
16 changes: 14 additions & 2 deletions shared/templates/pam_options/bash.template
Original file line number Diff line number Diff line change
Expand Up @@ -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+=("")
Expand Down
97 changes: 87 additions & 10 deletions shared/templates/pam_options/oval.template
Original file line number Diff line number Diff line change
Expand Up @@ -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 %}}

<def-group>
<definition class="compliance" id="{{{ _RULE_ID }}}" version="3">
{{{ oval_metadata("Configure PAM module", rule_title=rule_title) }}}
<criteria operator="AND" comment="Make sure arguments are properly configured">
{{% for arg in ARGUMENTS %}}
{{% if arg['variable']|length %}}
<criterion test_ref="test_pam_{{{ TYPE|lower }}}_{{{ MODULE|lower|replace('.so', '') }}}_{{{ arg['variable']|lower }}}" comment="Verify {{{ arg['variable'] }}} is set to the desired state" />
{{% if product == 'sle16' %}}
<criteria comment="PAM options properly configured" operator="OR">
<criteria operator="AND" comment="Make sure arguments are properly configured in {{{ PAM_VENDOR_FILE }}}">
<criterion comment="test if configuration file {{{ PATH }}} exists for {{{ rule_id }}}" test_ref="test_{{{ rule_id }}}_config_file_exists" negate="true"/>
{{% for arg in ARGUMENTS %}}
{{% if arg['variable']|length %}}
<criterion test_ref="test_pam_vendor_{{{ TYPE|lower }}}_{{{ MODULE|lower|replace('.so', '') }}}_{{{ arg['variable']|lower }}}" comment="Verify {{{ arg['variable'] }}} is set to the desired state" />
{{% else %}}
<criterion test_ref="test_pam_vendor_{{{ TYPE|lower }}}_{{{ MODULE|lower|replace('.so', '') }}}_{{{ arg['argument']|lower }}}" comment="Verify {{{ arg['argument'] }}} is set to the desired state" />
{{% endif %}}
{{% endfor %}}
</criteria>
<criteria operator="AND" comment="Make sure arguments are properly configured in {{{ PATH }}}">
{{{ oval_config_file_exists_criterion(PATH, rule_id=rule_id) }}}
{{% for arg in ARGUMENTS %}}
{{% if arg['variable']|length %}}
<criterion test_ref="test_pam_{{{ TYPE|lower }}}_{{{ MODULE|lower|replace('.so', '') }}}_{{{ arg['variable']|lower }}}" comment="Verify {{{ arg['variable'] }}} is set to the desired state" />
{{% else %}}
<criterion test_ref="test_pam_{{{ TYPE|lower }}}_{{{ MODULE|lower|replace('.so', '') }}}_{{{ arg['argument']|lower }}}" comment="Verify {{{ arg['argument'] }}} is set to the desired state" />
{{% endif %}}
{{% endfor %}}
</criteria>
</criteria>
{{% else %}}
<criterion test_ref="test_pam_{{{ TYPE|lower }}}_{{{ MODULE|lower|replace('.so', '') }}}_{{{ arg['argument']|lower }}}" comment="Verify {{{ arg['argument'] }}} is set to the desired state" />
{{% endif %}}
{{% endfor %}}
<criteria operator="AND" comment="Make sure arguments are properly configured in {{{ PATH }}}">
{{% for arg in ARGUMENTS %}}
{{% if arg['variable']|length %}}
<criterion test_ref="test_pam_{{{ TYPE|lower }}}_{{{ MODULE|lower|replace('.so', '') }}}_{{{ arg['variable']|lower }}}" comment="Verify {{{ arg['variable'] }}} is set to the desired state" />
{{% else %}}
<criterion test_ref="test_pam_{{{ TYPE|lower }}}_{{{ MODULE|lower|replace('.so', '') }}}_{{{ arg['argument']|lower }}}" comment="Verify {{{ arg['argument'] }}} is set to the desired state" />
{{% endif %}}
{{% endfor %}}
</criteria>
{{% endif %}}
</definition>

{{% if product == 'sle16' %}}
{{{ oval_config_file_exists_test(PATH, rule_id=rule_id) }}}
{{{ oval_config_file_exists_object(PATH, rule_id=rule_id) }}}
{{% endif %}}

{{% for arg in ARGUMENTS %}}
{{% if arg['variable']|length %}}
{{% if arg['variable_name'] %}}
{{% set pam_variable_name = arg['variable_name'] %}}
{{% else %}}
{{% set pam_variable_name = "var_password_pam_" + arg['variable'] %}}
{{% endif %}}


<ind:textfilecontent54_test id="test_pam_{{{ TYPE|lower }}}_{{{ MODULE|lower|replace('.so', '') }}}_{{{ arg['variable']|lower }}}"
check="all"
comment="Verify {{{ arg['variable'] }}} configuation of {{{ MODULE }}}" version="1">
Expand All @@ -29,15 +70,33 @@

<ind:textfilecontent54_object id="object_pam_{{{ TYPE|lower }}}_{{{ MODULE|lower|replace('.so', '') }}}_{{{ arg['variable']|lower }}}" comment="Check {{{ arg['variable'] }}} configuration of PAM {{{ MODULE }}} module" version="1">
<ind:filepath>{{{ PATH }}}</ind:filepath>
<ind:pattern operation="pattern match">^\s*{{{ TYPE }}}\s+{{{ MATCH_CONTROL_FLAG }}}\s+{{{ MODULE }}}.*\s{{{ arg['variable'] }}}=(-?\d+)(?:\s+.*)?</ind:pattern>
<ind:pattern operation="pattern match">^\s*{{{ TYPE }}}\s+{{{ MATCH_CONTROL_FLAG }}}\s+{{{ MODULE }}}.*\s{{{ arg['variable'] }}}=(-?[a-zA-Z0-9]+)(?:\s+.*)?</ind:pattern>
<ind:instance datatype="int" operation="greater than or equal">1</ind:instance>
</ind:textfilecontent54_object>

<ind:textfilecontent54_state id="state_pam_{{{ TYPE|lower }}}_{{{ MODULE|lower|replace('.so', '') }}}_{{{ arg['variable']|lower }}}" version="3">
<ind:subexpression datatype="int" operation="{{{ arg['operation'] }}}" var_ref="var_password_pam_{{{ arg['variable'] }}}" />
<ind:subexpression datatype={{% if arg['datatype'] %}}"{{{ arg['datatype'] }}}"{{% else %}}"int"{{% endif %}}
operation="{{{ arg['operation'] }}}" var_ref="{{{ pam_variable_name }}}" />
</ind:textfilecontent54_state>

<external_variable comment="PAM external variable var_password_pam_{{{ arg['variable'] }}}" datatype="int" id="var_password_pam_{{{ arg['variable'] }}}" version="1" />
<external_variable comment="PAM external variable {{{ pam_variable_name }}}" datatype="int" id="{{{ pam_variable_name }}}" version="1" />

{{% if product == 'sle16' %}}
<ind:textfilecontent54_test id="test_pam_vendor_{{{ TYPE|lower }}}_{{{ MODULE|lower|replace('.so', '') }}}_{{{ arg['variable']|lower }}}"
check="all"
comment="Verify {{{ arg['variable'] }}} configuation of {{{ MODULE }}}" version="1">
<ind:object object_ref="object_pam_vendor_{{{ TYPE|lower }}}_{{{ MODULE|lower|replace('.so', '') }}}_{{{ arg['variable']|lower }}}" />
<ind:state state_ref="state_pam_{{{ TYPE|lower }}}_{{{ MODULE|lower|replace('.so', '') }}}_{{{ arg['variable']|lower }}}" />
</ind:textfilecontent54_test>

<ind:textfilecontent54_object id="object_pam_vendor_{{{ TYPE|lower }}}_{{{ MODULE|lower|replace('.so', '') }}}_{{{ arg['variable']|lower }}}" comment="Check {{{ arg['variable'] }}} configuration of PAM {{{ MODULE }}} module" version="1">
<ind:filepath>{{{ PAM_VENDOR_FILE }}}</ind:filepath>
<ind:pattern operation="pattern match">^\s*{{{ TYPE }}}\s+{{{ MATCH_CONTROL_FLAG }}}\s+{{{ MODULE }}}.*\s{{{ arg['variable'] }}}=(-?[a-zA-Z0-9]+)(?:\s+.*)?</ind:pattern>
<ind:instance datatype="int" operation="greater than or equal">1</ind:instance>
</ind:textfilecontent54_object>
{{% endif %}}


{{% else %}}
<ind:textfilecontent54_test id="test_pam_{{{ TYPE|lower }}}_{{{ MODULE|lower|replace('.so', '') }}}_{{{ arg['argument']|lower }}}"
check="all" check_existence={{% if arg['remove_argument']|length %}}"none_exist"{{% else %}}"all_exist"{{% endif %}}
Expand All @@ -54,6 +113,24 @@
{{% endif %}}
<ind:instance datatype="int">1</ind:instance>
</ind:textfilecontent54_object>

{{% if product == 'sle16' %}}
<ind:textfilecontent54_test id="test_pam_vendor_{{{ TYPE|lower }}}_{{{ MODULE|lower|replace('.so', '') }}}_{{{ arg['argument']|lower }}}"
check="all" check_existence={{% if arg['remove_argument']|length %}}"none_exist"{{% else %}}"all_exist"{{% endif %}}
comment="Verify {{{ arg['argument'] }}} configuation of {{{ MODULE }}}" version="1">
<ind:object object_ref="object_pam_vendor_{{{ TYPE|lower }}}_{{{ MODULE|lower|replace('.so', '') }}}_{{{ arg['argument']|lower }}}" />
</ind:textfilecontent54_test>

<ind:textfilecontent54_object id="object_pam_vendor_{{{ TYPE|lower }}}_{{{ MODULE|lower|replace('.so', '') }}}_{{{ arg['argument']|lower }}}" comment="Check {{{ arg['argument'] }}} configuration of PAM {{{ MODULE }}} module" version="1">
<ind:filepath>{{{ PAM_VENDOR_FILE }}}</ind:filepath>
{{% if arg['argument_match']|length %}}
<ind:pattern operation="pattern match">^\s*{{{ TYPE }}}(?:(?!\n)\s)+{{{ MATCH_CONTROL_FLAG }}}(?:(?!\n)\s)+{{{ MODULE }}}((?!\n)\s[^\n]+)?(?!\n)\s+{{{ arg['argument'] }}}={{{ arg['argument_match'] }}}((\s+\S+)*\s*\\*\s*)$</ind:pattern>
{{% else %}}
<ind:pattern operation="pattern match">^\s*{{{ TYPE }}}(?:(?!\n)\s)+{{{ MATCH_CONTROL_FLAG }}}(?:(?!\n)\s)+{{{ MODULE }}}((?!\n)\s[^\n]+)?(?!\n)\s+{{{ arg['argument'] }}}((\s+\S+)*\s*\\*\s*)$</ind:pattern>
{{% endif %}}
<ind:instance datatype="int">1</ind:instance>
</ind:textfilecontent54_object>
{{% endif %}}
{{% endif %}}
{{% endfor %}}
</def-group>
Loading