
#!/bin/ksh
# File	: chk_secu-baseline_setting.ksh
# By	: Maarten de Boer, 100427
# Subject	: Check security setting
#(0.2)	: copy ${TMP} to /tmp/{PGM}.out. Added check options & hosts.equiv at vfilers
#(0.3)	: Added; Check options H3.1 & Header in output file, Changes some optiosn at H3.4
#(0.4)	: na_ volumes need NOT to be connected to a vfiler & ssl.enable=on; Print (v)filerrootvol if NOT empty
#(0.5)	: List of volumes (auto-)exported because of "nfs.export.auto-update=on"
#(0.6)  : Added Exclude-ing at options & H3.3 (SNMP-string)
#(0.7)	: Added Exclude-ing   echo "- Root-vol(0) access (H3.16) ${FILER}:" | tee -a ${TMP}
#(0.8)  : Added: [ "${VALUE}" != "is" ] . Sometimes we get this value back from vfiler
#(0.9)	: Added USAGE, --mailto & -f. Mod. of H3.9 & excludes for NXP
#(0.10)	: Added LOG-ing. Excludes NXP nfs.usd
#(0.11)	: SNMP-string not accepted.
#(0.12)	: Exculdes in H3.9
#(0.13)	: Added ${WARN} & To USD (via IMI) changed `date +%Y-%m-%d_%H:%M:%S`
#(0.14)	: Split in several chapters. Out also in .CSV for Baseline deviation report.
#	options ssh.enable (H3.1) not needed to be checked. SSH-secu check at H3.2
#	Intruducing of WARNCNT
#(0.1)	: Changed name (from chk_secu_setting) to chk_secu-baseline_setting.ksh; Adding TTLCNT; Added ${LOGNAME}
#(0.2)	: Creating USD-query-tickets for "M05 - Password hardening" & "M07 - Logging"
#(0.3)	: Added CIFS & iSCSI.
#(0.4)	: Mod. Root-volume exported (UK:11346400)
#(0.5)	: Changed USDMAIL to USD12
# 	.excludes: rw=nlxfsd01:nlxfsd02:nlxfsd03:aodbm01:aodbm02,root=nlxfsd01:nlxfsd02:nlxfsd03:aodbm01:aodbm02
#(0.6)	: Update for new N-series-env
#(0.7)	: Added: EXCLUDES + MAILPERFILER
#(0.8)	: Mod's; if at M05; echo ".. \c" -> echo -n ".."
# set -x
PGM="`basename $0|cut -d\. -f1`"
VERSION="0.8" 
TMP="/tmp/${PGM}.$$"
WARN="/tmp/${PGM}.warn.$$"
MAIL=""
MAILFILE="${TMP}.mailfile"
MAILTO="maarten.deboer@atos.net"
#MAILTO="geralt.somsen@atos.net maarten.deboer@atos.net"
#MAILTO="richard.loos@atos.net maarten.deboer@atos.net"
MAILTO="maarten.deboer@atos.net"
HOSTNAME="`hostname|cut -d\. -f1`"
FILERS="${HOME}/etc/filers"
SSH="/usr/bin/ssh -n"
DATI="`date +%Y-%m-%d_%H-%M`"
TXT="${PGM}_${DATI}_${HOSTNAME}.txt"
SSH="/usr/bin/ssh -n"
FILTER="[1234567890*]"
LOG="$HOME/log/${PGM}.log"
MAXLOGSIZE=1024   # In K's
USD=""
#USDMAIL="email@usd-prod.uk.atosorigin.com"
USDMAIL="prod-imi@gis.nl.ao-srv.com"
USDUSER="nl19471"
USDMSG="${TMP}.usd"
USDREPLYTO="maarten.deboer@atos.net"
USDTYPE="Incident"
CSV="${PGM}_${DATI}_${HOSTNAME}.csv"
WARNCNT=0  # Warning count
TTLCNT=0  # Total count
TMPCSV="${TMP}.csv" 
CIFSWARN="/tmp/${PGM}.cifswarn.$$"
EXCLUDES="${HOME}/etc/${PGM}.excludes"
MAILPERFILER="" 

# if not me (accourding to LOGNAME), then change some user related info
if [ "${LOGNAME}" != "nl19471" ]; then
  MAILTO="fsod@atos.net"
  USDUSER="nldsm01"
  USDREPLYTO="fsod@atos.net"
fi

