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