smbd: Simplify openat_pathref_fsp_case_insensitive()
[Samba.git] / source3 / script / tests / test_symlink_traversal_smb1_posix.sh
blob52d6cfb9e3d08bb1a804d9d250f91c03ef137a86
1 #!/bin/sh
3 if [ $# -lt 7 ]; then
4 cat <<EOF
5 Usage: test_symlink_traversal_smb1_posix.sh SERVER SERVER_IP USERNAME PASSWORD LOCAL_PATH PREFIX SMBCLIENT
6 EOF
7 exit 1
8 fi
10 SERVER="${1}"
11 SERVER_IP="${2}"
12 USERNAME="${3}"
13 PASSWORD="${4}"
14 LOCAL_PATH="${5}"
15 PREFIX="${6}"
16 SMBCLIENT="${7}"
17 SMBCLIENT="$VALGRIND ${SMBCLIENT}"
18 shift 6
20 incdir=$(dirname "$0")/../../../testprogs/blackbox
21 . "$incdir"/subunit.sh
23 failed=0
25 # Do not let deprecated option warnings muck this up
26 SAMBA_DEPRECATED_SUPPRESS=1
27 export SAMBA_DEPRECATED_SUPPRESS
29 # Define the test environment/filenames.
31 share_test_dir="$LOCAL_PATH"
33 # These files/directories will be created.
35 file_outside_share="/tmp/symlink_traverse_test_file.$$"
36 dir_outside_share="/tmp/symlink_traverse_test_dir.$$"
37 file_outside_share_noperms="/tmp/symlink_traverse_test_file_noperm.$$"
38 dir_outside_share_noperms="/tmp/symlink_traverse_test_dir_noperm.$$"
40 # These two objects do not exist.
42 file_outside_share_noexist="/tmp/symlink_traverse_test_noexist.$$"
43 dir_outside_share_noexist="/tmp/symlink_traverse_test_dir_noexist.$$"
46 # Cleanup function.
48 do_cleanup()
51 #subshell.
52 cd "$share_test_dir" || return
53 rm -f "file_exists"
54 rm -f "symlink_noexist"
55 rm -f "symlink_file_outside_share"
56 rm -f "symlink_file_outside_share_noexist"
57 rm -f "symlink_dir_outside_share"
58 rm -f "symlink_dir_outside_share_noexist"
59 rm -f "symlink_file_outside_share_noperms"
60 rm -f "symlink_dir_outside_share_noperms"
61 rm -rf "emptydir"
62 # Links inside share.
63 rm -f "symlink_file_inside_share_noperms"
64 rm -f "file_inside_share_noperms"
65 rm -f "symlink_dir_inside_share_noperms"
66 chmod 755 "dir_inside_share_noperms"
67 rm -rf "dir_inside_share_noperms"
69 rm -f "$file_outside_share"
70 rm -rf "$dir_outside_share"
71 rm -f "$file_outside_share_noperms"
72 rm -rf "$dir_outside_share_noperms"
76 # Ensure we start from a clean slate.
78 do_cleanup
81 # Create the test files/directories/symlinks.
83 # File/directory explicitly outside share.
84 touch "$file_outside_share"
85 mkdir "$dir_outside_share"
86 # File/directory explicitly outside share with permission denied.
87 touch "$file_outside_share_noperms"
88 chmod 0 "$file_outside_share_noperms"
89 mkdir "$dir_outside_share_noperms"
90 chmod 0 "$dir_outside_share_noperms"
92 # Create links to these objects inside the share definition.
94 #subshell.
95 cd "$share_test_dir" || return
96 touch "file_exists"
97 ln -s "noexist" "symlink_noexist"
98 ln -s "$file_outside_share" "symlink_file_outside_share"
99 ln -s "$file_outside_share_noexist" "symlink_file_outside_share_noexist"
100 ln -s "$dir_outside_share" "symlink_dir_outside_share"
101 ln -s "$dir_outside_share_noexist" "symlink_dir_outside_share_noexist"
102 ln -s "$file_outside_share_noperms" "symlink_file_outside_share_noperms"
103 ln -s "$dir_outside_share_noperms" "symlink_dir_outside_share_noperms"
105 # Create the identical symlink set underneath "emptydir"
106 mkdir "emptydir"
108 #subshell
109 cd "emptydir" || return
110 touch "file_exists"
111 ln -s "noexist" "symlink_noexist"
112 ln -s "$file_outside_share" "symlink_file_outside_share"
113 ln -s "$file_outside_share_noexist" "symlink_file_outside_share_noexist"
114 ln -s "$dir_outside_share" "symlink_dir_outside_share"
115 ln -s "$dir_outside_share_noexist" "symlink_dir_outside_share_noexist"
116 ln -s "$file_outside_share_noperms" "symlink_file_outside_share_noperms"
117 ln -s "$dir_outside_share_noperms" "symlink_dir_outside_share_noperms"
120 # Create symlinks to access denied file and directory
121 # objects within the share
122 touch "file_inside_share_noperms"
123 chmod 0 "file_inside_share_noperms"
124 ln -s "file_inside_share_noperms" "symlink_file_inside_share_noperms"
125 mkdir "dir_inside_share_noperms"
126 touch "dir_inside_share_noperms/noperm_file_exists"
127 chmod 0 "dir_inside_share_noperms"
128 ln -s "dir_inside_share_noperms" "symlink_dir_inside_share_noperms"
132 # smbclient function given command, path, expected error, and posix.
134 smbclient_expect_error()
136 filecmd="$1"
137 filename1="$2"
138 filename2="$3"
139 expected_error="$4"
140 tmpfile=$PREFIX/smbclient_interactive_prompt_commands
141 cat >"$tmpfile" <<EOF
142 posix
143 $filecmd $filename1 $filename2
144 quit
146 cmd='CLI_FORCE_INTERACTIVE=yes $SMBCLIENT -U$USERNAME%$PASSWORD //$SERVER/local_symlinks -I$SERVER_IP -mNT1 < $tmpfile 2>&1'
147 eval echo "$cmd"
148 out=$(eval "$cmd")
149 ret=$?
150 rm -f "$tmpfile"
152 if [ $ret != 0 ]; then
153 printf "%s\n" "$out"
154 printf "failed accessing local_symlinks with error %s\n" "$ret"
155 return 1
158 if [ "$expected_error" = "NT_STATUS_OK" ]; then
159 printf "%s" "$out" | grep -v "NT_STATUS_"
160 else
161 printf "%s" "$out" | grep "$expected_error"
163 ret=$?
164 if [ $ret != 0 ]; then
165 printf "%s\n" "$out"
166 printf "failed - should get %s doing posix \"%s %s %s\"\n" "$expected_error" "$filecmd" "$filename1" "$filename2"
167 return 1
172 # SMB1+posix tests.
174 test_symlink_traversal_SMB1_posix_onename()
176 name="$1"
177 do_rename="$2"
179 # get commands.
181 # Remember in SMB1+POSIX, "*" is a perfectly valid pathname component,
182 # and symlinks can be seen, but not necessarily followed.
184 smbclient_expect_error "get" "$name" "" "NT_STATUS_OBJECT_NAME_NOT_FOUND" || return 1
185 smbclient_expect_error "get" "$name/noexist" "" "NT_STATUS_OBJECT_PATH_NOT_FOUND" || return 1
186 smbclient_expect_error "get" "$name/*" "" "NT_STATUS_OBJECT_PATH_NOT_FOUND" || return 1
187 smbclient_expect_error "get" "$name/*/noexist" "" "NT_STATUS_OBJECT_PATH_NOT_FOUND" || return 1
188 # Now in subdirectory emptydir
189 smbclient_expect_error "get" "emptydir/$name" "" "NT_STATUS_OBJECT_NAME_NOT_FOUND" || return 1
190 smbclient_expect_error "get" "emptydir/$name/noexist" "" "NT_STATUS_OBJECT_PATH_NOT_FOUND" || return 1
191 smbclient_expect_error "get" "emptydir/$name/*" "" "NT_STATUS_OBJECT_PATH_NOT_FOUND" || return 1
192 smbclient_expect_error "get" "emptydir/$name/*/noexist" "" "NT_STATUS_OBJECT_PATH_NOT_FOUND" || return 1
194 # ls commands.
196 smbclient_expect_error "ls" "$name" "" "NT_STATUS_OK" || return 1
197 smbclient_expect_error "ls" "$name/noexist" "" "NT_STATUS_OBJECT_NAME_NOT_FOUND" || return 1
198 smbclient_expect_error "ls" "$name/*" "" "NT_STATUS_OBJECT_NAME_NOT_FOUND" || return 1
199 smbclient_expect_error "ls" "$name/*/noexist" "" "NT_STATUS_OBJECT_PATH_NOT_FOUND" || return 1
200 # Now in subdirectory emptydir
201 smbclient_expect_error "ls" "emptydir/$name" "" "NT_STATUS_OK" || return 1
202 smbclient_expect_error "ls" "emptydir/$name/noexist" "" "NT_STATUS_OBJECT_NAME_NOT_FOUND" || return 1
203 smbclient_expect_error "ls" "emptydir/$name/*" "" "NT_STATUS_OBJECT_NAME_NOT_FOUND" || return 1
204 smbclient_expect_error "ls" "emptydir/$name/*/noexist" "" "NT_STATUS_OBJECT_PATH_NOT_FOUND" || return 1
206 # SMB1+POSIX stat commands. All symlinks can be stat'ed.
208 smbclient_expect_error "stat" "$name" "" "NT_STATUS_OK" || return 1
209 smbclient_expect_error "stat" "emptydir/$name" "" "NT_STATUS_OK" || return 1
211 # del commands. Under SMB1+POSIX we can legitimately delete symlinks, so don't
212 # try and delete symlink targets, we need them for the later tests.
214 smbclient_expect_error "del" "$name/noexist" "" "NT_STATUS_OBJECT_NAME_NOT_FOUND" || return 1
215 # Now in subdirectory emptydir
216 smbclient_expect_error "del" "emptydir/$name/noexist" "" "NT_STATUS_OBJECT_NAME_NOT_FOUND" || return 1
218 if [ "$do_rename" = "do rename" ]; then
220 # rename commands. Under SMB1+POSIX we can legitimately rename symlinks, so don't
221 # try and rename symlink targets, we need them for the later tests.
223 smbclient_expect_error "rename" "file_exists" "$name/noexist" "NT_STATUS_OBJECT_PATH_NOT_FOUND" || return 1
224 # Now in subdirectory emptydir
225 smbclient_expect_error "rename" "file_exists" "emptydir/$name/noexist" "NT_STATUS_OBJECT_PATH_NOT_FOUND" || return 1
227 return 0
231 # Check error code returns traversing through different
232 # kinds of symlinks over SMB1+posix.
234 test_symlink_traversal_SMB1_posix()
236 test_symlink_traversal_SMB1_posix_onename "symlink_noexist" "no rename" || return 1
237 test_symlink_traversal_SMB1_posix_onename "symlink_file_outside_share" "do rename" || return 1
238 test_symlink_traversal_SMB1_posix_onename "symlink_dir_outside_share" "do rename" || return 1
239 test_symlink_traversal_SMB1_posix_onename "symlink_dir_outside_share_noexist" "no rename" || return 1
240 test_symlink_traversal_SMB1_posix_onename "symlink_file_outside_share_noperms" "do rename" || return 1
241 test_symlink_traversal_SMB1_posix_onename "symlink_dir_outside_share_noperms" "do rename" || return 1
243 # Test paths within share with no permissions.
245 # Can't 'get' file with no perms.
246 smbclient_expect_error "get" "file_inside_share_noperms" "" "NT_STATUS_ACCESS_DENIED" || return 1
247 # In SMB1+POSIX you can't "get" a symlink at all.
248 smbclient_expect_error "get" "symlink_file_inside_share_noperms" "" "NT_STATUS_OBJECT_NAME_NOT_FOUND" || return 1
249 # But can list it and the symlink to it.
250 smbclient_expect_error "ls" "file_inside_share_noperms" "" "NT_STATUS_OK" || return 1
251 smbclient_expect_error "ls" "symlink_file_inside_share_noperms" "" "NT_STATUS_OK" || return 1
252 # Can't 'get' file inside a directory with no perms.
253 smbclient_expect_error "get" "dir_inside_share_noperms/noperm_file_exists" "" "NT_STATUS_ACCESS_DENIED" || return 1
254 # In SMB1+POSIX you can't traverse through a symlink that points to a noperm directory.
255 smbclient_expect_error "get" "symlink_dir_inside_share_noperms/noperm_file_exists" "" "NT_STATUS_ACCESS_DENIED" || return 1
256 # But can list the directory with no perms and the symlink to it.
257 smbclient_expect_error "ls" "dir_inside_share_noperms" "" "NT_STATUS_OK" || return 1
258 smbclient_expect_error "ls" "symlink_dir_inside_share_noperms" "" "NT_STATUS_OK" || return 1
261 testit "symlink_traversal_SMB1_posix" \
262 test_symlink_traversal_SMB1_posix ||
263 failed=$((failed + 1))
266 # Cleanup.
267 do_cleanup
269 testok "$0" "$failed"