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/include/nfsgen.kshlib
28
29 # TX doesn't allow a regular user to access zone path
30 # we need to enter mount point first, then access other
31 # directories or files with relative path
32 cd $MNTDIR
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 FNAME=get_mode
42 [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
43 && set -x
44
45 typeset obj=$1
46 if (( ${#obj} == 0 )); then
47 return 1
48 fi
49
50 $LS -ld $obj | $AWK '{print $1}'
51 return $?
52 }
53
54 #
55 # Get the given file/directory ACL
56 #
57 # $1 object -- file or directroy
58 #
59 function get_acl #<obj>
60 {
61 FNAME=get_acl
62 [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
63 && set -x
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 return $?
72 }
73
74 #
75 # Get the given file/directory ACL
76 #
77 # $1 object -- file or directroy
78 #
79 function get_compact_acl #<obj>
80 {
81 FNAME=get_compact_acl
82 [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
83 && set -x
84
85 typeset obj=$1
86 if (( ${#obj} == 0 )); then
87 return 1
88 fi
89
90 $LS -Vd $obj | $NAWK '(NR != 1) {print $0}'
91 return $?
92 }
93
94 #
95 # Check the given two files/directories have the same ACLs
96 #
97 # Return 0, if source object acl is equal to target object acl.
98 #
99 # $1 source object
100 # $2 target object
101 #
102 function compare_acls #<src> <tgt>
103 {
104 FNAME=compare_acls
105 [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
106 && set -x
107
108 typeset src=$1
109 typeset tgt=$2
110
111 (( ${#src} == 0 || ${#tgt} == 0 )) && return 1
112 [[ $src == $tgt ]] && return 0
113
114 typeset tmpsrc=/tmp/compare_acls.src.$$
115 typeset tmptgt=/tmp/compare_acls.tgt.$$
116
117 get_acl $src > $tmpsrc
118 get_acl $tgt > $tmptgt
119 typeset -i ret=0
120 $DIFF $tmpsrc $tmptgt > /dev/null 2>&1
121 ret=$?
122 $RM -f $tmpsrc $tmptgt
123
124 if (( ret != 0 )); then
125 return $ret
126 fi
127
128 RUN_CHECK get_compact_acl $src > $tmpsrc || return 1
129 RUN_CHECK get_compact_acl $tgt > $tmptgt || return 1
130 $DIFF $tmpsrc $tmptgt > /dev/null 2>&1
131 ret=$?
132 $RM -f $tmpsrc $tmptgt
133
134 return $ret
135 }
136
137 #
138 # Check that the given two objects have the same modes.
139 # Return 0, if their modes are equal with each other. Otherwise, return 1.
140 #
141 # $1 source object
142 # $2 target object
143 #
144 function compare_modes #<src> <tgt>
145 {
146 FNAME=compare_modes
147 [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
148 && set -x
149
150 typeset src=$1
151 typeset tgt=$2
152 typeset -i i=0
153 set -A mode
154
155 (( ${#src} == 0 || ${#tgt} == 0 )) && return 1
156 [[ $src == $tgt ]] && return 0
157
158 typeset obj
159 for obj in $src $tgt
160 do
161 mode[i]=$(get_mode $obj)
162
163 (( i = i + 1 ))
164 done
165
166 [[ ${mode[0]} != ${mode[1]} ]] && return 1
167
168 return 0
169 }
170
171 #
172 # Check that the given two objects have the same xattrs.
173 # Return 0, if their xattrs are equal with each other. Otherwise, return 1.
174 #
175 # $1 source object
176 # $2 target object
177 #
178 function compare_xattrs #<src> <tgt>
179 {
180 FNAME=compare_xattrs
181 [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
182 && set -x
183
184 typeset src=$1
185 typeset tgt=$2
186
187 (( ${#src} == 0 || ${#tgt} == 0 )) && return 1
188 [[ $src == $tgt ]] && return 0
189
190 typeset tmpsrc=/tmp/compare_xattrs.src.$$
191 typeset tmptgt=/tmp/compare_xattrs.tgt.$$
192
193 RUN_CHECK get_xattr $src > $tmpsrc || return 1
194 RUN_CHECK get_xattr $tgt > $tmptgt || return 1
195 typeset -i ret=0
196 $DIFF $tmpsrc $tmptgt > /dev/null 2>&1
197 ret=$?
198 $RM -f $tmpsrc $tmptgt
199
200 return $ret
201 }
202
203 #
204 # Check '+' is set for a given file/directory with 'ls [-l]' command
205 #
206 # $1 object -- file or directory.
207 #
208 function plus_sign_check_l #<obj>
209 {
210 FNAME=plus_sign_check_l
211 [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
212 && set -x
213
214 typeset obj=$1
215 if (( ${#obj} == 0 )); then
216 return 1
217 fi
218
219 $LS -ld $obj | $AWK '{print $1}' | $GREP "+\>" > /dev/null
220 return $?
221 }
222
223 #
224 # Check '+' is set for a given file/directory with 'ls [-v]' command
225 #
226 # $1 object -- file or directory.
227 #
228 function plus_sign_check_v #<obj>
229 {
230 FNAME=plus_sign_check_v
231 [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
232 && set -x
233
234 typeset obj=$1
235 if (( ${#obj} == 0 )); then
236 return 1
237 fi
238
239 $LS -vd $obj | $NAWK '(NR == 1) {print $1}' | $GREP "+\>" > /dev/null
240 return $?
241 }
242
243 #
244 # Export the current user for the following usr_exec operating.
245 #
246 # $1 legal login name
247 #
248 function set_cur_usr #<login_name>
249 {
250 FNAME=set_cur_usr
251 [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
252 && set -x
253
254 export ACL_CUR_USER=$1
255 }
256
257 #
258 # Run commands by $ACL_CUR_USER
259 #
260 # $1-n commands and options
261 #
262 function usr_exec #<commands> [...]
263 {
264 FNAME=usr_exec
265 [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
266 && set -x
267
268 [[ $IS_KRB5 == 1 && $ACL_CUR_USER != root ]] \
269 && chg_usr_exec -k $KPASSWORD "$ACL_CUR_USER" $@ \
270 || chg_usr_exec "$ACL_CUR_USER" $@
271
272 return $?
273 }
274
275 #
276 # Count how many ACEs for the speficied file or directory.
277 #
278 # $1 file or directroy name
279 #
280 function count_ACE #<file or dir name>
281 {
282 FNAME=count_ACE
283 [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
284 && set -x
285
286 if [[ ! -e $1 ]]; then
287 echo "Need input file or directroy name."
288 return 1
289 fi
290
291 $LS -vd $1 | $NAWK 'BEGIN {count=0}
292 (NR != 1)&&(/[0-9]:/) {count++}
293 END {print count}'
294
295 return 0
296 }
297
298 #
299 # Get specified number ACE content of specified file or directory.
300 #
301 # $1 file or directory name
302 # $2 specified number
303 #
304 function get_ACE #<file or dir name> <specified number> <verbose|compact>
305 {
306 FNAME=get_ACE
307 [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
308 && set -x
309
310 if [[ ! -e $1 || $2 -ge $(count_ACE $1) ]]; then
311 return 1
312 fi
313
314 typeset file=$1
315 typeset -i num=$2
316 typeset format=${3:-verbose}
317 typeset -i next_num=-1
318
319 typeset tmpfile=/tmp/tmp_get_ACE.$$
320 typeset line=""
321 typeset args
322
323 case $format in
324 verbose) args="-vd"
325 ;;
326 compact) args="-Vd"
327 ;;
328 *) echo "Invalid parameter as ($format), " \
329 "only verbose|compact is supported."
330 exit $STF_FAIL
331 ;;
332 esac
333
334 $LS $args $file > $tmpfile
335 if (( $? != 0 )) then
336 echo "FAIL: $LS $args $file > $tmpfile"
337 exit $STF_FAIL
338 fi
339 while read line; do
340 [[ -z $line ]] && continue
341 if [[ $args == -vd ]]; then
342 if [[ $line == "$num":* ]]; then
343 (( next_num = num + 1 ))
344 fi
345 if [[ $line == "$next_num":* ]]; then
346 break
347 fi
348 if (( next_num != -1 )); then
349 print -n $line
350 fi
351 else
352 if (( next_num == num )); then
353 print -n $line
354 fi
355 (( next_num += 1 ))
356 fi
357 done < $tmpfile
358
359 $RM -f $tmpfile
360 if (( $? != 0 )); then
361 echo "FAIL: $RM -f $tmpfile"
362 exit $STF_FAIL
363 fi
364 }
365
366 #
367 # Cleanup exist user/group.
368 #
369 function cleanup_user_group
370 {
371 FNAME=cleanup_user_group
372 [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
373 && set -x
374
375 del_user $ACL_ADMIN
376
377 del_user $ACL_STAFF1
378 del_user $ACL_STAFF2
379 del_group $ACL_STAFF_GROUP
380
381 del_user $ACL_OTHER1
382 del_user $ACL_OTHER2
383 del_group $ACL_OTHER_GROUP
384
385 return 0
386 }
387
388 #
389 # According to specified access or acl_spec, do relevant operating by using the
390 # specified user.
391 #
392 # $1 specified user
393 # $2 node
394 # $3 acl_spec or access
395 #
396 function rwx_node #user node acl_spec|access
397 {
398 FNAME=rwx_node
399 [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
400 && set -x
401
402 typeset user=$1
403 typeset node=$2
404 typeset acl_spec=$3
405
406 if [[ $user == "" || $node == "" || $acl_spec == "" ]]; then
407 echo "node or acl_spec are not defined."
408 return 1
409 fi
410
411 if [[ -d $node ]]; then
412 case $acl_spec in
413 *:read_data:*|read_data)
414 RUN_CHECK chgusr_exec $user $LS -l $node
415 return $? ;;
416 *:write_data:*|write_data)
417 if [[ -f ${node}/tmpfile ]]; then
418 RUN_CHECK $RM -f ${node}/tmpfile \
419 || exit $STF_FAIL
420 fi
421 RUN_CHECK chgusr_exec $user $TOUCH ${node}/tmpfile
422 return $? ;;
423 *"execute:"*|execute)
424 RUN_CHECK chgusr_exec $user $FIND $node
425 return $? ;;
426 esac
427 else
428 case $acl_spec in
429 *:read_data:*|read_data)
430 RUN_CHECK chgusr_exec $user $CAT $node
431 return $? ;;
432 *:write_data:*|write_data)
433 RUN_CHECK chgusr_exec $user $DD if=/usr/bin/ls of=$node
434 return $? ;;
435 *"execute:"*|execute)
436 ACL_ERR_STR=$(chgusr_exec $user $node 2>&1)
437 return $? ;;
438 esac
439 fi
440 }
441
442 #
443 # Get the given file/directory xattr
444 #
445 # $1 object -- file or directroy
446 #
447 function get_xattr #<obj>
448 {
449 FNAME=get_xattr
450 [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
451 && set -x
452
453 typeset obj=$1
454 typeset xattr
455 if (( ${#obj} == 0 )); then
456 return 1
457 fi
458
459 for xattr in `$RUNAT $obj $LS | \
460 /usr/xpg4/bin/egrep -v -e SUNWattr_ro -e SUNWattr_rw` ; do
461 $RUNAT $obj $SUM $xattr || return 1
462 done
463 }
464
465 #
466 # Get the owner of a file/directory
467 #
468 function get_owner #node
469 {
470 FNAME=get_owner
471 [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
472 && set -x
473
474 typeset node=$1
475 typeset value
476
477 if [[ -z $node ]]; then
478 echo "node are not defined."
479 exit $STF_FAIL
480 fi
481
482 if [[ -d $node ]]; then
483 value=$($LS -dl $node | $AWK '{print $3}')
484 elif [[ -e $node ]]; then
485 value=$($LS -l $node | $AWK '{print $3}')
486 fi
487
488 $ECHO $value
489 }
490
491 #
492 # Get the group of a file/directory
493 #
494 function get_group #node
495 {
496 FNAME=get_group
497 [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
498 && set -x
499
500 typeset node=$1
501 typeset value
502
503 if [[ -z $node ]]; then
504 echo "node are not defined."
505 exit $STF_FAIL
506 fi
507
508 if [[ -d $node ]]; then
509 value=$($LS -dl $node | $AWK '{print $4}')
510 elif [[ -e $node ]]; then
511 value=$($LS -l $node | $AWK '{print $4}')
512 fi
513
514 $ECHO $value
515 }
516
517
518 #
519 # Get the group name that a UID belongs to
520 #
521 function get_user_group #uid
522 {
523 FNAME=get_user_group
524 [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
525 && set -x
526
527 typeset uid=$1
528 typeset value
529
530 if [[ -z $uid ]]; then
531 echo "UID not defined."
532 exit $STF_FAIL
533 fi
534
535 value=$(id $uid)
536
537 if [[ $? -eq 0 ]]; then
538 value=${value##*\(}
539 value=${value%%\)*}
540 $ECHO $value
541 else
542 echo "Invalid UID (uid)."
543 exit $STF_FAIL
544 fi
545 }
546
547 #
548 # Get the specified item of the specified string
549 #
550 # $1: Item number, count from 0.
551 # $2-n: strings
552 #
553 function getitem
554 {
555 FNAME=getitem
556 [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
557 && set -x
558
559 typeset -i n=$1
560 shift
561
562 (( n += 1 ))
563 eval echo \${$n}
564 }
565
566 #
567 # This function calculate the specified directory files checksum and write
568 # to the specified array.
569 #
570 # $1 directory in which the files will be cksum.
571 # $2 file array name which was used to store file cksum information.
572 # $3 attribute array name which was used to store attribute information.
573 #
574 function cksum_files #<dir> <file_array_name> <attribute_array_name>
575 {
576 FNAME=cksum_files
577 [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
578 && set -x
579
580 typeset dir=$1
581 typeset farr_name=$2
582 typeset aarr_name=$3
583
584 [[ ! -d $dir ]] && return
585 typeset files=$($LS $dir/file*)
586
587 typeset -i i=0
588 typeset -i n=0
589 while (( i < NUM_FILE )); do
590 typeset f=$(getitem $i $files)
591 RUN_CHECK eval $farr_name[$i]=\$\(\$CKSUM $f\) \
592 || cleanup $STF_FAIL
593
594 typeset -i j=0
595 while (( j < NUM_ATTR )); do
596 RUN_CHECK eval $aarr_name[$n]=\$\(\$RUNAT \$f \$CKSUM \
597 attribute.$j\) || cleanup $STF_FAIL
598
599 (( j += 1 ))
600 (( n += 1 ))
601 done
602
603 (( i += 1 ))
604 done
605 }
606
607 #
608 # This function compare two cksum results array.
609 #
610 # $1 The array name which stored the cksum before operation.
611 # $2 The array name which stored the cksum after operation.
612 #
613 function compare_cksum #<array1> <array2>
614 {
615 FNAME=compare_cksum
616 [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
617 && set -x
618
619 typeset before=$1
620 typeset after=$2
621 eval typeset -i count=\${#$before[@]}
622
623 typeset -i i=0
624 while (( i < count )); do
625 eval typeset var1=\${$before[$i]}
626 eval typeset var2=\${$after[$i]}
627
628 if [[ $var1 != $var2 ]]; then
629 return 1
630 fi
631
632 (( i += 1 ))
633 done
634
635 return 0
636 }
637
638 #
639 # This function calculate all the files cksum information in current directory
640 # and output them to the specified file.
641 #
642 # $1 directory from which the files will be cksum.
643 # $2 cksum output file
644 #
645 function record_cksum #<outfile>
646 {
647 FNAME=record_cksum
648 [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
649 && set -x
650
651 typeset dir=$1
652 typeset outfile=$2
653
654 [[ ! -d ${outfile%/*} ]] && usr_exec $MKDIR -p ${outfile%/*}
655
656 usr_exec $FIND $dir -depth -type f -exec cksum {} \\\; \
657 > $STF_TMPDIR/cksum.$$ || return 1
658 $SORT $STF_TMPDIR/cksum.$$ > $outfile
659 usr_exec $FIND $dir -depth -type f -xattr -exec runat {} \
660 cksum attribute* \\\; > $STF_TMPDIR/cksum.$$ \
661 || return 1
662 $SORT $STF_TMPDIR/cksum.$$ >> $outfile
663 return 0
664 }
665
666 #
667 # The function create_files creates the directories and files that the script
668 # will operate on to test extended attribute functionality.
669 #
670 # $1 The base directory in which to create directories and files.
671 #
672 function create_files #<directory>
673 {
674 FNAME=create_files
675 [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
676 && set -x
677
678 typeset basedir=$1
679
680 [[ ! -d $basedir ]] && RUN_CHECK usr_exec $MKDIR -m 777 $basedir
681 [[ ! -d $RES_DIR ]] && RUN_CHECK usr_exec $MKDIR -m 777 $RES_DIR
682 [[ ! -d $INI_DIR ]] && RUN_CHECK usr_exec $MKDIR -m 777 $INI_DIR
683 [[ ! -d $TST_DIR ]] && RUN_CHECK usr_exec $MKDIR -m 777 $TST_DIR
684 [[ ! -d $TMP_DIR ]] && RUN_CHECK usr_exec $MKDIR -m 777 $TMP_DIR
685
686 #
687 # Create the original file and its attribute files.
688 #
689 if [[ ! -a $RES_DIR/file ]]; then
690 RUN_CHECK "usr_exec \"$FILE_WRITE -W -c -o 4 -B \\\"1024 1 -1\\\" $RES_DIR/file\"" \
691 || cleanup $STF_FAIL
692 fi
693 if [[ ! -a $RES_DIR/attribute ]]; then
694 RUN_CHECK usr_exec $CP $RES_DIR/file $RES_DIR/attribute \
695 || cleanup $STF_FAIL
696 fi
697
698 typeset -i i=0
699 while (( i < NUM_FILE )); do
700 typeset dstfile=$INI_DIR/file.$$.$i
701 RUN_CHECK usr_exec $CP $RES_DIR/file $dstfile \
702 || cleanup $STF_FAIL
703
704 typeset -i j=0
705 while (( j < NUM_ATTR )); do
706 RUN_CHECK usr_exec $RUNAT $dstfile \
707 $CP $STF_SUITE/STF.INFO ./attribute.$j \
708 || cleanup $STF_FAIL
709 (( j += 1 ))
710 done
711
712 (( i += 1 ))
713 done
714 }
715
716
717 #
718 # The function remount the server's fs with appended option, which can be
719 # used to disable the attribute cache with "noac" option for some tests
720 #
721 # $1 the option which is appended.
722 #
723 function do_remount #<option>
724 {
725 FNAME=do_remount
726 [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
727 && set -x
728
729 typeset opt=$1
730 typeset mntdir
731
732 [[ $opt != "" ]] && opt=",$opt"
733 [[ $SETUP == none ]] && mntdir=$realMNT || mntdir=$MNTDIR
734 [[ $MNTOPT == "" ]] && MNTOPT="rw"
735
736 RUN_CHECK $UMOUNT $mntdir || return 1
737 RUN_CHECK $MOUNT -o $MNTOPT$opt $SERVER:$SHRDIR $mntdir \
738 || return 1
739
740 return 0
741 }