1*d9f008e6SMax Reitz#!/usr/bin/env bash 2*d9f008e6SMax Reitz# group: rw 3*d9f008e6SMax Reitz# 4*d9f008e6SMax Reitz# Test FUSE exports' allow-other option 5*d9f008e6SMax Reitz# 6*d9f008e6SMax Reitz# Copyright (C) 2021 Red Hat, Inc. 7*d9f008e6SMax Reitz# 8*d9f008e6SMax Reitz# This program is free software; you can redistribute it and/or modify 9*d9f008e6SMax Reitz# it under the terms of the GNU General Public License as published by 10*d9f008e6SMax Reitz# the Free Software Foundation; either version 2 of the License, or 11*d9f008e6SMax Reitz# (at your option) any later version. 12*d9f008e6SMax Reitz# 13*d9f008e6SMax Reitz# This program is distributed in the hope that it will be useful, 14*d9f008e6SMax Reitz# but WITHOUT ANY WARRANTY; without even the implied warranty of 15*d9f008e6SMax Reitz# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16*d9f008e6SMax Reitz# GNU General Public License for more details. 17*d9f008e6SMax Reitz# 18*d9f008e6SMax Reitz# You should have received a copy of the GNU General Public License 19*d9f008e6SMax Reitz# along with this program. If not, see <http://www.gnu.org/licenses/>. 20*d9f008e6SMax Reitz# 21*d9f008e6SMax Reitz 22*d9f008e6SMax Reitzseq=$(basename "$0") 23*d9f008e6SMax Reitzecho "QA output created by $seq" 24*d9f008e6SMax Reitz 25*d9f008e6SMax Reitzstatus=1 # failure is the default! 26*d9f008e6SMax Reitz 27*d9f008e6SMax Reitz_cleanup() 28*d9f008e6SMax Reitz{ 29*d9f008e6SMax Reitz _cleanup_qemu 30*d9f008e6SMax Reitz _cleanup_test_img 31*d9f008e6SMax Reitz rm -f "$EXT_MP" 32*d9f008e6SMax Reitz} 33*d9f008e6SMax Reitztrap "_cleanup; exit \$status" 0 1 2 3 15 34*d9f008e6SMax Reitz 35*d9f008e6SMax Reitz# get standard environment, filters and checks 36*d9f008e6SMax Reitz. ../common.rc 37*d9f008e6SMax Reitz. ../common.filter 38*d9f008e6SMax Reitz. ../common.qemu 39*d9f008e6SMax Reitz 40*d9f008e6SMax Reitz_supported_fmt generic 41*d9f008e6SMax Reitz 42*d9f008e6SMax Reitz_supported_proto file # We create the FUSE export manually 43*d9f008e6SMax Reitz 44*d9f008e6SMax Reitzsudo -n -u nobody true || \ 45*d9f008e6SMax Reitz _notrun 'Password-less sudo as nobody required to test allow_other' 46*d9f008e6SMax Reitz 47*d9f008e6SMax Reitz# $1: Export ID 48*d9f008e6SMax Reitz# $2: Options (beyond the node-name and ID) 49*d9f008e6SMax Reitz# $3: Expected return value (defaults to 'return') 50*d9f008e6SMax Reitz# $4: Node to export (defaults to 'node-format') 51*d9f008e6SMax Reitzfuse_export_add() 52*d9f008e6SMax Reitz{ 53*d9f008e6SMax Reitz allow_other_not_supported='option allow_other only allowed if' 54*d9f008e6SMax Reitz 55*d9f008e6SMax Reitz output=$( 56*d9f008e6SMax Reitz success_or_failure=yes _send_qemu_cmd $QEMU_HANDLE \ 57*d9f008e6SMax Reitz "{'execute': 'block-export-add', 58*d9f008e6SMax Reitz 'arguments': { 59*d9f008e6SMax Reitz 'type': 'fuse', 60*d9f008e6SMax Reitz 'id': '$1', 61*d9f008e6SMax Reitz 'node-name': '${4:-node-format}', 62*d9f008e6SMax Reitz $2 63*d9f008e6SMax Reitz } }" \ 64*d9f008e6SMax Reitz "${3:-return}" \ 65*d9f008e6SMax Reitz "$allow_other_not_supported" \ 66*d9f008e6SMax Reitz | _filter_imgfmt 67*d9f008e6SMax Reitz ) 68*d9f008e6SMax Reitz 69*d9f008e6SMax Reitz if echo "$output" | grep -q "$allow_other_not_supported"; then 70*d9f008e6SMax Reitz # Shut down qemu gracefully so it can unmount the export 71*d9f008e6SMax Reitz _send_qemu_cmd $QEMU_HANDLE \ 72*d9f008e6SMax Reitz "{'execute': 'quit'}" \ 73*d9f008e6SMax Reitz 'return' 74*d9f008e6SMax Reitz 75*d9f008e6SMax Reitz wait=yes _cleanup_qemu 76*d9f008e6SMax Reitz 77*d9f008e6SMax Reitz _notrun "allow_other not supported" 78*d9f008e6SMax Reitz fi 79*d9f008e6SMax Reitz 80*d9f008e6SMax Reitz echo "$output" 81*d9f008e6SMax Reitz} 82*d9f008e6SMax Reitz 83*d9f008e6SMax ReitzEXT_MP="$TEST_DIR/fuse-export" 84*d9f008e6SMax Reitz 85*d9f008e6SMax Reitz_make_test_img 64k 86*d9f008e6SMax Reitztouch "$EXT_MP" 87*d9f008e6SMax Reitz 88*d9f008e6SMax Reitzecho 89*d9f008e6SMax Reitzecho '=== Test permissions ===' 90*d9f008e6SMax Reitz 91*d9f008e6SMax Reitz# $1: allow-other value ('on'/'off'/'auto') 92*d9f008e6SMax Reitzrun_permission_test() 93*d9f008e6SMax Reitz{ 94*d9f008e6SMax Reitz _launch_qemu \ 95*d9f008e6SMax Reitz -blockdev \ 96*d9f008e6SMax Reitz "$IMGFMT,node-name=node-format,file.driver=file,file.filename=$TEST_IMG" 97*d9f008e6SMax Reitz 98*d9f008e6SMax Reitz _send_qemu_cmd $QEMU_HANDLE \ 99*d9f008e6SMax Reitz "{'execute': 'qmp_capabilities'}" \ 100*d9f008e6SMax Reitz 'return' 101*d9f008e6SMax Reitz 102*d9f008e6SMax Reitz fuse_export_add 'export' \ 103*d9f008e6SMax Reitz "'mountpoint': '$EXT_MP', 104*d9f008e6SMax Reitz 'allow-other': '$1'" 105*d9f008e6SMax Reitz 106*d9f008e6SMax Reitz # Should always work 107*d9f008e6SMax Reitz echo '(Removing all permissions)' 108*d9f008e6SMax Reitz chmod 000 "$EXT_MP" 2>&1 | _filter_testdir | _filter_imgfmt 109*d9f008e6SMax Reitz stat -c 'Permissions post-chmod: %a' "$EXT_MP" 110*d9f008e6SMax Reitz 111*d9f008e6SMax Reitz # Should always work 112*d9f008e6SMax Reitz echo '(Granting u+r)' 113*d9f008e6SMax Reitz chmod u+r "$EXT_MP" 2>&1 | _filter_testdir | _filter_imgfmt 114*d9f008e6SMax Reitz stat -c 'Permissions post-chmod: %a' "$EXT_MP" 115*d9f008e6SMax Reitz 116*d9f008e6SMax Reitz # Should only work with allow-other: Otherwise, no permissions can be 117*d9f008e6SMax Reitz # granted to the group or others 118*d9f008e6SMax Reitz echo '(Granting read permissions for everyone)' 119*d9f008e6SMax Reitz chmod 444 "$EXT_MP" 2>&1 | _filter_testdir | _filter_imgfmt 120*d9f008e6SMax Reitz stat -c 'Permissions post-chmod: %a' "$EXT_MP" 121*d9f008e6SMax Reitz 122*d9f008e6SMax Reitz echo 'Doing operations as nobody:' 123*d9f008e6SMax Reitz # Change to TEST_DIR, so nobody will not have to attempt a lookup 124*d9f008e6SMax Reitz pushd "$TEST_DIR" >/dev/null 125*d9f008e6SMax Reitz 126*d9f008e6SMax Reitz # This is already prevented by the permissions (without allow-other, FUSE 127*d9f008e6SMax Reitz # exports always have o-r), but test it anyway 128*d9f008e6SMax Reitz sudo -n -u nobody cat fuse-export >/dev/null 129*d9f008e6SMax Reitz 130*d9f008e6SMax Reitz # If the only problem were the lack of permissions, we should still be able 131*d9f008e6SMax Reitz # to stat the export as nobody; it should not work without allow-other, 132*d9f008e6SMax Reitz # though 133*d9f008e6SMax Reitz sudo -n -u nobody \ 134*d9f008e6SMax Reitz stat -c 'Permissions seen by nobody: %a' fuse-export 2>&1 \ 135*d9f008e6SMax Reitz | _filter_imgfmt 136*d9f008e6SMax Reitz 137*d9f008e6SMax Reitz # To prove the point, revoke read permissions for others and try again 138*d9f008e6SMax Reitz chmod o-r fuse-export 2>&1 | _filter_testdir | _filter_imgfmt 139*d9f008e6SMax Reitz 140*d9f008e6SMax Reitz # Should fail 141*d9f008e6SMax Reitz sudo -n -u nobody cat fuse-export >/dev/null 142*d9f008e6SMax Reitz # Should work with allow_other 143*d9f008e6SMax Reitz sudo -n -u nobody \ 144*d9f008e6SMax Reitz stat -c 'Permissions seen by nobody: %a' fuse-export 2>&1 \ 145*d9f008e6SMax Reitz | _filter_imgfmt 146*d9f008e6SMax Reitz 147*d9f008e6SMax Reitz popd >/dev/null 148*d9f008e6SMax Reitz 149*d9f008e6SMax Reitz _send_qemu_cmd $QEMU_HANDLE \ 150*d9f008e6SMax Reitz "{'execute': 'quit'}" \ 151*d9f008e6SMax Reitz 'return' 152*d9f008e6SMax Reitz 153*d9f008e6SMax Reitz wait=yes _cleanup_qemu 154*d9f008e6SMax Reitz} 155*d9f008e6SMax Reitz 156*d9f008e6SMax Reitz# 'auto' should behave exactly like 'on', because 'on' tests that 157*d9f008e6SMax Reitz# allow_other works (otherwise, this test is skipped) 158*d9f008e6SMax Reitzfor ao in off on auto; do 159*d9f008e6SMax Reitz echo 160*d9f008e6SMax Reitz echo "--- allow-other=$ao ---" 161*d9f008e6SMax Reitz 162*d9f008e6SMax Reitz run_permission_test "$ao" 163*d9f008e6SMax Reitzdone 164*d9f008e6SMax Reitz 165*d9f008e6SMax Reitz# success, all done 166*d9f008e6SMax Reitzecho "*** done" 167*d9f008e6SMax Reitzrm -f $seq.full 168*d9f008e6SMax Reitzstatus=0 169