#!/bin/ksh
#
# ident "uttscadm.ksh $Date: 2008-07-15 11:31:40 -0700 (Tue, 15 Jul 2008) $ $Revision: 256 $ SMI"
#
# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
# Use is subject to license terms.
#

# Admin CLI used for configuring the Sun Ray Connector

#
# Solaris 10 Trusted Extension guard
#
ORIGIN=`/usr/bin/dirname $0`
TXGUARD=${ORIGIN:-/opt/SUNWuttsc/lib}/../lib/txguard
. $TXGUARD
#
# Solaris 10 Trusted Extension guard 
#


PATH="/usr/sbin:/usr/bin:/sbin:/bin"
PROGRAM_ID=$(basename $0)

PW_PID=
TMP_DIR_PATH="/var/run"
TMP_PROGID=${TMP_DIR_PATH}/$PROGRAM_ID.$$
TMP_PWPIPE="${TMP_PROGID}.pipe"

trap "rm -f $TMP_PWPIPE; stty echo </dev/tty; CleanupPipeProcs; exit 1"\
 HUP INT QUIT TERM

SUNWUTETC=/etc/opt/SUNWut
UTADMIN_CONF=$SUNWUTETC/utadmin.conf
UTADMIN_PW=$SUNWUTETC/utadmin.pw
THIS_HOST=$(uname -n)
SRDS_LDAP_DEFAULT="${SUNWUTETC}/srds/default"
SRDS_LDAP_CURRENT="${SUNWUTETC}/srds/current"
UTDSD_CMD=/etc/init.d/utds
SRSS_PKG_LOC="`$SUNWUTETC/basedir/lib/utprodinfo -r SUNWuto`/SUNWut"
SRSS_DYNAMIC_ADMIN=$SRSS_PKG_LOC/lib/libutadmin.so.1
SUNWUTLIB=$SRSS_PKG_LOC/lib
SUNWUTSBIN=$SRSS_PKG_LOC/sbin

SUNWUTTSC_LOC="`$SUNWUTETC/basedir/lib/utprodinfo -r SUNWuttsc`/SUNWuttsc"
SUNWUTTSCLIB=$SUNWUTTSC_LOC/lib  
UTTSCPRINTERADM=$SUNWUTTSC_LOC/sbin/uttscprinteradm

ADMINSUBTREE=""
ADMINUSERNAME=""
OS=`/bin/uname -s`

RETCODE=0
ROOTPW=""

ETCSERVICES="/etc/services"
START_DELIMITER="#START SUNWuttsc"
END_DELIMITER="#END SUNWuttsc"
UTTSCPD="uttscpd"
UTTSCPDPORT="7014/tcp"
TMPFILE="/tmp/tmpservice.$$"


function setAdminVars {

ADMINSUBTREE=`grep admin.subtree $UTADMIN_CONF | awk '{print $NF}'`
ADMINUSERNAME=`grep admin.user.name $UTADMIN_CONF | awk '{print $NF}'`
}

function mustBeRoot {
	case "$(id)" in
	'uid=0('*)
		;; 
	*)
		print -u2 "Must be root to configure/unconfigure Sun Ray Connector for Windows Operating Systems"
		exit 1
		;;
	esac
}

#
# Usage - prints the usage message
# $1 - the exit code
function Usage {

    cat <<!

Usage:
uttscadm -c         # Configure the Sun Ray Connector for Windows Operating Systems
uttscadm -u         # Unconfigure the Sun Ray Connector for Windows Operating Systems
uttscadm -h         # Display this usage message
!
    exit $1

}

#Helpers for FIFOs used to get sensitive content out of command lines
#
#

CleanupPipeProcs() {
    [ -n "$PW_PID" ] && kill "$PW_PID" 2> /dev/null
}
 
CreatePipe() {
    mkfifo -m 600 "$1"
}

DestroyPipe() {
    rm -f "$1"
    [ -n "$2" ] && kill $2 2>/dev/null
}

CreateSecureFile() {
    touch "$1"
    chmod 600 "$1"
}

DestroySecureFile() {
     rm -f "$1"
}

CreatePWPipe_SunOS() {
    CreatePipe $TMP_PWPIPE || return 1
 
    print "$ROOTPW" > $TMP_PWPIPE &
    PW_PID=$!
}

DestroyPWPipe_SunOS() {
    DestroyPipe "$TMP_PWPIPE" "$PW_PID"
    PW_PID=
}

CreatePWPipe_Linux() {
	CreateSecureFile "$TMP_PWPIPE" || return 1
	print -n "$ROOTPW" > "$TMP_PWPIPE"
}

DestroyPWPipe_Linux() {
        DestroySecureFile "$TMP_PWPIPE"
}

