#!/bin/sh
# PCP QA Test No. 917
# SELinux Testing
#
# Copyright (c) 2017 Red Hat Inc.  All Rights Reserved.
#

seq=`basename $0`
echo "QA output created by $seq"

# get standard environment, filters and checks
. ./common.product
. ./common.filter
. ./common.check

policy_name="pcpupstream"
policy_file="$PCP_VAR_DIR/selinux/$policy_name.pp"
which sedismod >/dev/null 2>&1 || _notrun "sedismod tool not installed (module disassembly)"
which semodule >/dev/null 2>&1 || _notrun "semodule tool not installed"
which seinfo >/dev/null 2>&1 || _notrun "seinfo tool not installed"
( seinfo -t 2>&1 | grep 'Default policy search failed: No such file or directory' >/dev/null ) && _notrun "seinfo version bad: can't load default policy"
[ -f "$policy_file" ] || _notrun "upstream policy package not installed"
$sudo semodule -l 2>&1 | grep -q $policy_name || _notrun "upstream policy package not loaded"

nsfs_t=`seinfo -t | grep 'nsfs_t$'`
docker_var_lib_t=""
svirt_lxc_net_t=`seinfo -t | grep "svirt_lxc_net_t$"`
systemd_systemctl_exec_t=`seinfo -t | grep "systemd_systemctl_exec_t$"`
systemd_systemctl_unit_file_t=`seinfo -t | grep "systemd_unit_file_t$"`
systemd_systemctl_unit_dir_t=`seinfo -t | grep "systemd_unit_dir_t$"`
devlog_t=`seinfo -t | grep "devlog_t$"`
init_t=`seinfo -t | grep "init_t$"`
cap_userns_ptrace=`seinfo --class=cap_userns -x 2>&1 | grep "sys_ptrace$"`
unreserved_port_t=`seinfo -t | grep "unreserved_port_t$"`
tracefs_t=`seinfo -t | grep "tracefs_t$"`
class_status=`seinfo -x --class=system | grep "status$"`
sock_file_getattr=`seinfo -x --class=sock_file | grep "getattr$"`
hostname_exec_map_a=`seinfo -x --class=file | grep "map$"`
hostname_exec_map_b=`seinfo -x --common=file 2>/dev/null | grep "map$"`
#container_runtime_tmpfs_t=`seinfo -t | grep "container_runtime_tmpfs_t$"`
container_runtime_tmpfs_t=""
unconfined_service=`seinfo -t | grep "unconfined_service_t$"`
mock_var_lib=`seinfo -t | grep "mock_var_lib_t$"`
numad_context=`seinfo -t | grep "numad_t$"`

_filter_semodule()
{
    awk '{ print $1 }'
}

_filter_sedismod()
{
    sed -n '/--- begin avrule block ---/,$p'
}
_filter_sedismod1()
{
    sed -e '/^Command/d'
}
_filter_outfile()
{
    awk -v container_t="$container_runtime_t" \
	-v container_tmpfs_t="$container_runtime_tmpfs_t" \
	-v nsfs_t="$nsfs_t" \
	-v docker_var_lib_t="$docker_var_lib_t" \
	-v svirt_lxc_net_t="$svirt_lxc_net_t" \
	-v class_status="$class_status" \
	-v systemd_systemctl_exec_t="$systemd_systemctl_exec_t" \
	-v systemd_systemctl_unit_file_t="$systemd_systemctl_unit_file_t" \
	-v systemd_systemctl_unit_dir_t="$systemd_systemctl_unit_dir_t" \
	-v devlog_t="$devlog_t" \
	-v init_t="$init_t" \
	-v cap_userns_ptrace="$cap_userns_ptrace" \
	-v unreserved_port_t="$unreserved_port_t" \
	-v tracefs_t="$tracefs_t" \
	-v sock_file_getattr="$sock_file_getattr" \
	-v hostname_exec_map_a="$hostname_exec_map_a" \
	-v hostname_exec_map_b="$hostname_exec_map_b" \
	-v unconfined_service="$unconfined_service" \
	-v mock_var_lib="$mock_var_lib" \
	-v numad_context="$numad_context" \
    '{
    	if (container_t == "" && /container_runtime_t /)
	   !/container_runtime_t / ;
	else if (container_tmpfs_t == "" && /container_runtime_tmpfs_t/)
	   !/container_runtime_tmpfs_t/ ;
	else if (nsfs_t == "" && /nsfs_t/)
	   !/nsfs_t/ ;
    	else if (docker_var_lib_t == "" && /docker_var_lib_t/)
	   !/docker_var_lib_t/ ;
    	else if (svirt_lxc_net_t == "" && /svirt_lxc_net_t/)
	   !/svirt_lxc_net_t/ ;
    	else if (systemd_systemctl_exec_t == "" && /systemd_systemctl_exec_t/)
	   !/systemd_systemctl_exec_t/ ;
    	else if (systemd_systemctl_unit_file_t == "" && /systemd_unit_file_t/)
	   !/systemd_unit_file_t/ ;
    	else if (systemd_systemctl_unit_dir_t == "" && /systemd_unit_dir_t/)
	   !/systemd_unit_dir_t/ ;
	else if (devlog_t == "" && /devlog_t/)
	   !/devlog_t/ ;
	else if (init_t == "" && /init_t/)
	   !/init_t/ ;
	else if (cap_userns_ptrace == "" && /cap_userns/)
	   !/cap_userns/ ;
	else if (unreserved_port_t == "" && /unreserved_port_t/)
	   !/unreserved_port_t/ ;
	else if (tracefs_t == "" && /tracefs_t/)
	   !/tracefs_t/ ;
        else if (class_status == "" && /system.*status/)
           !/system.*status/ ;
	else if (sock_file_getattr == "" && /gpmctl_t/)
	   !/gpmctl_t/ ;
	else if (unconfined_service == "" && /unconfined_service_t/)
	   !/unconfined_service_t/ ;
	else if (mock_var_lib == "" && /mock_var_lib_t/)
	   !/mock_var_lib_t/ ;
        else if (hostname_exec_map_a == "" && hostname_exec_map_b == "" && /ldconfig_exec_t/ && /map/)
           !/ldconfig_exec_t/ ;
        else if (hostname_exec_map_a == "" && hostname_exec_map_b == "" && /pcp_tmp_t/ && /map/)
           !/pcp_tmp_t/ ;
	else if (numad_context == "" && /numda_t/)
	   !/numad_t/ ;
	else if (hostname_exec_map_a == "" && hostname_exec_map_b == "" && /hostname_exec_t/ && /pcp_pmie_t/) {
	     printf("  allow [pcp_pmie_t] [hostname_exec_t] : [file] { execute execute_no_trans getattr open read };\n")
	   }
	else
	   print;
    }'
}

status=1	# failure is the default!
$sudo rm -rf $tmp $tmp.* $seq.full
trap "cd $here; $sudo rm -rf $tmp $tmp.*; exit \$status" 0 1 2 3 15
echo > $seq.full

cat $seq.out.in | _filter_outfile > $seq.out

echo "full policy modules list on the system"
$sudo semodule -l >> $seq.full
echo "Checking that pcpupstream policy module has been properly installed"
awk '{ print $1 }' $seq.full | grep "pcpupstream$"  | _filter_semodule
# real QA test starts here
echo "Checking policies."
printf '1\nq\n' | sedismod $policy_file | _filter_sedismod | _filter_sedismod1


# success, all done
status=0
exit
