1 #!/bin/bash
2 #
3 # @(#) Create a new user in OSX. V1.1
4 #
5 # xaos@xm5design.com - July 14, 2010
6 #
7 DSCLLIST="/tmp/dsclist.txt"
8 DSCLLISTS="/tmp/dsclists.txt"
9 DRURUN=0
10 NUSER="newuser"
11 FIND_NEXT_UID=0
12 #
13 #
14 usage() {
15 echo "Usage: $0 [ -l [user] | -h | -a | -d ] User_Name { UID | . } GID"
16 echo -e "\nWhere:\n"
17 echo -e "\t-a\t\tWill create the user as an administrator"
18 echo -e "\t-d\t\tWill do a \"Dry Run\". It will check everything but not run any commands"
19 echo -e "\t-h\t\tWill print this help message"
20 echo -e "\t-l [user]\tWill list a user or all users and quit"
21 echo -e "\nSpecifying a \".\" (dot) for a UID means find the next available one."
22 echo -e "If the GID does not exist, the necessary commands to create it will be printed out."
23 echo -e "A default password (made of random numbers) will be created along with the userid."
24 }
25
26 #
27 # This only works for Darwin
28 if [[ "$(uname -s)" != "Darwin" ]]
29 then
30 echo "This script will only work for OSX"
31 exit 1
32 fi
33 #
34 #
35 NUSER=$1
36 NUID=$2
37 NGID=$3
38 NADMIN=0
39 #
40 # Get help ?
41 if [[ "${NUSER}" = "-h"* || "${NUSER}" = "--h"* ]]
42 then
43 usage
44 exit 1
45 fi
46 #
47 # Show a list of users?
48 if [[ "${NUSER}" = "-l" ]]
49 then
50 shift
51 MUSER=$1
52 if [[ "${MUSER}" == "" ]]
53 then
54 GENULIST=$(dscl "." list /users | sort -k 1)
55 else
56 GENULIST=${MUSER}
57 fi
58 #
59 DSCGLIST=$(dscl . list /Groups)
60 #
61 for ii in ${GENULIST}
62 do
63 echo "${ii}"
64 dscl . read /Users/${ii} | egrep "PrimaryGroupID|NFSHomeDirectory|RealName|UniqueID|UserShell" >${DSCLLIST}
65 while read line
66 do
67 if [[ "${line}" = *PrimaryGroupID* ]]
68 then
69 set $line
70 gtext=$1;gnumid=$2
71 foundid=0
72 #
73 for kk in ${DSCGLIST}
74 do
75 GIDTEXT=$(dscl . read /Groups/$kk | grep PrimaryGroupID)
76 set $GIDTEXT
77 gtextg=$1; gnumidg=$2
78 #
79 # now, compare the two
80 if (( gnumid == gnumidg ))
81 then
82 foundid=1
83 foundname=$kk
84 break
85 fi
86 done
87 if (( foundid ))
88 then
89 echo -e "\tPrimaryGroupID:\n\t\tName : ${foundname}\n\t\tNumber : ${gnumid}\n\t\tExists : Yes"
90 else
91 echo -e "\tPrimaryGroupID:\n\t\tName : ${foundname}\n\t\tNumber : ${gnumid}\n\t\tExists : No"
92 fi
93 else
94 set $line
95 key=$1
96 shift
97 keytext=$*
98 echo -e "\t${key}\n\t\t\"${keytext}\""
99 fi
100 done < ${DSCLLIST}
101 done
102 rm -f ${DSCLLIST}
103 exit 0
104 fi
105 #
106 # Does he need to be admin or dry run?
107 while :
108 do
109 if [[ "${NUSER}" = "-"* ]]
110 then
111 if [[ "${NUSER}" = "-a" ]]
112 then
113 NADMIN=1
114 elif [[ "${NUSER}" = "-d" ]]
115 then
116 DRYRUN=1
117 else
118 echo "Error: Unknown option: \"${NUSER}\". Bye."
119 exit
120 fi
121 shift
122 NUSER=$1
123 NUID=$2
124 NGID=$3
125 else
126 break
127 fi
128 done
129 #
130 # Check for no parms
131 if [[ "${NGID}" = "" ]]
132 then
133 usage
134 exit 1
135 fi
136 #
137 # Check if the user exists
138 if dscl "." read /Users/${NUSER} >/dev/null 2>&1
139 then
140 echo -e "User: \"${NUSER}\", already exists. Bye."
141 exit 1
142 fi
143 #
144 #
145 if [[ "${NUID}" = "." ]]
146 then
147 FIND_NEXT_UID=1
148 fi
149
150 #
151 #
152 if (( FIND_NEXT_UID ))
153 then
154 #
155 # Go through every id
156 GENULIST=$(dscl "." list /Users | sort -k 1)
157 rm -rf ${DSCLLIST}
158 for ii in ${GENULIST}
159 do
160 dscl . read /Users/${ii} | egrep "UniqueID" >>${DSCLLIST}
161 done
162 cat ${DSCLLIST} | awk '{print $2}' | sort -n > ${DSCLLISTS}
163 vim ${DSCLLISTS}
164 NUID=$(tail -1 ${DSCLLISTS})
165 let NUID=$NUID+1
166 echo -e "New UID found: \"${NUID}\""
167 rm -f ${DSCLLIST} ${DSCLLISTS}
168 fi
169 #
170 # Check if the UID exists
171 GENULIST=$(dscl "." list /Users | sort -k 1)
172 #
173 foundid=0
174 for ii in ${GENULIST}
175 do
176 dscl . read /Users/${ii} | egrep "UniqueID" >${DSCLLIST}
177 while read line
178 do
179 set $line
180 text=$1;numid=$2
181 if (( numid == NUID ))
182 then
183 foundid=1
184 break
185 fi
186 done < ${DSCLLIST}
187 done
188 rm -f ${DSCLLIST}
189 #
190 # Check it
191 if (( foundid ))
192 then
193 echo -e "UID: \"${NUID}\", already exists. Bye."
194 exit 1
195 else
196 echo -e "UID: \"${NUID}\", does not exist. Cool."
197 fi
198 #
199 # Check if the GID exists
200 GENULIST=$(dscl "." list /Groups | sort -k 1)
201 #
202 foundid=0
203 for ii in ${GENULIST}
204 do
205 dscl . read /Groups/${ii} | egrep "PrimaryGroupID" >${DSCLLIST}
206 while read line
207 do
208 set $line
209 text=$1;numid=$2
210 if (( numid == NGID ))
211 then
212 foundid=1
213 break
214 fi
215 done < ${DSCLLIST}
216 done
217 rm -f ${DSCLLIST}
218 #
219 # Check it
220 if (( foundid ))
221 then
222 echo -e "GID: \"${NGID}\", exists. Cool."
223 else
224 echo -e "GID: \"${NGID}\", does not exist.\n\tYou must create with commands:"
225 echo -e "\t\tdscl . create /Groups/${NUSER}"
226 echo -e "\t\tdscl . create /Groups/${NUSER} name ${NUSER}"
227 echo -e "\t\tdscl . create /Groups/${NUSER} passwd \"*\""
228 echo -e "\t\tdscl . create /Groups/${NUSER} gid ${NGID}"
229 echo -e "\t\tdscl . create /Groups/${NUSER} users ${NUSER}"
230 fi
231 #
232 #
233 MYNAME="Dr. Maximvs ${NUSER}"
234 MYPASS=$(printf "%d\n" "${RANDOM}${RANDOM}${RANDOM}")
235 #
236 if (( DRYRUN ))
237 then
238 echo -e "Preparing New Account\n\tUser: \"${NUSER}\"\n\tName: \"${MYNAME}\"\n\tUID: \"${NUID}\"\n\tGID: \"${NGID}\"\n\tPassword: \"${MYPASS}\""
239 exit
240 fi
241 #
242 # Process request
243 dscl "." -create /Users/${NUSER} || exit 1
244
245 #
246 # Create and set the shell property to bash.
247 dscl "." -create /Users/${NUSER} UserShell /bin/bash || { echo "Error Creating User Shell. Account was never created"; exit 1; }
248
249 #
250 # Create and set the user’s full name.
251 dscl "." -create /Users/${NUSER} RealName "${MYNAME}" || { echo -e "Error Creating User Real Name. Account Will be deleted"; dscl . delete /Users/${NUSER}; exit 1; }
252
253 #
254 # Create and set the user’s ID.
255 dscl "." -create /Users/${NUSER} UniqueID ${NUID} || { echo -e "Error Creating UID. Account Will be deleted"; dscl . delete /Users/${NUSER}; exit 1; }
256
257 #
258 # Create and set the user’s group ID property.
259 dscl "." -create /Users/${NUSER} PrimaryGroupID ${NGID} || { echo -e "Error Creating GID. Account Will be deleted"; dscl . delete /Users/${NUSER}; exit 1; }
260
261 #
262 # Create and set the user home directory.
263 dscl "." -create /Users/${NUSER} NFSHomeDirectory /Users/${NUSER} || { echo -e "Error Creating Home Directory. Account Will be deleted"; dscl . delete /Users/${NUSER}; exit 1; }
264
265 #
266 # Set the password.
267 dscl "." passwd /Users/${NUSER} ${MYPASS} || { echo -e "\nError Creating User Password. Continuing"; dscl . delete /Users/${NUSER}; exit 1; }
268
269 echo -e "New User created.\n\tUser: \"${NUSER}\"\n\tName: \"${MYNAME}\"\n\tDUID: \"${NUID}\"\n\tGID: \"${NGID}\"\n\tPassword: \"${MYPASS}\""
270
271 if (( NADMIN ))
272 then
273 #
274 # If you would like Dr. Maximus to be able to perform administrative functions:
275 dscl "." -append /Groups/admin GroupMembership ${NUSER} || exit 1
276 echo -e "\tAdministrator: \"Yes\""
277 else
278 echo -e "\tAdministrator: \"No\""
279 fi
280 #
281 # Create the home dir
282 createhomedir -c > /dev/null || exit 1
283 chmod 700 /Users/${NUSER}
284 #
285 # Now, check with Dscl
286 echo "Now Checking with dscl:"
287 dscl . read /Users/${NUSER} | sed 's/^/ /'
288 #
289 echo -e "\nTo Delete the user do:\n\tdscl \".\" delete /Users/${NUSER}"
290 #
291 exit 0