# Functions
CHECK_FILER_OPTIONS()
{
  cat ${TMP}.options.${2}|grep -v \^#|while read LINE
  do
    OPTION="`echo ${LINE} | cut -d\= -f1`"
    SETTO="`echo ${LINE} | cut -d\= -f2`"
    VALUE="`${SSH} ${1} options ${OPTION} | awk '{print $2}'`"
    let TTLCNT=${TTLCNT}+1
    if [ "${SETTO}" != "${VALUE}" ]; then
      EXCLUDE="`echo "${1}:${OPTION}=${VALUE}" | egrep -f ${TMP}.excludes`"
      if [ "${EXCLUDE}" != "" ]; then
        echo "  (${1}:${OPTION}=${VALUE}. Must be:${SETTO})=Excluded & accepted." | tee -a ${TMP}
      else
        echo "${1}:${OPTION}=${VALUE}. Must be:${SETTO}"|tee -a ${TMP}
        echo "Filer options ${1}:${OPTION}=${VALUE}. Must be:${SETTO}"|tee -a ${WARN}
        let WARNCNT=${WARNCNT}+1
      fi
    fi
  done
# Check options, per vfiler
  ${SSH} ${1} vfiler status | grep running | grep -v vfiler | awk '{print $1}' | while read VFILER
  do
    cat ${TMP}.options.${2}|grep -v \^#|while read LINE
    do
      OPTION="`echo ${LINE} | cut -d\= -f1`"
      SETTO="`echo ${LINE} | cut -d\= -f2`"
      let TTLCNT=${TTLCNT}+1
# Getting this value is different as from normal filer
# Some options are not available ("No such option")
      VALUE="`${SSH} ${1} vfiler run ${VFILER} options ${OPTION} 2>/dev/null |tail -1|grep -v ${VFILER}|awk '{print $2}
' 2>/dev/null`"
# Added: [ "${VALUE}" != "is" ] . Sometimes we get this value back from vfiler
      if [ "${VALUE}" != "is" ]; then

      if [ "${VALUE}" != "" ] && [ "${SETTO}" != "${VALUE}" ]; then
        EXCLUDE="`echo "${1}/${VFILER}:${OPTION}=${VALUE}" | egrep -f ${TMP}.excludes`"
        if [ "${EXCLUDE}" != "" ]; then
          echo "  (${1}/${VFILER}:${OPTION}=${VALUE}. Must be:${SETTO})=Excluded & accepted." | tee -a ${TMP}
        else
          echo "${1}/${VFILER}:${OPTION}=${VALUE}. Must be:${SETTO}"|tee -a ${TMP}
          echo "vFiler options ${1}/${VFILER}:${OPTION}=${VALUE}. Must be:${SETTO}"|tee -a ${WARN}
          let WARNCNT=${WARNCNT}+1
        fi
      fi
      else
        echo "${1}/${VFILER}:${OPTION}=${VALUE}. Wrong value. Need to be checked (by hand / running script again)."|tee
 -a ${TMP}|tee -a ${WARN}
      fi  # [ "${VALUE}" != "is" ]
    done  # cat
  done  # SSH vfiler status
}

CREATE_USD_TICKET()
# $1=Filer(CI), $2=USDTYPE, $3=USD-text
{
  echo "@REQUESTTYPE: ${2}" > ${USDMSG}
  echo "@REQUESTAREA: NL.Storage.StorageOnDemand" >> ${USDMSG}
  echo "@SEVERITY: 4" >> ${USDMSG}
  echo "@CI: ${1}" >> ${USDMSG}
  echo "@ORGANISATION: AtosOrigin.Netherlands" >> ${USDMSG}
  echo "@GROUP: NL.Storage.FSOD" >> ${USDMSG}
  echo "@REPLYTO: ${USDREPLYTO}" >> ${USDMSG}
  echo "@PROXYUSER: ${USDUSER}"  >> ${USDMSG}
  cat ${3} >> ${USDMSG}
  echo "[${PGM} v${VERSION}]" >> ${USDMSG}
  echo "@ENDOFUSDMESSAGE" >> ${USDMSG}

  cat ${USDMSG} | mailx -s "${USDUSER}: WARNING; Security check at ${1}." ${USDMAIL}

  echo "`date` ${PGM}: Mailed to USD-IMI (${USDMAIL})"|tee -a ${LOG}
}

USAGE()
{
  echo "Usage: ${PGM} <options>"
  echo "  Version: ${VERSION}"
  echo "  options     :"
  echo "    -m|--mail : do send Mail"
  echo "    -u|--usd  : do send to USD"
  echo "    -e|--etc  : Etc/filers-file (${FILERS})"
  echo "    -f        : Filter filername (${FILTER})"
  echo "    -h|--help : this Help"
  echo "    -V        : show Version"
  echo "    -x        : set -x"
  echo "    --mailto  : change MAILTO address & do send mail (${MAILTO})"
  echo "    --mpf     : MailPerFiler (normaly all filers in 1 mail)"
}

## MAIN
# Check options
if [ $# -eq 0 ]; then
  echo "No option(s) given. So not to know what to do. Exiting..."; echo; USAGE; exit 1
fi
while [ $# -gt 0 ]
  do
  case $1 in
    -f) FILTER=$2; shift ;;
    -m | --mail) MAIL=1 ;;
    -e | --etc) FILERS=$2; shift ;;
    --mailto) MAILTO=$2; MAIL=1; shift ;;
    --mpf) MAILPERFILER=1;;
    -u | --usd) USD=1;;
    -h | --help) USAGE; exit 1 ;;
    -V) echo "${PGM}: v${VERSION}"; exit 3 ;;
    -x)  set -x ;;
    *)  echo "Option ${1} not known. Exiting..."; echo; USAGE; exit 1 ;;
  esac
    shift
done

echo "`date` ${PGM} (v$VERSION) started (LOGNAME=${LOGNAME})."|tee -a $LOG
echo "ETC=${ETC}"
echo "EXCLUDES=${EXCLUDES}"
echo "FILTER=${FILTER}"
echo "MAIL=${MAIL}"
echo "MAILTO=${MAILTO}"
echo "MAILPERFILER=${MAILPERFILER}"
echo "USD=${USD}"

