#!/bin/sh
#
# @(#)$Id: sysreplace.sh,v 1.1.2.5.2.4 1996/10/06 08:55:04 russin Exp $
#
# Copyright 1996 Dynamic Software AB
# This is unpublished proprietary source code.
#
# Description:  Activate/Deactivate BoKS by replacing or
# 		restoring system programs.
#

PCNFSD_PROGRAM=/opt/SUNWpcnfs/sbin/rpc.pcnfsd
XDM_PROGRAM=/usr/openwin/bin/xdm
DTLOGIN_PROGRAM=/usr/dt/bin/dtlogin
XINIT_PROGRAM=/usr/openwin/bin/xinit
BOKS_etc=
eval "`boksdir -E`"
test -z "$BOKS_etc" && exit 1

if [ X"$1" = Xreplace ]; then
    REPLACE=true
elif [ X"$1" = Xrestore ]; then
    REPLACE=false
else
    echo "Usage: sysreplace replace | restore" >&2
    exit 1
fi

SUID_PROGRAMS="/usr/bin/login /sbin/su /usr/bin/su /usr/bin/passwd"
PROGRAMS="$SUID_PROGRAMS"
# INETD_PROGRAMS="/usr/sbin/in.ftpd /usr/sbin/in.rexecd /usr/sbin/in.rshd"
# The code below is not portable if the above is not /usr/sbin/in.rexecd etc.
INETD_CONF=/etc/inetd.conf
INETD_TMP=/tmp/inetd.conf.$$
touch $INETD_TMP

restart_inetd () {
    PID=`/bin/ps -ef | awk ' {if ($9 == "/usr/sbin/inetd") {print $2; exit}}'`
    test -n "$PID" && /bin/kill -1 $PID
}

# For each program where there is is BoKS version installed, move it,
# remove its setuid bit and replace it with a link to the BoKS program.
#
if $REPLACE; then
    # Tell rest of SSM that we are activated
    ENV_TMP=/tmp/boksenv.$$
    rm -f $ENV_TMP
    grep -v SSM_ACTIVE= $BOKS_etc/ENV >$ENV_TMP
    echo "SSM_ACTIVE=true" >>$ENV_TMP
    mv $ENV_TMP $BOKS_etc/ENV

    # Make sure we don't use crippled programs for replacement
    # This should be a no-op
    for p in $SUID_PROGRAMS; do
	if [ -f $p..ssm ]; then
	    chown 0 $p..ssm 2>/dev/null && chmod u+s $p..ssm
	fi
    done

    for p in $PROGRAMS; do
	test -f $p..ssm || continue
	if [ ! -f $p..org -a -f $p ]; then
	    mv $p $p..org
	fi
	rm -f $p
	test -u $p..org && chmod u-s $p..org
	ln -s `basename $p`..ssm $p
    done

    # Special treatment of optional programs which must have their
    # paths defined in the ENV file
    #
    p="$PCNFSD_PROGRAM"
    if [ -n "$p" -a -f "$p" -a -f $BOKS_lib/rpc.pcnfsd ]; then
	if [ ! -f $p..org ]; then
	    mv $p $p..org
	fi
	rm -f $p
	ln -s $BOKS_lib/rpc.pcnfsd $p
    fi

    p="$XDM_PROGRAM"
    if [ -n "$p" -a -f "$p" -a -f $BOKS_lib/X11/xdm ]; then
	if [ ! -f $p..org ]; then
	    mv $p $p..org
	fi
	rm -f $p
	ln -s $BOKS_lib/X11/xdm $p
    fi
    p="$DTLOGIN_PROGRAM"
    if [ -n "$p" -a -f "$p" -a -f $BOKS_lib/dtlogin ]; then
	if [ ! -f $p..org ]; then
	    mv $p $p..org
	fi
	rm -f $p
	ln -s $BOKS_lib/dtlogin $p
    fi

    p="$XINIT_PROGRAM"
    if [ -n "$p" -a -f "$p" -a -f "$BOKS_lib/X11/xinit" ]; then
	if [ ! -f $p..org ]; then
	    mv $p $p..org
	fi
	rm -f $p
	ln -s $BOKS_lib/X11/xinit $p
    fi

    # Now rewrite inetd.conf
    # Store old entrys wiht #old/SSM: prepended (used at uninstall)
    # Only turn onservice if it was on before
    # If SSM entries are there already, just overwrite those.    
    awk 'BEGIN {
		str = "%s\tstream\ttcp\tnowait\troot\t%s/%s\t%s\n";
        }
	/^[ \t]*(ftp|shell|exec)[ \t]/ {
		if ($1 == "ftp") p = "in.ftpd";
		if ($1 == "shell") p = "in.rshd";
		if ($1 == "exec") p = "in.rexecd";
		if ($0 !~ /SUNWssm/) {
			printf "#old/SSM: %s\n", $0;
		}
		done[$1] = 1;
		printf str, $1, blib, p, p;
		next;
	}
	{ print; }
	END {	# Enable this code to turn on service even if off
#		if (done["ftp"] != 1)
#		    printf str, "#ftp", blib, "in.ftpd", "in.ftpd";
#		if (done["shell"] != 1)
#		    printf str, "#shell", blib, "in.rshd", "in.rshd";
#		if (done["exec"] != 1)
#		    printf str, "#exec", blib, "in.rexecd", "in.rexecd";
	}' blib=$BOKS_lib $INETD_CONF > $INETD_TMP
    if [ -s $INETD_TMP ]; then
	# mv is noo good since /etc/inetd.conf normally is a link to
	# /etc/inet/inetd.conf. And we cannot mv to the latter, since
	# they may have removed the link...
	/bin/cp $INETD_CONF $INETD_CONF:ssm-inst
	/bin/cp $INETD_TMP $INETD_CONF
    fi
    rm -f $INETD_TMP
    restart_inetd
    exit 0
