#
# Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
# Use is subject to license terms.
#

SMBCONF=${SAMBA_CFGDIR}/lib/smb.conf
NMBD=${SAMBA_SBINDIR}/nmbd
SMBD=${SAMBA_SBINDIR}/smbd
SMBCLIENT=${SAMBA_BINDIR}/smbclient
NMBLOOKUP=${SAMBA_BINDIR}/nmblookup
NETBIOSNAME=`basename ${SAMBA_CFGDIR}`
NMBDLOCKF=${SAMBA_CFGDIR}/var/locks/nmbd.pid
SMBDLOCKF=${SAMBA_CFGDIR}/var/locks/smbd.pid
SAMBA_LOGDIR_TEMP=${SAMBA_CFGDIR}/logs
TMPF=/var/tmp/${NETBIOSNAME}.tmp
SCHA_RESOURCE_GET=/usr/cluster/bin/scha_resource_get

SCLH=`$SCHA_RESOURCE_GET -O Network_resources_used \
        -R $RESOURCE -G $RESOURCEGROUP`

LHOST=`scrgadm -pvv -j ${SCLH} | grep HostnameList | \
        grep value: | awk -F: '{print $4}'`

PROBE_TIMEOUT=`$SCHA_RESOURCE_GET -O Extension \
	-R $RESOURCE -G $RESOURCEGROUP Probe_timeout`

PROBE_TIMEOUT=`echo $PROBE_TIMEOUT | awk '{print $2}'`

SCLOGGER=/usr/cluster/lib/sc/scds_syslog
PKG=SUNWscsmb.samba
METHOD=`basename $0`

syslog_tag()
{
        #
        # Data Service message format
        #

        $SET_DEBUG

        print "SC[${PKG:-??}.${METHOD:-??}]:${RESOURCEGROUP:-??}:${RESOURCE:-??}"
}

scds_syslog()
{

        #
        # Log a message
        #

        $SET_DEBUG

        $SCLOGGER "$@" &
}

debug_message()
{
        #
        # Output a debug message to syslog if required
        #

        if [ "$DEBUG" = "$RESOURCE" -o "$DEBUG" = "ALL" ]
        then
                SET_DEBUG="set -x"

                DEBUG_TEXT=$1

                scds_syslog -p daemon.debug -t $(syslog_tag) -m \
                        "%s" "$DEBUG_TEXT"
        else
                SET_DEBUG=
        fi

}

stripfunc() {
         s1=1
         s2=`echo $1 | /bin/wc -c`
         s3=""

        while [ $s1 -lt ${s2} ]
        do
  
		s4=`echo $1 | /bin/cut -c ${s1}`

        	if [[ "${s4}" != @([0-9]) ]]; then
           	break
        	else
          	s3=${s3}${s4}
        	fi

        	s1=$(($s1+1))

        done

        echo $s3
}


validate_options()
{
        #
        # Ensure all options are set
        #

        for i in RESOURCE RESOURCEGROUP RUN_NMBD SAMBA_BINDIR SAMBA_SBINDIR SAMBA_CFGDIR SAMBA_FMUSER SAMBA_FMRESOURCE SAMBA_LOGDIR
        do
                case $i in
                        RESOURCE)
                        if [ -z $RESOURCE ]; then
                                logger -p daemon.err \
                                "ERROR: `basename $0` Option -R not set"
                                exit 1
                        fi;;

                        RESOURCEGROUP)
                        if [ -z $RESOURCEGROUP ]; then
                                logger -p daemon.err \
                                "ERROR: `basename $0` Option -G not set"
                                exit 1
                        fi;;

                        RUN_NMBD)
                        if [ -z $RUN_NMBD ]; then
                                RUN_NMBD=YES
                        fi;;

                        SAMBA_BINDIR)
                        if [ -z $SAMBA_BINDIR ]; then
                                logger -p daemon.err \
                                "ERROR: `basename $0` Option -B not set"
                                exit 1
                        fi;;

                        SAMBA_SBINDIR)
                        if [ -z $SAMBA_SBINDIR ]; then
                                logger -p daemon.err \
                                "ERROR: `basename $0` Option -S not set"
                                exit 1
                        fi;;

                        SAMBA_CFGDIR)
                        if [ -z $SAMBA_CFGDIR ]; then
                                logger -p daemon.err \
                                "ERROR: `basename $0` Option -C not set"
                                exit 1
                        fi;;

                        SAMBA_FMUSER)
                        if [ -z $SAMBA_FMUSER ]; then
                                logger -p daemon.err \
                                "ERROR: `basename $0` Option -U not set"
                                exit 1
                        fi;;

                        SAMBA_FMRESOURCE)
                        if [ -z $SAMBA_FMRESOURCE ]; then
                                logger -p daemon.err \
                                "ERROR: `basename $0` Option -M not set"
                                exit 1
                        fi;;

                        SAMBA_LOGDIR)
                        if [ -z $SAMBA_LOGDIR ]; then
				SAMBA_LOGDIR=$SAMBA_LOGDIR_TEMP
                        fi;;
                esac
        done

        #
        # Set LD_LIBRARY_PATH if SAMBA_LD_PATH is being used.
        #

        if [ ! -z "${SAMBA_LD_PATH}" ]; then
           export LD_LIBRARY_PATH=${SAMBA_LD_PATH}
        fi

}

