Skip to content

Commit

Permalink
Implement accounts_passwords_pam_faillock_enabled
Browse files Browse the repository at this point in the history
  • Loading branch information
alanmcanonical committed Jan 6, 2025
1 parent ef449a6 commit 29e58f6
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# platform = multi_platform_ubuntu

{{{ bash_pam_faillock_enable() }}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
<def-group>
<definition class="compliance" id="{{{ rule_id }}}" version="6">
{{{ oval_metadata(DESCRIPTION) }}}

{{% if 'debian' in product or 'ubuntu' in product %}}

<criteria operator="AND" comment="Check the proper configuration of pam_faillock.so">
<!-- pam_unix.so is a control module present in all realistic scenarios and also used
as reference for the correct position of pam_faillock.so in auth section. If the
system is properly configured, it must appear only once in auth section. -->
<criterion test_ref="test_accounts_passwords_pam_faillock_common_pam_unix_auth"
comment="pam_unix.so appears only once in auth section of common-auth"/>
<criterion test_ref="test_accounts_passwords_pam_faillock_common_pam_faillock_auth"
comment="pam_faillock.so is properly defined in auth section of common-auth"/>
<criterion test_ref="test_accounts_passwords_pam_faillock_common_pam_faillock_account"
comment="pam_faillock.so is properly defined in common-account"/>
</criteria>

{{% endif %}}
</definition>

<!-- The following tests demand complex regex which are necessary more than once.
These variables make simpler the usage of regex patterns. -->
<constant_variable id="var_accounts_passwords_pam_faillock_pam_unix_regex"
datatype="string" version="2"
comment="regex to identify pam_unix.so in auth section of pam files">
<value>^\s*auth\N+pam_unix\.so</value>
</constant_variable>

<constant_variable
id="var_accounts_passwords_pam_faillock_pam_faillock_auth_regex"
datatype="string" version="2"
comment="regex to identify pam_faillock.so entries in auth section of pam files">
{{% if 'debian' in product %}}
<value>^\s*auth\s+required\s+pam_faillock\.so.*preauth.*[\s\S]*^\s*auth.*pam_unix\.so[\s\S]*^\s*auth\s+\[default=die\]\s+pam_faillock\.so\s+authfail[\s\S]*^\s*auth\s+sufficient\s+pam_faillock\.so\s+authsucc</value>
{{% elif 'ubuntu' in product %}}
<value>^\s*auth\s+(requisite|required)\s+pam_faillock\.so.*preauth.*[\s\S]*^\s*auth.*pam_unix\.so[\s\S]*^\s*auth\s+\[default=die\]\s+pam_faillock\.so\s+authfail</value>
{{% elif 'openeuler' in product or 'kylinserver' in product %}}
<value>^[\s]*auth[\s]+(required|\[(?=.*?\bsuccess=ok\b)?(?=.*?\bnew_authtok_reqd=ok\b)?(?=.*?\bignore=ignore\b)?(?=.*?\bdefault=bad\b)?.*\])[\s]+pam_faillock\.so[\s\w\d=]+preauth[\s\S]*^[\s]*auth[\s]+(sufficient|\[(?=.*\bsuccess=done\b)?(?=.*?\bnew_authtok_reqd=done\b)?(?=.*?\bdefault=ignore\b)?.*\])[\s]+pam_unix\.so[\s\S]*^[\s]*auth[\s]+(required|\[(?=.*?\bsuccess=ok\b)?(?=.*?\bnew_authtok_reqd=ok\b)?(?=.*?\bignore=ignore\b)?(?=.*?\bdefault=die\b)?.*\])[\s]+pam_faillock\.so[\s\w\d=]+authfail</value>
{{% else %}}
<value>^[\s]*auth[\s]+(required|\[(?=.*?\bsuccess=ok\b)(?=.*?\bnew_authtok_reqd=ok\b)(?=.*?\bignore=ignore\b)(?=.*?\bdefault=bad\b).*\])[\s]+pam_faillock\.so[\s\w\d=]+preauth[\s\S]*^[\s]*auth[\s]+(sufficient|\[(?=.*\bsuccess=done\b)(?=.*?\bnew_authtok_reqd=done\b)(?=.*?\bdefault=ignore\b).*\])[\s]+pam_unix\.so[\s\S]*^[\s]*auth[\s]+(required|\[(?=.*?\bsuccess=ok\b)(?=.*?\bnew_authtok_reqd=ok\b)(?=.*?\bignore=ignore\b)(?=.*?\bdefault=bad\b).*\])[\s]+pam_faillock\.so[\s\w\d=]+authfail</value>
{{% endif %}}
</constant_variable>

<constant_variable
id="var_accounts_passwords_pam_faillock_pam_faillock_account_regex"
datatype="string" version="2"
comment="regex to identify pam_faillock.so entry in account section of pam files">
{{% if 'debian' in product or 'ubuntu' in product %}}
<value>^\s*account\s+required\s+pam_faillock\.so\s*(#.*)?$</value>
{{% elif 'openeuler' in product or 'kylinserver' in product %}}
<value>^[\s]*account[\s]+(required|\[(?=.*?\bsuccess=ok\b)?(?=.*?\bnew_authtok_reqd=ok\b)?(?=.*?\bignore=ignore\b)?(?=.*?\bdefault=bad\b)?.*\])[\s]+pam_unix\.so[\s\S]*^[\s]*account[\s]+(required|\[(?=.*?\bsuccess=ok\b)?(?=.*?\bnew_authtok_reqd=ok\b)?(?=.*?\bignore=ignore\b)?(?=.*?\bdefault=bad\b)?.*\])[\s]+pam_faillock\.so</value>
{{% else %}}
<value>^[\s]*account[\s]+(required|\[(?=.*?\bsuccess=ok\b)(?=.*?\bnew_authtok_reqd=ok\b)(?=.*?\bignore=ignore\b)(?=.*?\bdefault=bad\b).*\])[\s]+pam_faillock\.so[\s\S]*^[\s]*account[\s]+(required|\[(?=.*?\bsuccess=ok\b)(?=.*?\bnew_authtok_reqd=ok\b)(?=.*?\bignore=ignore\b)(?=.*?\bdefault=bad\b).*\])[\s]+pam_unix\.so</value>
{{% endif %}}
</constant_variable>

{{% macro generate_test_faillock_enabled(file_stem) %}}
<!-- Check occurences of pam_unix.so in auth section of {{{ file_stem }}}-auth file -->
<ind:textfilecontent54_test
check="all" check_existence="none_exist" version="2"
id="test_accounts_passwords_pam_faillock_{{{ file_stem }}}_pam_unix_auth"
comment="no more that one pam_unix.so is expected in auth section of {{{ file_stem }}}-auth">
<ind:object object_ref="object_accounts_passwords_pam_faillock_{{{ file_stem }}}_pam_unix_auth"/>
</ind:textfilecontent54_test>

<ind:textfilecontent54_object
version="2"
id="object_accounts_passwords_pam_faillock_{{{ file_stem }}}_pam_unix_auth"
comment="Get the second and subsequent occurrences of pam_unix.so in auth section of {{{ file_stem}}}-auth">
<ind:filepath>/etc/pam.d/{{{file_stem}}}-auth</ind:filepath>
<ind:pattern operation="pattern match" var_ref="var_accounts_passwords_pam_faillock_pam_unix_regex"/>
<ind:instance datatype="int" operation="greater than">1</ind:instance>
</ind:textfilecontent54_object>

<!-- Check common definition of pam_faillock.so in {{{ file_stem }}}-auth file -->
<ind:textfilecontent54_test
check="all" check_existence="only_one_exists" version="2"
id="test_accounts_passwords_pam_faillock_{{{ file_stem }}}_pam_faillock_auth"
comment="One and only one occurrence is expected in auth section of {{{ file_stem }}}-auth">
<ind:object
object_ref="object_accounts_passwords_pam_faillock_{{{ PRM_NAME}}}_{{{ file_stem }}}_pam_faillock_auth"/>
</ind:textfilecontent54_test>

<ind:textfilecontent54_object
version="2"
id="object_accounts_passwords_pam_faillock_{{{ PRM_NAME}}}_{{{ file_stem }}}_pam_faillock_auth"
comment="Check common definition of pam_faillock.so in auth section of common-auth">
<ind:filepath>/etc/pam.d/{{{ file_stem }}}-auth</ind:filepath>
<ind:pattern operation="pattern match"
var_ref="var_accounts_passwords_pam_faillock_pam_faillock_auth_regex"/>
<ind:instance datatype="int" operation="equals">1</ind:instance>
</ind:textfilecontent54_object>
{{% endmacro %}}

{{{ generate_test_faillock_enabled (file_stem="common") }}}

{{% macro generate_test_faillock_account(file_stem, file) %}}
<!-- Check common definition of pam_faillock.so in {{{ file_stem }}}-account -->
<ind:textfilecontent54_test
check="all" check_existence="only_one_exists" version="2"
id="test_accounts_passwords_pam_faillock_{{{ file_stem }}}_pam_faillock_account"
comment="One and only one occurrence is expected in {{{ file }}}">
<ind:object
object_ref="object_accounts_passwords_pam_faillock_{{{ file_stem }}}_pam_faillock_account"/>
</ind:textfilecontent54_test>

<ind:textfilecontent54_object
version="2"
id="object_accounts_passwords_pam_faillock_{{{ file_stem }}}_pam_faillock_account"
comment="Check common definition of pam_faillock.so in account section of {{{ file }}}">
<ind:filepath>/etc/pam.d/{{{ file }}}</ind:filepath>
<ind:pattern operation="pattern match"
var_ref="var_accounts_passwords_pam_faillock_pam_faillock_account_regex"/>
<ind:instance datatype="int" operation="equals">1</ind:instance>
</ind:textfilecontent54_object>
{{% endmacro %}}

{{{ generate_test_faillock_account (file_stem="common", file="common-account") }}}

</def-group>
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash
# platform = multi_platform_ubuntu

{{{ bash_enable_pam_faillock_directly_in_pam_files() }}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/bash
# platform = multi_platform_ubuntu

{{{ bash_enable_pam_faillock_directly_in_pam_files() }}}

echo > /etc/security/faillock.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/bash
# platform = multi_platform_ubuntu
# remediation = none

{{{ bash_enable_pam_faillock_directly_in_pam_files() }}}

# Multiple instances of pam_unix.so in auth section may, intentionally or not, interfere
# in the expected behaviour of pam_faillock.so. Remediation does not solve this automatically
# in order to preserve intentional changes.

sed -i '/# end of pam-auth-update config/i\auth sufficient pam_unix.so' /etc/pam.d/common-auth

0 comments on commit 29e58f6

Please sign in to comment.