CreatePWPipe() {

    case "$OS" in # {
    SunOS)
      CreatePWPipe_SunOS
    ;;

    Linux)
      CreatePWPipe_Linux
    ;;

    *)
      Fatal "unknown OS name $OS"
    ;;

    esac # }
}

DestroyPWPipe() {

    case "$OS" in # {
    SunOS)
      DestroyPWPipe_SunOS
    ;;

    Linux)
      DestroyPWPipe_Linux
    ;;

    *)
      Fatal "unknown OS name $OS"
    ;;

    esac # }
}

#

#
# function to get the LDAP port number from the utdsd.ini file
#
function get_ldap_port {
	if [[ -f ${SRDS_LDAP_CURRENT}/utdsd.ini ]]; then
		sed -n -e 's/^LdapPort=//p' ${SRDS_LDAP_CURRENT}/utdsd.ini
	else
		# utdsd.init does not exist under /etc/opt/SUNWut/srds/current
		# directory.  This can only happen when the system is being
		# configured the first time.  We get the default port from
		# the default directory.
		sed -n -e 's/^LdapPort=//p' ${SRDS_LDAP_DEFAULT}/utdsd.ini
	fi
}


function SetPlatformDependencies {

    case "$OS" in # {
    SunOS)
	LDAPADD="/usr/bin/ldapadd"
	LDAPDELETE="/usr/bin/ldapdelete"
	LDAPSEARCH="/usr/bin/ldapsearch -L"  # -L option ensures same ouput format on s9, s10
	LDAP_PWOPT="-j"
	DEFAULT_SSL_LIB=libcrypto.so.0.9.7
	DEFAULT_PATHNAME="/usr/sfw/lib/libcrypto.so.0.9.7"
	ALTERNATE_PATHNAME="/usr/sfw/lib/libcrypto.so.0.9.8"
	TR_CMD="tr '[a-z][A-Z]' '[n-z][a-m][N-Z][A-M]' "
	;;
    Linux)
	LDAPADD="/usr/bin/ldapadd -h ${THIS_HOST} -x"
	LDAPDELETE="/usr/bin/ldapdelete -h ${THIS_HOST} -x"
	LDAPSEARCH="/usr/bin/ldapsearch -h ${THIS_HOST} -x"
	LDAP_PWOPT="-y"
	DEFAULT_SSL_LIB=libcrypto.so.0.9.7
	#default path on 2.6 linux servers is /usr/lib for the libcrypto
	DEFAULT_PATHNAME="/usr/lib/libcrypto.so.0.9.7"
	ALTERNATE_PATHNAME="/lib/libcrypto.so.0.9.7a"
	TR_CMD="tr 'a-zA-Z' 'n-za-mN-ZA-M' "
	;;
    *)
	print -u2 "unknown OS name $OS"
	exit 1
	;;
    esac # }
}

function validateSRSSversion {

    Version=`$SUNWUTLIB/utprodinfo -p SUNWuto PRODVERS`
    majorVersion=`echo $Version | awk -F. '{print $1}'`
    minorVersion=`echo $Version | awk -F. '{print $2}'`

   if [[ $majorVersion -lt 4 || $majorVersion -eq 4 && $minorVersion -lt 0 ]]; then
     print "Only SRSS 4.0 and above are supported"
     exit 1
   fi
}

function mustBeConfigured {
#
# Check to see if utconfig has been run first by checking for the
# existence of /etc/opt/SUNWut/utadmin.conf
#
    if [[ ! -f $UTADMIN_CONF ]]
    then
        print -u2 "Please run utconfig first before configuring Sun Ray Connector for Windows Operating Systems."
	exit 1
    fi
}

# Read LDAP admin password from password file
# and decode it

function getPassword {

    if [[ ! -r $UTADMIN_PW ]]
    then
        print -u2 "Unable to read Sun Ray Data Store admin password. "
	exit 1
    fi

    ROOTPW=`$TR_CMD < $UTADMIN_PW`
}

PrintRestartMsg() {

     print -u2 "
*****************************************************************************
A restart of Sun Ray services is required before the Sun Ray Connector for 
Windows Operating Systems is used. Please run :

           $SUNWUTSBIN/utrestart

Note that this will *NOT* terminate any sessions.
*****************************************************************************"

}

