Fix SELinux backup execution context and probe source metadata before downtime

This commit is contained in:
admin committed 2026-09-10 15:11:10 +02:00
1 parent 5c8a7a30be
commit c0a24b63fc
9 files changed
+193 -14

No files matched your search

+25
View File
@@ -118,6 +118,8 @@ init_runtime() {
# Journald already captures service stdout. No dependency on systemd-cat in terminals.
exec > >(tee -a "$LOG_FILE") 2>&1
echo "== $OPERATION $RUN_ID =="
local security_context
if security_context=$(id -Z 2>/dev/null); then echo "-- SELinux process context: $security_context"; fi
need rsync; need tar; need "$COMPRESSOR"
STOPPED_SERVICES=(); NC_CHANGED=false; NC_WAS_ON=false; MUTATION_STARTED=false
trap 'exit 130' INT
@@ -190,8 +192,31 @@ check_db_credentials() {
done
}
check_source_access() (
# This subshell owns only a fresh private probe directory. Keep source data
# untouched and clean probe objects even if an attribute operation fails.
local probe p
probe=$(mktemp -d "$STAGING_ROOT/.access-probe-XXXXXXXX")
trap 'rm -rf -- "$probe"' EXIT
# Test through rsync itself: under SELinux it can enter a different domain
# than this root shell. A shell test -r / realpath alone misses that denial.
# --dirs lists one directory level only, without reading file contents,
# recursing through live mailboxes, or creating a destination.
for p in "${SOURCES[@]}"; do
rsync --list-only --dirs -- "$p/" 8>&- 9>&- >/dev/null || die "rsync cannot list source: $p; check permissions and SELinux audit records before retrying"
mkdir "$probe/root"
# Exclude ALL children: copy only root-directory metadata into the private
# probe. Exercise chmod/chown/times/ACLs/xattrs, including SELinux labels,
# before maintenance. This is not a recursive/full content access test.
rsync -aHAX --numeric-ids --exclude='/*' -- "$p/" "$probe/root/" 8>&- 9>&- || die "rsync cannot preserve directory metadata for: $p; inspect SELinux/filesystem permissions"
rm -rf -- "$probe/root"
done
echo '-- Source directory access and staging metadata probe passed'
)
preflight() {
for p in "${SOURCES[@]}"; do check_source_path "$p"; done
if [[ $OPERATION == backup ]]; then check_source_access; fi
check_db_credentials
if (( ${#DB_LABELS[@]} )); then
need "$DB_DUMP_BIN"; need "$DB_CLIENT_BIN"