#!/bin/bash

#########################################

CHR_ROOT=/chroot

#########################################

CHRBIN=/usr/sbin/chroot
PARTIAL=/var/cache/apt/archives/partial

#########################################

function get_daemons()
{
	case "$(readlink -f /proc/1/exe)" in
		*systemd*)
			INITSYS=systemd
			systemd_units=`systemctl list-units --type=service --state=active --quiet --no-pager |grep 'loaded active' |awk '{print $1}' | grep -v '@' | sed 's/\.service//'`

			for au in $systemd_units; do
				scriptname=`systemctl show $au --property=SourcePath | grep '^SourcePath=/etc/init.d/' | sed 's/SourcePath=//'`
				if [ -z "$scriptname" ]; then
					urd=$(systemctl show $au --property=RootDirectory | grep '^RootDirectory=/chroot/') && echo "$au:$urd" | sed 's/RootDirectory=\/chroot\///'
				else
					drd=$(grep -e "^CHRDIR=/chroot/" $scriptname) && echo "$au:$drd" | sed 's/CHRDIR=\/chroot\///'
				fi
			done
			;;
		*)
			find /etc/init.d/ -type f -regex '^.*\/[A-Za-z0-9\_\-]*$' -exec grep -He "^CHRDIR=/chroot/" {} \; | sed 's/^\/etc\/init.d\///' | sed 's/CHRDIR=\/chroot\///'
			;;
	esac
	return 0
}

function grsec_chr_suspend()
{
		MODE=1
		if [ "$1" == "0" ]; then
			MODE=0
		fi
		CHROPTS=`sysctl -aN 2>/dev/null |grep "kernel.grsecurity.chroot"`
		for CHROPT in $CHROPTS; do
			if [ "$CHROPT" == "kernel.grsecurity.chroot_caps" ]; then
				sysctl -q -w $CHROPT=0
			elif [ "$CHROPT" == "kernel.grsecurity.chroot_deny_bad_rename" ]; then
				sysctl -q -w $CHROPT=0
			else
				sysctl -q -w $CHROPT=$MODE
			fi
		done
}

function chr_daemons_restart()
{
	R_CHROOT=$1
	[ -d ${R_CHROOT} ] || return 21

	R_CHRN=`basename $R_CHROOT`

	to_restart=`echo "$CHR_DAEMONS" | grep ":${R_CHRN}$" | sed 's/:.*$//'`

	if [ -z "$to_restart" ]; then
		echo "No daemon to restart" >>${R_CHROOT}/var/log/unattended-upgrades/restart-daemon.log
		return 0
	fi

	case "$(readlink -f /proc/1/exe)" in
		*systemd*)
			to_restart_list=`echo $to_restart`
			date >>${R_CHROOT}/var/log/unattended-upgrades/restart-daemon.log
			systemctl restart $to_restart_list
			systemctl status $to_restart_list >>${R_CHROOT}/var/log/unattended-upgrades/restart-daemon.log
			return $?
			;;
		*)
			date >>${R_CHROOT}/var/log/unattended-upgrades/restart-daemon.log
			for r_daemon in $to_restart; do
				/etc/init.d/${r_daemon} stop >>${R_CHROOT}/var/log/unattended-upgrades/restart-daemon.log
			done
			sleep 5
			for r_daemon in $to_restart; do
				/etc/init.d/${r_daemon} start >>${R_CHROOT}/var/log/unattended-upgrades/restart-daemon.log
			done
			return 0
			;;
	esac

	return 0
}

#########################################

# gather from all the chroots
if [ -d $CHR_ROOT ]; then
	CHROOTS=`ls -1 $CHR_ROOT`
fi

CHR_DAEMONS=`get_daemons`

# suspend chroot hardening
grsec_chr_suspend 0

for CHR in $CHROOTS; do
	CHRDIR=$CHR_ROOT/$CHR
	if [ -d $CHRDIR/etc/apt ]; then
		if ! [ -d $CHRDIR$PARTIAL ]; then
			mkdir $CHRDIR$PARTIAL
		fi
		if [ -f $CHRDIR/etc/cron.daily/apt-compat -o -f $CHRDIR/usr/lib/apt/apt.systemd.daily ]; then
			#$CHRBIN $CHRDIR /etc/cron.daily/apt-compat
			$CHRBIN $CHRDIR /usr/lib/apt/apt.systemd.daily
		elif [ -f $CHRDIR/etc/cron.daily/apt ]; then
			$CHRBIN $CHRDIR /etc/cron.daily/apt
		fi
		if [ -f $CHRDIR/etc/cron.daily/dpkg ]; then
			$CHRBIN $CHRDIR /etc/cron.daily/dpkg
		fi
		sleep 1

		# restart chroot daemons if anything is upgraded
		UA_LOGDIR=$CHRDIR/var/log/unattended-upgrades
		if [ -d ${UA_LOGDIR} ]; then
			UPGRADED=`find ${UA_LOGDIR}/ -type f -cmin -30 -name 'unattended-upgrades-dpkg.log'`
			if [ "$UPGRADED" == "${UA_LOGDIR}/unattended-upgrades-dpkg.log" ]; then
				chr_daemons_restart $CHRDIR
			fi
		fi

	fi
done

# reset chroot hardening
grsec_chr_suspend 1

exit 0
