#!/bin/sh
# k5push, by Marc mengel

if [ "$1" = "-d" ]
then
    set -x
    debugflag=x
    shift
else
    debugflag=
fi

if [ $# -lt 1 ]
then
    cat <<EOTEXT 1>&2
usage: $0 [-d] [-c cycletime] [-f file] [[user@]host1] [[user@]host2] ...
to push kerberos tickets from here to sessions on host1 host2 ...
  -d turns on debugging
  -c check for updated ticket every cycletime seconds
  -f specify file containg [user@]host list
EOTEXT
    exit 1
fi

listfile=""
repeatflag=0
while :
do
    case "x$1" in 
    x-f) listfile=$2; shift; shift;;
    x-c) repeatflag=1; delay=$2; shift; shift;;
    *)   break;;
    esac
done

if [ "$repeatflag" = 1 ]
then
    output="`klist -f | head -5`"
fi

firsttime=1

while [ $firsttime = 1 -o $repeatflag = 1 ]
do

    firsttime=0
    if [ $repeatflag = 1 ]
    then
	# wait for ticket cache to be updated   
        newoutput="`klist -f | head -5`"
	while [ "$newoutput" = "$output" ]
	do
	    sleep $delay
            newoutput="`klist -f | head -5`"
	done
        output="$newoutput"
    fi

    if [ "x$listfile" != "x" ]
    then
	set : `cat $listfile`
	shift
    fi

    for host_user in "$@"
    do
	case "$host_user" in
	*@*)cmd="`echo $host_user | sed -e 's/\(.*\)@\(.*\)/host=\2;user=\1/'`"
	    eval "$cmd"
	    uargs="-l $user"
	    ;;
	*)  host=$host_user; 
	    user=$USER
	    uargs=""
	esac
	#
	# the block we rsh is a little convoluted:
	#	Get the list of pid-cache-file candidates
	#	     keep any  mentioning our username
	#	filter:
	#            cut out any symlinks
	#	     trim everything up to /tmp/
	#       filter again:
	#	     skip our current credential file
	#	     any filenames which still have our username 
	#              (beware of Geeks Bearing Gifts)
	#	loop through results each as $file
	#	    check what sort of file
	#	    /tmp/krb5cc_p<pid>* -> valid if pid is a kshd
	#		continue otheriwse
	#	    /tmp/krb5cc_<tty> -> valid if tty exists and USER's
	#		continue otheriwse
	#	    print a message
	#	    copy the current creds to that file
	#	
	(/usr/krb5/bin/rsh $uargs -F $host /bin/sh -${debugflag} 2>&1 | cat) << 'EOF'
	    PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/bsd:/usr/ucb
	    export PATH
	    cd /tmp
	    if ls -ld . | grep -v '^drwxrwxrwt' > /dev/null
	    then
		echo "Skipping `hostname` due to bad modes on /tmp"
		exit
	    fi
	    echo Updating keys for $USER on `hostname`
	    curcred=`echo $KRB5CCNAME | sed -e sxFILE:xx -e sx/tmp/xx`
	    export curcred user
	    find .  -name 'krb5cc_*' \! -name $curcred -user $USER -type f -perm 0600 -print 2>/dev/null | 
	      sed -e 's;^./;;' | 
	    while read file 
	    do 
		case $file in 
		*_p*) pid=`echo $file | sed -e sx.*krb5cc_pxx` 
		      if (ps $pid 2>/dev/null || ps -p $pid 2>/dev/null) | 
			  sed -e "s/^/found: $file => /" |
			  egrep 'kshd|klogind|telnetd|sshd' 
		      then
			    echo updating $file
			    cp ./$curcred ./$file
		      fi
		      ;;
		*)    tty=`echo $file | sed -e sx.*krb5cc_xx` 
		      if ls -Ll /dev/$tty /dev/pts/$tty 2>/dev/null | 
			  sed -e "s/^/found: $file => /" |
			  grep $USER 
		      then
			    echo updating $file
			    cp ./$curcred ./$file
		      fi
		      ;;
		esac
	    done
	    /usr/krb5/bin/kdestroy
EOF

    done
done
