From 116948cd1468b8a3e34af8e3671f4089e1f7584c Mon Sep 17 00:00:00 2001 From: Sam Doran Date: Wed, 23 Aug 2023 14:18:57 -0400 Subject: [PATCH] user - set current expiration correctly when no shadow entry exists (#75194) --- .../fragments/71916-user-expires-int.yml | 2 + lib/ansible/modules/user.py | 6 ++- test/integration/targets/user/tasks/main.yml | 1 + .../user/tasks/test_expires_no_shadow.yml | 47 +++++++++++++++++++ 4 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 changelogs/fragments/71916-user-expires-int.yml create mode 100644 test/integration/targets/user/tasks/test_expires_no_shadow.yml diff --git a/changelogs/fragments/71916-user-expires-int.yml b/changelogs/fragments/71916-user-expires-int.yml new file mode 100644 index 00000000000..4530bbcc8f7 --- /dev/null +++ b/changelogs/fragments/71916-user-expires-int.yml @@ -0,0 +1,2 @@ +bugfixes: + - user - set expiration value correctly when unable to retrieve the current value from the system (https://github.com/ansible/ansible/issues/71916) diff --git a/lib/ansible/modules/user.py b/lib/ansible/modules/user.py index cc06c27a6db..bc85c56b647 100644 --- a/lib/ansible/modules/user.py +++ b/lib/ansible/modules/user.py @@ -919,7 +919,8 @@ class User(object): if self.expires is not None: - current_expires = int(self.user_password()[1]) + current_expires = self.user_password()[1] or '0' + current_expires = int(current_expires) if self.expires < time.gmtime(0): if current_expires >= 0: @@ -1562,7 +1563,8 @@ class FreeBsdUser(User): if self.expires is not None: - current_expires = int(self.user_password()[1]) + current_expires = self.user_password()[1] or '0' + current_expires = int(current_expires) # If expiration is negative or zero and the current expiration is greater than zero, disable expiration. # In OpenBSD, setting expiration to zero disables expiration. It does not expire the account. diff --git a/test/integration/targets/user/tasks/main.yml b/test/integration/targets/user/tasks/main.yml index 23f321679d6..be4c4d6fdc4 100644 --- a/test/integration/targets/user/tasks/main.yml +++ b/test/integration/targets/user/tasks/main.yml @@ -31,6 +31,7 @@ - import_tasks: test_expires.yml - import_tasks: test_expires_new_account.yml - import_tasks: test_expires_new_account_epoch_negative.yml +- import_tasks: test_expires_no_shadow.yml - import_tasks: test_expires_min_max.yml - import_tasks: test_expires_warn.yml - import_tasks: test_shadow_backup.yml diff --git a/test/integration/targets/user/tasks/test_expires_no_shadow.yml b/test/integration/targets/user/tasks/test_expires_no_shadow.yml new file mode 100644 index 00000000000..4629c6fb07b --- /dev/null +++ b/test/integration/targets/user/tasks/test_expires_no_shadow.yml @@ -0,0 +1,47 @@ +# https://github.com/ansible/ansible/issues/71916 +- name: Test setting expiration for a user account that does not have an /etc/shadow entry + when: ansible_facts.os_family in ['RedHat', 'Debian', 'Suse'] + block: + - name: Remove ansibulluser + user: + name: ansibulluser + state: absent + remove: yes + + - name: Create user account entry in /etc/passwd + lineinfile: + path: /etc/passwd + line: "ansibulluser::575:575::/home/dummy:/bin/bash" + regexp: "^ansibulluser.*" + state: present + + - name: Create user with negative expiration + user: + name: ansibulluser + uid: 575 + expires: -1 + register: user_test_expires_no_shadow_1 + + - name: Create user with negative expiration again + user: + name: ansibulluser + uid: 575 + expires: -1 + register: user_test_expires_no_shadow_2 + + - name: Ensure changes were made appropriately + assert: + that: + - user_test_expires_no_shadow_1 is changed + - user_test_expires_no_shadow_2 is not changed + + - name: 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