Showing posts with label Automation. Show all posts
Showing posts with label Automation. Show all posts

Thursday, 13 June 2013

Unix / Solaris Password Expiration Automated email notification

I have been entrusted with setting up a mail alert system for user password expiration. The user should automatically get intimated through mail a few days before his password expiration date. I wrote a small script by taking help from www.unix.com and other forums.
Below is the script for checking the age of the password and alert the user if password is going to expire in next 15 days.

Script Name  :- /usr/bin/solchage

---script start here----

#!/usr/bin/bash
umask 0022
PATH=/usr/bin:/usr/sbin
SHADOW=/etc/shadow
DSHADOW=/etc/shadow.dummy
USER=$1


# Copy the contents of /etc/shadow to a dummy file and make sure the entries for system  
# users are not there in the dummy file. Also replace the encrypted password field with      
# *LK* to make sure passwords are not visible or cannot be copied by someone else.

cat ${SHADOW} | egrep -v "root|daemon|etc" | awk -F: '{print $1,"*LK*",$3,$4,$5,$6,$7,$8}' | sed 's/ /:/g' > ${DSHADOW}

PASSWDFILE=/etc/passwd

# Specify the mail domain of your company here.
DOMAIN=xyz
.com

# The next line extracts the users email id from GECOS field of /etc/passwd file. So as a pre # requisite to running this script, you must enter the email id of the user, without the            # domain name, in GECOS field as i have assumed here. Let me know if you can think of a
# more elegant way of extracting this information.

EMAIL=`grep ^${USER} ${PASSWDFILE} | awk -F: '{print $5}'`

# Save the message in a file.
FILE=/tmp/msg.$$


# Set the password policy here, i.e the number of days after which user must change              # password.
PWPOLICY=90

# Set the warning period here.
WARN=15


# Calculate the number of seconds elapsed since Jan 1 ,1970 i.e Unix epoch.

EPOCH=`perl -e 'print time;'`


# Convert the number of seconds into days.

DAYSEPOCH=`expr ${EPOCH} / 86400`


# Calculate the number of days since password was changed for the last time for a particular # user. This info can be extracted from 3rd field of /etc/passwd file. This is expressed as
# the number of days between January 1,  1970, and  the  date  that  the  password was last
# modified.


LASTCHG=`grep ^${USER} ${DSHADOW} | awk -F: '{print $3}'`



# Subtract the above value from the number of days since epoch to arrive at the number    #  of days since last password change. 

PASSWDCHANGE=`expr ${DAYSEPOCH} - ${LASTCHG}`


EXPIRED=`expr ${PWPOLICY} - ${PASSWDCHANGE}`


if [ "${EXPIRED}" -lt "${WARN}" ]; then

cat > ${FILE} <<EOF
Dear ${USER},

Your password will expire in ${EXPIRED} days. Please change it as soon as possible.
EOF


mailx -s "Password expiring soon." ${EMAIL}@${DOMAIN} < ${FILE}

fi--- script end here---

To run the above main script, you have to run another small script which i produce below.
Copy the above script and place it under /usr/bin and name it solchage. Ofcourse you can give it another name, its upto you but make corresponding changes in below script as well if you do so.

Lets name the second script as /var/pwexpire.sh. So put this script in crontab for execution once everyday. It will run for all users, and send them a mail if their password is going to expire within 15 days.

Script Name:- /var/pwexpire.sh

--- script begin here ---


cat /etc/passwd | egrep -v "root|daemon|etc|sys|adm|lp|uucp|nuucp|smmsp|listen|gdm|webservd|postgres|svctag|nobody|noaccess|nobody4" | awk -F: '{print $1}' | egrep -v "bin" | xargs -I {} /usr/bin/solchage {}

---script end here---


What the above script does ? Let us examine step by step.

1) It reads /etc/passwd file and cuts out system users from the list
2) Then prints the remaining usernames using awk and removes all other entries except first filed from the output.
3) Then xargs executes our script /usr/bin/solchage one by one for every listed user. This is required because the our script takes username as argument ( see USER=$1 above ) and runs for that particular user.

You will have to give execute permissions to both the scripts.

Friday, 17 May 2013

How to delete all files in a directory except the last 3 files ?

The trick here is as follows
1) Do the listing sorted by file modification time.
2) Use tail or head to cut out the 3 latest files and
3) Then do ’ rm’ on all files that remain.

Suppose you have to delete all files except the latest 3 from the folder /var/path_to_folder.
So the below command will accomplish your task.

# cd /var/path_to_folder && /usr/xpg4/bin/ls -t /var/path_to_folder | tail -n +3 | xargs rm –r


The above command lists all files in the directory sorted as per last modification time ( you may use –u switch to ls command to sort according to last access time instead of last modification time, see man page for ls for details), then tail command takes the listing as its input and cuts out the 3 files from top. Pay attention to the + sign before 3 , if i had used -3 in place +3 the result would have been something entirely different. The –n +3 operates on top of the listed output and removes the top 3 lines from the output. On the other hand , -n -3 would have operated on last 3 lines of the output and instead of removing those lines it would have printed out those lines to the terminal. The meanings and usage of + and - are very different. The usage also changes dramatically if i had used head instead of tail to cut out the 3 lines. Take care of this and before going on to our next step with "xargs and rm" command, be sure of the output you are getting here , as you would end up deleting last 3 files accidently if you misinterpreted the above.

Why i used xargs ? Because xargs constructs argument list and invokes the desired utility ( in our case ‘rm’ ) sequentially on each argument from the list. Our output after doing the tail is a list of files, one per line , as is usual when doing listing. The "rm" command wont act on these one per line arguments if supplied as it is to a single rm invocation. So xargs helps us here by invoking rm once for each filename.