validate() 
{
	#
	# Validate Samba 
	#

        debug_message "Function: validate - Begin"
	$SET_DEBUG

	rc_validate=0
	#
	# Validate the bin & sbin directories
	#

	if [ ! -d "${SAMBA_BINDIR}" ]
	then
   		scds_syslog -p daemon.error -t $(syslog_tag) -m \
			"Validate - Samba bin directory %s does not exist" \
			"${SAMBA_BINDIR}"
		rc_validate=1
	else
		debug_message "Validate - Samba bin directory ${SAMBA_BINDIR} exists" 
	fi

	if [ ! -d "${SAMBA_SBINDIR}" ]
	then
   		scds_syslog -p daemon.error -t $(syslog_tag) -m \
			"Validate - Samba sbin directory %s does not exist" \
			"${SAMBA_SBINDIR}"
		rc_validate=1
	else
		debug_message "Validate - Samba sbin directory ${SAMBA_SBINDIR} exists"
	fi

	#
	# Validate the configuration directory
	#

	if [ ! -d "${SAMBA_CFGDIR}" ]
	then
   		scds_syslog -p daemon.error -t $(syslog_tag) -m \
			"Validate - Samba configuration directory %s does not exist" \
			"${SAMBA_CFGDIR}"
		rc_validate=1
	else
		debug_message "Validate - Samba configuration directory ${SAMBA_CFGDIR} exists"
	fi

	#
	# Validate that the Samba log directory exists
	#

	if [ ! -d "${SAMBA_LOGDIR}" ]
	then
   		scds_syslog -p daemon.error -t $(syslog_tag) -m \
			"Validate - Samba log directory %s does not exist" \
			"${SAMBA_LOGDIR}"
		rc_validate=1
	else
		debug_message "Validate - Samba log directory ${SAMBA_LOGDIR} exists" 
	fi

	#
	# Validate that the smbd is executable
	#

	if [ ! -x "${SMBD}" ]
	then
   		scds_syslog -p daemon.error -t $(syslog_tag) -m \
			"Validate - smbd %s non-existent executable" \
			"${SMBD}"
		rc_validate=1
	else
		debug_message "Validate - smbd ${SMBD} exists and is executable"
	fi

	#
	# Validate that the nmbd is executable
	#

	if [ ! -x "${NMBD}" ]
	then
   		scds_syslog -p daemon.error -t $(syslog_tag) -m \
			"Validate - nmbd %s non-existent executable" \
			"${NMBD}"
		rc_validate=1
	else
		debug_message "Validate - nmbd ${NMBD} exists and is executable"
	fi

	#
	# Validate that smb.conf file exists
	#

	if [ ! -f "${SMBCONF}" ]
	then
   		scds_syslog -p daemon.error -t $(syslog_tag) -m \
			"Validate - smbconf %s does not exist" \
			"${SMBCONF}"
		rc_validate=1	
	else
		debug_message "Validate - smbconf ${SMBCONF} exists"
	fi

	#
	# Validate that fault monitor resource exists
	#

	if [ -z "`/bin/grep '\[' ${SMBCONF} | /bin/cut -d'[' -f2 |\
		 /bin/cut -d']' -f1 | /bin/grep ${SAMBA_FMRESOURCE}`" ]
	then
   		scds_syslog -p daemon.error -t $(syslog_tag) -m \
			"Validate - Faultmonitor-resource <%s> does not exist" \
			"${SAMBA_FMRESOURCE}"
		rc_validate=1
	else
		debug_message "Validate - Faultmonitor-resource ${SAMBA_FMRESOURCE} exists"
	fi

	#
	# Validate that smbclient program is executable 
	#

	if [ ! -x "${SMBCLIENT}" ]
	then
   		scds_syslog -p daemon.error -t $(syslog_tag) -m \
			"Validate - smbclient %s non-existent executable" \
			"${SMBCLIENT}"
		rc_validate=1
	else
		debug_message "Validate - smbclient ${SMBCLIENT} exists and is executable"
	fi

	#
	# Validate that nmblookup program is executable
	#

	if [ ! -x "${NMBLOOKUP}" ]
	then
   		scds_syslog -p daemon.error -t $(syslog_tag) -m \
			"Validate - nmblookup %s non-existent executable" \
			"${NMBLOOKUP}"
		rc_validate=1
	else
		debug_message "Validate - nmblookup ${NMBLOOKUP} exists and is executable"
	fi

	#
	# Validate that fault monitor user exists
	#

        echo ${SAMBA_FMUSER} |awk 'BEGIN { FS="\\" } {print $NF}' | cut -d'%' -f1 > ${TMPF}
        USER=`cat ${TMPF}`

	if [ -z "`getent passwd ${USER}`" ]
	then
 		scds_syslog -p daemon.error -t $(syslog_tag) -m \
			"Validate - Couldn't retrieve faultmonitor-user <%s> from the nameservice" \
			"${USER}"
		rc_validate=1
	else
		debug_message "Validate - Retrieved faultmonitor-user ${USER} from the nameservice"
	fi

	#
	# Check the Samba version
	#

        # Is 2.2.x being used

        ${NMBLOOKUP} -h >/dev/null 2>&1

        if [ $? -eq 0 ]; then
           VERSION=`${NMBLOOKUP} -h | grep 'Version ' | awk '{print $2}'`
        else
           VERSION=`${NMBLOOKUP} -V | awk '{print $2}'`
        fi

	SAMBA_VERSION=`echo ${VERSION} | cut -d'.' -f1`
	SAMBA_RELEASE=`echo ${VERSION} | cut -d'.' -f2`
	SAMBA_UPDATE=` echo ${VERSION} | cut -d'.' -f3`

	debug_message "Validate - Samba version <${SAMBA_VERSION}.${SAMBA_RELEASE}.${SAMBA_UPDATE}> is being used"

	# Strip off any non-digits

	SAMBA_VERSION=`stripfunc ${SAMBA_VERSION}`
	SAMBA_RELEASE=`stripfunc ${SAMBA_RELEASE}`
	SAMBA_UPDATE=`stripfunc ${SAMBA_UPDATE}`

	rc_validate_version=0

        if [ -z "${VERSION}" ]
        then
                scds_syslog -p daemon.error -t $(syslog_tag) -m \
                        "Validate - Couldn't retrieve Samba version number"
                rc_validate=1
        elif [ "${SAMBA_VERSION}" -lt 2 ]; then
             rc_validate_version=1
        elif [ "${SAMBA_VERSION}" -eq 2 -a "${SAMBA_RELEASE}" -le 2 -a "${SAMBA_UPDATE}" -lt 2 ]; then
             rc_validate_version=1
        fi

        if [ "${rc_validate_version}" -gt 0 ]; then

                scds_syslog -p daemon.error -t $(syslog_tag) -m \
                        "This version of samba <%s> is not supported with this dataservice" \
                        `printf ${SAMBA_VERSION}.${SAMBA_RELEASE}.${SAMBA_UPDATE}`
                rc_validate=1
        fi

	#
	# Validate $RUN_NMBD
	#

	case "${RUN_NMBD}" in
		YES|Yes|yes|Y|y) RUN_NMBD=YES
			debug_message "Validate - RUN_NMBD=$RUN_NMBD"
			;;
		NO|No|no|N|n)    RUN_NMBD=NO
			debug_message "Validate - RUN_NMBD=$RUN_NMBD"
			;;
		*)	rc_validate=1

			scds_syslog -p daemon.error -t $(syslog_tag) -m \
				"Validate - RUN_NMBD=%s is invalid - specify YES or NO" \
				"$RUN_NMBD"
			;;
	esac
	
        debug_message "Function: validate - End"
}

