Print this page
7290 ZFS test suite needs to control what utilities it can run
Reviewed by: Dan Kimmel <dan.kimmel@delphix.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>


   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


 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 {


 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 }


   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


 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 speficied 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 {


 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 }