xref: /freebsd/contrib/pjdfstest/tests/chown/00.t (revision 4928135658a9d0eaee37003df6137ab363fcb0b4)
1#!/bin/sh
2# vim: filetype=sh noexpandtab ts=8 sw=8
3# $FreeBSD: head/tools/regression/pjdfstest/tests/chown/00.t 228975 2011-12-30 00:04:11Z uqs $
4
5desc="chown changes ownership"
6
7dir=`dirname $0`
8. ${dir}/../misc.sh
9
10if supported lchmod; then
11	echo "1..1349"
12else
13	echo "1..1323"
14fi
15
16n0=`namegen`
17n1=`namegen`
18n2=`namegen`
19
20expect 0 mkdir ${n2} 0755
21cdir=`pwd`
22cd ${n2}
23
24# super-user can always modify ownership
25for type in regular dir fifo block char socket symlink; do
26	if [ "${type}" != "symlink" ]; then
27		create_file ${type} ${n0}
28
29		expect 0 chown ${n0} 123 456
30		expect 123,456 lstat ${n0} uid,gid
31		expect 0 chown ${n0} 0 0
32		expect 0,0 lstat ${n0} uid,gid
33
34		expect 0 symlink ${n0} ${n1}
35		uidgid=`${fstest} lstat ${n1} uid,gid`
36		expect 0 chown ${n1} 123 456
37		expect 123,456 stat ${n1} uid,gid
38		expect 123,456 stat ${n0} uid,gid
39		expect ${uidgid} lstat ${n1} uid,gid
40		expect 0 unlink ${n1}
41
42		if [ "${type}" = "dir" ]; then
43			expect 0 rmdir ${n0}
44		else
45			expect 0 unlink ${n0}
46		fi
47	fi
48
49	create_file ${type} ${n0}
50	expect 0 lchown ${n0} 123 456
51	expect 123,456 lstat ${n0} uid,gid
52	if [ "${type}" = "dir" ]; then
53		expect 0 rmdir ${n0}
54	else
55		expect 0 unlink ${n0}
56	fi
57done
58
59# non-super-user can modify file group if he is owner of a file and
60# gid he is setting is in his groups list.
61for type in regular dir fifo block char socket symlink; do
62	if [ "${type}" != "symlink" ]; then
63		create_file ${type} ${n0}
64
65		expect 0 chown ${n0} 65534 65533
66		expect 65534,65533 lstat ${n0} uid,gid
67		expect 0 -u 65534 -g 65532,65531 -- chown ${n0} -1 65532
68		expect 65534,65532 lstat ${n0} uid,gid
69		expect 0 -u 65534 -g 65532,65531 chown ${n0} 65534 65531
70		expect 65534,65531 lstat ${n0} uid,gid
71
72		expect 0 symlink ${n0} ${n1}
73		uidgid=`${fstest} lstat ${n1} uid,gid`
74		expect 0 chown ${n1} 65534 65533
75		expect 65534,65533 stat ${n0} uid,gid
76		expect 65534,65533 stat ${n1} uid,gid
77		expect ${uidgid} lstat ${n1} uid,gid
78		expect 0 -u 65534 -g 65532,65531 -- chown ${n1} -1 65532
79		expect 65534,65532 stat ${n0} uid,gid
80		expect 65534,65532 stat ${n1} uid,gid
81		expect ${uidgid} lstat ${n1} uid,gid
82		expect 0 -u 65534 -g 65532,65531 chown ${n1} 65534 65531
83		expect 65534,65531 stat ${n0} uid,gid
84		expect 65534,65531 stat ${n1} uid,gid
85		expect ${uidgid} lstat ${n1} uid,gid
86		expect 0 unlink ${n1}
87
88		if [ "${type}" = "dir" ]; then
89			expect 0 rmdir ${n0}
90		else
91			expect 0 unlink ${n0}
92		fi
93	fi
94
95	create_file ${type} ${n0}
96	expect 0 lchown ${n0} 65534 65533
97	expect 65534,65533 lstat ${n0} uid,gid
98	expect 0 -u 65534 -g 65532,65531 -- lchown ${n0} -1 65532
99	expect 65534,65532 lstat ${n0} uid,gid
100	expect 0 -u 65534 -g 65532,65531 lchown ${n0} 65534 65531
101	expect 65534,65531 lstat ${n0} uid,gid
102	if [ "${type}" = "dir" ]; then
103		expect 0 rmdir ${n0}
104	else
105		expect 0 unlink ${n0}
106	fi
107done
108
109# chown(2) return 0 if user is not owner of a file, but chown(2) is called
110# with both uid and gid equal to -1.
111for type in regular dir fifo block char socket symlink; do
112	if [ "${type}" != "symlink" ]; then
113		create_file ${type} ${n0}
114
115		expect 0 chown ${n0} 65534 65533
116		expect 0 -u 65532 -g 65531 -- chown ${n0} -1 -1
117		expect 65534,65533 stat ${n0} uid,gid
118
119		expect 0 symlink ${n0} ${n1}
120		uidgid=`${fstest} lstat ${n1} uid,gid`
121		expect 0 chown ${n1} 65534 65533
122		expect 65534,65533 stat ${n0} uid,gid
123		expect 65534,65533 stat ${n1} uid,gid
124		expect ${uidgid} lstat ${n1} uid,gid
125		expect 0 -u 65532 -g 65531 -- chown ${n0} -1 -1
126		expect 65534,65533 stat ${n0} uid,gid
127		expect 65534,65533 stat ${n1} uid,gid
128		expect ${uidgid} lstat ${n1} uid,gid
129		expect 0 unlink ${n1}
130
131		if [ "${type}" = "dir" ]; then
132			expect 0 rmdir ${n0}
133		else
134			expect 0 unlink ${n0}
135		fi
136	fi
137
138	create_file ${type} ${n0}
139	expect 0 lchown ${n0} 65534 65533
140	expect 0 -u 65532 -g 65531 -- lchown ${n0} -1 -1
141	expect 65534,65533 lstat ${n0} uid,gid
142	if [ "${type}" = "dir" ]; then
143		expect 0 rmdir ${n0}
144	else
145		expect 0 unlink ${n0}
146	fi
147done
148
149# when super-user calls chown(2), set-uid and set-gid bits may be removed.
150for type in regular dir fifo block char socket symlink; do
151	if [ "${type}" != "symlink" ]; then
152		create_file ${type} ${n0}
153
154		expect 0 chown ${n0} 65534 65533
155		expect 0 chmod ${n0} 06555
156		expect 06555,65534,65533 stat ${n0} mode,uid,gid
157		expect 0 chown ${n0} 65532 65531
158		expect "(06555|0555),65532,65531" stat ${n0} mode,uid,gid
159		expect 0 chmod ${n0} 06555
160		expect 06555,65532,65531 stat ${n0} mode,uid,gid
161		expect 0 chown ${n0} 0 0
162		expect "(06555|0555),0,0" stat ${n0} mode,uid,gid
163
164		expect 0 symlink ${n0} ${n1}
165		expect 0 chown ${n1} 65534 65533
166		expect 0 chmod ${n1} 06555
167		expect 06555,65534,65533 stat ${n0} mode,uid,gid
168		expect 06555,65534,65533 stat ${n1} mode,uid,gid
169		expect 0 chown ${n1} 65532 65531
170		expect "(06555|0555),65532,65531" stat ${n0} mode,uid,gid
171		expect "(06555|0555),65532,65531" stat ${n1} mode,uid,gid
172		expect 0 chmod ${n1} 06555
173		expect 06555,65532,65531 stat ${n0} mode,uid,gid
174		expect 06555,65532,65531 stat ${n1} mode,uid,gid
175		expect 0 chown ${n1} 0 0
176		expect "(06555|0555),0,0" stat ${n0} mode,uid,gid
177		expect "(06555|0555),0,0" stat ${n1} mode,uid,gid
178		expect 0 unlink ${n1}
179
180		if [ "${type}" = "dir" ]; then
181			expect 0 rmdir ${n0}
182		else
183			expect 0 unlink ${n0}
184		fi
185	fi
186
187	if [ "${type}" != "symlink" ] || supported lchmod; then
188		create_file ${type} ${n0}
189		expect 0 lchown ${n0} 65534 65533
190		if supported lchmod; then
191			expect 0 lchmod ${n0} 06555
192		else
193			expect 0 chmod ${n0} 06555
194		fi
195		expect 06555,65534,65533 lstat ${n0} mode,uid,gid
196		expect 0 lchown ${n0} 65532 65531
197		expect "(06555|0555),65532,65531" lstat ${n0} mode,uid,gid
198		if supported lchmod; then
199			expect 0 lchmod ${n0} 06555
200		else
201			expect 0 chmod ${n0} 06555
202		fi
203		expect 06555,65532,65531 lstat ${n0} mode,uid,gid
204		expect 0 lchown ${n0} 0 0
205		expect "(06555|0555),0,0" lstat ${n0} mode,uid,gid
206		if [ "${type}" = "dir" ]; then
207			expect 0 rmdir ${n0}
208		else
209			expect 0 unlink ${n0}
210		fi
211	fi
212done
213
214# when non-super-user calls chown(2) successfully, set-uid and set-gid bits may
215# be removed, except when both uid and gid are equal to -1.
216for type in regular dir fifo block char socket symlink; do
217	#
218	# Linux makes a destinction for behavior when an executable file vs a
219	# non-executable file. From chmod(2):
220	#
221	#   When the owner or group of an executable file are changed by an
222	#   unprivileged user the S_ISUID and S_ISGID mode bits are cleared.
223	#
224	# I believe in this particular case, the behavior's bugged.
225	#
226	if [ "${type}" = "dir" -a "${os}" = "Linux" ]; then
227		_todo_msg="Linux doesn't clear the SGID/SUID bits for directories, despite the description noted"
228	else
229		_todo_msg=
230	fi
231	if [ "${type}" != "symlink" ]; then
232		create_file ${type} ${n0}
233
234		expect 0 chown ${n0} 65534 65533
235		expect 0 chmod ${n0} 06555
236		expect 06555,65534,65533 stat ${n0} mode,uid,gid
237		expect 0 -u 65534 -g 65533,65532 chown ${n0} 65534 65532
238		[ -n "${_todo_msg}" ] && todo "Linux" "${_todo_msg}"
239		expect 0555,65534,65532 stat ${n0} mode,uid,gid
240		expect 0 chmod ${n0} 06555
241		expect 06555,65534,65532 stat ${n0} mode,uid,gid
242		expect 0 -u 65534 -g 65533,65532 -- chown ${n0} -1 65533
243		[ -n "${_todo_msg}" ] && todo "Linux" "${_todo_msg}"
244		expect 0555,65534,65533 stat ${n0} mode,uid,gid
245		expect 0 chmod ${n0} 06555
246		expect 06555,65534,65533 stat ${n0} mode,uid,gid
247		expect 0 -u 65534 -g 65533,65532 -- chown ${n0} -1 -1
248		expect "(06555|0555),65534,65533" stat ${n0} mode,uid,gid
249
250		expect 0 symlink ${n0} ${n1}
251		expect 0 chown ${n1} 65534 65533
252		expect 0 chmod ${n1} 06555
253		expect 06555,65534,65533 stat ${n0} mode,uid,gid
254		expect 06555,65534,65533 stat ${n1} mode,uid,gid
255		expect 0 -u 65534 -g 65533,65532 chown ${n1} 65534 65532
256		[ -n "${_todo_msg}" ] && todo "Linux" "${_todo_msg}"
257		expect 0555,65534,65532 stat ${n0} mode,uid,gid
258		[ -n "${_todo_msg}" ] && todo "Linux" "${_todo_msg}"
259		expect 0555,65534,65532 stat ${n1} mode,uid,gid
260		expect 0 chmod ${n1} 06555
261		expect 06555,65534,65532 stat ${n0} mode,uid,gid
262		expect 06555,65534,65532 stat ${n1} mode,uid,gid
263		expect 0 -u 65534 -g 65533,65532 -- chown ${n1} -1 65533
264		[ -n "${_todo_msg}" ] && todo "Linux" "${_todo_msg}"
265		expect 0555,65534,65533 stat ${n0} mode,uid,gid
266		[ -n "${_todo_msg}" ] && todo "Linux" "${_todo_msg}"
267		expect 0555,65534,65533 stat ${n1} mode,uid,gid
268		expect 0 chmod ${n1} 06555
269		expect 06555,65534,65533 stat ${n0} mode,uid,gid
270		expect 06555,65534,65533 stat ${n1} mode,uid,gid
271		expect 0 -u 65534 -g 65533,65532 -- chown ${n1} -1 -1
272		expect "(06555|0555),65534,65533" stat ${n0} mode,uid,gid
273		expect "(06555|0555),65534,65533" stat ${n1} mode,uid,gid
274		expect 0 unlink ${n1}
275
276		if [ "${type}" = "dir" ]; then
277			expect 0 rmdir ${n0}
278		else
279			expect 0 unlink ${n0}
280		fi
281	fi
282
283	if [ "${type}" != "symlink" ] || supported lchmod; then
284		create_file ${type} ${n0}
285
286		expect 0 lchown ${n0} 65534 65533
287		if supported lchmod; then
288			expect 0 lchmod ${n0} 06555
289		else
290			expect 0 chmod ${n0} 06555
291		fi
292		expect 06555,65534,65533 lstat ${n0} mode,uid,gid
293		expect 0 -u 65534 -g 65533,65532 lchown ${n0} 65534 65532
294		[ -n "${_todo_msg}" ] && todo "Linux" "${_todo_msg}"
295		expect 0555,65534,65532 lstat ${n0} mode,uid,gid
296		if supported lchmod; then
297			expect 0 lchmod ${n0} 06555
298		else
299			expect 0 chmod ${n0} 06555
300		fi
301		expect 06555,65534,65532 lstat ${n0} mode,uid,gid
302		expect 0 -u 65534 -g 65533,65532 -- lchown ${n0} -1 65533
303		[ -n "${_todo_msg}" ] && todo "Linux" "${_todo_msg}"
304		expect 0555,65534,65533 lstat ${n0} mode,uid,gid
305		if supported lchmod; then
306			expect 0 lchmod ${n0} 06555
307		else
308			expect 0 chmod ${n0} 06555
309		fi
310		expect 06555,65534,65533 lstat ${n0} mode,uid,gid
311		expect 0 -u 65534 -g 65533,65532 -- lchown ${n0} -1 -1
312		expect "(06555|0555),65534,65533" lstat ${n0} mode,uid,gid
313
314		if [ "${type}" = "dir" ]; then
315			expect 0 rmdir ${n0}
316		else
317			expect 0 unlink ${n0}
318		fi
319	fi
320done
321
322# successful chown(2) call (except uid and gid equal to -1) updates ctime.
323for type in regular dir fifo block char socket symlink; do
324	if [ "${type}" != "symlink" ]; then
325		create_file ${type} ${n0}
326
327		ctime1=`${fstest} stat ${n0} ctime`
328		sleep 1
329		expect 0 chown ${n0} 65534 65533
330		expect 65534,65533 stat ${n0} uid,gid
331		ctime2=`${fstest} stat ${n0} ctime`
332		test_check $ctime1 -lt $ctime2
333		ctime1=`${fstest} stat ${n0} ctime`
334		sleep 1
335		expect 0 -u 65534 -g 65532 chown ${n0} 65534 65532
336		expect 65534,65532 stat ${n0} uid,gid
337		ctime2=`${fstest} stat ${n0} ctime`
338		test_check $ctime1 -lt $ctime2
339
340		expect 0 symlink ${n0} ${n1}
341		ctime1=`${fstest} stat ${n1} ctime`
342		sleep 1
343		expect 0 chown ${n1} 65533 65532
344		expect 65533,65532 stat ${n1} uid,gid
345		ctime2=`${fstest} stat ${n1} ctime`
346		test_check $ctime1 -lt $ctime2
347		ctime1=`${fstest} stat ${n1} ctime`
348		sleep 1
349		expect 0 -u 65533 -g 65531 chown ${n1} 65533 65531
350		expect 65533,65531 stat ${n1} uid,gid
351		ctime2=`${fstest} stat ${n1} ctime`
352		test_check $ctime1 -lt $ctime2
353		expect 0 unlink ${n1}
354
355		if [ "${type}" = "dir" ]; then
356			expect 0 rmdir ${n0}
357		else
358			expect 0 unlink ${n0}
359		fi
360	fi
361
362	create_file ${type} ${n0}
363
364	ctime1=`${fstest} lstat ${n0} ctime`
365	sleep 1
366	expect 0 lchown ${n0} 65534 65533
367	expect 65534,65533 lstat ${n0} uid,gid
368	ctime2=`${fstest} lstat ${n0} ctime`
369	test_check $ctime1 -lt $ctime2
370	ctime1=`${fstest} lstat ${n0} ctime`
371	sleep 1
372	expect 0 -u 65534 -g 65532 lchown ${n0} 65534 65532
373	expect 65534,65532 lstat ${n0} uid,gid
374	ctime2=`${fstest} lstat ${n0} ctime`
375	test_check $ctime1 -lt $ctime2
376
377	if [ "${type}" = "dir" ]; then
378		expect 0 rmdir ${n0}
379	else
380		expect 0 unlink ${n0}
381	fi
382done
383
384for type in regular dir fifo block char socket symlink; do
385	if [ "${type}" != "symlink" ]; then
386		create_file ${type} ${n0}
387
388		ctime1=`${fstest} stat ${n0} ctime`
389		sleep 1
390		expect 0 -- chown ${n0} -1 -1
391		ctime2=`${fstest} stat ${n0} ctime`
392		todo Linux "According to POSIX: If both owner and group are -1, the times need not be updated."
393		test_check $ctime1 -eq $ctime2
394		expect 0,0 stat ${n0} uid,gid
395
396		expect 0 symlink ${n0} ${n1}
397		ctime1=`${fstest} stat ${n1} ctime`
398		sleep 1
399		expect 0 -- chown ${n1} -1 -1
400		ctime2=`${fstest} stat ${n1} ctime`
401		todo Linux "According to POSIX: If both owner and group are -1, the times need not be updated."
402		test_check $ctime1 -eq $ctime2
403		expect 0,0 stat ${n1} uid,gid
404		expect 0 unlink ${n1}
405
406		if [ "${type}" = "dir" ]; then
407			expect 0 rmdir ${n0}
408		else
409			expect 0 unlink ${n0}
410		fi
411	fi
412
413	create_file ${type} ${n0}
414
415	ctime1=`${fstest} lstat ${n0} ctime`
416	sleep 1
417	expect 0 -- lchown ${n0} -1 -1
418	ctime2=`${fstest} lstat ${n0} ctime`
419	todo Linux "According to POSIX: If both owner and group are -1, the times need not be updated."
420	test_check $ctime1 -eq $ctime2
421	expect 0,0 lstat ${n0} uid,gid
422
423	if [ "${type}" = "dir" ]; then
424		expect 0 rmdir ${n0}
425	else
426		expect 0 unlink ${n0}
427	fi
428done
429
430# unsuccessful chown(2) does not update ctime.
431for type in regular dir fifo block char socket symlink; do
432	if [ "${type}" != "symlink" ]; then
433		create_file ${type} ${n0}
434
435		ctime1=`${fstest} stat ${n0} ctime`
436		sleep 1
437		expect EPERM -u 65534 -- chown ${n0} 65534 -1
438		expect EPERM -u 65534 -g 65534 -- chown ${n0} -1 65534
439		expect EPERM -u 65534 -g 65534 chown ${n0} 65534 65534
440		ctime2=`${fstest} stat ${n0} ctime`
441		test_check $ctime1 -eq $ctime2
442		expect 0,0 stat ${n0} uid,gid
443
444		expect 0 symlink ${n0} ${n1}
445		ctime1=`${fstest} stat ${n1} ctime`
446		sleep 1
447		expect EPERM -u 65534 -- chown ${n1} 65534 -1
448		expect EPERM -u 65534 -g 65534 -- chown ${n1} -1 65534
449		expect EPERM -u 65534 -g 65534 chown ${n1} 65534 65534
450		ctime2=`${fstest} stat ${n1} ctime`
451		test_check $ctime1 -eq $ctime2
452		expect 0,0 stat ${n1} uid,gid
453		expect 0 unlink ${n1}
454
455		if [ "${type}" = "dir" ]; then
456			expect 0 rmdir ${n0}
457		else
458			expect 0 unlink ${n0}
459		fi
460	fi
461
462	create_file ${type} ${n0}
463
464	ctime1=`${fstest} lstat ${n0} ctime`
465	sleep 1
466	expect EPERM -u 65534 -- lchown ${n0} 65534 -1
467	expect EPERM -u 65534 -g 65534 -- lchown ${n0} -1 65534
468	expect EPERM -u 65534 -g 65534 lchown ${n0} 65534 65534
469	ctime2=`${fstest} lstat ${n0} ctime`
470	test_check $ctime1 -eq $ctime2
471	expect 0,0 lstat ${n0} uid,gid
472
473	if [ "${type}" = "dir" ]; then
474		expect 0 rmdir ${n0}
475	else
476		expect 0 unlink ${n0}
477	fi
478done
479
480cd ${cdir}
481expect 0 rmdir ${n2}
482