5 Usage: test_symlink_traversal_smb1_posix.sh SERVER SERVER_IP USERNAME PASSWORD LOCAL_PATH PREFIX SMBCLIENT
17 SMBCLIENT
="$VALGRIND ${SMBCLIENT}"
20 incdir
=$
(dirname "$0")/..
/..
/..
/testprogs
/blackbox
21 .
"$incdir"/subunit.sh
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
="${TMPDIR:-/tmp}/symlink_traverse_test_file.$$"
36 dir_outside_share
="${TMPDIR:-/tmp}/symlink_traverse_test_dir.$$"
37 file_outside_share_noperms
="${TMPDIR:-/tmp}/symlink_traverse_test_file_noperm.$$"
38 dir_outside_share_noperms
="${TMPDIR:-/tmp}/symlink_traverse_test_dir_noperm.$$"
40 # These two objects do not exist.
42 file_outside_share_noexist
="${TMPDIR:-/tmp}/symlink_traverse_test_noexist.$$"
43 dir_outside_share_noexist
="${TMPDIR:-/tmp}/symlink_traverse_test_dir_noexist.$$"
52 cd "$share_test_dir" ||
return
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"
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.
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.
95 cd "$share_test_dir" ||
return
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"
109 cd "emptydir" ||
return
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
()
140 tmpfile
=$PREFIX/smbclient_interactive_prompt_commands
141 cat >"$tmpfile" <<EOF
143 $filecmd $filename1 $filename2
146 cmd
='CLI_FORCE_INTERACTIVE=yes $SMBCLIENT -U$USERNAME%$PASSWORD //$SERVER/local_symlinks -I$SERVER_IP -mNT1 < $tmpfile 2>&1'
152 if [ $ret != 0 ]; then
154 printf "failed accessing local_symlinks with error %s\n" "$ret"
158 if [ "$expected_error" = "NT_STATUS_OK" ]; then
159 printf "%s" "$out" |
grep -v "NT_STATUS_"
161 printf "%s" "$out" |
grep "$expected_error"
164 if [ $ret != 0 ]; then
166 printf "failed - should get %s doing posix \"%s %s %s\"\n" "$expected_error" "$filecmd" "$filename1" "$filename2"
174 test_symlink_traversal_SMB1_posix_onename
()
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
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
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))
269 testok
"$0" "$failed"