#!/bin/bash

mac_ena=`cat /parsecfs/mac_enabled 2> /dev/null`;

# max values for label parts
sysmaxlev=3
sysmaxilev=`cat /sys/module/parsec/parameters/max_ilev`
hexmaxilev=`printf %x $sysmaxilev`
sysmaxcat=0xffffffffffffffff

sysmaxlbl="$sysmaxlev:$sysmaxilev:$sysmaxcat"
confmaxlbl="$sysmaxlev:0:$sysmaxcat"

case "$mac_ena" in
	1)
		imaxlbl="$sysmaxlbl"
		maxlbl="$confmaxlbl"
		;;
	*)
		imaxlbl="0:$sysmaxilev:0"
		maxlbl="0:0:0"
		;;
esac

# --after-test is used by tests from /usr/sbin/parsec/tests
if [ $# -gt 0 ]; then
    while [ -n "$1" ]; do
        case "$1" in
            "--after-test")
            /usr/sbin/pdpl-file "0:0:0:0" /tmp
            /usr/sbin/pdpl-file "$sysmaxlbl:CCNRA" /
            exit 0
            ;;
        esac
        shift
    done
fi

# ccnr/CCNRA flag allows storing variable-label content
/usr/sbin/pdpl-file "$sysmaxlbl:CCNRA" /
/usr/sbin/pdpl-file "$imaxlbl:CCNRA" /dev
/usr/sbin/pdpl-file "$sysmaxlbl:ccnr" /dev/pts

# set max label on block devices to prevent direct data access
/usr/sbin/pdpl-file "$imaxlbl"       /dev/sd*
/usr/sbin/pdpl-file "$imaxlbl"       /dev/hd* 2>/dev/null
/usr/sbin/pdpl-file "$imaxlbl"       /dev/vd* 2>/dev/null
/usr/sbin/pdpl-file "$imaxlbl"       /dev/xvd*  2>/dev/null
/usr/sbin/pdpl-file "$imaxlbl"       /dev/dm*  2>/dev/null
/usr/sbin/pdpl-file -R "$imaxlbl:CCNRA" /dev/mapper
/usr/sbin/pdpl-file "$imaxlbl"       /dev/mmc*  2>/dev/null
/usr/sbin/pdpl-file "$imaxlbl"       /dev/mtdblock* 2>/dev/null
/usr/sbin/pdpl-file "$imaxlbl"       /dev/nvme* 2>/dev/null

# prevent input device hijacking
/usr/sbin/pdpl-file -R "$imaxlbl:CCNRA" /dev/input
/usr/sbin/pdpl-file -R "$imaxlbl"       /dev/input

# deny access to mem devices
# /dev/mem needed for mga driver gets integrity 8 (Graphic_server)
/usr/sbin/pdpl-file ":8"             /dev/mem 2>/dev/null
/usr/sbin/pdpl-file ":$sysmaxilev"   /dev/kmem 2>/dev/null
/usr/sbin/pdpl-file ":$sysmaxilev"   /dev/port 2>/dev/null

# allow access to virtualbox special devices for all users
[ -e /dev/vboxuser ] &&
/usr/sbin/pdpl-file "0:0:0:ehole"    /dev/vboxuser
[ -e /dev/vboxguest ] &&
/usr/sbin/pdpl-file "0:0:0:ehole"    /dev/vboxguest

# level-specific shared storage, see /etc/parsec/mlinks
/usr/sbin/pdpl-file "$imaxlbl:CCNRA" /run/
/usr/sbin/pdpl-file "$maxlbl:ccnr" /run/private/
/usr/sbin/pdpl-file "$maxlbl:ccnr" /run/private/shm/
/usr/sbin/pdpl-file "$maxlbl:ccnr" /run/private/mount/
/usr/sbin/pdpl-file "$maxlbl:ccnr" /run/user/
/usr/sbin/pdpl-file "$maxlbl:ccnr" /run/user/private/

# protect mail and print spools
/usr/sbin/pdpl-file "$sysmaxlbl:ccnr" /var/
/usr/sbin/pdpl-file "$sysmaxlbl:ccnr" /var/spool/
/usr/sbin/pdpl-file "$confmaxlbl:ccnr" /var/mail/

# reset integrity level for directories in /var/spool
find /var/spool -type d -not -path /var/spool/cron -not -path /var/spool |
while read -r dir; do
	ilev=$(/usr/bin/pdp-ls -Mdn "$dir" | cut -d':' -f2)
	if [ "$ilev" != "0" ]; then
		/usr/sbin/pdpl-file -Rrs "$sysmaxlev:0:0" "$dir"
	fi
