#!/bin/sh
#< Check /etc/passwd security

# Perfoms a variety of *basic* checks on /etc/passwd, and
# reports its findings

_passwd=/etc/passwd
hline="======================================================================="

clear

echo $hline
echo "passwd.sec - $_passwd file checker"
echo $hline
echo -e "Check http://www.zazzybob.com for latest version\n"

# first check for duplicated UIDs
output=`cut -d':' -f 3 $_passwd | sort | uniq -d`
if [ ! -z "$output" ]; then
   echo $hline
   echo "Warning: Duplicate UIDs found"
   echo $hline
   for userid in $output; do
      _userid=$userid
      _count=`grep "^[^:]*:[^:]*:$userid" $_passwd | wc -l |\
              sed 's/[ \t]//g'`
     
      echo "UID: $_userid (Count: $_count)"
   done
   echo "Entries:"
   for userid in $output; do
      grep "^[^:]*:[^:]*:$userid" $_passwd
      
   done
fi

# awk routine heavily inspired by the old COPS program
awk -F':' -v h=$hline '{
   if ($0 ~ /^[ \t]*$/ )
      { printf( "%s\nWarning: Line %d is blank\n%s\n", h, NR, h ) }
   else
   {
      if ( NF != 7 )
          { printf( "%s\nWarning: Line %d does not have 7 fields:\n%s\n\t%s\n\t(Number of fields: %d)\n", h, NR, h, $0, NF ) }
      if ( $1 !~ /^[A-Za-z0-9]*$/ )
          { printf( "%s\nWarning: Line %d contains non-alphanumeric username\n%s\n\t%s\n", h, NR, h, $1 ) }
      if ( $3 ~ /^0+$/ && $1 != "root" )
          { printf( "%s\nWarning: Line %d, non-root user %s has uid zero\n%s\n\t%s\n", h, NR, $1, h, $0 ) }
      if ( $4 ~ /^0+$/ && $1 != "root" )
          { printf( "%s\nBeware: Line %d, non-root user %s is member of group gid zero\n%s\n\t%s\n", h, NR, $1, h, $0 ) }
   }
}' $_passwd

# veer away from awk
counter=0
while read line
do
   let "counter = $counter + 1"  # pre-increment
   # ignore blank lines
   if [ -z "$line" ]; then
      continue
   fi
   _shell=`echo $line | cut -d':' -f 7`   
   _user=`echo $line | cut -d':' -f 1`
   grep $_shell /etc/shells > /dev/null 2>&1
   if [ "$?" -ne "0" ]; then
      echo $hline
      echo "Beware: Line $counter, user $_user has shell not listed in /etc/shells"
      echo $hline
      echo -e "\t$line"
      echo -e "\tShell: $_shell"
   fi
   _homedir=`echo $line | cut -d':' -f 6`
   if [ ! -d "$_homedir" ]; then
      echo $hline
      echo "Warning: Line $counter, user $_user has non-existant home directory"
      echo $hline
      echo -e "\t$line"
      echo -e "\tHome: $_homedir"
   fi
done < $_passwd

echo -e "\nCheck Complete!\n"

exit 0