1#!/bin/ksh -p
2#
3# CDDL HEADER START
4#
5# The contents of this file are subject to the terms of the
6# Common Development and Distribution License (the "License").
7# You may not use this file except in compliance with the License.
8#
9# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10# or http://www.opensolaris.org/os/licensing.
11# See the License for the specific language governing permissions
12# and limitations under the License.
13#
14# When distributing Covered Code, include this CDDL HEADER in each
15# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16# If applicable, add the following below this CDDL HEADER, with the
17# fields enclosed by brackets "[]" replaced with your own identifying
18# information: Portions Copyright [yyyy] [name of copyright owner]
19#
20# CDDL HEADER END
21#
22
23#
24# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
25# Use is subject to license terms.
26#
27
28#
29# Copyright (c) 2016 by Delphix. All rights reserved.
30#
31
32. $STF_SUITE/tests/functional/acl/acl_common.kshlib
33
34#
35# DESCRIPTION:
36# Verify that '/usr/bin/mv' supports ZFS ACL
37#
38# STRATEGY:
39# 1. Create file and  directory in zfs filesystem
40# 2. Set special ACE to the file and directory
41# 3. Copy the file/directory within and across zfs file system
42# 4. Verify that the ACL of file/directroy is not changed
43#
44
45verify_runnable "both"
46
47function cleanup
48{
49	(( ${#cwd} != 0 )) && cd $cwd
50	[[ -d $TESTDIR ]] && log_must rm -rf $TESTDIR/*
51	[[ -d $TESTDIR1 ]] && log_must rm -rf $TESTDIR1
52	(( ${#mask} != 0 )) && log_must umask $mask
53}
54
55function testing_mv #<flag for file|dir> <file1|dir1> <file2|dir2>
56{
57	typeset flag=$1
58	set -A obj $2 $3
59	typeset -i i=0
60	typeset orig_acl=""
61	typeset orig_mode=""
62	typeset dst_acl=""
63	typeset dst_mode=""
64
65	if [[ $flag == "f" ]]; then
66	while (( i < ${#obj[*]} ))
67	do
68		orig_acl="$(get_acl ${obj[i]})"
69		orig_mode="$(get_mode ${obj[i]})"
70		if (( i < 1 )); then
71			log_must mv ${obj[i]} $dst_file
72			dst_acl=$(get_acl $dst_file)
73			dst_mode=$(get_mode $dst_file)
74		else
75			log_must mv ${obj[i]} $TESTDIR1
76			dst_acl=$(get_acl $TESTDIR1/${obj[i]})
77			dst_mode=$(get_mode $TESTDIR1/${obj[i]})
78		fi
79
80		if [[ "$dst_mode" != "$orig_mode" ]] || \
81			[[ "$dst_acl" != "$orig_acl" ]]; then
82			log_fail "mv fails to keep the acl for file."
83		fi
84
85		(( i = i + 1 ))
86	done
87	else
88	while (( i < ${#obj[*]} ))
89	do
90		typeset orig_nested_acl=""
91		typeset orig_nested_mode=""
92		typeset dst_nested_acl=""
93		typeset dst_nested_mode=""
94
95		orig_acl=$(get_acl ${obj[i]})
96		orig_mode=$(get_mode ${obj[i]})
97		orig_nested_acl=$(get_acl ${obj[i]}/$nestedfile)
98		orig_nested_mode=$(get_mode ${obj[i]}/$nestedfile)
99		if (( i < 1 )); then
100			log_must mv ${obj[i]} $dst_dir
101			dst_acl=$(get_acl $dst_dir)
102			dst_mode=$(get_mode $dst_dir)
103			dst_nested_acl=$(get_acl $dst_dir/$nestedfile)
104			dst_nested_mode=$(get_mode $dst_dir/$nestedfile)
105		else
106			log_must mv ${obj[i]} $TESTDIR1
107			dst_acl=$(get_acl $TESTDIR1/${obj[i]})
108			dst_mode=$(get_mode $TESTDIR1/${obj[i]})
109			dst_nested_acl=$(get_acl \
110				$TESTDIR1/${obj[i]}/$nestedfile)
111			dst_nested_mode=$(get_mode \
112				$TESTDIR1/${obj[i]}/$nestedfile)
113		fi
114
115		if [[ "$orig_mode" != "$dst_mode" ]] || \
116		   [[ "$orig_acl" != "$dst_acl" ]] || \
117		   [[ "$dst_nested_mode" != "$orig_nested_mode" ]] || \
118		   [[ "$dst_nested_acl" != "$orig_nested_acl" ]]; then
119			log_fail "mv fails to recursively keep the acl for " \
120				"directory."
121		fi
122
123		(( i = i + 1 ))
124	done
125	fi
126}
127
128log_assert "Verify that 'mv' supports ZFS ACLs."
129
130log_onexit cleanup
131
132spec_ace="everyone@:execute:allow"
133set -A orig_file "origfile1.$$" "origfile2.$$"
134set -A orig_dir "origdir1.$$" "origdir2.$$"
135nestedfile="nestedfile.$$"
136dst_file=dstfile.$$
137dst_dir=dstdir.$$
138cwd=$PWD
139mask=`umask`
140umask 0022
141
142#
143# This assertion should only test 'mv' within the same filesystem
144#
145TESTDIR1=$TESTDIR/testdir1$$
146
147[[ ! -d $TESTDIR1 ]] && \
148	log_must mkdir -p $TESTDIR1
149
150log_note "Create files and directories and set special ace on them for testing. "
151cd $TESTDIR
152typeset -i i=0
153while (( i < ${#orig_file[*]} ))
154do
155	log_must touch ${orig_file[i]}
156	log_must chmod A0+$spec_ace ${orig_file[i]}
157
158	(( i = i + 1 ))
159done
160i=0
161while (( i < ${#orig_dir[*]} ))
162do
163	log_must mkdir ${orig_dir[i]}
164	log_must touch ${orig_dir[i]}/$nestedfile
165
166	for obj in ${orig_dir[i]} ${orig_dir[i]}/$nestedfile; do
167		log_must chmod A0+$spec_ace $obj
168	done
169
170	(( i = i + 1 ))
171done
172
173testing_mv "f" ${orig_file[0]} ${orig_file[1]}
174testing_mv "d" ${orig_dir[0]} ${orig_dir[1]}
175
176log_pass "'mv' succeeds to support ZFS ACLs."
177