444 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			444 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
| #!/bin/sh
 | |
| #
 | |
| # ----------------------------------------------------------------------
 | |
| #    Copyright (c) 1999, 2000, 20001, 2004, 2005, NOVELL (All rights reserved)
 | |
| #
 | |
| #    This program is free software; you can redistribute it and/or
 | |
| #    modify it under the terms of version 2 of the GNU General Public
 | |
| #    License published by the Free Software Foundation.
 | |
| #
 | |
| #    This program is distributed in the hope that it will be useful,
 | |
| #    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
| #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
| #    GNU General Public License for more details.
 | |
| #
 | |
| #    You should have received a copy of the GNU General Public License
 | |
| #    along with this program; if not, contact Novell, Inc.
 | |
| # ----------------------------------------------------------------------
 | |
| # rc.subdomain.functions by Steve Beattie
 | |
| # Modified for Gentoo Linux, by Matthew Snelham
 | |
| #
 | |
| # Modifications Copyright 1999-2006 Gentoo Foundation
 | |
| # Distributed under the terms of the GNU General Public License v2
 | |
| # $Header: $
 | |
| 
 | |
| 
 | |
| # NOTE: rc.subdomain initscripts that source this file need to implement
 | |
| # the following set of functions:
 | |
| #	sd_action
 | |
| #	sd_log_info_msg
 | |
| #	sd_log_success_msg
 | |
| #	sd_log_warning_msg
 | |
| #       sd_log_failure_msg
 | |
| 
 | |
| 
 | |
| CONFIG_DIR=/etc/apparmor
 | |
| MODULE=apparmor
 | |
| OLD_MODULE=subdomain
 | |
| if [ -f "${CONFIG_DIR}/${MODULE}.conf" ] ; then
 | |
| 	APPARMOR_CONF="${CONFIG_DIR}/${MODULE}.conf"
 | |
| elif [ -f "${CONFIG_DIR}/${OLD_MODULE}.conf" ] ; then
 | |
| 	APPARMOR_CONF="${CONFIG_DIR}/${OLD_MODULE}.conf"
 | |
| else
 | |
| 	sd_log_warning_msg "Unable to find config file in ${CONFIG_DIR}, installation problem?"
 | |
| fi
 | |
| 
 | |
| # Read configuration options from ${APPARMOR_CONF}, default is to
 | |
| # warn if subdomain won't load.
 | |
| APPARMOR_MODULE_PANIC="warn"
 | |
| SUBDOMAIN_ENABLE_OWLSM="no"
 | |
| APPARMOR_ENABLE_AAEVENTD="no"
 | |
| 
 | |
| if [ -f "${APPARMOR_CONF}" ] ; then
 | |
| 	source "${APPARMOR_CONF}"
 | |
| fi
 | |
| 
 | |
| if [ -f /sbin/apparmor_parser ] ; then
 | |
| 	PARSER=/sbin/apparmor_parser
 | |
| else
 | |
| 	sd_log_failure_msg "Unable to find apparmor_parser, installation problem?"
 | |
| 	exit 1
 | |
| fi
 | |
| 
 | |
| # APPARMOR_DIR might be redefined in ${APPARMOR_CONF}
 | |
| if [ -d "${APPAMROR_DIR}" ] ; then
 | |
| 	PROFILE_DIR=${APPARMOR_DIR}
 | |
| elif [ -d /etc/apparmor.d ] ; then
 | |
| 	PROFILE_DIR=/etc/apparmor.d
 | |
| fi
 | |
| ABSTRACTIONS="-I${PROFILE_DIR}"
 | |
| AA_EV_BIN=/usr/sbin/aa-eventd
 | |
| AA_EV_PIDFILE=/var/run/aa-eventd.pid
 | |
| AA_STATUS=/usr/sbin/apparmor_status
 | |
| SD_EV_BIN=/usr/sbin/sd-event-dispatch.pl
 | |
| SD_EV_PIDFILE=/var/run/sd-event-dispatch.init.pid
 | |
| SD_STATUS=/usr/sbin/subdomain_status
 | |
| if grep -q securityfs /proc/filesystems ; then
 | |
| 	SECURITYFS=/sys/kernel/security
 | |
| fi
 | |
| 
 | |
| SUBDOMAINFS_MOUNTPOINT=$(grep subdomainfs /etc/fstab  | \
 | |
| 	sed -e 's|^[[:space:]]*[^[:space:]]\+[[:space:]]\+\(/[^[:space:]]*\)[[:space:]]\+subdomainfs.*$|\1|' 2> /dev/null)
 | |
| 
 | |
