xref: /freebsd/usr.sbin/pw/tests/pw_useradd_test.sh (revision 9f23cbd6cae82fd77edfad7173432fa8dccd0a95)
1# $FreeBSD$
2
3# Import helper functions
4. $(atf_get_srcdir)/helper_functions.shin
5
6# Test add user
7atf_test_case user_add
8user_add_body() {
9	populate_etc_skel
10
11	atf_check -s exit:0 ${PW} useradd test
12	atf_check -s exit:0 -o match:"^test:.*" \
13		grep "^test:.*" $HOME/master.passwd
14}
15
16# Test add user with option -N
17atf_test_case user_add_noupdate
18user_add_noupdate_body() {
19	populate_etc_skel
20
21	atf_check -s exit:0 -o match:"^test:.*" ${PW} useradd test -N
22	atf_check -s exit:1 -o empty grep "^test:.*" $HOME/master.passwd
23}
24
25# Test add user with comments
26atf_test_case user_add_comments
27user_add_comments_body() {
28	populate_etc_skel
29
30	atf_check -s exit:0 ${PW} useradd test -c 'Test User,work!,123,user@example.com'
31	atf_check -s exit:0 -o match:'^test:.*:Test User,work!,123,user@example.com:' \
32		grep '^test:.*:Test User,work!,123,user@example.com:' $HOME/master.passwd
33}
34
35# Test add user with comments and option -N
36atf_test_case user_add_comments_noupdate
37user_add_comments_noupdate_body() {
38	populate_etc_skel
39
40	atf_check -s exit:0 -o match:"^test:.*:Test User,work,123,456:" \
41		${PW} useradd test -c "Test User,work,123,456" -N
42	atf_check -s exit:1 -o empty grep "^test:.*" $HOME/master.passwd
43}
44
45# Test add user with invalid comments
46atf_test_case user_add_comments_invalid
47user_add_comments_invalid_body() {
48	populate_etc_skel
49
50	atf_check -s exit:65 -e match:"invalid character" \
51		${PW} useradd test -c "Test User,work,123:456,456"
52	atf_check -s exit:1 -o empty \
53		grep "^test:.*:Test User,work,123:456,456:" $HOME/master.passwd
54}
55
56# Test add user with invalid comments and option -N
57atf_test_case user_add_comments_invalid_noupdate
58user_add_comments_invalid_noupdate_body() {
59	populate_etc_skel
60
61	atf_check -s exit:65 -e match:"invalid character" \
62		${PW} useradd test -c "Test User,work,123:456,456" -N
63	atf_check -s exit:1 -o empty grep "^test:.*" $HOME/master.passwd
64}
65
66# Test add user with alternate homedir
67atf_test_case user_add_homedir
68user_add_homedir_body() {
69	populate_etc_skel
70
71	atf_check -s exit:0 ${PW} useradd test -d /foo/bar
72	atf_check -s exit:0 -o match:"^test:\*:.*::0:0:User &:/foo/bar:.*" \
73		${PW} usershow test
74}
75
76# Test add user with account expiration as an epoch date
77atf_test_case user_add_account_expiration_epoch
78user_add_account_expiration_epoch_body() {
79	populate_etc_skel
80
81	DATE=`date -j -v+1d "+%s"`
82	atf_check -s exit:0 ${PW} useradd test -e ${DATE}
83	atf_check -s exit:0 -o match:"^test:\*:.*::0:${DATE}:.*" \
84		${PW} usershow test
85}
86
87# Test add user with account expiration as a DD-MM-YYYY date
88atf_test_case user_add_account_expiration_date_numeric
89user_add_account_expiration_date_numeric_body() {
90	populate_etc_skel
91
92	DATE=`date -j -v+1d "+%d-%m-%Y"`
93	EPOCH=`date -j -f "%d-%m-%Y %H:%M:%S" "${DATE} 00:00:00" "+%s"`
94	atf_check -s exit:0 ${PW} useradd test -e ${DATE}
95	atf_check -s exit:0 -o match:"^test:\*:.*::0:${EPOCH}:User &:.*" \
96		${PW} usershow test
97}
98
99# Test add user with account expiration as a DD-MM-YYYY date
100atf_test_case user_add_account_expiration_date_month
101user_add_account_expiration_date_month_body() {
102	populate_etc_skel
103
104	DATE=`date -j -v+1d "+%d-%b-%Y"`
105	EPOCH=`date -j -f "%d-%b-%Y %H:%M:%S" "${DATE} 00:00:00" "+%s"`
106	atf_check -s exit:0 ${PW} useradd test -e ${DATE}
107	atf_check -s exit:0 -o match:"^test:\*:.*::0:${EPOCH}:User &:.*" \
108		${PW} usershow test
109}
110
111# Test add user with account expiration as a relative date
112atf_test_case user_add_account_expiration_date_relative
113user_add_account_expiration_date_relative_body() {
114	populate_etc_skel
115
116	EPOCH=`date -j -v+13m "+%s"`
117	BUF=`expr $EPOCH + 5`
118	atf_check -s exit:0 ${PW} useradd test -e +13o
119	TIME=`${PW} usershow test | awk -F ':' '{print $7}'`
120	[ ! -z $TIME -a $TIME -ge $EPOCH -a $TIME -lt $BUF ] || \
121		atf_fail "Expiration time($TIME) was not within $EPOCH - $BUF seconds."
122}
123
124# Test add user with password expiration as an epoch date
125atf_test_case user_add_password_expiration_epoch
126user_add_password_expiration_epoch_body() {
127	populate_etc_skel
128
129	DATE=`date -j -v+1d "+%s"`
130	atf_check -s exit:0 ${PW} useradd test -p ${DATE}
131	atf_check -s exit:0 -o match:"^test:\*:.*::${DATE}:0:.*" \
132		${PW} usershow test
133}
134
135# Test add user with password expiration as a DD-MM-YYYY date
136atf_test_case user_add_password_expiration_date_numeric
137user_add_password_expiration_date_numeric_body() {
138	populate_etc_skel
139
140	DATE=`date -j -v+1d "+%d-%m-%Y"`
141	EPOCH=`date -j -f "%d-%m-%Y %H:%M:%S" "${DATE} 00:00:00" "+%s"`
142	atf_check -s exit:0 ${PW} useradd test -p ${DATE}
143	atf_check -s exit:0 -o match:"^test:\*:.*::${EPOCH}:0:User &:.*" \
144		${PW} usershow test
145}
146
147# Test add user with password expiration as a DD-MMM-YYYY date
148atf_test_case user_add_password_expiration_date_month
149user_add_password_expiration_date_month_body() {
150	populate_etc_skel
151
152	DATE=`date -j -v+1d "+%d-%b-%Y"`
153	EPOCH=`date -j -f "%d-%b-%Y %H:%M:%S" "${DATE} 00:00:00" "+%s"`
154	atf_check -s exit:0 ${PW} useradd test -p ${DATE}
155	atf_check -s exit:0 -o match:"^test:\*:.*::${EPOCH}:0:User &:.*" \
156		${PW} usershow test
157}
158
159# Test add user with password expiration as a relative date
160atf_test_case user_add_password_expiration_date_relative
161user_add_password_expiration_date_relative_body() {
162	populate_etc_skel
163
164	EPOCH=`date -j -v+13m "+%s"`
165	BUF=`expr $EPOCH + 5`
166	atf_check -s exit:0 ${PW} useradd test -p +13o
167	TIME=`${PW} usershow test | awk -F ':' '{print $6}'`
168	[ ! -z $TIME -a $TIME -ge $EPOCH -a $TIME -lt $BUF ] || \
169		atf_fail "Expiration time($TIME) was not within $EPOCH - $BUF seconds."
170}
171
172atf_test_case user_add_name_too_long
173user_add_name_too_long_body() {
174	populate_etc_skel
175	atf_check -e match:"too long" -s exit:64 \
176		${PW} useradd name_very_vert_very_very_very_long
177}
178
179atf_test_case user_add_name_with_spaces
180user_add_name_with_spaces_body() {
181	populate_etc_skel
182	atf_check -s exit:65 -e match:"invalid character" \
183		  ${PW} useradd 'test user'
184	atf_check -s exit:1 -o empty grep "^test user:.*" $HOME/master.passwd
185	# Try again with -n which uses a slightly different code path.
186	atf_check -s exit:65 -e match:"invalid character" \
187		  ${PW} useradd -n 'test user'
188	atf_check -s exit:1 -o empty grep "^test user:.*" $HOME/master.passwd
189}
190
191atf_test_case user_add_name_with_spaces_and_gid_specified
192user_add_name_with_spaces_and_gid_specified_body() {
193	populate_etc_skel
194	gid=12345
195	user_name="test user"
196	# pw useradd should fail because of the space in the user
197	# name, not because the group doesn't exist.
198	atf_check -s exit:65 -e match:"invalid character" \
199		  ${PW} useradd "${user_name}" -g ${gid}
200	atf_check -s exit:1 -o empty grep "^${user_name}:.*" $HOME/master.passwd
201	# Try again with -n which uses a slightly different code path.
202	atf_check -s exit:65 -e match:"invalid character" \
203		  ${PW} useradd -n "${user_name}" -g ${gid}
204	atf_check -s exit:1 -o empty grep "^${user_name}:.*" $HOME/master.passwd
205	# Make sure the user isn't added even if the group exists
206	atf_check -s exit:0 ${PW} groupadd blafasel -g ${gid}
207	atf_check -s exit:65 -e match:"invalid character" \
208		  ${PW} useradd "${user_name}" -g ${gid}
209	atf_check -s exit:1 -o empty grep "^${user_name}:.*" $HOME/master.passwd
210	# Try again with the -n option.
211	atf_check -s exit:65 -e match:"invalid character" \
212		  ${PW} useradd -n "${user_name}" -g ${gid}
213	atf_check -s exit:1 -o empty grep "^${user_name}:.*" $HOME/master.passwd
214}
215
216atf_test_case user_add_expiration
217user_add_expiration_body() {
218	populate_etc_skel
219
220	atf_check -s exit:0 \
221		${PW} useradd foo -e 20-03-2037
222	atf_check -o inline:"foo:*:1001:1001::0:2121120000:User &:/home/foo:/bin/sh\n" \
223		-s exit:0 grep "^foo" ${HOME}/master.passwd
224	atf_check -s exit:0 ${PW} userdel foo
225	atf_check -s exit:0 \
226		${PW} useradd foo -e 20-03-37
227	atf_check -o inline:"foo:*:1001:1001::0:2121120000:User &:/home/foo:/bin/sh\n" \
228		-s exit:0 grep "^foo" ${HOME}/master.passwd
229	atf_check -s exit:0 ${PW} userdel foo
230	atf_check -s exit:0 \
231		${PW} useradd foo -e 20-Mar-2037
232	atf_check -o inline:"foo:*:1001:1001::0:2121120000:User &:/home/foo:/bin/sh\n" \
233		-s exit:0 grep "^foo" ${HOME}/master.passwd
234	atf_check -s exit:0 ${PW} userdel foo
235	atf_check -e inline:"pw: Invalid date\n" -s exit:1 \
236		${PW} useradd foo -e 20-Foo-2037
237	atf_check -e inline:"pw: Invalid date\n" -s exit:1 \
238		${PW} useradd foo -e 20-13-2037
239	atf_check -s exit:0 ${PW} useradd foo -e "12:00 20-03-2037"
240	atf_check -s exit:0 ${PW} userdel foo
241	atf_check -e inline:"pw: Invalid date\n" -s exit:1 \
242		${PW} useradd foo -e "12 20-03-2037"
243	atf_check -s exit:0 ${PW} useradd foo -e "20-03-2037	12:00"
244	atf_check -s exit:0 ${PW} userdel foo
245}
246
247atf_test_case user_add_invalid_user_entry
248user_add_invalid_user_entry_body() {
249	touch ${HOME}/master.passwd
250	touch ${HOME}/group
251
252	pwd_mkdb -p -d ${HOME} ${HOME}/master.passwd || \
253		atf_fail "generate passwd from master.passwd"
254	atf_check -s exit:0 ${PW} useradd foo
255	echo "foo1:*:1002" >> ${HOME}/master.passwd
256	atf_check -s exit:1 -e match:"Invalid user entry" ${PW} useradd foo2
257}
258
259atf_test_case user_add_invalid_group_entry
260user_add_invalid_group_entry_body() {
261	touch ${HOME}/master.passwd
262	touch ${HOME}/group
263
264	pwd_mkdb -p -d ${HOME} ${HOME}/master.passwd || \
265		atf_fail "generate passwd from master.passwd"
266	atf_check -s exit:0 ${PW} useradd foo
267	echo 'foo1:*:1002' >> group
268	atf_check -s exit:1 -e match:"Invalid group entry" ${PW} useradd foo2
269}
270
271atf_test_case user_add_password_from_h
272user_add_password_from_h_body() {
273	populate_etc_skel
274
275	atf_check -s exit:0 ${PW} useradd foo -h 0 <<-EOF
276	$(echo mypassword)
277	EOF
278	passhash=`awk -F ':' '/^foo:/ {print $2}' $HOME/master.passwd`
279	atf_check -s exit:0 -o inline:$passhash \
280		$(atf_get_srcdir)/crypt $passhash "mypassword"
281}
282
283atf_test_case user_add_R
284user_add_R_body() {
285	populate_root_etc_skel
286
287	atf_check -s exit:0 ${RPW} useradd foo
288	atf_check -s exit:0 ${RPW} useradd bar -m
289	test -d ${HOME}/home || atf_fail "Home parent directory not created"
290	test -d ${HOME}/home/bar || atf_fail "Directory not created"
291	atf_check -s exit:0 ${RPW} userdel bar
292	test -d ${HOME}/home/bar || atf_fail "Directory removed"
293	atf_check -s exit:0 ${RPW} useradd bar
294	atf_check -s exit:0 ${RPW} userdel bar -r
295	[ ! -d ${HOME}/home/bar ] || atf_fail "Directory not removed"
296}
297
298atf_test_case user_add_R_no_symlink
299user_add_R_no_symlink_body() {
300	populate_root_etc_skel
301
302	mkdir ${HOME}/usr
303	atf_check -s exit:0 ${RPW} useradd foo -m
304	[ ! -d ${HOME}/usr/home ] || atf_fail "/usr/home created"
305	test -d ${HOME}/home || atf_fail "/home directory not created"
306}
307
308atf_test_case user_add_R_intermed
309user_add_R_intermed_body() {
310	populate_root_etc_skel
311
312	atf_check -s exit:0 ${RPW} useradd foo -m -d /a/b/c/foo
313	test -d ${HOME}/a/b/c || atf_fail "intermediate directories not created"
314	test -d ${HOME}/a/b/c/foo || atf_fail "user directory not created"
315}
316
317atf_test_case user_add_skel
318user_add_skel_body() {
319	populate_root_etc_skel
320
321	mkdir ${HOME}/skel
322	echo "a" > ${HOME}/skel/.a
323	echo "b" > ${HOME}/skel/b
324	mkdir ${HOME}/skel/c
325	mkdir ${HOME}/skel/c/d
326	mkdir ${HOME}/skel/dot.plop
327	echo "c" > ${HOME}/skel/c/d/dot.c
328	mkdir ${HOME}/home
329	ln -sf /nonexistent ${HOME}/skel/c/foo
330	atf_check -s exit:0 ${RPW} useradd foo -k /skel -m
331	test -d ${HOME}/home/foo || atf_fail "Directory not created"
332	test -f ${HOME}/home/foo/.a || atf_fail "File not created"
333	atf_check -o file:${HOME}/skel/.a -s exit:0 cat ${HOME}/home/foo/.a
334	atf_check -o file:${HOME}/skel/b -s exit:0 cat ${HOME}/home/foo/b
335	test -d ${HOME}/home/foo/c || atf_fail "Dotted directory in skel not copied"
336	test -d ${HOME}/home/foo/.plop || atf_fail "Directory in skell not created"
337	atf_check -o inline:"/nonexistent\n" -s ignore readlink -f ${HOME}/home/foo/c/foo
338	atf_check -o file:${HOME}/skel/c/d/dot.c -s exit:0 cat ${HOME}/home/foo/c/d/.c
339}
340
341atf_test_case user_add_uid0
342user_add_uid0_body() {
343	populate_etc_skel
344	atf_check -e inline:"pw: WARNING: new account \`foo' has a uid of 0 (superuser access!)\n" \
345		-s exit:0 ${PW} useradd foo -u 0 -g 0 -d /root -s /bin/sh -c "Bourne-again Superuser" -o
346	atf_check \
347		-o inline:"foo:*:0:0::0:0:Bourne-again Superuser:/root:/bin/sh\n" \
348		-s exit:0 ${PW} usershow foo
349}
350
351atf_test_case user_add_uid_too_large
352user_add_uid_too_large_body() {
353	populate_etc_skel
354	atf_check -s exit:64 -e inline:"pw: Bad id '9999999999999': too large\n" \
355		${PW} useradd -n test1 -u 9999999999999
356}
357
358atf_test_case user_add_bad_shell
359user_add_bad_shell_body() {
360	populate_etc_skel
361
362	atf_check -s exit:0 ${PW} useradd foo -s sh
363	atf_check -s exit:78 -e ignore ${PW} useradd bar -s badshell
364}
365
366atf_test_case user_add_already_exists
367user_add_already_exists_body() {
368	populate_etc_skel
369
370	atf_check -s exit:0 ${PW} useradd foo
371	atf_check -s exit:65 \
372		-e inline:"pw: login name \`foo' already exists\n" \
373		${PW} useradd foo
374}
375
376atf_test_case user_add_w_error
377user_add_w_error_body() {
378	populate_etc_skel
379
380	atf_check -s exit:1 -e match:"pw: Invalid value for default password" \
381		${PW} useradd foo -w invalid_value
382}
383
384atf_test_case user_add_w_no
385user_add_w_no_body() {
386	populate_etc_skel
387
388	atf_check -s exit:0 ${PW} useradd foo -w no
389	atf_check -s exit:0 -o match:"^foo:\*" grep "^foo:" $HOME/master.passwd
390}
391
392atf_test_case user_add_w_none
393user_add_w_none_body() {
394	populate_etc_skel
395
396	atf_check -s exit:0 ${PW} useradd foo -w none
397	atf_check -s exit:0 -o match:"^foo::" grep "^foo:" $HOME/master.passwd
398}
399
400atf_test_case user_add_w_random
401user_add_w_random_body() {
402	populate_etc_skel
403
404	password=`${PW} useradd foo -w random | cat`
405	passhash=`awk -F ':' '/^foo:/ {print $2}' $HOME/master.passwd`
406	atf_check -s exit:0 -o inline:$passhash \
407		$(atf_get_srcdir)/crypt $passhash "$password"
408}
409
410atf_test_case user_add_w_yes
411user_add_w_yes_body() {
412	populate_etc_skel
413	password=`${PW} useradd foo -w random | cat`
414	passhash=`awk -F ':' '/^foo:/ {print $2}' $HOME/master.passwd`
415	atf_check -s exit:0 -o inline:$passhash \
416		$(atf_get_srcdir)/crypt $passhash "$password"
417}
418
419atf_test_case user_add_with_pw_conf
420user_add_with_pw_conf_body()
421{
422	populate_etc_skel
423	atf_check -s exit:0 \
424		${PW} useradd -D -C ${HOME}/pw.conf \
425		-u 2000,32767 -i 2000,32767
426	atf_check -s exit:0 \
427		-o inline:"minuid = 2000\nmaxuid = 32767\nmingid = 2000\nmaxgid = 32767\n" \
428		grep "^m.*id =" ${HOME}/pw.conf
429	atf_check -s exit:0 \
430		${PW} useradd foo -C ${HOME}/pw.conf
431}
432
433atf_test_case user_add_defaultgroup
434user_add_defaultgroup_body()
435{
436	populate_etc_skel
437	echo 'defaultgroup = "plop"' > ${HOME}/pw.conf
438	atf_check -s exit:0 \
439		${PW} groupadd plop -g 442
440	atf_check -s exit:0 \
441		${PW} useradd foo -C ${HOME}/pw.conf
442	atf_check -s exit:0 \
443		-o inline:"foo:*:1001:442::0:0:User &:/home/foo:/bin/sh\n" \
444		${PW} usershow foo
445}
446
447atf_test_case user_add_conf_defaultpasswd
448user_add_conf_defaultpasswd_body()
449{
450	populate_etc_skel
451
452	atf_check -s exit:0 ${PW} useradd -D -w no
453	atf_check -o inline:"defaultpasswd = \"no\"\n" \
454	    grep defaultpasswd ${HOME}/pw.conf
455	atf_check -s exit:0 ${PW} useradd -D -w none
456	atf_check -o inline:"defaultpasswd = \"none\"\n" \
457	    grep defaultpasswd ${HOME}/pw.conf
458	atf_check -s exit:0 ${PW} useradd -D -w random
459	atf_check -o inline:"defaultpasswd = \"random\"\n" \
460	    grep defaultpasswd ${HOME}/pw.conf
461	atf_check -s exit:0 ${PW} useradd -D -w yes
462	atf_check -o inline:"defaultpasswd = \"yes\"\n" \
463	    grep defaultpasswd ${HOME}/pw.conf
464}
465
466atf_test_case user_add_existing_login_group
467user_add_existing_login_group_body()
468{
469	populate_etc_skel
470
471	atf_check -s exit:0 ${PW} groupadd testuser
472	atf_check -s exit:0 ${PW} useradd user1 -G testuser
473	atf_check -s exit:0 ${PW} useradd testuser
474	atf_check -o match:"1" \
475	    sh -c "grep testuser ${HOME}/group | wc -l"
476}
477
478atf_test_case user_add_already_in_group
479user_add_already_in_group_body()
480{
481	populate_etc_skel
482
483	echo "testgroup:*:4242:testuser" >> ${HOME}/group
484	atf_check -s exit:0 ${PW} useradd testuser -G testgroup
485	atf_check -o not-match:"testuser,testuser" \
486		grep testuser ${HOME}/group
487}
488
489atf_init_test_cases() {
490	atf_add_test_case user_add
491	atf_add_test_case user_add_noupdate
492	atf_add_test_case user_add_comments
493	atf_add_test_case user_add_comments_noupdate
494	atf_add_test_case user_add_comments_invalid
495	atf_add_test_case user_add_comments_invalid_noupdate
496	atf_add_test_case user_add_homedir
497	atf_add_test_case user_add_account_expiration_epoch
498	atf_add_test_case user_add_account_expiration_date_numeric
499	atf_add_test_case user_add_account_expiration_date_month
500	atf_add_test_case user_add_account_expiration_date_relative
501	atf_add_test_case user_add_password_expiration_epoch
502	atf_add_test_case user_add_password_expiration_date_numeric
503	atf_add_test_case user_add_password_expiration_date_month
504	atf_add_test_case user_add_password_expiration_date_relative
505	atf_add_test_case user_add_name_too_long
506	atf_add_test_case user_add_name_with_spaces
507	atf_add_test_case user_add_name_with_spaces_and_gid_specified
508	atf_add_test_case user_add_expiration
509	atf_add_test_case user_add_invalid_user_entry
510	atf_add_test_case user_add_invalid_group_entry
511	atf_add_test_case user_add_password_from_h
512	atf_add_test_case user_add_R
513	atf_add_test_case user_add_R_no_symlink
514	atf_add_test_case user_add_R_intermed
515	atf_add_test_case user_add_skel
516	atf_add_test_case user_add_uid0
517	atf_add_test_case user_add_uid_too_large
518	atf_add_test_case user_add_bad_shell
519	atf_add_test_case user_add_already_exists
520	atf_add_test_case user_add_w_error
521	atf_add_test_case user_add_w_no
522	atf_add_test_case user_add_w_none
523	atf_add_test_case user_add_w_random
524	atf_add_test_case user_add_w_yes
525	atf_add_test_case user_add_with_pw_conf
526	atf_add_test_case user_add_defaultgroup
527
528	atf_add_test_case user_add_conf_defaultpasswd
529	atf_add_test_case user_add_existing_login_group
530	atf_add_test_case user_add_already_in_group
531}
532