touch ${TMP} ${TMP}.nfsstat ${TMP}.excludes ${USDMSG} ${WARN} ${TMPCSV} ${CIFSWARN}
# Check & move LOG-file if longer then max.
LOGSIZE=`du -ka $LOG | cut -f1`
if [ $LOGSIZE -ge $MAXLOGSIZE ]; then
  mv $LOG $LOG.old
  touch $LOG
fi

# Init options-file
cat << !EOF >> ${TMP}.options.M1
# H3.1
ssh.access=*
ssh.passwd_auth.enable=on
ssh.pubkey_auth.enable=on
!EOF
cat << !EOF >> ${TMP}.options.M2
# H3.2
ssh1.enable=off
ssh2.enable=on
httpd.admin.enable=on
httpd.admin.ssl.enable=on
ldap.ssl.enable=off
ssl.enable=on
!EOF
cat << !EOF >> ${TMP}.options.M3
# H3.3
telnet.enable=off
telnet.access=none
autologout.telnet.enable=on
rsh.enable=off
rsh.access=none
snmp.enable=on
!EOF
cat << !EOF >> ${TMP}.options.M4
# H3.4
security.passwd.lockout.numtries=4294967294
security.passwd.rules.enable=on
security.passwd.rules.everyone=on
security.passwd.rules.minimum=8
security.passwd.rules.minimum.alphabetic=2
security.passwd.rules.minimum.digit=1
security.passwd.rules.minimum.symbol=1
security.passwd.firstlogin.enable=on
security.passwd.rules.history=5
!EOF
cat << !EOF >> ${TMP}.options.M6
# H3.6
autologout.console.enable=on
autologout.console.timeout=60
autologout.telnet.enable=on
autologout.telnet.timeout=60
ssh.idle.timeout=600
httpd.timeout=300
!EOF
cat << !EOF >> ${TMP}.options.M7
# H3.7
auditlog.enable=on
auditlog.max_file_size=100000000
!EOF
cat << !EOF >> ${TMP}.options.M8
# 3.8
timed.proto=ntp
##timed.servers=${HOSTNAME}
timed.servers=nlxfsd01
!EOF
cat << !EOF >> ${TMP}.options.M14
# H3.14.2
nfs.mount_rootonly=on
wafl.root_only_chown=on
ip.match_any_ifaddr=off 
ip.fastpath.enable=on
pcnfsd.enable=off
nfs.udp.enable=off
nfs.tcp.enable=on
nfs.export.auto-update=off
!EOF

touch ${TMP}.excludes
if [ ! -f ${EXCLUDES} ]; then
  echo "`date` No ${EXCLUDES} found. So NO excludes will be made."|tee -a ${LOG}
else
# Remove # from .excludes-file
  echo "`date` ${EXCLUDES} found. Will be used."|tee -a ${LOG}
  cat ${EXCLUDES} |grep -v ^# >> ${TMP}.excludes
fi  # {EXCLUDES}

# Create header for .csv-file
echo -n "# Host ; M01 - Enable secure access ;" >> ${TMPCSV}
echo -n "M02 - Disable insecure and unneeded protocols ;" >> ${TMPCSV}
echo -n "M03 - Controlled access to FSOD management components ;" >> ${TMPCSV}
echo -n "M04 - Password Security ;" >> ${TMPCSV}
echo -n "M05 - Password hardening ;" >> ${TMPCSV}
echo -n "M06 - Autologout ;" >> ${TMPCSV}
echo -n "M07 - Logging ;" >> ${TMPCSV}
echo -n "M08 - Network Time Protocol (NTP);" >> ${TMPCSV}
echo -n "M09 - Secure Network configuration ;" >> ${TMPCSV}
echo -n "M10 - Login banner ;" >> ${TMPCSV}
echo -n "M11 - Role-Based Access Control ;" >> ${TMPCSV}
echo -n "M12 - No group account ;" >> ${TMPCSV}
echo -n "M13 - CIFS ;" >> ${TMPCSV}
echo -n "M14 - NFS ;" >> ${TMPCSV}
echo -n "M15 - iSCSI ;" >> ${TMPCSV}
echo -n "M16 - Access of root volume ;" >> ${TMPCSV}
echo  "" >> ${TMPCSV}

# Start Checking (loop)
for FILER in `cat ${FILERS}|grep -v \^#|awk -F\; '{print $1}'|sort|grep ${FILTER}`
do
  echo "" | tee -a ${TMP}
  echo "* ${FILER}" | tee -a ${TMP}
  echo "`date` ${PGM}: ${FILER}."|tee -a $LOG

  echo -n "${FILER};" >> ${TMPCSV}

  echo "+ M01 - Enable secure access" | tee -a ${TMP}
  WARNCNT=0
  TTLCNT=0
  echo "- Options (H 3.1) ${FILER}:" | tee -a ${TMP}
  CHECK_FILER_OPTIONS ${FILER} "M1"
  echo "- Hosts.equiv (H3.1) ${FILER}: & vfilers" | tee -a ${TMP}