done

# level-specific shared storage, see /etc/parsec/mlinks
/usr/sbin/pdpl-file "$confmaxlbl:ccnr" /var/private/
/usr/sbin/pdpl-file "$confmaxlbl:ccnr" /var/private/*

# set integrity on digsig interface files
/usr/sbin/pdpl-file ":$sysmaxilev" /sys
/usr/sbin/pdpl-file ":$sysmaxilev" /sys/digsig
/usr/sbin/pdpl-file ":$sysmaxilev" /sys/digsig/*

# /home stores user homes for various levels
/usr/sbin/pdpl-file "$sysmaxlbl:CCNRA" /home/
/usr/sbin/pdpl-file "$sysmaxlbl:CCNRA" /home/.pdp/

source /etc/environment
if [ -n "$PDP_HOME" ]; then
	mkdir -p $PDP_HOME &&
	/usr/sbin/pdpl-file "$sysmaxlbl:CCNRA" $PDP_HOME
fi

# allow access to GPU special devices for all users
find /dev/dri     -type c -exec /usr/sbin/pdpl-file "0:0:0:ehole" {} \;
find /dev/nvidia* -type c -exec /usr/sbin/pdpl-file "0:0:0:ehole" {} \; 2>/dev/null

find /dev/mali* -type c -exec /usr/sbin/pdpl-file "0:0:0:ehole" {} \; 2>/dev/null

# integrity 8 (Graphic_server) for xauth dir
mkdir -p /var/run/xauth
pdpl-file 0:8:0:0 /var/run/xauth

# pre-create [/var]/run/xrdp with zero label (obsolete)
mkdir -p /var/run/xrdp
pdpl-file 0:0:0:0 /var/run/xrdp

# in strict_mode, set irelax on /tmp, adjust hi-ilev users' homes integrity
if [ "`cat /sys/module/parsec/parameters/strict_mode 2> /dev/null`" = "Y" ]; then
	pdpl-file 0:$sysmaxilev::irelax /tmp
	pdpl-file 0:$sysmaxilev /var/spool/cron
	pdpl-file 0:$sysmaxilev::irelax /var/spool/cron/crontabs

	for micfile in /etc/parsec/micdb/*; do
		uid=$(basename $micfile)
		umic=`printf %d 0x$(cat $micfile | cut -d ":" -f2)`
		uhome=$(getent passwd $uid | cut -d ":" -f6)
		uname=$(getent passwd $uid | cut -d ":" -f1)
		hmic=$(pdp-ls -Mdn $uhome | tr -s " " | cut -d " " -f5 | cut -d ":" -f2)
		if [ "$hmic" -ne "$umic" ]; then
			pdpl-file -R "0:$umic:0:0" /home/${uname}
		fi
	done
else
	pdpl-file -R 0:0:0:0 /tmp

	# set high integrity on homes for astra-admin members
	for admin in `getent group astra-admin | gawk -F: '{print $4}' | gawk '{gsub(","," ")}1'` ; do
		if [ -d /home/${admin} ] && grep -q "^.*:$hexmaxilev$" /etc/parsec/micdb/`id -u $admin` 2>/dev/null ; then
			pdpl-file "0:$sysmaxilev:0:0" /home/${admin}
		fi
	done
fi

# set up audit for parsec system files
/usr/sbin/setfaud -Rm o:cyu /etc/digsig
/usr/sbin/setfaud -Rm o:cyu /etc/parsec

/usr/sbin/setfaud -dm o:cyu /etc/digsig
/usr/sbin/setfaud -dm o:cyu /etc/parsec
/usr/sbin/setfaud -dm o:cyu /etc/parsec/auddb
/usr/sbin/setfaud -dm o:cyu /etc/parsec/capdb
/usr/sbin/setfaud -dm o:cyu /etc/parsec/macdb
/usr/sbin/setfaud -dm o:cyu /etc/parsec/micdb
if [ -e /proc/sched_debug ]; then chmod 0400 /proc/sched_debug || true; fi
if [ -e /sys/module/kernel/parameters/consoleblank ]; then chmod 0400 /sys/module/kernel/parameters/consoleblank || true; fi

pdpl-file -u :::silev /usr/bin/passwd
pdpl-file -u :::silev /usr/bin/sumac
