#!/bin/bash

### BEGIN INIT INFO
# Provides:          secure-bindmounts
# Required-Start:    $local_fs $remote_fs mountall
# Required-Stop:
# Default-Start:     2 3 4 5
# Default-Stop:
# Short-Description: secure bindmounts
# Description:       Secure bindmounts (apply noexec, nosuid, nodev)
### END INIT INFO

function get_bindmounts()
{
	while read MNT_FSNAME MNT_DIR MNT_TYPE MNT_OPTS MNT_FREQ MNT_PASS MNT_JUNK; do
		case "$MNT_FSNAME" in
			""|\#*)
			continue;
			;;
		esac
		case "$MNT_OPTS" in
			""*bind*)
			echo "$MNT_OPTS;$MNT_DIR"
			;;
		esac
	done < /etc/fstab
}

function secure_bindmount()
{
	nmnt_dir=$1
	nmnt_opt=$2

	if [ -n "$nmnt_dir" -a -d "$nmnt_dir" ]; then
		if ! (echo "$live_mounts" | grep "on ${nmnt_dir} " |grep -E "[,\(]${nmnt_opt}[,\)]" >/dev/null); then
			case "$nmnt_opt" in
				noexec)
				echo "mount -o remount,noexec $nmnt_dir"
				;;
				nosuid)
				echo "mount -o remount,nosuid $nmnt_dir"
				;;
				nodev)
				echo "mount -o remount,nodev $nmnt_dir"
				;;
				ro)
				echo "mount -o remount,ro $nmnt_dir"
				;;
			esac
			echo "SECURED $nmnt_dir ($nmnt_opt)"
		fi
	fi
}

case $1 in
    stop)
	echo "Securing bindmounts: nothing to do"
    ;;

    *)
	echo "Securing bindmounts:"

	bindmounts=`get_bindmounts`
	live_mounts=`mount`

	for bm in $bindmounts;do

		mnt_opts=${bm%%;*}
		mnt_dir=${bm#*;}

		if [ -n "$mnt_dir" -a -d "$mnt_dir" ]; then
			if (echo "$live_mounts" | grep "on ${mnt_dir} " >/dev/null); then
				if [[ "$mnt_opts" == *"noexec"* ]]; then
					secure_bindmount $mnt_dir noexec
				fi
				if [[ "$mnt_opts" == *"nosuid"* ]]; then
					secure_bindmount $mnt_dir nosuid
				fi
				if [[ "$mnt_opts" == *"nodev"* ]]; then
					secure_bindmount $mnt_dir nodev
				fi
				if [[ "$mnt_opts" == *"ro"* ]]; then
					secure_bindmount $mnt_dir ro
				fi
			else
				echo "WARNING: $mnt_dir not mounted"
			fi
		fi
	done
	echo "All bindmounts secured."
    ;;
esac
