1#!/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# 29# Copyright (c) 2012, 2016 by Delphix. All rights reserved. 30# 31 32. $STF_SUITE/tests/functional/acl/acl_common.kshlib 33 34# 35# DESCRIPTION: 36# Verify that the write_owner for 37# owner/group/everyone are correct. 38# 39# STRATEGY: 40# 1. Create file and directory in zfs filesystem 41# 2. Set special write_owner ACE to the file and directory 42# 3. Try to chown/chgrp of the file and directory to take owner/group 43# 4. Verify that the owner/group are correct. Follow these rules: 44# (1) If uid is granted the write_owner permission, then it can only do 45# chown to its own uid, or a group that they are a member of. 46# (2) Owner will ignore permission of (1) even write_owner not granted. 47# (3) Superuser will always permit whatever they do. 48# 49 50verify_runnable "both" 51 52function cleanup 53{ 54 [[ -d $basedir ]] && rm -rf $basedir 55 [[ -f $TESTDIR/$ARCHIVEFILE ]] && log_must rm -f $TESTDIR/$ARCHIVEFILE 56 return 0 57} 58 59log_assert "Verify that the chown/chgrp could take owner/group " \ 60 "while permission is granted." 61log_onexit cleanup 62 63# 64# Get the owner of a file/directory 65# 66function get_owner 67{ 68 typeset node=$1 69 70 if [[ -z $node ]]; then 71 log_fail "node are not defined." 72 fi 73 74 echo $(ls -dl $node | awk '{print $3}') 75} 76 77# 78# Get the group of a file/directory 79# 80function get_group 81{ 82 typeset node=$1 83 84 if [[ -z $node ]]; then 85 log_fail "node are not defined." 86 fi 87 88 echo $(ls -dl $node | awk '{print $4}') 89} 90 91 92# 93# Get the group name that a UID belongs to 94# 95function get_user_group 96{ 97 typeset uid=$1 98 typeset value 99 100 if [[ -z $uid ]]; then 101 log_fail "UID not defined." 102 fi 103 104 value=$(id $uid) 105 106 if [[ $? -eq 0 ]]; then 107 value=${value##*\(} 108 value=${value%%\)*} 109 echo $value 110 else 111 log_fail "Invalid UID (uid)." 112 fi 113} 114 115function operate_node_owner 116{ 117 typeset user=$1 118 typeset node=$2 119 typeset old_owner=$3 120 typeset expect_owner=$4 121 typeset ret new_owner 122 123 if [[ $user == "" || $node == "" ]]; then 124 log_fail "user, node are not defined." 125 fi 126 127 su $user -c "chown $expect_owner $node" 128 ret=$? 129 new_owner=$(get_owner $node) 130 131 if [[ $new_owner != $old_owner ]]; then 132 tar xpf $TESTDIR/$ARCHIVEFILE 133 fi 134 135 if [[ $ret -eq 0 ]]; then 136 if [[ $new_owner != $expect_owner ]]; then 137 log_note "Owner not changed as expected " \ 138 "($old_owner|$new_owner|$expect_owner), " \ 139 "but return code is $ret." 140 return 1 141 fi 142 elif [[ $ret -ne 0 && $new_owner != $old_owner ]]; then 143 log_note "Owner changed ($old_owner|$new_owner), " \ 144 "but return code is $ret." 145 return 2 146 fi 147 148 return $ret 149} 150 151function operate_node_group 152{ 153 typeset user=$1 154 typeset node=$2 155 typeset old_group=$3 156 typeset expect_group=$4 157 typeset ret new_group 158 159 if [[ $user == "" || $node == "" ]]; then 160 log_fail "user, node are not defined." 161 fi 162 163 su $user -c "chgrp $expect_group $node" 164 ret=$? 165 new_group=$(get_group $node) 166 167 if [[ $new_group != $old_group ]]; then 168 tar xpf $TESTDIR/$ARCHIVEFILE 169 fi 170 171 if [[ $ret -eq 0 ]]; then 172 if [[ $new_group != $expect_group ]]; then 173 log_note "Group not changed as expected " \ 174 "($old_group|$new_group|$expect_group), " \ 175 "but return code is $ret." 176 return 1 177 fi 178 elif [[ $ret -ne 0 && $new_group != $old_group ]]; then 179 log_note "Group changed ($old_group|$new_group), " \ 180 "but return code is $ret." 181 return 2 182 fi 183 184 return $ret 185} 186 187function logname 188{ 189 typeset acl_target=$1 190 typeset user=$2 191 typeset old=$3 192 typeset new=$4 193 typeset ret="log_mustnot" 194 195 # To super user, read and write deny permission was override. 196 if [[ $user == root ]]; then 197 ret="log_must" 198 elif [[ $user == $new ]] ; then 199 if [[ $user == $old || $acl_target == *:allow ]]; then 200 ret="log_must" 201 fi 202 fi 203 204 print $ret 205} 206 207function check_chmod_results 208{ 209 typeset user=$1 210 typeset node=$2 211 typeset flag=$3 212 typeset acl_target=$3:$4 213 typeset g_usr=$5 214 typeset o_usr=$6 215 typeset log old_owner old_group new_owner new_group 216 217 old_owner=$(get_owner $node) 218 old_group=$(get_group $node) 219 220 if [[ $flag == "owner@" || $flag == "everyone@" ]]; then 221 for new_owner in $user "nobody"; do 222 new_group=$(get_user_group $new_owner) 223 224 log=$(logname $acl_target $user \ 225 $old_owner $new_owner) 226 227 $log operate_node_owner $user $node \ 228 $old_owner $new_owner 229 230 $log operate_node_group $user $node \ 231 $old_group $new_group 232 done 233 fi 234 if [[ $flag == "group@" || $flag == "everyone@" ]]; then 235 for new_owner in $g_usr "nobody"; do 236 new_group=$(get_user_group $new_owner) 237 238 log=$(logname $acl_target $g_usr $old_owner \ 239 $new_owner) 240 241 $log operate_node_owner $g_usr $node \ 242 $old_owner $new_owner 243 244 $log operate_node_group $g_usr \ 245 $node $old_group $new_group 246 done 247 fi 248 if [[ $flag == "everyone@" ]]; then 249 for new_owner in $g_usr "nobody"; do 250 new_group=$(get_user_group $new_owner) 251 252 log=$(logname $acl_target $o_usr $old_owner \ 253 $new_owner) 254 255 $log operate_node_owner $o_usr $node \ 256 $old_owner $new_owner 257 258 $log operate_node_group $o_usr $node \ 259 $old_group $new_group 260 done 261 fi 262} 263 264function test_chmod_basic_access 265{ 266 typeset user=$1 267 typeset node=${2%/} 268 typeset g_usr=$3 269 typeset o_usr=$4 270 typeset flag acl_t 271 272 for flag in $a_flag; do 273 for acl_t in $a_access; do 274 log_must su $user -c "chmod A+$flag:$acl_t $node" 275 276 tar cpf $TESTDIR/$ARCHIVEFILE basedir 277 278 check_chmod_results $user $node $flag $acl_t $g_usr \ 279 $o_usr 280 281 log_must su $user -c "chmod A0- $node" 282 done 283 done 284} 285 286function setup_test_files 287{ 288 typeset base_node=$1 289 typeset user=$2 290 typeset group=$3 291 292 rm -rf $base_node 293 294 log_must mkdir -p $base_node 295 log_must chown $user:$group $base_node 296 297 # Prepare all files/sub-dirs for testing. 298 log_must su $user -c "touch $file" 299 log_must su $user -c "chmod 444 $file" 300 log_must su $user -c "mkdir -p $dir" 301 log_must su $user -c "chmod 444 $dir" 302 log_must su $user -c "chmod 555 $base_node" 303} 304 305typeset ARCHIVEFILE=archive.tar 306typeset a_access="write_owner:allow write_owner:deny" 307typeset a_flag="owner@ group@ everyone@" 308typeset basedir="$TESTDIR/basedir" 309typeset file="$basedir/file" 310typeset dir="$basedir/dir" 311 312cd $TESTDIR 313setup_test_files $basedir 'root' 'root' 314test_chmod_basic_access 'root' $file $ZFS_ACL_ADMIN $ZFS_ACL_OTHER1 315test_chmod_basic_access 'root' $dir $ZFS_ACL_ADMIN $ZFS_ACL_OTHER1 316rm -rf $basedir 317 318setup_test_files $basedir $ZFS_ACL_STAFF1 $ZFS_ACL_STAFF_GROUP 319test_chmod_basic_access $ZFS_ACL_STAFF1 $file $ZFS_ACL_STAFF2 $ZFS_ACL_OTHER1 320test_chmod_basic_access $ZFS_ACL_STAFF1 $dir $ZFS_ACL_STAFF2 $ZFS_ACL_OTHER1 321rm -rf $basedir 322 323log_pass "Verify that the chown/chgrp could take owner/group " \ 324 "while permission is granted." 325