[stable-2.7] User module - allow bang and exclamation in password field without warning (#46498)

* Allow bang and exclamation without warning

Allow the password field to be ! or * without warning when using this feature to create accounts that are locked.

Add documentation  and tests to cover this.

* Use set() rather than braces for Python 2.6
(cherry picked from commit 066af3b6ca)

Co-authored-by: Sam Doran <sdoran@redhat.com>
This commit is contained in:
Sam Doran 2018-11-05 16:35:10 -05:00 committed by Toshio Kuratomi
parent 12271999e2
commit bab062d639
3 changed files with 52 additions and 22 deletions

View file

@ -0,0 +1,2 @@
bugfixes:
- user - remove warning when creating a disabled account with '!' or '*' in the password field (https://github.com/ansible/ansible/issues/46334)

View file

@ -98,6 +98,7 @@ options:
description:
- Optionally set the user's password to this crypted value.
- On macOS systems, this value has to be cleartext. Beware of security issues.
- To create a disabled account or Linux systems, set this to C('!') or C('*').
- See U(https://docs.ansible.com/ansible/faq.html#how-do-i-generate-crypted-passwords-for-the-user-module)
for details on various ways to generate these password values.
state:
@ -448,32 +449,37 @@ class User(object):
self.ssh_file = os.path.join('.ssh', 'id_%s' % self.ssh_type)
def check_password_encrypted(self):
# darwin need cleartext password, so no check
# Darwin needs cleartext password, so skip validation
if self.module.params['password'] and self.platform != 'Darwin':
maybe_invalid = False
# : for delimiter, * for disable user, ! for lock user
# these characters are invalid in the password
if any(char in self.module.params['password'] for char in ':*!'):
maybe_invalid = True
if '$' not in self.module.params['password']:
maybe_invalid = True
# Allow setting the password to * or ! in order to disable the account
if self.module.params['password'] in set(['*', '!']):
maybe_invalid = False
else:
fields = self.module.params['password'].split("$")
if len(fields) >= 3:
# contains character outside the crypto constraint
if bool(_HASH_RE.search(fields[-1])):
maybe_invalid = True
# md5
if fields[1] == '1' and len(fields[-1]) != 22:
maybe_invalid = True
# sha256
if fields[1] == '5' and len(fields[-1]) != 43:
maybe_invalid = True
# sha512
if fields[1] == '6' and len(fields[-1]) != 86:
maybe_invalid = True
else:
# : for delimiter, * for disable user, ! for lock user
# these characters are invalid in the password
if any(char in self.module.params['password'] for char in ':*!'):
maybe_invalid = True
if '$' not in self.module.params['password']:
maybe_invalid = True
else:
fields = self.module.params['password'].split("$")
if len(fields) >= 3:
# contains character outside the crypto constraint
if bool(_HASH_RE.search(fields[-1])):
maybe_invalid = True
# md5
if fields[1] == '1' and len(fields[-1]) != 22:
maybe_invalid = True
# sha256
if fields[1] == '5' and len(fields[-1]) != 43:
maybe_invalid = True
# sha512
if fields[1] == '6' and len(fields[-1]) != 86:
maybe_invalid = True
else:
maybe_invalid = True
if maybe_invalid:
self.module.warn("The input password appears not to have been hashed. "
"The 'password' argument must be encrypted for this module to work properly.")

View file

@ -101,6 +101,24 @@
- name: there should be a warning complains about the character set of password
assert:
that: "'warnings' in test_user_encrypt2"
- name: change password to '!'
user:
name: ansibulluser
password: '!'
register: test_user_encrypt3
- name: change password to '*'
user:
name: ansibulluser
password: '*'
register: test_user_encrypt4
- name: there should be no warnings when setting the password to '!' and '*'
assert:
that:
- "'warnings' not in test_user_encrypt3"
- "'warnings' not in test_user_encrypt4"
when: ansible_system != 'Darwin'
@ -314,6 +332,8 @@
timezone:
name: America/Denver
register: original_timezone
tags:
- timezone
- name: Change system timezone to make sure expiration comparison works properly
block:
@ -333,6 +353,8 @@
- name: Restore original timezone - {{ original_timezone.diff.before.name }}
timezone:
name: "{{ original_timezone.diff.before.name }}"
tags:
- timezone
- name: Unexpire user