# 3.1	Enable secure access: No Telnet, RSH & Hosts.equiv
# Check hosts.equiv
  HOSTSEQUIV="`${SSH} ${FILER} rdfile /etc/hosts.equiv|grep -v \^#`"
  let TTLCNT=${TTLCNT}+1
  if [ "${HOSTSEQUIV}" != "" ]; then
    echo "${FILER}: /etc/hosts.equiv is NOT empty."|tee -a ${TMP}|tee -a ${WARN}
    let WARNCNT=${WARNCNT}+1
    echo ${HOSTSEQUIV} | tee -a ${TMP}
  fi
# Check Hosts.equiv, per vfiler
  ${SSH} ${FILER} vfiler status | grep running | grep -v vfiler | awk '{print $1}' | while read VFILER
  do
    VFILERROOTVOL="`${SSH} ${FILER} vfiler status -r ${VFILER}|grep "\[/etc\]"|awk '{print $2}'`"
    HOSTSEQUIV="`${SSH} ${FILER} rdfile ${VFILERROOTVOL}/etc/hosts.equiv 2>/dev/null |grep -v \^# `"
    let TTLCNT=${TTLCNT}+1
    if [ "${HOSTSEQUIV}" != "" ]; then
      echo "${FILER}: ${VFILERROOTVOL}/etc/hosts.equiv is NOT empty."|tee -a ${TMP}
      echo ${HOSTSEQUIV}|tee -a ${TMP}
      echo "${FILER}: ${VFILERROOTVOL}/etc/hosts.equiv is NOT empty."|tee -a ${WARN}
      let WARNCNT=${WARNCNT}+1
      echo ${HOSTSEQUIV}|tee -a ${WARN}
    fi
  done
# Errorly exported volumes, because of "nfs.export.auto-update=on"
# Check per vfiler
echo "- Exported volumes with no information (due to options nfs.export.auto-update=on)." | tee -a ${TMP}
  ${SSH} ${FILER} vfiler status|grep running|grep -v vfiler|awk '{print $1}'|while read VFILER
  do
    ${SSH} ${FILER} vfiler run ${VFILER} df -g|grep -v vfiler|grep -v snapshot|grep -v 'snap reserve'|grep '/vol/'|awk '{print $1}'|while read VOL
    do
      EXPORTFSINFO="`${SSH} ${FILER} vfiler run ${VFILER} exportfs -q ${VOL}|grep vol`"
# Check is it has export-info. If so, do 2nd test.
      if [ "${EXPORTFSINFO}" != "" ]; then
        EXPORTFSINFO="`${SSH} ${FILER} vfiler run ${VFILER} exportfs -q ${VOL}|grep vol|cut -d\= -f4`"
# Check if "short" export-info. If so, its not OK
        let TTLCNT=${TTLCNT}+1
        if [ "${EXPORTFSINFO}" = "" ]; then
          echo "${FILER}/${VFILER}"|tee -a ${TMP}
          ${SSH} ${FILER} vfiler run ${VFILER} exportfs -q ${VOL}|grep vol|tee -a ${TMP}
          echo "${FILER}/${VFILER} Exported volumes with no information (due to options nfs.export.auto-update=on)"|tee -a ${WARN}
          let WARNCNT=${WARNCNT}+1
          ${SSH} ${FILER} vfiler run ${VFILER} exportfs -q ${VOL}|grep vol|tee -a ${WARN}
        fi
      fi
    done
  done
  if [ ${TTLCNT} -gt 0 ]; then
    let PERC="(${TTLCNT}-${WARNCNT})*100/${TTLCNT}"
  else
    let PERC="100"
  fi
  echo "= ${WARNCNT}/${TTLCNT} warnings = ${PERC} %"  | tee -a ${TMP}
  echo -n "${PERC};" >> ${TMPCSV}

  echo "+ M02 - Disable insecure and unneeded protocols" | tee -a ${TMP}
  WARNCNT=0
  TTLCNT=0
# 3.2	Disable insecure and unneeded protocols
  echo "- Options (H 3.2) ${FILER}:" | tee -a ${TMP}
  CHECK_FILER_OPTIONS ${FILER} "M2"
  if [ ${TTLCNT} -gt 0 ]; then
    let PERC="(${TTLCNT}-${WARNCNT})*100/${TTLCNT}"
  else
    let PERC="100"
  fi
  echo "= ${WARNCNT}/${TTLCNT} warnings = ${PERC} %"  | tee -a ${TMP}
  echo -n "${PERC};" >> ${TMPCSV}

  echo "+ M03 - Controlled access to FSOD management components" | tee -a ${TMP}
  WARNCNT=0
  TTLCNT=0
  echo "- Options (H 3.3) ${FILER}:" | tee -a ${TMP}
# 3.3	Controlled access to FSOD management components
  CHECK_FILER_OPTIONS ${FILER} "M3"
  echo "- SNMP-string (H3.3) ${FILER}:" | tee -a ${TMP}
# 3.3	Controlled access to FSOD management components
# Check SNMP-string
  SNMPCOMSTR="`${SSH} ${FILER} snmp community| grep public`"
  if [ "${SNMPCOMSTR}" != "" ]; then
