Cover V04, I04
Article
Listing 1
Listing 2

jul95.tar


Listing 1: closeit: The login management script

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
en 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