#!/bin/sh

#################################################################################
#
#   Lynis
# ------------------
#
# Copyright 2007-2009, 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.
#
#################################################################################
#
# Name services
#
#################################################################################
#
    InsertSection "Software: name services"
#
#################################################################################
#
    BIND_RUNNING=0
    BIND_CONFIG_LOCS="/etc /etc/bind /usr/local/etc"
    BIND_CONFIG_LOCATIONS=""
    POWERDNS_RUNNING=0
    POWERDNS_CONFIG_LOCS="/etc/powerdns /usr/local/etc"
    POWERDNS_CONFIG_LOCATION=""
    YPBIND_RUNNING=0
#
#################################################################################
#
    # Test        : NAME-4016
    # Description : Check main domain (domain <domain name> in /etc/resolv.conf)
    Register --test-no NAME-4016 --weight L --network NO --description "Check /etc/resolv.conf default domain"
    if [ ${SKIPTEST} -eq 0 ]; then
	logtext "Test: check /etc/resolv.conf for default domain"
	if [ -f /etc/resolv.conf ]; then
	    logtext "Result: /etc/resolv.conf found"
	    FIND=`cat /etc/resolv.conf | grep "^domain" | awk '{ print $2 }'`
	    if [ "${FIND}" = "" ]; then
	        logtext "Result: no default domain found"
		Display --indent 2 --text "- Checking default DNS search domain..." --result NONE --color WHITE
	      else
	        logtext "Result: found default domain"
		logtext "Output: ${FIND}"
		report "resolv_conf_domain=${I}"
	      	Display --indent 2 --text "- Checking default DNS search domain..." --result FOUND --color GREEN
		RESOLV_DOMAINNAME="${FIND}"
	    fi
	fi
    fi
#
#################################################################################
#
    # Test        : NAME-4018
    # Description : Check search domains in /etc/resolv.conf
    # Notes       : Maximum of one search keyword is allowed in /etc/resolv.conf
    Register --test-no NAME-4018 --weight L --network NO --description "Check /etc/resolv.conf search domains"
    if [ ${SKIPTEST} -eq 0 ]; then
        N=0
	logtext "Test: check /etc/resolv.conf for search domains"
	if [ -f /etc/resolv.conf ]; then
	    logtext "Result: /etc/resolv.conf found"
	    FIND=`cat /etc/resolv.conf | grep "^search" | sed 's/^search //'`
	    if [ "${FIND}" = "" ]; then
	        logtext "Result: no search domains found, default domain is being used"
	      else
		for I in ${FIND}; do
		    logtext "Found search domain: ${I}"
		    report "resolv_conf_search_domain[]=${I}"
		    N=`expr ${N} + 1`
	        done
		# Warn if we have more than 6 search domains, which is maximum in most resolvers
		if [ ${N} -gt 6 ]; then
		    logtext "Result: Found ${N} search domains"
		    Display --indent 2 --text "- Checking search domains..." --result WARNING --color YELLOW
		    ReportWarning ${TEST_NO} "L" "Found more than 6 search domains, which is usually more than the maximum allowed number in most resolvers"
		  else
		    logtext "Result: Found ${N} search domains"
		    Display --indent 2 --text "- Checking search domains..." --result FOUND --color GREEN
		fi
	    fi
	  else
	    logtext "Result: /etc/resolv.conf does not exist, skipping test"
	    Display --indent 2 --text "- Checking search domains..." --result "NOT FOUND" --color YELLOW
	fi

	# Check amount of search domains (max 1)
	    FIND=`cat /etc/resolv.conf | grep "^search" | wc -l | tr -s ' ' | tr -d ' '`
	    if [ ! "${FIND}" = "0" -a ! "${FIND}" = "1" ]; then
	        logtext "Result: found ${FIND} line(s) with a search statement (expecting less than 2 lines)"    
		Display --indent 4 --text "- Checking search domains lines..." --result "CONFIG ERROR" --color YELLOW
		ReportWarning ${TEST_NO} "L" "Found more than 1 search lines in /etc/resolv.conf, which is probably a misconfiguration"
	      else
	        logtext "Result: found ${FIND} line(s) with a search statement (expecting less than 2 lines)"
	    fi
    fi
