0

In a RHEL 7.9 environment with Ansible 2.9.27 and Python 2.7.5, I like to find out

  • How old are the password for the local root account in days?
  • How many days have passed since the last password change?

Whereby it is possible to get the date of the last password change via

sudo chage -l root
Last password change                                    : Jan 01, 1970
...
  • How to calculate the difference between the last change date and today in Ansible?
U880D
  • 1,146

2 Answers2

2

RHEL should have a working getent, so you can get the password age data from there. It's the third field, as a number of days from 1970. Today's day number can be found from the current time in seconds since the epoch divided by 86400 and truncated. (Well, give or take your time zone offset, maybe. I'm not sure if the shadow tools store the day number according to the local timezone, or according to UTC.)

# user=ilkkachu
# age=$(( $(date +%s) / 86400 - $(getent -- shadow "$user" |cut -d: -f3) ))
# printf "age of user %s's password is %d days\n" "$user" "$age"
age of user ilkkachu's password is 1444 days

You'll likely need to be root so that getent can get the required information, though. (That would be true for data in /etc/shadow, but if the data is in e.g. LDAP, it could depend on the configuration.)

Of course allowing someone to run getent as root (e.g. via sudo) would also allow them to see the password hash, which they don't need, and which would be more than just chage -l let them know. To prevent that, or at least make it harder, you could create a script that runs that getent | cut pipeline and only allow them permission to run that.

ilkkachu
  • 138,973
0

After some research I've found that the difference between the current time in seconds and the seconds since a date can be just subtracted in the below shown way. After that it is only necessary to make days out of seconds by dividing.

  - name: Gather root password age in days
    shell:
      cmd: echo $(( ($(date +%s) - $(date +%s -d "$(chage -l root | head -1 | cut -d ':' -f 2)")) / 86400 ))
    check_mode: false
    changed_when: false
    failed_when: false
    register: result
  • name: Show result debug: msg: "{{ result.stdout | int }}"

Thanks to

Further Steps

If it comes to non-local account from LDAP, much more work will be necessary.

U880D
  • 1,146