  1 #!/bin/ksh
  2 :
  3 ## closeit: a Korn shell to let a system
  4 ## administrator readily disable logins to one or
  5 ## more accounts and display a message to the
  6 ## account users.
  7 
  8 # exit quietly if we aren't root
  9 
 10 id|grep 'uid=0' >&- || exit 2		
 11 
 12 # Files we create here are writeable
 13 # only by root
 14 
 15 umask 033
 16 
 17 ### Set up initial environment
 18 
 19 # Note: FLAGFILE is set in /etc/profile
 20 set -a
 21 ORGARGS=$*
 22 # Working directory
 23 WORKDIR=/nowrite
 24 # For storing our home directory list
 25 DIRECLIST=${WORKDIR}/direclist
 26 # File for manipulating our user message
 27 MSGTEMPLATE=${WORKDIR}/msgtmp.closeit
 28 export MSGTEMPLATE
 29 # Our shell
 30 C_SHELL=/bin/ksh
 31 # Preferred editor
 32 C_EDITOR=/usr/bin/joe
 33 PROGNAME=`basename $0`
 34 EOFKEY=Ctrl-D
 35 # For initial display purposes
 36 USERNAME='$USERNAME'	
 37 OPENTIME='$OPENTIME'
 38 
 39 ### The Usage routine reports command syntax
 40 ### and other information
 41 
 42 Usage()
 43 {
 44 if [ "$PROGNAME" = "closeit" ]
 45 then
 46   cat << !!!
 47 
 48   ${PROGNAME} [all] [who] [?]
 49 
 50   $PROGNAME disables logins for usernames
 51   specified, which are read interactively. The
 52   "all" option operates on all users listed in
 53   $DIRECLIST.  The "who" option displays all
 54   user accounts currently disabled.  The "?"
 55   option displays this message.  The current
 56   contents of $DIRECLIST are:
 57 
 58 !!!
 59   cat $DIRECLIST;echo
 60 fi
 61 
 62 if [ "$PROGNAME" = openit ]
 63 then
 64   cat <<+++
 65 
 66   $PROGNAME [all]
 67 
 68   ${PROGNAME} reopens any accounts closed by
 69   closeit (to which it is linked), reporting on
 70   each action it takes.  If the keyword "all"
 71   is not used it takes input from standard
 72   input.
 73 
 74 +++
 75 fi
 76 exit 0
 77 }
 78 
 79 ### The Getusers routine uses /etc/passwd to
 80 ### build a list of current users and their
 81 ### home directories
 82 
 83 Getusers()
 84 {
 85 DIRECLIST 2>/dev/null  # Initialize our name file
 86 OLDIFS=$IFS	           # Save old IFS
 87 IFS=':'		   # Set IFS for /etc/passwd
 88 
 89 # Select /etc/passwd lines ending in 'sh,' set
 90 # the elements of each line to positional
 91 # parameters, store $1 and $6 in our name-
 92 # home directory file ($DIRECLIST).  Modify
 93 # to fit your needs, but be sure you don't
 94 # close root.
 95 
 96 grep '.*sh *$' /etc/passwd|while read line
 97 do
 98 set -f - $line
 99 [ "$6" ] && [ "$7" ] && [ ! "$1" = "root" ] && \
100 [ ! "$1" = "sysnews" ] && \
101 echo "$1\t$6" >> $DIRECLIST
102 done
103 IFS=$OLDIFS	  # Restore old IFS
104 set -- $ORGARGS	  # Restore old arguments
105 }
106 
107 ### The MakeMessage routine selects the current
108 ### default message to be presented to the user or
109 ### lets the system administrator make a new one
110 
111 MakeMessage()
112 {
113 cat <<@@@ > $MSGTEMPLATE
114 
115   Sorry, account ${USERNAME} is temporarily
116   closed for maintenance.
117 		
118   It should be available again about ${OPENTIME}.
119 
120 	    (Press <ENTER>)
121 @@@
122 
123 
124 ANSWER=v
125 while [ "$ANSWER" = "v" -o "$ANSWER" = "y" ]
126 do
127   tput clear
128   echo "\n\n\tYou can use a default message \
129 or compose one now."
130   echo "\tOr enter 'v' to view the current \
131 message."
132   echo "\n\tDo you want to compose a new \
133 message? (y/n/v) \c"
134   read ANSWER
135 
136   case $ANSWER in
137   Y|y* )
138     ANSWER=y
139     $C_EDITOR $MSGTEMPLATE
140   ;;
141 
142   V|v* )
143     ANSWER=v
144     tput clear
145     cat $MSGTEMPLATE
146     echo "\n\n[[ Press <Enter> to return ]]"
147     read NUL
148   ;;
149 
150   * )
151     tput clear
152   ;;
153   esac
154 
155 done
156 }
157 
158 ### WriteMessage tests the validity of the supplied
159 ### user name and writes the flag file to his home
160 ### directory
161 
162 WriteMessage()
163 {
164 
165 # Match the user's input with leading characters
166 # in $DIRECLIST
167 
168 eval grep \'\^${USERNAME}\' ${DIRECLIST} | \
169 read USER HOMEDIR
170 if [ "$USER" ]
171 then
172 
173 # Build a 'here document' to wrap up the user's
174 # displayed message and write it to the correct
175 # home directory
176 
177   (echo 'cat << %%%';cat $MSGTEMPLATE;echo;echo '%%%')|\
178    ${C_SHELL} > ${HOMEDIR}/$FLAGFILE 2>&-
179 else
180   echo "\n\tInvalid user name: ${USERNAME}"
181 fi
182 }
183 
184 ### ListWho lists all users whose logins are
185 ### currently disabled
186 
187 ListWho()
188 {
189 echo "\n\tAccounts now closed:"
190 while read USERNAME HOMEDIR
191 do
192   [ -f ${HOMEDIR}/$FLAGFILE ] && echo "\t\t$USERNAME"
193 done < $DIRECLIST
194 }
195 
196 ### GoAhead lets the user back out, otherwise takes
197 ### input as to reopening time for the account
198 
199 GoAhead()
200 {
201 echo "\n\tPreparing to close user accounts."
202 echo "\tDo you want to continue? (y/n) \c"
203 read ANSWER
204 case $ANSWER in
205 y|Y* )
206   if grep OPENTIME $MSGTEMPLATE >&-
207   then
208     echo "\tTime to reopen: \c"
209     read OPENTIME; export OPENTIME
210   fi
211 ;;
212 
213 *   )
214   exit 1
215 ;;
216 esac
217 }
218 
219 ########################
220 #                      #
221 # Main line of program #
222 #                      #
223 ########################
224 
225 tput clear
226 
227 # Maximum one parameter
228 
229 [ $# -gt 1 -o "$1" = '?' ] && Usage	
230 
231 # The script can be invoked as 'closeit'
232 # or 'openit'
233 
234 case $PROGNAME in
235 closeit )
236   if [ "$1" ]
237   then
238     case $1 in
239     who )
240       Getusers
241       ListWho
242       exit 0
243     ;;
244     all )
245       Getusers
246       MakeMessage
247       GoAhead
248       while read USERNAME HOMEDIR
249       do
250         export USERNAME
251         WriteMessage
252       done < $DIRECLIST
253       ListWho
254       exit 0
255     ;;
256     *   )
257       Usage
258     ;;
259     esac
260   else
261     Getusers
262     MakeMessage
263     GoAhead
264     echo "\n\tEnter account names \
265 (${EOFKEY} when done):"
266     while read USERNAME
267     do
268       if [ "$USERNAME" ]
269       then
270         export USERNAME
271         WriteMessage
272       fi
273     done
274     ListWho
275     exit 0
276   fi
277 ;;
278 
279 openit )
280 
281   # If $1 is 'all' redirect input from $DIRECLIST,
282   # otherwise prepare to take a list of accounts
283   # from standard input
284 
285   [ "$1" = "all" ] && exec <$DIRECLIST || \
286   echo "\n\tEnter account names \
287 (${EOFKEY} when done):"
288 
289   while read USR HDIR
290   do
291   if [ "$USR" ]
292   then
293     USERNAME=`eval grep \'\^$USR\' ${DIRECLIST}|cut -f1`
294     if [ ! "$USERNAME" ]
295     then
296       echo "\tInvalid username: $USR"
297     else
298       HOMEDIR=${HDIR:-`eval grep \'\^$USR\' \
299       ${DIRECLIST}|cut -f2`}
300       if [ -f ${HOMEDIR}/${FLAGFILE} ]
301       then
302         rm -f ${HOMEDIR}/${FLAGFILE}
303         if [ $? = 0 ]
304         then
305           echo "\t$USERNAME opened"
306         else
307           echo "\tOpen failed for ${USERNAME}"
308         fi
309       else
310         echo "\t$USERNAME not closed"
311       fi
312     fi
313   fi
314   done
315   ListWho
316 ;;
317 
318 esac