#
#################################################################################
#
    # Test        : NAME-4020
    # Description : Check non default resolv.conf options
    Register --test-no NAME-4020 --weight L --network NO --description "Check non default options"
    if [ ${SKIPTEST} -eq 0 ]; then
	logtext "Test: check /etc/resolv.conf for non default options"
	if [ -f /etc/resolv.conf ]; then
	    logtext "Result: /etc/resolv.conf found"
	    FIND=`grep "^options" /etc/resolv.conf | awk '{ print $2 }'`
	    if [ "${FIND}" = "" ]; then
		logtext "Result: no specific other options configured in /etc/resolv.conf"
	        Display --indent 2 --text "- Checking /etc/resolv.conf options..." --result "NONE" --color WHITE
              else
	        for I in ${FIND}; do
	            logtext "Found option: ${I}"
		    report "resolv_conf_option[]=${I}"
	    	    #rotate --> add performance tune point
	    	    #timeout <3 --> add performe tune point
	        done
	        Display --indent 2 --text "- Checking /etc/resolv.conf options..." --result "FOUND" --color GREEN
	    fi
	  else
	    logtext "Result: /etc/resolv.conf not found, test skipped"
	    Display --indent 2 --text "- Checking /etc/resolv.conf options..." --result "NOT FOUND" --color YELLOW
	fi
    fi
#
#################################################################################
#
    # Test        : NAME-4024
    # Description : Check Solaris uname -n output
    Register --test-no NAME-4024 --os Solaris --weight L --network NO --description "Solaris uname -n output"
    if [ ${SKIPTEST} -eq 0 ]; then
	FIND=`uname -n`
	logtext "Result: 'uname -n' returned ${FIND}"
        Display --indent 2 --text "- Checking uname -n output..." --result DONE --color GREEN
    fi
#
#################################################################################
#
    # Test        : NAME-4026
    # Description : Check Solaris /etc/nodename
    # Notes       : If a system is standalone, /etc/nodename should contain a system name only, not FQDN
    Register --test-no NAME-4026 --os Solaris --weight L --network NO --description "Check /etc/nodename"
    if [ ${SKIPTEST} -eq 0 ]; then
	logtext "Test: checking /etc/nodename"
	if [ -f /etc/nodename ]; then
	    logtext "Result: file /etc/nodename exists"
	    FIND=`cat /etc/nodename`
	    logtext "Output: ${FIND}"
	    Display --indent 2 --text "- Checking /etc/nodename..." --result "DONE" --color GREEN
	  else
	    logtext "Result: file /etc/nodename could not be found"
            Display --indent 2 --text "- Checking /etc/nodename..." --result "NONE FOUND" --color YELLOW
	fi
    fi
#
#################################################################################
#
    # Test        : NAME-4028
    # Description : Check DNS domain name
    # To Do       : grep ^DOMAINNAME /etc/conf.d/domainname (remove "'s)
    Register --test-no NAME-4028 --weight L --network NO --description "Check domain name"
    if [ ${SKIPTEST} -eq 0 ]; then
	DOMAINNAME=""
	logtext "Test: Checking file /etc/domainname"
        if [ -f /etc/domainname ]; then
	    logtext "Result: file /etc/domainname exists"
	    FIND2=`cat /etc/domainname`
	    if [ ! "${FIND}" = "" ]; then
	        logtext "Found domain name: ${FIND}"
		DOMAINNAME="${FIND}"
	      else
	        logtext "Result: no domain name found in file"
	    fi
	  else
	    logtext "Result: file /etc/domainname does not exist"
	fi
	
	logtext "Test: Checking if dnsdomainname command is available"
	if [ ! "${DNSDOMAINNAMEBINARY}" = "" ]; then
	    FIND2=`${DNSDOMAINNAMEBINARY} 2> /dev/null`
	    if [ ! "${FIND2}" = "" ]; then
	        logtext "Result: dnsdomainname command returned a value"
		logtext "Found domain name: ${FIND2}"
		DOMAINNAME="${FIND2}"
	      else
	        logtext "Result: dnsdomainname command returned no value"
	    fi
	  else
	    logtext "Result: dnsdomainname binary not found, skip specific test"
	fi
	
	# If files and commands can't be found, use defined value from resolv.conf
        if [ "${DOMAINNAME}" = "" ]; then
	    if [ ! "${RESOLV_DOMAINNAME}" = "" ]; then
	        logtext "Result: using domain name from /etc/resolv.conf"
	    fi
	fi
	    
	if [ ! "${DOMAINNAME}" = "" ]; then
	    logtext "Result: found domain name"
	    report "domainname=${DOMAINNAME}"
            Display --indent 2 --text "- Searching DNS domain name..." --result "FOUND" --color GREEN
	    Display --indent 6 --text "Domain name: ${DOMAINNAME}"
	  else
            Display --indent 2 --text "- Searching DNS domain name..." --result "UNKNOWN" --color YELLOW	
	fi
    fi
