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