#!/bin/ksh
#
# $OpenIMAPD$
#
# rc.d(8) service script for imapd(8).

daemon="/usr/local/sbin/imapd"

. /etc/rc.d/rc.subr

rc_bg=YES

_relink_tar="/usr/share/relink/usr/local/sbin/imapd/imapd.tar"

rc_pre() {
	local _tmp

	[[ -f ${_relink_tar} ]] || return 0

	# mktemp -d is safe on its own: it creates the directory atomically,
	# 0700 and root-owned, under a name nobody can predict. Everything this
	# function writes goes INSIDE it for that reason.
	#
	# This used to redirect to a fixed /tmp/imapd-relink.log, which was a
	# symlink target: rc_pre() runs as root, and on every "rcctl start" or
	# "rcctl restart" -- not only at boot -- so any local user could plant
	# that name as a link to /etc/master.passwd or anything else and have
	# ">" truncate it. The sticky bit on /tmp does not prevent creating a
	# name that does not exist yet, and an unlink first would only narrow
	# the window (OpenBSD ports guide, "Security Recommendations").
	_tmp=$(mktemp -d /tmp/imapd-relink.XXXXXXXXXX) || {
		logger -t imapd -p daemon.err \
		    "relink: mktemp failed, skipping (${_relink_tar} left in place)"
		return 0
	}

	if ( cd "${_tmp}" && tar xf "${_relink_tar}" && sh install.sh ) \
	    >"${_tmp}/relink.log" 2>&1; then
		rm -f "${_relink_tar}"
		rm -rf "${_tmp}"
		logger -t imapd -p daemon.info \
		    "relink applied successfully"
	else
		# Deliberately NOT cleaned up: the log is the only diagnostic,
		# and ${_tmp} is the one place it can be left that an attacker
		# can neither read nor pre-create. One directory per failed
		# relink, alongside the ${_relink_tar} that is also kept.
		logger -t imapd -p daemon.err \
		    "relink failed -- starting previously installed binary;" \
		    "output in ${_tmp}/relink.log, ${_relink_tar} left in place"
	fi
	return 0
}

rc_cmd $1
