#!/bin/sh
# Refresh from this RPM's source, never a previous install's generated module.
# SC-581: an unowned cached .pp otherwise preserves obsolete entrypoint labels.
set -eu

[ -e /sys/fs/selinux/enforce ] || exit 0

src=/usr/share/selinux/packages
makefile=/usr/share/selinux/devel/Makefile
# shcp_mailpolicy (the SC-236 Go policy runner's domain, shcp-master#2189) requires
# shcpd's types, so both load in ONE semodule transaction: neither can be left
# half-refreshed against the other.
modules="shcpd shcp_mailpolicy"
for mod in $modules; do
    for file in "$src/$mod.te" "$src/$mod.fc"; do
        if [ ! -f "$file" ]; then
            echo "shcp-selinux-refresh: required policy source missing: $file" >&2
            exit 1
        fi
    done
done
if [ ! -f "$makefile" ]; then
    echo "shcp-selinux-refresh: required policy source missing: $makefile" >&2
    exit 1
fi

work=$(mktemp -d /var/tmp/shcpd-selinux.XXXXXX)
trap 'rm -rf -- "$work"' EXIT
trap 'exit 1' HUP INT TERM
pps=
for mod in $modules; do
    cp "$src/$mod.te" "$src/$mod.fc" "$work/"
    pps="$pps $work/$mod.pp"
done
(
    cd "$work"
    for mod in $modules; do
        make -f "$makefile" "$mod.pp"
    done
)
# A compilation/load failure must never fall back to the old cached module.
# shellcheck disable=SC2086
semodule -i $pps
for mod in $modules; do
    install -m 0644 "$work/$mod.pp" "$src/$mod.pp"
done

# The SC-236 outbound policy socket (shcp-installer#932) is listening before any
# later shcpd upgrade runs this, and systemd labels it only when it binds. Without
# the relabel a socket created under an older module keeps shcpd_runtime_t, which
# postfix_smtpd_t may not write: every authenticated EL send defers 451 until the
# socket is restarted. The transfer scratch can likewise predate the SC-461
# fcontext; relabel its bounded subtree so existing exports become readable to
# shcpd_t on upgrade (#1717). The Go policy runner, published by the installer
# before a shcpd that ships its domain, is bin_t until relabeled, and bin_t is no
# entrypoint to shcp_mailpolicy_t. Absent paths (an EL box before the installer
# step, or a stopped socket) are skipped like the rest; deb never ships this helper.
for path in /usr/sbin/shcpd /usr/sbin/shcp-mail-policy /etc/shcp /var/lib/shcp /var/log/shcpd /run/shcp/outbound-policy.sock /var/backups/shcp-backup-scratch/transfers; do
    [ -e "$path" ] || continue
    restorecon -R "$path"
done
