#!/bin/sh

PREREQ="3adm_disable"

prereqs()
{
	echo "$PREREQ"
}

case $1 in
	prereqs)
		prereqs
		exit 0
		;;
esac

. /scripts/functions
. /scripts/security-functions

clear

securityfs_mnt=/sys/kernel/security
kysec_status_path="$securityfs_mnt/kysec/status"

kysec_is_enabled()
{
	if [ -e "$kysec_status_path" ]; then
		cat "$kysec_status_path"
	else
		echo 0
	fi
}

kysec_enabled=`kysec_is_enabled`

kysec_tmp=/etc/kysec/tmp
kysec_whlist_db=/etc/kysec/db/whlist.db
kysec_init=/usr/sbin/kysec-init

relabel_system_for_whlist()
{
	show_message "正在扫描文件系统..."
	rm -rf ${rootmnt}/$kysec_tmp
	mkdir -p -m 1777 ${rootmnt}/$kysec_tmp
	find ${rootmnt} -depth -maxdepth 1 \( -path ${rootmnt}/proc -o -path ${rootmnt}/run -o -path ${rootmnt}/sys -o -path ${rootmnt}/dev -o -path ${rootmnt}/tmp -o -path ${rootmnt}/cdrom -o -path ${rootmnt}/media -o -path ${rootmnt}/mnt -o -path ${rootmnt}/box -o -path ${rootmnt}/backup -o -path ${rootmnt}/data -o -path ${rootmnt}/lost+found -o -path ${rootmnt} \) -prune -o -print 1>${rootmnt}/$kysec_tmp/scanf
	cat ${rootmnt}/$kysec_tmp/scanf | xargs -i -P $(nproc) find {} \( -type f -o -type l \) -print 1>>${rootmnt}/$kysec_tmp/scan
	new=$(echo ${rootmnt} | sed 's#\/#\\\/#g')
	sed -i 's/^'${new}'//g' ${rootmnt}/$kysec_tmp/scan
	split -l 3333 ${rootmnt}/$kysec_tmp/scan -d -a 4 scan_
	mv scan_* ${rootmnt}/$kysec_tmp

	show_message "正在初始化系统执行控制安全标记，请稍候..."
	cat ${rootmnt}/$kysec_tmp/scanf | xargs -i -P $(nproc) ${kysec_init} --set-xattr {}
	${kysec_init} --rootmnt ${rootmnt} --set-special

	setfattr -n security.kysec -v none:none:trusted ${rootmnt}
}

relabel_system_for_whlist1()
{
        show_message "正在扫描文件系统..."
        rm -rf ${rootmnt}/$kysec_tmp
        mkdir -p -m 1777 ${rootmnt}/$kysec_tmp
        find ${rootmnt} -depth -maxdepth 1 \( -path ${rootmnt}/proc -o -path ${rootmnt}/run -o -path ${rootmnt}/sys -o -path ${rootmnt}/dev -o -path ${rootmnt}/tmp -o -path ${rootmnt}/cdrom -o -path ${rootmnt}/media -o -path ${rootmnt}/mnt -o -path ${rootmnt}/box -o -path ${rootmnt}/backup -o -path ${rootmnt}/data -o -path ${rootmnt}/home -o -path ${rootmnt}/lost+found -o -path ${rootmnt} \) -prune -o -print 1>${rootmnt}/$kysec_tmp/scanf
        cat ${rootmnt}/$kysec_tmp/scanf | xargs -i -P $(nproc) find {} \( -type f -o -type l \) -print 1>>${rootmnt}/$kysec_tmp/scan
        new=$(echo ${rootmnt} | sed 's#\/#\\\/#g')
        sed -i 's/^'${new}'//g' ${rootmnt}/$kysec_tmp/scan
        split -l 3333 ${rootmnt}/$kysec_tmp/scan -d -a 4 scan_
        mv scan_* ${rootmnt}/$kysec_tmp

        show_message "正在初始化系统执行控制安全标记，请稍候..."
        cat ${rootmnt}/$kysec_tmp/scanf | xargs -i -P $(nproc) ${kysec_init} --set-xattr {}
        ${kysec_init} --rootmnt ${rootmnt} --set-special

        setfattr -n security.kysec -v none:none:trusted ${rootmnt}
}

