#!/bin/sh

#################################################################################
#
#   Lynis
# ------------------
#
# Copyright 2007-2008, Michael Boelen (michael@rootkit.nl), The Netherlands
# Web site: http://www.rootkit.nl
#
# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are
# welcome to redistribute it under the terms of the GNU General Public License.
# See LICENSE file for usage of this software.
#
#################################################################################
#
# User, Group and authentication tests
#
#################################################################################
#
InsertSection "Users, Groups and Authentication"
#
#################################################################################


    # Search accounts with UID 0

    TESTID="USERS_UID_ZERO"
    counttests
    logtext "Test: Searching accounts with UID 0"
    FIND=`grep -v '^:0:0:::' /etc/passwd | grep ":0:" | cut -d ":" -f1,3 | grep '0' | grep -v 'root:0'` 
    if [ ! "${FIND}" = "" ]; then
	Display --indent 2 --text "- Search administrator accounts..." --result WARNING --color RED
	echo "        Result: Found more than one administrator accounts"
	logtext "Warning: found more than one user with UID 0"
	ReportWarning "${TEST_NO}" "H" "Multiple users with UID 0 found in passwd file"
	for I in ${FIND}; do
	  logtext "Administrator account: ${I}"
	done
	
	if [ "${OS}" = "FreeBSD" ]; then
	  logtext "FreeBSD note: default there is a user 'toor' installed. This account is considered "
	  logtext "useless unless it is assigned a password and used for emergencies. ie: bad shell for "
	  logtext "root user."
	  logtext "Suggestion: use vipw to delete the 'toor' user, if you don't use it."
	fi
      else
	Display --indent 2 --text "- Search administrator accounts..." --result OK --color GREEN
	logtext "Result: No accounts found with UID 0 other than root."
	ReportResult ${TESTID} OK NONE ""
    fi
#
#################################################################################
#

if [ "${OS}" = "FreeBSD" ]; then

    logtext "Test: ${USER_PASSWD_DOUBLEUID_AUDIT_TITLE}"
    logtext "Description: ${USER_PASSWD_DOUBLEUID_AUDIT_DESCRIPTION}"
    logtext "Action: Checking for non unique accounts"

    # Check master.passwd
    if [ -f /etc/master.passwd ]; then
        FIND=`cat /etc/master.passwd | grep -v '^#' | cut -d ':' -f3 | uniq -d`
	if [ "${FIND}" = "" ]; then
	    Display --indent 2 --text "- Checking UIDs... " --result OK --color GREEN
	    logtext "Result: all accounts found in /etc/master.passwd are unique"
	  else
	    Display --indent 2 --text "- Checking UIDs... " --result WARNING --color RED
    	    logtext "Warning: some non unique UIDs found"
    	    logtext "Output (non unique UIDs): ${FIND}"
	    logtext "Impact: HIGH"
	    ReportWarning "XXXX-0000" "H" "Multiple accounts found with same UID"
        fi
      else
	Display --indent 2 --text "- Checking UIDs... " --result SKIPPED --color WHITE
        logtext "Result: test skipped, /etc/master.passwd file not available"
    fi
    logtext "Remarks: ${USER_PASSWD_DOUBLEUID_AUDIT_TEXT}"
    logtextbreak

#
#################################################################################
#

    # [FreeBSD] /etc/group test
    counttests
    logtext "Test: Searching for presence /usr/sbin/chkgrp binary... "
    if [ -f /usr/sbin/chkgrp ]; then
	Display --indent 2 --text "- Checking chkgrp tool..." --result FOUND --color WHITE
	logtext "Result: /usr/sbin/chkgrp binary found. Using this to perform next test(s)."
	logtext "Test: Testing consistency of /etc/group file... "
	FIND=`/usr/sbin/chkgrp | grep -v 'is fine'`
	if [ "${FIND}" = "" ]; then
	    Display --indent 2 --text "- Consistency check /etc/group file..." --result OK --color GREEN
	    logtext "Result: chkgrp test performed, Group file seems to be ok."
	  else
	    Display --indent 2 --text "- Consistency check /etc/group file..." --result WARNING --color RED
	    logtext "Warning: chkgrp found some errors. Run the tool manually to see details."
	    logtext "chkgrp output: ${FIND}"
	    logtext "Impact: MEDIUM"
	    ReportWarning "XXXX-0000" "M" "chkgrp reported inconsistencies in /etc/group file"
	fi
      else
	echo "[ ${WHITE}SKIPPED${NORMAL} ]"
	logtext "Result: /usr/sbin/chkgrp binary not found. Can't perform /etc/group consistency test."
    fi
fi

#
#################################################################################
#

# Test            : run grpck to test group files (most likely /etc/group and shadow group files)
# Expected result : 0 (exit code)

    logtext "Test: Checking for grpck binary..."
    if [ ! "${GRPCKBINARY}" = "" ]; then
        counttests
	if [ "${OS}" = "Linux" ]; then
	    FIND=`${GRPCKBINARY} -r 2> /dev/null ; echo $?`
	  elif [ "${OS}" = "AIX" ]; then
	    FIND=`${GRPCKBINARY} -n 2> /dev/null ; echo $?`
	  else
	    FIND=`${GRPCKBINARY} 2> /dev/null ; echo $?`
	fi
	
	#YYY if SUSE then use quiet option
	#FIND=`${GRPCKBINARY} -q 2> /dev/null ; echo $?`
	if [ "${FIND}" = "0" ]; then
	    Display --indent 2 --text "- Test group files (grpck)..." --result OK --color GREEN
	    logtext "Result: grpck binary didn't find any errors in the group files"
	  else
	    Display --indent 2 --text "- Test group files (grpck)..." --result WARNING --color RED
	    logtext "Warning: grpck binary found errors"
	    logtext "Suggestion: run grpck manually and check your group files"
	    report "warning[]=Inconsistencies found in group files by grpck"
	fi
      else
        logtext "Result: grpck test skipped (couldn't find grpck binary)"
    fi
    logtextbreak

