From f9c4e4a64269bc4211a59b58b7657b967d8958cc Mon Sep 17 00:00:00 2001
From: Derek Ahn <dahn@hpe.com>
Date: Mon, 18 Mar 2019 15:48:50 -0700
Subject: [PATCH] Add forked audit shell script

---
 cs-audit.sh | 1638 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 1638 insertions(+)
 create mode 100755 cs-audit.sh

diff --git a/cs-audit.sh b/cs-audit.sh
new file mode 100755
index 0000000..165c46e
--- /dev/null
+++ b/cs-audit.sh
@@ -0,0 +1,1638 @@
+#!/bin/bash
+
+#This script will run through several checks and for each check output to the terminal 'OK' or 'ERROR
+#The checks are designed to test whether or not the host conforms to the benchmarks in the
+#following document
+#https://benchmarks.cisecurity.org/tools2/linux/CIS_CentOS_Linux_7_Benchmark_v1.1.0.pdf
+
+#This is aimed to be a starting point for a sysadmin to check or audit hosts he/she supports
+#It's envisaged that it will need customising to suit a particular environment
+#eg. there are about 200 checks, someone may want to chop out X of them to suit their environment
+#The script does not change anything on the host, mostly it runs a lot of greps & cuts
+#on config files.
+#To quickly get an idea of what this script does have a look at the 'main' and 'func_wrapper' functions
+#Copyright (c) 2015, Ross Hamilton. All rights reserved.
+
+
+# colors
+RED_COLOR=`tput setaf 1`
+GREEN_COLOR=`tput setaf 2`
+RESET_COLOR=`tput sgr0`
+
+FSTAB='/etc/fstab'
+YUM_CONF='/etc/yum.conf'
+GRUB_CFG='/boot/grub2/grub.cfg'
+GRUB_DIR='/etc/grub.d'
+SELINUX_CFG='/etc/selinux/config'
+NTP_CONF='/etc/ntp.conf'
+SYSCON_NTPD='/etc/sysconfig/ntpd'
+LIMITS_CNF='/etc/security/limits.conf'
+SYSCTL_CNF='/etc/sysctl.conf'
+CENTOS_REL='/etc/centos-release'
+LATEST_REL_STR='CentOS Linux release 7.6.1810 (Core)'
+HOSTS_ALLOW='/etc/hosts.allow'
+HOSTS_DENY='/etc/hosts.deny'
+CIS_CNF='/etc/modprobe.d/CIS.conf'
+RSYSLOG_CNF='/etc/rsyslog.conf'
+AUDITD_CNF='/etc/audit/auditd.conf'
+AUDIT_RULES='/etc/audit/audit.rules'
+LOGR_SYSLOG='/etc/logrotate.d/syslog'
+ANACRONTAB='/etc/anacrontab'
+CRONTAB='/etc/crontab'
+CRON_HOURLY='/etc/cron.hourly'
+CRON_DAILY='/etc/cron.daily'
+CRON_WEEKLY='/etc/cron.weekly'
+CRON_MONTHLY='/etc/cron.monthly'
+CRON_DIR='/etc/cron.d'
+AT_ALLOW='/etc/at.allow'
+AT_DENY='/etc/at.deny'
+CRON_ALLOW='/etc/cron.allow'
+CRON_DENY='/etc/cron.deny'
+SSHD_CFG='/etc/ssh/sshd_config'
+SYSTEM_AUTH='/etc/pam.d/system-auth'
+PWQUAL_CNF='/etc/security/pwquality.conf'
+PASS_AUTH='/etc/pam.d/password-auth'
+PAM_SU='/etc/pam.d/su'
+GROUP='/etc/group'
+LOGIN_DEFS='/etc/login.defs'
+PASSWD='/etc/passwd'
+SHADOW='/etc/shadow'
+GSHADOW='/etc/gshadow'
+BASHRC='/etc/bashrc'
+PROF_D='/etc/profile.d'
+MOTD='/etc/motd'
+ISSUE='/etc/issue'
+ISSUE_NET='/etc/issue.net'
+BANNER_MSG='/etc/dconf/db/gdm.d/01-banner-message'
+
+function separate_partition {
+  # Test that the supplied $1 is a separate partition
+
+  local filesystem="${1}"
+  grep -q "[[:space:]]${filesystem}[[:space:]]" "${FSTAB}" || return
+}
+
+function mount_option {
+  # Test the the supplied mount option $2 is in use on the supplied filesystem $1
+
+  local filesystem="${1}"
+  local mnt_option="${2}"
+
+  grep "[[:space:]]${filesystem}[[:space:]]" "${FSTAB}" | grep -q "${mnt_option}" || return
+
+  mount | grep "[[:space:]]${filesystem}[[:space:]]" | grep -q "${mnt_option}" || return
+}
+
+function bind_mounted_to {
+  # Test that a directory /foo/dir is bind mounted onto a particular filesystem
+
+  local directory="${1}"
+  local filesystem="${2}"
+  local E_NO_MOUNT_OUTPUT=1
+
+  grep "^${filesystem}[[:space:]]" "${FSTAB}" | grep -q "${directory}" || return
+
+  local grep_mount
+  grep_mount=$(mount | grep "^${filesystem}[[:space:]]" | grep "${directory}")
+  #If $directory doesn't appear in the mount output as mounted on the $filesystem
+  #it may appear in the output as being mounted on the same device as $filesystem, check for this
+  local fs_dev
+  local dir_dev
+  fs_dev="$(mount | grep "[[:space:]]${filesystem}[[:space:]]" | cut -d" " -f1)"
+  dir_dev="$(mount | grep "[[:space:]]${directory}[[:space:]]" | cut -d" " -f1)"
+  if [[ -z "${grep_mount}" ]] && [[ "${fs_dev}" != "${dir_dev}" ]] ; then
+    return "${E_NO_MOUNT_OUTPUT}"
+  fi
+}
+
+function test_disable_mounting {
+  # Test the the supplied filesystem type $1 is disabled
+
+  local module="${1}"
+  modprobe -n -v ${module} | grep -q "install \+/bin/true" || return
+
+  lsmod | grep -qv "${module}" || return
+}
+
+function centos_gpg_key_installed {
+  # Test CentOS GPG Key is installed
+  local centos_off_str='gpg(CentOS-7 Key (CentOS 7 Official Signing Key) <security@centos.org>)'
+  rpm -q --queryformat "%{SUMMARY}\n" gpg-pubkey | grep -q "${centos_off_str}" || return
+}
+
+function yum_gpgcheck {
+  # Check that gpgcheck is Globally Activated
+  cut -d \# -f1 ${YUM_CONF} | grep 'gpgcheck' | grep -q 'gpgcheck=1' || return
+}
+
+function yum_update {
+  # Check for outstanding pkg update with yum
+  yum -q check-update || return
+}
+
+function pkg_integrity {
+  # Verify the installed packages by comparing the installed files against file info stored in the pkg
+  local rpm_out
+  rpm_out="$(rpm -qVa | awk '$2 != "c" { print $0}')"
+  [[ -z "${rpm_out}" ]] || return
+}
+
+function rpm_installed {
+  # Test whether an rpm is installed
+
+  local rpm="${1}"
+  local rpm_out
+  rpm_out="$(rpm -q --queryformat "%{NAME}\n" ${rpm})"
+  [[ "${rpm}" = "${rpm_out}" ]] || return
+}
+
+function verify_aide_cron {
+  # Verify there is a cron job scheduled to run the aide check
+  crontab -u root -l | cut -d\# -f1 | grep -q "aide \+--check" || return
+}
+
+function verify_selinux_grubcfg {
+  # Verify SELinux is not disabled in grub.cfg file
+
+  local grep_out1
+  grep_out1="$(grep selinux=0 ${GRUB_CFG})"
+  [[ -z "${grep_out1}" ]] || return
+
+  local grep_out2
+  grep_out2="$(grep enforcing=0 ${GRUB_CFG})"
+  [[ -z "${grep_out2}" ]] || return
+}
+
+function verify_selinux_state {
+  # Verify SELinux configured state in /etc/selinux/config
+  cut -d \# -f1 ${SELINUX_CFG} | grep 'SELINUX=' | tr -d '[[:space:]]' | grep -q 'SELINUX=enforcing' || return
+}
+
+function verify_selinux_policy {
+  # Verify SELinux policy in /etc/selinux/config
+  cut -d \# -f1 ${SELINUX_CFG} | grep 'SELINUXTYPE=' | tr -d '[[:space:]]' | grep -q 'SELINUXTYPE=targeted' || return
+}
+
+function rpm_not_installed {
+  # Check that the supplied rpm $1 is not installed
+  local rpm="${1}"
+  rpm -q ${rpm} | grep -q "package ${rpm} is not installed" || return
+}
+
+function unconfined_procs {
+  # Test for unconfined daemons
+  local ps_out
+  ps_out="$(ps -eZ | egrep 'initrc|unconfined' | egrep -v 'bash|ps|grep')"
+  [[ -n "${ps_out}" ]] || return
+}
+
+function check_grub_owns {
+  # Check User/Group Owner on grub.cfg file
+  stat -L -c "%u %g" ${GRUB_CFG} | grep -q '0 0' || return
+}
+
+function check_grub_perms {
+  # Check Perms on grub.cfg file
+  stat -L -c "%a" ${GRUB_CFG} | grep -q '.00' || return
+}
+
+function check_file_perms {
+  # Check Perms on a supplied file match supplied pattern
+  local file="${1}"
+  local pattern="${2}"
+
+  stat -L -c "%a" ${file} | grep -q "${pattern}" || return
+}
+
+function check_root_owns {
+  # Check User/Group Owner on the specified file
+  local file="${1}"
+  stat -L -c "%u %g" ${file} | grep -q '0 0' || return
+}
+
+function check_boot_pass {
+  grep -q 'set superusers=' "${GRUB_CFG}"
+  if [[ "$?" -ne 0 ]]; then
+    grep -q 'set superusers=' ${GRUB_DIR}/* || return
+    file="$(grep 'set superusers' ${GRUB_DIR}/* | cut -d: -f1)"
+    grep -q 'password' "${file}" || return
+  else
+    grep -q 'password' "${GRUB_CFG}" || return
+  fi
+}
+
+function check_svc_not_enabled {
+  # Verify that the service $1 is not enabled
+  local service="$1"
+  systemctl list-unit-files | grep -qv "${service}" && return
+  systemctl is-enabled "${service}" | grep -q 'enabled' || return
+}
+
+function check_svc_enabled {
+  # Verify that the service $1 is enabled
+  local service="$1"
+  systemctl list-unit-files | grep -q "${service}.service" || return
+  systemctl is-enabled "${service}" | grep -q 'enabled' && return
+}
+
+function ntp_cfg {
+  cut -d\# -f1 ${NTP_CONF} | egrep "restrict{1}[[:space:]]+default{1}" ${NTP_CONF} | grep kod \
+| grep nomodify | grep notrap | grep nopeer | grep -q noquery || return
+
+  cut -d\# -f1 ${NTP_CONF} | egrep "restrict{1}[[:space:]]+\-6{1}[[:space:]]+default" | grep kod \
+| grep nomodify | grep notrap | grep nopeer | grep -q noquery || return
+
+  cut -d\# -f1 ${NTP_CONF} | egrep -q "^[[:space:]]*server" || return
+
+  cut -d\# -f1 ${SYSCON_NTPD} | grep "OPTIONS=" | grep -q "ntp:ntp" || return
+}
+
+function restrict_core_dumps {
+  # Verify that suid programs cannot dump their core
+  egrep -q "\*{1}[[:space:]]+hard[[:space:]]+core[[:space:]]+0" "${LIMITS_CNF}" || return
+  cut -d\# -f1 ${SYSCTL_CNF} | grep fs.suid_dumpable | cut -d= -f2 | tr -d '[[:space:]]' | grep -q '0' || return
+}
+
+function chk_sysctl_cnf {
+  # Check the sysctl_conf file contains a particular flag, set to a particular value
+  local flag="$1"
+  local value="$2"
+  local sysctl_cnf="$3"
+
+  cut -d\# -f1 ${sysctl_cnf} | grep "${flag}" | cut -d= -f2 | tr -d '[[:space:]]' | grep -q "${value}" || return
+}
+
+
+function chk_sysctl {
+  local flag="$1"
+  local value="$2"
+
+  sysctl "${flag}" | cut -d= -f2 | tr -d '[[:space:]]' | grep -q "${value}" || return
+}
+
+function chk_latest_rel {
+  grep -q "${LATEST_REL_STR}" "${CENTOS_REL}" || return
+}
+
+function sticky_wrld_w_dirs {
+  dirs="$(df --local -P | awk {'if (NR!=1) print $6'} | xargs -I '{}' find '{}' -xdev -type d \
+\( -perm -0002 -a ! -perm -1000 \))"
+  [[ -z "${dirs}" ]] || return
+}
+
+function check_umask {
+  cut -d\# -f1 /etc/sysconfig/init | grep -q "umask[[:space:]]027" || return
+}
+
+function check_def_tgt {
+  #Check that the default boot target is multi-user.target
+  local default_tgt
+  default_tgt="$(systemctl get-default)"
+  [[ "${default_tgt}" = "multi-user.target" ]] || return
+}
+
+function mta_local_only {
+  # If port 25 is being listened on, check it is on the loopback address
+  netstat_out="$(netstat -an | grep "LIST" | grep ":25[[:space:]]")"
+  if [[ "$?" -eq 0 ]] ; then
+    ip=$(echo ${netstat_out} | cut -d: -f1 | cut -d" " -f4)
+    [[ "${ip}" = "127.0.0.1" ]] || return
+  fi
+}
+
+function ip6_router_advertisements_dis {
+  # Check that IPv6 Router Advertisements are disabled
+  # If ipv6 is disabled then we don't mind what IPv6 router advertisements are set to
+  # If ipv6 is enabled then both settings should be set to zero
+  chk_sysctl net.ipv6.conf.all.disable_ipv6 1 && return
+  chk_sysctl net.ipv6.conf.all.accept_ra 0 || return
+  chk_sysctl net.ipv6.conf.default.accept_ra 0 || return
+}
+
+function ip6_redirect_accept_dis {
+  # Check that IPv6 Redirect Acceptance is disabled
+  # If ipv6 is disabled then we don't mind what IPv6 redirect acceptance is set to
+  # If ipv6 is enabled then both settings should be set to zero
+  chk_sysctl net.ipv6.conf.all.disable_ipv6 1 && return
+  chk_sysctl net.ipv6.conf.all.accept_redirects 0 || return
+  chk_sysctl net.ipv6.conf.default.accept_redirects 0 || return
+}
+
+function chk_file_exists {
+  local file="$1"
+  [[ -f "${file}" ]] || return
+}
+
+function chk_hosts_deny_content {
+  # Check the hosts.deny file resembles ALL: ALL
+  cut -d\# -f1 ${HOSTS_DENY} | grep -q "ALL[[:space:]]*:[[:space:]]*ALL" || return
+}
+
+function chk_cis_cnf {
+  local protocol="$1"
+  local file="$2"
+  grep -q "install[[:space:]]${protocol}[[:space:]]/bin/true" ${file} || return
+}
+
+function chk_rsyslog_content {
+  # rsyslog should be configured to send logs to a remote host
+  # grep output should resemble
+  # *.* @@loghost.example.com
+  grep -q "^*.*[^I][^I]*@" ${RSYSLOG_CNF} || return
+}
+
+function audit_log_storage_size {
+  # Check the max size of the audit log file is configured
+  cut -d\# -f1 ${AUDITD_CNF} | egrep -q "max_log_file[[:space:]]|max_log_file=" || return
+}
+
+
+function dis_on_audit_log_full {
+  # Check auditd.conf is configured to notify the admin and halt the system when audit logs are full
+  cut -d\# -f2 ${AUDITD_CNF} | grep 'space_left_action' | cut -d= -f2 | tr -d '[[:space:]]' | grep -q 'email' || return
+  cut -d\# -f2 ${AUDITD_CNF} | grep 'action_mail_acct' | cut -d= -f2 | tr -d '[[:space:]]' | grep -q 'root' || return
+  cut -d\# -f2 ${AUDITD_CNF} | grep 'admin_space_left_action' | cut -d= -f2 | tr -d '[[:space:]]' | grep -q 'halt' || return
+}
+
+function keep_all_audit_info {
+  # Check auditd.conf is configured to retain audit logs
+  cut -d\# -f2 ${AUDITD_CNF} | grep 'max_log_file_action' | cut -d= -f2 | tr -d '[[:space:]]' | grep -q 'keep_logs' || return
+}
+
+function audit_procs_prior_2_auditd {
+  # Check lines that start with linux have the audit=1 parameter set
+  grep_grub="$(grep "^[[:space:]]*linux" ${GRUB_CFG} | grep -v 'audit=1')"
+  [[ -z "${grep_grub}" ]] || return
+}
+
+function audit_date_time {
+  # Confirm that the time-change lines specified below do appear in the audit.rules file
+  cut -d\# -f1 ${AUDIT_RULES} | egrep "\-k[[:space:]]+time-change" | egrep "\-S[[:space:]]+settimeofday" \
+  | egrep "\-S[[:space:]]+adjtimex" | egrep "\-F[[:space:]]+arch=b64" | egrep -q "\-a[[:space:]]+always,exit|\-a[[:space:]]+exit,always" || return
+  cut -d\# -f1 ${AUDIT_RULES} | egrep "\-k[[:space:]]+time-change" | egrep "\-S[[:space:]]+settimeofday" \
+  | egrep "\-S[[:space:]]+adjtimex" | egrep "\-F[[:space:]]+arch=b32" | egrep "\-S[[:space:]]+stime" | egrep -q "\-a[[:space:]]+always,exit|\-a[[:space:]]+exit,always" || return
+  cut -d\# -f1 ${AUDIT_RULES} | egrep "\-k[[:space:]]+time-change" | egrep "\-F[[:space:]]+arch=b64" \
+  | egrep "\-S[[:space:]]+clock_settime" | egrep -q "\-a[[:space:]]+always,exit|\-a[[:space:]]+exit,always" || return
+  cut -d\# -f1 ${AUDIT_RULES} | egrep "\-k[[:space:]]+time-change" | egrep "\-F[[:space:]]+arch=b32" \
+  | egrep "\-S[[:space:]]+clock_settime" | egrep -q "\-a[[:space:]]+always,exit|\-a[[:space:]]+exit,always" || return
+  cut -d\# -f1 ${AUDIT_RULES} | egrep "\-k[[:space:]]+time-change" | egrep "\-p[[:space:]]+wa" \
+  | egrep -q "\-w[[:space:]]+\/etc\/localtime" || return
+}
+
+function audit_user_group {
+  # Confirm that the identity lines specified below do appear in the audit.rules file
+  cut -d\# -f1 ${AUDIT_RULES} | egrep "\-k[[:space:]]+identity" | egrep "\-p[[:space:]]+wa" \
+  | egrep -q "\-w[[:space:]]+\/etc\/group" || return
+  cut -d\# -f1 ${AUDIT_RULES} | egrep "\-k[[:space:]]+identity" | egrep "\-p[[:space:]]+wa" \
+  | egrep -q "\-w[[:space:]]+\/etc\/passwd" || return
+  cut -d\# -f1 ${AUDIT_RULES} | egrep "\-k[[:space:]]+identity" | egrep "\-p[[:space:]]+wa" \
+  | egrep -q "\-w[[:space:]]+\/etc\/gshadow" || return
+  cut -d\# -f1 ${AUDIT_RULES} | egrep "\-k[[:space:]]+identity" | egrep "\-p[[:space:]]+wa" \
+  | egrep -q "\-w[[:space:]]+\/etc\/shadow" || return
+  cut -d\# -f1 ${AUDIT_RULES} | egrep "\-k[[:space:]]+identity" | egrep "\-p[[:space:]]+wa" \
+  | egrep -q "\-w[[:space:]]+\/etc\/security\/opasswd" || return
+}
+
+function audit_network_env {
+  # Confirm that the system-locale lines specified below do appear in the audit.rules file
+  cut -d\# -f1 ${AUDIT_RULES} | egrep "\-k[[:space:]]+system-locale" | egrep "\-S[[:space:]]+sethostname" \
+  | egrep "\-S[[:space:]]+setdomainname" | egrep "\-F[[:space:]]+arch=b64" | egrep -q "\-a[[:space:]]+always,exit|\-a[[:space:]]+exit,always" || return
+  cut -d\# -f1 ${AUDIT_RULES} | egrep "\-k[[:space:]]+system-locale" | egrep "\-S[[:space:]]+sethostname" \
+  | egrep "\-S[[:space:]]+setdomainname" | egrep "\-F[[:space:]]+arch=b32" | egrep -q "\-a[[:space:]]+always,exit|\-a[[:space:]]+exit,always" || return
+  cut -d\# -f1 ${AUDIT_RULES} | egrep "\-k[[:space:]]+system-locale" | egrep "\-p[[:space:]]+wa" \
+  | egrep -q "\-w[[:space:]]+\/etc\/issue" || return
+  cut -d\# -f1 ${AUDIT_RULES} | egrep "\-k[[:space:]]+system-locale" | egrep "\-p[[:space:]]+wa" \
+  | egrep -q "\-w[[:space:]]+\/etc\/issue.net" || return
+  cut -d\# -f1 ${AUDIT_RULES} | egrep "\-k[[:space:]]+system-locale" | egrep "\-p[[:space:]]+wa" \
+  | egrep -q "\-w[[:space:]]+\/etc\/hosts" || return
+  cut -d\# -f1 ${AUDIT_RULES} | egrep "\-k[[:space:]]+system-locale" | egrep "\-p[[:space:]]+wa" \
+  | egrep -q "\-w[[:space:]]+\/etc\/sysconfig\/network" || return
+}
+
+function audit_logins_logouts {
+  # Confirm that the logins lines specified below do appear in the audit.rules file
+  cut -d\# -f1 ${AUDIT_RULES} | egrep "\-k[[:space:]]+logins" | egrep "\-p[[:space:]]+wa" \
+  | egrep -q "\-w[[:space:]]+\/var\/log\/faillog" || return
+  cut -d\# -f1 ${AUDIT_RULES} | egrep "\-k[[:space:]]+logins" | egrep "\-p[[:space:]]+wa" \
+  | egrep -q "\-w[[:space:]]+\/var\/log\/lastlog" || return
+  cut -d\# -f1 ${AUDIT_RULES} | egrep "\-k[[:space:]]+logins" | egrep "\-p[[:space:]]+wa" \
+  | egrep -q "\-w[[:space:]]+\/var\/log\/tallylog" || return
+}
+
+function audit_session_init {
+  # Confirm that the logins lines specified below do appear in the audit.rules file
+  cut -d\# -f1 ${AUDIT_RULES} | egrep "\-k[[:space:]]+session" | egrep "\-p[[:space:]]+wa" \
+  | egrep -q "\-w[[:space:]]+\/var\/run\/utmp" || return
+  cut -d\# -f1 ${AUDIT_RULES} | egrep "\-k[[:space:]]+session" | egrep "\-p[[:space:]]+wa" \
+  | egrep -q "\-w[[:space:]]+\/var\/log\/wtmp" || return
+  cut -d\# -f1 ${AUDIT_RULES} | egrep "\-k[[:space:]]+session" | egrep "\-p[[:space:]]+wa" \
+  | egrep -q "\-w[[:space:]]+\/var\/log\/btmp" || return
+}
+
+function audit_sys_mac {
+  # Confirm that the logins lines specified below do appear in the audit.rules file
+  cut -d\# -f1 ${AUDIT_RULES} | egrep "\-k[[:space:]]+MAC-policy" | egrep "\-p[[:space:]]+wa" \
+  | egrep -q "\-w[[:space:]]+\/etc\/selinux\/" || return
+}
+
+function audit_dac_perm_mod_events {
+  # Confirm that perm_mod lines matching the patterns below do appear in the audit.rules file
+  cut -d\# -f1 ${AUDIT_RULES} | egrep "\-k[[:space:]]+perm_mod" | egrep "\-S[[:space:]]+chmod" \
+  | egrep "\-S[[:space:]]+fchmod" | egrep "\-S[[:space:]]+fchmodat" | egrep "\-F[[:space:]]+arch=b64" \
+  | egrep "\-F[[:space:]]+auid>=1000" | egrep "\-F[[:space:]]+auid\!=4294967295" \
+  | egrep -q "\-a[[:space:]]+always,exit|\-a[[:space:]]+exit,always" || return
+
+  cut -d\# -f1 ${AUDIT_RULES} | egrep "\-k[[:space:]]+perm_mod" | egrep "\-S[[:space:]]+chmod" \
+  | egrep "\-S[[:space:]]+fchmod" | egrep "\-S[[:space:]]+fchmodat" | egrep "\-F[[:space:]]+arch=b32" \
+  | egrep "\-F[[:space:]]+auid>=1000" | egrep "\-F[[:space:]]+auid\!=4294967295" \
+  | egrep -q "\-a[[:space:]]+always,exit|\-a[[:space:]]+exit,always" || return
+
+  cut -d\# -f1 ${AUDIT_RULES} | egrep "\-k[[:space:]]+perm_mod" | egrep "\-S[[:space:]]+chown" \
+  | egrep "\-S[[:space:]]+fchown" | egrep "\-S[[:space:]]+fchownat" | egrep "\-S[[:space:]]+fchown" \
+  | egrep "\-F[[:space:]]+arch=b64" | egrep "\-F[[:space:]]+auid>=1000" | egrep "\-F[[:space:]]+auid\!=4294967295" \
+  | egrep -q "\-a[[:space:]]+always,exit|\-a[[:space:]]+exit,always" || return
+
+  cut -d\# -f1 ${AUDIT_RULES} | egrep "\-k[[:space:]]+perm_mod" | egrep "\-S[[:space:]]+chown" \
+  | egrep "\-S[[:space:]]+fchown" | egrep "\-S[[:space:]]+fchownat" | egrep "\-S[[:space:]]+fchown" \
+  | egrep "\-F[[:space:]]+arch=b32" | egrep "\-F[[:space:]]+auid>=1000" | egrep "\-F[[:space:]]+auid\!=4294967295" \
+  | egrep -q "\-a[[:space:]]+always,exit|\-a[[:space:]]+exit,always" || return
+
+  cut -d\# -f1 ${AUDIT_RULES} | egrep "\-k[[:space:]]+perm_mod" | egrep "\-S[[:space:]]+setxattr" \
+  | egrep "\-S[[:space:]]+lsetxattr" | egrep "\-S[[:space:]]+fsetxattr" | egrep "\-S[[:space:]]+removexattr" \
+  | egrep "\-S[[:space:]]+lremovexattr" | egrep "\-S[[:space:]]+fremovexattr" | egrep "\-F[[:space:]]+arch=b64" \
+  | egrep "\-F[[:space:]]+auid>=1000" | egrep "\-F[[:space:]]+auid\!=4294967295" \
+  | egrep -q "\-a[[:space:]]+always,exit|\-a[[:space:]]+exit,always" || return
+
+  cut -d\# -f1 ${AUDIT_RULES} | egrep "\-k[[:space:]]+perm_mod" | egrep "\-S[[:space:]]+setxattr" \
+  | egrep "\-S[[:space:]]+lsetxattr" | egrep "\-S[[:space:]]+fsetxattr" | egrep "\-S[[:space:]]+removexattr" \
+  | egrep "\-S[[:space:]]+lremovexattr" | egrep "\-S[[:space:]]+fremovexattr" | egrep "\-F[[:space:]]+arch=b32" \
+  | egrep "\-F[[:space:]]+auid>=1000" | egrep "\-F[[:space:]]+auid\!=4294967295" \
+  | egrep -q "\-a[[:space:]]+always,exit|\-a[[:space:]]+exit,always" || return
+}
+
+function unsuc_unauth_acc_attempts {
+  cut -d\# -f1 ${AUDIT_RULES} | egrep "\-k[[:space:]]+access" | egrep "\-S[[:space:]]+creat" \
+  | egrep "\-S[[:space:]]+open" | egrep "\-S[[:space:]]+openat" | egrep "\-S[[:space:]]+truncate" \
+  | egrep "\-S[[:space:]]+ftruncate" | egrep "\-F[[:space:]]+arch=b64" | egrep "\-F[[:space:]]+auid>=1000" \
+  | egrep "\-F[[:space:]]+auid\!=4294967295" | egrep "\-F[[:space:]]exit=\-EACCES" \
+  | egrep -q "\-a[[:space:]]+always,exit|\-a[[:space:]]+exit,always" || return
+
+  cut -d\# -f1 ${AUDIT_RULES} | egrep "\-k[[:space:]]+access" | egrep "\-S[[:space:]]+creat" \
+  | egrep "\-S[[:space:]]+open" | egrep "\-S[[:space:]]+openat" | egrep "\-S[[:space:]]+truncate" \
+  | egrep "\-S[[:space:]]+ftruncate" | egrep "\-F[[:space:]]+arch=b32" | egrep "\-F[[:space:]]+auid>=1000" \
+  | egrep "\-F[[:space:]]+auid\!=4294967295" | egrep "\-F[[:space:]]exit=\-EACCES" \
+  | egrep -q "\-a[[:space:]]+always,exit|\-a[[:space:]]+exit,always" || return
+
+  cut -d\# -f1 ${AUDIT_RULES} | egrep "\-k[[:space:]]+access" | egrep "\-S[[:space:]]+creat" \
+  | egrep "\-S[[:space:]]+open" | egrep "\-S[[:space:]]+openat" | egrep "\-S[[:space:]]+truncate" \
+  | egrep "\-S[[:space:]]+ftruncate" | egrep "\-F[[:space:]]+arch=b64" | egrep "\-F[[:space:]]+auid>=1000" \
+  | egrep "\-F[[:space:]]+auid\!=4294967295" | egrep "\-F[[:space:]]exit=\-EPERM" \
+  | egrep -q "\-a[[:space:]]+always,exit|\-a[[:space:]]+exit,always" || return
+
+  cut -d\# -f1 ${AUDIT_RULES} | egrep "\-k[[:space:]]+access" | egrep "\-S[[:space:]]+creat" \
+  | egrep "\-S[[:space:]]+open" | egrep "\-S[[:space:]]+openat" | egrep "\-S[[:space:]]+truncate" \
+  | egrep "\-S[[:space:]]+ftruncate" | egrep "\-F[[:space:]]+arch=b32" | egrep "\-F[[:space:]]+auid>=1000" \
+  | egrep "\-F[[:space:]]+auid\!=4294967295" | egrep "\-F[[:space:]]exit=\-EPERM" \
+  | egrep -q "\-a[[:space:]]+always,exit|\-a[[:space:]]+exit,always" || return
+
+}
+
+function coll_priv_cmds {
+  local priv_cmds
+  priv_cmds="$(find / -xdev \( -perm -4000 -o -perm -2000 \) -type f)"
+  for cmd in ${priv_cmds} ; do
+    cut -d\# -f1 ${AUDIT_RULES} | egrep "\-k[[:space:]]+privileged" | egrep "\-F[[:space:]]+path=${cmd}" \
+    | egrep "\-F[[:space:]]+perm=x" | egrep "\-F[[:space:]]+auid>=1000" | egrep "\-F[[:space:]]+auid\!=4294967295" \
+    | egrep -q "\-a[[:space:]]+always,exit|\-a[[:space:]]+exit,always" || return
+  done
+}
+
+function coll_suc_fs_mnts {
+  cut -d\# -f1 ${AUDIT_RULES} | egrep "\-k[[:space:]]+mounts" | egrep "\-S[[:space:]]+mount" \
+  | egrep "\-F[[:space:]]+arch=b64" | egrep "\-F[[:space:]]+auid>=1000" \
+  | egrep "\-F[[:space:]]+auid\!=4294967295" \
+  | egrep -q "\-a[[:space:]]+always,exit|\-a[[:space:]]+exit,always" || return
+
+  cut -d\# -f1 ${AUDIT_RULES} | egrep "\-k[[:space:]]+mounts" | egrep "\-S[[:space:]]+mount" \
+  | egrep "\-F[[:space:]]+arch=b32" | egrep "\-F[[:space:]]+auid>=1000" \
+  | egrep "\-F[[:space:]]+auid\!=4294967295" \
+  | egrep -q "\-a[[:space:]]+always,exit|\-a[[:space:]]+exit,always" || return
+}
+
+function coll_file_del_events {
+  cut -d\# -f1 ${AUDIT_RULES} | egrep "\-k[[:space:]]+delete" | egrep "\-S[[:space:]]+unlink" \
+  | egrep "\-F[[:space:]]+arch=b64" | egrep "\-S[[:space:]]+unlinkat" | egrep "\-S[[:space:]]+rename" \
+  | egrep "\-S[[:space:]]+renameat" | egrep "\-F[[:space:]]+auid>=1000" \
+  | egrep "\-F[[:space:]]+auid\!=4294967295" \
+  | egrep -q "\-a[[:space:]]+always,exit|\-a[[:space:]]+exit,always" || return
+
+  cut -d\# -f1 ${AUDIT_RULES} | egrep "\-k[[:space:]]+delete" | egrep "\-S[[:space:]]+unlink" \
+  | egrep "\-F[[:space:]]+arch=b32" | egrep "\-S[[:space:]]+unlinkat" | egrep "\-S[[:space:]]+rename" \
+  | egrep "\-S[[:space:]]+renameat" | egrep "\-F[[:space:]]+auid>=1000" \
+  | egrep "\-F[[:space:]]+auid\!=4294967295" \
+  | egrep -q "\-a[[:space:]]+always,exit|\-a[[:space:]]+exit,always" || return
+
+}
+
+function coll_chg2_sysadm_scope {
+  cut -d\# -f1 ${AUDIT_RULES} | egrep "\-k[[:space:]]+scope" | egrep "\-p[[:space:]]+wa" \
+  | egrep -q "\-w[[:space:]]+\/etc\/sudoers" || return
+
+}
+
+function coll_sysadm_actions {
+  cut -d\# -f1 ${AUDIT_RULES} | egrep "\-k[[:space:]]+actions" | egrep "\-p[[:space:]]+wa" \
+  | egrep -q "\-w[[:space:]]+\/var\/log\/sudo.log" || return
+
+}
+
+function kmod_lod_unlod {
+  cut -d\# -f1 ${AUDIT_RULES} | egrep "\-k[[:space:]]+modules" | egrep "\-p[[:space:]]+x" \
+  | egrep -q "\-w[[:space:]]+\/sbin\/insmod" || return
+
+  cut -d\# -f1 ${AUDIT_RULES} | egrep "\-k[[:space:]]+modules" | egrep "\-p[[:space:]]+x" \
+  | egrep -q "\-w[[:space:]]+\/sbin\/rmmod" || return
+
+  cut -d\# -f1 ${AUDIT_RULES} | egrep "\-k[[:space:]]+modules" | egrep "\-p[[:space:]]+x" \
+  | egrep -q "\-w[[:space:]]+\/sbin\/modprobe" || return
+
+  cut -d\# -f1 ${AUDIT_RULES} | egrep "\-k[[:space:]]+modules" | egrep "\-S[[:space:]]+delete_module" \
+  | egrep "\-F[[:space:]]+arch=b64" | egrep "\-S[[:space:]]+init_module" \
+  | egrep -q "\-a[[:space:]]+always,exit|\-a[[:space:]]+exit,always" || return
+}
+
+function audit_cfg_immut {
+  # There should be a "-e 2" at the end of the audit.rules file
+  cut -d\# -f1 ${AUDIT_RULES} | egrep -q "^-e[[:space:]]+2" || return
+}
+
+function logrotate_cfg {
+  [[ -f "${LOGR_SYSLOG}" ]] || return
+
+  local timestamp
+  timestamp=$(date '+%Y%m%d_%H%M%S')
+  local tmp_data="/tmp/logrotate.tmp.${timestamp}"
+  local file_list="/var/log/messages /var/log/secure /var/log/maillog /var/log/spooler /var/log/boot.log /var/log/cron"
+  local line_num
+  line_num=$(grep -n '{' "${LOGR_SYSLOG}" | cut -d: -f1)
+  line_num=$((${line_num} - 1))
+  head -${line_num} "${LOGR_SYSLOG}" > ${tmp_data}
+  for file in ${file_list} ; do
+    grep -q "${file}" ${tmp_data} || return
+  done
+  rm "${tmp_data}"
+}
+
+function atd_cfg {
+ [[ ! -f ${AT_DENY} ]] || return
+ [[ -f ${AT_ALLOW} ]] || return
+ check_root_owns "${AT_ALLOW}"
+ check_file_perms "${AT_ALLOW}" 600
+}
+
+function at_cron_auth_users {
+ [[ ! -f ${AT_DENY} ]] || return
+ [[ ! -f ${CRON_DENY} ]] || return
+ check_root_owns "${CRON_ALLOW}"
+ check_root_owns "${AT_ALLOW}"
+ check_file_perms "${CRON_ALLOW}" 600
+ check_file_perms "${AT_ALLOW}" 600
+}
+
+function chk_param {
+  local file="${1}"
+  local parameter="${2}"
+  local value="${3}"
+  cut -d\# -f1 ${file} | egrep -q "^${parameter}[[:space:]]+${value}" || return
+}
+
+
+function ssh_maxauthtries {
+  local allowed_max="${1}"
+  local actual_value
+  actual_value=$(cut -d\# -f1 ${SSHD_CFG} | grep 'MaxAuthTries' | cut -d" " -f2)
+  [[ ${actual_value} -le ${allowed_max} ]] || return
+}
+
+function ssh_access {
+  local allow_users
+  local allow_groups
+  local deny_users
+  local deny_users
+  allow_users="$(cut -d\# -f1 ${SSHD_CFG} | grep "AllowUsers" | cut -d" " -f2)"
+  allow_groups="$(cut -d\# -f1 ${SSHD_CFG} | grep "AllowGroups" | cut -d" " -f2)"
+  deny_users="$(cut -d\# -f1 ${SSHD_CFG} | grep "DenyUsers" | cut -d" " -f2)"
+  deny_groups="$(cut -d\# -f1 ${SSHD_CFG} | grep "DenyGroups" | cut -d" " -f2)"
+  [[ -n "${allow_users}" ]] || return
+  [[ -n "${allow_groups}" ]] || return
+  [[ -n "${deny_users}" ]] || return
+  [[ -n "${deny_groups}" ]] || return
+}
+
+function pass_hash_algo {
+  local algo="${1}"
+  authconfig --test | grep 'hashing' | grep -q "${algo}" || return
+}
+
+function pass_req_params {
+  # verify the pam_pwquality.so params in /etc/pam.d/system-auth
+  grep pam_pwquality.so ${SYSTEM_AUTH} | grep 'password' | grep 'requisite' | grep 'try_first_pass' | grep 'local_users_only' | grep 'retry=3' | grep -q 'authtok_type=' || return
+  grep -q 'minlen=14' ${PWQUAL_CNF} || return
+  grep -q 'dcredit=-1' ${PWQUAL_CNF} || return
+  grep -q 'ucredit=-1' ${PWQUAL_CNF} || return
+  grep -q 'ocredit=-1' ${PWQUAL_CNF} || return
+  grep -q 'lcredit=-1' ${PWQUAL_CNF} || return
+}
+
+function failed_pass_lock {
+ egrep "auth[[:space:]]+required" ${PASS_AUTH} | grep -q 'pam_deny.so' || return
+ egrep "auth[[:space:]]+required" ${PASS_AUTH} | grep 'pam_faillock.so' | grep 'preauth' | grep 'audit' | grep 'silent' | grep 'deny=5' | grep -q 'unlock_time=900' || return
+ grep 'auth' ${PASS_AUTH} | grep 'pam_unix.so' | egrep -q "\[success=1[[:space:]]+default=bad\]" || return
+ grep 'auth' ${PASS_AUTH} | grep 'pam_faillock.so' | grep 'authfail' | grep 'audit' | grep 'deny=5' | grep 'unlock_time=900' | egrep -q "\[default=die\]" || return
+ egrep "auth[[:space:]]+sufficient" ${PASS_AUTH} | grep 'pam_faillock.so' | grep 'authsucc' | grep 'audit' | grep 'deny=5' | grep -q 'unlock_time=900' || return
+ egrep "auth[[:space:]]+required" ${PASS_AUTH} | grep -q 'pam_deny.so' || return
+
+ egrep "auth[[:space:]]+required" ${SYSTEM_AUTH} | grep -q 'pam_env.so' || return
+ egrep "auth[[:space:]]+required" ${SYSTEM_AUTH} | grep 'pam_faillock.so' | grep 'preauth' | grep 'audit' | grep 'silent' | grep 'deny=5' | grep -q 'unlock_time=900' || return
+ grep 'auth' ${SYSTEM_AUTH} | grep 'pam_unix.so' | egrep -q "\[success=1[[:space:]]+default=bad\]" || return
+ grep 'auth' ${SYSTEM_AUTH} | grep 'pam_faillock.so' | grep 'authfail' | grep 'audit' | grep 'deny=5' | grep 'unlock_time=900' | egrep -q "\[default=die\]" || return
+ egrep "auth[[:space:]]+sufficient" ${SYSTEM_AUTH} | grep 'pam_faillock.so' | grep 'authsucc' | grep 'audit' | grep 'deny=5' | grep -q 'unlock_time=900' || return
+ egrep "auth[[:space:]]+required" ${SYSTEM_AUTH} | grep -q 'pam_deny.so' || return
+}
+
+function lim_passwd_reuse {
+ egrep "auth[[:space:]]+sufficient" ${SYSTEM_AUTH} | grep 'pam_unix.so' | grep -q 'remember=5' || return
+}
+
+function su_access {
+  egrep "auth[[:space:]]+required" "${PAM_SU}" | grep 'pam_wheel.so' | grep -q 'use_uid' || return
+  grep 'wheel' "${GROUP}" | cut -d: -f4 | grep -q 'root' || return
+}
+
+function dis_sys_accs {
+  # Check that system accounts are disabled
+  local accounts
+  accounts="$(egrep -v "^\+" /etc/passwd | awk -F: '($1!="root" && $1!="sync" && $1!="shutdown" \
+&& $1!="halt" && $3<1000 && $7!="/sbin/nologin") {print}')"
+  [[ -z "${accounts}" ]] || return
+}
+
+function root_def_grp {
+  local gid1
+  local gid2
+  gid1="$(grep "^root:" "${PASSWD}" | cut -d: -f4)"
+  [[ "${gid1}" -eq 0 ]] || return
+  gid2="$(id -g root)"
+  [[ "${gid2}" -eq 0 ]] || return
+}
+
+function def_umask_for_users {
+  cut -d\#  -f1 "${BASHRC}" | egrep -q "umask[[:space:]]+027" || return
+  egrep -q "umask[[:space:]]+027" ${PROF_D}/* || return
+}
+
+function inactive_usr_acs_locked {
+  # After being inactive for a period of time the account should be disabled
+  local days
+  local inactive_threshold=30
+  days="$(useradd -D | grep INACTIVE | cut -d= -f2)"
+  [[ ${days} -ge ${inactive_threshold} ]] || return
+}
+
+function warning_banners {
+  # Check that system login banners don't contain any OS information
+  local motd
+  local issue
+  local issue_net
+  motd="$(egrep '(\\v|\\r|\\m|\\s)' ${MOTD})"
+  issue="$(egrep '(\\v|\\r|\\m|\\s)' ${ISSUE})"
+  issue_net="$(egrep '(\\v|\\r|\\m|\\s)' ${ISSUE_NET})"
+  [[ -z "${motd}" ]] || return
+  [[ -z "${issue}" ]] || return
+  [[ -z "${issue_net}" ]] || return
+}
+
+function gnome_banner {
+  # On a host aiming to meet CIS requirements GNOME is unlikely to be installed
+  # Thus the function says if the file exists then it should have these lines in it
+  if [[ -f "${BANNER_MSG}" ]] ; then
+    egrep '[org/gnome/login-screen]' ${BANNER_MSG} || return
+    egrep 'banner-message-enable=true' ${BANNER_MSG} || return
+    egrep 'banner-message-text=' ${BANNER_MSG} || return
+  fi
+}
+
+function unowned_files {
+  local uo_files
+  uo_files="$(df --local -P | awk {'if (NR!=1) print $6'} | xargs -I '{}' find '{}' -xdev -nouser)"
+  [[ -z "${uo_files}" ]] || return
+}
+
+
+function ungrouped_files {
+  local ug_files
+  ug_files="$(df --local -P | awk {'if (NR!=1) print $6'} | xargs -I '{}' find '{}' -xdev -nogroup)"
+  [[ -z "${ug_files}" ]] || return
+}
+
+function suid_exes {
+  # For every suid exe on the host use the rpm cmd to verify that it should be suid executable
+  # If the rpm cmd returns no output then the rpm is as it was when it was installed so no prob
+  local suid_exes
+  suid_exes="$(df --local -P | awk {'if (NR!=1) print $6'} | xargs -I '{}' find '{}' -xdev -type f -perm -4000 -print)"
+  for suid_exe in ${suid_exes}
+  do
+    rpm_out="$(rpm -V $(rpm -qf ${suid_exe}))"
+    [[ -z "${rpm_out}" ]] || return
+  done
+}
+
+function sgid_exes {
+  # For every sgid exe on the host use the rpm cmd to verify that it should be sgid executable
+  # If the rpm cmd returns no output then the rpm is as it was when it was installed so no prob
+  local sgid_exes
+  sgid_exes="$(df --local -P | awk {'if (NR!=1) print $6'} | xargs -I '{}' find '{}' -xdev -type f -perm -4000 -print)"
+  for sgid_exe in ${sgid_exes}
+  do
+    rpm_out="$(rpm -V $(rpm -qf ${sgid_exe}))"
+    [[ -z "${rpm_out}" ]] || return
+  done
+}
+
+function passwd_field_chk {
+  local shadow_out
+  shadow_out="$(awk -F: '($2 == "" ) { print $1 }' ${SHADOW})"
+  [[ -z "${shadow_out}" ]] || return
+}
+
+function nis_in_file {
+  # Check for lines starting with + in the supplied file $1
+  # In /etc/{passwd,shadow,group} it used to be a marker to insert data from NIS
+  # There shouldn't be any entries like this
+  local file="${1}"
+  local grep_out
+  grep_out="$(grep '^+:' ${file})"
+  [[ -z "${grep_out}" ]] || return
+}
+
+function no_uid0_other_root {
+  local grep_passwd
+  grep_passwd="$(awk -F: '($3 == 0) { print $1 }' ${PASSWD})"
+  [[ "${grep_passwd}" = "root" ]] || return
+}
+
+function world_w_dirs {
+  dirs="$(df --local -P | awk {'if (NR!=1) print $6'} | xargs -I '{}' find '{}' -xdev -type f -perm -0002)"
+  [[ -z "${dirs}" ]] || return
+}
+
+function root_path {
+  # There should not be an empty dir in $PATH
+  local grep=/bin/grep
+  local sed=/bin/sed
+  path_grep="$(echo ${PATH} | ${grep} '::')"
+  [[ -z "${path_grep}" ]] || return
+
+  # There should not be a trailing : on $PATH
+  path_grep="$(echo ${PATH} | ${grep} :$)"
+  [[ -z "${path_grep}" ]] || return
+
+  path_dirs="$(echo $PATH | ${sed} -e 's/::/:/' -e 's/:$//' -e 's/:/ /g')"
+  for dir in ${path_dirs} ; do
+    # PATH should not contain .
+    [[ "${dir}" != "." ]] || return
+
+    #$dir should be a directory
+    [[ -d "${dir}" ]] || return
+
+    local ls_out
+    ls_out="$(ls -ldH ${dir})"
+    if is_group_writable ${ls_out} ; then return 1 ; else return 0 ; fi
+    if is_other_writable ${ls_out} ; then return 1 ; else return 0 ; fi
+
+
+    # Directory should be owned by root
+    dir_own="$(echo ${ls_out} | awk '{print $3}')"
+    [[ "${dir_own}" = "root" ]] || return
+  done
+}
+
+function is_group_readable {
+  local ls_output="${1}"
+  # 5th byte of ls output is the field for group readable
+  [[ "${ls_output:4:1}" = "r" ]] || return
+}
+
+function is_group_writable {
+  local ls_output="${1}"
+  # 6th byte of ls output is the field for group writable
+  [[ "${ls_output:5:1}" = "w" ]] || return
+}
+
+function is_group_executable {
+  local ls_output="${1}"
+  # 7th byte of ls output is the field for group readable
+  [[ "${ls_output:6:1}" = "r" ]] || return
+}
+
+function is_other_readable {
+  local ls_output="${1}"
+  # 8th byte of ls output is the field for other readable
+  [[ "${ls_output:7:1}" = "r" ]] || return
+}
+
+function is_other_writable {
+  local ls_output="${1}"
+  # 9th byte of ls output is the field for other writable
+  [[ "${ls_output:8:1}" = "w" ]] || return
+}
+
+function is_other_executable {
+  local ls_output="${1}"
+  # 10th byte of ls output is the field for other executable
+  [[ "${ls_output:9:1}" = "x" ]] || return
+}
+
+function home_dir_perms {
+  dirs="$(grep -v 'root|halt|sync|shutdown' ${PASSWD} | awk -F: '($7 != "/sbin/nologin") { print $6 }')"
+  [[ -z "${dirs}" ]] && return
+  for dir in ${dirs} ; do
+    [[ -d "${dir}" ]] || continue
+    local ls_out
+    ls_out="$(ls -ldH ${dir})"
+    if is_group_writable ${ls_out} ; then return 1 ; else return 0 ; fi
+    if is_other_readable ${ls_out} ; then return 1 ; else return 0 ; fi
+    if is_other_writable ${ls_out} ; then return 1 ; else return 0 ; fi
+    if is_other_executable ${ls_out} ; then return 1 ; else return 0 ; fi
+  done
+}
+
+function dot_file_perms {
+  dirs="$(grep -v 'root|halt|sync|shutdown' ${PASSWD} | awk -F: '($7 != "/sbin/nologin") { print $6 }')"
+  for dir in ${dirs} ; do
+    [[ -d "${dir}" ]] || continue
+    for file in ${dir}/.[A-Za-z0-9]* ; do
+      if [[ ! -h "${file}" && -f "${file}" ]] ; then
+        local ls_out
+        ls_out="$(ls -ldH ${dir})"
+        if is_group_writable ${ls_out} ; then return 1 ; else return 0 ; fi
+        if is_other_writable ${ls_out} ; then return 1 ; else return 0 ; fi
+      fi
+    done
+  done
+}
+
+function dot_rhosts_files {
+  dirs="$(grep -v 'root|halt|sync|shutdown' ${PASSWD} | awk -F: '($7 != "/sbin/nologin") { print $6 }')"
+  for dir in ${dirs} ; do
+    [[ -d "${dir}" ]] || continue
+    local file="${dir}/.rhosts"
+    if [[ ! -h "${file}" && -f "${file}" ]] ; then
+      return 1
+    else
+      return 0
+    fi
+  done
+}
+
+function chk_groups_passwd {
+  # We don't want to see any groups in /etc/passwd that aren't in /etc/group
+  group_ids="$(cut -s -d: -f4 ${PASSWD} | sort -u)"
+  for group_id in ${group_ids} ; do
+    grep -q -P "^.*?:x:${group_id}:" ${GROUP} || return
+  done
+}
+
+function chk_home_dirs_exist {
+  #Check that users home directory do all exist
+  while read user uid dir ; do
+    if [[ "${uid}" -ge 1000 && ! -d "${dir}" && "${user}" != "nfsnobody" ]] ; then
+      return 1
+    fi
+  done < <(awk -F: '{ print $1 " " $3 " " $6 }' ${PASSWD})
+}
+
+function chk_home_dirs_owns {
+  #Check that users home directory do all exist
+  while read user uid dir ; do
+    if [[ "${uid}" -ge 1000 && ! -d "${dir}" && "${user}" != "nfsnobody" ]] ; then
+      local owner
+      owner="$(stat -L -c "%U" "${dir}")"
+      [[ "${owner}" = "${user}" ]] || return
+    fi
+  done < <(awk -F: '{ print $1 " " $3 " " $6 }' ${PASSWD})
+}
+
+function dot_netrc_perms {
+  dirs="$(grep -v 'root|halt|sync|shutdown' ${PASSWD} | awk -F: '($7 != "/sbin/nologin") { print $6 }')"
+  for dir in ${dirs} ; do
+    [[ -d "${dir}" ]] || continue
+    for file in ${dir}/.netrc ; do
+      if [[ ! -h "${file}" && -f "${file}" ]] ; then
+        local ls_out
+        ls_out="$(ls -ldH ${dir})"
+        if is_group_readable ${ls_out} ; then return 1 ; else return 0 ; fi
+        if is_group_writable ${ls_out} ; then return 1 ; else return 0 ; fi
+        if is_group_executable ${ls_out} ; then return 1 ; else return 0 ; fi
+        if is_other_readable ${ls_out} ; then return 1 ; else return 0 ; fi
+        if is_other_writable ${ls_out} ; then return 1 ; else return 0 ; fi
+        if is_other_executable ${ls_out} ; then return 1 ; else return 0 ; fi
+      fi
+    done
+  done
+}
+
+function user_dot_netrc {
+  # We don't want to see any ~/.netrc files
+  local dirs
+  dirs="$(cut -d: -f6 ${PASSWD})"
+  for dir in ${dirs} ; do
+    [[ -d "${dir}" ]] || continue
+    if [[ ! -h "${dir}/.netrc" && -f "${dir}/.netrc" ]] ; then
+      return 1
+    fi
+  done
+}
+
+function user_dot_forward {
+  # We don't want to see any ~/.forward files
+  local dirs
+  dirs="$(cut -d: -f6 ${PASSWD})"
+  for dir in ${dirs} ; do
+    [[ -d "${dir}" ]] || continue
+    if [[ ! -h "${dir}/.forward" && -f "${dir}/.forward" ]] ; then
+      return 1
+    fi
+  done
+}
+
+function duplicate_uids {
+  local num_of_uids
+  local uniq_num_of_uids
+  num_of_uids="$(cut -f3 -d":" ${PASSWD} | wc -l)"
+  uniq_num_of_uids="$(cut -f3 -d":" ${PASSWD} | sort -n | uniq | wc -l)"
+  [[ "${num_of_uids}" -eq "${uniq_num_of_uids}" ]] || return
+}
+
+function duplicate_gids {
+  local num_of_gids
+  local uniq_num_of_gids
+  num_of_gids="$(cut -f3 -d":" ${GROUP} | wc -l)"
+  uniq_num_of_gids="$(cut -f3 -d":" ${GROUP} | sort -n | uniq | wc -l)"
+  [[ "${num_of_gids}" -eq "${uniq_num_of_gids}" ]] || return
+}
+
+function chk_uids_4_res {
+  local default_users='root bin daemon adm lp sync shutdown halt mail news uucp operator games \
+gopher ftp nobody nscd vcsa rpc mailnull smmsp pcap ntp dbus avahi sshd rpcuser \
+nfsnobody haldaemon avahi-autoipd distcache apache oprofile webalizer dovecot squid \
+named xfs gdm sabayon usbmuxd rtkit abrt saslauth pulse postfix tcpdump polkitd tss chrony'
+  while read user uid; do
+    local found=0
+    for duser in ${default_users} ; do
+      if [[ "${user}" = "${duser}" ]] ; then
+        found=1
+      fi
+    done
+    [[ "${found}" -eq 1 ]] || return
+  done < <(awk -F: '($3 < 1000) {print $1" "$3 }' ${PASSWD})
+}
+
+function duplicate_usernames {
+  local num_of_usernames
+  local num_of_uniq_usernames
+  num_of_usernames="$(cut -f1 -d":" ${PASSWD} | wc -l)"
+  num_of_uniq_usernames="$(cut -f1 -d":" ${PASSWD} | sort | uniq | wc -l)"
+  [[ "${num_of_usernames}" -eq "${num_of_uniq_usernames}" ]] || return
+}
+
+function duplicate_groupnames {
+  local num_of_groupnames
+  local num_of_uniq_groupnames
+  num_of_groupnames="$(cut -f1 -d":" ${GROUP} | wc -l)"
+  num_of_uniq_groupnames="$(cut -f1 -d":" ${GROUP} | sort | uniq | wc -l)"
+  [[ "${num_of_groupnames}" -eq "${num_of_uniq_groupnames}" ]] || return
+}
+
+function func_wrapper {
+  func_name=$1
+  shift
+  args=$@
+  ${func_name} ${args}
+  if [[ "$?" -eq 0 ]]; then
+    echo ${func_name} ${args} ${GREEN_COLOR}OK${RESET_COLOR}
+  else
+    echo ${func_name} ${args} ${RED_COLOR}ERROR${RESET_COLOR}
+  fi
+}
+
+
+function main {
+
+  # CIS 1.1.1 Test that there is a separate /tmp partition
+  func_wrapper separate_partition /tmp
+
+  # CIS 1.1.2 Test that the nodev option is on the /tmp partition
+  func_wrapper mount_option /tmp nodev
+
+  # CIS 1.1.3 Test that the nosuid option is on the /tmp partition
+  func_wrapper mount_option /tmp nosuid
+
+  # CIS 1.1.4 Test that the noexec option is on the /tmp partition
+  func_wrapper mount_option /tmp noexec
+
+  # CIS 1.1.5 Test that there is a separate /var partition
+  func_wrapper separate_partition /var
+
+  # CIS 1.1.6 Test that the /var/tmp directory is bind mounted onto the /tmp filesystem
+  func_wrapper bind_mounted_to /var/tmp /tmp
+
+  # CIS 1.1.7 Test that there is a separate /var/log partition
+  func_wrapper separate_partition /var/log
+
+  # CIS 1.1.8 Test that there is a separate /var/log/audit partition
+  func_wrapper separate_partition /var/log/audit
+
+  # CIS 1.1.9 Test that there is a separate /home partition
+  func_wrapper separate_partition /home
+
+  # CIS 1.1.10 Test that the nodev option is on the /home partition
+  func_wrapper mount_option /home nodev
+
+  # TO DO CIS 1.1.11 nodev option on removable media partitions
+  # TO DO CIS 1.1.12 noexec option on removable media partitions
+  # TO DO CIS 1.1.13 nosuid option on removable media partitions
+
+  # CIS 1.1.14 Test that the nodev option is on the /dev/shm partition
+  func_wrapper mount_option /dev/shm nodev
+
+  # CIS 1.1.15 Test that the nosuid option is on the /dev/shm partition
+  func_wrapper mount_option /dev/shm nosuid
+
+  # CIS 1.1.16 Test that the noexec option is on the /dev/shm partition
+  func_wrapper mount_option /dev/shm noexec
+
+  # TO DO CIS 1.1.17 Check for the sticky bit on all world writable dirs
+  func_wrapper sticky_wrld_w_dirs
+
+  # CIS 1.1.18 Test that the mounting of cramfs filesystems is disabled
+  func_wrapper test_disable_mounting cramfs
+
+  # CIS 1.1.19 Test that the mounting of freevxfs filesystems is disabled
+  func_wrapper test_disable_mounting freevxfs
+
+  # CIS 1.1.20 Test that the mounting of jffs2 filesystems is disabled
+  func_wrapper test_disable_mounting jffs2
+
+  # CIS 1.1.21 Test that the mounting of hfs filesystems is disabled
+  func_wrapper test_disable_mounting hfs
+
+  # CIS 1.1.22 Test that the mounting of hfsplus filesystems is disabled
+  func_wrapper test_disable_mounting hfsplus
+
+  # CIS 1.1.23 Test that the mounting of squashfs filesystems is disabled
+  func_wrapper test_disable_mounting squashfs
+
+  # CIS 1.1.24 Test that the mounting of udf filesystems is disabled
+  func_wrapper test_disable_mounting udf
+
+  # CIS 1.2.1 Check that the CentOS GPG Key is Installed
+  func_wrapper centos_gpg_key_installed
+
+  # CIS 1.2.2 Check that gpgcheck is globally activated
+  func_wrapper yum_gpgcheck
+
+  # CIS 1.2.3 Check software package updates with yum
+  func_wrapper yum_update
+
+  # CIS 1.2.4 Verify package integrity using RPM
+  func_wrapper pkg_integrity
+
+  # CIS 1.3.1 Check that the AIDE rpm is installed
+  func_wrapper rpm_installed aide
+
+  # CIS 1.3.2 Check periodic execution of file integrity (that aide runs from cron)
+  func_wrapper verify_aide_cron
+
+  # CIS 1.4.1 Check that SELinux is not disabled in /boot/grub2/grub.cfg
+  func_wrapper verify_selinux_grubcfg
+
+  # CIS 1.4.2 Verify SELinux configured state in /etc/selinux/config
+  func_wrapper verify_selinux_state
+
+  # CIS 1.4.3 Verify SELinux policy in /etc/selinux/config
+  func_wrapper verify_selinux_policy
+
+  # CIS 1.4.4 Check setroubleshoot RPM is not installed
+  func_wrapper rpm_not_installed setroubleshoot
+
+  # CIS 1.4.5 Check setroubleshoot RPM is not installed
+  func_wrapper rpm_not_installed mcstrans
+
+  # CIS 1.4.6 Check for unconfined daemons
+  func_wrapper unconfined_procs
+
+  # CIS 1.5.1 Check ownership on /boot/grub2/grub.cfg
+  func_wrapper check_root_owns ${GRUB_CFG}
+
+  # CIS 1.5.2 Check permissions on /boot/grub2/grub.cfg
+  func_wrapper check_grub_perms
+
+  # CIS 1.5.3 Check permissions on /boot/grub2/grub.cfg
+  func_wrapper check_boot_pass
+
+  # TO DO CIS 1.6.1
+  func_wrapper restrict_core_dumps
+
+  # CIS 1.6.2 Verify that the flag to force randomized virtual memory region placement is set
+  func_wrapper chk_sysctl kernel.randomize_va_space 2
+
+  # TO DO CIS 1.7
+  func_wrapper chk_latest_rel
+
+  # CIS 2.1.1 Check telnet-server RPM is not installed
+  func_wrapper rpm_not_installed telnet-server
+
+  # CIS 2.1.2 Check telnet RPM is not installed
+  func_wrapper rpm_not_installed telnet
+
+  # CIS 2.1.3 Check rsh-server RPM is not installed
+  func_wrapper rpm_not_installed rsh-server
+
+  # CIS 2.1.4 Check rsh RPM is not installed
+  func_wrapper rpm_not_installed rsh
+
+  # CIS 2.1.5 Check ypbind RPM is not installed
+  func_wrapper rpm_not_installed ypbind
+
+  # CIS 2.1.6 Check ypserv RPM is not installed
+  func_wrapper rpm_not_installed ypserv
+
+  # CIS 2.1.7 Check tftp RPM is not installed
+  func_wrapper rpm_not_installed tftp
+
+  # CIS 2.1.8 Check tftp-server RPM is not installed
+  func_wrapper rpm_not_installed tftp-server
+
+  # CIS 2.1.9 Check talk RPM is not installed
+  func_wrapper rpm_not_installed talk
+
+  # CIS 2.1.10 Check talk-server RPM is not installed
+  func_wrapper rpm_not_installed talk-server
+
+  # CIS 2.1.11 Check xinetd RPM is not installed
+  func_wrapper rpm_not_installed xinetd
+
+  # CIS 2.1.12 Check chargen-dgram is not enabled
+  func_wrapper check_svc_not_enabled chargen-dgram
+
+  # CIS 2.1.13 Check chargen-stream is not enabled
+  func_wrapper check_svc_not_enabled chargen-stream
+
+  # CIS 2.1.14 Check daytime-dgram is not enabled
+  func_wrapper check_svc_not_enabled daytime-dgram
+
+  # CIS 2.1.15 Check daytime-stream is not enabled
+  func_wrapper check_svc_not_enabled daytime-stream
+
+  # CIS 2.1.16 Check echo-dgram is not enabled
+  func_wrapper check_svc_not_enabled echo-dgram
+
+  # CIS 2.1.17 Check echo-dgram is not enabled
+  func_wrapper check_svc_not_enabled echo-stream
+
+  # CIS 2.1.18 Check tcpmux-server is not enabled
+  func_wrapper check_svc_not_enabled tcpmux-server
+
+  # CIS 3.1 Check Daemon umask
+  func_wrapper check_umask
+
+  # TODO CIS 3.2  X Window System
+  func_wrapper check_def_tgt
+
+  # CIS 3.2 Check telnet-server RPM is not installed
+  func_wrapper rpm_not_installed xorg-x11-server-common
+
+  # CIS 3.3 Check avahi-daemon is not enabled
+  func_wrapper check_svc_not_enabled avahi-daemon
+
+  # CIS 3.4 Check cups is not enabled
+  func_wrapper check_svc_not_enabled cups
+
+  # CIS 3.5 Check dhcp RPM is not installed
+  func_wrapper rpm_not_installed dhcp
+
+  # CIS 3.6 NTP config
+  func_wrapper ntp_cfg
+
+  # CIS 3.7.1 Check LDAP RPMs are not installed
+  func_wrapper rpm_not_installed openldap-servers
+  func_wrapper rpm_not_installed openldap-clients
+
+  # CIS 3.8 Check NFS and RPC are not enabled
+  func_wrapper check_svc_not_enabled nfslock
+  func_wrapper check_svc_not_enabled rpcgssd
+  func_wrapper check_svc_not_enabled rpcbind
+  func_wrapper check_svc_not_enabled rpcidmapd
+  func_wrapper check_svc_not_enabled rpcsvcgssd
+
+  # CIS 3.9 Check bind RPM is not installed
+  func_wrapper rpm_not_installed bind
+
+  # CIS 3.10 Check vsftpd RPM is not installed
+  func_wrapper rpm_not_installed vsftpd
+
+  # CIS 3.11 Check httpd RPM is not installed
+  func_wrapper rpm_not_installed httpd
+
+  # CIS 3.12 Check dovecot RPM is not installed
+  func_wrapper rpm_not_installed dovecot
+
+  # CIS 3.13 Check samba RPM is not installed
+  func_wrapper rpm_not_installed samba
+
+  # CIS 3.14 Check squid RPM is not installed
+  func_wrapper rpm_not_installed squid
+
+  # CIS 3.15 Check net-snmp RPM is not installed
+  func_wrapper rpm_not_installed net-snmp
+
+  # CIS 3.16 MTA in local-only mode
+  # Disable for now as function requires netstat and netstat is not part of the build
+  #func_wrapper mta_local_only
+
+  # CIS 4.1.1 IP Forwarding should be disabled
+  func_wrapper chk_sysctl net.ipv4.ip_forward 0
+
+  # CIS 4.1.2 Send Packet Redirects should be disabled
+  func_wrapper chk_sysctl net.ipv4.conf.all.send_redirects 0
+  func_wrapper chk_sysctl net.ipv4.conf.default.send_redirects 0
+
+  # CIS 4.2.1 Source Routed Packet Acceptance should be disabled
+  func_wrapper chk_sysctl net.ipv4.conf.all.accept_source_route 0
+  func_wrapper chk_sysctl net.ipv4.conf.default.accept_source_route 0
+
+  # CIS 4.2.2 ICMP Redirect Acceptance should be disabled
+  func_wrapper chk_sysctl net.ipv4.conf.all.accept_redirects 0
+  func_wrapper chk_sysctl net.ipv4.conf.default.accept_redirects 0
+
+  # CIS 4.2.3 ICMP Redirect Acceptance should be disabled
+  func_wrapper chk_sysctl net.ipv4.conf.all.secure_redirects 0
+  func_wrapper chk_sysctl net.ipv4.conf.all.secure_redirects 0
+  func_wrapper chk_sysctl net.ipv4.conf.default.secure_redirects 0
+
+  # CIS 4.2.4 Log Suspicious Packets
+  func_wrapper chk_sysctl net.ipv4.conf.all.log_martians 1
+  func_wrapper chk_sysctl net.ipv4.conf.default.log_martians 1
+
+  # CIS 4.2.5 Ignore Broadcast Requests should be enabled
+  func_wrapper chk_sysctl net.ipv4.icmp_echo_ignore_broadcasts 1
+
+  # CIS 4.2.6 Bad Error Message Protection should be enabled
+  func_wrapper chk_sysctl net.ipv4.icmp_ignore_bogus_error_responses 1
+
+  # CIS 4.2.7 RFC-recommended Source Route Validation should be enabled
+  func_wrapper chk_sysctl net.ipv4.conf.all.rp_filter 1
+  func_wrapper chk_sysctl net.ipv4.conf.default.rp_filter 1
+
+  # CIS 4.2.8 TCP SYN Cookies should be enabled
+  func_wrapper chk_sysctl net.ipv4.tcp_syncookies 1
+
+  # TODO CIS 4.3.1 Check Wireless Interfaces are deactivated
+
+  # CIS 4.4.1.1 If IPv6 enabled IPv6 Router Advertisements should be disabled
+  func_wrapper ip6_router_advertisements_dis
+
+  # CIS 4.4.1.2 If IPv6 enabled IPv6 Redirect Acceptance should be disabled
+  func_wrapper ip6_redirect_accept_dis
+
+  # CIS 4.4.2 IPv6 disabled
+  func_wrapper chk_sysctl net.ipv6.conf.all.disable_ipv6 1
+
+  # CIS 4.5.1 Check that TCP Wrappers are installed
+  func_wrapper rpm_installed tcp_wrappers
+
+  # CIS 4.5.2 Check that /etc/hosts.allow exists
+  func_wrapper chk_file_exists ${HOSTS_ALLOW}
+
+  # CIS 4.5.3 Verify permissions on /etc/hosts.allow
+  func_wrapper check_root_owns ${HOSTS_ALLOW}
+  func_wrapper check_file_perms ${HOSTS_ALLOW} 644
+
+  # CIS 4.5.4 Check that /etc/hosts.deny exists
+  func_wrapper chk_file_exists ${HOSTS_DENY}
+  func_wrapper chk_hosts_deny_content
+  func_wrapper check_root_owns ${HOSTS_DENY}
+  func_wrapper check_file_perms ${HOSTS_DENY} 644
+
+  # CIS 4.6.1 Check that CIS.conf file should disable uncommon network protocol dccp
+  func_wrapper chk_cis_cnf dccp ${CIS_CNF}
+
+  # CIS 4.6.2 Check that CIS.conf file should disable uncommon network protocol sctp
+  func_wrapper chk_cis_cnf sctp ${CIS_CNF}
+
+  # CIS 4.6.3 Check that CIS.conf file should disable uncommon network protocol rds
+  func_wrapper chk_cis_cnf rds ${CIS_CNF}
+
+  # CIS 4.6.4 Check that CIS.conf file should disable uncommon network protocol tipc
+  func_wrapper chk_cis_cnf tipc ${CIS_CNF}
+
+  # CIS 4.7 Firewalld should be enabled
+  func_wrapper check_svc_enabled firewalld
+
+  # CIS 5.1.1 Check that rsyslog is installed
+  func_wrapper rpm_installed rsyslog
+
+  # CIS 5.1.2 rsyslog should be enabled
+  func_wrapper check_svc_enabled rsyslog
+
+  # CIS 5.1.3 Configure rsyslog.conf
+  # This is too environment specific to audit for here
+
+  # CIS 5.1.4 Check perms on rsyslog.conf
+  func_wrapper chk_file_exists ${RSYSLOG_CNF}
+  func_wrapper check_root_owns ${RSYSLOG_CNF}
+  func_wrapper check_file_perms ${RSYSLOG_CNF} 600
+
+  # CIS 5.1.5 rsyslog.conf sending logs to a remote host
+  func_wrapper chk_rsyslog_content
+
+  # CIS 5.1.6 This benchmark is only applicable to rsyslog loghosts
+
+  # CIS 5.2.1.1 Audit Log Storage Size should be configured
+  func_wrapper audit_log_storage_size
+
+  # CIS 5.2.1.2 Disable System on Audit Log Full
+  func_wrapper dis_on_audit_log_full
+
+  # CIS 5.2.1.3 Disable System on Audit Log Full
+  func_wrapper keep_all_audit_info
+
+  # CIS 5.2.2 auditd should be enabled
+  func_wrapper check_svc_enabled auditd
+
+  # CIS 5.2.3
+  func_wrapper audit_procs_prior_2_auditd
+
+  # CIS 5.2.4 Record events that modify date & time info
+  func_wrapper audit_date_time
+
+  # CIS 5.2.5 Record events that modify user & group info
+  func_wrapper audit_user_group
+
+  # CIS 5.2.6 Record events that modify the system's network env
+  func_wrapper audit_network_env
+
+  # CIS 5.2.7 Record events that modify the system's Mandatory Access Controls
+  func_wrapper audit_sys_mac
+
+  # CIS 5.2.8 Verify Collection Login and Logout events is configured
+  func_wrapper audit_logins_logouts
+
+  # CIS 5.2.9 Verify Collection of Session Initiation info is configured
+  func_wrapper audit_session_init
+
+  # CIS 5.2.10 Verify Collection of Discretionary Access Control permission modification events
+  func_wrapper audit_dac_perm_mod_events
+
+  # CIS 5.2.11 Verify collection of unsuccessful unauthorized access attempts to files
+  func_wrapper unsuc_unauth_acc_attempts
+
+  # CIS 5.2.12 Verify collection of privileged commands
+  func_wrapper coll_priv_cmds
+
+  # CIS 5.2.13 Verify collection of privileged commands
+  func_wrapper coll_suc_fs_mnts
+
+  # CIS 5.2.14 Verify collection of privileged commands
+  func_wrapper coll_file_del_events
+
+  # CIS 5.2.15 Verify collection of privileged commands
+  func_wrapper coll_chg2_sysadm_scope
+
+  # CIS 5.2.16 Verify collection of privileged commands
+  func_wrapper coll_sysadm_actions
+
+  # CIS 5.2.17 Verify collection of Kernel Module Loading and Unloading
+  func_wrapper kmod_lod_unlod
+
+  # CIS 5.2.18 Verify collection of Kernel Module Loading and Unloading
+  func_wrapper audit_cfg_immut
+
+  # CIS 5.3 Log rotate should be configured
+  func_wrapper logrotate_cfg
+
+  # CIS 6.1.1 cron and anacron config
+  func_wrapper rpm_installed cronie-anacron
+
+  # CIS 6.1.2 enable crond daemon
+  func_wrapper check_svc_enabled crond
+
+  # CIS 6.1.3-6.1.8 user/group owner and perms on
+  # /etc/anacrontab /etc/crontab /etc/cron.hourly /etc/cron.daily /etc/cron.weekly /etc/cron.monthly /etc/cron.d
+
+  for file in ${ANACRONTAB} ${CRONTAB} ${CRON_HOURLY} ${CRON_DAILY} ${CRON_WEEKLY} ${CRON_MONTHLY} ${CRON_DIR} ; do
+    func_wrapper check_root_owns "${file}"
+    func_wrapper check_file_perms "${file}" 600
+  done
+
+  # CIS 6.1.10 at daemon config
+  func_wrapper atd_cfg
+
+  # CIS 6.1.11 restrict at/cron to authorized users
+  func_wrapper at_cron_auth_users
+
+  # CIS 6.2.1 SSH protocol should be 2
+  func_wrapper chk_param "${SSHD_CFG}" Protocol 2
+
+  # CIS 6.2.2 LogLevel to INFO
+  func_wrapper chk_param "${SSHD_CFG}" LogLevel INFO
+
+  # CIS 6.2.3 Permissions on sshd_config
+  func_wrapper check_root_owns "${SSHD_CFG}"
+  func_wrapper check_file_perms "${SSHD_CFG}" 600
+
+  # CIS 6.2.4 SSH X11Forwarding
+  func_wrapper chk_param "${SSHD_CFG}" X11Forwarding no
+
+  # CIS 6.2.5 SSH MaxAuthTries
+  func_wrapper ssh_maxauthtries 4
+
+  # CIS 6.2.6 SSH X11Forwarding
+  func_wrapper chk_param "${SSHD_CFG}" IgnoreRhosts yes
+
+  # CIS 6.2.7 SSH HostbasedAuthentication
+  func_wrapper chk_param "${SSHD_CFG}" HostbasedAuthentication no
+
+  # CIS 6.2.8 SSH PermitRootLogin
+  func_wrapper chk_param "${SSHD_CFG}" PermitRootLogin no
+
+  # CIS 6.2.9 SSH PermitEmptyPasswords
+  func_wrapper chk_param "${SSHD_CFG}" PermitEmptyPasswords no
+
+  # CIS 6.2.10 SSH PermitUserEnvironment
+  func_wrapper chk_param "${SSHD_CFG}" PermitUserEnvironment no
+
+  # CIS 6.2.11 SSH Ciphers
+  func_wrapper chk_param "${SSHD_CFG}" Ciphers aes128-ctr,aes192-ctr,aes256-ctr
+
+  # CIS 6.2.12 SSH Idle Timeout Interval for User Login
+  func_wrapper chk_param "${SSHD_CFG}" ClientAliveInterval 300
+  func_wrapper chk_param "${SSHD_CFG}" ClientAliveCountMax 0
+
+  # CIS 6.2.13 Limit access to SSH
+  func_wrapper ssh_access
+
+  # CIS 6.2.14 SSH banner
+  func_wrapper chk_param "${SSHD_CFG}" Banner /etc/issue.net
+
+  # CIS 6.3.1 SHA-512 password hashing algorithm
+  func_wrapper pass_hash_algo sha512
+
+  # CIS 6.3.2 password creation requirement parameters using pam_pwquality
+  func_wrapper pass_req_params
+
+  # CIS 6.3.3 Set lockout for failed password attempts
+  func_wrapper failed_pass_lock
+
+  # CIS 6.3.4 Limit password reuse
+  func_wrapper lim_passwd_reuse
+
+  # CIS 6.4 Restrict root login to system console
+  # This is too env specific to put a check in for
+
+  # CIS 6.5 Restrict access to su
+  func_wrapper su_access
+
+  # CIS 7.1.1 Password expiration days
+  func_wrapper chk_param "${LOGIN_DEFS}" PASS_MAX_DAYS 90
+
+  # CIS 7.1.2 Password change minimum number of days
+  func_wrapper chk_param "${LOGIN_DEFS}" PASS_MIN_DAYS 7
+
+  # CIS 7.1.3 Password expiring warning days
+  func_wrapper chk_param "${LOGIN_DEFS}" PASS_WARN_AGE 7
+
+  # CIS 7.2 Disable System Accounts
+  func_wrapper dis_sys_accs
+
+  # CIS 7.3 Default group for root account
+  func_wrapper root_def_grp
+
+  # CIS 7.4 Default group for root account
+  func_wrapper def_umask_for_users
+
+  # CIS 7.5 Inactive User accounts should be locked
+  func_wrapper inactive_usr_acs_locked
+
+  # CIS 8.1 user/group owner and perms on
+  # /etc/motd /etc/issue /etc/issue.net
+
+  for file in ${MOTD} ${ISSUE} ${ISSUE_NET} ; do
+    func_wrapper check_root_owns "${file}"
+    func_wrapper check_file_perms "${file}" 644
+  done
+
+  # CIS 8.2 OS Information should not be in Login Warning Banners
+  func_wrapper warning_banners
+
+  # CIS 8.3 Set GNOME Warning Banner
+  # On a host aiming to meet CIS requirements GNOME is unlikely to be installed
+  # Thus the function says if the file exists then it should have these lines in it
+  func_wrapper gnome_banner
+
+  # CIS 9.1.2 Verify perms on /etc/passwd
+  func_wrapper check_file_perms "${PASSWD}" 644
+
+  # CIS 9.1.3 Verify perms on /etc/shadow
+  func_wrapper check_file_perms "${SHADOW}" 0
+
+  # CIS 9.1.4 Verify perms on /etc/gshadow
+  func_wrapper check_file_perms "${GSHADOW}" 0
+
+  # CIS 9.1.5 Verify perms on /etc/group
+  func_wrapper check_file_perms "${GROUP}" 644
+
+  # CIS 9.1.6-9 user/group owner and perms on /etc/passwd /etc/shadow /etc/gshadow /etc/group
+  for file in ${PASSWD} ${SHADOW} ${GSHADOW} ${GROUP} ; do
+    func_wrapper check_root_owns "${file}"
+  done
+
+  # CIS 9.1.10 Shouldn't have any world writable files
+  func_wrapper world_w_dirs
+
+  # CIS 9.1.11 Shouldn't have any unowned files & dirs
+  func_wrapper unowned_files
+
+  # CIS 9.1.12 Shouldn't have any ungrouped files & dirs
+  func_wrapper ungrouped_files
+
+  # CIS 9.1.13 Check for suid executables
+  func_wrapper suid_exes
+
+  # CIS 9.1.14 Check for sgid executables
+  func_wrapper sgid_exes
+
+  # CIS 9.2.1 Ensure password fields are not empty
+  func_wrapper passwd_field_chk
+
+  # CIS 9.2.2 Verify no legacy "+" entries exist in /etc/passwd
+  func_wrapper nis_in_file ${PASSWD}
+
+  # CIS 9.2.3 Verify no legacy "+" entries exist in /etc/shadow
+  func_wrapper nis_in_file ${SHADOW}
+
+  # CIS 9.2.4 Verify no legacy "+" entries exist in /etc/group
+  func_wrapper nis_in_file ${GROUP}
+
+  # CIS 9.2.5 Verify no UID 0 accounts exist other than root
+  func_wrapper no_uid0_other_root
+
+  # CIS 9.2.6 Ensure root PATH integrity
+  func_wrapper root_path
+
+  # CIS 9.2.7 Home dir perms
+  func_wrapper home_dir_perms
+
+  # CIS 9.2.8 User dot file permissions
+  func_wrapper dot_file_perms
+
+  # CIS 9.2.9 User .netrc permissions
+  func_wrapper dot_netrc_perms
+
+  # CIS 9.2.10 User .rhosts files
+  func_wrapper dot_rhosts_files
+
+  # CIS 9.2.11 User .rhosts files
+  func_wrapper chk_groups_passwd
+
+  # CIS 9.2.12 User .rhosts files
+  func_wrapper chk_home_dirs_exist
+
+  # CIS 9.2.13 Check home directory ownership
+  func_wrapper chk_home_dirs_owns
+
+  # CIS 9.2.14 Check for Duplicate UIDs in /etc/passwd
+  func_wrapper duplicate_uids
+
+  # CIS 9.2.15 Check for Duplicate GIDs in /etc/group
+  func_wrapper duplicate_gids
+
+  # CIS 9.2.16 Check that reserved uids are assigned
+  func_wrapper chk_uids_4_res
+
+  # CIS 9.2.17 Check for Duplicate usernames in /etc/passwd
+  func_wrapper duplicate_usernames
+
+  # CIS 9.2.18 Check for Duplicate groupnames in /etc/group
+  func_wrapper duplicate_groupnames
+
+  # CIS 9.2.19 Check for presence of user .netrc files
+  func_wrapper user_dot_netrc
+
+  # CIS 9.2.20 Check for presence of user .forward files
+  func_wrapper user_dot_forward
+
+}
+
+main