updated on Fri Jan 20 04:00:45 UTC 2012
[aur-mirror.git] / selinux-shadow / adduser
bloba5d7fd4fa2a48869389641ecbd49915d44e7aa88
1 #!/bin/bash
3 # Copyright 1995 Hrvoje Dogan, Croatia.
4 # Copyright 2002, 2003, 2004 Stuart Winter, West Midlands, England, UK.
5 # Copyright 2004 Slackware Linux, Inc., Concord, CA, USA
6 # All rights reserved.
8 # Redistribution and use of this script, with or without modification, is
9 # permitted provided that the following conditions are met:
11 # 1. Redistributions of this script must retain the above copyright
12 # notice, this list of conditions and the following disclaimer.
14 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
17 # EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
18 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
20 # OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
21 # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
22 # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
23 # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 ##########################################################################
27 # Program: /usr/sbin/adduser
28 # Purpose: Interactive front end to /usr/sbin/useradd for Slackware Linux
29 # Author : Stuart Winter <stuart@polplex.co.uk>
30 # Based on the original Slackware adduser by Hrvoje Dogan
31 # with modifications by Patrick Volkerding
32 # Version: 1.09
33 ##########################################################################
34 # Usage..: adduser [<new_user_name>]
35 ##########################################################################
36 # History #
37 ###########
38 # v1.09 - 07/06/04
39 # * Added standard Slackware script licence to the head of this file.
40 # v1.08 - 25/04/04
41 # * Disallow user names that begin with a numeric because useradd
42 # (from shadow v4.03) does not allow them. <sw>
43 # v1.07 - 07/03/03
44 # * When supplying a null string for the uid (meaning 'Choose next available'),
45 # if there were file names in the range 'a-z' in the pwd then the
46 # egrep command considered these files rather than the null string.
47 # The egrep expression is now in quotes.
48 # Reported & fixed by Vadim O. Ustiansky <sw>
49 # v1.06 - 31/03/03
50 # * Ask to chown user.group the home directory if it already exists.
51 # This helps reduce later confusion when adding users whose home dir
52 # already exists (mounted partition for example) and is owned
53 # by a user other than the user to which the directory is being
54 # assigned as home. Default is not to chown.
55 # Brought to my attention by mRgOBLIN. <sw>
56 # v1.05 - 04/01/03
57 # * Advise & prevent users from creating logins with '.' characters
58 # in the user name. <sw>
59 # * Made pending account creation info look neater <sw>
60 # v1.04 - 09/06/02
61 # * Catered for shadow-4.0.3's 'useradd' binary that no longer
62 # will let you create a user that has any uppercase chars in it
63 # This was reported on the userlocal.org forums
64 # by 'xcp' - thanks. <sw,pjv>
65 # v1.03 - 20/05/02
66 # * Support 'broken' (null lines in) /etc/passwd and
67 # /etc/group files <sw>
68 # * For recycling UIDs (default still 'off'), we now look in
69 # /etc/login.defs for the UID_MIN value and use it
70 # If not found then default to 1000 <sw>
71 # v1.02 - 10/04/02
72 # * Fix user-specified UID bug. <pjv>
73 # v1.01 - 23/03/02
74 # * Match Slackware indenting style, simplify. <pjv>
75 # v1.00 - 22/03/02
76 # * Created
77 #######################################################################
79 # Path to files
80 pfile=/etc/passwd
81 gfile=/etc/group
82 sfile=/etc/shells
84 # Paths to binaries
85 useradd=/usr/sbin/useradd
86 chfn=/usr/bin/chfn
87 passwd=/usr/bin/passwd
89 # Defaults
90 defhome=/home
91 defshell=/bin/bash
92 defgroup=users
94 # Determine what the minimum UID is (for UID recycling)
95 # (we ignore it if it's not at the beginning of the line (i.e. commented out with #))
96 export recycleUIDMIN="$(grep ^UID_MIN /etc/login.defs | awk '{print $2}' 2>/dev/null)"
97 # If we couldn't find it, set it to the default of 1000
98 if [ -z "$recycleUIDMIN" ]; then
99 export recycleUIDMIN=1000 # this is the default from Slackware's /etc/login.defs
103 # This setting enables the 'recycling' of older unused UIDs.
104 # When you userdel a user, it removes it from passwd and shadow but it will
105 # never get used again unless you specify it expliticly -- useradd (appears to) just
106 # look at the last line in passwd and increment the uid. I like the idea of
107 # recycling uids but you may have very good reasons not to (old forgotten
108 # confidential files still on the system could then be owned by this new user).
109 # We'll set this to no because this is what the original adduser shell script
110 # did and it's what users expect.
111 recycleuids=no
113 # Function to read keyboard input.
114 # bash1 is broken (even ash will take read -ep!), so we work around
115 # it (even though bash1 is no longer supported on Slackware).
116 function get_input() {
117 local output
118 if [ "`echo $BASH_VERSION | cut -b1`" = "1" ]; then
119 echo -n "${1} " >&2 # fudge for use with bash v1
120 read output
121 else # this should work with any other /bin/sh
122 read -ep "${1} " output
124 echo $output
127 # Function to display the account info
128 function display () {
129 local goose
130 goose="$(echo $2 | cut -d ' ' -f 2-)" # lop off the prefixed argument useradd needs
131 echo -n "$1 "
132 # If it's null then display the 'other' information
133 if [ -z "$goose" -a ! -z "$3" ]; then
134 echo "$3"
135 else
136 echo "$goose"
140 # Function to check whether groups exist in the /etc/group file
141 function check_group () {
142 local got_error group
143 if [ ! -z "$@" ]; then
144 for group in $@ ; do
145 local uid_not_named="" uid_not_num=""
146 grep -v "$^" $gfile | awk -F: '{print $1}' | grep "^${group}$" >/dev/null 2>&1 || uid_not_named=yes
147 grep -v "$^" $gfile | awk -F: '{print $3}' | grep "^${group}$" >/dev/null 2>&1 || uid_not_num=yes
148 if [ ! -z "$uid_not_named" -a ! -z "$uid_not_num" ]; then
149 echo "- Group '$group' does not exist"
150 got_error=yes
152 done
154 # Return exit code of 1 if at least one of the groups didn't exist
155 if [ ! -z "$got_error" ]; then
156 return 1
160 #: Read the login name for the new user :#
162 # Remember that most Mail Transfer Agents are case independant, so having
163 # 'uSer' and 'user' may cause confusion/things to break. Because of this,
164 # useradd from shadow-4.0.3 no longer accepts usernames containing uppercase,
165 # and we must reject them, too.
167 # Set the login variable to the command line param
168 echo
169 LOGIN="$1"
170 needinput=yes
171 while [ ! -z $needinput ]; do
172 if [ -z "$LOGIN" ]; then
173 while [ -z "$LOGIN" ]; do LOGIN="$(get_input "Login name for new user []:")" ; done
175 grep "^${LOGIN}:" $pfile >/dev/null 2>&1 # ensure it's not already used
176 if [ $? -eq 0 ]; then
177 echo "- User '$LOGIN' already exists; please choose another"
178 unset LOGIN
179 elif [ ! -z "$( echo $LOGIN | grep "^[0-9]" )" ]; then
180 echo "- User names cannot begin with a number; please choose another"
181 unset LOGIN
182 elif [ ! "$LOGIN" = "`echo $LOGIN | tr A-Z a-z`" ]; then # useradd does not allow uppercase
183 echo "- User '$LOGIN' contains illegal characters (uppercase); please choose another"
184 unset LOGIN
185 elif [ ! -z "$( echo $LOGIN | grep '\.' )" ]; then
186 echo "- User '$LOGIN' contains illegal characters (period/dot); please choose another"
187 unset LOGIN
188 else
189 unset needinput
191 done
193 # Display the user name passed from the shell if it hasn't changed
194 if [ "$1" = "$LOGIN" ]; then
195 echo "Login name for new user: $LOGIN"
198 #: Get the UID for the user & ensure it's not already in use :#
200 # Whilst we _can_ allow users with identical UIDs, it's not a 'good thing' because
201 # when you change password for the uid, it finds the first match in /etc/passwd
202 # which isn't necessarily the correct user
204 echo
205 needinput=yes
206 while [ ! -z "$needinput" ]; do
207 _UID="$(get_input "User ID ('UID') [ defaults to next available ]:")"
208 grep -v "^$" $pfile | awk -F: '{print $3}' | grep "^${_UID}$" >/dev/null 2>&1
209 if [ $? -eq 0 ]; then
210 echo "- That UID is already in use; please choose another"
211 elif [ ! -z "$(echo $_UID | egrep '[A-Za-z]')" ]; then
212 echo "- UIDs are numerics only"
213 else
214 unset needinput
216 done
217 # If we were given a UID, then syntax up the variable to pass to useradd
218 if [ ! -z "$_UID" ]; then
219 U_ID="-u ${_UID}"
220 else
221 # Will we be recycling UIDs?
222 if [ "$recycleuids" = "yes" ]; then
223 U_ID="-u $(awk -F: '{uid[$3]=1} END { for (i=ENVIRON["recycleUIDMIN"];i in uid;i++);print i}' $pfile)"
227 #: Get the initial group for the user & ensure it exists :#
229 # We check /etc/group for both the text version and the group ID number
230 echo
231 needinput=yes
232 while [ ! -z "$needinput" ]; do
233 GID="$(get_input "Initial group [ ${defgroup} ]:")"
234 check_group "$GID"
235 if [ $? -gt 0 ]; then
236 echo "- Please choose another"
237 else
238 unset needinput
240 done
241 # Syntax the variable ready for useradd
242 if [ -z "$GID" ]; then
243 GID="-g ${defgroup}"
244 else
245 GID="-g ${GID}"
248 #: Get additional groups for the user :#
250 echo
251 needinput=yes
252 while [ ! -z "$needinput" ]; do
253 AGID="$(get_input "Additional groups (comma separated) []:")"
254 AGID="$(echo "$AGID" | tr -d ' ' | tr , ' ')" # fix up for parsing
255 if [ ! -z "$AGID" ]; then
256 check_group "$AGID" # check all groups at once (treated as N # of params)
257 if [ $? -gt 0 ]; then
258 echo "- Please re-enter the group(s)"
259 else
260 unset needinput # we found all groups specified
261 AGID="-G $(echo "$AGID" | tr ' ' ,)"
263 else
264 unset needinput # we don't *have* to have additional groups
266 done
268 #: Get the new user's home dir :#
270 echo
271 needinput=yes
272 while [ ! -z "$needinput" ]; do
273 HME="$(get_input "Home directory [ ${defhome}/${LOGIN} ]")"
274 if [ -z "$HME" ]; then
275 HME="${defhome}/${LOGIN}"
277 # Warn the user if the home dir already exists
278 if [ -d "$HME" ]; then
279 echo "- Warning: '$HME' already exists !"
280 getyn="$(get_input " Do you wish to change the home directory path ? (Y/n) ")"
281 if [ "$(echo $getyn | grep -i "n")" ]; then
282 unset needinput
283 # You're most likely going to only do this if you have the dir *mounted* for this user's $HOME
284 getyn="$(get_input " Do you want to chown $LOGIN.$( echo $GID | awk '{print $2}') $HME ? (y/N) ")"
285 if [ "$(echo $getyn | grep -i "y")" ]; then
286 CHOWNHOMEDIR=$HME # set this to the home directory
289 else
290 unset needinput
292 done
293 HME="-d ${HME}"
295 #: Get the new user's shell :#
296 echo
297 needinput=yes
298 while [ ! -z "$needinput" ]; do
299 unset got_error
300 SHL="$(get_input "Shell [ ${defshell} ]")"
301 if [ -z "$SHL" ]; then
302 SHL="${defshell}"
304 # Warn the user if the shell doesn't exist in /etc/shells or as a file
305 if [ -z "$(grep "^${SHL}$" $sfile)" ]; then
306 echo "- Warning: ${SHL} is not in ${sfile} (potential problem using FTP)"
307 got_error=yes
309 if [ ! -f "$SHL" ]; then
310 echo "- Warning: ${SHL} does not exist as a file"
311 got_error=yes
313 if [ ! -z "$got_error" ]; then
314 getyn="$(get_input " Do you wish to change the shell ? (Y/n) ")"
315 if [ "$(echo $getyn | grep -i "n")" ]; then
316 unset needinput
318 else
319 unset needinput
321 done
322 SHL="-s ${SHL}"
324 #: Get the expiry date :#
325 echo
326 needinput=yes
327 while [ ! -z "$needinput" ]; do
328 EXP="$(get_input "Expiry date (YYYY-MM-DD) []:")"
329 if [ ! -z "$EXP" ]; then
330 # Check to see whether the expiry date is in the valid format
331 if [ -z "$(echo "$EXP" | grep "^[[:digit:]]\{4\}[-]\?[[:digit:]]\{2\}[-]\?[[:digit:]]\{2\}$")" ]; then
332 echo "- That is not a valid expiration date"
333 else
334 unset needinput
335 EXP="-e ${EXP}"
337 else
338 unset needinput
340 done
342 # Display the info about the new impending account
343 echo
344 echo "New account will be created as follows:"
345 echo
346 echo "---------------------------------------"
347 display "Login name.......: " "$LOGIN"
348 display "UID..............: " "$_UID" "[ Next available ]"
349 display "Initial group....: " "$GID"
350 display "Additional groups: " "$AGID" "[ None ]"
351 display "Home directory...: " "$HME"
352 display "Shell............: " "$SHL"
353 display "Expiry date......: " "$EXP" "[ Never ]"
354 echo
356 echo "This is it... if you want to bail out, hit Control-C. Otherwise, press"
357 echo "ENTER to go ahead and make the account."
358 read junk
360 echo
361 echo "Creating new account..."
362 echo
363 echo
365 # Add the account to the system
366 CMD="$useradd "$HME" -m "$EXP" "$U_ID" "$GID" "$AGID" "$SHL" "$LOGIN""
367 $CMD
369 if [ $? -gt 0 ]; then
370 echo "- Error running useradd command -- account not created!"
371 echo "(cmd: $CMD)"
372 exit 1
375 # chown the home dir ? We can only do this once the useradd has
376 # completed otherwise the user name doesn't exist.
377 if [ ! -z "${CHOWNHOMEDIR}" ]; then
378 chown "$LOGIN"."$( echo $GID | awk '{print $2}')" "${CHOWNHOMEDIR}"
381 # Set the finger information
382 $chfn "$LOGIN"
383 if [ $? -gt 0 ]; then
384 echo "- Warning: an error occurred while setting finger information"
387 # Set a password
388 $passwd "$LOGIN"
389 if [ $? -gt 0 ]; then
390 echo "* WARNING: An error occured while setting the password for"
391 echo " this account. Please manually investigate this *"
392 exit 1
395 echo
396 echo
397 echo "Account setup complete."
398 exit 0