1#!/bin/sh 2# 3# Copyright (c) 2018-2021, Christer Edwards <christer.edwards@gmail.com> 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions are met: 8# 9# * Redistributions of source code must retain the above copyright notice, this 10# list of conditions and the following disclaimer. 11# 12# * Redistributions in binary form must reproduce the above copyright notice, 13# this list of conditions and the following disclaimer in the documentation 14# and/or other materials provided with the distribution. 15# 16# * Neither the name of the copyright holder nor the names of its 17# contributors may be used to endorse or promote products derived from 18# this software without specific prior written permission. 19# 20# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31. /usr/local/share/bastille/common.sh 32. /usr/local/etc/bastille/bastille.conf 33 34usage() { 35 error_exit "Usage: bastille destroy [force] | [container|release]" 36} 37 38destroy_jail() { 39 local OPTIONS 40 bastille_jail_base="${bastille_jailsdir}/${TARGET}" ## dir 41 bastille_jail_log="${bastille_logsdir}/${TARGET}_console.log" ## file 42 43 if [ "$(/usr/sbin/jls name | awk "/^${TARGET}$/")" ]; then 44 if [ "${FORCE}" = "1" ]; then 45 bastille stop "${TARGET}" 46 else 47 error_notify "Jail running." 48 error_exit "See 'bastille stop ${TARGET}'." 49 fi 50 fi 51 52 if [ ! -d "${bastille_jail_base}" ]; then 53 error_exit "Jail not found." 54 fi 55 56 if [ -d "${bastille_jail_base}" ]; then 57 info "Deleting Jail: ${TARGET}." 58 if [ "${bastille_zfs_enable}" = "YES" ]; then 59 if [ -n "${bastille_zfs_zpool}" ]; then 60 if [ -n "${TARGET}" ]; then 61 OPTIONS="-r" 62 if [ "${FORCE}" = "1" ]; then 63 OPTIONS="-rf" 64 fi 65 ## remove jail zfs dataset recursively 66 zfs destroy "${OPTIONS}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}" 67 fi 68 fi 69 fi 70 71 if [ -d "${bastille_jail_base}" ]; then 72 ## removing all flags 73 chflags -R noschg "${bastille_jail_base}" 74 75 ## remove jail base 76 rm -rf "${bastille_jail_base}" 77 fi 78 79 # Remove target from bastille_list if exist 80 # Mute sysrc output here as it may be undesirable on large startup list 81 if [ -n "$(sysrc -qn bastille_list | tr -s " " "\n" | awk "/^${TARGET}$/")" ]; then 82 sysrc bastille_list-="${TARGET}" > /dev/null 83 fi 84 85 ## archive jail log 86 if [ -f "${bastille_jail_log}" ]; then 87 mv "${bastille_jail_log}" "${bastille_jail_log}"-"$(date +%F)" 88 info "Note: jail console logs archived." 89 info "${bastille_jail_log}-$(date +%F)" 90 fi 91 92 ## clear any active rdr rules 93 if [ ! -z "$(pfctl -a "rdr/${TARGET}" -Psn 2>/dev/null)" ]; then 94 info "Clearing RDR rules:" 95 pfctl -a "rdr/${TARGET}" -Fn 96 fi 97 echo 98 fi 99} 100 101destroy_rel() { 102 local OPTIONS 103 104 ## check release name match before destroy 105 if [ -n "${NAME_VERIFY}" ]; then 106 TARGET="${NAME_VERIFY}" 107 else 108 usage 109 fi 110 111 bastille_rel_base="${bastille_releasesdir}/${TARGET}" ## dir 112 113 ## check if this release have containers child 114 BASE_HASCHILD="0" 115 if [ -d "${bastille_jailsdir}" ]; then 116 JAIL_LIST=$(ls "${bastille_jailsdir}" | sed "s/\n//g") 117 for _jail in ${JAIL_LIST}; do 118 if grep -qwo "${TARGET}" "${bastille_jailsdir}/${_jail}/fstab" 2>/dev/null; then 119 error_notify "Notice: (${_jail}) depends on ${TARGET} base." 120 BASE_HASCHILD="1" 121 fi 122 done 123 fi 124 125 if [ ! -d "${bastille_rel_base}" ]; then 126 error_exit "Release base not found." 127 else 128 if [ "${BASE_HASCHILD}" -eq "0" ]; then 129 info "Deleting base: ${TARGET}" 130 if [ "${bastille_zfs_enable}" = "YES" ]; then 131 if [ -n "${bastille_zfs_zpool}" ]; then 132 if [ -n "${TARGET}" ]; then 133 OPTIONS="-r" 134 if [ "${FORCE}" = "1" ]; then 135 OPTIONS="-rf" 136 fi 137 zfs destroy "${OPTIONS}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${TARGET}" 138 if [ "${FORCE}" = "1" ]; then 139 if [ -d "${bastille_cachedir}/${TARGET}" ]; then 140 zfs destroy "${OPTIONS}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/cache/${TARGET}" 141 fi 142 fi 143 fi 144 fi 145 fi 146 147 if [ -d "${bastille_rel_base}" ]; then 148 ## removing all flags 149 chflags -R noschg "${bastille_rel_base}" 150 151 ## remove jail base 152 rm -rf "${bastille_rel_base}" 153 fi 154 155 if [ "${FORCE}" = "1" ]; then 156 ## remove cache on force 157 if [ -d "${bastille_cachedir}/${TARGET}" ]; then 158 rm -rf "${bastille_cachedir}/${TARGET}" 159 fi 160 fi 161 echo 162 else 163 error_notify "Cannot destroy base with child containers." 164 fi 165 fi 166} 167 168# Handle special-case commands first. 169case "$1" in 170help|-h|--help) 171 usage 172 ;; 173esac 174 175## reset this options 176FORCE="" 177 178## handle additional options 179case "${1}" in 180 -f|--force|force) 181 FORCE="1" 182 shift 183 ;; 184 -*) 185 error_notify "Unknown Option." 186 usage 187 ;; 188esac 189 190TARGET="${1}" 191 192if [ $# -gt 1 ] || [ $# -lt 1 ]; then 193 usage 194fi 195 196## check what should we clean 197case "${TARGET}" in 198*-CURRENT|*-CURRENT-I386|*-CURRENT-i386|*-current) 199 ## check for FreeBSD releases name 200 NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '^([1-9]{2,2})\.[0-9](-CURRENT|-CURRENT-i386)$' | tr '[:lower:]' '[:upper:]' | sed 's/I/i/g') 201 destroy_rel 202 ;; 203*-RELEASE|*-RELEASE-I386|*-RELEASE-i386|*-release|*-RC1|*-rc1|*-RC2|*-rc2|*-RC3|*-rc3|*-RC4|*-rc4|*-RC5|*-rc5|*-BETA1|*-BETA2|*-BETA3|*-BETA4|*-BETA5) 204 ## check for FreeBSD releases name 205 NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '^([1-9]{2,2})\.[0-9](-RELEASE|-RELEASE-i386|-RC[1-5]|-BETA[1-5])$' | tr '[:lower:]' '[:upper:]' | sed 's/I/i/g') 206 destroy_rel 207 ;; 208*-stable-LAST|*-STABLE-last|*-stable-last|*-STABLE-LAST) 209 ## check for HardenedBSD releases name 210 NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '^([1-9]{2,2})(-stable-last)$' | sed 's/STABLE/stable/g;s/last/LAST/g') 211 destroy_rel 212 ;; 213*-stable-build-[0-9]*|*-STABLE-BUILD-[0-9]*) 214 ## check for HardenedBSD(specific stable build releases) 215 NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '([0-9]{1,2})(-stable-build)-([0-9]{1,3})$' | sed 's/BUILD/build/g;s/STABLE/stable/g') 216 destroy_rel 217 ;; 218*-stable-build-latest|*-stable-BUILD-LATEST|*-STABLE-BUILD-LATEST) 219 ## check for HardenedBSD(latest stable build release) 220 NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '([0-9]{1,2})(-stable-build-latest)$' | sed 's/STABLE/stable/;s/build/BUILD/g;s/latest/LATEST/g') 221 destroy_rel 222 ;; 223current-build-[0-9]*|CURRENT-BUILD-[0-9]*) 224 ## check for HardenedBSD(specific current build releases) 225 NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '(current-build)-([0-9]{1,3})' | sed 's/BUILD/build/g;s/CURRENT/current/g') 226 destroy_rel 227 ;; 228current-build-latest|current-BUILD-LATEST|CURRENT-BUILD-LATEST) 229 ## check for HardenedBSD(latest current build release) 230 NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '(current-build-latest)$' | sed 's/CURRENT/current/;s/build/BUILD/g;s/latest/LATEST/g') 231 destroy_rel 232 ;; 233Ubuntu_1804|Ubuntu_2004|UBUNTU_1804|UBUNTU_2004) 234 ## check for Linux releases 235 NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '(Ubuntu_1804)$|(Ubuntu_2004)$' | sed 's/UBUNTU/Ubuntu/g;s/ubuntu/Ubuntu/g') 236 destroy_rel 237 ;; 238Debian9|Debian10|Debian11|DEBIAN9|DEBIAN10|DEBIAN11) 239 ## check for Linux releases 240 NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '(Debian9)$|(Debian10)$|(Debian11)$' | sed 's/DEBIAN/Debian/g') 241 destroy_rel 242 ;; 243*) 244 ## just destroy a jail 245 destroy_jail 246 ;; 247esac 248