# Exclude
p
    EXCLUDE="`echo "SNMP-community-string=${SNMPCOMSTR}."|egrep -f ${TMP}.excludes`"
    let TTLCNT=${TTLCNT}+1
    if [ "${EXCLUDE}" != "" ]; then
      echo "  (${FILER}: SNMP-community-string=${SNMPCOMSTR}. Must be \"ro ${HOSTNAME}\")=Excluded & accepted." | tee -a ${TMP}
    else
      echo "${FILER}: SNMP-community-string=${SNMPCOMSTR}. Must be \"ro ${HOSTNAME}\""|tee -a ${TMP}|tee -a ${WARN}
      let WARNCNT=${WARNCNT}+1
    fi
  fi
  if [ ${TTLCNT} -gt 0 ]; then
    let PERC="(${TTLCNT}-${WARNCNT})*100/${TTLCNT}"
  else
    let PERC="100"
  fi
  echo "= ${WARNCNT}/${TTLCNT} warnings = ${PERC} %"  | tee -a ${TMP}
  echo -n "${PERC};" >> ${TMPCSV}

  echo "+ M04 - Password Security" | tee -a ${TMP}
  WARNCNT=0
  TTLCNT=0
# 3.4	Password Security
  echo "- Options (H 3.4) ${FILER}:" | tee -a ${TMP}
  CHECK_FILER_OPTIONS ${FILER} "M4"
  if [ ${TTLCNT} -gt 0 ]; then
    let PERC="(${TTLCNT}-${WARNCNT})*100/${TTLCNT}"
  else
    let PERC="100"
  fi
  echo "= ${WARNCNT}/${TTLCNT} warnings = ${PERC} %"  | tee -a ${TMP}
  echo -n "${PERC};" >> ${TMPCSV}

  echo "+ M05 - Password hardening" | tee -a ${TMP}
  echo "  An Query-ticket request (via IMI) will be send to USD." | tee -a ${TMP}
  echo -n "NA;" >> ${TMPCSV}

  echo "+ M06 - Autologout" | tee -a ${TMP}
  WARNCNT=0
  TTLCNT=0
# 3.6	Autologout
  echo "- Options (H 3.6) ${FILER}:" | tee -a ${TMP}
  CHECK_FILER_OPTIONS ${FILER} "M6"
  if [ ${TTLCNT} -gt 0 ]; then
    let PERC="(${TTLCNT}-${WARNCNT})*100/${TTLCNT}"
  else
    let PERC="100"
  fi
  echo "= ${WARNCNT}/${TTLCNT} warnings = ${PERC} %"  | tee -a ${TMP}
  echo -n "${PERC};" >> ${TMPCSV}

  echo "+ M07 - Logging" | tee -a ${TMP}
  WARNCNT=0
  TTLCNT=0
# 3.7	Logging
  echo "- Options (H 3.7) ${FILER}:" | tee -a ${TMP}
  CHECK_FILER_OPTIONS ${FILER} "M7"
  if [ ${TTLCNT} -gt 0 ]; then
    let PERC="(${TTLCNT}-${WARNCNT})*100/${TTLCNT}"
  else
    let PERC="100"
  fi
  echo "= ${WARNCNT}/${TTLCNT} warnings = ${PERC} %"  | tee -a ${TMP}
  echo -n "${PERC};" >> ${TMPCSV}

  echo "+ M08 - Network Time Protocol (NTP)" | tee -a ${TMP}
  WARNCNT=0
  TTLCNT=0
# 3.8	Network Time Protocol (NTP) 
  echo "- Options (H 3.8) ${FILER}:" | tee -a ${TMP}
  CHECK_FILER_OPTIONS ${FILER} "M8"
  if [ ${TTLCNT} -gt 0 ]; then
    let PERC="(${TTLCNT}-${WARNCNT})*100/${TTLCNT}"
  else
    let PERC="100"
  fi
  echo "= ${WARNCNT}/${TTLCNT} warnings = ${PERC} %"  | tee -a ${TMP}
  echo -n "${PERC};" >> ${TMPCSV}

  echo "+ M09 - Secure Network configuration" | tee -a ${TMP}
  WARNCNT=0
  TTLCNT=0
# 3.13	Separation between customers
  echo "- Wrong volumes connected at a vfiler (H3.9) ${FILER}:" | tee -a ${TMP}
# 3.9	Secure Network configuration
# Check if the correct volumes are connect to the right vfiler (Vol: cc_<vfiler>_yyyy) -> v<filer>)
  ${SSH} ${FILER} vfiler status | grep running | grep -v vfiler | awk '{print $1}' | while read VFILER
  do
    echo "  - ${FILER}/${VFILER}:" | tee -a ${TMP}
    CUSTOMPART="`echo ${VFILER}|sed -e 's/nlnafv//g'|sed -e 's/hwnafv//g'`"
    let TTLCNT=${TTLCNT}+1
    FOUND=""  # switch for counting Warnings. When found. Set to 1
#echo "|${CUSTOMPART}|"
# Generate list of volumes which NOT belong to the vfiler (vol.name = vfiler-name)
    ${SSH} ${FILER} vfiler run ${VFILER} vol status|grep online|grep -v vfiler|grep -v "_${CUSTOMPART}_" |while read LINE
    do
# Exclude
      EXCLUDE="`echo ${FILER}/${VFILER}:${LINE} | egrep -f ${TMP}.excludes`"
