Posts Tagged ‘expiring’

How to set up Notify by email expiring local UNIX user accounts on Linux / BSD with a bash script

Thursday, August 24th, 2023


If you have already configured Linux Local User Accounts Password Security policies Hardening – Set Password expiry, password quality, limit repatead access attempts, add directionary check, increase logged history command size and you want your configured local user accounts on a Linux / UNIX / BSD system to not expire before the user is reminded that it will be of his benefit to change his password on time, not to completely loose account to his account, then you might use a small script that is just checking the upcoming expiry for a predefined users and emails in an array with lslogins command like you will learn in this article.

The script below is written by a colleague Lachezar Pramatarov (Credit for the script goes to him) in order to solve this annoying expire problem, that we had all the time as me and colleagues often ended up with expired accounts and had to bother to ask for the password reset and even sometimes clearance of account locks. Hopefully this little script will help some other unix legacy admin systems to get rid of the account expire problem.

For the script to work you will need to have a properly configured SMTP (Mail server) with or without a relay to be able to send to the script predefined email addresses that will get notified. 

Here is example of a user whose account is about to expire in a couple of days and who will benefit of getting the Alert that he should hurry up to change his password until it is too late 🙂

[root@linux ~]# date
Thu Aug 24 17:28:18 CEST 2023

[root@server~]# chage -l lachezar
Last password change                                    : May 30, 2023
Password expires                                        : Aug 28, 2023
Password inactive                                       : never
Account expires                                         : never
Minimum number of days between password change          : 0
Maximum number of days between password change          : 90
Number of days of warning before password expires       : 14

Here is the that will report the user

# vim  /usr/local/bin/


# This script will send warning emails for password expiration 
# on the participants in the following list:
# 20, 15, 10 and 0-7 days before expiration
# ! Script sends expiry Alert only if day is Wednesday – if (( $(date +%u)==3 )); !

# email to send if expiring
# the users that are admins added to belong to this group
notify_email_header_customer_name='Customer Name';