| if [ -d "/var/lib/${MODULE}" ] ; then
 | |
| 	APPARMOR_TMPDIR="/var/lib/${MODULE}"
 | |
| else
 | |
| 	APPARMOR_TMPDIR="/tmp"
 | |
| fi
 | |
| 
 | |
| 
 | |
| function parse_profiles() {	
 | |
| 	# get parser arg
 | |
| 	case "$1" in
 | |
| 		load)
 | |
| 			PARSER_ARGS="--add"
 | |
| 			PARSER_MSG="Loading AppArmor profiles "
 | |
| 			;;
 | |
| 		reload)
 | |
| 			PARSER_ARGS="--replace"
 | |
| 			PARSER_MSG="Reloading AppArmor profiles "
 | |
| 			;;
 | |
| 		*)
 | |
| 			exit 1
 | |
| 			;;
 | |
| 	esac
 | |
| 	sd_log_info_msg "$PARSER_MSG"
 | |
| 
 | |
| 	# run the parser on all of the apparmor profiles
 | |
| 	if [ ! -f "$PARSER" ]; then
 | |
| 		sd_log_failure_msg "$PARSER_MSG - AppArmor parser not found"
 | |
| 		exit 1
 | |
| 	fi
 | |
| 
 | |
| 	if [ ! -d "$PROFILE_DIR" ]; then
 | |
| 		sd_log_failure_msg "$PARSER_MSG - Profile directory not found"
 | |
| 		exit 1
 | |
| 	fi
 | |
| 
 | |
| 	if [ "X" == "X$(ls $PROFILE_DIR/)" ]; then
 | |
| 		sd_log_warning_msg "$PARSER_MSG - No profiles found"
 | |
| 		exit 1
 | |
| 	fi
 | |
| 
 | |
