Need script to monitor change in /etc/passwd

Hi All,

From Audit point of view, I need to add a script to my production Solaris servers. That should be able to mail me, if any user is added or removed.
That means, I should get a mail, what user is deleted or added in /etc/passwd, i.e. if there is a change in this file, I should be notified via mail.
I am not expert in scripting. Please help me in best possible way to implement.

Regards
Abhishek

Three steps, all run as root:

cd
cksum /etc/passwd | awk '{print $1}' > passwd.cksum
chmod 700 passwd.cksum

Create this script:

#!/bin/ksh
cd
value=$(cksum /etc/passwd | awk '{print $1}' )
value2=$( < passwd.cksum)
[ "$value2" = "$value" ] && exit  # everything is okay
/usr/bin echo "/etc/passwd changed" | /usr/bin/mailx -s '/etc/passwd alert'     me@mycompany.com
echo "$value2" > passwd.cksum   # prevent redundant error messages

Don't forget to test it first, and chmod +x your script.

Have it run every 10 minutes-- enter with crontab -e, which should put you in vi:

0,10,20,30,40,50 * * * *  /path/to/the/script/above/myscript.sh 2> /path/to/log

You may be able to do this without scripting.

Are you using a network management system that receives SNMP traps?

We use HP OM on a few systems and we generate a message (which can be e-mailed) when there is a change to /etc/passwd or /etc/shadow.

This script will also mail the names of deleted/added users, but does not catch other changes:

#!/bin/bash
ME=myusername@mymailhost
ulistorig=( `cut -d: -f1 /etc/passwd | sort` )
dateorig=`date`
while true; do
  ulistdel=""
  ulistadd=""
  sleep 10
  ulistcurr=( `cut -d: -f1 /etc/passwd | sort` )
  i=0
  j=0
  while [[ $i -lt ${#ulistorig[@]} && $j -lt ${#ulistcurr[@]} ]]; do
    if [[ "${ulistorig}" == "${ulistcurr[j]}" ]]; then
      i=$((i+1))
      j=$((j+1))
    elif [[ "${ulistorig}" < "${ulistcurr[j]}" ]]; then
      ulistdel="$ulistdel ${ulistorig}"
      i=$((i+1))
    else
      ulistadd="$ulistadd ${ulistcurr[j]}"
      j=$((j+1))
    fi
  done
  while [[ $i -lt ${#ulistorig[@]} ]]; do
    ulistdel="$ulistdel ${ulistorig}"
    i=$((i+1))
  done
  while [[ $j -lt ${#ulistcurr[@]} ]]; do
    ulistadd="$ulistdel ${ulistorig}"
    i=$((i+1))
  done
  if [[ -n "$ulistdel" || -n "$ulistadd" ]]; then
    mailx -s "file changed" $ME <<EOF
changes in file since $dateorig:
  deleted users: $ulistdel
  added users: $ulistadd
EOF
  # echo changes to stdout, too
    cat <<EOF
changes in file since $dateorig:
  deleted users: $ulistdel
  added users: $ulistadd
EOF
    ulistorig=( `echo ${ulistcurr[@]}` )
    dateorig=`date`
  else
    # optional no changes message (for debugging/testing)
    echo "no changes in file since $dateorig"
  fi
done

Hi HFREYER,

This script works well. Thanks a lot for providing it. But only issue is, if I run the script, it will keep on going, untill we do Control+C.
I want to configure it on mutiple servers.

ShawnD41 :- We are not using Network Management System

jim mcnamara :- When I run this script, it was not sending mail. Its logs saying as below -
/root/myscript.sh[6]: /usr/bin: cannot execute
/root/myscript.sh[6]: /usr/bin: cannot execute

Regards

Hi solaris_1977,
how do you wish to control the termination of the script ? kill ? run for some period ?
To run it permanently on a remote server, you may start it like this:

nohup /path/to/script &

Then it will continue running after logout from the remote server.

Hi jim mcnamara,
I don't know why you get the "cannot execute" message. You my try run the mailx separately in order to check if it is correctly installed or your configuration is correct, respectively:

echo hello | mailx -s test myusername@mymailhost

Hi hfreyer,

If you run it in nohup, it will keep on running, which will eat CPU time as well.

For jim mcnamara's script, it do not give me deleted or added user-name in my mail.

I wanted something like, script should check once a day (may be through cron), which user is added or deleted from original /etc/passwd file. May be I can get a mail like
"user123 deleted from /etc/passwd: Server456"
"user321 added to /etc/passwd: Server456"

Regards

Actually if you used only the command line progs `useradd`, `usermod` or `userdel`, via a shell script and using the return values, then that would be all you need.
useradd(8) - Linux man page

However for verification, apart from comparing the xcheksum, you might like put the information in an array and compare the contents.

OK

Don't worry about CPU time. The script will be >99% of the time in "sleep",
which won't consume CPU time. Still have to think about the other point.