relabel_system_from_whlist()
{
	show_message "正在初始化系统执行控制安全标记，请稍候..."
	${kysec_init} --rootmnt ${rootmnt} --from-whlist
}

set_kysec_status()
{
	echo $1 > $kysec_status_path
}

relabel_file=${rootmnt}/.exectl

export exectl=
export relabel_flag=

get_relabel_flag()
{
	for x in $(cat /proc/cmdline); do
		case $x in
		exectl=*)
			exectl=${x#exectl=}
			;;
		esac
	done

	if [ -f "$relabel_file" -o "x${exectl}" = "x1" ]; then
		relabel_flag=$(sqlite3 "${rootmnt}/$kysec_whlist_db" "select * from relabel_status;")
	fi
}

do_remount()
{
	old_value=`cat $kysec_status_path`

	mount -o remount,rw ${ROOT} ${rootmnt}

	[ 0 -ne "$kysec_enabled" ] && set_kysec_status 4

	mount -t proc -o nodev,noexec,nosuid proc "$rootmnt/proc"
	mount -t sysfs -o nodev,noexec,nosuid sys "$rootmnt/sys"
	mount -t devtmpfs udev "$rootmnt/dev"

	chroot "${rootmnt}" /bin/mount -a

	if [ "$1" = "all" ]; then
		relabel_system_for_whlist
	elif [ "$1" = "whlist" ]; then
		relabel_system_from_whlist
	fi

	rm -f $relabel_file

	[ 0 -ne "$kysec_enabled" ] && set_kysec_status $old_value

	umount "$rootmnt/dev"
	umount "$rootmnt/sys"
	umount "$rootmnt/proc"
}

settag(){
        scanfile="${rootmnt}/$kysec_tmp/scan_v101"
        if [ -f "$scanfile" ]; then
                rm $scanfile
        fi

        touch $scanfile
        for i in `sqlite3 ${rootmnt}/fs.old/etc/kysec/db/whlist.db 'select path,exectl from objects_list where path LIKE "/home/%" or path LIKE "/data/%"';`
        do
                echo $i 
                path=${i%|*}
                exectl=${i#*|}

                if [ -f "$path" ];      then
                        setfattr -n security.kysec -v none:none:$exectl ${rootmnt}/$path
                        echo $path >> ${rootmnt}/$kysec_tmp/scan_v101
                fi
        done
}

do_remount1()
{
        old_value=`cat $kysec_status_path`

        mount -o remount,rw ${ROOT} ${rootmnt}

        [ 0 -ne "$kysec_enabled" ] && set_kysec_status 4

        mount -t proc -o nodev,noexec,nosuid proc "$rootmnt/proc"
        mount -t sysfs -o nodev,noexec,nosuid sys "$rootmnt/sys"
        mount -t devtmpfs udev "$rootmnt/dev"

        chroot "${rootmnt}" /bin/mount -a

        relabel_system_for_whlist1
	settag

        [ 0 -ne "$kysec_enabled" ] && set_kysec_status $old_value

        umount "$rootmnt/dev"
        umount "$rootmnt/sys"
        umount "$rootmnt/proc"
}

if [ -f "${rootmnt}/.autov101" ];then
        # disable kernel messages temporarily
        level=`cat /proc/sys/kernel/printk | awk '{print $1}'`
        show_message "文件系统Kysec安全标记需要重新初始化"
        echo 1 > /proc/sys/kernel/printk

        do_remount1
        # enable kernel messages
        echo "$level" > /proc/sys/kernel/printk
        clear_message
	if [ -f "$relabel_file" ]; then
                rm -f $relabel_file
	fi

	if [ -f "${rootmnt}/.autov101" ];then
		rm -rf ${rootmnt}/.autov101
	fi

	clear
	exit 0
fi

get_relabel_flag

if [ -n "$relabel_flag" ];then
	if [ "x$relabel_flag" = "x0" ]; then
		# disable kernel messages temporarily
		level=`cat /proc/sys/kernel/printk | awk '{print $1}'`
		show_message "文件系统Kysec安全标记需要重新初始化"
		echo 1 > /proc/sys/kernel/printk

		do_remount all
		# enable kernel messages
		echo "$level" > /proc/sys/kernel/printk
		clear_message
	elif [ "x$relabel_flag" = "x1" ]; then
		#do_remount whlist
		rm -f $relabel_file
	fi
fi

clear