#
#################################################################################
#
    # Test        : NAME-4032
    # Description : Check name service caching daemon (NSCD) status
    Register --test-no NAME-4032 --weight L --network NO --description "Check nscd status"
    if [ ${SKIPTEST} -eq 0 ]; then
	logtext "Test: checking nscd status"
	FIND=`${PSBINARY} ax | grep "nscd" | grep -v "nscd"`
	if [ ! "${FIND}" = "" ]; then
	    logtext "Result: nscd is running"
            Display --indent 2 --text "- Checking nscd status..." --result RUNNING --color GREEN	    
	  else 
	    logtext "Result: nscd is not running"
            Display --indent 2 --text "- Checking nscd status..." --result "NOT FOUND" --color WHITE
	    #YYY show performance suggestion if LDAP is used
	fi
    fi
#
#################################################################################
#
    # Test        : NAME-4202
    # Description : Check if BIND is running
    Register --test-no NAME-4202 --weight L --network NO --description "Check BIND status"
    if [ ${SKIPTEST} -eq 0 ]; then
        logtext "Test: Checking for running BIND instance"
	FIND=`${PSBINARY} ax | grep "/named" | grep -v "grep"`
	if [ ! "${FIND}" = "" ]; then
	    logtext "Result: found BIND process"
	    Display --indent 2 --text "- Checking BIND status..." --result "FOUND" --color GREEN
	    BIND_RUNNING=1
	  else
	    logtext "Result: BIND not running"
	    Display --indent 2 --text "- Checking BIND status..." --result "NOT FOUND" --color WHITE
	fi
    fi