#echo "|${EXCLUDE}|"
      if [ "${EXCLUDE}" != "" ]; then
        echo "  (${FILER}/${VFILER}:${LINE})=Excluded & accepted."|tee -a ${TMP}
      else
        echo "${FILER}/${VFILER}:${LINE}"|tee -a ${TMP}
        echo "Wrong volume connected to vfiler ${FILER}/${VFILER}:${LINE}"|tee -a ${WARN}
        FOUND=1
      fi
    done
    if [ ${FOUND} ]; then
      let WARNCNT=${WARNCNT}+1
    fi
  done
  if [ ${TTLCNT} -gt 0 ]; then
    let PERC="(${TTLCNT}-${WARNCNT})*100/${TTLCNT}"
  else
    let PERC="100"
  fi
  echo "= ${WARNCNT}/${TTLCNT} warnings = ${PERC} %"  | tee -a ${TMP}
  echo -n "${PERC};" >> ${TMPCSV}

  echo "+ M10 - Login banner" | tee -a ${TMP}
  echo "  The NetApp filer does not have a login banner" | tee -a ${TMP}
  echo -n "NA;" >> ${TMPCSV}

  echo "+ M11 - Role-Based Access Control" | tee -a ${TMP}
  echo "  RBAC is not checked from this script" | tee -a ${TMP}
  echo -n "NA;" >> ${TMPCSV}

  echo "+ M12 - No group account" | tee -a ${TMP}
  echo "  \"No group accounts\" is not checked from this script" | tee -a ${TMP}
  echo -n "NA;" >> ${TMPCSV}

  echo "+ M13 - CIFS" | tee -a ${TMP}
  WARNCNT=0
  TTLCNT=0
# It is preferable to have for all CIFS shares Authenticated Users on 'Full Control'.
# On request of the customer it can be "everyone / Full Control" 
# Local admin (the user administrator on vfiler) need to be disabled. 
# This user is created when CIFS is setup. And need to be disabled. Otherwise this user can access CIFS-shares. 
  echo "  Check shares at vfilers for 'everyone / Full Control'" | tee -a ${TMP}
  echo "${FILER}: These vfilers do have CIFS-share with 'everyone / Full Control'" > ${CIFSWARN}
  echo "Which is not advisable accourding to NLW-OC9-0025 FSOD Security Baseline Measures and Validation, M13 - CIFS" >> ${CIFSWARN}
  ${SSH} ${FILER} vfiler status | grep running | grep -v vfiler | awk '{print $1}' | while read VFILER
  do
    echo "  - ${FILER}/${VFILER}:" | tee -a ${TMP} | tee -a ${CIFSWARN}
# check if the user administrator is disabled
    let TTLCNT=${TTLCNT}+1
    ANSW="`${SSH} ${FILER} vfiler run ${VFILER} useradmin user list administrator | grep 'Status: enabled'`"
    if [ "${ANSW}" != "" ]; then
      echo "The user 'administrator' is still enabled (this should be disabled)." | tee -a ${TMP} | tee -a ${CIFSWARN}
      let WARNCNT=${WARNCNT}+1
    fi

# Check Shares
    ${SSH} ${FILER} vfiler run ${VFILER} cifs shares | grep 'vol' | cut -f1 -d ' ' | while read SHARE
    do
      let TTLCNT=${TTLCNT}+1
      ANSW="`${SSH} ${FILER} vfiler run ${VFILER} cifs shares ${SHARE}| grep everyone`"
      # if "everyone" (ANSW=not empty) then report
      if [ "${ANSW}" != "" ]; then
        echo ${SHARE}: | tee -a ${TMP} | tee -a ${CIFSWARN}
        echo ${ANSW} | tee -a ${TMP} | tee -a ${CIFSWARN}
        let WARNCNT=${WARNCNT}+1
      fi
    done  # SHARE

  done  # vfiler
  if [ ${TTLCNT} -gt 0 ]; then
    let PERC="(${TTLCNT}-${WARNCNT})*100/${TTLCNT}"
  else
    let PERC="100"
  fi
  echo "= ${WARNCNT}/${TTLCNT} warnings = ${PERC} %"  | tee -a ${TMP}
  echo -n "${PERC};" >> ${TMPCSV}
  # Create a seperate USD ticket for this filer when CIFS warnings has been found
  # When -u | --usd, send to USD PER Filer (Filer=CI)
  if [ ${WARNCNT} -gt 0 ] && [ ${USD} ]; then
    CREATE_USD_TICKET ${FILER} "Incident" ${CIFSWARN}
  fi  # [ -s ${WARNCNT} ]

  echo "+ M14 - NFS" | tee -a ${TMP}
  WARNCNT=0
  TTLCNT=0
# 3.14.2	NFS
  echo "- Options (H 3.14.2) ${FILER}:" | tee -a ${TMP}
  CHECK_FILER_OPTIONS ${FILER} "M14"
  echo "- UDP-calls (H3.14.2) ${FILER}:" | tee -a ${TMP}
# 3.14.2	NFS
# Check UDP-usage, per vfiler
  ${SSH} ${FILER} vfiler status | grep running | grep -v vfiler | awk '{print $1}' | while read VFILER
  do
