1 #! /usr/bin/ksh -p
   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 #
  24 # Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  25 # Use is subject to license terms.
  26 #
  27 
  28 . $STF_SUITE/tests/acl/acl_common.kshlib
  29 
  30 #################################################################################
  31 #
  32 # __stc_assertion_start
  33 #
  34 # ID: acl_chmod_rwx_pos002
  35 #
  36 # DESCRIPTION:
  37 #       chmod A{+|-|=} read_data|write_data|execute for owner@ group@ or everyone@
  38 #       correctly alters mode bits .
  39 #
  40 # STRATEGY:
  41 #       1. Loop root and non-root user.
  42 #       2. Get the random initial map.
  43 #       3. Get the random ACL string.
  44 #       4. Separately chmod +|-|= read_data|write_data|execute
  45 #       5. Check map bits 
  46 #
  47 # TESTABILITY: explicit
  48 #
  49 # TEST_AUTOMATION_LEVEL: automated
  50 #
  51 # __stc_assertion_end
  52 #
  53 ################################################################################
  54 
  55 [[ :$NFSGEN_DEBUG: = *:${NAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
  56         && set -x
  57 
  58 echo "ASSERTION: chmod A{+|-|=} read_data|write_data|execute for owner@, group@ " \
  59         "or everyone@ correctly alters mode bits."
  60 
  61 set -A bits 0 1 2 3 4 5 6 7
  62 set -A a_flag owner group everyone
  63 set -A a_access read_data write_data execute
  64 set -A a_type allow deny
  65 
  66 #
  67 # Get a random item from an array.
  68 #
  69 # $1 the base set
  70 #
  71 function random_select #array_name
  72 {
  73         [[ :$NFSGEN_DEBUG: = *:${NAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
  74                 && set -x
  75 
  76         typeset arr_name=$1
  77         typeset -i ind
  78 
  79         eval typeset -i cnt=\${#${arr_name}[@]}
  80         (( ind = $RANDOM % cnt ))
  81 
  82         eval print \${${arr_name}[$ind]}
  83 }
  84 
  85 #
  86 # Create a random string according to array name, the item number and 
  87 # separated tag.
  88 #
  89 # $1 array name where the function get the elements
  90 # $2 the items number which you want to form the random string
  91 # $3 the separated tag
  92 #
  93 function form_random_str #<array_name> <count> <sep>
  94 {
  95         [[ :$NFSGEN_DEBUG: = *:${NAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
  96                 && set -x
  97 
  98         typeset arr_name=$1
  99         typeset -i count=${2:-1}
 100         typeset sep=${3:-""}
 101 
 102         typeset str=""
 103         while (( count > 0 )); do
 104                 str="${str}$(random_select $arr_name)${sep}"
 105 
 106                 (( count -= 1 ))
 107         done
 108 
 109         print $str
 110 }
 111 
 112 #
 113 # Get the sub string from specified source string
 114 #
 115 # $1 source string
 116 # $2 start position. Count from 1
 117 # $3 offset
 118 #
 119 function get_substr #src_str pos offset
 120 {
 121         [[ :$NFSGEN_DEBUG: = *:${NAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
 122                 && set -x
 123 
 124         typeset pos offset
 125 
 126         $ECHO $1 | \
 127                 $NAWK -v pos=$2 -v offset=$3 '{print substr($0, pos, offset)}'
 128 }
 129 
 130 #
 131 # According to the original bits, the input ACE access and ACE type, return the
 132 # expect bits after 'chmod A0{+|=}'.
 133 #
 134 # $1 bits which was make up of three bit 'rwx'
 135 # $2 ACE access which is read_data, write_data or execute
 136 # $3 ACE type which is allow or deny
 137 #
 138 function cal_bits #bits acl_access acl_type
 139 {
 140         [[ :$NFSGEN_DEBUG: = *:${NAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
 141                 && set -x
 142 
 143         typeset bits=$1
 144         typeset acl_access=$2
 145         typeset acl_type=$3
 146         set -A bit r w x
 147 
 148         typeset tmpbits=""
 149         typeset -i i=0 j
 150         while (( i < 3 )); do
 151                 if [[ $acl_access == *"${a_access[i]}"* ]]; then
 152                         if [[ $acl_type == "allow" ]]; then
 153                                 tmpbits="$tmpbits${bit[i]}"
 154                         elif [[ $acl_type == "deny" ]]; then
 155                                 tmpbits="${tmpbits}-"
 156                         fi
 157                 else
 158                         (( j = i + 1 ))
 159                         tmpbits="$tmpbits$(get_substr $bits $j 1)"
 160                 fi
 161 
 162                 (( i += 1 ))
 163         done
 164 
 165         echo "$tmpbits"
 166 }
 167 
 168 #
 169 # Based on the initial node map before chmod and the ace-spec, check if chmod
 170 # has the correct behaven to map bits.
 171 #
 172 function check_test_result #init_mode node acl_flag acl_access a_type
 173 {
 174         [[ :$NFSGEN_DEBUG: = *:${NAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
 175                 && set -x
 176 
 177         typeset init_mode=$1
 178         typeset node=$2
 179         typeset acl_flag=$3
 180         typeset acl_access=$4
 181         typeset acl_type=$5
 182 
 183         typeset -L3 u_bits=$init_mode
 184         typeset g_bits=$(get_substr $init_mode 4 3)
 185         typeset -R3 o_bits=$init_mode
 186 
 187         if [[ $acl_flag == "owner" || $acl_flag == "everyone" ]]; then
 188                 u_bits=$(cal_bits $u_bits $acl_access $acl_type)
 189         fi
 190         if [[ $acl_flag == "group" || $acl_flag == "everyone" ]]; then
 191                 g_bits=$(cal_bits $g_bits $acl_access $acl_type)
 192         fi
 193         if [[ $acl_flag == "everyone" ]]; then
 194                 o_bits=$(cal_bits $o_bits $acl_access $acl_type)
 195         fi
 196 
 197         typeset cur_mode=$(get_mode $node)
 198         cur_mode=$(get_substr $cur_mode 2 9)
 199 
 200         if [[ $cur_mode != $u_bits$g_bits$o_bits ]]; then
 201                 echo "FAIL: Current map($cur_mode) != " \
 202                         "expected map($u_bits$g_bits$o_bits)"
 203                 cleanup $STF_FAIL
 204         fi
 205 }
 206 
 207 function test_chmod_map #<node>
 208 {
 209         [[ :$NFSGEN_DEBUG: = *:${NAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
 210                 && set -x
 211 
 212         typeset node=$1 
 213         typeset init_mask acl_flag acl_access acl_type
 214         typeset -i cnt
 215 
 216         if (( ${#node} == 0 )); then
 217                 echo "FAIL: file name or directroy name is not defined."
 218                 cleanup $STF_FAIL
 219         fi
 220 
 221         # Get the initial map
 222         eval "init_mask=$(form_random_str bits 3)"
 223         # Get ACL flag, access & type
 224         eval "acl_flag=$(form_random_str a_flag)"
 225         (( cnt = ($RANDOM % ${#a_access[@]}) + 1 ))
 226         eval "acl_access=$(form_random_str a_access $cnt '/')"
 227         acl_access=${acl_access%/}
 228         eval "acl_type=$(form_random_str a_type)"
 229 
 230         typeset acl_spec=${acl_flag}@:${acl_access}:${acl_type}
 231 
 232         # Set the initial map and back the initial ACEs
 233         typeset orig_ace=$STF_TMPDIR/orig_ace.$$
 234         typeset cur_ace=$STF_TMPDIR/cur_ace.$$
 235 
 236         for operator in "A0+" "A0="; do
 237                 RUN_CHECK usr_exec $CHMOD $init_mask $node || cleanup $STF_FAIL
 238                 eval "init_mode=$(get_mode $node)"
 239                 eval "init_mode=$(get_substr $init_mode 2 9)"
 240                 RUN_CHECK usr_exec eval "$LS -vd $node > $orig_ace" || cleanup $STF_FAIL
 241 
 242                 # To "A=", firstly add one ACE which can't modify map
 243                 if [[ $operator == "A0=" ]]; then
 244                         RUN_CHECK $CHMOD A0+user:$ACL_OTHER1:execute:deny \
 245                                 $node || cleanup $STF_FAIL
 246                 fi
 247                 RUN_CHECK usr_exec $CHMOD $operator$acl_spec $node \
 248                         || cleanup $STF_FAIL
 249                 check_test_result \
 250                         $init_mode $node $acl_flag $acl_access $acl_type
 251 
 252                 # Check "chmod A-"
 253                 RUN_CHECK usr_exec $CHMOD A0- $node || cleanup $STF_FAIL
 254                 RUN_CHECK usr_exec eval "$LS -vd $node > $cur_ace" || cleanup $STF_FAIL
 255         
 256                 # original ACEs should be equal to current ACEs 
 257                 if ! $DIFF $orig_ace $cur_ace; then
 258                         echo "FAIL: 'chmod A-' failed."
 259                         cleanup $STF_FAIL
 260                 fi
 261         done
 262 
 263         if [[ -f $orig_ace ]]; then
 264                 RUN_CHECK usr_exec $RM -f $orig_ace || cleanup $STF_FAIL
 265         fi
 266         if [[ -f $cur_ace ]]; then
 267                 RUN_CHECK usr_exec $RM -f $cur_ace || cleanup $STF_FAIL
 268         fi
 269 }
 270 
 271 for user in root $ACL_STAFF1; do
 272         set_cur_usr $user
 273         
 274         typeset -i loop_cnt=20
 275         while (( loop_cnt > 0 )); do
 276                 RUN_CHECK usr_exec $TOUCH $testfile || cleanup $STF_FAIL
 277                 test_chmod_map $testfile
 278                 RUN_CHECK $RM -f $testfile || cleanup $STF_FAIL
 279 
 280                 RUN_CHECK usr_exec $MKDIR $testdir || cleanup $STF_FAIL
 281                 test_chmod_map $testdir
 282                 RUN_CHECK $RM -rf $testdir || cleanup $STF_FAIL
 283 
 284                 (( loop_cnt -= 1 ))
 285         done
 286 done
 287 
 288 # chmod A{+|-|=} read_data|write_data|execute for owner@, group@ or everyone@
 289 # correctly alters mode bits passed.
 290 cleanup $STF_PASS