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