declare -A mails=(
# list below accounts which will receive account expiry emails

# syntax to define uid / email
# [“account_name_from_etc_passwd”]="real_email_addr@fqdn";

#    [“abc”]=""
#    [“cba”]=""
#    [“acct7”]=""
#    [“acct8”]=""
#    [“acct9”]=""

declare -A days

while IFS="=" read -r person day ; do
done < <(lslogins –noheadings -o USER,GROUP,PWD-CHANGE,PWD-WARN,PWD-MIN,PWD-MAX,PWD-EXPIR,LAST-LOGIN,FAILED-LOGIN  –time-format=iso | awk '{print "echo "$1" "$2" "$3" $(((($(date +%s -d \""$3"+90 days\")-$(date +%s)))/86400)) "$5}' | /bin/bash | grep -E " $admin_group " | awk '{print $1 "=" $4}')

#echo ${days[laprext]}
for person in "${!mails[@]}"; do
     echo "$person ${days[$person]}";

#     echo $tmp
# each person will receive mails only if 20th days / 15th days / 10th days remaining till expiry or if less than 7 days receive alert mail every day

     if  (( (${tmp}==20) || (${tmp}==15) || (${tmp}==10) || ((${tmp}>=0) && (${tmp}<=7)) )); 
         echo "Hello, your password for $(hostname -s) will expire after ${days[$person]} days.” | mail -s “$notify_email_header_customer_name $(hostname -s) server password expiration”  -r passwd_expire ${mails[$person]};
     elif ((${tmp}<0));
#          echo "The password for $person on $(hostname -s) has EXPIRED before{days[$person]} days. Please take an action ASAP.” | mail -s “EXPIRED password of  $person on $(hostname -s)”  -r EXPIRED ${mails[$person]};

# ==3 meaning day is Wednesday the day on which OnCall Person changes

        if (( $(date +%u)==3 ));
             echo "The password for $person on $(hostname -s) has EXPIRED. Please take an action." | mail -s "EXPIRED password of  $person on $(hostname -s)"  -r EXPIRED $alert_email;


To make the script notify about expiring user accounts, place the script under some directory lets say /usr/local/bin/ and make it executable and configure a cron job that will schedule it to run every now and then.

# cat /etc/cron.d/passwd_expire_cron

# /etc/cron.d/pwd_expire
# Check password expiration for users
# 2023-01-16 LPR
02 06 * * * root /usr/local/bin/ >/dev/null

Script will execute every day morning 06:02 by the cron job and if the day is wednesday (3rd day of week) it will send warning emails for password expiration if 20, 15, 10 days are left before account expires if only 7 days are left until the password of user acct expires, the script will start sending the Alarm every single day for 7th, 6th … 0 day until pwd expires.

If you don't have an expiring accounts and you want to force a specific account to have a expire date you can do it with:

# chage -E 2023-08-30 someuser

Or set it for new created system users with:

# useradd -e 2023-08-30 username

That's it the script will notify you on User PWD expiry.

If you need to for example set a single account to expire 90 days from now (3 months) that is a kind of standard password expiry policy admins use, do it with:

# date -d "90 days" +"%Y-%m-%d"

Ideas for script improvement

The downside of the script if you have too many local user accounts is you have to hardcode into it the username and user email_address attached to and that would be tedios task if you have 100+ accounts. 

However it is pretty easy if you already have a multitude of accounts in /etc/passwd that are from UID range to loop over them in a small shell loop and build new array from it. Of course for a solution like this to work you will have to have defined as user data as GECOS with command like chfn.

[georgi@server ~]$ chfn
Changing finger information for test.
Name [test]: 
Office []:
Office Phone []: 
Home Phone []: 


[root@server test]# finger georgi
Login: georgi                       Name: georgi
Directory: /home/georgi                   Shell: /bin/bash
On since чт авг 24 17:41 (EEST) on :0 from :0 (messages off)
On since чт авг 24 17:43 (EEST) on pts/0 from :0
   2 seconds idle
On since чт авг 24 17:44 (EEST) on pts/1 from :0
   49 minutes 30 seconds idle
On since чт авг 24 18:04 (EEST) on pts/2 from :0
   32 minutes 42 seconds idle
New mail received пт окт 30 17:24 2020 (EET)
     Unread since пт окт 30 17:13 2020 (EET)
No Plan.

Then it should be relatively easy to add the GECOS for multilpe accounts if you have them predefined in a text file for each existing local user account.

Hope this script will help some sysadmin out there, many thanks to Lachezar for allowing me to share the script here.
Enjoy ! 🙂

IBM Tivoli (Spectrum Protect) update self-signed client expiring SSL certificates

Wednesday, March 17th, 2021


Say you're using Tivoli TSM to manage your backups for tsm (if you don't know what is IBM TSM (Spectrum Protect) Backup solution check my previous article on how to use IBM Tivoli to list configured, scheduled, how to do restore backups with dsmc console client.

And you follow below steps to enable SSL communication with a CA-signed certificate between Spectrum Protect client and server:

E.g. you have to

  • Obtained the CA root certificate.
  • Configure the clients. To use SSL, each client must import the self-signed server certificate.

Used the GSKit command-line utility (gsk8capicmd for 32-bit clients or gsk8capicmd_64 for 64-bit clients) to import the certificate.


1. The problem

This self-signed certificates has expire date which after some time might have expire date coming. If your environment has something like PCI security standards enabled and you do a Quarterly security scans with something like QualysGuard (Qaulys vulnerability management tool). 

In the case of Qualys scans you may receive GSK messages in dsmerro.log if the certificate is expiring:


03/04/2021 14:35:07 ANS9959W IBM Spectrum Protect acceptor received a non-critical network error 88, IBM Spectrum Protect return code : -50.

03/05/2021 13:04:59 ANS1579E GSKit function gsk_secure_soc_init failed with 414: GSK_ERROR_BAD_CERT

03/05/2021 13:04:59 TCP/IP received rc 88 trying to accept connection from server.

03/05/2021 13:04:59 ANS9959W IBM Spectrum Protect acceptor received a non-critical network error 88, IBM Spectrum Protect return code : -50.


2. To check the situation on the host with TSM self-signed expiry


2.1  First get the FQDN and certificate name

[root@redhat: ~ ]# FQDN=$(hostname –fqdn |tr '[:lower:]’ ‘[:upper:]');


[root@redhat: ~ ]# echo "FQDN to be used is: $FQDN. Please be careful it is correct (if machine has wrong FQDN) you might have issues";

[root@redhat: ~ ]# gsk8capicmd_64 -cert -list -db /etc/adsm/Nodes/$FQDN/spclicert.kdb -stashed

The gsk8capicmd_64 is IBM's tool to view and manage SSL certificates it is perhaps a C written binary that has a compiled patched version of a normal openssl tool. Using it is the ibm recommended way to manage Tivoli certificates.

2.2  Get details using -label=CERTNAME and check for expiration date


[root@redhat: ~ ]# gsk8capicmd_64 -cert -details -label $FQDN -db /etc/adsm/Nodes/$FQDN/spclicert.kdb -stashed

Certificates found
* default, – personal, ! trusted, # secret key


3. To update the certificates


3.1 Copy the old certificates for backup

As usual do a backup in case if something goes wrong and you need to restore

[root@redhat: ~ ]# mkdir /root/certbck-tsm_$(date +"%b-%d-%Y")/

[root@redhat: ~ ]# cp -rpv /etc/adsm/Nodes/$FQDN/spclicert* /root/certbck-tsm_$(date +"%b-%d-%Y")/


3.2 Stop the dsmcad backup service

[root@redhat: ~ ]# systemctl stop dsmcad

Double check the service is stopped by checking for any remain dsm processes

[root@redhat: ~ ]# ps axf | grep dsm

3.3 Remove the expiring certificates from host

[root@redhat: ~ ]# rm -v /etc/adsm/Nodes/$FQDN/spclicert*


3.4 Generate new certificates with dsmc client

[root@redhat: ~ ]# dsmc query session -optfile="/opt/tivoli/tsm/client/ba/bin/dsm.opt"


3.5 Check if all is generated as expected

[root@redhat: ~ ]# ls -l  /etc/adsm/Nodes/$FQDN/spclicert*

3.6 Start the backup service

[root@redhat: ~ ]# systemctl start dsmcad

3.7  Check  /var/tsm/dsmwebcl.log for the port number of webclient

 [root@redhat: ~ ]# cat /var/tsm/dsmwebcl.log

03/16/2021 13:31:41 (dsmcad) ————————————————————
03/16/2021 13:31:41 (dsmcad) Command will be executed in 11 hours and 50 minutes.
03/16/2021 15:56:01 (dsmcad) ANS9959W IBM Spectrum Protect acceptor received a non-critical network error 88, IBM Spectrum Protect return code : -50.
03/17/2021 01:21:41 (dsmcad) Executing scheduled command now.
03/17/2021 01:22:53 (dsmcad) Next operation scheduled:
03/17/2021 01:22:53 (dsmcad) ————————————————————
03/17/2021 01:22:53 (dsmcad) Schedule Name:         0120_SCHED_P
03/17/2021 01:22:53 (dsmcad) Action:                Incremental
03/17/2021 01:22:53 (dsmcad) Objects:
03/17/2021 01:22:53 (dsmcad) Options:               -subdir=yes
03/17/2021 01:22:53 (dsmcad) Server Window Start:   01:20:00 on 03/18/2021
03/17/2021 01:22:53 (dsmcad) ————————————————————
03/17/2021 01:22:53 (dsmcad) Command will be executed in 12 hours.
03/17/2021 13:22:53 (dsmcad) Executing scheduled command now.
03/17/2021 13:22:54 (dsmcad) Next operation scheduled:
03/17/2021 13:22:54 (dsmcad) ————————————————————
03/17/2021 13:22:54 (dsmcad) Schedule Name:         0120_SCHED_P
03/17/2021 13:22:54 (dsmcad) Action:                Incremental
03/17/2021 13:22:54 (dsmcad) Objects:
03/17/2021 13:22:54 (dsmcad) Options:               -subdir=yes
03/17/2021 13:22:54 (dsmcad) Server Window Start:   01:20:00 on 03/18/2021
03/17/2021 13:22:54 (dsmcad) ————————————————————

 [root@redhat: ~ ]# grep -i port /var/tsm/dsmwebcl.log
03/11/2021 16:59:19 (dsmcad) ANS3000I TCP/IP communications available on port 37506.
03/12/2021 11:35:21 (dsmcad) ANS3000I TCP/IP communications available on port 40510.
03/12/2021 14:53:03 (dsmcad) ANS3000I TCP/IP communications available on port 45005.


3.8  You can check the certificate expiery mask yourself as qualys scanner and check the new certificate 

[root@redhat: ~ ]# dsmc_port=$(netstat -tulpan|grep -i dsm|awk '{ print $4 }'|cut -d":" -f2);
[root@redhat: ~ ]# echo $dsmc_port

[root@redhat: ~ ]# openssl s_client -servername -connect$dsmc_port |  openssl x509 -noout -dates

notBefore=Mar  6 14:09:55 2021 GMT
notAfter=Mar  7 14:09:55 2022 GMT

Hopefully your expiry date is fine that means you're done, you can place the steps in a single script to save time, if you have to run it in a year time.