| 	for profile in $PROFILE_DIR/*; do
 | |
| 	        if [ "${profile%.rpmnew}" != "${profile}" -o \
 | |
| 		     "${profile%.rpmsave}" != "${profile}" -o \
 | |
| 		     "${profile%\~}" != "${profile}" ]
 | |
| 		then 
 | |
| 			sd_log_warning_msg "Skipping profile $profile"
 | |
| 		elif [ -f "${profile}" ] ; then
 | |
| 			sd_action "  Adding profile: `basename ${profile}`" $PARSER $ABSTRACTIONS $PARSER_ARGS ${profile} 
 | |
| 			if [ $? -ne 0 ]; then
 | |
| 				waserror=1
 | |
| 			fi
 | |
| 		fi
 | |
| 	done
 | |
| }
 | |
| 
 | |
| function profiles_names_list() {	
 | |
| 	# run the parser on all of the apparmor profiles
 | |
| 	TMPFILE=$1
 | |
| 	if [ ! -f "$PARSER" ]; then
 | |
| 		sd_log_failure_msg "AppArmor parser ($PARSER) not found"
 | |
| 		exit 1
 | |
| 	fi
 | |
| 
 | |
| 	if [ ! -d "$PROFILE_DIR" ]; then
 | |
| 		sd_log_failure_msg "Profile directory ($PROFILE_DIR) not found"
 | |
| 		exit 1
 | |
| 	fi
 | |
| 
 | |
| 	for profile in $PROFILE_DIR/*; do
 | |
| 	        if [ "${profile%.rpmnew}" != "${profile}" -o \
 | |
| 		     "${profile%.rpmsave}" != "${profile}" -o \
 | |
| 		     "${profile%\~}" != "${profile}" ]
 | |
| 		then 
 | |
| 			echo "nop" >/dev/null
 | |
| 		elif [ -f "${profile}" ] ; then
 | |
| 			LIST_ADD=$($PARSER $ABSTRACTIONS -N "$profile" | grep -v '\^')
 | |
| 			if [ $? -eq 0 ]; then
 | |
| 				echo "$LIST_ADD" >>$TMPFILE
 | |
| 			fi
 | |
| 		fi
 | |
| 	done
 | |
| }
 | |
| 
 | |
| function is_securityfs_mounted() {
 | |
| 	if grep -q securityfs /proc/filesystems && grep -q securityfs /proc/mounts ; then
 | |
| 		if [ -f "${SECURITYFS}/${MODULE}/profiles" ]; then
 | |
| 			SFS_MOUNTPOINT="${SECURITYFS}/${MODULE}"
 | |
| 			return 0
 | |
| 		fi
 | |
| 	fi
 | |
| 	return 1
 | |
| }
 | |
| 
 | |
| function mount_securityfs() {
 | |
| 	if [ "X" != "X${SECURITYFS}" ]; then
 | |
| 		if ! grep -q securityfs /proc/mounts ; then
 | |
| 			sd_action "Mounting securityfs on ${SECURITYFS}" \
 | |
| 					mount -t securityfs securityfs "${SECURITYFS}"
 | |
| 			rc=$?
 | |
| 			if [ -f "${SECURITYFS}/${MODULE}/profiles" ]; then
 | |
| 				SFS_MOUNTPOINT="${SECURITYFS}/${MODULE}"
 | |
| 			else
 | |
| 				SFS_MOUNTPOINT="${SECURITYFS}/${MODULE}"
 | |
| 			fi
 | |
| 			return $rc
 | |
| 		fi
 | |
| 	fi
 | |
| 	return 0
 | |
| }
 | |
| 
 | |
| function unmount_securityfs() {
 | |
| 	SUBDOMAINFS=$(grep subdomainfs /proc/mounts  | cut -d" " -f2 2> /dev/null)
 | |
| 	if [ "X" != "X${SUBDOMAINFS}" ]; then
 | |
| 		sd_action "Unmounting securityfs" umount ${SUBDOMAINFS}
 | |
| 	fi
 | |
| }
 | |
| 
 | |
| function failstop_system() {
 | |
| 	level=$(runlevel | cut -d" " -f2)
 | |
| 	if [ $level -ne "1" ] ; then
 | |
| 		sd_log_failure_msg "Could not start AppArmor.  Changing to runlevel 1"
 | |
| 		telinit 1;
 | |
| 		return -1;
 | |
| 	fi
 | |
| 	sd_log_failure_msg "Could not start AppArmor."
 | |
| 	return -1
 | |
| }
 | |
| 
 | |
| function module_panic() {
 | |
| 	# the module failed to load, determine what action should be taken
 | |
| 
 | |
| 	case "$APPARMOR_MODULE_PANIC" in
 | |
| 		"warn"|"WARN") sd_log_failure_msg "Could not start AppArmor"
 | |
| 			return -1 ;;
 | |
| 		"panic"|"PANIC") failstop_system
 | |
| 			rc=$?
 | |
| 			return $rc ;;
 | |
| 		*) sd_log_failure_msg "Invalid AppArmor module fail option"
 | |
| 			return -1 ;;
 | |
| 	esac
 | |
| }
 | |
| 
 | |
| function load_module() {
 | |
| 	if modinfo -F filename apparmor > /dev/null 2>&1 ; then
 | |
| 		MODULE=apparmor
 | |
| 	elif modinfo -F filename subdomain > /dev/null 2>&1 ; then
 | |
| 		MODULE=subdomain
 | |
| 	fi
 | |
| 	if ! grep -qE "^(subdomain|apparmor)[[:space:]]" /proc/modules ; then
 | |
| 		sd_action "Loading AppArmor module" /sbin/modprobe $MODULE $1
 | |
| 		rc=$?
 | |
| 		if [ $rc -ne 0 ] ; then
 | |
| 			# we couldn't find the module
 | |
| 			module_panic
 | |
| 			rc=$?
 | |
| 			if [ $rc -ne 0 ] ; then
 | |
| 				exit $rc
 | |
| 			fi
 | |
| 		fi
 | |
| 	fi
 | |
| }	
 | |
| 
 | |
| function start_sd_event() {
 | |
| 	if [ -x "$AA_EV_BIN" -a "${APPARMOR_ENABLE_AAEVENTD}" = "yes" ] ; then
 | |
| 		sd_action "Starting AppArmor Event daemon" startproc -f -p $AA_EV_PIDFILE $AA_EV_BIN -p $AA_EV_PIDFILE
 | |
| 	elif [ -x "$SD_EV_BIN" -a "${APPARMOR_ENABLE_AAEVENTD}" = "yes" ] ; then
 | |
| 		sd_action "Starting AppArmor Event daemon" startproc -f -p $SD_EV_PIDFILE $SD_EV_BIN -p $SD_EV_PIDFILE
 | |
| 	fi
 | |
| }
 | |
| 
 | |
| function stop_sd_event() {
 | |
| 	if [ -x "$AA_EV_BIN" -a -f "$AA_EV_PIDFILE" ] ; then
 | |
| 		sd_action "Shutting down AppArmor Event daemon" killproc -G -p $AA_EV_PIDFILE -INT $AA_EV_BIN
 | |
| 	fi
 | |
| 	if [ -f "$SD_EV_PIDFILE" ] ; then
 | |
| 		sd_action "Shutting down AppArmor Event daemon" killproc -G -p $SD_EV_PIDFILE -INT $SD_EV_BIN
 | |
| 	fi
 | |
| }
 | |
| 
 | |
| function subdomain_start() {
 | |
| 	if ! grep -qE "^(subdomain|apparmor)[[:space:]]" /proc/modules ; then
 | |
| 		load_module
 | |
| 		rc=$?
 | |
| 		if [ $rc -ne 0 ] ; then
 | |
| 			return $rc
 | |
| 		fi
 | |
| 	fi
 | |
| 
 | |
| 	if ! is_securityfs_mounted ; then
 | |
| 		mount_securityfs
 | |
| 		rc=$?
 | |
| 		if [ $rc -ne 0 ] ; then
 | |
| 			return $rc
 | |
| 		fi
 | |
| 	fi
 | |
| 
 | |
| 	if [ ! -w "$SFS_MOUNTPOINT/.load" ] ; then
 | |
| 		sd_log_failure_msg "Loading AppArmor profiles - failed, Do you have the correct privileges?"
 | |
| 		return 1
 | |
| 	fi
 | |
| 
 | |
| 	configure_owlsm
 | |
| 
 | |
| 	if [ $(wc -l "$SFS_MOUNTPOINT/profiles" | awk '{print $1}') -eq 0 ] ; then
 | |
| 		parse_profiles load
 | |
| 	else
 | |
| 		sd_log_warning_msg "Loading AppArmor profiles - AppArmor already loaded with profiles."
 | |
| 	fi
 | |
| }
 | |
| 
 | |
| function remove_profiles() {
 | |
| 	# removing profiles as we directly read from subdomainfs
 | |
| 	# doesn't work, since we are removing entries which screws up
 | |
| 	# our position.  Lets hope there are never enough profiles to
 | |
| 	# overflow the variable
 | |
| 	if ! is_securityfs_mounted ; then
 | |
| 		sd_log_failure_msg "failed: is securityfs loaded?"
 | |
| 		return 1
 | |
| 	fi
 | |
| 
 | |
| 	if [ ! -w "$SFS_MOUNTPOINT/.remove" ] ; then
 | |
| 		sd_log_failure_msg "failed: Do you have the correct privileges?"
 | |
| 		return 1
 | |
| 	fi
 | |
| 
 | |
| 	if [ ! -x "${PARSER}" ] ; then
 | |
| 		sd_log_failure_msg "failed: unable to execute subdomain parser"
 | |
| 		return 1
 | |
| 	fi
 | |
| 
 | |
| 	retval=0
 | |
| 	IFS=$'\n'
 | |
| 	enforced_profiles=$(sed -e "s/ (\(enforce\|complain\))$//" "$SFS_MOUNTPOINT/profiles")
 | |
| 	for profile in $enforced_profiles ; do 
 | |
| 		sd_action "  Removing profile: ${profile}" sh -c "echo \"$profile { }\" | $PARSER -R"
 | |
| 		rc=$?
 | |
| 		if [ ${rc} -ne 0 ] ; then 
 | |
| 			retval=${rc}
 | |
| 		fi
 | |
| 	done
 | |
| 	if [ ${retval} -ne 0 ] ; then
 | |
| 		waserror=1
 | |
| 	fi	
 | |
| }
 | |
| 
 | |
| function subdomain_stop() {
 | |
| 	stop_sd_event
 | |
| 	sd_log_info_msg "Unloading AppArmor profiles"
 | |
| 	remove_profiles
 | |
| }
 | |
| 
 | |
| function subdomain_kill() {
 | |
| 	stop_sd_event
 | |
| 	unmount_securityfs
 | |
| 	if grep -qE "^apparmor[[:space:]]" /proc/modules ; then
 | |
| 		MODULE=apparmor
 | |
| 	elif grep -qE "^subdomain[[:space:]]" /proc/modules ; then
 | |
| 		MODULE=subdomain
 | |
| 	else
 | |
| 		MODULE=apparmor
 | |
| 	fi
 | |
| 	sd_action "Unloading AppArmor modules" /sbin/modprobe -r $MODULE
 | |
| }
 | |
| 
 | |
| function __subdomain_restart() {
 | |
| 	if [ ! -w "$SFS_MOUNTPOINT/.load" ] ; then
 | |
| 		sd_log_failure_msg "Loading AppArmor profiles - failed, Do you have the correct privileges?"
 | |
| 		return 4
 | |
| 	fi
 | |
| 
 | |
| 	configure_owlsm
 | |
| 	parse_profiles reload
 | |
| 	PNAMES_LIST=$(mktemp ${APPARMOR_TMPDIR}/tmp.XXXXXXXX)
 | |
| 	profiles_names_list ${PNAMES_LIST}
 | |
| 	MODULE_PLIST=$(mktemp ${APPARMOR_TMPDIR}/tmp.XXXXXXXX)
 | |
| 	sed  -e "s/ (\(enforce\|complain\))$//" "$SFS_MOUNTPOINT/profiles" | sort >"$MODULE_PLIST"
 | |
| 	#profiles=$(cat $PNAMES_LIST | sort | comm -2 -3 "$MODULE_PLIST" -)
 | |
| 	#for profile in $profiles ; do
 | |
| 	IFS=$'\n' && for profile in $(cat $PNAMES_LIST | sort | comm -2 -3 "$MODULE_PLIST" -) ; do
 | |
| 		echo "\"$profile\" {}" | $PARSER -R >/dev/null
 | |
| 	done
 | |
| 	rm "$MODULE_PLIST"
 | |
| 	rm "$PNAMES_LIST"
 | |
| 	return 0
 | |
| }
 | |
| 
 | |
| function subdomain_restart() {
 | |
| 	if ! grep -qE "^(subdomain|apparmor)[[:space:]]" /proc/modules ; then
 | |
| 		subdomain_start
 | |
| 		rc=$?
 | |
| 		return $rc
 | |
| 	fi
 | |
| 
 | |
| 	if ! is_securityfs_mounted ; then
 | |
| 		mount_securityfs
 | |
| 		rc=$?
 | |
| 		if [ $rc -ne 0 ] ; then
 | |
| 			return $rc
 | |
| 		fi
 | |
| 	fi
 | |
| 
 | |
| 	__subdomain_restart
 | |
| 	rc=$?
 | |
| 	return $rc
 | |
| }
 | |
| 
 | |
| function subdomain_try_restart() {
 | |
| 	if ! grep -qE "^(subdomain|apparmor)[[:space:]]" /proc/modules ; then
 | |
| 		return 1
 | |
| 	fi
 | |
| 
 | |
| 	if ! is_securityfs_mounted ; then
 | |
| 		return 1
 | |
| 	fi
 | |
| 
 | |
| 	__subdomain_restart
 | |
| 	rc=$?
 | |
| 	return $rc
 | |
| }
 | |
| 
 | |
| function subdomain_debug() {
 | |
| 	subdomain_kill
 | |
| 	load_module "subdomain_debug=1"
 | |
| 	mount_securityfs
 | |
| 	configure_owlsm
 | |
| 	parse_profiles load
 | |
| }
 | |
| 
 | |
| function configure_owlsm () {
 | |
| 	if [ "${SUBDOMAIN_ENABLE_OWLSM}" = "yes" -a -f ${SFS_MOUNTPOINT}/control/owlsm ] ; then
 | |
| 		# Sigh, the "sh -c" is necessary for the SuSE sd_action
 | |
| 		# and it can't be abstracted out as a seperate function, as
 | |
| 		# that breaks under RedHat's action, which needs a
 | |
| 		# binary to invoke.
 | |
| 		sd_action "Enabling OWLSM extension" sh -c "echo -n \"1\" > \"${SFS_MOUNTPOINT}/control/owlsm\""
 | |
| 	elif [ -f "${SFS_MOUNTPOINT}/control/owlsm" ] ; then
 | |
| 		sd_action "Disabling OWLSM extension" sh -c "echo -n \"0\" > \"${SFS_MOUNTPOINT}/control/owlsm\""
 | |
| 	fi
 | |
| }
 | |
| 
 | |
| function subdomain_status () {
 | |
| 	if test -x ${AA_STATUS} ; then
 | |
| 		${AA_STATUS} --verbose
 | |
| 		return $?
 | |
| 	fi
 | |
| 	if test -x ${SD_STATUS} ; then
 | |
| 		${SD_STATUS} --verbose
 | |
| 		return $?
 | |
| 	fi
 | |
| 	if ! grep -qE "^(subdomain|apparmor)[[:space:]]" /proc/modules ; then
 | |
| 		sd_log_failure_msg "AppArmor not loaded."
 | |
| 		rc=1
 | |
| 	else
 | |
| 		sd_log_success_msg "AppArmor module enabled."
 | |
| 		rc=0
 | |
| 	fi
 | |
| 	sd_log_warning_msg "Install the apparmor-utils package to receive more detailed"
 | |
| 	sd_log_warning_msg "status information here (or examine ${SFS_MOUNTPOINT} directly)."
 | |
| 
 | |
| 	return $rc
 | |
| }
 |