a0aa53d1a1
CVE-2018-16837 Co-authored-by: Toshio Kuratomi <a.badger@gmail.com>
524 lines
14 KiB
YAML
524 lines
14 KiB
YAML
# Test code for the user module.
|
|
# (c) 2017, James Tanner <tanner.jc@gmail.com>
|
|
|
|
# This file is part of Ansible
|
|
#
|
|
# Ansible is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# Ansible is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
- name: get the jinja2 version
|
|
shell: python -c 'import jinja2; print(jinja2.__version__)'
|
|
register: jinja2_version
|
|
delegate_to: localhost
|
|
changed_when: no
|
|
|
|
- debug:
|
|
msg: "Jinja version: {{ jinja2_version.stdout }}, Python version: {{ ansible_python_version }}"
|
|
|
|
|
|
## user add
|
|
|
|
- name: remove the test user
|
|
user:
|
|
name: ansibulluser
|
|
state: absent
|
|
|
|
- name: try to create a user
|
|
user:
|
|
name: ansibulluser
|
|
state: present
|
|
register: user_test0_0
|
|
|
|
- name: create the user again
|
|
user:
|
|
name: ansibulluser
|
|
state: present
|
|
register: user_test0_1
|
|
|
|
- debug:
|
|
var: user_test0
|
|
verbosity: 2
|
|
|
|
- name: make a list of users
|
|
script: userlist.sh {{ ansible_distribution }}
|
|
register: user_names
|
|
|
|
- debug:
|
|
var: user_names
|
|
verbosity: 2
|
|
|
|
- name: validate results for testcase 0
|
|
assert:
|
|
that:
|
|
- user_test0_0 is changed
|
|
- user_test0_1 is not changed
|
|
- '"ansibulluser" in user_names.stdout_lines'
|
|
|
|
# test user add with password
|
|
- name: add an encrypted password for user
|
|
user:
|
|
name: ansibulluser
|
|
password: "$6$rounds=656000$TT4O7jz2M57npccl$33LF6FcUMSW11qrESXL1HX0BS.bsiT6aenFLLiVpsQh6hDtI9pJh5iY7x8J7ePkN4fP8hmElidHXaeD51pbGS."
|
|
state: present
|
|
update_password: always
|
|
register: test_user_encrypt0
|
|
|
|
- name: there should not be warnings
|
|
assert:
|
|
that: "'warnings' not in test_user_encrypt0"
|
|
|
|
- block:
|
|
- name: add an plaintext password for user
|
|
user:
|
|
name: ansibulluser
|
|
password: "plaintextpassword"
|
|
state: present
|
|
update_password: always
|
|
register: test_user_encrypt1
|
|
|
|
- name: there should be a warning complains that the password is plaintext
|
|
assert:
|
|
that: "'warnings' in test_user_encrypt1"
|
|
|
|
- name: add an invalid hashed password
|
|
user:
|
|
name: ansibulluser
|
|
password: "$6$rounds=656000$tgK3gYTyRLUmhyv2$lAFrYUQwn7E6VsjPOwQwoSx30lmpiU9r/E0Al7tzKrR9mkodcMEZGe9OXD0H/clOn6qdsUnaL4zefy5fG+++++"
|
|
state: present
|
|
update_password: always
|
|
register: test_user_encrypt2
|
|
|
|
- name: there should be a warning complains about the character set of password
|
|
assert:
|
|
that: "'warnings' in test_user_encrypt2"
|
|
when: ansible_system != 'Darwin'
|
|
|
|
|
|
# https://github.com/ansible/ansible/issues/42484
|
|
# Skipping macOS for now since there is a bug when changing home directory
|
|
- block:
|
|
- name: create user specifying home
|
|
user:
|
|
name: ansibulluser
|
|
state: present
|
|
home: "{{ user_home_prefix[ansible_system] }}/ansibulluser"
|
|
register: user_test3_0
|
|
|
|
- name: create user again specifying home
|
|
user:
|
|
name: ansibulluser
|
|
state: present
|
|
home: "{{ user_home_prefix[ansible_system] }}/ansibulluser"
|
|
register: user_test3_1
|
|
|
|
- name: change user home
|
|
user:
|
|
name: ansibulluser
|
|
state: present
|
|
home: "{{ user_home_prefix[ansible_system] }}/ansibulluser-mod"
|
|
register: user_test3_2
|
|
|
|
- name: change user home back
|
|
user:
|
|
name: ansibulluser
|
|
state: present
|
|
home: "{{ user_home_prefix[ansible_system] }}/ansibulluser"
|
|
register: user_test3_3
|
|
|
|
- name: validate results for testcase 3
|
|
assert:
|
|
that:
|
|
- user_test3_0 is not changed
|
|
- user_test3_1 is not changed
|
|
- user_test3_2 is changed
|
|
- user_test3_3 is changed
|
|
when: ansible_system != 'Darwin'
|
|
|
|
|
|
## user check
|
|
|
|
- name: run existing user check tests
|
|
user:
|
|
name: "{{ user_names.stdout_lines | random }}"
|
|
state: present
|
|
create_home: no
|
|
loop: "{{ range(1, 5+1) | list }}"
|
|
register: user_test1
|
|
|
|
- debug:
|
|
var: user_test1
|
|
verbosity: 2
|
|
|
|
- name: validate results for testcase 1
|
|
assert:
|
|
that:
|
|
- user_test1.results is defined
|
|
- user_test1.results | length == 5
|
|
|
|
- name: validate changed results for testcase 1 (jinja >= 2.6)
|
|
assert:
|
|
that:
|
|
- user_test1.results | map(attribute='changed') | unique | list == [False]
|
|
- user_test1.results | map(attribute='state') | unique | list == ['present']
|
|
when: jinja2_version.stdout is version('2.6', '>=')
|
|
|
|
- name: validate changed results for testcase 1 (jinja < 2.6)
|
|
assert:
|
|
that:
|
|
- "user_test1.results[0] is not changed"
|
|
- "user_test1.results[1] is not changed"
|
|
- "user_test1.results[2] is not changed"
|
|
- "user_test1.results[3] is not changed"
|
|
- "user_test1.results[4] is not changed"
|
|
- "user_test1.results[0]['state'] == 'present'"
|
|
- "user_test1.results[1]['state'] == 'present'"
|
|
- "user_test1.results[2]['state'] == 'present'"
|
|
- "user_test1.results[3]['state'] == 'present'"
|
|
- "user_test1.results[4]['state'] == 'present'"
|
|
when: jinja2_version.stdout is version('2.6', '<')
|
|
|
|
|
|
## user remove
|
|
|
|
- name: try to delete the user
|
|
user:
|
|
name: ansibulluser
|
|
state: absent
|
|
force: true
|
|
register: user_test2
|
|
|
|
- name: make a new list of users
|
|
script: userlist.sh {{ ansible_distribution }}
|
|
register: user_names2
|
|
|
|
- debug:
|
|
var: user_names2
|
|
verbosity: 2
|
|
|
|
- name: validate results for testcase 2
|
|
assert:
|
|
that:
|
|
- '"ansibulluser" not in user_names2.stdout_lines'
|
|
|
|
|
|
- block:
|
|
- name: create non-system user on macOS to test the shell is set to /bin/bash
|
|
user:
|
|
name: macosuser
|
|
register: macosuser_output
|
|
|
|
- name: validate the shell is set to /bin/bash
|
|
assert:
|
|
that:
|
|
- 'macosuser_output.shell == "/bin/bash"'
|
|
|
|
- name: cleanup
|
|
user:
|
|
name: macosuser
|
|
state: absent
|
|
|
|
- name: create system user on macos to test the shell is set to /usr/bin/false
|
|
user:
|
|
name: macosuser
|
|
system: yes
|
|
register: macosuser_output
|
|
|
|
- name: validate the shell is set to /usr/bin/false
|
|
assert:
|
|
that:
|
|
- 'macosuser_output.shell == "/usr/bin/false"'
|
|
|
|
- name: cleanup
|
|
user:
|
|
name: macosuser
|
|
state: absent
|
|
|
|
- name: create non-system user on macos and set the shell to /bin/sh
|
|
user:
|
|
name: macosuser
|
|
shell: /bin/sh
|
|
register: macosuser_output
|
|
|
|
- name: validate the shell is set to /bin/sh
|
|
assert:
|
|
that:
|
|
- 'macosuser_output.shell == "/bin/sh"'
|
|
|
|
- name: cleanup
|
|
user:
|
|
name: macosuser
|
|
state: absent
|
|
when: ansible_distribution == "MacOSX"
|
|
|
|
|
|
## user expires
|
|
# Date is March 3, 2050
|
|
- name: Set user expiration
|
|
user:
|
|
name: ansibulluser
|
|
state: present
|
|
expires: 2529881062
|
|
register: user_test_expires1
|
|
|
|
- name: Set user expiration again to ensure no change is made
|
|
user:
|
|
name: ansibulluser
|
|
state: present
|
|
expires: 2529881062
|
|
register: user_test_expires2
|
|
|
|
- name: Ensure that account with expiration was created and did not change on subsequent run
|
|
assert:
|
|
that:
|
|
- user_test_expires1 is changed
|
|
- user_test_expires2 is not changed
|
|
|
|
- name: Verify expiration date for Linux
|
|
block:
|
|
- name: LINUX | Get expiration date for ansibulluser
|
|
getent:
|
|
database: shadow
|
|
key: ansibulluser
|
|
|
|
- name: LINUX | Ensure proper expiration date was set
|
|
assert:
|
|
that:
|
|
- getent_shadow['ansibulluser'][6] == '29281'
|
|
when: ansible_os_family in ['RedHat', 'Debian', 'Suse']
|
|
|
|
|
|
- name: Verify expiration date for BSD
|
|
block:
|
|
- name: BSD | Get expiration date for ansibulluser
|
|
shell: 'grep ansibulluser /etc/master.passwd | cut -d: -f 7'
|
|
changed_when: no
|
|
register: bsd_account_expiration
|
|
|
|
- name: BSD | Ensure proper expiration date was set
|
|
assert:
|
|
that:
|
|
- bsd_account_expiration.stdout == '2529878400'
|
|
when: ansible_os_family == 'FreeBSD'
|
|
|
|
- name: Change timezone
|
|
timezone:
|
|
name: America/Denver
|
|
register: original_timezone
|
|
|
|
- name: Change system timezone to make sure expiration comparison works properly
|
|
block:
|
|
- name: Create user with expiration again to ensure no change is made in a new timezone
|
|
user:
|
|
name: ansibulluser
|
|
state: present
|
|
expires: 2529881062
|
|
register: user_test_different_tz
|
|
|
|
- name: Ensure that no change was reported
|
|
assert:
|
|
that:
|
|
- user_test_different_tz is not changed
|
|
|
|
always:
|
|
- name: Restore original timezone - {{ original_timezone.diff.before.name }}
|
|
timezone:
|
|
name: "{{ original_timezone.diff.before.name }}"
|
|
|
|
|
|
- name: Unexpire user
|
|
user:
|
|
name: ansibulluser
|
|
state: present
|
|
expires: -1
|
|
register: user_test_expires3
|
|
|
|
- name: Verify un expiration date for Linux
|
|
block:
|
|
- name: LINUX | Get expiration date for ansibulluser
|
|
getent:
|
|
database: shadow
|
|
key: ansibulluser
|
|
|
|
- name: LINUX | Ensure proper expiration date was set
|
|
assert:
|
|
msg: "expiry is supposed to be empty or -1, not {{ getent_shadow['ansibulluser'][6] }}"
|
|
that:
|
|
- not getent_shadow['ansibulluser'][6] or getent_shadow['ansibulluser'][6] | int < 0
|
|
when: ansible_os_family in ['RedHat', 'Debian', 'Suse']
|
|
|
|
- name: Verify un expiration date for linux/BSD
|
|
block:
|
|
- name: Unexpire user again to check for change
|
|
user:
|
|
name: ansibulluser
|
|
state: present
|
|
expires: -1
|
|
register: user_test_expires4
|
|
|
|
- name: Ensure first expiration reported a change and second did not
|
|
assert:
|
|
msg: The second run of the expiration removal task reported a change when it should not
|
|
that:
|
|
- user_test_expires3 is changed
|
|
- user_test_expires4 is not changed
|
|
when: ansible_os_family in ['RedHat', 'Debian', 'Suse', 'FreeBSD']
|
|
|
|
- name: Verify un expiration date for BSD
|
|
block:
|
|
- name: BSD | Get expiration date for ansibulluser
|
|
shell: 'grep ansibulluser /etc/master.passwd | cut -d: -f 7'
|
|
changed_when: no
|
|
register: bsd_account_expiration
|
|
|
|
- name: BSD | Ensure proper expiration date was set
|
|
assert:
|
|
msg: "expiry is supposed to be '0', not {{ bsd_account_expiration.stdout }}"
|
|
that:
|
|
- bsd_account_expiration.stdout == '0'
|
|
when: ansible_os_family == 'FreeBSD'
|
|
|
|
# Test setting no expiration when creating a new account
|
|
# https://github.com/ansible/ansible/issues/44155
|
|
- name: Remove ansibulluser
|
|
user:
|
|
name: ansibulluser
|
|
state: absent
|
|
|
|
- name: Create user account without expiration
|
|
user:
|
|
name: ansibulluser
|
|
state: present
|
|
expires: -1
|
|
register: user_test_create_no_expires_1
|
|
|
|
- name: Verify un expiration date for Linux
|
|
block:
|
|
- name: LINUX | Get expiration date for ansibulluser
|
|
getent:
|
|
database: shadow
|
|
key: ansibulluser
|
|
|
|
- name: LINUX | Ensure proper expiration date was set
|
|
assert:
|
|
msg: "expiry is supposed to be empty or -1, not {{ getent_shadow['ansibulluser'][6] }}"
|
|
that:
|
|
- not getent_shadow['ansibulluser'][6] or getent_shadow['ansibulluser'][6] | int < 0
|
|
when: ansible_os_family in ['RedHat', 'Debian', 'Suse']
|
|
|
|
- name: Verify un expiration date for BSD
|
|
block:
|
|
- name: BSD | Get expiration date for ansibulluser
|
|
shell: 'grep ansibulluser /etc/master.passwd | cut -d: -f 7'
|
|
changed_when: no
|
|
register: bsd_account_expiration
|
|
|
|
- name: BSD | Ensure proper expiration date was set
|
|
assert:
|
|
msg: "expiry is supposed to be '0', not {{ bsd_account_expiration.stdout }}"
|
|
that:
|
|
- bsd_account_expiration.stdout == '0'
|
|
when: ansible_os_family == 'FreeBSD'
|
|
|
|
# Test expiration with a very large negative number. This should have the same
|
|
# result as setting -1.
|
|
- name: Set expiration date using very long negative number
|
|
user:
|
|
name: ansibulluser
|
|
state: present
|
|
expires: -2529881062
|
|
register: user_test_expires5
|
|
|
|
- name: Ensure no change was made
|
|
assert:
|
|
that:
|
|
- user_test_expires5 is not changed
|
|
|
|
- name: Verify un expiration date for Linux
|
|
block:
|
|
- name: LINUX | Get expiration date for ansibulluser
|
|
getent:
|
|
database: shadow
|
|
key: ansibulluser
|
|
|
|
- name: LINUX | Ensure proper expiration date was set
|
|
assert:
|
|
msg: "expiry is supposed to be empty or -1, not {{ getent_shadow['ansibulluser'][6] }}"
|
|
that:
|
|
- not getent_shadow['ansibulluser'][6] or getent_shadow['ansibulluser'][6] | int < 0
|
|
when: ansible_os_family in ['RedHat', 'Debian', 'Suse']
|
|
|
|
- name: Verify un expiration date for BSD
|
|
block:
|
|
- name: BSD | Get expiration date for ansibulluser
|
|
shell: 'grep ansibulluser /etc/master.passwd | cut -d: -f 7'
|
|
changed_when: no
|
|
register: bsd_account_expiration
|
|
|
|
- name: BSD | Ensure proper expiration date was set
|
|
assert:
|
|
msg: "expiry is supposed to be '0', not {{ bsd_account_expiration.stdout }}"
|
|
that:
|
|
- bsd_account_expiration.stdout == '0'
|
|
when: ansible_os_family == 'FreeBSD'
|
|
|
|
|
|
## shadow backup
|
|
- block:
|
|
- name: Create a user to test shadow file backup
|
|
user:
|
|
name: ansibulluser
|
|
state: present
|
|
register: result
|
|
|
|
- name: Find shadow backup files
|
|
find:
|
|
path: /etc
|
|
patterns: 'shadow\..*~$'
|
|
use_regex: yes
|
|
register: shadow_backups
|
|
|
|
- name: Assert that a backup file was created
|
|
assert:
|
|
that:
|
|
- result.bakup
|
|
- shadow_backups.files | map(attribute='path') | list | length > 0
|
|
when: ansible_os_family == 'Solaris'
|
|
|
|
|
|
# Test creating ssh key with passphrase
|
|
- name: Remove ansibulluser
|
|
user:
|
|
name: ansibulluser
|
|
state: absent
|
|
|
|
- name: Create user with ssh key
|
|
user:
|
|
name: ansibulluser
|
|
state: present
|
|
generate_ssh_key: yes
|
|
ssh_key_file: "{{ output_dir }}/test_id_rsa"
|
|
ssh_key_passphrase: secret_passphrase
|
|
|
|
- name: Unlock ssh key
|
|
command: "ssh-keygen -y -f {{ output_dir }}/test_id_rsa -P secret_passphrase"
|
|
register: result
|
|
|
|
- name: Check that ssh key was unlocked successfully
|
|
assert:
|
|
that:
|
|
- result.rc == 0
|
|
|
|
- name: Clean ssh key
|
|
file:
|
|
path: "{{ output_dir }}/test_id_rsa"
|
|
state: absent
|