diff options
author | Sam Doran <sdoran@redhat.com> | 2019-04-22 15:24:10 -0400 |
---|---|---|
committer | Toshio Kuratomi <a.badger@gmail.com> | 2019-04-24 14:45:52 -0600 |
commit | 76f6d21ff3e7bb5118cb078b6924905ce012e9e6 (patch) | |
tree | b72682451b3e9013645d71a10d15a2a239010381 /lib | |
parent | 0cfbc1feb888e99d62ea5655f19bdeced39ee3d4 (diff) | |
download | ansible-76f6d21ff3e7bb5118cb078b6924905ce012e9e6.tar.gz |
[stable-2.8] User - Fix shadow file parsing on AIX (#55230)
Implement a new method for shadow file parsing so it can be subclassed.
(cherry picked from commit f27eccabbd)
Co-authored-by: Sam Doran <sdoran@redhat.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/ansible/modules/system/user.py | 65 |
1 files changed, 58 insertions, 7 deletions
diff --git a/lib/ansible/modules/system/user.py b/lib/ansible/modules/system/user.py index 31757389a0..cc1ab81190 100644 --- a/lib/ansible/modules/system/user.py +++ b/lib/ansible/modules/system/user.py @@ -907,13 +907,19 @@ class User(object): if not self.user_exists(): return passwd, expires elif self.SHADOWFILE: - # Read shadow file for user's encrypted password string - if os.path.exists(self.SHADOWFILE) and os.access(self.SHADOWFILE, os.R_OK): - with open(self.SHADOWFILE, 'r') as f: - for line in f: - if line.startswith('%s:' % self.name): - passwd = line.split(':')[1] - expires = line.split(':')[self.SHADOWFILE_EXPIRE_INDEX] or -1 + passwd, expires = self.parse_shadow_file() + + return passwd, expires + + def parse_shadow_file(self): + passwd = '' + expires = '' + if os.path.exists(self.SHADOWFILE) and os.access(self.SHADOWFILE, os.R_OK): + with open(self.SHADOWFILE, 'r') as f: + for line in f: + if line.startswith('%s:' % self.name): + passwd = line.split(':')[1] + expires = line.split(':')[self.SHADOWFILE_EXPIRE_INDEX] or -1 return passwd, expires def get_ssh_key_path(self): @@ -2326,6 +2332,7 @@ class AIX(User): - create_user() - remove_user() - modify_user() + - parse_shadow_file() """ platform = 'AIX' @@ -2467,6 +2474,50 @@ class AIX(User): else: return (rc2, out + out2, err + err2) + def parse_shadow_file(self): + """Example AIX shadowfile data: + nobody: + password = * + + operator1: + password = {ssha512}06$xxxxxxxxxxxx.... + lastupdate = 1549558094 + + test1: + password = * + lastupdate = 1553695126 + + """ + + b_name = to_bytes(self.name) + if os.path.exists(self.SHADOWFILE) and os.access(self.SHADOWFILE, os.R_OK): + with open(self.SHADOWFILE, 'rb') as bf: + b_lines = bf.readlines() + + b_passwd_line = b'' + b_expires_line = b'' + for index, b_line in enumerate(b_lines): + # Get password and lastupdate lines which come after the username + if b_line.startswith(b'%s:' % b_name): + b_passwd_line = b_lines[index + 1] + b_expires_line = b_lines[index + 2] + break + + # Sanity check the lines because sometimes both are not present + if b' = ' in b_passwd_line: + b_passwd = b_passwd_line.split(b' = ', 1)[-1].strip() + else: + b_passwd = b'' + + if b' = ' in b_expires_line: + b_expires = b_expires_line.split(b' = ', 1)[-1].strip() + else: + b_expires = b'' + + passwd = to_native(b_passwd) + expires = to_native(b_expires) or -1 + return passwd, expires + class HPUX(User): """ |