function createLDAPschema {

	OUTFILE=/tmp/ldap.add.tmp
	print "dn: utname=remoteclient,$ADMINSUBTREE" > $OUTFILE
	print "objectClass: utMap" >> $OUTFILE
	print "utname:  remoteclient" >> $OUTFILE

	CreatePWPipe ||
	   Fatal "Cannot create pipe $TMP_PWPIPE for required LDAP additions"

	${LDAPADD} -p $LDAP_PORT -D $ADMINUSERNAME  $LDAP_PWOPT $TMP_PWPIPE \
	   -f $OUTFILE
	DestroyPWPipe

	RETCODE=`echo $?`
	rm $OUTFILE

	print "dn: utname=users,utname=remoteclient,$ADMINSUBTREE" > $OUTFILE
	print "objectClass: utMap" >> $OUTFILE
	print "utname: users" >> $OUTFILE

	CreatePWPipe ||
	   Fatal "Cannot create pipe $TMP_PWPIPE for required LDAP additions"

	${LDAPADD} -p $LDAP_PORT -D $ADMINUSERNAME  $LDAP_PWOPT $TMP_PWPIPE \
	   -f $OUTFILE

	DestroyPWPipe

	rm $OUTFILE

}


function removeServicesEntry {
        awk -f - $ETCSERVICES <<!
                BEGIN { DOPRINT = 1; STATUS = 0 }

                /^$START_DELIMITER$/ {
                    if ( DOPRINT == 0 )
                        STATUS = 2
                    else
                        DOPRINT = 0
                }

                { if ( DOPRINT == 1 ) { print } }

                /^$END_DELIMITER$/ {
                    if ( DOPRINT == 1 )
                        STATUS = 2
                    else
                        DOPRINT = 1
                }

                END {
                    if ( DOPRINT == 0 )
                        exit 2
                    else
                        exit STATUS
                }
!
        if [[ $? != 0 ]]; then
            print -u2 "Error: '$ETCSERVICES' does not have SUNWuttsc entry correctly setup.\n" 1>&2
	    exit 1
        fi
}

function addServicesEntry {
        # Entry does not exist, add it.
        echo $START_DELIMITER 
        echo "$UTTSCPD         $UTTSCPDPORT                        # SRWC proxy daemon" 
        echo $END_DELIMITER
}


function removeLDAPschema {

	getPassword

	SEARCHBASE="utname=users,utname=remoteclient,$ADMINSUBTREE"

	CreatePWPipe ||
	   Fatal "Cannot create pipe $TMP_PWPIPE for required LDAP search"

	for user in `{
	    ${LDAPSEARCH} -p $LDAP_PORT -D "$ADMINUSERNAME" \
	    $LDAP_PWOPT $TMP_PWPIPE \
            -b "$SEARCHBASE" \
            -s one "utname=*" utname | grep "utname:" | awk '/utname: / {print $2}'
	}`
        do
            $UTTSCPRINTERADM -d $user
        done

	DestroyPWPipe

        OUTFILE=/tmp/ldap.del.tmp
        print "utname=users,utname=remoteclient,$ADMINSUBTREE" > $OUTFILE

	CreatePWPipe ||
	   Fatal "Cannot create pipe $TMP_PWPIPE for required LDAP deletions"

	${LDAPDELETE} -p $LDAP_PORT -D "$ADMINUSERNAME" \
	$LDAP_PWOPT $TMP_PWPIPE -f $OUTFILE

	DestroyPWPipe

	RETCODE=`echo $?`
        rm $OUTFILE

        print "utname=remoteclient,$ADMINSUBTREE" > $OUTFILE

	CreatePWPipe ||
	   Fatal "Cannot create pipe $TMP_PWPIPE for required LDAP deletions"

	${LDAPDELETE} -p $LDAP_PORT -D "$ADMINUSERNAME" \
	$LDAP_PWOPT $TMP_PWPIPE -f $OUTFILE

	DestroyPWPipe

        rm $OUTFILE

}

function setupProxyDaemon {

    #  Add an entry for the uttscpd in /etc/services files. 
    #
    grep "^$UTTSCPD" $ETCSERVICES >/dev/null 2>&1
    if [[ $? -ne 0 ]]; then
       addServicesEntry > $TMPFILE      
       cat $TMPFILE >> $ETCSERVICES
       rm $TMPFILE
     fi

    # Launch SRDS Proxy daemon
    $SUNWUTTSC_LOC/sbin/uttscrestart


}

function removeProxyDaemon {

    # Stop SRDS Proxy Daemon
    /etc/init.d/uttscp stop

    # Remove entry from /etc/services file
    grep "^$UTTSCPD" $ETCSERVICES >/dev/null 2>&1
    if [[ $? -eq 0 ]]; then
        removeServicesEntry > $TMPFILE
	cp $TMPFILE $ETCSERVICES
	rm $TMPFILE
    fi
}


