|
|
- #!/bin/sh
-
- log_write() {
- local facility=kern.$1
- logger -t AppArmor -p $facility "$2"
- }
-
- AA_STATUS=/usr/sbin/aa-status
- SECURITYFS=/sys/kernel/security
- SFS_MOUNTPOINT="${SECURITYFS}/apparmor"
- PARSER=/sbin/apparmor_parser
- PARSER_OPTS=
- ADDITIONAL_PROFILE_DIR=
-
- [ -d /etc/apparmor.d ] && PROFILE_DIRS=/etc/apparmor.d ||
- log_write warning "Unable to find profiles: /etc/apparmor.d"
-
- [ -n "$ADDITIONAL_PROFILE_DIR" ] && [ -d "$ADDITIONAL_PROFILE_DIR" ] &&
- PROFILE_DIRS="$PROFILE_DIRS $ADDITIONAL_PROFILE_DIR"
-
- dir_is_empty() {
- [ "$(du -s $1 | cut -f 1)" -eq 0 ] && return 0 || return 1
- }
-
- profiles_loaded_count() {
-
- [ -f ${SFS_MOUNTPOINT}/profiles ] &&
- return $(cat "${SFS_MOUNTPOINT}/profiles" | wc -l) || return 0
- }
-
- is_profiles_loaded() {
-
- [ -f ${SFS_MOUNTPOINT}/profiles ] && {
- rc=$(cat "${SFS_MOUNTPOINT}/profiles" | wc -l)
- [ "$rc" -ne 0 ] && return 0 || return 1
- }
- return 1
- }
-
- is_container_with_internal_policy() {
-
- local ns_stacked_path="${SFS_MOUNTPOINT}/.ns_stacked"
- local ns_name_path="${SFS_MOUNTPOINT}/.ns_name"
- local ns_stacked
- local ns_name
-
- if ! [ -f "$ns_stacked_path" ] || ! [ -f "$ns_name_path" ]; then
- return 1
- fi
-
- read -r ns_stacked < "$ns_stacked_path"
- if [ "$ns_stacked" != "yes" ]; then
- return 1
- fi
-
- # LXD and LXC set up AppArmor namespaces starting with "lxd-" and
- # "lxc-", respectively. Return non-zero for all other namespace
- # identifiers.
-
- read -r ns_name < "$ns_name_path"
- if [ "${ns_name#lxd-*}" = "$ns_name" ] && \
- [ "${ns_name#lxc-*}" = "$ns_name" ]; then
- return 1
- fi
-
- return 0
- }
-
- skip_profile() {
-
- local profile="$1"
-
- if [ "${profile%.rpmnew}" != "$profile" ] || \
- [ "${profile%.rpmsave}" != "$profile" ] || \
- [ "${profile%.orig}" != "$profile" ] || \
- [ "${profile%.rej}" != "$profile" ] || \
- [ "${profile%\~}" != "$profile" ] ; then
- return 1
- fi
-
- # Silently ignore the dpkg, pacman, ipk and xbps files
-
- if [ "${profile%.dpkg-new}" != "$profile" ] || \
- [ "${profile%.dpkg-old}" != "$profile" ] || \
- [ "${profile%.dpkg-dist}" != "$profile" ] || \
- [ "${profile%.dpkg-bak}" != "$profile" ] || \
- [ "${profile%.dpkg-remove}" != "$profile" ] || \
- [ "${profile%.ipk}" != "$profile" ] || \
- [ "${profile%.ipk-new}" != "$profile" ] || \
- [ "${profile%.ipk-old}" != "$profile" ] || \
- [ "${profile%.ipk-dist}" != "$profile" ] || \
- [ "${profile%.ipk-bak}" != "$profile" ] || \
- [ "${profile%.ipk-remove}" != "$profile" ] || \
- [ "${profile%.pacsave}" != "$profile" ] || \
- [ "${profile%.pacnew}" != "$profile" ] ; then
- return 2
- fi
-
- $(echo "$profile" | grep -E -q '^.+\.new-[0-9\.]+_[0-9]+$'); [ "$?" -eq 0 ] && return 2
-
- return 0
- }
-
- __parse_profiles_dir() {
-
- local parser_cmd="$1"
- local profile_dir="$2"
- local status=0
-
- [ -x "$PARSER" ] || {
- log_write err "Unable to execute AppArmor parser"
- return 1
- }
-
- [ -d "$profile_dir" ] || {
- log_write warning "AppArmor profiles not found: $profile_dir"
- return 1
- }
-
- dir_is_empty "$profile_dir"; [ "$?" -eq 0 ] && {
- log_write err "No profiles found in $profile_dir"
- return 1
- }
-
- local nprocs=$(cat /proc/cpuinfo |grep "processor\t:"|wc -l)
- local rc=0
- local xargs_args=""
- [ "$nprocs" -ge 2 ] && xargs_args="--max-procs=$nprocs"
-
- "$PARSER" $PARSER_OPTS "$parser_cmd" -- "$profile_dir" || {
-
- for profile in "$profile_dir"/*; do
- skip_profile "$profile"
- skip=$?
- [ "$skip" -ne 0 ] && {
- [ "$skip" -ne 2 ] && log_write info "Skipped loading profile $profile"
- continue
- }
- [ -f "$profile" ] || continue
- echo "$profile"
- done | \
-
- # Use xargs to parallelize calls to the parser over all CPUs
-
- /usr/libexec/xargs-findutils -n1 -d"\n" $xargs_args \
- "$PARSER" $PARSER_OPTS "$parser_cmd" --
-
- [ "$?" -ne 0 ] && {
- rc=1
- log_write err "At least one profile failed to load"
- }
- }
-
- return $rc
- }
-
- parse_profiles() {
-
- case "$1" in
- load)
- PARSER_CMD="--add"
- PARSER_MSG="Loading profiles"
- ;;
- reload)
- PARSER_CMD="--replace"
- PARSER_MSG="Reloading profiles"
- ;;
- *)
- log_write err "Unknown parameter $1"
- log_write info "parse_profiles parameter must be either 'load' or 'reload'"
- return 1
- ;;
- esac
-
- log_write info "$PARSER_MSG"
-
- [ -w "$SFS_MOUNTPOINT/.load" ] || {
- log_write err "${SFS_MOUNTPOINT}/.load not writable"
- return 1
- }
-
- [ -f "$PARSER" ] || {
- log_write err "AppArmor parser not found"
- return 1
- }
-
- # run parser on all profiles
- local rc=0
- for profile_dir in $PROFILE_DIRS; do
- __parse_profiles_dir "$PARSER_CMD" "$profile_dir" || rc=$?
- done
-
- return $rc
- }
-
- is_apparmor_loaded() {
-
- is_securityfs_mounted; [ "$?" -eq 0 ] || {
- mount_securityfs
- }
-
- [ -f "${SFS_MOUNTPOINT}/profiles" ] && return 0
- [ -d /sys/module/apparmor ] && return 0 || return 1
- }
-
- is_securityfs_mounted() {
-
- [ -d "$SECURITYFS" ] && {
- grep -q securityfs /proc/filesystems && grep -q securityfs /proc/mounts
- return $?
- }
- return 1
- }
-
- mount_securityfs() {
-
- local rc=0
-
- grep -q securityfs /proc/filesystems; [ "$?" -eq 0 ] && {
- mount -t securityfs securityfs "$SECURITYFS"
- rc=$?
- [ "$rc" -eq 0 ] && log_write info "Mounting securityfs" ||
- log_write err "Failed to mount securityfs"
- }
- return $rc
- }
-
- apparmor_start() {
-
- local announced=0
- is_securityfs_mounted; [ "$?" -ne 0 ] && {
- log_write info "Starting AppArmor"
- announced=1
- mount_securityfs; [ "$?" -eq 0 ] || return $?
- }
-
- is_apparmor_loaded; [ "$?" -eq 0 ] || {
- [ "$announced" -eq 0 ] && log_write info "Starting AppArmor"
- announced=1
- log_write err "AppArmor kernel support is not present"
- return 1
- }
-
- [ -d /var/lib/apparmor ] || mkdir -p /var/lib/apparmor > /dev/null
-
- is_profiles_loaded; [ "$?" -eq 0 ] || {
- [ "$announced" -eq 0 ] && log_write info "Starting AppArmor"
- announced=1
- parse_profiles load
- return $?
- } || {
- parse_profiles reload
- return $?
- }
- }
-
- remove_profiles() {
-
- log_write info "Unloading profiles"
-
- is_apparmor_loaded; [ "$?" -eq 0 ] || {
- log_write err "AppArmor kernel support is not present"
- return 1
- }
-
- [ -w "$SFS_MOUNTPOINT/.remove" ] || {
- log_write err "${SFS_MOUNTPOINT}/.remove not writable"
- return 1
- }
-
- [ -x "$PARSER" ] || {
- log_write err "Unable to execute AppArmor parser"
- return 1
- }
-
- local rc=0
-
- sed -e "s/ (\(enforce\|complain\))$//" "$SFS_MOUNTPOINT/profiles" | \
- LC_COLLATE=C sort | grep -v // | {
- while read -r profile ; do
- printf "%s" "$profile" > "$SFS_MOUNTPOINT/.remove"
- result=$?
- [ "$result" -eq 0 ] || rc=$result
- done
- }
- return $rc
- }
-
- apparmor_stop() {
-
- is_apparmor_loaded; [ "$?" -eq 0 ] || return 1
- is_profiles_loaded; [ "$?" -eq 0 ] && {
- log_write info "Stopping AppArmor"
- remove_profiles
- return $?
- } || return 0
- }
-
- apparmor_restart() {
-
- is_profiles_loaded; [ "$?" -eq 0 ] || {
- apparmor_start
- return $?
- }
-
- is_apparmor_loaded; [ "$?" -eq 0 ] || {
- apparmor_start
- return $?
- }
-
- log_write info "Restarting AppArmor"
- parse_profiles reload
- return $?
- }
-
- apparmor_reload() {
-
- is_profiles_loaded; [ "$?" -eq 0 ] || {
- apparmor_start
- return $?
- }
-
- is_apparmor_loaded; [ "$?" -eq 0 ] || {
- apparmor_start
- return $?
- }
-
- log_write info "Reloading AppArmor"
- parse_profiles reload
- return $?
- }
-
- apparmor_list_profiles() {
-
- is_apparmor_loaded; [ "$?" -eq 0 ] || {
- echo "AppArmor kernel support is not present"
- return 1
- }
-
- [ -x "$PARSER" ] || {
- echo "Unable to execute AppArmor parser"
- return 1
- }
-
- # run parser on all profiles
- for profile_dir in $PROFILE_DIRS; do
- [ -d "$profile_dir" ] || {
- echo "AppArmor profiles not found: $profile_dir"
- continue
- }
-
- for profile in "$profile_dir"/*; do
- if skip_profile "$profile" && [ -f "$profile" ] ; then
- LIST_ADD=$("$PARSER" -N "$profile" )
- [ "$?" -eq 0 ] && echo "$LIST_ADD"
- fi
- done
- done
- return 0
- }
-
-
- apparmor_status() {
-
- is_apparmor_loaded; [ "$?" -eq 0 ] || {
- echo "AppArmor kernel support is not present"
- return 1
- }
-
- [ -x "$AA_STATUS" ] && {
- "$AA_STATUS" --verbose
- return $?
- }
-
- echo "AppArmor is enabled."
- echo "Install apparmor-utils to receive more detailed status"
- echo "information or examine $SFS_MOUNTPOINT directly."
-
- return 0
- }
|