# Get counter of UDP-calls. Expected to be 0. So UDP is not used
# do use nfsstat without -t (since last reboot).
# So counters can be Zeroed & checked a 2nd time
    ${SSH} ${FILER} vfiler run ${VFILER} nfsstat > ${TMP}.nfsstat
    LINENR="`grep -n UDP ${TMP}.nfsstat|cut -d\: -f1`"
    let "LINENR= ${LINENR} +2"
    UDPCALLS="`head -n ${LINENR} ${TMP}.nfsstat|tail -1|awk '{print $1}'`"
    if [ ${UDPCALLS} -gt 0 ]; then
      echo "${FILER}/${VFILER}:UDP-calls=${UDPCALLS} (since last Zeroed). Expected to be 0." | tee -a ${TMP}
    fi
  done
  if [ ${TTLCNT} -gt 0 ]; then
    let PERC="(${TTLCNT}-${WARNCNT})*100/${TTLCNT}"
  else
    let PERC="100"
  fi
  echo "= ${WARNCNT}/${TTLCNT} warnings = ${PERC} %"  | tee -a ${TMP}
  echo -n "${PERC};" >> ${TMPCSV}

  echo "+ M15 - iSCSI"|tee -a ${TMP}
  WARNCNT=0
  TTLCNT=0
#  echo "  Will check if iSCSI is running and if there iSCSI LUNs are configured. " | tee -a ${TMP}
  ANSW="`${SSH} ${FILER} iscsi status| grep 'iSCSI service is running'`"
  # Check is iSCSI is running, then check LUNS. If iSCSI is Enabled & NO LUNS, this is NOT OK
  if [ "${ANSW}" != "" ]; then
    # iSCSI i running.
    echo "  iSCSI is running. Will check if there are LUNs configured."|tee -a ${TMP}
    LUNSFOUND=""
    ${SSH} ${FILER} vfiler status | grep running | grep -v vfiler | awk '{print $1}' | while read VFILER
    do
      let TTLCNT=${TTLCNT}+1
      LUNS="`${SSH} ${FILER} vfiler run ${VFILER} lun show|grep 'vol'`"
      # When LUNs found. Is OK.
      echo "  - ${FILER}/${VFILER}:"|tee -a ${TMP}
      if [ "${LUNS}" != "" ]; then
        echo "${LUNS}"|tee -a ${TMP}
        LUNSFOUND="1"
      else
        echo "No LUNs found."|tee -a ${TMP}
      fi  # ${LUNS}
    done  # vfilers
    if [ "${LUNSFOUND}" = "" ]; then
      echo "  - ${FILER}/${VFILER}:" | tee -a ${TMP}
      echo "No LUNs found (at all vfilers), with iSCSI enabled. iSCSI should be disabled."|tee -a ${TMP}
      let WARNCNT=${WARNCNT}+1
    fi
  else
    echo "  iSCSI is NOT running." | tee -a ${TMP}
  fi  # ANSW
  if [ ${TTLCNT} -gt 0 ]; then
    let PERC="(${TTLCNT}-${WARNCNT})*100/${TTLCNT}"
  else
    let PERC="100"
  fi
  echo "= ${WARNCNT}/${TTLCNT} warnings = ${PERC} %"  | tee -a ${TMP}
  echo -n "${PERC};" >> ${TMPCSV}

  echo "+ M16 - Access of root volume" | tee -a ${TMP}
  WARNCNT=0
  TTLCNT=0
# 3.16	Access of root-volume (vol0). Check export of root-volume(vol0)
  echo "- List of root-volume (vol0) exports of ${FILER} (if not empty) (H3.16):" | tee -a ${TMP}
  ROOTVOL="`${SSH} ${FILER} vol status|grep ' root'|awk '{print $1}'`"
  ROOTVOLEXPORT="`${SSH} ${FILER} exportfs | grep \"/vol/${ROOTVOL}\"`"
  if [ "${ROOTVOLEXPORT}" != "" ]; then
    let TTLCNT=${TTLCNT}+1
    EXCLUDE="`echo "${FILER}:${ROOTVOLEXPORT}" | egrep -f ${TMP}.excludes`"
#echo "|${EXCLUDE}|"
    if [ "${EXCLUDE}" != "" ]; then
      echo "  (${FILER}:${ROOTVOLEXPORT})=Excluded & accepted."|tee -a ${TMP}
    else
      echo "${FILER}:${ROOTVOLEXPORT}"|tee -a ${TMP}
      echo "Root-volume exported; ${FILER}:${ROOTVOLEXPORT}"|tee -a ${WARN}
      let WARNCNT=${WARNCNT}+1
    fi
  fi
  echo "- List of root-volume (vol0) exports of vfilers (if not empty) (H3.16):" | tee -a ${TMP}
  ${SSH} ${FILER} vfiler status | grep running | grep -v vfiler | awk '{print $1}' | while read VFILER
  do
    VFILERROOTVOL="`${SSH} ${FILER} vfiler status -r ${VFILER}|grep "\[/etc\]"|awk '{print $2}'`"
    VFILERROOTVOLEXPORT="`${SSH} ${FILER} vfiler run ${VFILER} exportfs | grep ${VFILERROOTVOL}`"
    if [ "${VFILERROOTVOLEXPORT}" != "" ]; then
      let TTLCNT=${TTLCNT}+1
      EXCLUDE="`echo "${FILER}/${VFILER}:${VFILERROOTVOLEXPORT}" | egrep -f ${TMP}.excludes`"
