From a3812312a04f27a6c8a38d9f7dd50f1cdc389dc0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Nov 2021 11:48:42 -0800 Subject: [PATCH 1/5] s3: smbd: Tighten up info level checks for SMB1+POSIX to make sure POSIX was negotiated first. Add knownfail for samba3.smbtorture_s3.plain.POSIX-BLOCKING-LOCK(nt4_dc_smb1) as currently this forgets to negotiate SMB1+POSIX before doing SMB1+POSIX calls. Signed-off-by: Jeremy Allison --- selftest/knownfail.d/posix_lock_fail | 1 + source3/smbd/trans2.c | 52 ++++++++++++++++++++++++---- 2 files changed, 47 insertions(+), 6 deletions(-) create mode 100644 selftest/knownfail.d/posix_lock_fail diff --git a/selftest/knownfail.d/posix_lock_fail b/selftest/knownfail.d/posix_lock_fail new file mode 100644 index 00000000000..bf8a884cb16 --- /dev/null +++ b/selftest/knownfail.d/posix_lock_fail @@ -0,0 +1 @@ +^samba3.smbtorture_s3.plain.POSIX-BLOCKING-LOCK.smbtorture\(nt4_dc_smb1\) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 5f763d4ab4d..d0969e04e48 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -5237,8 +5237,13 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, uint32_t access_mask = 0; size_t len = 0; - if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) { - return NT_STATUS_INVALID_LEVEL; + if (INFO_LEVEL_IS_UNIX(info_level)) { + if (!lp_unix_extensions()) { + return NT_STATUS_INVALID_LEVEL; + } + if (!req->posix_pathnames) { + return NT_STATUS_INVALID_LEVEL; + } } DEBUG(5,("smbd_do_qfilepathinfo: %s (%s) level=%d max_data=%u\n", @@ -6051,9 +6056,15 @@ static void call_trans2qfilepathinfo(connection_struct *conn, DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level)); - if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) { - reply_nterror(req, NT_STATUS_INVALID_LEVEL); - return; + if (INFO_LEVEL_IS_UNIX(info_level)) { + if (!lp_unix_extensions()) { + reply_nterror(req, NT_STATUS_INVALID_LEVEL); + return; + } + if (!req->posix_pathnames) { + reply_nterror(req, NT_STATUS_INVALID_LEVEL); + return; + } } /* Initial check for valid fsp ptr. */ @@ -6146,6 +6157,10 @@ static void call_trans2qfilepathinfo(connection_struct *conn, reply_nterror(req, NT_STATUS_INVALID_LEVEL); return; } + if (!req->posix_pathnames) { + reply_nterror(req, NT_STATUS_INVALID_LEVEL); + return; + } } if (req->posix_pathnames) { @@ -9174,7 +9189,9 @@ NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn, if (!lp_unix_extensions()) { return NT_STATUS_INVALID_LEVEL; } - + if (!req->posix_pathnames) { + return NT_STATUS_INVALID_LEVEL; + } status = smbd_do_posix_setfilepathinfo(conn, req, req, @@ -9395,6 +9412,17 @@ static void call_trans2setfilepathinfo(connection_struct *conn, } info_level = SVAL(params,2); + if (INFO_LEVEL_IS_UNIX(info_level)) { + if (!lp_unix_extensions()) { + reply_nterror(req, NT_STATUS_INVALID_LEVEL); + return; + } + if (!req->posix_pathnames) { + reply_nterror(req, NT_STATUS_INVALID_LEVEL); + return; + } + } + smb_fname = fsp->fsp_name; if (fsp_get_pathref_fd(fsp) == -1) { @@ -9473,6 +9501,18 @@ static void call_trans2setfilepathinfo(connection_struct *conn, } info_level = SVAL(params,0); + + if (INFO_LEVEL_IS_UNIX(info_level)) { + if (!lp_unix_extensions()) { + reply_nterror(req, NT_STATUS_INVALID_LEVEL); + return; + } + if (!req->posix_pathnames) { + reply_nterror(req, NT_STATUS_INVALID_LEVEL); + return; + } + } + if (req->posix_pathnames) { srvstr_get_path_posix(req, params, -- 2.30.2 From c364bcb67cd4cdb9ca1029c9692a830b8b6e9676 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Nov 2021 12:16:44 -0800 Subject: [PATCH 2/5] s3: smbtorture3: Ensure we correctly negotiate SMB1+POSIX on second connection. This must be done before doing POSIX calls on a connection. Remove knownfail. Signed-off-by: Jeremy Allison --- selftest/knownfail.d/posix_lock_fail | 1 - source3/torture/torture.c | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) delete mode 100644 selftest/knownfail.d/posix_lock_fail diff --git a/selftest/knownfail.d/posix_lock_fail b/selftest/knownfail.d/posix_lock_fail deleted file mode 100644 index bf8a884cb16..00000000000 --- a/selftest/knownfail.d/posix_lock_fail +++ /dev/null @@ -1 +0,0 @@ -^samba3.smbtorture_s3.plain.POSIX-BLOCKING-LOCK.smbtorture\(nt4_dc_smb1\) diff --git a/source3/torture/torture.c b/source3/torture/torture.c index 8cfa05dd5c2..fc57655739e 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -8911,6 +8911,11 @@ static bool run_posix_blocking_lock(int dummy) return false; } + status = torture_setup_unix_extensions(cli2); + if (!NT_STATUS_IS_OK(status)) { + return false; + } + cli_setatr(cli1, fname, 0, 0); cli_posix_unlink(cli1, fname); -- 2.30.2 From 3f5e83f8c2ec9d86f7e03cd7f31afd3ec4af77c7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Nov 2021 16:57:18 -0800 Subject: [PATCH 3/5] s3: smbtorture3: Add test POSIX-SYMLINK-ERRORCODE to ensure we always get NT_STATUS_OBJECT_NAME_NOT_FOUND for dangling or unavailable symlinks. Creates 3 symlinks: 1). Within share pointing to non-existing target. 2). Outside share but to existing target. 3). Outside share but to non-existing target. It then tries to SMB1+POSIX stat these objects, all should succeed. It then tries to open via 3 methods: 1). SMB1+POSIX cli_posix_open() 2). SMB1 Windows cli_ntcreate() 3). SMB2 Windows cli_ntcreate() Ensure we always get NT_STATUS_OBJECT_NAME_NOT_FOUND for all return codes. Add knownfail. Signed-off-by: Jeremy Allison --- selftest/knownfail.d/posix_symlink_errorcode | 2 + source3/selftest/tests.py | 1 + source3/torture/proto.h | 1 + source3/torture/test_posix.c | 284 +++++++++++++++++++ source3/torture/torture.c | 4 + 5 files changed, 292 insertions(+) create mode 100644 selftest/knownfail.d/posix_symlink_errorcode diff --git a/selftest/knownfail.d/posix_symlink_errorcode b/selftest/knownfail.d/posix_symlink_errorcode new file mode 100644 index 00000000000..e2e5d28be5c --- /dev/null +++ b/selftest/knownfail.d/posix_symlink_errorcode @@ -0,0 +1,2 @@ +^samba3.smbtorture_s3.plain.POSIX-SYMLINK-ERRORCODE.smbtorture\(nt4_dc_smb1\) +^samba3.smbtorture_s3.crypt.POSIX-SYMLINK-ERRORCODE.smbtorture\(nt4_dc_smb1\) diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py index f4319959353..af2be90040e 100755 --- a/source3/selftest/tests.py +++ b/source3/selftest/tests.py @@ -299,6 +299,7 @@ posix_tests = ["POSIX", "POSIX-APPEND", "POSIX-SYMLINK-ACL", "POSIX-SYMLINK-EA", "POSIX-SYMLINK-RENAME", "POSIX-SYMLINK-GETPATHINFO", "POSIX-SYMLINK-SETPATHINFO", + "POSIX-SYMLINK-ERRORCODE", ] for t in posix_tests: diff --git a/source3/torture/proto.h b/source3/torture/proto.h index 65fa17523d8..00583e9926a 100644 --- a/source3/torture/proto.h +++ b/source3/torture/proto.h @@ -96,6 +96,7 @@ bool run_case_insensitive_create(int dummy); bool run_posix_symlink_rename_test(int dummy); bool run_posix_symlink_getpathinfo_test(int dummy); bool run_posix_symlink_setpathinfo_test(int dummy); +bool run_posix_symlink_errorcode_test(int dummy); bool run_nbench2(int dummy); bool run_async_echo(int dummy); diff --git a/source3/torture/test_posix.c b/source3/torture/test_posix.c index 20b2b136761..af44a697f1a 100644 --- a/source3/torture/test_posix.c +++ b/source3/torture/test_posix.c @@ -1888,3 +1888,287 @@ out: TALLOC_FREE(frame); return correct; } + +/* + Ensure we get the same error code of + NT_STATUS_OBJECT_NAME_NOT_FOUND for dangling + symlinks, no matter where they point or how we + try and access them. + */ + +/* Needed for SMB2 connection. */ +extern fstring host, workgroup, share, password, username, myname; +extern struct cli_credentials *torture_creds; + +bool run_posix_symlink_errorcode_test(int dummy) +{ + TALLOC_CTX *frame = NULL; + struct cli_state *cli_unix = NULL; + struct cli_state *cli_smb1_noposix = NULL; + struct cli_state *cli_smb2 = NULL; + NTSTATUS status; + struct stat statbuf; + bool correct = false; + size_t i; + int ret; + SMB_STRUCT_STAT sbuf; + uint16_t fnum_smb1 = (uint16_t)-1; + uint16_t fnum_smb2 = (uint16_t)-1; + const char *namearray_symlinks[3] = { + "nonexist_errorcode_symlink", + "tmp_symlink", + "tmp_noexist_symlink"}; + /* Can't use const herer as the third entry is dynamic. */ + char *namearray_target[3] = { + discard_const_p(char, "nonexist_errorcode_target"), + discard_const_p(char, "/tmp"), + NULL}; + + frame = talloc_stackframe(); + + printf("Starting POSIX-SYMLINK-ERRORCODE test\n"); + + /* Ensure /tmp exists. */ + ret = lstat("/tmp", &statbuf); + if (ret != 0) { + printf("lstat of /tmp failed error %s\n", + strerror(errno)); + TALLOC_FREE(frame); + return false; + } + /* + * Try 10 times to get a target name out of share we know doesn't exist. + */ + for (i = 0; i < 10; i++) { + namearray_target[2] = talloc_asprintf(talloc_tos(), + "/tmp/XXX%x%x", + (unsigned)i, + (unsigned)random()); + if (namearray_target[2] == NULL) { + TALLOC_FREE(frame); + return false; + } + ret = lstat(namearray_target[2], &statbuf); + if (ret == 0) { + TALLOC_FREE(namearray_target[2]); + continue; + } + if (ret != -1 && errno != ENOENT) { + TALLOC_FREE(namearray_target[2]); + continue; + } + break; + } + if (i == 10) { + printf("Can't find a temporary nonexistent name in /tmp\n"); + TALLOC_FREE(frame); + return false; + } + + /* Open an SMB1+POSIX connection. */ + if (!torture_open_connection(&cli_unix, 0)) { + printf("torture_open_connection SMB1+POSIX failed !\n"); + TALLOC_FREE(frame); + return false; + } + torture_conn_set_sockopt(cli_unix); + status = torture_setup_unix_extensions(cli_unix); + if (!NT_STATUS_IS_OK(status)) { + printf("torture_setup_unix_extensions failed !\n"); + TALLOC_FREE(frame); + return false; + } + + /* + * Start with a clean slate. + * Ensure + * "nonexist_errorcode_target" + * "nonexist_errorcode_symlink", + * "tmp_symlink", + * "tmp_noexist_symlink" + * don't exist. + */ + cli_posix_unlink(cli_unix, namearray_target[0]); + for (i = 0; i < ARRAY_SIZE(namearray_symlinks); i++) { + cli_posix_unlink(cli_unix, namearray_symlinks[i]); + } + + /* + * Create all 3 symlinks. + * 1). "nonexist_errorcode_symlink" -> "nonexist_errorcode_target". + * 2). "tmp_symlink" -> "/tmp" + * 3). "tmp_noexist_symlink" -> /tmp/XXX. + */ + for (i = 0; i < ARRAY_SIZE(namearray_symlinks); i++) { + status = cli_posix_symlink(cli_unix, + namearray_target[i], + namearray_symlinks[i]); + if (!NT_STATUS_IS_OK(status)) { + printf("cli_posix_symlink of %s -> %s failed " + "error %s\n", + namearray_symlinks[i], + namearray_target[i], + nt_errstr(status)); + goto out; + } + } + + /* We should be able to stat all 3. */ + for (i = 0; i < ARRAY_SIZE(namearray_symlinks); i++) { + status = cli_posix_stat(cli_unix, namearray_symlinks[i], &sbuf); + if (!NT_STATUS_IS_OK(status)) { + printf("cli_posix_stat of %s failed error %s\n", + namearray_symlinks[i], + nt_errstr(status)); + goto out; + } + } + + /* + * But Opening all 3 via SMB1+POSIX should get + * NT_STATUS_OBJECT_NAME_NOT_FOUND. + */ + for (i = 0; i < ARRAY_SIZE(namearray_symlinks); i++) { + status = cli_posix_open(cli_unix, + namearray_symlinks[i], + O_RDONLY, + 0600, + &fnum_smb1); + if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { + printf("cli_posix_open of %s got error %s " + "should be NT_STATUS_OBJECT_NAME_NOT_FOUND.\n", + namearray_symlinks[i], + nt_errstr(status)); + goto out; + } + } + + /* + * Opening all 3 via SMB1 without POSIX should also get + * NT_STATUS_OBJECT_NAME_NOT_FOUND. + */ + /* Open an SMB1 connection - without POSIX. */ + if (!torture_open_connection(&cli_smb1_noposix, 0)) { + printf("torture_open_connection SMB1 without POSIX failed !\n"); + TALLOC_FREE(frame); + return false; + } + for (i = 0; i < ARRAY_SIZE(namearray_symlinks); i++) { + status = cli_ntcreate(cli_smb1_noposix, /* cli. */ + namearray_symlinks[i], /* fname */ + 0, /* CreatFlags */ + READ_CONTROL_ACCESS, /* DesiredAccess */ + 0, /* FileAttributes */ + FILE_SHARE_READ| + FILE_SHARE_WRITE| + FILE_SHARE_DELETE, /* ShareAccess */ + FILE_OPEN, /* CreateDisposition */ + 0, /* CreateOptions */ + 0x0, /* SecurityFlags */ + &fnum_smb2, /* fnum. */ + NULL); /* cr */ + if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { + printf("cli_ntcreate of %s got error %s " + "should be NT_STATUS_OBJECT_NAME_NOT_FOUND.\n", + namearray_symlinks[i], + nt_errstr(status)); + goto out; + } + } + + /* Open an SMB2 connection. */ + if (!torture_init_connection(&cli_smb2)) { + printf("torture_init_connection for SMB2 failed\n"); + goto out; + } + + status = smbXcli_negprot(cli_smb2->conn, + cli_smb2->timeout, + PROTOCOL_SMB2_02, + PROTOCOL_SMB2_02); + if (!NT_STATUS_IS_OK(status)) { + printf("SMB2 smbXcli_negprot returned %s\n", + nt_errstr(status)); + goto out; + } + + status = cli_session_setup_creds(cli_smb2, torture_creds); + if (!NT_STATUS_IS_OK(status)) { + printf("SMB2 cli_session_setup returned %s\n", + nt_errstr(status)); + goto out; + } + + status = cli_tree_connect(cli_smb2, share, "?????", NULL); + if (!NT_STATUS_IS_OK(status)) { + printf("SMB2 cli_tree_connect returned %s\n", + nt_errstr(status)); + goto out; + } + + /* + * Opening all 3 via SMB2 should get + * NT_STATUS_OBJECT_NAME_NOT_FOUND. + */ + for (i = 0; i < ARRAY_SIZE(namearray_symlinks); i++) { + status = cli_ntcreate(cli_smb2, /* cli. */ + namearray_symlinks[i], /* fname */ + 0, /* CreatFlags */ + READ_CONTROL_ACCESS, /* DesiredAccess */ + 0, /* FileAttributes */ + FILE_SHARE_READ| + FILE_SHARE_WRITE| + FILE_SHARE_DELETE, /* ShareAccess */ + FILE_OPEN, /* CreateDisposition */ + 0, /* CreateOptions */ + 0x0, /* SecurityFlags */ + &fnum_smb2, /* fnum. */ + NULL); /* cr */ + if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { + printf("cli_ntcreate of %s got error %s " + "should be NT_STATUS_OBJECT_NAME_NOT_FOUND.\n", + namearray_symlinks[i], + nt_errstr(status)); + goto out; + } + } + + printf("POSIX-SYMLINK-ERRORCODE test passed\n"); + correct = true; + +out: + if (fnum_smb1 != (uint16_t)-1) { + cli_close(cli_unix, fnum_smb1); + } + if (fnum_smb2 != (uint16_t)-1) { + cli_close(cli_smb2, fnum_smb2); + } + /* Ensure + * "nonexist_errorcode_target" + * "nonexist_errorcode_symlink", + * "tmp_symlink", + * "tmp_noexist_symlink" + * don't exist. + */ + cli_posix_unlink(cli_unix, namearray_target[0]); + for (i = 0; i < ARRAY_SIZE(namearray_symlinks); i++) { + cli_posix_unlink(cli_unix, namearray_symlinks[i]); + } + if (cli_unix != NULL) { + if (!torture_close_connection(cli_unix)) { + correct = false; + } + } + if (cli_smb1_noposix != NULL) { + if (!torture_close_connection(cli_smb1_noposix)) { + correct = false; + } + } + if (cli_smb2 != NULL) { + if (!torture_close_connection(cli_smb2)) { + correct = false; + } + } + TALLOC_FREE(frame); + return correct; +} diff --git a/source3/torture/torture.c b/source3/torture/torture.c index fc57655739e..faaf2c58bcf 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -15021,6 +15021,10 @@ static struct { .name = "POSIX-SYMLINK-SETPATHINFO", .fn = run_posix_symlink_setpathinfo_test, }, + { + .name = "POSIX-SYMLINK-ERRORCODE", + .fn = run_posix_symlink_errorcode_test, + }, { .name = "WINDOWS-BAD-SYMLINK", .fn = run_symlink_open_test, -- 2.30.2 From 2b42776e04cb3ac09b782d993fa752e74b62cf4e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Nov 2021 11:46:58 -0800 Subject: [PATCH 4/5] s3: smbd: In check_reduced_name(), return NT_STATUS_OBJECT_NAME_NOT_FOUND instead of NT_STATUS_ACCESS_DENIED for symlinks we cannot reach. They are either out of share or point to nowhere. Always match the symlink error returned by openat_pathref_fsp(). This unifies the return for symlinks over SMB1, SMB1+POSIX and SMB2 when parsing a path and lays the foundation for SMB2+POSIX. Update test_smbclient_s3.sh to check this. Signed-off-by: Jeremy Allison --- source3/script/tests/test_smbclient_s3.sh | 10 +++++----- source3/smbd/vfs.c | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/source3/script/tests/test_smbclient_s3.sh b/source3/script/tests/test_smbclient_s3.sh index 89a17656159..e250d4dd106 100755 --- a/source3/script/tests/test_smbclient_s3.sh +++ b/source3/script/tests/test_smbclient_s3.sh @@ -1044,12 +1044,12 @@ EOF return 1 fi -# This should fail with NT_STATUS_ACCESS_DENIED - echo "$out" | grep 'NT_STATUS_ACCESS_DENIED' +# This should fail with NT_STATUS_OBJECT_NAME_NOT_FOUND + echo "$out" | grep 'NT_STATUS_OBJECT_NAME_NOT_FOUND' ret=$? if [ $ret != 0 ] ; then echo "$out" - echo "failed - should get NT_STATUS_ACCESS_DENIED listing \\widelinks_share\\source" + echo "failed - should get NT_STATUS_OBJECT_NAME_NOT_FOUND listing \\widelinks_share\\source" return 1 fi } @@ -1168,11 +1168,11 @@ EOF return 1 fi - echo "$out" | grep 'NT_STATUS_ACCESS_DENIED' + echo "$out" | grep 'NT_STATUS_OBJECT_NAME_NOT_FOUND' ret=$? if [ $ret -ne 0 ] ; then echo "$out" - echo "failed - should get NT_STATUS_ACCESS_DENIED getting \\nosymlinks\\source" + echo "failed - should get NT_STATUS_OBJECT_NAME_NOT_FOUND getting \\nosymlinks\\source" return 1 fi diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index 570de843811..457d1f43caf 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -1429,7 +1429,7 @@ NTSTATUS check_reduced_name(connection_struct *conn, conn_rootdir, resolved_name); TALLOC_FREE(resolved_fname); - return NT_STATUS_ACCESS_DENIED; + return NT_STATUS_OBJECT_NAME_NOT_FOUND; } } @@ -1453,7 +1453,7 @@ NTSTATUS check_reduced_name(connection_struct *conn, *p, fname); TALLOC_FREE(resolved_fname); - return NT_STATUS_ACCESS_DENIED; + return NT_STATUS_OBJECT_NAME_NOT_FOUND; } p++; @@ -1484,7 +1484,7 @@ NTSTATUS check_reduced_name(connection_struct *conn, p); TALLOC_FREE(resolved_fname); TALLOC_FREE(new_fname); - return NT_STATUS_ACCESS_DENIED; + return NT_STATUS_OBJECT_NAME_NOT_FOUND; } } -- 2.30.2 From 3fec8eec675be26f7d640e73d572f625f2d9d151 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Nov 2021 13:43:08 -0800 Subject: [PATCH 5/5] s3: smbd: For SMB1+POSIX clients trying to open a symlink, always return NT_STATUS_OBJECT_NAME_NOT_FOUND. Matches the error return from openat_pathref_fsp(). NT_STATUS_OBJECT_PATH_NOT_FOUND is for a bad component in a path, not a bad terminal symlink. Now all symlink errors are returned as NT_STATUS_OBJECT_NAME_NOT_FOUND for both SMB1, SMB1+POSIX and SMB2+. Remove knownfail. Signed-off-by: Jeremy Allison --- selftest/knownfail.d/posix_symlink_errorcode | 2 -- source3/smbd/open.c | 13 ++++++------- 2 files changed, 6 insertions(+), 9 deletions(-) delete mode 100644 selftest/knownfail.d/posix_symlink_errorcode diff --git a/selftest/knownfail.d/posix_symlink_errorcode b/selftest/knownfail.d/posix_symlink_errorcode deleted file mode 100644 index e2e5d28be5c..00000000000 --- a/selftest/knownfail.d/posix_symlink_errorcode +++ /dev/null @@ -1,2 +0,0 @@ -^samba3.smbtorture_s3.plain.POSIX-SYMLINK-ERRORCODE.smbtorture\(nt4_dc_smb1\) -^samba3.smbtorture_s3.crypt.POSIX-SYMLINK-ERRORCODE.smbtorture\(nt4_dc_smb1\) diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 7f1aedbd1fb..753c0f56ada 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -1448,12 +1448,10 @@ static NTSTATUS open_file(files_struct *fsp, * POSIX client that hit a symlink. We don't want to * return NT_STATUS_STOPPED_ON_SYMLINK to avoid handling * this special error code in all callers, so we map - * this to NT_STATUS_OBJECT_PATH_NOT_FOUND. Historically - * the lower level functions returned status code mapped - * from errno by map_nt_error_from_unix() where ELOOP is - * mapped to NT_STATUS_OBJECT_PATH_NOT_FOUND. + * this to NT_STATUS_OBJECT_NAME_NOT_FOUND to match + * openat_pathref_fsp(). */ - status = NT_STATUS_OBJECT_PATH_NOT_FOUND; + status = NT_STATUS_OBJECT_NAME_NOT_FOUND; } if (!NT_STATUS_IS_OK(status)) { DEBUG(3,("Error opening file %s (%s) (local_flags=%d) " @@ -1536,9 +1534,10 @@ static NTSTATUS open_file(files_struct *fsp, { /* * Don't allow stat opens on symlinks directly unless - * it's a POSIX open. + * it's a POSIX open. Match the return code from + * openat_pathref_fsp(). */ - return NT_STATUS_OBJECT_PATH_NOT_FOUND; + return NT_STATUS_OBJECT_NAME_NOT_FOUND; } if (!fsp->fsp_flags.is_pathref) { -- 2.30.2