start_samba()
{
	#
	# Start Samba
	#

        debug_message "Function: start_samba - Begin"
	$SET_DEBUG

	#
	# Start nmbd 
	#

	nmbdst=99

	if [ "$RUN_NMBD" = "YES" ]
	then
		${NMBD} -D -s ${SMBCONF} -l ${SAMBA_LOGDIR}
		nmbdst=$?
	fi

	#
	# Start smbd 
	#

	${SMBD} -D -s ${SMBCONF} -l ${SAMBA_LOGDIR}
	smbst=$?

        debug_message "Function: start_samba - End"
}

stop_samba()
{
	#
	# Stop Samba
	#

        debug_message "Function: stop_samba - Begin"
	$SET_DEBUG
	
	#
	# Kill nmbd pid else pkill nmbd
	#

	if [ "$RUN_NMBD" = "YES" ]
	then
		if [ -f "${NMBDLOCKF}" ]
		then
   			pid=`cat ${NMBDLOCKF}`

			debug_message "stop_samba - nmbd lockfile found send TERM to ${pid} and remove lockfile"

   			/bin/kill -TERM ${pid}
   			/bin/rm -f ${NMBDLOCKF}
		else
			debug_message "stop_samba - nmbd lockfile not found - send TERM to nmbd"

   			pkill -TERM nmbd
		fi
	fi

	#
	# Kill smbd pid else pkill smbd
	#

	if [ -f "${SMBDLOCKF}" ]
	then
   		pid=`cat ${SMBDLOCKF}`

		debug_message "stop_samba - smbd lockfile found send TERM to ${pid} and remove lockfile"

   		/bin/kill -TERM ${pid}
   		/bin/rm -f ${SMBDLOCKF}
	else
		debug_message "stop_samba - smbd lockfile not found send TERM to nmbd"

   		pkill -TERM smbd
	fi

        debug_message "Function: stop_samba - End"
}

