#!/bin/ksh -p
#
# ident "@(#)utdmsession.ksh	1.10 04/04/08 SMI"
#
# Copyright 2002, 2004 Sun Microsystems, Inc.  All rights reserved.
# Use is subject to license terms.
#
# utdmsession - Inform the Device Manager of session creation and
#		destruction events.
#
#	Note that since session management needs to manage the
#	per-display session_proc file, we do that here since we
#	already have all the information we need to do that.
#
#    usage:
#
#	utdmsession -c Xdisplay [-z tag]
#	    create DM session based on Xdisplay
#	    -z - optional tag for logging purposes
#
#	utdmsession -d Xdisplay [-z tag]
#	    destroy DM session based on X display
#	    -z - optional tag for logging purposes
#

#exec 2>&1 2>/var/tmp/utdmsession.$$       # Debug
#set -x

MOD="`/bin/basename $0`"
USAGE="usage: $MOD [-c|-d] Xdisplay [-z tag]"

    DPY=""
    TAG="$MOD"

    while getopts :c:d:z: action
      do
	case "$action" in
	    c) ACTION="create" ; DPY="$OPTARG" ;;
	    d) ACTION="destroy" ; DPY="$OPTARG" ;;
	    z) TAG="$OPTARG" ;;
	    ?) echo $USAGE ; exit 1 ;;
	esac
      done
    shift $(expr $OPTIND - 1)

    if [ $# -ne 0 -o "$DPY" = "" ] ; then
	echo $USAGE
	exit 2
    fi

    DPYDIR="/var/opt/SUNWut/displays"
    DEVICE_SESSION="$(/bin/sed -n '/^SESSION=.*:/s///p' $DPYDIR/$DPY 2>/dev/null)"

    #
    # If no session, then there's not much we can do.
    # We can be silent about this condition since it's not
    # necessarily an error.
    #
    if [ "$DEVICE_SESSION" = "" ] ; then
	exit 0
    fi

    #
    # OK we've got an X display that maps to a session, now
    # setup the required pointers and actually do the work
    # of talking to the Device Manager about this session.
    #
    SESSION_INFO_DIR="/tmp/SUNWut/session_info"
    SESSION_PROC=/tmp/SUNWut/session_proc/$DPY
    DEVMGR_PIPE=/tmp/SUNWut/.utdevmgr
    PKG_OPT_INFO="$(/bin/pkginfo -r SUNWuto)"
    UTSCREVENT="$PKG_OPT_INFO/SUNWut/lib/utscrevent"
    TMPFILE="/var/opt/SUNWut/tmp/$MOD.$$"

    # set USER to root if no user
    if [[ -n $USER ]] then
	USER_ID="$(/usr/xpg4/bin/id -u $USER)"
	GROUP_ID="$(/usr/xpg4/bin/id -g $USER)"
    else
	USER_ID="$(/usr/xpg4/bin/id -u root)"
	GROUP_ID="$(/usr/xpg4/bin/id -g root)"
    fi

    # mount root and mount parent directory paths
    MOUNT_DIR="/tmp/SUNWut/mnt"
    if [[ -n $USER ]] then
	USER_MOUNT_DIR="$MOUNT_DIR/$USER"
    else
	# no user, use root
	USER_MOUNT_DIR="$MOUNT_DIR/root"
    fi

    #
    # Destroy session information
    #
    if [ "$ACTION" = "destroy" ] ; then

	/bin/rm -f $SESSION_INFO_DIR/$DEVICE_SESSION >/dev/null 2>&1
	/bin/rm -f $SESSION_PROC >/dev/null 2>&1

	# remove user's mount parent dir if empty
	if [[ -d $USER_MOUNT_DIR ]] then
		# remove first level of children if empty
		for CHILDDIRS in `/usr/bin/ls $USER_MOUNT_DIR`
		do
			MNT_CHILD_DIR=$USER_MOUNT_DIR/$CHILDDIRS
			if [[ -d $MNT_CHILD_DIR ]] then
				/bin/rmdir $MNT_CHILD_DIR >/dev/null 2>&1
			fi
		done
		/bin/rmdir $USER_MOUNT_DIR >/dev/null 2>&1
	fi

	# Tell the DM about this session.
	if [ -p "$DEVMGR_PIPE" ] ; then
	    echo $ACTION $DEVICE_SESSION > $DEVMGR_PIPE
	fi

	# Tell the smartcard subsystem about this session.
	$UTSCREVENT -d $DPY -z $TAG

    #
    # Create session information
    #
    else

	#
	# Store the UID and GID into the session info file. The
	# DM uses this information to determine session ownership.
	# set strict umask before creating $SESSION_INFO_DIR/$DEVICE_SESSION
	MY_UMASK="`umask`"
	umask  077
	printf "uid=$USER_ID\ngid=$GROUP_ID\nXID=$DPY\n" \
				> $SESSION_INFO_DIR/$DEVICE_SESSION
	# reset umask
	umask $MY_UMASK

	# save current umask and create dir with a strict umask
	MY_UMASK="`umask`"
	umask  077

	# if mount root directory does not exist, create it now
	if [[ ! ( -d $MOUNT_DIR ) ]] then
		TMP_PMOUNT_DIR="/var/opt/SUNWut/tmp/$MOD.pmnt.$$"
		/bin/mkdir $TMP_PMOUNT_DIR 2>/dev/null
		/bin/chown root:root $TMP_PMOUNT_DIR
		/bin/chmod 0755 $TMP_PMOUNT_DIR
		mv $TMP_PMOUNT_DIR $MOUNT_DIR
	fi

	# create user's mount parent directory if it does not exist
	# current umask is still good
	if [[ ! ( -d $USER_MOUNT_DIR ) ]] then
		TMP_UMOUNT_DIR="/var/opt/SUNWut/tmp/$MOD.umnt.$$"
		/bin/mkdir $TMP_UMOUNT_DIR 2>/dev/null
		/bin/chown $USER_ID:$GROUP_ID $TMP_UMOUNT_DIR
		/bin/chmod 0700 $TMP_UMOUNT_DIR
		mv $TMP_UMOUNT_DIR $USER_MOUNT_DIR
	fi

	# reset umask
	umask $MY_UMASK

	#
	# Store the user for session management.
	# The session_proc file must already been created by
	# Xsetup.
	# Note that this is not strictly related to the DM, but
	# we are here and already have all the information
	# we need to do this (SESSIONID, UID, etc...).
	#
	# Remove any existing UID that was in the file - this
	# UID was put here by a previous invocation of this script.
	#
	# It's OK if the session_proc file doesn't exist, since
	# we could be being called to create a new session before
	# the X files have been run (i.e. from utdtsession). In this
	# case, just create a new session_proc file and add the
	# current UID to that file.
	#
	/bin/grep -v "^uid=" $SESSION_PROC >$TMPFILE 2>/dev/null
	mv $TMPFILE $SESSION_PROC

	/bin/grep "^uid=" $SESSION_INFO_DIR/$DEVICE_SESSION >> $SESSION_PROC

	# Tell the DM about this session.
	if [ -p $DEVMGR_PIPE ] ; then
	    echo $ACTION $DEVICE_SESSION > $DEVMGR_PIPE
	fi

	# Tell the smartcard subsystem about this session.
	$UTSCREVENT -c $DPY -z $TAG

    fi

exit 0
