#!/bin/sh

#################################################################################
#
#   Lynis
# ------------------
#
# Copyright 2007-2015, Michael Boelen, CISOfy (michael.boelen@cisofy.com)
# Web site: https://cisofy.com
#
# 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.
#
#################################################################################
#
# Scheduled tasks
#
#################################################################################
#
    InsertSection "Scheduled tasks"
#
#################################################################################
#
    ATD_RUNNING=0
#
#################################################################################
#
    # Test        : SCHD-7704
    # Description : Check crontab / cronjobs
    Register --test-no SCHD-7704 --weight L --network NO --description "Check crontab/cronjobs"
    if [ ${SKIPTEST} -eq 0 ]; then
        FindCronJob()
          {
            sCRONJOBS=`egrep '^([0-9*])' $1 | tr '\t' ' ' | tr -s ' ' | tr ' ' ','`
          }

        if [ -f /etc/crontab ]; then
            FindCronJob /etc/crontab
            for I in ${sCRONJOBS}; do
                logtext "Found cronjob (/etc/crontab): ${I}"
                report "cronjob[]=${I}"
            done
        fi

        CRON_DIRS="/etc/cron.d"
        for I in ${CRON_DIRS}; do
            logtext "Test: checking directory ${I}"
            if [ -d ${I} ]; then
                FileIsReadable ${I}
                if [ ${CANREAD} -eq 1 ]; then
                    logtext "Result: found directory ${I}"
                    logtext "Test: searching files in ${I}"
                    FIND=`find ${I} -type f -print`
                    if [ "${FIND}" = "" ]; then
                        logtext "Result: no files found in ${I}"
                      else
                        logtext "Result: found one or more files in ${I}. Analyzing files.."
                        for J in ${FIND}; do
                            FindCronJob ${J}
                            for K in ${sCRONJOBS}; do
                                logtext "Result: Found cronjob (${I}): ${K}"
                            done
                        done
                        logtext "Result: done with analyzing files in ${I}"
                    fi
                  else
                    logtext "Result: can not read file or directory ${I}"
                fi
              else
                logtext "Result: directory ${I} does not exist"
            fi
        done

        CRON_DIRS="/etc/cron.hourly /etc/cron.daily /etc/cron.weekly /etc/cron.monthly"
        for I in ${CRON_DIRS}; do
            logtext "Test: checking directory ${I}"
            if [ -d ${I} ]; then
                logtext "Result: found directory ${I}"
                logtext "Test: searching files in ${I}"
                FIND=`find ${I} -type f -print | grep -v ".placeholder"`
                if [ "${FIND}" = "" ]; then
                    logtext "Result: no files found in ${I}"
                  else
                    logtext "Result: found one or more files in ${I}. Analyzing files.."
                    for J in ${FIND}; do
                        logtext "Result: Found cronjob (${I}): ${J}"
                        report "cronjob[]=${J}"
                    done
                    logtext "Result: done with analyzing files in ${I}"
                fi
              else
                logtext "Result: directory ${I} does not exist"
            fi
        done

        # /var/spool/cron/* and /var/spool/cron/crontabs/*
        # Search only in one tree, to avoid searching the tree twice
        if [ -d /var/spool/cron/crontabs ]; then
            FIND=`find /var/spool/cron/crontabs -type f -print`
            for I in ${FIND}; do
                FindCronJob ${I}
                for J in ${sCRONJOBS}; do
                    logtext "Found cronjob (/var/spool/cron/crontabs): ${I} (${J})"
                    report "cronjob[]=${I}"
                done
            done
          else
            if [ -d /var/spool/cron ]; then
                FIND=`find /var/spool/cron -type f -print`
                for I in ${FIND}; do
                    FindCronJob ${I}
                    for J in ${sCRONJOBS}; do
                        logtext "Found cronjob (/var/spool/cron): ${I} (${J})"
                        logtext "cronjob[]=${I}"
                    done
                done
            fi
        fi

        # Anacron
        if [ "${OS}" = "Linux" ]; then
            if [ -f /etc/anacrontab ]; then
                logtext "Test: checking anacrontab"
                sANACRONJOBS=`egrep '^([0-9@])' /etc/anacrontab | tr '\t' ' ' | tr -s ' ' | tr ' ' ','`
                for J in ${sANACRONJOBS}; do
                    logtext "Found anacron job (/etc/anacrontab): ${J}"
                    report "cronjob[]=${J}"
                done
            fi
        fi

        Display --indent 2 --text "- Checking crontab/cronjob" --result DONE --color GREEN
    fi
#
#################################################################################
#
    # Test        : SCHD-7718
    # Description : Check atd status
    Register --test-no SCHD-7718 --weight L --network NO --description "Check at users"
    if [ ${SKIPTEST} -eq 0 ]; then
        logtext "Test: Checking atd status"
        FIND=`${PSBINARY} ax | grep "/atd" | grep -v "grep"`
        if [ ! "${FIND}" = "" ]; then
            logtext "Result: at daemon active"
            Display --indent 2 --text "- Checking atd status" --result RUNNING --color GREEN
            ATD_RUNNING=1
          else
            logtext "Result: at daemon not active"
            Display --indent 2 --text "- Checking atd status" --result "NOT RUNNING" --color WHITE
        fi
    fi