fi

# Restore -- undo the above, by removing the link and moving
# the original program back in place again.
#

# Tell rest of SSM that we are de-activated
ENV_TMP=/tmp/boksenv.$$
rm -f $ENV_TMP
grep -v SSM_ACTIVE= $BOKS_etc/ENV >$ENV_TMP
mv $ENV_TMP $BOKS_etc/ENV

for p in $PROGRAMS $XDM_PROGRAM $PCNFSD_PROGRAM $XINIT_PROGRAM $DTLOGIN_PROGRAM; do
    test -f $p..org || continue
    rm -f $p
    mv $p..org $p
done

# Now rewrite inetd.conf
# Replace SSM entries with originals (if present with #old/SSM:) oherwise
# write standard Solaris ones
awk 'BEGIN {
		str = "%s\tstream\ttcp\tnowait\troot\t%s/%s\t%s\n";
		last = "";
	}
	/^#?(ftp|shell|exec)[ \t]/ {
		if ($1 ~ /#?ftp/) p = "in.ftpd";
		if ($1 ~ /#?shell/) p = "in.rshd";
		if ($1 ~ /#?exec/) p = "in.rexecd";
		if ($6 == sprintf("%s/%s", blib, p)) {
		    if ($1 ~ /^#/)
			next;
		    if (last != "")
			print last;
		    else
			printf str, $1, "/usr/sbin", p, p;
		} else {
		    print;
		}
		next;
	}
	/^#old\/SSM: / {
		last = substr($0, 11, 1000);
		next;
	}
	{
		last = "";
		print;
	}' blib=$BOKS_lib $INETD_CONF > $INETD_TMP

if [ -s $INETD_TMP ]; then
    # mv is noo good since /etc/inetd.conf normally is a link to
    # /etc/inet/inetd.conf. And we cannot mv to the latter, since
    # they may have removed the link...
    /bin/cp $INETD_CONF $INETD_CONF:ssm-un
    /bin/cp $INETD_TMP $INETD_CONF
fi
rm -f $INETD_TMP
restart_inetd


# Turn on setuid bits on programs that should have them
#
for p in $SUID_PROGRAMS; do
    test -f $p..ssm || continue
    chmod u+s $p
done
exit 0
