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 2008 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# Copyright 2016 Nexenta Systems, Inc. 31# 32 33. $STF_SUITE/tests/functional/acl/acl_common.kshlib 34. $STF_SUITE/tests/functional/acl/cifs/cifs.kshlib 35 36# 37# DESCRIPTION: 38# Verify the user with PRIV_FILE_FLAG_SET/PRIV_FILE_FLAG_CLEAR 39# could set/clear BSD'ish attributes. 40# (Immutable, nounlink, and appendonly) 41# 42# STRATEGY: 43# 1. Loop super user and non-super user to run the test case. 44# 2. Create basedir and a set of subdirectores and files within it. 45# 3. Grant user has PRIV_FILE_FLAG_SET/PRIV_FILE_FLAG_CLEAR separately. 46# 4. Verify set/clear BSD'ish attributes should succeed. 47# 48 49verify_runnable "global" 50 51function cleanup 52{ 53 rm -rf $mntpt/file $mntpt/dir >/dev/null 2>&1 54 55 log_must cp $orig_user_attr /etc/user_attr 56 log_must rm -f $orig_user_attr 57} 58 59function try 60{ 61 typeset obj=$1 # The file or dir to operate on 62 typeset attr=$2 # The attribute to set or clear 63 typeset user=$3 # The user to run the command as 64 typeset priv=$4 # What privilege to run with if non-root 65 typeset op=$5 # Whether to set or clear the attribute 66 67 typeset cmd="chmod $op$attr $obj" 68 69 # 70 # No one can add 'q' (av_quarantine) to a directory. root can do 71 # anything else. A regular user can remove no attributes without the 72 # 'all' privilege, and can add attributes (other than 'q' on a 73 # directory) with the 'file_flag_set' or 'all' privileges. 74 # 75 if [[ $user == 'root' ]]; then 76 if [[ $attr =~ 'q' && -d $obj && $op == $add ]]; then 77 log_mustnot $cmd 78 else 79 log_must $cmd 80 fi 81 else 82 if [[ $attr =~ 'q' && -d $obj && $op == $add ]]; then 83 log_mustnot su $user -c "$cmd" 84 else 85 if [[ $op == $add ]]; then 86 if [[ -n $priv ]]; then 87 log_must su $user -c "$cmd" 88 else 89 log_mustnot su $user -c "$cmd" 90 fi 91 else 92 if [[ $attr = 'q' && -d $obj ]]; then 93 log_must su $user -c "$cmd" 94 elif [[ $priv =~ 'all' ]]; then 95 log_must su $user -c "$cmd" 96 else 97 log_mustnot su $user -c "$cmd" 98 # 99 # Remove the attribute, so the next 100 # iteration starts with a known state. 101 # 102 log_must $cmd 103 fi 104 fi 105 fi 106 fi 107 108 109 # Can't add av_quarantine to a directory, so don't check for that 110 [[ $attr == 'q' && $op == $add && -d $obj ]] && return 111 chk_attr $op $obj $attr 112} 113 114function chk_attr 115{ 116 typeset op=$1 117 typeset obj=$2 118 typeset attr=$3 119 120 # Extract the attribute string - just the text inside the braces 121 typeset attrstr="$(ls -d/ c $obj | sed '1d; s/.*{\(.*\)}.*/\1/g')" 122 123 if [[ $op == $add ]]; then 124 [[ $attrstr =~ $attr ]] || log_fail "$op $attr -> $attrstr" 125 else 126 [[ $attrstr =~ $attr ]] && log_fail "$op $attr -> $attrstr" 127 fi 128} 129 130# 131# Grant the privset to the given user 132# 133# $1: The given user 134# $2: The given privset 135# 136function grant_priv 137{ 138 typeset user=$1 139 typeset priv=$2 140 141 if [[ -z $user || -z $priv ]]; then 142 log_fail "User($user), Priv($priv) not defined." 143 fi 144 145 priv_mod=",$priv" 146 147 # If we're root, don't modify /etc/user_attr 148 [[ $user == 'root' ]] && return 0 149 150 echo "$user::::type=normal;defaultpriv=basic$priv_mod" >> \ 151 /etc/user_attr 152 return $? 153} 154 155# 156# Revoke the all additional privset from the given user 157# 158# $1: The given user 159# 160function reset_privs 161{ 162 typeset user=$1 163 164 if [[ -z $user ]]; then 165 log_fail "User not defined." 166 fi 167 168 priv_mod= 169 170 cp $orig_user_attr /etc/user_attr || log_fail "Couldn't modify user_attr" 171 return 0 172} 173 174log_assert "Verify set/clear BSD'ish attributes will succeed while user has " \ 175 "file_flag_set or all privilege" 176log_onexit cleanup 177 178add='S+c' 179del='S-c' 180mntpt=$(get_prop mountpoint $TESTPOOL/$TESTFS) 181orig_user_attr="/tmp/user_attr.$$" 182attributes="u i a d q m" 183 184log_must cp /etc/user_attr $orig_user_attr 185 186for owner in root $ZFS_ACL_STAFF1 $ZFS_ACL_STAFF2; do 187 touch $mntpt/file || log_fail "Failed to create $mntpt/file" 188 mkdir $mntpt/dir || log_fail "Failed to mkdir $mntpt/dir" 189 chown $owner $mntpt/file $mntpt/dir || log_fail "Failed to chown file" 190 for user in 'root' $ZFS_ACL_STAFF2; do 191 for attr in $attributes; do 192 for priv in 'file_flag_set' 'all'; do 193 log_note "Trying $owner $user $attr $priv" 194 grant_priv $user $priv 195 try $mntpt/file $attr $user $priv $add 196 try $mntpt/file $attr $user $priv $del 197 try $mntpt/dir $attr $user $priv $add 198 try $mntpt/dir $attr $user $priv $del 199 reset_privs $user 200 done 201 done 202 done 203 rm -rf $mntpt/file $mntpt/dir || log_fail \ 204 "$(ls -d/ c $mntpt/file $mntpt/dir)" 205done 206 207log_pass "Set/Clear BSD'ish attributes succeed while user has " \ 208 "PRIV_FILE_FLAG_SET/PRIV_FILE_FLAG_CLEAR privilege" 209