yunohost/data/helpers.d/filesystem
Maniack Crudelis 47ce6d9e33 New helper ynh_secure_remove (#281)
* New helper ynh_secure_remove
A secure way to remove a file or directory.
Prevent to knew issues.
Tested with this paths:
- / -> Not removed
- /var -> Not removed
- /var/www -> Not removed
- /var/www/file -> Removed
- /opt -> Not removed
- /opt/file -> Removed
- /home/yunohost.app -> Not removed
- /home -> Not removed
- /home/ -> Not removed
- // -> Not removed
- /etc/cron.d/ -> Not removed
- /etc -> Not removed
- /etc/ -> Not removed
- /etc/X11 -> Removed
- /etc/X11/$var -> Removed (if $var is not empty)

* JimboJoe's typo fix
2017-04-30 22:37:52 +02:00

110 lines
3.4 KiB
Text

CAN_BIND=${CAN_BIND:-1}
# Mark a file or a directory for backup
# Note: currently, SRCPATH will be copied or binded to DESTPATH
#
# usage: ynh_backup srcdir destdir to_bind no_root
# | arg: srcdir - directory to bind or copy
# | arg: destdir - mountpoint or destination directory
# | arg: to_bind - 1 to bind mounting the directory if possible
# | arg: no_root - 1 to execute commands as current user
ynh_backup() {
local SRCPATH=$1
local DESTPATH=$2
local TO_BIND=${3:-0}
local SUDO_CMD="sudo"
[[ "${4:-}" = "1" ]] && SUDO_CMD=
# validate arguments
[[ -e "${SRCPATH}" ]] || {
echo "Source path '${SRCPATH}' does not exist" >&2
return 1
}
# prepend the backup directory
[[ -n "${YNH_APP_BACKUP_DIR:-}" && "${DESTPATH:0:1}" != "/" ]] \
&& DESTPATH="${YNH_APP_BACKUP_DIR}/${DESTPATH}"
[[ ! -e "${DESTPATH}" ]] || {
echo "Destination path '${DESTPATH}' already exist" >&2
return 1
}
# attempt to bind mounting the directory
if [[ "${CAN_BIND}" = "1" && "${TO_BIND}" = "1" ]]; then
eval $SUDO_CMD mkdir -p "${DESTPATH}"
if sudo mount --rbind "${SRCPATH}" "${DESTPATH}"; then
# try to remount destination directory as read-only
sudo mount -o remount,ro,bind "${SRCPATH}" "${DESTPATH}" \
|| true
return 0
else
CAN_BIND=0
echo "Bind mounting seems to be disabled on your system."
echo "You have maybe to check your apparmor configuration."
fi
# delete mountpoint directory safely
mountpoint -q "${DESTPATH}" && sudo umount -R "${DESTPATH}"
eval $SUDO_CMD rm -rf "${DESTPATH}"
fi
# ... or just copy the directory
eval $SUDO_CMD mkdir -p $(dirname "${DESTPATH}")
eval $SUDO_CMD cp -a "${SRCPATH}" "${DESTPATH}"
}
# Deprecated helper since it's a dangerous one!
ynh_bind_or_cp() {
local AS_ROOT=${3:-0}
local NO_ROOT=0
[[ "${AS_ROOT}" = "1" ]] || NO_ROOT=1
echo "This helper is deprecated, you should use ynh_backup instead" >&2
ynh_backup "$1" "$2" 1 "$NO_ROOT"
}
# Create a directory under /tmp
#
# Deprecated helper
#
# usage: ynh_mkdir_tmp
# | ret: the created directory path
ynh_mkdir_tmp() {
echo "The helper ynh_mkdir_tmp is deprecated." >&2
echo "You should use 'mktemp -d' instead and manage permissions \
properly with chmod/chown." >&2
local TMP_DIR=$(mktemp -d)
# Give rights to other users could be a security risk.
# But for retrocompatibility we need it. (This helpers is deprecated)
chmod 755 $TMP_DIR
echo $TMP_DIR
}
# Remove a file or a directory securely
#
# usage: ynh_secure_remove path_to_remove
# | arg: path_to_remove - File or directory to remove
ynh_secure_remove () {
path_to_remove=$1
forbidden_path=" \
/var/www \
/home/yunohost.app"
if [[ "$forbidden_path" =~ "$path_to_remove" \
# Match all paths or subpaths in $forbidden_path
|| "$path_to_remove" =~ ^/[[:alnum:]]+$ \
# Match all first level paths from / (Like /var, /root, etc...)
|| "${path_to_remove:${#path_to_remove}-1}" = "/" ]]
# Match if the path finishes by /. Because it seems there is an empty variable
then
echo "Avoid deleting $path_to_remove." >&2
else
if [ -e "$path_to_remove" ]
then
sudo rm -R "$path_to_remove"
else
echo "$path_to_remove wasn't deleted because it doesn't exist." >&2
fi
fi
}