xref: /freebsd/usr.sbin/chown/tests/chown_test.sh (revision d0b2dbfa0ecf2bbc9709efc5e20baf8e4b44bbbf)
1c19afa1cSEnji Cooper#
2c19afa1cSEnji Cooper# Copyright (c) 2017 Dell EMC
3c19afa1cSEnji Cooper# All rights reserved.
4c19afa1cSEnji Cooper#
5c19afa1cSEnji Cooper# Redistribution and use in source and binary forms, with or without
6c19afa1cSEnji Cooper# modification, are permitted provided that the following conditions
7c19afa1cSEnji Cooper# are met:
8c19afa1cSEnji Cooper# 1. Redistributions of source code must retain the above copyright
9c19afa1cSEnji Cooper#    notice, this list of conditions and the following disclaimer.
10c19afa1cSEnji Cooper# 2. Redistributions in binary form must reproduce the above copyright
11c19afa1cSEnji Cooper#    notice, this list of conditions and the following disclaimer in the
12c19afa1cSEnji Cooper#    documentation and/or other materials provided with the distribution.
13c19afa1cSEnji Cooper#
14c19afa1cSEnji Cooper# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15c19afa1cSEnji Cooper# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16c19afa1cSEnji Cooper# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17c19afa1cSEnji Cooper# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18c19afa1cSEnji Cooper# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19c19afa1cSEnji Cooper# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20c19afa1cSEnji Cooper# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21c19afa1cSEnji Cooper# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22c19afa1cSEnji Cooper# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23c19afa1cSEnji Cooper# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24c19afa1cSEnji Cooper# SUCH DAMAGE.
25c19afa1cSEnji Cooper#
26c19afa1cSEnji Cooper
27*6e810e51SGlen Barberget_filesystem()
28*6e810e51SGlen Barber{
29*6e810e51SGlen Barber	local mountpoint=$1
30*6e810e51SGlen Barber
31*6e810e51SGlen Barber	df -T $mountpoint | tail -n 1 | cut -wf 2
32*6e810e51SGlen Barber}
33*6e810e51SGlen Barber
34c19afa1cSEnji Cooperatf_test_case RH_flag
35c19afa1cSEnji CooperRH_flag_head()
36c19afa1cSEnji Cooper{
37c19afa1cSEnji Cooper	atf_set	"descr" "Verify that setting ownership recursively via -R doesn't " \
38c19afa1cSEnji Cooper			"affect symlinks specified via the arguments when -H " \
39c19afa1cSEnji Cooper			"is specified"
40c19afa1cSEnji Cooper	atf_set "require.user" "root"
41c19afa1cSEnji Cooper}
42c19afa1cSEnji CooperRH_flag_body()
43c19afa1cSEnji Cooper{
44c19afa1cSEnji Cooper	atf_check mkdir -p A/B
45c19afa1cSEnji Cooper	atf_check ln -s B A/C
46c19afa1cSEnji Cooper	atf_check chown -h 42:42 A/C
47c19afa1cSEnji Cooper	atf_check -o inline:'0:0\n0:0\n42:42\n' stat -f '%u:%g' A A/B A/C
48c19afa1cSEnji Cooper	atf_check chown -RH 84:84 A
49c19afa1cSEnji Cooper	atf_check -o inline:'84:84\n84:84\n84:84\n' stat -f '%u:%g' A A/B A/C
50c19afa1cSEnji Cooper	atf_check chown -RH 126:126 A/C
51c19afa1cSEnji Cooper	atf_check -o inline:'84:84\n126:126\n84:84\n' stat -f '%u:%g' A A/B A/C
52c19afa1cSEnji Cooper}
53c19afa1cSEnji Cooper
54c19afa1cSEnji Cooperatf_test_case RL_flag
55c19afa1cSEnji CooperRL_flag_head()
56c19afa1cSEnji Cooper{
57c19afa1cSEnji Cooper	atf_set	"descr" "Verify that setting ownership recursively via -R doesn't " \
58c19afa1cSEnji Cooper			"affect symlinks specified via the arguments when -L " \
59c19afa1cSEnji Cooper			"is specified"
60c19afa1cSEnji Cooper	atf_set "require.user" "root"
61c19afa1cSEnji Cooper}
62c19afa1cSEnji CooperRL_flag_body()
63c19afa1cSEnji Cooper{
64c19afa1cSEnji Cooper	atf_check mkdir -p A/B
65c19afa1cSEnji Cooper	atf_check ln -s B A/C
66c19afa1cSEnji Cooper	atf_check chown -h 42:42 A/C
67c19afa1cSEnji Cooper	atf_check -o inline:'0:0\n0:0\n42:42\n' stat -f '%u:%g' A A/B A/C
68c19afa1cSEnji Cooper	atf_check chown -RL 84:84 A
69c19afa1cSEnji Cooper	atf_check -o inline:'84:84\n84:84\n42:42\n' stat -f '%u:%g' A A/B A/C
70c19afa1cSEnji Cooper	atf_check chown -RL 126:126 A/C
71c19afa1cSEnji Cooper	atf_check -o inline:'84:84\n126:126\n42:42\n' stat -f '%u:%g' A A/B A/C
72c19afa1cSEnji Cooper}
73c19afa1cSEnji Cooper
74c19afa1cSEnji Cooperatf_test_case RP_flag
75c19afa1cSEnji CooperRP_flag_head()
76c19afa1cSEnji Cooper{
77c19afa1cSEnji Cooper	atf_set	"descr" "Verify that setting ownership recursively via -R " \
78c19afa1cSEnji Cooper			"doesn't affect symlinks specified via the arguments " \
79c19afa1cSEnji Cooper			"when -P is specified"
80c19afa1cSEnji Cooper	atf_set "require.user" "root"
81c19afa1cSEnji Cooper}
82c19afa1cSEnji CooperRP_flag_body()
83c19afa1cSEnji Cooper{
84c19afa1cSEnji Cooper	atf_check mkdir -p A/B
85c19afa1cSEnji Cooper	atf_check ln -s B A/C
86c19afa1cSEnji Cooper	atf_check chown -h 42:42 A/C
87c19afa1cSEnji Cooper	atf_check -o inline:'0:0\n0:0\n42:42\n' stat -f '%u:%g' A A/B A/C
88c19afa1cSEnji Cooper	atf_check chown -RP 84:84 A
89c19afa1cSEnji Cooper	atf_check -o inline:'84:84\n84:84\n84:84\n' stat -f '%u:%g' A A/B A/C
90c19afa1cSEnji Cooper	atf_check chown -RP 126:126 A/C
91c19afa1cSEnji Cooper	atf_check -o inline:'84:84\n84:84\n126:126\n' stat -f '%u:%g' A A/B A/C
92c19afa1cSEnji Cooper}
93c19afa1cSEnji Cooper
94c19afa1cSEnji Cooperatf_test_case f_flag cleanup
95c19afa1cSEnji Cooperf_flag_head()
96c19afa1cSEnji Cooper{
97c19afa1cSEnji Cooper	atf_set	"descr" "Verify that setting a mode for a file with -f " \
98c19afa1cSEnji Cooper			"doesn't emit an error message/exit with a non-zero " \
99c19afa1cSEnji Cooper			"code"
100c19afa1cSEnji Cooper	atf_set "require.user" "root"
101c19afa1cSEnji Cooper}
102c19afa1cSEnji Cooper
103c19afa1cSEnji Cooperf_flag_body()
104c19afa1cSEnji Cooper{
105c19afa1cSEnji Cooper	atf_check truncate -s 0 foo bar
106c19afa1cSEnji Cooper	atf_check chown 0:0 foo bar
107*6e810e51SGlen Barber	case "$(get_filesystem .)" in
108*6e810e51SGlen Barber	zfs)
109*6e810e51SGlen Barber		atf_expect_fail "ZFS does not support UF_IMMUTABLE; returns EPERM"
110*6e810e51SGlen Barber		;;
111*6e810e51SGlen Barber	esac
112c19afa1cSEnji Cooper	atf_check chflags uchg foo
113c19afa1cSEnji Cooper	atf_check -e not-empty -s not-exit:0 chown 42:42 foo bar
114c19afa1cSEnji Cooper	atf_check -o inline:'0:0\n42:42\n' stat -f '%u:%g' foo bar
115c19afa1cSEnji Cooper	atf_check -s exit:0 chown -f 84:84 foo bar
116c19afa1cSEnji Cooper	atf_check -o inline:'0:0\n84:84\n' stat -f '%u:%g' foo bar
117c19afa1cSEnji Cooper}
118c19afa1cSEnji Cooper
119c19afa1cSEnji Cooperf_flag_cleanup()
120c19afa1cSEnji Cooper{
121*6e810e51SGlen Barber	chflags 0 foo || :
122c19afa1cSEnji Cooper}
123c19afa1cSEnji Cooper
124c19afa1cSEnji Cooperatf_test_case h_flag
125c19afa1cSEnji Cooperh_flag_head()
126c19afa1cSEnji Cooper{
127c19afa1cSEnji Cooper	atf_set	"descr" "Verify that setting a mode for a file with -f " \
128c19afa1cSEnji Cooper			"doesn't emit an error message/exit with a non-zero " \
129c19afa1cSEnji Cooper			"code"
130c19afa1cSEnji Cooper	atf_set "require.user" "root"
131c19afa1cSEnji Cooper}
132c19afa1cSEnji Cooper
133c19afa1cSEnji Cooperh_flag_body()
134c19afa1cSEnji Cooper{
135c19afa1cSEnji Cooper	atf_check truncate -s 0 foo
136c19afa1cSEnji Cooper	atf_check -o inline:'0:0\n' stat -f '%u:%g' foo
137c19afa1cSEnji Cooper	atf_check ln -s foo bar
138c19afa1cSEnji Cooper	atf_check -o inline:'0:0\n0:0\n' stat -f '%u:%g' foo bar
139c19afa1cSEnji Cooper	atf_check chown -h 42:42 bar
140c19afa1cSEnji Cooper	atf_check -o inline:'0:0\n42:42\n' stat -f '%u:%g' foo bar
141c19afa1cSEnji Cooper	atf_check chown 84:84 bar
142c19afa1cSEnji Cooper	atf_check -o inline:'84:84\n42:42\n' stat -f '%u:%g' foo bar
143c19afa1cSEnji Cooper}
144c19afa1cSEnji Cooper
145c19afa1cSEnji Cooperatf_test_case v_flag
146c19afa1cSEnji Cooperv_flag_head()
147c19afa1cSEnji Cooper{
148c19afa1cSEnji Cooper	atf_set	"descr" "Verify that setting ownership with -v emits the " \
149c19afa1cSEnji Cooper			"file doesn't emit an error message/exit with a " \
150c19afa1cSEnji Cooper			"non-zero code"
151c19afa1cSEnji Cooper	atf_set "require.user" "root"
152c19afa1cSEnji Cooper}
153c19afa1cSEnji Cooperv_flag_body()
154c19afa1cSEnji Cooper{
155c19afa1cSEnji Cooper	atf_check truncate -s 0 foo bar
156c19afa1cSEnji Cooper	atf_check chown 0:0 foo
157c19afa1cSEnji Cooper	atf_check chown 42:42 bar
158c19afa1cSEnji Cooper	atf_check -o 'inline:bar\n' chown -v 0:0 foo bar
159c19afa1cSEnji Cooper	atf_check chown -v 0:0 foo bar
160c19afa1cSEnji Cooper	for f in foo bar; do
161c19afa1cSEnji Cooper		echo "$f: 0:0 -> 84:84";
162c19afa1cSEnji Cooper	done > output.txt
163c19afa1cSEnji Cooper	atf_check -o file:output.txt chown -vv 84:84 foo bar
164c19afa1cSEnji Cooper	atf_check chown -vv 84:84 foo bar
165c19afa1cSEnji Cooper}
166c19afa1cSEnji Cooper
167c19afa1cSEnji Coopermd_file="md.out"
168c19afa1cSEnji Cooperatf_test_case x_flag cleanup
169c19afa1cSEnji Cooperx_flag_head()
170c19afa1cSEnji Cooper{
171c19afa1cSEnji Cooper	atf_set	"descr" "Verify that setting a mode with -x doesn't set " \
172c19afa1cSEnji Cooper			"ownership across mountpoints"
173c19afa1cSEnji Cooper	atf_set "require.user" "root"
174c19afa1cSEnji Cooper}
175c19afa1cSEnji Cooperx_flag_body()
176c19afa1cSEnji Cooper{
177c19afa1cSEnji Cooper	atf_check -o save:$md_file mdconfig -a -t malloc -s 20m
178c19afa1cSEnji Cooper	if ! md_device=$(cat $md_file); then
179c19afa1cSEnji Cooper		atf_fail "cat $md_file failed"
180c19afa1cSEnji Cooper	fi
181c19afa1cSEnji Cooper	atf_check -o not-empty newfs /dev/$md_device
182c19afa1cSEnji Cooper	atf_check mkdir mnt
183c19afa1cSEnji Cooper	atf_check mount /dev/$md_device mnt
184c19afa1cSEnji Cooper	atf_check truncate -s 0 foo bar mnt/bazbaz
185c19afa1cSEnji Cooper	atf_check ln -s bar mnt/barbaz
186c19afa1cSEnji Cooper	atf_check ln -s ../foo mnt/foobaz
187c19afa1cSEnji Cooper	cd mnt
188c19afa1cSEnji Cooper	test_files="../foo ../bar barbaz bazbaz foobaz"
189c19afa1cSEnji Cooper	atf_check -o inline:'0:0\n0:0\n0:0\n0:0\n0:0\n' \
190c19afa1cSEnji Cooper	    stat -f '%u:%g' $test_files
191c19afa1cSEnji Cooper	atf_check chown -Rx 42:42 .
192c19afa1cSEnji Cooper	atf_check -o inline:'0:0\n0:0\n42:42\n42:42\n42:42\n' \
193c19afa1cSEnji Cooper	    stat -f '%u:%g' $test_files
194c19afa1cSEnji Cooper	atf_check chown -R 84:84 .
195c19afa1cSEnji Cooper	atf_check -o inline:'0:0\n0:0\n84:84\n84:84\n84:84\n' \
196c19afa1cSEnji Cooper	    stat -f '%u:%g' $test_files
197c19afa1cSEnji Cooper}
198c19afa1cSEnji Cooperx_flag_cleanup()
199c19afa1cSEnji Cooper{
200c19afa1cSEnji Cooper	if ! md_device=$(cat $md_file) || [ -z "$md_device" ]; then
201c19afa1cSEnji Cooper		echo "Couldn't get device from $md_file"
202c19afa1cSEnji Cooper		exit 0
203c19afa1cSEnji Cooper	fi
204c19afa1cSEnji Cooper	umount mnt
205c19afa1cSEnji Cooper	mdconfig -d -u $md_device
206c19afa1cSEnji Cooper}
207c19afa1cSEnji Cooper
208c19afa1cSEnji Cooperatf_init_test_cases()
209c19afa1cSEnji Cooper{
210c19afa1cSEnji Cooper	atf_add_test_case RH_flag
211c19afa1cSEnji Cooper	atf_add_test_case RL_flag
212c19afa1cSEnji Cooper	atf_add_test_case RP_flag
213c19afa1cSEnji Cooper	atf_add_test_case f_flag
214c19afa1cSEnji Cooper	atf_add_test_case h_flag
215c19afa1cSEnji Cooper	atf_add_test_case v_flag
216c19afa1cSEnji Cooper	atf_add_test_case x_flag
217c19afa1cSEnji Cooper}
218