]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tests/sys/cddl/zfs/tests/acl/acl_common.kshlib
Merge llvm trunk r338150, and resolve conflicts.
[FreeBSD/FreeBSD.git] / tests / sys / cddl / zfs / tests / acl / acl_common.kshlib
1 # vim: filetype=sh
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 # $FreeBSD$
24
25 #
26 # Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
27 # Use is subject to license terms.
28 #
29 # ident "@(#)acl_common.kshlib  1.4     09/05/19 SMI"
30 #
31
32 . $STF_SUITE/include/libtest.kshlib
33
34 # FreeBSD doesn't support ZFS extended attributes.  It also doesn't support the
35 # same ACL mechanisms Solaris does for testing.
36 if [[ $os_name != "FreeBSD" ]]; then
37         export ZFS_XATTR="true"
38         export ZFS_ACL="true"
39 else
40         log_note "On FreeBSD most xattr and ACL tests are disabled"
41 fi
42
43 #
44 # Get the given file/directory access mode
45 #
46 # $1 object -- file or directroy
47 #
48 function get_mode #<obj>
49 {
50         typeset obj=$1
51         if (( ${#obj} == 0 )); then
52                 return 1
53         fi
54
55         $LS -ld $obj | $AWK '{print $1}'
56 }
57
58 #
59 # Get the given file/directory ACL
60 #
61 # $1 object -- file or directroy
62 #
63 function get_acl #<obj>
64 {
65         typeset obj=$1
66         if (( ${#obj} == 0 )); then
67                 return 1
68         fi
69
70         $LS -vd $obj | $NAWK '(NR != 1) {print $0}'
71 }
72
73 #
74 # Get the given file/directory ACL
75 #
76 # $1 object -- file or directroy
77 #
78 function get_compact_acl #<obj>
79 {
80         typeset obj=$1
81         if (( ${#obj} == 0 )); then
82                 return 1
83         fi
84
85         $LS -Vd $obj | $NAWK '(NR != 1) {print $0}'
86 }
87
88 #
89 # Check the given two files/directories have the same ACLs
90 #
91 # Return 0, if source object acl is equal to target object acl.
92
93 # $1 source object
94 # $2 target object
95 #
96 function compare_acls #<src> <tgt>
97 {
98         typeset src=$1
99         typeset tgt=$2
100
101         (( ${#src} == 0 || ${#tgt} == 0 )) && return 1
102         [[ $src == $tgt ]] && return 0
103
104         typeset tmpsrc=$TMPDIR/compare_acls.src.${TESTCASE_ID}
105         typeset tmptgt=$TMPDIR/compare_acls.tgt.${TESTCASE_ID}
106
107         get_acl $src > $tmpsrc
108         get_acl $tgt > $tmptgt
109         typeset -i ret=0
110         $DIFF $tmpsrc $tmptgt > /dev/null 2>&1
111         ret=$?  
112         $RM -f $tmpsrc $tmptgt
113
114         if (( ret != 0 )); then
115                 return $ret
116         fi
117
118         get_compact_acl $src > $tmpsrc
119         get_compact_acl $tgt > $tmptgt
120         $DIFF $tmpsrc $tmptgt > /dev/null 2>&1
121         ret=$?  
122         $RM -f $tmpsrc $tmptgt
123
124         return $ret
125 }
126
127 #
128 # Check that the given two objects have the same modes.
129 # Return 0, if their modes are equal with each other. Otherwise, return 1.
130 #
131 # $1 source object
132 # $2 target object
133 #
134 function compare_modes #<src> <tgt>
135 {
136         typeset src=$1
137         typeset tgt=$2
138         typeset -i i=0
139         set -A mode
140
141         (( ${#src} == 0 || ${#tgt} == 0 )) && return 1
142         [[ $src == $tgt ]] && return 0
143
144         typeset obj
145         for obj in $src $tgt
146         do
147                 mode[i]=$(get_mode $obj)
148
149                 (( i = i + 1 ))
150         done
151
152         [[ ${mode[0]} != ${mode[1]} ]] && return 1
153
154         return 0
155 }
156
157 #
158 # Check that the given two objects have the same xattrs.
159 # Return 0, if their xattrs are equal with each other. Otherwise, return 1.
160 #
161 # $1 source object
162 # $2 target object
163 #
164 function compare_xattrs #<src> <tgt>
165 {
166         typeset src=$1
167         typeset tgt=$2
168
169         (( ${#src} == 0 || ${#tgt} == 0 )) && return 1
170         [[ $src == $tgt ]] && return 0
171
172         typeset tmpsrc=$TMPDIR/compare_xattrs.src.${TESTCASE_ID}
173         typeset tmptgt=$TMPDIR/compare_xattrs.tgt.${TESTCASE_ID}
174
175         get_xattr $src > $tmpsrc
176         get_xattr $tgt > $tmptgt
177         typeset -i ret=0
178         $DIFF $tmpsrc $tmptgt > /dev/null 2>&1
179         ret=$?  
180         $RM -f $tmpsrc $tmptgt
181
182         return $ret
183 }
184
185 #
186 # Check '+' is set for a given file/directory with 'ls [-l]' command
187 #
188 # $1 object -- file or directory.
189 #
190 function plus_sign_check_l #<obj>
191 {
192         typeset obj=$1
193         if (( ${#obj} == 0 )); then
194                 return 1
195         fi
196
197         $LS -ld $obj | $AWK '{print $1}' | $GREP "+\>" > /dev/null
198
199         return $?
200 }
201
202 #
203 # Check '+' is set for a given file/directory with 'ls [-v]' command
204 #
205 # $1 object -- file or directory.
206 #
207 function plus_sign_check_v #<obj>
208 {
209         typeset obj=$1
210         if (( ${#obj} == 0 )); then
211                 return 1
212         fi
213
214         $LS -vd $obj | $NAWK '(NR == 1) {print $1}' | $GREP "+\>" > /dev/null
215
216         return $?
217 }
218
219 #
220 # A wrapper function of c program
221 #
222 # $1 legal login name
223 # $2-n commands and options
224 #
225 function chgusr_exec #<login_name> <commands> [...]
226 {
227         $CHG_USR_EXEC $@
228         return $?
229 }
230
231 #
232 # Export the current user for the following usr_exec operating.
233 #
234 # $1 legal login name
235 #
236 function set_cur_usr #<login_name>
237 {
238         export ZFS_ACL_CUR_USER=$1
239 }
240
241 #
242 # Run commands by $ZFS_ACL_CUR_USER
243 #
244 # $1-n commands and options
245 #
246 function usr_exec #<commands> [...]
247 {
248         $CHG_USR_EXEC "$ZFS_ACL_CUR_USER" $@
249         return $?
250 }
251
252 #
253 # Count how many ACEs for the specified file or directory.
254 #
255 # $1 file or directroy name
256 #
257 function count_ACE #<file or dir name>
258 {
259         if [[ ! -e $1 ]]; then
260                 log_note "Need input file or directroy name."
261                 return 1
262         fi
263
264         $LS -vd $1 | $NAWK 'BEGIN {count=0}
265                         (NR != 1)&&(/[0-9]:/) {count++}
266                         END {print count}'
267
268         return 0
269 }
270
271 #
272 # Get specified number ACE content of specified file or directory.
273 #
274 # $1 file or directory name
275 # $2 specified number
276 #
277 function get_ACE #<file or dir name> <specified number> <verbose|compact>
278 {
279         if [[ ! -e $1 || $2 -ge $(count_ACE $1) ]]; then
280                 return 1
281         fi
282
283         typeset file=$1
284         typeset -i num=$2
285         typeset format=${3:-verbose}
286         typeset -i next_num=-1
287
288         typeset tmpfile=$TMPDIR/tmp_get_ACE.${TESTCASE_ID}
289         typeset line=""
290         typeset args
291
292         case $format in
293                 verbose) args="-vd"
294                         ;;
295                 compact) args="-Vd"
296                         ;;
297                 *) log_fail "Invalid parameter as ($format), " \
298                         "only verbose|compact is supported."
299                         ;;
300         esac
301
302         $LS $args $file > $tmpfile
303         (( $? != 0 )) && log_fail "FAIL: $LS $args $file > $tmpfile"
304         while read line; do
305                 [[ -z $line ]] && continue
306                 if [[ $args == -vd ]]; then
307                         if [[ $line == "$num":* ]]; then
308                                 (( next_num = num + 1 ))
309                         fi
310                         if [[ $line == "$next_num":* ]]; then
311                                 break
312                         fi
313                         if (( next_num != -1 )); then
314                                 print -n $line
315                         fi
316                 else
317                         if (( next_num == num )); then
318                                 print -n $line
319                         fi
320                         (( next_num += 1 ))
321                 fi
322         done < $tmpfile
323
324         $RM -f $tmpfile
325         (( $? != 0 )) && log_fail "FAIL: $RM -f $tmpfile"
326 }
327
328 #
329 # Cleanup exist user/group.
330 #
331 function cleanup_user_group
332 {
333         del_user $ZFS_ACL_ADMIN
334
335         del_user $ZFS_ACL_STAFF1
336         del_user $ZFS_ACL_STAFF2
337         del_group $ZFS_ACL_STAFF_GROUP
338
339         del_user $ZFS_ACL_OTHER1
340         del_user $ZFS_ACL_OTHER2
341         del_group $ZFS_ACL_OTHER_GROUP
342
343         return 0
344 }
345
346 #
347 # Clean up testfile and test directory
348 #
349 function cleanup
350 {
351         if [[ -d $TESTDIR ]]; then
352                 cd $TESTDIR
353                 $RM -rf $TESTDIR/*
354         fi
355 }
356
357 #
358 # According to specified access or acl_spec, do relevant operating by using the
359 # specified user.
360 #
361 # $1 specified user
362 # $2 node
363 # $3 acl_spec or access
364 #
365 function rwx_node #user node acl_spec|access
366 {
367         typeset user=$1
368         typeset node=$2
369         typeset acl_spec=$3
370
371         if [[ $user == "" || $node == "" || $acl_spec == "" ]]; then
372                 log_note "node or acl_spec are not defined."
373                 return 1
374         fi
375
376         if [[ -d $node ]]; then
377                 case $acl_spec in
378                 *:read_data:*|read_data)
379                         chgusr_exec $user $LS -l $node > /dev/null 2>&1
380                         return $? ;;
381                 *:write_data:*|write_data)
382                         if [[ -f ${node}/tmpfile ]]; then
383                                 log_must $RM -f ${node}/tmpfile
384                         fi
385                         chgusr_exec $user $TOUCH ${node}/tmpfile > \
386                                 /dev/null 2>&1
387                         return $? ;;
388                 *"execute:"*|execute)
389                         chgusr_exec $user $FIND $node > /dev/null 2>&1
390                         return $? ;;
391                 esac
392         else
393                 case $acl_spec in
394                 *:read_data:*|read_data)
395                         chgusr_exec $user $CAT $node > /dev/null 2>&1
396                         return $? ;;
397                 *:write_data:*|write_data)
398                         chgusr_exec $user $DD if=/bin/ls of=$node > \
399                                 /dev/null 2>&1
400                         return $? ;;
401                 *"execute:"*|execute)
402                         ZFS_ACL_ERR_STR=$(chgusr_exec $user $node 2>&1) 
403                         return $? ;;
404                 esac
405         fi
406 }
407
408 #
409 # Get the given file/directory xattr
410 #
411 # $1 object -- file or directroy
412 #
413 function get_xattr #<obj>
414 {
415         typeset obj=$1
416         typeset xattr
417         if (( ${#obj} == 0 )); then
418                 return 1
419         fi
420
421         for xattr in `$RUNAT $obj $LS | \
422                 /usr/bin/egrep -v -e SUNWattr_ro -e SUNWattr_rw` ; do
423                 $RUNAT $obj $SUM $xattr
424         done
425 }
426
427 #
428 # Get the owner of a file/directory
429 #
430 function get_owner #node
431 {
432         typeset node=$1
433         typeset value
434
435         if [[ -z $node ]]; then
436                 log_fail "node are not defined."
437         fi
438
439         if [[ -d $node ]]; then
440                 value=$($LS -dl $node | $AWK '{print $3}')
441         elif [[ -e $node ]]; then
442                 value=$($LS -l $node | $AWK '{print $3}')
443         fi
444
445         $ECHO $value
446 }
447
448 #
449 # Get the group of a file/directory
450 #
451 function get_group #node
452 {
453         typeset node=$1
454         typeset value
455
456         if [[ -z $node ]]; then
457                 log_fail "node are not defined."
458         fi
459
460         if [[ -d $node ]]; then
461                 value=$($LS -dl $node | $AWK '{print $4}')
462         elif [[ -e $node ]]; then
463                 value=$($LS -l $node | $AWK '{print $4}')
464         fi
465
466         $ECHO $value
467 }
468
469
470 #
471 # Get the group name that a UID belongs to
472 #
473 function get_user_group #uid
474 {
475         typeset uid=$1
476         typeset value
477
478         if [[ -z $uid ]]; then
479                 log_fail "UID not defined."
480         fi
481
482         value=$(id $uid)
483
484         if [[ $? -eq 0 ]]; then
485                 value=${value##*\(}
486                 value=${value%%\)*}
487                 $ECHO $value
488         else
489                 log_fail "Invalid UID (uid)."
490         fi
491 }
492
493 #
494 # Get the specified item of the specified string
495 #
496 # $1:   Item number, count from 0.
497 # $2-n: strings
498 #
499 function getitem
500 {
501         typeset -i n=$1
502         shift
503
504         (( n += 1 ))
505         eval print \${$n}
506 }
507
508 #
509 # This function calculate the specified directory files checksum and write
510 # to the specified array.
511 #
512 # $1 directory in which the files will be cksum.
513 # $2 file array name which was used to store file cksum information.
514 # $3 attribute array name which was used to store attribute information.
515 #
516 function cksum_files #<dir> <file_array_name> <attribute_array_name>
517 {
518         typeset dir=$1
519         typeset farr_name=$2
520         typeset aarr_name=$3
521
522         [[ ! -d $dir ]] && return
523         typeset oldpwd=$PWD
524         cd $dir
525         typeset files=$($LS file*)
526
527         typeset -i i=0
528         typeset -i n=0
529         while (( i < NUM_FILE )); do
530                 typeset f=$(getitem $i $files)
531                 eval $farr_name[$i]=\$\(\$CKSUM $f\)
532
533                 typeset -i j=0
534                 while (( j < NUM_ATTR )); do
535                         eval $aarr_name[$n]=\$\(\$RUNAT \$f \$CKSUM \
536                                 attribute.$j\)
537
538                         (( j += 1 ))
539                         (( n += 1 ))
540                 done
541
542                 (( i += 1 ))
543         done
544
545         cd $oldpwd
546 }
547
548 #
549 # This function compare two cksum results array.
550 #
551 # $1 The array name which stored the cksum before operation.
552 # $2 The array name which stored the cksum after operation.
553 #
554 function compare_cksum #<array1> <array2>
555 {
556         typeset before=$1
557         typeset after=$2
558         eval typeset -i count=\${#$before[@]}
559
560         typeset -i i=0
561         while (( i < count )); do
562                 eval typeset var1=\${$before[$i]}
563                 eval typeset var2=\${$after[$i]}
564
565                 if [[ $var1 != $var2 ]]; then
566                         return 1
567                 fi
568
569                 (( i += 1 ))
570         done
571
572         return 0
573 }
574
575 #
576 # This function calculate all the files cksum information in current directory 
577 # and output them to the specified file.
578 #
579 # $1 directory from which the files will be cksum.
580 # $2 cksum output file
581 #
582 function record_cksum #<outfile>
583 {
584         typeset dir=$1
585         typeset outfile=$2
586
587         [[ ! -d ${outfile%/*} ]] && usr_exec $MKDIR -p ${outfile%/*}
588
589         usr_exec cd $dir ; $FIND . -depth -type f -exec cksum {} \\\; | $SORT > $outfile
590         usr_exec cd $dir ; $FIND . -depth -type f -xattr -exec runat {} \
591                 cksum attribute* \\\; | $SORT >> $outfile
592 }
593
594 #
595 # The function create_files creates the directories and files that the script 
596 # will operate on to test extended attribute functionality.
597 #
598 # $1 The base directory in which to create directories and files.
599 #
600 function create_files #<directory>
601 {
602         typeset basedir=$1
603
604         [[ ! -d $basedir ]] && usr_exec $MKDIR -m 777 $basedir
605         [[ ! -d $RES_DIR  ]] && usr_exec $MKDIR -m 777 $RES_DIR
606         [[ ! -d $INI_DIR ]] && usr_exec $MKDIR -m 777 $INI_DIR
607         [[ ! -d $TST_DIR ]] && usr_exec $MKDIR -m 777 $TST_DIR
608         [[ ! -d $TMP_DIR  ]] && usr_exec $MKDIR -m 777 $TMP_DIR
609
610         #
611         # Create the original file and its attribute files.
612         #
613         [[ ! -a $RES_DIR/file ]] && \
614                 usr_exec $FILE_WRITE -o create -f $RES_DIR/file \
615                         -b 1024 -d 0 -c 1
616         [[ ! -a $RES_DIR/attribute ]] && \
617                 usr_exec $CP $RES_DIR/file $RES_DIR/attribute
618
619         typeset oldpwd=$PWD
620         cd $INI_DIR
621
622         typeset -i i=0
623         while (( i < NUM_FILE )); do
624                 typeset dstfile=$INI_DIR/file.${TESTCASE_ID}.$i
625                 usr_exec $CP $RES_DIR/file $dstfile
626
627                 typeset -i j=0
628                 while (( j < NUM_ATTR )); do
629                         usr_exec $RUNAT $dstfile \
630                                 $CP $RES_DIR/attribute ./attribute.$j
631                         (( j += 1 ))
632                 done
633
634                 (( i += 1 ))
635         done
636
637         cd $oldpwd
638 }