4 # The contents of this file are subject to the terms of the
5 # Common Development and Distribution License (the "License").
6 # You may not use this file except in compliance with the License.
8 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 # or http://www.opensolaris.org/os/licensing.
10 # See the License for the specific language governing permissions
11 # and limitations under the License.
13 # When distributing Covered Code, include this CDDL HEADER in each
14 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 # If applicable, add the following below this CDDL HEADER, with the
16 # fields enclosed by brackets "[]" replaced with your own identifying
17 # information: Portions Copyright [yyyy] [name of copyright owner]
23 # Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 # Use is subject to license terms.
28 # Copyright (c) 2016, 2018 by Delphix. All rights reserved.
31 . $STF_SUITE/tests/functional/acl/acl.cfg
32 . $STF_SUITE/include/libtest.shlib
35 # Get the given file/directory access mode
37 # $1 object -- file or directroy
39 function get_mode #<obj>
42 if (( ${#obj} == 0 )); then
46 ls -ld $obj | awk '{print $1}'
50 # Get the given file/directory ACL
52 # $1 object -- file or directroy
54 function get_acl #<obj>
57 if (( ${#obj} == 0 )); then
61 ls -vd $obj | nawk '(NR != 1) {print $0}'
65 # Get the given file/directory ACL
67 # $1 object -- file or directroy
69 function get_compact_acl #<obj>
72 if (( ${#obj} == 0 )); then
76 ls -Vd $obj | nawk '(NR != 1) {print $0}'
80 # Check the given two files/directories have the same ACLs
82 # Return 0, if source object acl is equal to target object acl.
87 function compare_acls #<src> <tgt>
92 (( ${#src} == 0 || ${#tgt} == 0 )) && return 1
93 [[ $src == $tgt ]] && return 0
95 typeset tmpsrc=/tmp/compare_acls.src.$$
96 typeset tmptgt=/tmp/compare_acls.tgt.$$
98 get_acl $src > $tmpsrc
99 get_acl $tgt > $tmptgt
101 diff $tmpsrc $tmptgt > /dev/null 2>&1
103 rm -f $tmpsrc $tmptgt
105 if (( ret != 0 )); then
109 get_compact_acl $src > $tmpsrc
110 get_compact_acl $tgt > $tmptgt
111 diff $tmpsrc $tmptgt > /dev/null 2>&1
113 rm -f $tmpsrc $tmptgt
119 # Check that the given two objects have the same modes.
120 # Return 0, if their modes are equal with each other. Otherwise, return 1.
125 function compare_modes #<src> <tgt>
132 (( ${#src} == 0 || ${#tgt} == 0 )) && return 1
133 [[ $src == $tgt ]] && return 0
138 mode[i]=$(get_mode $obj)
143 [[ ${mode[0]} != ${mode[1]} ]] && return 1
149 # Check that the given two objects have the same xattrs.
150 # Return 0, if their xattrs are equal with each other. Otherwise, return 1.
155 function compare_xattrs #<src> <tgt>
160 (( ${#src} == 0 || ${#tgt} == 0 )) && return 1
161 [[ $src == $tgt ]] && return 0
163 typeset tmpsrc=/tmp/compare_xattrs.src.$$
164 typeset tmptgt=/tmp/compare_xattrs.tgt.$$
166 get_xattr $src > $tmpsrc
167 get_xattr $tgt > $tmptgt
169 diff $tmpsrc $tmptgt > /dev/null 2>&1
171 rm -f $tmpsrc $tmptgt
177 # Check '+' is set for a given file/directory with 'ls [-l]' command
179 # $1 object -- file or directory.
181 function plus_sign_check_l #<obj>
184 if (( ${#obj} == 0 )); then
188 ls -ld $obj | awk '{print $1}' | grep "+$" > /dev/null
194 # Check '+' is set for a given file/directory with 'ls [-v]' command
196 # $1 object -- file or directory.
198 function plus_sign_check_v #<obj>
201 if (( ${#obj} == 0 )); then
205 ls -vd $obj | awk '(NR == 1) {print $1}' | grep "+$" > /dev/null
211 # A wrapper function of c program
213 # $1 legal login name
214 # $2-n commands and options
216 function chgusr_exec #<login_name> <commands> [...]
223 # Export the current user for the following usr_exec operating.
225 # $1 legal login name
227 function set_cur_usr #<login_name>
229 export ZFS_ACL_CUR_USER=$1
233 # Run commands by $ZFS_ACL_CUR_USER
235 # $1-n commands and options
237 function usr_exec #<commands> [...]
239 chg_usr_exec "$ZFS_ACL_CUR_USER" $@
244 # Count how many ACEs for the speficied file or directory.
246 # $1 file or directroy name
248 function count_ACE #<file or dir name>
250 if [[ ! -e $1 ]]; then
251 log_note "Need input file or directroy name."
255 ls -vd $1 | nawk 'BEGIN {count=0}
256 (NR != 1)&&(/[0-9]:/) {count++}
263 # Get specified number ACE content of specified file or directory.
265 # $1 file or directory name
266 # $2 specified number
268 function get_ACE #<file or dir name> <specified number> <verbose|compact>
270 if [[ ! -e $1 || $2 -ge $(count_ACE $1) ]]; then
276 typeset format=${3:-verbose}
277 typeset -i next_num=-1
279 typeset tmpfile=/tmp/tmp_get_ACE.$$
288 *) log_fail "Invalid parameter as ($format), " \
289 "only verbose|compact is supported."
293 ls $args $file > $tmpfile
294 (( $? != 0 )) && log_fail "FAIL: ls $args $file > $tmpfile"
296 [[ -z $line ]] && continue
297 if [[ $args == -vd ]]; then
298 if [[ $line == "$num":* ]]; then
299 (( next_num = num + 1 ))
301 if [[ $line == "$next_num":* ]]; then
304 if (( next_num != -1 )); then
308 if (( next_num == num )); then
316 (( $? != 0 )) && log_fail "FAIL: rm -f $tmpfile"
320 # Cleanup exist user/group.
322 function cleanup_user_group
324 del_user $ZFS_ACL_ADMIN
326 del_user $ZFS_ACL_STAFF1
327 del_user $ZFS_ACL_STAFF2
328 del_group $ZFS_ACL_STAFF_GROUP
330 del_user $ZFS_ACL_OTHER1
331 del_user $ZFS_ACL_OTHER2
332 del_group $ZFS_ACL_OTHER_GROUP
338 # Clean up testfile and test directory
342 if [[ -d $TESTDIR ]]; then
349 # According to specified access or acl_spec, do relevant operating by using the
354 # $3 acl_spec or access
356 function rwx_node #user node acl_spec|access
362 if [[ $user == "" || $node == "" || $acl_spec == "" ]]; then
363 log_note "node or acl_spec are not defined."
367 if [[ -d $node ]]; then
369 *:read_data:*|read_data)
370 chgusr_exec $user ls -l $node > /dev/null 2>&1
372 *:write_data:*|write_data)
373 if [[ -f ${node}/tmpfile ]]; then
374 log_must rm -f ${node}/tmpfile
376 chgusr_exec $user touch ${node}/tmpfile > \
379 *"execute:"*|execute)
380 chgusr_exec $user find $node > /dev/null 2>&1
385 *:read_data:*|read_data)
386 chgusr_exec $user cat $node > /dev/null 2>&1
388 *:write_data:*|write_data)
389 chgusr_exec $user dd if=/usr/bin/ls of=$node > \
392 *"execute:"*|execute)
393 ZFS_ACL_ERR_STR=$(chgusr_exec $user $node 2>&1)
400 # Get the given file/directory xattr
402 # $1 object -- file or directroy
404 function get_xattr #<obj>
408 if (( ${#obj} == 0 )); then
412 for xattr in `runat $obj ls | \
413 /usr/bin/egrep -v -e SUNWattr_ro -e SUNWattr_rw` ; do
414 runat $obj sum $xattr
419 # Get the owner of a file/directory
421 function get_owner #node
426 if [[ -z $node ]]; then
427 log_fail "node are not defined."
430 if [[ -d $node ]]; then
431 value=$(ls -dl $node | awk '{print $3}')
432 elif [[ -e $node ]]; then
433 value=$(ls -l $node | awk '{print $3}')
440 # Get the group of a file/directory
442 function get_group #node
447 if [[ -z $node ]]; then
448 log_fail "node are not defined."
451 if [[ -d $node ]]; then
452 value=$(ls -dl $node | awk '{print $4}')
453 elif [[ -e $node ]]; then
454 value=$(ls -l $node | awk '{print $4}')
462 # Get the group name that a UID belongs to
464 function get_user_group #uid
469 if [[ -z $uid ]]; then
470 log_fail "UID not defined."
475 if [[ $? -eq 0 ]]; then
480 log_fail "Invalid UID (uid)."
485 # Get the specified item of the specified string
487 # $1: Item number, count from 0.
500 # This function calculate the specified directory files checksum and write
501 # to the specified array.
503 # $1 directory in which the files will be cksum.
504 # $2 file array name which was used to store file cksum information.
505 # $3 attribute array name which was used to store attribute information.
507 function cksum_files #<dir> <file_array_name> <attribute_array_name>
513 [[ ! -d $dir ]] && return
516 typeset files=$(ls file*)
520 while (( i < NUM_FILE )); do
521 typeset f=$(getitem $i $files)
522 eval $farr_name[$i]=\$\(\cksum $f\)
525 while (( j < NUM_ATTR )); do
526 eval $aarr_name[$n]=\$\(\runat \$f \cksum \
540 # This function compare two cksum results array.
542 # $1 The array name which stored the cksum before operation.
543 # $2 The array name which stored the cksum after operation.
545 function compare_cksum #<array1> <array2>
549 eval typeset -i count=\${#$before[@]}
552 while (( i < count )); do
553 eval typeset var1=\${$before[$i]}
554 eval typeset var2=\${$after[$i]}
556 if [[ $var1 != $var2 ]]; then
567 # This function calculate all the files cksum information in current directory
568 # and output them to the specified file.
570 # $1 directory from which the files will be cksum.
571 # $2 cksum output file
573 function record_cksum #<outfile>
578 [[ ! -d ${outfile%/*} ]] && usr_exec mkdir -p ${outfile%/*}
580 usr_exec cd $dir ; find . -depth -type f -exec cksum {} \\\; | \
582 usr_exec cd $dir ; find . -depth -type f -xattr -exec runat {} \
583 cksum attribute* \\\; | sort >> $outfile
587 # The function create_files creates the directories and files that the script
588 # will operate on to test extended attribute functionality.
590 # $1 The base directory in which to create directories and files.
592 function create_files #<directory>
596 [[ ! -d $basedir ]] && usr_exec mkdir -m 777 $basedir
597 [[ ! -d $RES_DIR ]] && usr_exec mkdir -m 777 $RES_DIR
598 [[ ! -d $INI_DIR ]] && usr_exec mkdir -m 777 $INI_DIR
599 [[ ! -d $TST_DIR ]] && usr_exec mkdir -m 777 $TST_DIR
600 [[ ! -d $TMP_DIR ]] && usr_exec mkdir -m 777 $TMP_DIR
603 # Create the original file and its attribute files.
605 [[ ! -a $RES_DIR/file ]] && \
606 usr_exec file_write -o create -f $RES_DIR/file \
608 [[ ! -a $RES_DIR/attribute ]] && \
609 usr_exec cp $RES_DIR/file $RES_DIR/attribute
615 while (( i < NUM_FILE )); do
616 typeset dstfile=$INI_DIR/file.$$.$i
617 usr_exec cp $RES_DIR/file $dstfile
620 while (( j < NUM_ATTR )); do
621 usr_exec runat $dstfile \
622 cp $RES_DIR/attribute ./attribute.$j