function configTSC {

    # Activities to be done at config time are :
    # Prompt for OpenSSL path and create a symbolic link from /opt/SUNWuttsc/lib
    # to the libcrypto library, if the library does not exist in the standard path.
    # If this link already exists, display the link value and continue.

	   if [[ ! -f $DEFAULT_PATHNAME ]]
	   then
		   if  [[ -L $SUNWUTTSCLIB/$DEFAULT_SSL_LIB ]]
		   then
		     linkname=`ls -l $SUNWUTTSCLIB/$DEFAULT_SSL_LIB | awk '{print $NF}'`
		     print "OpenSSL library already linked to: " $linkname 
		     print "Continuing.."
		   else
		     UT_PATHNAME_OK=false
		     
		     while ! $UT_PATHNAME_OK
		     do 
		       print -n "Enter complete location for $DEFAULT_SSL_LIB [$ALTERNATE_PATHNAME] : "
			 read -r
			 case "$REPLY" in 
			   "")		  
			       PATHNAME=$ALTERNATE_PATHNAME
			       ;;
			   *)
			       PATHNAME=$REPLY
			       ;;
			 esac

			 if [[ -f $PATHNAME ]]
			 then
				UT_PATHNAME_OK=true
				print "\nCreating link ...\n"
				ln -s $PATHNAME $SUNWUTTSCLIB/$DEFAULT_SSL_LIB
			 else
			   print -u2 "\nInvalid filename $PATHNAME "
			 fi
			 
		       done	    
		   fi
	   fi	

    #    Call the script to update permissions in ldap for creating new
    #    branch. Stop and start the Sun Ray Data store process.
    #    Do all this only if schema doesn't already exist and only on primary.
    
    if ! $SUNWUTSBIN/utreplica -i | grep "UT_Replica_Id_Sec" > /dev/null 2>&1; then
    
      getPassword

      # Do search and throw away OUTPUT.. this prevents it from being 
      # displayed on screen
      
      SEARCHBASE="utname=users,utname=remoteclient,$ADMINSUBTREE"

      CreatePWPipe ||
	   Fatal "Cannot create pipe $TMP_PWPIPE for required LDAP search"

      OUTPUT=`{
	${LDAPSEARCH} -p $LDAP_PORT -D "$ADMINUSERNAME" \
	$LDAP_PWOPT $TMP_PWPIPE \
        -b "$SEARCHBASE" "utname=*" 2>&1 > /dev/null 
      }` 
      
      RETURNSTATUS=`echo $?`
      DestroyPWPipe
      
      # ldapsearhc returns 0 if it is successful in finding a match. Non-zero
      # otherwise.
      if [[ $RETURNSTATUS != 0 ]]
      then		  
	  # 4. Create LDAP schema for printer cache storage.
	
	  print "Creating required LDAP schema ... "
	  createLDAPschema
	  if [ $RETCODE == 0 ] 
	  then
	      print "Done."
	      PrintRestartMsg
	  fi
      else
	print "Data Store schema already in place. No change Required."
	
      fi
    fi

    case "$OS" in # {
    SunOS)	   
	   # Setup and start the daemon
	   setupProxyDaemon
	   ;;
    esac #}

}


function unconfigTSC {

    # Activities to be done at un-config time are :
    # 1. Remove the libcrypto library link from /opt/SUNWut/lib 
    # 2. Remove LDAP schema for printer cache storage.

    while true; do
            print -n "\nUnconfiguring Sun Ray Connector for Windows Operating Systems. Continue (Y/[N]): "
	    read -r
	    case "$REPLY" in
	      [Yy]|[Yy][Ee][Ss]) break;;
	      [Nn]|[Nn][Oo] | "")  
			exit 1;;
	    esac
    done

    if [[ -f $SUNWUTTSCLIB/$DEFAULT_SSL_LIB ]] 
    then
      print "Removing link $SUNWUTTSCLIB/$DEFAULT_SSL_LIB..."
      rm -rf $SUNWUTTSCLIB/$DEFAULT_SSL_LIB
    fi

    case "$OS" in # {
    SunOS)	   
	   # Stop and unconfig SRDS Proxy Daemon
	   removeProxyDaemon	  
	   ;;
    esac #}

    if [[ ! -f $UTADMIN_CONF ]]
    then
        exit 0 
    fi
    
    # if configured, then set the admin variables
    setAdminVars

    if ! $SUNWUTSBIN/utreplica -i | grep "UT_Replica_Id_Sec" > /dev/null 2>&1; then
        print "Removing LDAP schema ..."

        removeLDAPschema
	if [ $RETCODE == 0 ] 
	then
	      print "Done."
	else
	      print "Unconfig failed."
	fi
    fi
}

#
# MAIN
#

mustBeRoot
LDAP_PORT=$(get_ldap_port)

SetPlatformDependencies

if [[ $# -ne 1 ]]; then
	Usage 1
fi

case "$1" in 
'-c')
        validateSRSSversion
	mustBeConfigured
	setAdminVars
    	configTSC
    ;;
'-u')
	unconfigTSC
	;;
'-h')
        Usage 0
	;;
*)
        Usage 1
	;;
esac

