TA-unix/bin/service.sh

196 lines
5.9 KiB
Bash
Executable file

#!/bin/sh
# SPDX-FileCopyrightText: 2024 Splunk, Inc.
# SPDX-License-Identifier: Apache-2.0
# shellcheck disable=SC1091
. "$(dirname "$0")"/common.sh
# In AWK scripts in this file, the following are true:
# FULLTEXT is used to capture the output for SHA256 checksum generation.
# SPLUNKD is used to determine Splunk service status.
if [ "$KERNEL" = "Linux" ] ; then
if ! queryHaveCommand systemctl; then
assertHaveCommand date
assertHaveCommand chkconfig
CMD='eval date ; /sbin/chkconfig --list'
# shellcheck disable=SC2016
PARSE_0='NR==1 {DATE=$0 ; FULLTEXT=""}'
# shellcheck disable=SC2016
PARSE_1='NR>1 {
FULLTEXT = FULLTEXT $0 "\n"
split($0, ARR)
EVT="app=" ARR[1]
for (i=0 ; i<7 ; i++) {
split(ARR[i+2], STATE, ":")
EVT = EVT " runlevel" i "=" STATE[2]
}
if (ARR[1] ~ /[Ss][Pp][Ll][Uu][Nn][Kk]/) { SPLUNKD=1 }
printf "%s type=chkconfig %s\n", DATE, EVT
}'
MASSAGE="$PARSE_0 $PARSE_1"
# Send the collected full text to openssl; this avoids any timing discrepancies
# between when the information is collected and when we process it.
# shellcheck disable=SC2016
POSTPROCESS='END {
if (SPLUNKD==0) { printf "%s app=\"Splunk\" StartMode=Disabled\n", DATE }
printf "%s %s", DATE, "file_hash="
printf "%s", FULLTEXT | "LD_LIBRARY_PATH=$SPLUNK_HOME/lib $SPLUNK_HOME/bin/openssl sha256"
}'
else
assertHaveCommand systemctl
assertHaveCommand date
# Run the systemctl command to get all units and their state
CMD='eval date; systemctl list-units --type=service --all'
# shellcheck disable=SC2016
PARSE_0='NR==1 {DATE=$0}'
# shellcheck disable=SC2016
PARSE_1='
# On header row, get lengths to the fields
NR==2 {
match($0, /^ */); leading=RLENGTH;
match($0, /^.*DESC/); desclen=RLENGTH-4;
FULLTEXT="";
next;
}'
# shellcheck disable=SC2016
PARSE_2='(NR > 2){
# Stop at the empty line
if ( !NF ) { exit; }
# Skip the leading spaces
$0 = substr( $0, leading );
# the description spans fields so catch it seperately
desc=substr( $0, desclen );
FULLTEXT = FULLTEXT $0 "\n"
if ($1 ~ /[Ss][Pp][Ll][Uu][Nn][Kk]/) { SPLUNKD=1 }
printf "%s type=systemctl UNIT=%s, LOADED=%s, ACTIVE=%s, SUB=%s, DESCRIPTION=\"%s\" \n",DATE, $1, $2, $3, $4, desc
}'
MASSAGE="$PARSE_0 $PARSE_1 $PARSE_2"
# shellcheck disable=SC2016
POSTPROCESS='END {
if (SPLUNKD==0) { printf "%s app=\"Splunk\" StartMode=Disabled\n", DATE }
printf "%s %s", DATE, "file_hash="
printf "%s", FULLTEXT | "LD_LIBRARY_PATH=$SPLUNK_HOME/lib $SPLUNK_HOME/bin/openssl sha256"
}'
fi
elif [ "$KERNEL" = "SunOS" ] ; then
assertHaveCommand date
assertHaveCommand svcs
CMD='eval date ; svcs -H -a -o STATE,FMRI'
# shellcheck disable=SC2016
PARSE_0='NR==1 {DATE=$0 ; FULLTEXT=""}'
# shellcheck disable=SC2016
PARSE_1='NR>1 {
STATE="State=\""$1"\""
idx=index($2,":")
STARTNAME="StartName=\""substr($2,0,idx-1)"\""
APP="app=\""substr($2,idx+1)"\""
FULLTEXT=FULLTEXT $0 "\n"
}'
PARSE_2='/^legacy_run/ {
STARTMODE="StartMode=\"Auto\""
}'
PARSE_3='/^online/ {
STARTMODE="StartMode=\"Auto\""
STATE="State=\"Running\""
}'
PARSE_4='/^disabled/ {
STARTMODE="StartMode=\"Disabled\""
STATE="State=\"Stopped\""
}'
INLINE_PRINT='NR>1 && APP!=0 {printf "%s %s %s %s %s\n", DATE, APP, STARTMODE, STARTNAME, STATE}'
MASSAGE="$PARSE_0 $PARSE_1 $PARSE_2 $PARSE_3 $PARSE_4 $INLINE_PRINT"
# Send the collected full text to openssl; this avoids any timing discrepancies
# between when the information is collected and when we process it.
# shellcheck disable=SC2016
POSTPROCESS='END {
if (SPLUNKD==0) { printf "%s app=\"Splunk\" StartMode=Disabled\n", DATE }
printf "%s %s", DATE, "file_hash="
printf "%s", FULLTEXT | "LD_LIBRARY_PATH=$SPLUNK_HOME/lib $SPLUNK_HOME/bin/openssl sha256"
}'
elif [ "$KERNEL" = "Darwin" ] ; then
assertHaveCommand date
assertHaveCommand defaults
assertHaveCommand dscl
assertHaveCommand find
assertHaveCommand ls
# Get startup items
CMD='eval date ; ls -1 /System/Library/StartupItems/ /Library/StartupItems/'
# Get per-user startup items
# shellcheck disable=SC2044
for PLIST_FILE in $(find /Users -name "loginwindow.plist") ; do
CMD=$CMD' ; echo '$PLIST_FILE': ; defaults read '$PLIST_FILE
done
# shellcheck disable=SC2016
PARSE_0='NR==1 {DATE=$0}'
# Retrieve path for system startup items
# shellcheck disable=SC2016
PARSE_1='/^\/(System|Library)/ {
split($0, tmparr, ":")
PATH="file_path=\""tmparr[1]
USER=0
START_MODE="StartMode=Auto"
START_TYPE="StartType=startup"
}'
# Retrieve user information for user startup items.
# shellcheck disable=SC2016
PARSE_2='/^\/Users/ {
split($0, tmparr, "/")
USER="user=" tmparr[3]
START_MODE="StartMode=Auto"
START_TYPE="StartType=login"
}'
# Retrieve the path for user startup items.
# shellcheck disable=SC2016
PARSE_3='/[[:blank:]]*Path/ {
split($0, path_arr, "=")
num=split(path_arr[2], app_arr, "/")
split(app_arr[num], app_final, ".")
split(path_arr[2], path_final, "\"")
APP="app=\"" app_final[1] "\""
FILE_PATH="file_path=\"" path_final[2] "\""
# Only print if we find a path.
printf "%s %s %s %s %s %s\n", DATE, APP, START_MODE, START_TYPE, FILE_PATH, USER
# Note that we found splunkd if app matches
if (APP ~ /[Ss][Pp][Ll][Uu][Nn][Kk]/) { SPLUNKD=1 }
}'
# Retrieve the system startup item name from the output of "ls -1"
# shellcheck disable=SC2016
PARSE_4='/^[^\/]/ {
if (NR>1 && USER==0 && NF > 0) {
APP="app=\""$0"\""
PATH=PATH$0"\""
printf "%s %s %s %s %s\n", DATE, APP, START_MODE, START_TYPE, PATH
}
# Note that we found splunkd if app matches
if (APP ~ /[Ss][Pp][Ll][Uu][Nn][Kk]/) { SPLUNKD=1 }
}'
MASSAGE="$PARSE_0 $PARSE_1 $PARSE_2 $PARSE_3 $PARSE_4"
POSTPROCESS='END { if (SPLUNKD==0) { printf "%s app=\"Splunk\" StartMode=Disabled\n", DATE } }'
else
# Exits
failUnsupportedScript
fi
$CMD | tee "$TEE_DEST" | $AWK "$MASSAGE $POSTPROCESS"
echo "Cmd = [$CMD]; | $AWK '$MASSAGE $POSTPROCESS'" >> "$TEE_DEST"