#! /bin/sh

# Question 6, shell programming assignment, 2003.

prog=$(basename $0)
usage() {
   echo "Usage: $prog [-v] [-d directory]"
   echo -- "-v verbose mode (show all SUID, SGID files)"
   echo "Default: only show SUID, SGID files where permission or ownership"
   echo "does not match original installed state."
   echo -- "-d directory: examine files below directory instead of current dir."
   exit 1
}

unset START_DIRECTORY
VERBOSE=0
while getopts ":vd:" opt
do
    case $opt in
        v) VERBOSE=1   ;;
        d) START_DIRECTORY=$OPTARG ;;
        *) usage       ;;
    esac
done

UG_TMPFILE=$(mktemp /tmp/${prog}.XXXXXX)   || exit 1
U_TMPFILE=$(mktemp /tmp/${prog}.XXXXXX)    || exit 1
G_TMPFILE=$(mktemp /tmp/${prog}.XXXXXX)    || exit 1
RPM_TMPFILE=$(mktemp /tmp/${prog}.XXXXXX)  || exit 1
trap "rm $UG_TMPFILE $U_TMPFILE $G_TMPFILE $RPM_TMPFILE" \
    HUP INT QUIT PIPE ALRM TERM EXIT

if [ "$START_DIRECTORY" ]; then
    cd "$START_DIRECTORY" > /dev/null 2>&1 \
    || { echo "Cannot cd to $START_DIRECTORY"; exit 1; }
fi

find $PWD -path '/proc' -prune -o \
          -type f \( -perm -6000 -fprintf ${UG_TMPFILE} "%m\t%u\t%g\t%p\n" -o \
                     -perm -4000 -fprintf ${U_TMPFILE}  "%m\t%u\t%g\t%p\n" -o \
                     -perm -2000 -fprintf ${G_TMPFILE}  "%m\t%u\t%g\t%p\n" \)

for file in $(cat $UG_TMPFILE $U_TMPFILE $G_TMPFILE | cut -f 4-)
do
    if ! ORIG_STATE=$(fgrep $file ${RPM_TMPFILE})
    then
        rpm -q --qf \
        '[%6o{FILEMODES}\t%{FILEUSERNAME}\t%{FILEGROUPNAME}\t%{FILENAMES}\n]' \
            -f $file \
            | cut -c 3-6,8- >> ${RPM_TMPFILE}
        if ! ORIG_STATE=$(fgrep $file ${RPM_TMPFILE})
        then
            # This file is not owned by any RPM package.
            # More important to show it!!!!!!
            NOT_RPM=1
        else
            NOT_RPM=0
        fi
    fi
    CURRENT_STATE=$(cat $UG_TMPFILE $U_TMPFILE $G_TMPFILE | grep "${file}$")
    set -- $CURRENT_STATE
    mode=$1 user=$2 group=$3
    if [ "$NOT_RPM" = "1" ]; then
        printf "NOT RPM: %-10s  %-10s  %-14s  %s\n" \
            $mode $user $group $file
        continue
    fi
    set -- $ORIG_STATE
    orig_mode=$1 orig_user=$2 orig_group=$3
    if [ "$mode"  != "$orig_mode" -o \
         "$user"  != "$orig_user" -o \
         "$group" != "$orig_group" ]
    then
        if [ "$mode" != "$orig_mode" ]; then
            modeinfo="$orig_mode=>$mode"
        else
            modeinfo="$mode"
        fi
        if [ "$user"  != "$orig_user" ]; then
            userinfo="$orig_user=>$user"
        else
            userinfo="$user"
        fi
        if [ "$group"  != "$orig_group" ]; then
            groupinfo="$orig_group=>$group"
        else
            groupinfo="$group"
        fi
        
        printf "WARNING: %-10s  %-10s  %-14s  %s\n" \
            $modeinfo $userinfo $groupinfo $file
    elif [ "$VERBOSE" = "1" ]; then
        printf "okay:    %-10s  %-10s  %-14s  %s\n" \
            $mode $user $group $file
    fi
done
