#!/bin/pfksh -p # # CDDL HEADER START # # The contents of this file are subject to the terms of the # Common Development and Distribution License (the "License"). # You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. # See the License for the specific language governing permissions # and limitations under the License. # # When distributing Covered Code, include this CDDL HEADER in each # file and include the License file at usr/src/OPENSOLARIS.LICENSE. # If applicable, add the following below this CDDL HEADER, with the # fields enclosed by brackets "[]" replaced with your own identifying # information: Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END # # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # # See http://blogs.sun.com/chrisg/tags/access_hours # ACCESS_FILE=/etc/opt/local/access_hours AUDIO=/usr/demo/SOUND/sounds/computer.au PATH=/opt/SUNWut/bin:/usr/bin:/usr/sbin:/opt/SUNWut/sbin # # CRONMIN is the minute of the hour when the cronjob that checks the # cronjob will run. # CRONMIN=$(date +%M) # # AT_DELAY is the string that is passed to as "at now + $AT_DELAY" so that # the job that clears the DTU from the ip filter is delayed long enough # for the DTU to reset but not so long as to be really irritating. # AT_DELAY="2 min" # # SLEEP_SECONDS is the number of seconds warning the user gets if they are # currently logged in when the script decides they our out of hours. # SLEEP_SECONDS=30 # # Turn of globbing so that any wild cards for times in the access file # don't get turned into the contents of the cwd. # set -o noglob if ! [[ -f $ACCESS_FILE ]] then ACCESS_FILE=/dev/null fi function log { logger -t check_access -p daemon.notice $@ } # # time2mins. Take a 24 hour time in format HHMM and return the minute # of the day. # function time2mins { typeset -i10 i i=$1 print $(((i/100)*60 + i%100)) } function out_of_hour { typeset -i n=$(time2mins $(date +%H%M)) typeset -i s=$(time2mins $1) typeset -i e=$(time2mins $2) if (( s < e)) then if (( n < s || n >= e)) then return 0 fi else if (( n < s && n >= e)) then return 0 fi fi return 1 } function write_crontab { while getopts d name do case $name in d) print '1,$d' ;; esac done shift $(($OPTIND - 1)) typeset IFS=": ${IFS}" print 'a' print "TZ=$TZ" print "$CRONMIN * * * * $1 -t ${SLEEP_SECONDS} ${verbose:+-x }-c $2" while read user day start end dtu do [[ ${user} != ${user#\#} ]] && continue typeset -Z2 m=$((end % 100)) typeset -Z2 h=$((end / 100)) print "$m $h * * $day $1 -t ${SLEEP_SECONDS} ${verbose:+-x }$user" done < $ACCESS_FILE print '.' print 'w' print 'q' print 'q' return 0 } function check_dtu { typeset dtu typeset IFS=", $IFS" [[ "$1" == "" ]] && return 0 for dtu in $1 do [[ $dtu == $DTU ]] && return 0 done return 1 } function check_day { typeset -i today=$(date +%w) if [[ $1 == '*' ]] || \ ( [[ ${1##*,} == $1 ]] && \ (( ${1%-*} <= today )) && (( ${1#*-} >= today )) ) then return 0 elif [[ ${1##*,} != $1 ]] && \ ( check_day ${1##*,} || check_day ${1%,*} ) then return 0 else return 1 fi } function out_of_hours { typeset x=1 typeset IFS=": $IFS" while read user day start end dtu do if [[ $user == $1 ]] && check_day $day check_dtu $dtu then out_of_hour $start $end x=$? break fi done < $ACCESS_FILE return $x } function check_user { typeset ret=0; typeset display token user address dtu /opt/SUNWut/bin/utwho -c | while read display token user address dtu do if [[ $user == $1 ]] then print $address DTU=$dtu ret=1 fi done return $ret } function block_user { typeset address address=$(check_user $1) if [[ $? == 1 ]] then if (( ${SLEEP_SECONDS} != 0 )) then utwall ${AUDIO:+-a ${AUDIO} }-d -t "$(date)\nThis Unit will detach in $SLEEP_SECONDS seconds." $1 sleep $SLEEP_SECONDS address=$(check_user $1) if [[ $? == 0 ]] then log "User accepted warning $1" return fi fi log blocking $address due to user $1 print block in from $address | ipf -f - if (( $? == 0 )) then at -k now + ${AT_DELAY:-2 min} 2> /dev/null << EOF print block in from $address | ipf -r -f - EOF fi return 0 fi } while getopts xcdt:D: name do case $name in c) do_cron=1 ;; d) detach=1 ;; D) DTU=$OPTARG ;; t) SLEEP_SECONDS=$OPTARG ;; x) verbose=1; set -x; functions | while read x name do typeset -ft $name done esac done shift $(($OPTIND - 1)) if (( ${do_cron:-0} == 1 )) then user=${1:-${LOGNAME}} if crontab -l $user > /dev/null 2>&1 then delete=-d fi write_crontab "$delete" $0 $user | EDITOR=/usr/bin/ed crontab -e $user > /dev/null exit $? fi check_user $1 if out_of_hours $1 || [[ ${detach:-0} == 1 ]] then block_user $1 exit 1 fi exit 0