source: npl/system/shadow/adduser @ 0105685

gcc484ntopperl-5.22
Last change on this file since 0105685 was c5c522c, checked in by Edwin Eefting <edwin@datux.nl>, 8 years ago

initial commit, transferred from cleaned syn3 svn tree

  • Property mode set to 100755
File size: 13.6 KB
Line 
1#!/bin/bash
2#
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.
7#
8# Redistribution and use of this script, with or without modification, is
9# permitted provided that the following conditions are met:
10#
11# 1. Redistributions of this script must retain the above copyright
12#    notice, this list of conditions and the following disclaimer.
13#
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.
24#
25#
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#######################################################################
78
79# Path to files
80pfile=/etc/passwd
81gfile=/etc/group
82sfile=/etc/shells
83
84# Paths to binaries
85useradd=/usr/sbin/useradd
86chfn=/usr/bin/chfn
87passwd=/usr/bin/passwd
88chmod=/bin/chmod
89
90# Defaults
91defhome=/home
92defshell=/bin/bash
93defchmod=711 # home dir permissions - may be preferable to use 701, however.
94defgroup=users
95
96# Determine what the minimum UID is (for UID recycling)
97# (we ignore it if it's not at the beginning of the line (i.e. commented out with #))
98export recycleUIDMIN="$(grep ^UID_MIN /etc/login.defs | awk '{print $2}' 2>/dev/null)"
99# If we couldn't find it, set it to the default of 1000
100if [ -z "$recycleUIDMIN" ]; then
101   export recycleUIDMIN=1000  # this is the default from Slackware's /etc/login.defs
102fi
103
104
105# This setting enables the 'recycling' of older unused UIDs.
106# When you userdel a user, it removes it from passwd and shadow but it will
107# never get used again unless you specify it expliticly -- useradd (appears to) just
108# look at the last line in passwd and increment the uid.  I like the idea of
109# recycling uids but you may have very good reasons not to (old forgotten
110# confidential files still on the system could then be owned by this new user).
111# We'll set this to no because this is what the original adduser shell script
112# did and it's what users expect.
113recycleuids=no
114
115# Function to read keyboard input.
116# bash1 is broken (even ash will take read -ep!), so we work around
117# it (even though bash1 is no longer supported on Slackware).
118function get_input() {
119  local output
120  if [ "`echo $BASH_VERSION | cut -b1`" = "1" ]; then
121    echo -n "${1} " >&2 # fudge for use with bash v1
122    read output
123  else # this should work with any other /bin/sh
124    read -ep "${1} " output
125  fi
126  echo $output
127}
128
129# Function to display the account info
130function display () {
131  local goose
132  goose="$(echo $2 | cut -d ' ' -f 2-)"  # lop off the prefixed argument useradd needs
133  echo -n "$1 "
134  # If it's null then display the 'other' information
135  if [ -z "$goose" -a ! -z "$3" ]; then
136    echo "$3"
137  else
138    echo "$goose"
139  fi
140}
141
142# Function to check whether groups exist in the /etc/group file
143function check_group () {
144  local got_error group
145  if [ ! -z "$@" ]; then 
146  for group in $@ ; do
147    local uid_not_named="" uid_not_num=""
148    grep -v "$^" $gfile | awk -F: '{print $1}' | grep "^${group}$" >/dev/null 2>&1 || uid_not_named=yes 
149    grep -v "$^" $gfile | awk -F: '{print $3}' | grep "^${group}$" >/dev/null 2>&1 || uid_not_num=yes
150    if [ ! -z "$uid_not_named" -a ! -z "$uid_not_num" ]; then
151      echo "- Group '$group' does not exist"
152      got_error=yes
153    fi
154  done
155  fi
156  # Return exit code of 1 if at least one of the groups didn't exist
157  if [ ! -z "$got_error" ]; then
158    return 1
159  fi
160}   
161
162#: Read the login name for the new user :#
163#
164# Remember that most Mail Transfer Agents are case independant, so having
165# 'uSer' and 'user' may cause confusion/things to break.  Because of this,
166# useradd from shadow-4.0.3 no longer accepts usernames containing uppercase,
167# and we must reject them, too.
168
169# Set the login variable to the command line param
170echo
171LOGIN="$1"
172needinput=yes
173while [ ! -z $needinput ]; do
174  if [ -z "$LOGIN" ]; then
175    while [ -z "$LOGIN" ]; do LOGIN="$(get_input "Login name for new user []:")" ; done
176  fi
177  grep "^${LOGIN}:" $pfile >/dev/null 2>&1  # ensure it's not already used
178  if [ $? -eq 0 ]; then
179    echo "- User '$LOGIN' already exists; please choose another"
180    unset LOGIN
181  elif [ ! -z "$( echo $LOGIN | grep "^[0-9]" )" ]; then
182    echo "- User names cannot begin with a number; please choose another"
183    unset LOGIN
184  elif [ ! "$LOGIN" = "`echo $LOGIN | tr A-Z a-z`" ]; then # useradd does not allow uppercase
185    echo "- User '$LOGIN' contains illegal characters (uppercase); please choose another"
186    unset LOGIN
187  elif [ ! -z "$( echo $LOGIN | grep '\.' )" ]; then
188    echo "- User '$LOGIN' contains illegal characters (period/dot); please choose another"
189    unset LOGIN
190  else
191    unset needinput
192  fi
193done
194
195# Display the user name passed from the shell if it hasn't changed
196if [ "$1" = "$LOGIN" ]; then
197  echo "Login name for new user: $LOGIN"
198fi
199
200#: Get the UID for the user & ensure it's not already in use :#
201#
202# Whilst we _can_ allow users with identical UIDs, it's not a 'good thing' because
203# when you change password for the uid, it finds the first match in /etc/passwd
204# which isn't necessarily the correct user
205#
206echo
207needinput=yes
208while [ ! -z "$needinput" ]; do
209  _UID="$(get_input "User ID ('UID') [ defaults to next available ]:")"
210  grep -v "^$" $pfile | awk -F: '{print $3}' | grep "^${_UID}$" >/dev/null 2>&1
211  if [ $? -eq 0 ]; then
212    echo "- That UID is already in use; please choose another"
213  elif [ ! -z "$(echo $_UID | egrep '[A-Za-z]')" ]; then
214    echo "- UIDs are numerics only"         
215  else
216    unset needinput
217  fi
218done
219# If we were given a UID, then syntax up the variable to pass to useradd
220if [ ! -z "$_UID" ]; then
221  U_ID="-u ${_UID}"
222else
223  # Will we be recycling UIDs?
224  if [ "$recycleuids" = "yes" ]; then
225    U_ID="-u $(awk -F: '{uid[$3]=1} END { for (i=ENVIRON["recycleUIDMIN"];i in uid;i++);print i}' $pfile)"
226  fi   
227fi
228
229#: Get the initial group for the user & ensure it exists :#
230#
231# We check /etc/group for both the text version and the group ID number
232echo
233needinput=yes
234while [ ! -z "$needinput" ]; do
235  GID="$(get_input "Initial group [ ${defgroup} ]:")"
236  check_group "$GID"
237  if [ $? -gt 0 ]; then
238    echo "- Please choose another"
239  else
240    unset needinput
241  fi
242done
243# Syntax the variable ready for useradd
244if [ -z "$GID" ]; then
245  GID="-g ${defgroup}"
246else
247  GID="-g ${GID}"
248fi
249
250#: Get additional groups for the user :#
251#
252echo
253needinput=yes
254while [ ! -z "$needinput" ]; do
255  AGID="$(get_input "Additional groups (comma separated) []:")"
256  AGID="$(echo "$AGID" | tr -d ' ' | tr , ' ')" # fix up for parsing
257  if [ ! -z "$AGID" ]; then
258    check_group "$AGID"  # check all groups at once (treated as N # of params)
259    if [ $? -gt 0 ]; then
260      echo "- Please re-enter the group(s)"
261    else
262      unset needinput # we found all groups specified
263      AGID="-G $(echo "$AGID" | tr ' ' ,)"
264    fi
265  else
266    unset needinput   # we don't *have* to have additional groups
267  fi
268done
269
270#: Get the new user's home dir :#
271#       
272echo
273needinput=yes
274while [ ! -z "$needinput" ]; do
275  HME="$(get_input "Home directory [ ${defhome}/${LOGIN} ]")"
276  if [ -z "$HME" ]; then
277    HME="${defhome}/${LOGIN}"
278  fi
279  # Warn the user if the home dir already exists
280  if [ -d "$HME" ]; then
281    echo "- Warning: '$HME' already exists !"
282    getyn="$(get_input "  Do you wish to change the home directory path ? (Y/n) ")"
283    if [ "$(echo $getyn | grep -i "n")" ]; then
284      unset needinput
285      # You're most likely going to only do this if you have the dir *mounted* for this user's $HOME
286      getyn="$(get_input "  Do you want to chown $LOGIN.$( echo $GID | awk '{print $2}') $HME ? (y/N) ")"
287      if [ "$(echo $getyn | grep -i "y")" ]; then
288         CHOWNHOMEDIR=$HME # set this to the home directory
289      fi
290    fi
291  else
292    unset needinput
293  fi
294done           
295HME="-d ${HME}" 
296   
297#: Get the new user's shell :#
298echo
299needinput=yes
300while [ ! -z "$needinput" ]; do
301  unset got_error
302  SHL="$(get_input "Shell [ ${defshell} ]")"
303  if [ -z "$SHL" ]; then
304    SHL="${defshell}"
305  fi
306  # Warn the user if the shell doesn't exist in /etc/shells or as a file
307  if [ -z "$(grep "^${SHL}$" $sfile)" ]; then
308    echo "- Warning: ${SHL} is not in ${sfile} (potential problem using FTP)"
309    got_error=yes
310  fi
311  if [ ! -f "$SHL" ]; then
312    echo "- Warning: ${SHL} does not exist as a file"
313    got_error=yes
314  fi
315  if [ ! -z "$got_error" ]; then
316    getyn="$(get_input "  Do you wish to change the shell ? (Y/n) ")"
317    if [ "$(echo $getyn | grep -i "n")" ]; then
318      unset needinput
319    fi
320  else
321    unset needinput
322  fi
323done           
324SHL="-s ${SHL}"
325
326#: Get the expiry date :#
327echo
328needinput=yes
329while [ ! -z "$needinput" ]; do
330  EXP="$(get_input "Expiry date (YYYY-MM-DD) []:")"
331  if [ ! -z "$EXP" ]; then
332    # Check to see whether the expiry date is in the valid format
333    if [ -z "$(echo "$EXP" | grep "^[[:digit:]]\{4\}[-]\?[[:digit:]]\{2\}[-]\?[[:digit:]]\{2\}$")" ]; then
334      echo "- That is not a valid expiration date"
335    else
336      unset needinput
337      EXP="-e ${EXP}"
338    fi
339  else
340    unset needinput
341  fi
342done
343
344# Display the info about the new impending account
345echo
346echo "New account will be created as follows:"
347echo
348echo "---------------------------------------"
349display "Login name.......: " "$LOGIN"
350display "UID..............: " "$_UID" "[ Next available ]"
351display "Initial group....: " "$GID"
352display "Additional groups: " "$AGID" "[ None ]"
353display "Home directory...: " "$HME"
354display "Shell............: " "$SHL"
355display "Expiry date......: " "$EXP" "[ Never ]"
356echo
357
358echo "This is it... if you want to bail out, hit Control-C.  Otherwise, press"
359echo "ENTER to go ahead and make the account."
360read junk
361
362echo
363echo "Creating new account..."
364echo
365echo
366
367# Add the account to the system
368CMD="$useradd "$HME" -m "$EXP" "$U_ID" "$GID" "$AGID" "$SHL" "$LOGIN""
369$CMD
370
371if [ $? -gt 0 ]; then
372  echo "- Error running useradd command -- account not created!"
373  echo "(cmd: $CMD)"
374  exit 1
375fi
376
377# chown the home dir ?  We can only do this once the useradd has
378# completed otherwise the user name doesn't exist.
379if [ ! -z "${CHOWNHOMEDIR}" ]; then
380  chown "$LOGIN"."$( echo $GID | awk '{print $2}')" "${CHOWNHOMEDIR}"
381fi
382
383# Set the finger information
384$chfn "$LOGIN"
385if [ $? -gt 0 ]; then
386  echo "- Warning: an error occurred while setting finger information"
387fi
388
389# Set a password
390$passwd "$LOGIN"
391if [ $? -gt 0 ]; then
392  echo "* WARNING: An error occured while setting the password for"
393  echo "           this account.  Please manually investigate this *"
394  exit 1
395fi
396
397# If it was created (it should have been!), set the permissions for that user's dir
398HME="$(echo "$HME" | awk '{print $2}')"  # We have to remove the -g prefix
399if [ -d "$HME" ]; then
400  $chmod $defchmod "$HME"
401fi
402
403echo
404echo
405echo "Account setup complete."
406exit 0
407
Note: See TracBrowser for help on using the repository browser.