check_samba()
{
	#
	# Check Samba 
	#

        debug_message "Function: check_samba - Begin"
	$SET_DEBUG

	rc_check_samba=0
        #
        # Check if the agent is starting
        #

        if [ ! -z "`pgrep start_samba`" ]
        then
                debug_message "check_samba - Samba is starting, exiting"
                rc_check_samba=1
                return
        fi

	#
	# Ask name service if the fault monitor user can be retrieved
	#

        echo ${SAMBA_FMUSER} |awk 'BEGIN { FS="\\" } {print $NF}' | cut -d'%' -f1 > ${TMPF}
        USER=`cat ${TMPF}`

	if [ -z "`getent passwd ${USER}`" ]
	then
 		scds_syslog -p daemon.error -t $(syslog_tag) -m \
			"check_samba - Couldn't retrieve faultmonitor-user <%s> from the nameservice" \
			"${USER}"

                rc_check_samba=1
                return
	fi

	#
	# Nmbd probe command
	#

	if [ "$RUN_NMBD" = "YES" ]
	then
		for lh in $LHOST
		do
			debug_message "check_samba - Run nmblookup for ${lh}"

			${NMBLOOKUP} -s ${SMBCONF} -U ${lh} ${NETBIOSNAME} \
			| /usr/xpg4/bin/grep -i -e ERR -e FAIL > ${TMPF}

			if [ -s "${TMPF}" ]
        		then
                		scds_syslog -p daemon.error -t $(syslog_tag) -m \
                        	"check_samba - Nmbd for <%s> is not working, failed to retrieve ipnumber for %s" \
                        	"${NETBIOSNAME}" " ${NETBIOSNAME}"

                		rc_check_samba=1
                		return
        		else
                		debug_message "check_samba - nmblookup for ${lh} is working"
        		fi
		done
	fi

	#
	# Samba probe command 
	#
	#
	# If smbclient can't connect, there could be network/server issues causing smbclient to fail.
	# These errors maybe transient and correctable within a few seconds. Therefore before calling
	# an error (which would result in a restart), we will retry the smbclient request within 85% 
	# of the available Probe_timeout less 15 seconds, which is approximately the timeout for the
	# first smbclient failure. 
	#
	# However, doing this is only realistic if Probe_timeout=30 seconds or more. If Probe_timeout
	# is below 30 seconds then we'll just try smbclient once, which was the previous behaviour.

	if [ ${PROBE_TIMEOUT} -ge 30 ]
	then
		MAX_PROBE_TIMEOUT=`expr \( ${PROBE_TIMEOUT} \* 85 \/ 100 \) \- 15 `
	else
		MAX_PROBE_TIMEOUT=2
	fi

	while [ ${MAX_PROBE_TIMEOUT} -ge 2 ]
	do
		${SMBCLIENT} '\\'${NETBIOSNAME}'\'${SAMBA_FMRESOURCE} -s ${SMBCONF} -U `echo ${SAMBA_FMUSER}` \
			-c 'pwd;exit' | /usr/xpg4/bin/grep -i -e ERR -e FAIL > ${TMPF}

		if [ -s "${TMPF}" ]
		then
  			scds_syslog -p daemon.error -t $(syslog_tag) -m \
				"check_samba - Samba server <%s> not working, failed to connect to samba-resource <%s>" \
				"${NETBIOSNAME}" " ${SAMBA_FMRESOURCE}"

                	rc_check_samba=1
			MAX_PROBE_TIMEOUT=`expr ${MAX_PROBE_TIMEOUT} - 2`
			sleep 1
		else
                	rc_check_samba=0
			MAX_PROBE_TIMEOUT=0
			debug_message "check_samba - Samba is working"
		fi
	done

        debug_message "Function: check_samba - End"
}