#echo "|${EXCLUDE}|"
      if [ "${EXCLUDE}" != "" ]; then
        echo "  (${FILER}/${VFILER}:${VFILERROOTVOLEXPORT})=Excluded & accepted."|tee -a ${TMP}
      else
        echo "${FILER}/${VFILER}:${VFILERROOTVOLEXPORT}"|tee -a ${TMP}
        echo "Root-volume exported; ${FILER}/${VFILER}:${VFILERROOTVOLEXPORT}"|tee -a ${WARN}
        let WARNCNT=${WARNCNT}+1
      fi
    fi
  done
  if [ ${TTLCNT} -gt 0 ]; then
    let PERC="(${TTLCNT}-${WARNCNT})*100/${TTLCNT}"
  else
    let PERC="100"
  fi
  echo "= ${WARNCNT}/${TTLCNT} warnings = ${PERC} %"  | tee -a ${TMP}
  echo -n "${PERC};" >> ${TMPCSV}

# When -u | --usd, send to USD PER Filer (Filer=CI)
  if [ ${USD} ]; then
    if [ -s ${WARN} ]; then
      CREATE_USD_TICKET ${FILER} "Incident" ${WARN}
      cp /dev/null ${WARN}
    fi  # [ -s ${WARN} ]

    # Create USD-query-tickets for "M05 - Password hardening" 4 times (every 3 month) a year
    # Must be AFTER the above USD-ticket creating. Because ${WARN} is used to transport ticket Description
    MON="`date +%m`"
    if [ ${MON} = 01 ] || [ ${MON} = 04 ] || [ ${MON} = 07 ] || [ ${MON} = 10 ]; then
      echo "${FILER}: Has the root / administrator password of the filer being changed?" >> ${WARN}
      echo "Accoording to the Atos Origin Password Policy, AOM-SEC-0001" >> ${WARN}
      echo "This request is made to fullfill NLW-OC9-0025 FSOD Security Baseline Measures and Validation, M05 - Password hardening" >> ${WARN}
       CREATE_USD_TICKET ${FILER} "Query" ${WARN}

       if [ ${MAILPERFILER} ]; then
         cat ${WARN}|unix2dos|uuencode ${TXT}|mailx -s ":${HOSTNAME}: ${FILER} Check security baseline settings report (.TXT) at `date +%Y-%m-%d_%H:%M:%S` [${PGM} v${VERSION}]" ${MAILTO}
         echo "`date` MailedPerFiler to ${MAILTO} "|tee -a ${LOG}
       fi  # [ ${MAILPERFILER} ]

       cp /dev/null ${WARN}
    fi  # ${MON}

  fi  # [ ${USD} ]

  if [ ${MAILPERFILER} ]; then
    cat ${WARN}|unix2dos|uuencode ${TXT}|mailx -s ":${HOSTNAME}: ${FILER} Check security baseline settings report (.TXT) at `date +%Y-%m-%d_%H:%M:%S` [${PGM} v${VERSION}]" ${MAILTO}
    echo "`date` MailedPerFiler to ${MAILTO} "|tee -a ${LOG}
    cp /dev/null ${WARN}
  fi  # [ ${MAILPERFILER} ]

  echo " " >> ${TMPCSV}
done  # for FILER

# Create USD-query-tickets for "M07 - Logging"
if [ ${USD} ]; then
  echo "${HOSTNAME}: Has the monthly backup of FSOD auditlogfiles run correctly (without errors)?" >> ${WARN}
  echo "This request is made to fullfill NLW-OC9-0025 FSOD Security Baseline Measures and Validation, M07 - Logging" >> ${WARN}
echo ${WARN}
  CREATE_USD_TICKET ${HOSTNAME} "Query" ${WARN}
  cp /dev/null ${WARN}
fi  # [ ${USD} ]

echo "#"|tee -a ${TMP}
echo "# Output (${TXT}) from ${HOSTNAME} at `date +%Y-%m-%d_%H:%M:%S` of ${PGM} version ${VERSION}"|tee -a ${TMP}
echo "# (etc)FILERS=${FILERS}, FILTER=${FILTER}, sentMAIL=${MAIL}, MAILTO=${MAILTO} MPF=${MAILPERFILER} "|tee -a ${TMP}
echo "# Ready at `date`"|tee -a ${TMP}

# save the "output"(tmp) file to .out
cp ${TMP} /tmp/${PGM}.out

# Mail the info
if [ ${MAIL} ]; then
  cat ${TMP}|unix2dos|uuencode ${TXT}|mailx -s ":${HOSTNAME}: Check security baseline settings report (.TXT) at `date +%Y-%m-%d_%H:%M:%S` [${PGM} v${VERSION}]" ${MAILTO}
  cat ${TMPCSV}|uuencode ${CSV}|mailx -s ":${HOSTNAME}: Check security baseline output sheet (.CSV) at `date +%Y-%m-%d_%H:%M:%S` [${PGM} v${VERSION}]" ${MAILTO}
  echo "`date` ${PGM}: Mailed (.TXT & .CSV) to ${MAILTO}."|tee -a ${LOG}
fi  # if [ ${MAIL} ]

cp ${TMP} /tmp/${PGM}.txt
cp ${TMPCSV} /tmp/${PGM}.csv

# Cleanup
rm ${TMP} ${TMP}.options.M* ${TMP}.nfsstat ${TMP}.excludes ${USDMSG} ${WARN} ${TMPCSV} ${CIFSWARN}
echo "`date` ${PGM} (v$VERSION) finished."|tee -a $LOG
exit 0

