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
|