#
#################################################################################
#

if [ "${OS}" = "FreeBSD" ]; then
    counttests
    logtext "Test: Checking login shells"
    if [ -f /etc/master.passwd ]; then
	# Check for all shells, except: /sbin/nologin
        FIND=`cat /etc/master.passwd | grep "[a-z]:\*:" | grep -v '/sbin/nologin'`
        if [ "${FIND}" = "" ]; then
	    Display --indent 2 --text "- Checking login shells..." --result OK --color GREEN
          else
	    Display --indent 2 --text "- Checking login shells..." --result WARNING --color RED
    	    logtext "Warning: possible harmful shell found (for passwordless account!)"
	    logtext "Output: ${FIND}"
	    report "warning[]=Found shell with passwordless account"
         fi
      else
	echo "[ ${WHITE}SKIPPED${NORMAL} ]"
        logtext "Result: No /etc/master.passwd file found"
    fi
    logtextbreak
fi

#
#################################################################################
#

if [ -f /etc/group ]; then
    counttests
    logtext "Test: Checking for non unique group ID's in /etc/group"
    FIND=`awk -F: '{ print $3 }' /etc/group | grep -v '^#' | sort | uniq -d`
    if [ "${FIND}" = "" ]; then	
	Display --indent 2 --text "- Checking non unique group ID's... " --result OK --color GREEN
        logtext "Result: All group ID's are unique"
        #loginfo NONE OK
      else
      	Display --indent 2 --text "- Checking non unique group ID's... " --result WARNING --color WARNING
        logtext "Warning: Found the same group ID multiple times"
	logtext "Output: ${FIND}"
	ReportSuggestion "XXXX-0000" "Check your /etc/group file and correct inconsistencies"
	ReportWarning "XXXX-0000" "H" "Found multiple groups with same group ID"
    fi
    logtextbreak

#
#################################################################################
#

    counttests
    logtext "Test: Checking for non unique group names in /etc/group"
    FIND=`awk -F: '{ print $1 }' /etc/group | grep -v '^#' | sort | uniq -d`
    if [ "${FIND}" = "" ]; then
	Display --indent 2 --text "- Checking non unique group names... " --result OK --color GREEN
        logtext "Result: All group names are unique"
        #loginfo NONE OK
      else
      	Display --indent 2 --text "- Checking non unique group names... " --result WARNING --color WARNING
	logtext "Warning: found the same group name multiple times"
	logtext "Output: ${FIND}"
	logtext "Suggestion: Check your /etc/group file and correct inconsistencies"
        #loginfo MEDIUM BAD
	report "warning[]=Found inconsistencies in group file (multiple occurences of a single group)"
    fi

    logtextbreak
fi    

#
#################################################################################
#

    # Test password file consistency for Solaris
    if [ "${OS}" = "SunOS" -a -x /usr/sbin/pwck ]; then
        counttests
	logtext "Test: Checking password file consistency (pwck)"
	FIND=`/usr/sbin/pwck 2> /dev/null; echo $?`
	if [ "${FIND}" = "0" ]; then
	    Display --indent 2 --text "- Checking password file consistency..." --result OK --color GREEN
	    logtext "Result: pwck finished didn't find problems"
	  else
	    Display --indent 2 --text "- Checking password file consistency..." --result WARNING --color RED
            logtext "Warning: pwck found one or more errors/warnings in the password file."
	    logtext "Suggestion: run pwck manually and correct found issues."
	fi
    fi

#
#################################################################################
#

    counttests
    Display --indent 2 --text "- Query system users (non daemons)..."
    logtext "Test: Read real system users from /etc/passwd..."
    FIND=""

    #YYY
    #HPUX > 100
    #MacOS: just reading passwd file is not enough
    #OpenBSD/NetBSD: unknown

    if [ "${OS}" = "FreeBSD" ]; then
      logtext "FreeBSD real users output (ID > 1000, but not 65534):"
      FIND=`awk -F: '($3 > 1000) && ($3 != 65534) || ($3 == 0) { print $1","$3 }' /etc/passwd`
    fi

    if [ "${OS}" = "Linux" ]; then
      logtext "Linux real users output (ID > 500, but not 65534):"
      FIND=`awk -F: '($3 > 500) && ($3 != 65534) || ($3 == 0) { print $1","$3 }' /etc/passwd`
    fi

    if [ "${OS}" = "SunOS" ]; then
      logtext "Solaris real users output (ID > 100, but not 60001/65534):"
      FIND=`awk -F: '($3 > 100 && $3 != 60001 && $3 != 65534) || ($3 == 0) { print $1","$3 }' /etc/passwd`
    fi

    # Check if we got any output
    if [ "${FIND}" = "" ]; then
        Display --indent 4 --text "Result: No users found"
        logtext "Result: Querying of system users skipped"
      else
        for I in ${FIND}; do
          logtext "Real user: ${I}"
          report "real_user[]=${I}"
        done
    fi

    logtextbreak





wait_for_keypress


#
#================================================================================
# Lynis - Copyright 2007-2008, Michael Boelen - www.rootkit.nl - The Netherlands
