#!/bin/ksh -p
#
# ident "@(#)utsyslog-ngctl.ksh	1.2	08/09/19 SMI"
#
# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
# Use is subject to license terms.
#

set -u
########################################################################
#
# Configures syslog-ng to handle syslog requests from SRSS
#
# Note that this script is called not just at product activation and
# deactivation.  It is also executed whenever 'utconfig' takes SRSS into
# or out of configured (ie DS-is-active) mode.  This is required because
# syslog-ng enforces logfile ownership and permissions the first time it
# writes to a logfile.  This means that we must reconfigure syslog-ng
# when the logfile group ownership flips from "root" to "utadmin" and
# vice versa, otherwise syslog-ng will "repair" those ownership changes
# (which, among other things, will make the logfiles inaccessible to the
# web admin GUI).  So, take care to not do anything here that would
# damage SRSS if sequences of disable/enable executions of this script
# are executed while the rest of SRSS remains in the enabled state.
#
########################################################################


########################################################################
#
# Operation entry points, one for each keyword.  This is where the
# specific work for this feature happens.
#
########################################################################

#
# disable()
#
function disable {

    typeset -i10 exitval=0

    # If there's no syslog-ng conf file then there's nothing for us to
    # do here.

    if [[ -f "$syslogng_conf" ]] ; then

	# Strip out any lines that carry our marker
	grep -q "$syslogng_tag" "$syslogng_conf"
	if [ $? -eq 0 ] ; then
	    typeset tmp_ngconf="${syslogng_conf}-SunRay-tmp.$$"
	    rm -f "$tmp_ngconf"
	    ( umask 077 && cat /dev/null > "$tmp_ngconf" )
	    grep -v "$syslogng_tag" "$syslogng_conf" >> "$tmp_ngconf"

	    # If the filesystem was full or close to full then our $tmp_ngconf
	    # could be truncated.  If that's happened then we don't want to
	    # replace the original conf file with a damaged version.  Check
	    # by computing a checksum of the intended result and comparing
	    # that against a checksum of the tempfile.  Note that we do a
	    # string comparison of the 'cksum' outputs, which verifies both
	    # the sum and the length of the input.
	    #
	    wantsum=`grep -v "$syslogng_tag" "$syslogng_conf" | cksum`
	    gotsum=`cat "$tmp_ngconf" | cksum`

	    if [ "$wantsum" = "$gotsum" ] ; then
		(umask 133 && cat "$tmp_ngconf" > "$syslogng_conf")
		rm -f "$tmp_ngconf"
		if $VERB; then
		    print "Sun Ray syslog-ng entries disabled"
		fi
		pkill -HUP -x syslog-ng
	    else
		# on failure we leave $tmp_ngconf intact as evidence for later investigation
		exitval=1
		print -u2 \
		  "Error: failed to remove Sun Ray entries from ${syslogng_conf}"
		print -u2 \
		  "       Please remove those entries manually"
	    fi
	fi

	# Now try to remove the SELinux AppArmor configuration that lets
	# syslog-ng update our logfiles.

	if [ -f "$syslogng_apparmor_conf" ] ; then

	    # Strip out any lines that refer to /var/opt/SUNWut/log
	    grep -q "${SUNWUTVAR}/log" "$syslogng_apparmor_conf"
	    if [ $? -eq 0 ] ; then
		typeset tmp_aaconf="${syslogng_apparmor_conf}-SunRay-tmp.$$"
		rm -f "$tmp_aaconf"
		( umask 077 && cat /dev/null > "$tmp_aaconf" )
		grep -v "${SUNWUTVAR}/log" "$syslogng_apparmor_conf" >> "$tmp_aaconf"

		# Again do the checksum dance to make verify that we have
		# a sane $tmp_aaconf.
		#
	        wantsum=`grep -v "${SUNWUTVAR}/log" "$syslogng_apparmor_conf" | cksum`
	        gotsum=`cat "$tmp_aaconf" | cksum`

		if [ "$wantsum" = "$gotsum" ] ; then
		    (umask 133 && cat "$tmp_aaconf" > "$syslogng_apparmor_conf")
		    rm -f "$tmp_aaconf"
		    if $VERB; then
			print "Sun Ray syslog-ng AppArmor entries disabled"
		    fi
		    if [ -x /etc/init.d/boot.apparmor ] ; then
		        if $VERB; then
			    print "Attempting to apply updated syslog-ng AppArmor configuration"
			fi
			/etc/init.d/boot.apparmor reload > /dev/null
		    fi
		else
		    # on failure we leave $tmp_aaconf intact as evidence for later investigation
		    exitval=1
		    print -u2 \
		      "Error: failed to remove Sun Ray entries from ${syslogng_apparmor_conf}"
		    print -u2 \
		      "       Please remove those entries manually"
		fi
	    fi
	fi
    fi

    return $exitval
}

