When Samba master (pre 4.18) is configured without O_PATH, file listings (smb2 query directory) will fail if the file posix permissions do not include owner read permissions. This became obvious when testing the SMB3 posix patches, since I could create/open/delete a file without owner read, but then couldn't list it. This does not happen when built with O_PATH. It's easy to reproduce: ADDITIONAL_CFLAGS='-DDISABLE_OPATH=1' ./configure.developer --without-ad-dc && SELFTEST_TESTENV=fileserver make testenv In a different terminal, change directory to the share and create a file without owner read permissions: dmulder@dmlaptop:~/code/samba> cd st/fileserver/share dmulder@dmlaptop:~/code/samba/st/fileserver/share> rm -rf * dmulder@dmlaptop:~/code/samba/st/fileserver/share> touch test dmulder@dmlaptop:~/code/samba/st/fileserver/share> chmod u-r test dmulder@dmlaptop:~/code/samba/st/fileserver/share> l total 136K drwxrwxrwx 2 dmulder 132K Aug 10 10:30 ./ drwxrwxrwx 12 dmulder 4.0K Aug 10 10:20 ../ --w-r--r-- 1 dmulder 0 Aug 10 10:30 test Within the testenv: dmulder@fileserver:~/code/samba> ./bin/smbclient -s $SMB_CONF_PATH \\\\$SERVER_IP\\tmpPassword for [WORKGROUP\dmulder]: Try "help" to get a list of possible commands. smb: \> ls . D 0 Wed Aug 10 16:30:05 2022 .. D 0 Wed Aug 10 16:20:19 2022 1921725720 blocks of size 1024. 1224130300 blocks available smb: \> In your other terminal, give the test file owner read permissions again: dmulder@dmlaptop:~/code/samba/st/fileserver/share> chmod u+r test dmulder@dmlaptop:~/code/samba/st/fileserver/share> l total 136K drwxrwxrwx 2 dmulder 132K Aug 10 10:30 ./ drwxrwxrwx 12 dmulder 4.0K Aug 10 10:20 ../ -rw-r--r-- 1 dmulder 0 Aug 10 10:30 test And in the testenv: smb: \> ls . D 0 Wed Aug 10 16:30:05 2022 .. D 0 Wed Aug 10 16:20:19 2022 test N 0 Wed Aug 10 16:30:05 2022 1921725720 blocks of size 1024. 1224128856 blocks available smb: \> Testing the same scenario when built with O_PATH always lists the test file.
OK, log here shows (for file JRATEST) with no O_PATH: openat_pathref_fullname: fsp [..]: OK file_free: freed files structure 0 (1 used) smbd_dirptr_get_entry mask=[*] found .. fname=.. (..) smbd_marshall_dir_entry: space_remaining = 8388488 smbd_marshall_dir_entry: SMB_FIND_ID_BOTH_DIRECTORY_INFO smbd_dirptr_get_entry: dir [.] dirptr [0x5603dc87eb10] offset [9188369107692161392] => dname [JRATEST] openat_pathref_fsp: smb_fname [JRATEST] openat_pathref_fullname: smb_fname [JRATEST] fsp_new: allocated files structure (2 used) file_name_hash: /home/jeremy/src/samba/git/metze/st/fileserver/share/JRATEST hash 0x16409c1a push_sec_ctx(1000, 1000) : sec_ctx_stack_ndx = 1 push_conn_ctx(682576849) : conn_ctx_stack_ndx = 0 setting sec ctx (0, 0) - sec_ctx_stack_ndx = 1 Security token: (NULL) UNIX token of user 0 Primary group is 0 and contains 0 supplementary groups pop_sec_ctx (1000, 1000) - sec_ctx_stack_ndx = 0 fd_openat: name JRATEST, flags = 04000 mode = 00, fd = -1. NT_STATUS_ACCESS_DENIED openat_pathref_fullname: Opening pathref for [JRATEST] failed: NT_STATUS_ACCESS_DENIED
David, does this happen in real-world cases other than our test environment ? I added a DEBUG that shows that for test file JRATEST: vfswrap_openat: JRATEST: vfswrap_openat: have_opath = 0, is_pathref = 1 and then I see: push_sec_ctx(1000, 1000) : sec_ctx_stack_ndx = 1 push_conn_ctx(390295636) : conn_ctx_stack_ndx = 0 setting sec ctx (0, 0) - sec_ctx_stack_ndx = 1 Security token: (NULL) UNIX token of user 0 Primary group is 0 and contains 0 supplementary groups pop_sec_ctx (1000, 1000) - sec_ctx_stack_ndx = 0 before the call to: fd_openat: name JRATEST, flags = 04000 mode = 00, fd = -1. NT_STATUS_ACCESS_DENIED I think this is an artifact of the test environment, in that when we're running under testenv we have no access to real root - we just fake it. So if the real underlying filesystem has a file with u-r removed, then under the test env we can never get to it, even if we've done a become_root(). Try and reproduce this with the -DDISABLE_OPATH=1 build running for real, and I think you'll find we still access the u-r file. I think you might have to fix your test to cope with this.
(In reply to Jeremy Allison from comment #2) Ah, that makes sense. I've only seen it in the test environment. I've already modified the tests to avoid this issue, so we can simply close this bug.
I just confirmed that this does work as expected outside the samba test environment.
(In reply to Jeremy Allison from comment #2) I also hit this with this commit: https://gitlab.com/samba-team/samba/-/merge_requests/2669/diffs?commit_id=573ab934ead73fc01d10a88d5ab4b3fa492e7994 So we need to add this to selftest/skip.opath-required where we already have a "These fail because become_root() doesn't work in make test" section? Or better have a selftest/knownfail.opath-required?
My preference would be for a selftest/knownfail.opath-required, but I'll leave it up to you :-).
(In reply to Jeremy Allison from comment #6) I agree, but I didn't know we could do a knownfail for specific environments. Is this something that needs implemented, or does this already work?
(In reply to David Mulder from comment #7) --- a/selftest/wscript +++ b/selftest/wscript @@ -280,6 +280,7 @@ def cmd_testonly(opt): if os.environ.get('DISABLE_OPATH'): env.OPTIONS += " --exclude=${srcdir}/selftest/skip.opath-required" + env.FILTER_XFAIL += " --expected-failures=${srcdir}/selftest/knownfail.opath-required" if env.ADDRESS_SANITIZER: # We try to find the correct libasan automatically But first the backbox tests need to support knownfail for individual subtests...