#!/bin/sh
# 
# there are a number of reasonable ways to configure a system
# for use with sash.  Try to find the admin's choice as efficiently
# as possible, and optionally remember the result for later.
#
# Originally, answers were tracked in the form:  Q5=Y Q6=N
# [translation: The answer to question 5 is yes, question 6 is no.]
#
# debconf is fairly stable at this point, but is an optional package.
# The challenge is to support legacy (/var/lib/sash/package-config,
# or some alternative, specified on the command line) as well as
# debconf, if available.  The following cases must be considered:
# * new installs, and systems with no saved history
# * legacy systems, with valid /var/lib/sash/package-config
# * systems which don't have debconf installed
#
# Note: "debconf is not intended to be a registry", so I'm not
# getting rid of /var/lib/sash/package-config.


# clean up potential damage from earlier versions of sashconfig
if [ -f /etc/shadow ]; then
	chown root.shadow /etc/shadow
	chmod 640 /etc/shadow
fi

set -e; trap "echo Aborting sashconfig" 0

# parse cmdline for any pre-set answers:
uc(){ tr '[a-z]' '[A-Z]';}

preset(){
	Q=$(echo "$1" | sed 's/[^0-9]//g')
	A=$(echo "$1" | uc | sed 's/[^YN]//g')
	eval Q$Q="$A"
}
for option in $(set | grep '^Q[0-6]=.$'); do
	# don't inherit answers
	preset "$(option | sed 's/=.*//')";
done
Q0=Y
for option in "$@"; do preset "$option"; done

# debconf inspired prompt handler:
# don't ask if we already know the answer
ask(){
	num=$1; eval A=\$Q$num; shift;
	if [ -z "$A" ]; then
		while [ -z "$A" ]; do
			echo -n "$*? [Y/n/?/q] "
			read resp ignore
			case $resp in
				'?'*) help | sensible-pager;;
				Q|q) exit 1;;
				Y*|y*|'') A=Y;;
				N*|n*) A=N;;
				*) echo Invalid response;;
			esac
			echo
		done
	else
		eval echo '$*': \$Q$num
	fi
	eval Q$num=$A
}

help(){
	cat <<___

Answer any question with "?" to get this help.
Answer any question with "q" to cancel and exit
The default answer to any question is Yes, you may also type "Y" or "y"
You may instead type "N" or "n" 

Questions where the answer is obvious, or irrelevant, are skipped.

The questions are:

1 Create sashroot account?

	Advantage: current root account is left untouched
	Disadvantage: you'd have two root accounts to keep track of

2 Clone root password for sashroot?

	Advantage: easy to remember
	Disadvantage: easy to remember

3 Prompt for new sashroot password at config time?

	Advantage: harder to remember
	Disadvantage: harder to remember

4 Make sash to login shell for root?

Only offered if you did not use the sashroot account.  Note that you
can change root's shell at any time with chsh.

5 Delete sashroot account when sash package is removed?

	Advantage: more secure
	Disadvantage: may lose account customization (if any)

6 Remember this configuration?

If not you'll get these questions again the next time the sash package
is configured.  Note that, currently, you can get these questions again
by running sashconfig.  Note that even if you answer yes to this question
the configuration will not be saved if your choices cause any errors.

Final note: Even if you elect not to have sash as a root shell,
you might be able to salvage a system using init=/bin/sash at the
boot prompt.

___
}


clone_root_as_sashroot(){
	if (
		# /etc/shadow might not exist
		if [ -e $1 ]; then
			lockfile-create $1
			if grep -q ^sashroot: $1; then
				: sashroot already exists in $1
			else
				echo cloning root account entry to create sashroot account in $1
				umask 077
				perl -pe '
					if (/^root:/ && !$found_root) {
						$found_root++;
						print;
						s/^/sash/;
					}
					END{
						die "no root account entry\n"
							unless $found_root;
					}
				' $1 >$1-sashroot.tmp
				chown --reference=$1 $1-sashroot.tmp
				chmod --reference=$1 $1-sashroot.tmp
				mv $1-sashroot.tmp $1
			fi
			lockfile-remove $1
		fi
	) ; then
		echo Cloned sashroot from root in $1
	else 
		# we died, attempt to clean up
		lockfile-remove $1
		exit 1
	fi
}

# for sash.postinst
ask 0 Configure sash
if [ "$Q0" = N ]; then
	exit 0
fi

create=Create
if grep -q ^sashroot: /etc/passwd; then
	create='Use existing'
fi
ask 1 $create sashroot account
if [ "$Q1" = Y ]; then
	if [ "$create" = Create -a "$Q3" != Y ]; then
		ask 2 "Clone root password for sashroot"
	fi
	if [ "$Q2" != Y ]; then
		ask 3 Prompt for new sashroot password at config time
	fi
else
	ask 4 Make sash the login shell for root
fi
if [ "$create" != Create -o "$Q1" = Y ]; then
	ask 5 Delete sashroot account when sash package is removed
	if [ "$Q5" = Y ]; then
		Q6=Y
	fi
fi
ask 6 Remember this configuration?
if [ "$Q6" = Y ]; then
	echo root may change this configuration with sashconfig
	echo or, cancel it with rm /var/lib/sash/package-config
	echo
fi


if [ "$Q1" = Y ]; then
	if [ "$create" = Create ]; then
		if [ "$Q2" = Y ]; then
			clone_root_as_sashroot /etc/passwd
			clone_root_as_sashroot /etc/shadow
		else
			(
				set -x
				useradd -c 'emergency root shell' -d /root -g root -m -s /bin/sash -u 0 -o sashroot
			)
		fi
	fi
	if [ "$Q3" = Y ]; then
		passwd sashroot
	fi
	(
		set -x
		chsh -s /bin/sash sashroot
	)
else
	if [ "$Q4" = Y ]; then
		(
			set -x
			chsh -s /bin/sash root
		)
	fi
fi
if [ "$Q6" = Y ]; then
	(
		set | grep ^Q[0-6]=
		help
	) >/var/lib/sash/package-config
fi

trap true 0
