Make sure that the script is running with root privileges
[usertools.macosx.git] / useradd.macosx.sh
1 #!/bin/bash
2 #
3 # useradd.macosx
4 # Copyright (c)2008 Barton IT-Consulting, Alexander Barton
5 #
6 # 2008-07-28, alex@barton-it.de - R2
7 #  - start directory services when not running (e. g. single user mode)
8 # 2008-07-28, alex@barton-it.de - R1
9 #  - initial version.
10 #
11
12 NAME=`basename $0`
13 RELEASE="2"
14
15 Abort() {
16         [ $# -lt 1 ] \
17                 && echo "$NAME: Error detected, aborting now!" \
18                 || echo "$NAME: $*"
19         exit 9
20 }
21 Usage() {
22         echo "$NAME (useradd.macosx.sh) release $RELEASE"
23         echo "Copyright (c)2008 Barton IT-Consulting, Alexander Barton (alex@barton-it.de)"
24         echo
25         echo "This is free software; see the source for copying conditions. There is NO"
26         echo "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
27         echo
28         echo "Usage: $NAME [-X] [-A] [-v] [-c <realName>] [-d <homeDir>]"
29         echo "       [-g <groupId>] [-s <shell>] [-u <userId>] <login>"
30         echo
31         echo " -A               User should become a local administrator."
32         echo " -c <realName>    Real name of the new user (aka \"comment\" field)."
33         echo " -d <homeDir>     Home directory of the user; default: '/User/<login>'."
34         echo " -g <groupId>     Group ID of the new user; default: 20 (='staff')."
35         echo " -s <shell>       Shell of the new user; default: '/bin/bash'."
36         echo " -u <userId>      User ID of the new user; default: next free UID."
37         echo " -v               Verbose mode, show more information during runtime."
38         echo " -X               Debug mode, only show what would be done."
39         echo
40         exit 1
41 }
42
43 # Check operating system version
44 sw_vers -productName 2>/dev/null | grep "Mac OS X" >/dev/null 2>&1
45 [ $? -eq 0 ] || Abort "This script requires Mac OS X!"
46 epoch=`sw_vers -productVersion | cut -d'.' -f1`
47 major=`sw_vers -productVersion | cut -d'.' -f2`
48 if [ $epoch -ne 10 -o $major -ne 5 ]; then
49         Abort "This script requires Mac OS X 10.5.x Leopard!"
50 fi
51
52 # Defaults
53 declare -i debug=0
54 declare -i verbose=0
55 declare -i user_id=-1
56 declare -i group_id=20
57 declare -i become_admin=0
58 user_name=""
59 real_name=""
60 home_dir=""
61 shell="/bin/bash"
62
63 # Parse command line
64 while [ $# -gt 0 ]; do
65         case "$1" in
66                 "-A")
67                         declare -i become_admin=1
68                         ;;
69                 "-c")
70                         shift
71                         [ $# -gt 0 ] || Usage
72                         real_name="$1"
73                         ;;
74                 "-d")
75                         shift
76                         [ $# -gt 0 ] || Usage
77                         home_dir="$1"
78                         ;;
79                 "-g")
80                         shift
81                         [ $# -gt 0 ] || Usage
82                         declare -i group_id="$1"
83                         ;;
84                 "-s")
85                         shift
86                         [ $# -gt 0 ] || Usage
87                         shell="$1"
88                         ;;
89                 "-u")
90                         shift
91                         [ $# -gt 0 ] || Usage
92                         declare -i user_id="$1"
93                         ;;
94                 "-v")
95                         declare -i verbose=1
96                         ;;
97                 "-X")
98                         declare -i debug=1
99                         ;;
100                 -*)
101                         Usage
102                         ;;
103                 *)
104                         [ -z "$user_name" ] || Usage
105                         user_name="$1"
106         esac
107         shift
108 done
109 [ -n "$user_name" ] || Usage
110 [ -n "$real_name" ] || real_name="$user_name"
111 [ -n "$home_dir" ] || home_dir="/Users/$user_name"
112 [ -n "$shell" ] || shell="/bin/bash"
113
114 [ "$UID" -eq 0 ] || Abort "This script must be run as root!"
115
116 # Check that directory services are running
117 launchctl list 2>/dev/null | fgrep "com.apple.DirectoryServices" >/dev/null 2>&1
118 if [ $? -ne 0 ]; then
119         echo "Starting directory services ..."
120         launchctl load /System/Library/LaunchDaemons/com.apple.DirectoryServicesLocal.plist || Abort
121         sleep 1
122         launchctl load /System/Library/LaunchDaemons/com.apple.DirectoryServices.plist || Abort
123         sleep 1
124 else
125         [ "$verbose" -ne 0 ] && echo "Directory services already loaded, ok."
126 fi
127
128 # No user ID given, generate it
129 if [ $user_id -lt 0 ]; then
130         # search next free user ID
131         declare -i new_id=501
132         id "$new_id" >/dev/null 2>&1
133         while [ $? -eq 0 ]; do
134                 new_id=$new_id+1;
135                 id "$new_id" >/dev/null 2>&1
136         done
137         user_id=$new_id
138 fi
139
140 # Validate user name, user id and group id
141 id "$user_id" >/dev/null 2>&1
142 [ $? -ne 0 ] || Abort "User id $user_id already used!"
143 id "$user_name" >/dev/null 2>&1
144 [ $? -ne 0 ] || Abort "User name '$user_name' already used!"
145 [ -n "$user_id" -a "$user_id" -ge 1 ] || Abort "User ID must be >0!"
146 [ -n "$group_id" -a "$group_id" -ge 0 ] || Abort "Group ID must be >=0!"
147
148 if [ "$verbose" -ne 0 -o "$debug" -ne 0 ]; then
149         echo "uid=$user_id"
150         echo "gid=$group_id"
151         echo "user_name=$user_name"
152         echo "real_name=$real_name"
153         echo "home_dir=$home_dir"
154         echo "shell=$shell"
155         echo "become_admin=$become_admin"
156         echo
157 fi
158 [ "$debug" -ne 0 ] && exit 8
159
160 if [ `id -u` -ne 0 ]; then
161         Abort "This script requires root privileges!"
162 fi
163
164 # Create directory entries
165 [ "$verbose" -ne 0 ] && echo "Creating user ..."
166 dscl . -create /Users/"$user_name" || Abort
167 [ "$verbose" -ne 0 ] && echo "Populating user ..."
168 dscl . -create /Users/"$user_name" UniqueID "$user_id" || Abort
169 dscl . -create /Users/"$user_name" PrimaryGroupID "$group_id" || Abort
170 dscl . -create /Users/"$user_name" NFSHomeDirectory "$home_dir" || Abort
171 dscl . -create /Users/"$user_name" UserShell "$shell" || Abort
172 dscl . -create /Users/"$user_name" RealName "$real_name" || Abort
173 #dscl . -passwd /Users/"$user_name" "maccc" || Abort
174 if [ "$become_admin" -ne 0 ]; then
175         [ "$verbose" -ne 0 ] && echo "Adding user to 'admin' group ..."
176         dscl . -append /Groups/admin GroupMembership "$user_name" || Abort
177 fi
178
179 # Create home directory
180 [ "$verbose" -ne 0 ] && echo "Creating user home directory ..."
181 mkdir -p "$home_dir" || Abort
182 chown "$user_id:$group_id" "$home_dir" || Abort
183 chmod 755 "$home_dir" || Abort
184
185 [ "$verbose" -ne 0 ] && echo
186 echo "User '$user_name' ($user_id) has been created."
187 exit 0
188
189 # -eof-