#
#################################################################################
#
    # Test        : NAME-4204
    # Description : Check configuration file of BIND
    if [ ${BIND_RUNNING} -eq 1 ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
    Register --test-no NAME-4204 --preqs-met ${PREQS_MET} --weight L --network NO --description "Search BIND configuration file"
    if [ ${SKIPTEST} -eq 0 ]; then
	logtext "Test: Search BIND configuration file"
	#YYY add chrooted environments
	for I in ${BIND_CONFIG_LOCS}; do
	    if [ -f ${I}/named.conf ]; then
	        BIND_CONFIG_LOCATION="${I}/named.conf"
	        logtext "Result: found configuration file (${BIND_CONFIG_LOCATION})"		
	    fi
	done
	if [ ! "${BIND_CONFIG_LOCATION}" = "" ]; then
	    Display --indent 4 --text "- Checking BIND configuration file..." --result "FOUND" --color GREEN
	  else
	    Display --indent 4 --text "- Checking BIND configuration file..." --result "NOT FOUND" --color YELLOW
	fi
    fi
#
#################################################################################
#
    # Test        : NAME-4206
    # Description : Check BIND configuration file consistency
    if [ ${BIND_RUNNING} -eq 1 -a ! "${BIND_CONFIG_LOCATION}" = "" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
    Register --test-no NAME-4206 --preqs-met ${PREQS_MET} --weight L --network NO --description "Check BIND configuration consistency"
    if [ ${SKIPTEST} -eq 0 ]; then
	logtext "Test: searching for named-checkconf binary"
        if [ ! "${NAMEDCHECKCONFBINARY}" = "" ]; then
	    logtext "Result: named-checkconf is installed"
	    FIND=`${NAMEDCHECKCONFBINARY} ${BIND_CONFIG_LOCATION}; echo $?`
	    if [ "${FIND}" = "0" ]; then
	        logtext "Result: configuration file ${BIND_CONFIG_LOCATION} seems to be fine"
	        Display --indent 4 --text "- Checking BIND configuration consistency..." --result "OK" --color GREEN
	      else
	        logtext "Result: possible errors found in ${BIND_CONFIG_LOCATION}"
	        Display --indent 4 --text "- Checking BIND configuration consistency..." --result WARNING --color RED
		#YYY warning
	    fi
	  else
	    logtext "Result: named-checkconf not found, skipping test"
	fi
    fi
#
#################################################################################
#
    # Test        : NAME-4208
    # Description : Check DNS server type (master, slave, caching, forwarding)
    #Register --test-no NAME-4050 --weight L --network NO --description "Check nscd status"
    #if [ ${SKIPTEST} -eq 0 ]; then
#
#################################################################################
#
    # Test        : NAME-4210
    # Description : Check if we can determine useful information from banner
    if [ ${BIND_RUNNING} -eq 1 -a ! "${BIND_CONFIG_LOCATION}" = "" -a ! "${DIGBINARY}" = "" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
    Register --test-no NAME-4210 --preqs-met ${PREQS_MET} --weight L --network NO --description "Check DNS banner"
    if [ ${SKIPTEST} -eq 0 ]; then
        logtext "Test: Trying to determine version from banner"
	FIND=`${DIGBINARY} @localhost version.bind chaos txt | grep "^version.bind" | grep TXT | egrep "[0-9].[0-9].[0-9]*"`
	if [ "${FIND}" = "" ]; then
	    logtext "Result: no useful information in banner found"
	    Display --indent 4 --text "- Checking BIND version in banner ..." --result "OK" --color GREEN
	    AddHP 2 2
	  else
	    logtext "Result: possible BIND version available in version banner"
	    Display --indent 4 --text "- Checking BIND version in banner..." --result WARNING --color RED
	    ReportWarning ${TEST_NO} "M" "Found BIND version in banner"
	    #YYY suggestion
	    AddHP 0 2
	fi
    fi
#
#################################################################################
#
    # Test        : NAME-4212
    # Description : Check version option in BIND configuration
    #if [ ${BIND_RUNNING} -eq 1 -a ! "${BIND_CONFIG_LOCATION}" = "" -a ! "${DIGBINARY}" = "" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
    #Register --test-no NAME-4210 --preqs-met ${PREQS_MET} --weight L --network NO --description "Check DNS banner"
#
#################################################################################
#
    # Test        : NAME-4220
    # Description : Check if we can perform a zone transfer of primary domain
    #Register --test-no NAME-4220 --weight L --network NO --description "Check zone transfer"
    #if [ ${SKIPTEST} -eq 0 ]; then
#
#################################################################################
#
    # Test        : NAME-4222
    # Description : Check if we can perform a zone transfer of PTR (of primary domain)
    #Register --test-no NAME-4222 --weight L --network NO --description "Check zone transfer"
    #if [ ${SKIPTEST} -eq 0 ]; then
#
#################################################################################
#
    # Test        : NAME-4230
    # Description : Check if PowerDNS is running
    Register --test-no NAME-4230 --weight L --network NO --description "Check PowerDNS status"
    if [ ${SKIPTEST} -eq 0 ]; then
        logtext "Test: Checking for running PowerDNS instance"
	FIND=`${PSBINARY} ax | grep "/pdns_server" | grep -v "grep"`
	if [ ! "${FIND}" = "" ]; then
	    logtext "Result: found PowerDNS process"
	    Display --indent 2 --text "- Checking PowerDNS status..." --result "FOUND" --color GREEN
	    POWERDNS_RUNNING=1
	  else
	    logtext "Result: PowerDNS not running"
	    Display --indent 2 --text "- Checking PowerDNS status..." --result "NOT FOUND" --color WHITE
	fi
    fi
#
#################################################################################
#
    # Test        : NAME-4232
    # Description : Check PowerDNS configuration file
    if [ ${POWERDNS_RUNNING} -eq 1 ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
    Register --test-no NAME-4232 --preqs-met ${PREQS_MET} --weight L --network NO --description "Search PowerDNS configuration file"
    if [ ${SKIPTEST} -eq 0 ]; then
	logtext "Test: Search PowerDNS configuration file"
	#YYY add chrooted environments
	for I in ${POWERDNS_CONFIG_LOCS}; do
	    if [ -f ${I}/pdns.conf ]; then
	        POWERDNS_CONFIG_LOCATION="${I}/pdns.conf"
	        logtext "Result: found configuration file (${POWERDNS_CONFIG_LOCATION})"		
	    fi
	done
	if [ ! "${POWERDNS_CONFIG_LOCATION}" = "" ]; then
	    Display --indent 4 --text "- Checking PowerDNS configuration file..." --result "FOUND" --color GREEN
	  else
	    Display --indent 4 --text "- Checking PowerDNS configuration file..." --result "NOT FOUND" --color YELLOW
	fi
    fi
#
#################################################################################
#
#    # Test        : NAME-4234
#    # Description : Check PowerDNS configuration file consistency
#    if [ ${POWERDNS_RUNNING} -eq 1 -a ! "${POWERDNS_CONFIG_LOCATION}" = "" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
#    Register --test-no NAME-4234 --weight L --network NO --description "Check PowerDNS configuration consistency"
#    if [ ${SKIPTEST} -eq 0 ]; then
#    fi
#
#################################################################################
#
    # Test        : NAME-4236
    # Description : Check PowerDNS backends
    if [ ${POWERDNS_RUNNING} -eq 1 -a ! "${POWERDNS_CONFIG_LOCATION}" = "" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
    Register --test-no NAME-4236 --preqs-met ${PREQS_MET} --weight L --network NO --description "Check PowerDNS backends"
    if [ ${SKIPTEST} -eq 0 ]; then
        logtext "Test: Checking for PowerDNS backends"
	FIND=`cat ${POWERDNS_CONFIG_LOCATION} | grep "^launch" | awk -F= '{ print $2 }'`
	if [ ! "${FIND}" = "" ]; then
	    for I in ${FIND}; do
	        logtext "Found backend: ${I}"
	    done
	    Display --indent 4 --text "- Checking PowerDNS backends..." --result "FOUND" --color GREEN
	  else
	    logtext "Result: no PowerDNS backends found"
	    Display --indent 4 --text "- Checking PowerDNS backends..." --result "NOT FOUND" --color YELLOW
	fi
    fi
#
#################################################################################
#
    # Test        : NAME-4302
    # Description : Check NIS ypbind daemon status
    Register --test-no NAME-4304 --weight L --network NO --description "Check NIS ypbind status"
    if [ ${SKIPTEST} -eq 0 ]; then
        logtext "Test: Checking status of ypbind daemon"
	FIND=`${PSBINARY} ax | grep "ypbind" | grep -v "grep"`
	if [ ! "${FIND}" = "" ]; then
	    logtext "Result: ypbind is running"
	    Display --indent 2 --text "- Checking ypbind status..." --result "FOUND" --color GREEN
	    YPBIND_RUNNING=1
	  else
	    logtext "Result: ypbind is not active"
	    Display --indent 2 --text "- Checking ypbind status..." --result "NOT FOUND" --color WHITE
	fi
    fi
#
#################################################################################
#
    # Test        : NAME-4306
    # Description : Check NIS domain
    # Notes       : FreeBSD: sysctl kern.domainname
    if [ ${YPBIND_RUNNING} -eq 1 ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
    Register --test-no NAME-4306 --preqs-met ${PREQS_MET} --weight L --network NO --description "Check NIS domain"
    if [ ${SKIPTEST} -eq 0 ]; then
        logtext "Test: Checking `domainname` for NIS domain value"
	FIND=`${DOMAINNAMEBINARY} | grep -v "(none)"`
	if [ ! "${FIND}" = "" ]; then
	    logtext "Value: ${FIND}"
	    NISDOMAIN="${FIND}"
	  else
	    logtext "Result: no NIS domain found in command output"
	fi
	# Solaris / Linux style
	logtext "Test: Checking file /etc/defaultdomain"
	if [ -f /etc/defaultdomain ]; then
	    logtext "Result: file /etc/defaultdomain exists"
	    FIND2=`cat /etc/defaultdomain`
	    if [ ! "${FIND2}" = "" ]; then
	        logtext "Output: ${FIND2}"
		NISDOMAIN="${FIND2}"
	      else
	        logtext "Result: no NIS domain found in file"
	    fi
	fi
	# Red Hat style
	logtext "Test: checking /etc/sysconfig/network"
	if [ -f /etc/sysconfig/network ]; then
	    logtext "Result: file /etc/sysconfig/network exists"
	    logtext "Test: checking NISDOMAIN value in file"
	    FIND3=`grep "^NISDOMAIN" /etc/sysconfig/network | awk -F= '{ print $2 }' | sed 's/"//g'`
	    if [ ! "${FIND3}" = "" ]; then
	        logtext "Found NIS domain: ${FIND3}"
		NISDOMAIN="${FIND3}"
	      else
	        logtext "Result: No NIS domain found in file"
	    fi
	  else
	    logtext "Result: file /etc/sysconfig/network does not exist"
	fi
	# Check if we found any NIS domain
	if [ ! "${NISDOMAIN}" = "" ]; then    
	    logtext "Found NIS domain: ${NISDOMAIN}"
	    report "nisdomain=${NISDOMAIN}"
	    Display --indent 4 --text "- Checking NIS domain..." --result "FOUND" --color GREEN
	  else
	    logtext "Result: No NIS domain found"
	    Display --indent 4 --text "- Checking NIS domain..." --result "UNKNOWN" --color YELLOW
	fi
    fi
#
#################################################################################
#

wait_for_keypress

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