#
# enable()
#
# Configure syslog-ng to append user.info and local.info messages into
# /var/opt/SUNWut/log/messages and /var/opt/SUNWut/log/admin_log
# respectively.  Also tweak the SELinux configuration to allow the
# syslog-ng daemon to append to these two files.
# 
# NOTE: nothing will be done if the syslog entries already exist.
#
function enable {

    if [[ -f "$syslogng_conf" ]] ; then

        # Start by tweaking the AppArmor configuration to allow syslog-ng to
	# write to our logfiles.  Do this first so that it's all in place
	# before we tell syslog-ng to start delivering messages to our files.
	#
	if [ -f "$syslogng_apparmor_conf" ] ; then

	    # If our entries are already there, we have no work to do
	    #
	    grep -q "${SUNWUTVAR}/log" "$syslogng_apparmor_conf"
	    if [ $? -ne 0 ] ; then
		typeset tmp_aaconf="${syslogng_apparmor_conf}-SunRay-tmp.$$"
		rm -f "$tmp_aaconf"
		( umask 077 && cat /dev/null > "$tmp_aaconf" )
		awk '$1 == "}" \
			{ printf("  # files in %s added by Sun Ray activation\n",LOGDIR); 
			  printf("  %s/%s w,\n",LOGDIR,"messages"); 
			  printf("  %s/%s w,\n",LOGDIR,"admin_log");
			}
			{ print
			}' LOGDIR="$SUNWUTVAR"/log "$syslogng_apparmor_conf" >> "$tmp_aaconf"

		# Sanity check. The new configuration in $tmp_aaconf should contain more lines
		# than the original.
		#
		oldlines=`cat "$syslogng_apparmor_conf" | wc -l`
		newlines=`cat "$tmp_aaconf" | wc -l`
		if [ $newlines -gt $oldlines ] ; then
		    cat "$tmp_aaconf" > "$syslogng_apparmor_conf"
		    rm -f "$tmp_aaconf"
		    if $VERB; then
			print "Sun Ray syslog-ng AppArmor entries enabled"
		    fi
		    if [ -x /etc/init.d/boot.apparmor ] ; then
			if $VERB; then
			    print "Attempting to apply updated syslog-ng AppArmor configuration"
			fi
			/etc/init.d/boot.apparmor reload > /dev/null
		    fi
		else
		    # on failure we leave $tmp_aaconf intact as evidence for later investigation
		    exitval=1
		    print -u2 \
		      "Error: failed to add Sun Ray entries to ${syslogng_apparmor_conf}"
		    print -u2 \
		      "       Please add those entries manually"
		fi
	    fi
	fi

	# Now update the syslog-ng configuration if it doesn't already
	# contain our entries.
	#
	grep -q "$syslogng_tag" "$syslogng_conf"
	if [ $? -ne 0 ] ; then

	    typeset logfile_uid="0"
	    typeset logfile_gid=`/etc/opt/SUNWut/basedir/lib/utadmingid`
	    typeset logfile_perms="0640"

	    # In unconfigured mode use tighter permissions.  There should be a better
	    # way of figuring out whether we're configured or unconfigured.  Ugly as
	    # this is, it's better than trying to infer it from the existence of
	    # DS-related files.
	    #
	    if [ "$logfile_gid" = "root" ] ; then
		logfile_perms="0600"
	    fi

	    typeset tmp_ngconf="${syslogng_conf}-SunRay-tmp.$$"
	    rm -f "$tmp_ngconf"
	    (umask 077 && cat "${syslogng_conf}" > "$tmp_ngconf")

	    typeset message_log="$SUNWUTVAR/log/messages"
	    (umask 077 && touch "$message_log")
	    chown "$logfile_uid":"$logfile_gid" "$message_log"
	    chmod "$logfile_perms" "$message_log"

	    cat <<EoF >> "$tmp_ngconf"
$syslogng_tag (begin messages)
filter      f_SunRay_userinfo { level(info) and facility(user); }; $syslogng_tag
destination d_SunRay_msglog { file("$message_log" owner("$logfile_uid") group("$logfile_gid") perm($logfile_perms)); }; $syslogng_tag
log         { source(src); filter(f_SunRay_userinfo); destination(d_SunRay_msglog); }; $syslogng_tag
$syslogng_tag (end messages)
EoF

	    typeset admin_log="$SUNWUTVAR/log/admin_log"
	    (umask 077 && touch "$admin_log")
	    chown "$logfile_uid":"$logfile_gid" "$admin_log"
	    chmod "$logfile_perms" "$admin_log"

	    cat <<EoF >> "$tmp_ngconf"
$syslogng_tag (begin admin_log)
filter      f_SunRay_local1info { level(info) and facility(local1); }; $syslogng_tag
destination d_SunRay_admlog { file("$admin_log" owner("$logfile_uid") group("$logfile_gid") perm($logfile_perms)); }; $syslogng_tag
log         { source(src); filter(f_SunRay_local1info); destination(d_SunRay_admlog); }; $syslogng_tag
$syslogng_tag (end admin_log)
EoF

	    # Sanity check. The new configuration in $tmp_ngconf should contain more lines
	    # than the original.
	    #
	    oldlines=`cat "$syslogng_conf" | wc -l`
	    newlines=`cat "$tmp_ngconf" | wc -l`
	    if [ $newlines -gt $oldlines ] ; then
		cat "$tmp_ngconf" > "$syslogng_conf"
		rm -f "$tmp_ngconf"
		if $VERB; then
		    print "Sun Ray syslog-ng entries enabled"
		fi
		pkill -HUP -x syslog-ng
	    else
		# on failure we leave $tmp_ngconf intact as evidence for later investigation
		exitval=1
		print -u2 \
		  "Error: failed to add Sun Ray entries to ${syslogng_conf}"
		print -u2 \
		  "       Please add those entries manually"
	    fi
	fi
    fi

    return 0
}


#########################################
# LOCAL VARIABLES
# They must defined here to resolve the some of parameter resolution
# problem
#########################################
local_variables() {
	syslogng_conf="/etc/syslog-ng/syslog-ng.conf"
	syslogng_tag="# added by Sun Ray activation -- do not modify"
	syslogng_apparmor_conf="/etc/apparmor.d/sbin.syslog-ng"
}


#########################################
#
# Configurable parameter
#
#########################################
# NONE

#########################################
#
# variables used in the shared script utctl-shlib
#
#########################################
DESCR="configures syslog-ng for use with Sun Ray"

########################################################################
#
# Execution starts here
#

progpath=`dirname $0`
. "$progpath"/utctl-shlib