#
#################################################################################
#
    # Test        : SCHD-7720
    # Description : Check at users
    # Notes       : if at.allow exists, only users listed can schedule at jobs
    #               if at.allow does not exist, but at.deny does, everyone
    #               except the listed ones can schedule jobs. If both can't be
    #               found, only root can schedule jobs.
    if [ ${ATD_RUNNING} -eq 1 ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
    Register --test-no SCHD-7720 --preqs-met ${PREQS_MET} --weight L --network NO --description "Check at users"
    if [ ${SKIPTEST} -eq 0 ]; then
        AT_UNKNOWN=0
        case ${OS} in
            FreeBSD)          AT_ALLOW="/var/at/at.allow";        AT_DENY="/var/at/at.deny"         ;;
            HPUX)             AT_ALLOW="/usr/lib/cron/at.allow";  AT_DENY="/usr/lib/cron/at.deny"   ;;
            Linux)            AT_ALLOW="/etc/at.allow";           AT_DENY="/etc/at.deny"            ;;
            OpenBSD)          AT_ALLOW="/var/cron/at.allow";      AT_DENY="/var/cron/at.deny"       ;;
            SunOS)            AT_ALLOW="/etc/cron.d/at.allow";    AT_DENY="/etc/cron.d/at.deny"     ;;
            *)                AT_UNKNOWN=1; logtext "Test skipped, files for at unknown"            ;;
        esac
        if [ ${AT_UNKNOWN} -eq 0 ]; then
            logtext "Test: checking for file ${AT_ALLOW}"
            if [ -f ${AT_ALLOW} ]; then
                FileIsReadable ${AT_ALLOW}
                if [ ${CANREAD} -eq 1 ]; then
                    logtext "Result: file ${AT_ALLOW} exists, only listed users can schedule at jobs"
                    FIND=`cat ${AT_ALLOW} | sort`
                    if [ "${FIND}" = "" ]; then
                        logtext "Result: File empty, no users are allowed to schedule at jobs"
                      else
                        for I in ${FIND}; do
                           logtext "Allowed at user: ${I}"
                        done
                    fi
                  else
                    logtext "Result: can not read ${AT_ALLOW} (no permission)"
                fi
             else
               logtext "Result: file ${AT_ALLOW} does not exist"
               logtext "Test: checking for file ${AT_DENY}"
               if [ -f ${AT_DENY} ]; then
                   FileIsReadable ${AT_DENY}
                   if [ ${CANREAD} -eq 1 ]; then
                       logtext "Result: file ${AT_DENY} exists, only non listed users can schedule at jobs"
                       FIND=`cat ${AT_DENY} | sort`
                       if [ "${FIND}" = "" ]; then
                           logtext "Result: file is empty, no users are denied access to schedule jobs"
                         else
                           for I in ${FIND}; do
                               logtext "Denied at user: ${I}"
                           done
                       fi
                     else
                       logtext "Result: can not read ${AT_DENY} (no permission)"
                   fi
                 else
                   logtext "Result: both ${AT_ALLOW} and ${AT_DENY} do not exist"
                   logtext "Note: only root can schedule at jobs"
                   AddHP 1 1
               fi
            fi
            Display --indent 4 --text "- Checking at users" --result DONE --color GREEN
          else
            Display --indent 4 --text "- Checking at users" --result SKIPPED --color YELLOW
        fi
    fi
#
#################################################################################
#
    # Test        : SCHD-7724
    # Description : Check scheduled at jobs
    if [ ${ATD_RUNNING} -eq 1 ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
    Register --test-no SCHD-7724 --preqs-met ${PREQS_MET} --weight L --network NO --description "Check at jobs"
    if [ ${SKIPTEST} -eq 0 ]; then
        logtext "Test: Check scheduled at jobs"
        FIND=`atq | grep -v "no files in queue" | ${AWKBINARY} '{gsub("\t"," ");print}' | sed 's/ /!space!/g'`
        if [ ! "${FIND}" = "" ]; then
            logtext "Result: found one or more jobs"
            for I in ${FIND}; do
                I=`echo ${I} | sed 's/!space!/ /g'`
                logtext "Found at job: ${I}"
            done
            Display --indent 4 --text "- Checking at jobs" --result FOUND --color GREEN
          else
            logtext "Result: no pending at jobs"
            Display --indent 4 --text "- Checking at jobs" --result NONE --color GREEN
        fi
    fi
#
#################################################################################
#

wait_for_keypress

#
#================================================================================
# Lynis - Copyright 2007-2015, Michael Boelen, CISOfy - https://cisofy.com
