From 72fa89e83d8a40befe685fc78770a52f2c03c70e Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Mon, 1 Feb 2021 11:59:37 +0100 Subject: [PATCH 01/21] s3/libadouble: stat path before calling openat_pathref_fsp() in ad_unconvert_open_ad() BUG: https://bugzilla.samba.org/show_bug.cgi?id=14730 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison (cherry picked from commit 4f30c04462fb1536323606dd4216fe5e32458ba5) --- source3/lib/adouble.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/source3/lib/adouble.c b/source3/lib/adouble.c index dffc0d5b7be..0ab9019cfb5 100644 --- a/source3/lib/adouble.c +++ b/source3/lib/adouble.c @@ -1492,13 +1492,18 @@ static bool ad_unconvert_open_ad(TALLOC_CTX *mem_ctx, NTSTATUS status; int ret; - status = openat_pathref_fsp(handle->conn->cwd_fsp, adpath); - if (!NT_STATUS_IS_OK(status) && - !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) - { + ret = vfs_stat(handle->conn, adpath); + if (ret == -1 && errno != ENOENT) { return false; } + if (VALID_STAT(adpath->st)) { + status = openat_pathref_fsp(handle->conn->cwd_fsp, adpath); + if (!NT_STATUS_IS_OK(status)) { + return false; + } + } + status = SMB_VFS_CREATE_FILE( handle->conn, NULL, /* req */ -- 2.31.1 From eb6d2bdbf622f54d4d9cff85b6e19ea25c6be5b4 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Mon, 1 Feb 2021 12:00:35 +0100 Subject: [PATCH 02/21] smbd: stat path before calling openat_pathref_fsp() in unlink_internals() BUG: https://bugzilla.samba.org/show_bug.cgi?id=14730 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison (cherry picked from commit ab82dbc5ae43cdb661bf49627a84926163bc8998) --- source3/smbd/reply.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 834fd484192..bf2a13a2aac 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -3281,6 +3281,7 @@ NTSTATUS unlink_internals(connection_struct *conn, NTSTATUS status = NT_STATUS_OK; struct smb_filename *smb_fname_dir = NULL; TALLOC_CTX *ctx = talloc_tos(); + int ret; /* Split up the directory from the filename/mask. */ status = split_fname_dir_mask(ctx, smb_fname->base_name, @@ -3457,6 +3458,15 @@ NTSTATUS unlink_internals(connection_struct *conn, goto out; } + ret = vfs_stat(conn, f); + if (ret != 0) { + status = map_nt_error_from_unix(errno); + TALLOC_FREE(dir_hnd); + TALLOC_FREE(frame); + TALLOC_FREE(talloced); + goto out; + } + status = openat_pathref_fsp(conn->cwd_fsp, f); if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) -- 2.31.1 From f747abc5c5c89578c94a57ef5d2df79e1f01e930 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Mon, 1 Feb 2021 12:01:01 +0100 Subject: [PATCH 03/21] smbd: fix a resource leak in create_file_unixpath() BUG: https://bugzilla.samba.org/show_bug.cgi?id=14730 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison (cherry picked from commit e636e20f90d4ee221ce6e20cab15a3cecb03850f) --- source3/smbd/open.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source3/smbd/open.c b/source3/smbd/open.c index acb248047bf..f7f893a92a1 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -5783,6 +5783,7 @@ static NTSTATUS create_file_unixpath(connection_struct *conn, "for base %s failed: " "%s\n", smb_fname->base_name, nt_errstr(status))); + TALLOC_FREE(smb_fname_base); goto fail; } } -- 2.31.1 From 61f8d2cf8631d17bfb19c1c2b644bebadf9eb48c Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Mon, 1 Feb 2021 12:01:22 +0100 Subject: [PATCH 04/21] smbd: call stat before openat_pathref_fsp() in create_file_unixpath() BUG: https://bugzilla.samba.org/show_bug.cgi?id=14730 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison (cherry picked from commit aa0ef26d1e9dcef0bcb47974d7cf60db922d7d08) --- source3/smbd/open.c | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/source3/smbd/open.c b/source3/smbd/open.c index f7f893a92a1..0451adcce96 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -5587,6 +5587,7 @@ static NTSTATUS create_file_unixpath(connection_struct *conn, files_struct *base_fsp = NULL; files_struct *fsp = NULL; NTSTATUS status; + int ret; DBG_DEBUG("create_file_unixpath: access_mask = 0x%x " "file_attributes = 0x%x, share_access = 0x%x, " @@ -5734,30 +5735,34 @@ static NTSTATUS create_file_unixpath(connection_struct *conn, goto fail; } - SET_STAT_INVALID(smb_fname_base->st); - /* * We may be creating the basefile as part of creating the * stream, so it's legal if the basefile doesn't exist at this * point, the create_file_unixpath() below will create it. But * if the basefile exists we want a handle so we can fstat() it. */ - status = openat_pathref_fsp(conn->cwd_fsp, smb_fname_base); - if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) { - status = NT_STATUS_OBJECT_NAME_NOT_FOUND; - } - if (!NT_STATUS_IS_OK(status) && - !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) - { - DBG_ERR("open_smb_fname_fsp [%s] failed: %s\n", - smb_fname_str_dbg(smb_fname_base), - nt_errstr(status)); + + ret = vfs_stat(conn, smb_fname_base); + if (ret == -1 && errno != ENOENT) { + status = map_nt_error_from_unix(errno); TALLOC_FREE(smb_fname_base); goto fail; } - - if (smb_fname_base->fsp != NULL) { - int ret; + if (ret == 0) { + status = openat_pathref_fsp(conn->cwd_fsp, + smb_fname_base); + if (NT_STATUS_EQUAL(status, + NT_STATUS_STOPPED_ON_SYMLINK)) + { + status = NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + if (!NT_STATUS_IS_OK(status)) { + DBG_ERR("open_smb_fname_fsp [%s] failed: %s\n", + smb_fname_str_dbg(smb_fname_base), + nt_errstr(status)); + TALLOC_FREE(smb_fname_base); + goto fail; + } ret = SMB_VFS_FSTAT(smb_fname_base->fsp, &smb_fname_base->st); -- 2.31.1 From d24f8b69e9b95b0515a6da3aed79fd0e12c686f9 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Mon, 1 Feb 2021 12:03:08 +0100 Subject: [PATCH 05/21] smbd: remove a redundant fstat()in create_file_unixpath() openat_pathref_fsp() deep inside already calls fstat(). BUG: https://bugzilla.samba.org/show_bug.cgi?id=14730 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison (cherry picked from commit 91edc50dc0aaa82d9ede7a7f8cf0f63312eb8503) --- source3/smbd/open.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 0451adcce96..172bc2e2f1f 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -5764,14 +5764,6 @@ static NTSTATUS create_file_unixpath(connection_struct *conn, goto fail; } - ret = SMB_VFS_FSTAT(smb_fname_base->fsp, - &smb_fname_base->st); - if (ret != 0) { - DBG_DEBUG("Unable to stat stream [%s]: %s\n", - smb_fname_str_dbg(smb_fname_base), - strerror(errno)); - } - /* * https://bugzilla.samba.org/show_bug.cgi?id=10229 * We need to check if the requested access mask -- 2.31.1 From 4d13d93f60405fdc575ef4552be784e89406daa0 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Mon, 1 Feb 2021 12:04:01 +0100 Subject: [PATCH 06/21] smbd: stat path before calling openat_pathref_fsp() in open_pathref_base_fsp() BUG: https://bugzilla.samba.org/show_bug.cgi?id=14730 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison (cherry picked from commit c31fe2f9e7d65409229b7ad73418793ab34d359d) --- source3/smbd/files.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source3/smbd/files.c b/source3/smbd/files.c index d9fd2b8ea86..02442a962ed 100644 --- a/source3/smbd/files.c +++ b/source3/smbd/files.c @@ -395,6 +395,7 @@ static NTSTATUS open_pathref_base_fsp(const struct files_struct *dirfsp, { struct smb_filename *smb_fname_base = NULL; NTSTATUS status; + int ret; smb_fname_base = synthetic_smb_fname(talloc_tos(), fsp->fsp_name->base_name, @@ -406,6 +407,11 @@ static NTSTATUS open_pathref_base_fsp(const struct files_struct *dirfsp, return NT_STATUS_NO_MEMORY; } + ret = vfs_stat(fsp->conn, smb_fname_base); + if (ret != 0) { + return map_nt_error_from_unix(errno); + } + status = openat_pathref_fsp(dirfsp, smb_fname_base); if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(smb_fname_base); -- 2.31.1 From 9c2b7739d74bbe8d1ca5cad4b14cbb8df0f4f0ef Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Mon, 1 Feb 2021 12:04:49 +0100 Subject: [PATCH 07/21] smbd: move smb_fname creation to earlier point in smbd_dirptr_get_entry() No change in behaviour. Makes way for the next commit adding additional logic. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14730 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison (cherry picked from commit b3a0d6a128989b593f135c425dd59351d13b6120) --- source3/smbd/dir.c | 68 +++++++++++++++++++++------------------------- 1 file changed, 31 insertions(+), 37 deletions(-) diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index ae92fa08161..f562cda6bee 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -860,6 +860,33 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx, return false; } + /* + * We don't want to pass ./xxx to modules below us so don't + * add the path if it is just . by itself. + */ + if (dirptr_path_is_dot) { + memcpy(pathreal, dname, talloc_get_size(dname)); + } else { + memcpy(pathreal, dpath, pathlen); + pathreal[pathlen] = '/'; + memcpy(pathreal + slashlen + pathlen, dname, + talloc_get_size(dname)); + } + + /* Create smb_fname with NULL stream_name. */ + smb_fname = synthetic_smb_fname(talloc_tos(), + pathreal, + NULL, + &sbuf, + dirptr->smb_dname->twrp, + dirptr->smb_dname->flags); + TALLOC_FREE(pathreal); + if (smb_fname == NULL) { + TALLOC_FREE(dname); + TALLOC_FREE(fname); + return false; + } + /* Create smb_fname with NULL stream_name. */ atname = synthetic_smb_fname(talloc_tos(), dname, @@ -870,7 +897,7 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx, if (atname == NULL) { TALLOC_FREE(dname); TALLOC_FREE(fname); - TALLOC_FREE(pathreal); + TALLOC_FREE(smb_fname); return false; } @@ -893,14 +920,14 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx, TALLOC_FREE(atname); TALLOC_FREE(dname); TALLOC_FREE(fname); - TALLOC_FREE(pathreal); + TALLOC_FREE(smb_fname); continue; } else if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) { if (!(atname->flags & SMB_FILENAME_POSIX_PATH)) { TALLOC_FREE(atname); TALLOC_FREE(dname); TALLOC_FREE(fname); - TALLOC_FREE(pathreal); + TALLOC_FREE(smb_fname); continue; } /* @@ -915,7 +942,7 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx, TALLOC_FREE(atname); TALLOC_FREE(dname); TALLOC_FREE(fname); - TALLOC_FREE(pathreal); + TALLOC_FREE(smb_fname); continue; } /* @@ -927,34 +954,6 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx, check_dfs_symlink = true; } - /* - * We don't want to pass ./xxx to modules below us so don't - * add the path if it is just . by itself. - */ - if (dirptr_path_is_dot) { - memcpy(pathreal, dname, talloc_get_size(dname)); - } else { - memcpy(pathreal, dpath, pathlen); - pathreal[pathlen] = '/'; - memcpy(pathreal + slashlen + pathlen, dname, - talloc_get_size(dname)); - } - - /* Create smb_fname with NULL stream_name. */ - smb_fname = synthetic_smb_fname(talloc_tos(), - pathreal, - NULL, - &sbuf, - dirptr->smb_dname->twrp, - dirptr->smb_dname->flags); - if (smb_fname == NULL) { - TALLOC_FREE(atname); - TALLOC_FREE(dname); - TALLOC_FREE(fname); - TALLOC_FREE(pathreal); - return false; - } - status = move_smb_fname_fsp_link(smb_fname, atname); TALLOC_FREE(atname); if (!NT_STATUS_IS_OK(status)) { @@ -964,7 +963,6 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx, TALLOC_FREE(smb_fname); TALLOC_FREE(dname); TALLOC_FREE(fname); - TALLOC_FREE(pathreal); continue; } @@ -973,7 +971,6 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx, TALLOC_FREE(smb_fname); TALLOC_FREE(dname); TALLOC_FREE(fname); - TALLOC_FREE(pathreal); continue; } @@ -992,7 +989,6 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx, TALLOC_FREE(smb_fname); TALLOC_FREE(dname); TALLOC_FREE(fname); - TALLOC_FREE(pathreal); continue; } @@ -1002,7 +998,6 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx, TALLOC_FREE(smb_fname); TALLOC_FREE(dname); TALLOC_FREE(fname); - TALLOC_FREE(pathreal); continue; } @@ -1037,7 +1032,6 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx, TALLOC_FREE(dname); *_smb_fname = talloc_move(ctx, &smb_fname); - TALLOC_FREE(pathreal); if (*_smb_fname == NULL) { return false; } -- 2.31.1 From 94ca0c1e4eef6da626e19991c5ac43c7f26e4e1e Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Mon, 1 Feb 2021 12:09:39 +0100 Subject: [PATCH 08/21] smbd: stat path before calling openat_pathref_fsp() in smbd_dirptr_get_entry() BUG: https://bugzilla.samba.org/show_bug.cgi?id=14730 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison (cherry picked from commit 87e97e1b519159b5f4c5ed4ef684783855e79ac3) --- source3/smbd/dir.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index f562cda6bee..dc53fc0b30d 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -793,6 +793,7 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx, const char *dpath = dirptr->smb_dname->base_name; bool dirptr_path_is_dot = ISDOT(dpath); NTSTATUS status; + int ret; *_smb_fname = NULL; *_mode = 0; @@ -887,11 +888,27 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx, return false; } + if (!VALID_STAT(smb_fname->st)) { + /* + * If stat() fails with ENOENT it might be a + * msdfs-symlink in Windows context, this is checked + * below, for now we just want to fill stat info as good + * as we can. + */ + ret = vfs_stat(conn, smb_fname); + if (ret != 0 && errno != ENOENT) { + TALLOC_FREE(smb_fname); + TALLOC_FREE(dname); + TALLOC_FREE(fname); + continue; + } + } + /* Create smb_fname with NULL stream_name. */ atname = synthetic_smb_fname(talloc_tos(), dname, NULL, - &sbuf, + &smb_fname->st, dirptr->smb_dname->twrp, dirptr->smb_dname->flags); if (atname == NULL) { -- 2.31.1 From 203c036ae92ea27ea7693a3c5ecc4eec500badcd Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Mon, 1 Feb 2021 10:17:13 +0100 Subject: [PATCH 09/21] smbd: expect valid stat info in openat_pathref_fsp() We're never creating files here, so instead of waiting for the underlying open() to return ENOENT, just check that we have valid stat info, expecting all callers to have called SMB_VFS_[L]STAT() on the smb_fname. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14730 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison (cherry picked from commit 48bc561d1a8bb5ce99663b58a2e5e9aa344af96a) --- source3/smbd/files.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/source3/smbd/files.c b/source3/smbd/files.c index 02442a962ed..ee1afece33f 100644 --- a/source3/smbd/files.c +++ b/source3/smbd/files.c @@ -441,7 +441,6 @@ NTSTATUS openat_pathref_fsp(const struct files_struct *dirfsp, { connection_struct *conn = dirfsp->conn; struct smb_filename *full_fname = NULL; - bool file_existed = VALID_STAT(smb_fname->st); struct files_struct *fsp = NULL; int open_flags = O_RDONLY; NTSTATUS status; @@ -455,7 +454,11 @@ NTSTATUS openat_pathref_fsp(const struct files_struct *dirfsp, return NT_STATUS_OK; } - if (file_existed && S_ISLNK(smb_fname->st.st_ex_mode)) { + if (!VALID_STAT(smb_fname->st)) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + if (S_ISLNK(smb_fname->st.st_ex_mode)) { return NT_STATUS_STOPPED_ON_SYMLINK; } @@ -540,9 +543,7 @@ NTSTATUS openat_pathref_fsp(const struct files_struct *dirfsp, return NT_STATUS_OBJECT_NAME_NOT_FOUND; } - if (file_existed && - !check_same_dev_ino(&smb_fname->st, &fsp->fsp_name->st)) - { + if (!check_same_dev_ino(&smb_fname->st, &fsp->fsp_name->st)) { DBG_DEBUG("file [%s] - dev/ino mismatch. " "Old (dev=%ju, ino=%ju). " "New (dev=%ju, ino=%ju).\n", -- 2.31.1 From baadf95f6be8832e65a590e06eee97aa82c240e1 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Tue, 2 Feb 2021 13:49:56 +0100 Subject: [PATCH 10/21] smbd: simplify error codepath in openat_pathref_fsp() No change in behaviour: the cleanup code at the fail label does the same as the cleanup this patch removes. It has an extra fd_close() that is not existing in the removed cleanup, but as fsp->fd is -1, that's a noop. And when previously the return NT_STATUS_OBJECT_NAME_NOT_FOUND; returns an an explicit status code, when now doing goto fail status will also be set to NT_STATUS_OBJECT_NAME_NOT_FOUND. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14730 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison (cherry picked from commit cd3d970c84b340630745bc555a86ac2d1306baac) --- source3/smbd/files.c | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/source3/smbd/files.c b/source3/smbd/files.c index ee1afece33f..69dbd09a550 100644 --- a/source3/smbd/files.c +++ b/source3/smbd/files.c @@ -505,21 +505,6 @@ NTSTATUS openat_pathref_fsp(const struct files_struct *dirfsp, status = fd_openat(dirfsp, smb_fname, fsp, open_flags, 0); if (!NT_STATUS_IS_OK(status)) { - DBG_DEBUG("Could not open fd for [%s]: %s\n", - fsp_str_dbg(fsp), - nt_errstr(status)); - - if (fsp->base_fsp != NULL) { - struct files_struct *tmp_base_fsp = fsp->base_fsp; - - fsp_set_base_fsp(fsp, NULL); - - fd_close(tmp_base_fsp); - file_free(NULL, tmp_base_fsp); - } - file_free(NULL, fsp); - fsp = NULL; - if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND) || NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) { @@ -536,11 +521,7 @@ NTSTATUS openat_pathref_fsp(const struct files_struct *dirfsp, */ status = NT_STATUS_OBJECT_NAME_NOT_FOUND; } - if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { - goto fail; - } - - return NT_STATUS_OBJECT_NAME_NOT_FOUND; + goto fail; } if (!check_same_dev_ino(&smb_fname->st, &fsp->fsp_name->st)) { -- 2.31.1 From 1df49a79cd1ffb0561bcf58140557baa8c6fd2b2 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Tue, 2 Feb 2021 11:18:54 +0100 Subject: [PATCH 11/21] smbd: don't return NT_STATUS_STOPPED_ON_SYMLINK in openat_pathref_fsp() NT_STATUS_STOPPED_ON_SYMLINK is returned when trying to open a symlink, most callers are not interested in this. Some callers that would want to know whether openat_pathref_fsp() failed specifically on a symlink are setup_close_full_information(), smbd_dirptr_get_entry(), unlink_internals() and filename_convert_internal(), so we fix those callers to handle the symlink case themselves. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14730 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison (cherry picked from commit 977f37643b223e164fbbf6c3ba1d37aa546ddb7d) --- source3/smbd/dir.c | 33 +++++++-------------------------- source3/smbd/filename.c | 15 +++++---------- source3/smbd/files.c | 9 +++++++-- source3/smbd/reply.c | 8 ++++++-- source3/smbd/smb2_close.c | 5 ++++- 5 files changed, 29 insertions(+), 41 deletions(-) diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index dc53fc0b30d..6614b4d4c47 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -931,44 +931,25 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx, */ status = openat_pathref_fsp(dirptr->dir_hnd->fsp, atname); if (!NT_STATUS_IS_OK(status) && - !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) && - !NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) + !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { TALLOC_FREE(atname); TALLOC_FREE(dname); TALLOC_FREE(fname); TALLOC_FREE(smb_fname); continue; - } else if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) { + } else if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { if (!(atname->flags & SMB_FILENAME_POSIX_PATH)) { - TALLOC_FREE(atname); - TALLOC_FREE(dname); - TALLOC_FREE(fname); - TALLOC_FREE(smb_fname); - continue; + check_dfs_symlink = true; } /* - * It's a symlink, disable getting dosmode in the - * mode_fn() and prime the mode as - * FILE_ATTRIBUTE_NORMAL. + * Check if it's a symlink. We only want to return this + * if it's a DFS symlink or in POSIX mode. Disable + * getting dosmode in the mode_fn() and prime the mode + * as FILE_ATTRIBUTE_NORMAL. */ mode = FILE_ATTRIBUTE_NORMAL; get_dosmode = false; - } else if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { - if (atname->flags & SMB_FILENAME_POSIX_PATH) { - TALLOC_FREE(atname); - TALLOC_FREE(dname); - TALLOC_FREE(fname); - TALLOC_FREE(smb_fname); - continue; - } - /* - * Likely a dangling symlink. We only want to return - * this if it's a DFS symlink, so we need to check for - * that. Set get_dosmode to skip getting dosmode. - */ - get_dosmode = false; - check_dfs_symlink = true; } status = move_smb_fname_fsp_link(smb_fname, atname); diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index 184a293f205..9035c7e82c7 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -1982,14 +1982,9 @@ static NTSTATUS filename_convert_internal(TALLOC_CTX *ctx, } status = openat_pathref_fsp(conn->cwd_fsp, smb_fname); - if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) { + if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { /* - * Don't leak NT_STATUS_STOPPED_ON_SYMLINK into the callers: - * it's a special SMB2 error that needs an extended SMB2 error - * response. We don't support that for SMB2 and it doesn't exist - * at all in SMB1. - * - * So we deal with symlinks here as we do in + * We deal with symlinks here as we do in * SMB_VFS_CREATE_FILE(): return success for POSIX clients with * the notable difference that there will be no fsp in * smb_fname->fsp. @@ -1997,10 +1992,10 @@ static NTSTATUS filename_convert_internal(TALLOC_CTX *ctx, * For Windows (non POSIX) clients fail with * NT_STATUS_OBJECT_NAME_NOT_FOUND. */ - if (ucf_flags & UCF_POSIX_PATHNAMES) { + if (smb_fname->flags & SMB_FILENAME_POSIX_PATH && + S_ISLNK(smb_fname->st.st_ex_mode)) + { status = NT_STATUS_OK; - } else { - status = NT_STATUS_OBJECT_NAME_NOT_FOUND; } } if (!NT_STATUS_IS_OK(status)) { diff --git a/source3/smbd/files.c b/source3/smbd/files.c index 69dbd09a550..371af875d4b 100644 --- a/source3/smbd/files.c +++ b/source3/smbd/files.c @@ -459,7 +459,7 @@ NTSTATUS openat_pathref_fsp(const struct files_struct *dirfsp, } if (S_ISLNK(smb_fname->st.st_ex_mode)) { - return NT_STATUS_STOPPED_ON_SYMLINK; + return NT_STATUS_OBJECT_NAME_NOT_FOUND; } status = fsp_new(conn, conn, &fsp); @@ -506,7 +506,8 @@ NTSTATUS openat_pathref_fsp(const struct files_struct *dirfsp, status = fd_openat(dirfsp, smb_fname, fsp, open_flags, 0); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND) || - NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) + NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND) || + NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) { /* * streams_xattr return NT_STATUS_NOT_FOUND for @@ -518,6 +519,10 @@ NTSTATUS openat_pathref_fsp(const struct files_struct *dirfsp, * * NT_STATUS_OBJECT_NAME_NOT_FOUND is the simple * ENOENT case. + * + * NT_STATUS_STOPPED_ON_SYMLINK is returned when trying + * to open a symlink, our callers are not interested in + * this. */ status = NT_STATUS_OBJECT_NAME_NOT_FOUND; } diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index bf2a13a2aac..194905e8c63 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -3468,9 +3468,13 @@ NTSTATUS unlink_internals(connection_struct *conn, } status = openat_pathref_fsp(conn->cwd_fsp, f); - if (!NT_STATUS_IS_OK(status) && - !NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) + if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) && + (f->flags & SMB_FILENAME_POSIX_PATH) && + S_ISLNK(f->st.st_ex_mode)) { + status = NT_STATUS_OK; + } + if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(dir_hnd); TALLOC_FREE(frame); TALLOC_FREE(talloced); diff --git a/source3/smbd/smb2_close.c b/source3/smbd/smb2_close.c index 03c60156370..da2a8fa59c8 100644 --- a/source3/smbd/smb2_close.c +++ b/source3/smbd/smb2_close.c @@ -167,7 +167,10 @@ static void setup_close_full_information(connection_struct *conn, int ret; status = openat_pathref_fsp(conn->cwd_fsp, smb_fname); - if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) { + if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) && + (smb_fname->flags & SMB_FILENAME_POSIX_PATH) && + S_ISLNK(smb_fname->st.st_ex_mode)) + { status = NT_STATUS_OK; } if (!NT_STATUS_IS_OK(status)) { -- 2.31.1 From 1f53f8a1881c3410f4f286b90ab5fab75793b007 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Tue, 2 Feb 2021 15:54:02 +0100 Subject: [PATCH 12/21] net: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from openat_pathref_fsp() BUG: https://bugzilla.samba.org/show_bug.cgi?id=14730 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison (cherry picked from commit 6e7142ba6c79c9c6f3ce299b6c7dd476cc229e6b) --- source3/utils/net_vfs.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/source3/utils/net_vfs.c b/source3/utils/net_vfs.c index 62be0a44ca2..73eda3e5cda 100644 --- a/source3/utils/net_vfs.c +++ b/source3/utils/net_vfs.c @@ -243,9 +243,6 @@ static int net_vfs_get_ntacl(struct net_context *net, } status = openat_pathref_fsp(state.conn_tos->conn->cwd_fsp, smb_fname); - if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) { - status = NT_STATUS_OBJECT_NAME_NOT_FOUND; - } if (!NT_STATUS_IS_OK(status)) { DBG_ERR("openat_pathref_fsp [%s] failed: %s\n", smb_fname_str_dbg(smb_fname), nt_errstr(status)); -- 2.31.1 From 2e458867c7029cf1734b1df5e8cde4d509b799eb Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Tue, 2 Feb 2021 15:54:43 +0100 Subject: [PATCH 13/21] smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from get_file_handle_for_metadata() BUG: https://bugzilla.samba.org/show_bug.cgi?id=14730 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison (cherry picked from commit 0d454f34db52d2903c830e1f1acd56a9a1dca04b) --- source3/smbd/dosmode.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index ccfeaca124d..ea225a9b1ef 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -1378,9 +1378,6 @@ static NTSTATUS get_file_handle_for_metadata(connection_struct *conn, } status = openat_pathref_fsp(conn->cwd_fsp, smb_fname_cp); - if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) { - status = NT_STATUS_OBJECT_NAME_NOT_FOUND; - } if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(smb_fname_cp); return status; -- 2.31.1 From e60353acd468f3f274f2907b734fbbaa9b0b06ed Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Tue, 2 Feb 2021 15:56:44 +0100 Subject: [PATCH 14/21] smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from open_streams_for_delete() BUG: https://bugzilla.samba.org/show_bug.cgi?id=14730 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison (cherry picked from commit f121374514ed6957b9c6d022a17cc4e5c8aea9a6) --- source3/smbd/open.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 172bc2e2f1f..dd58e4f6071 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -4997,9 +4997,6 @@ static NTSTATUS open_streams_for_delete(connection_struct *conn, } status = openat_pathref_fsp(conn->cwd_fsp, smb_fname_cp); - if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) { - status = NT_STATUS_OBJECT_NAME_NOT_FOUND; - } if (!NT_STATUS_IS_OK(status)) { DBG_DEBUG("Unable to open stream [%s]: %s\n", smb_fname_str_dbg(smb_fname_cp), -- 2.31.1 From d14aa38b9fd55553dffa2cfdd083d18b2f1cf4b3 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Tue, 2 Feb 2021 15:57:09 +0100 Subject: [PATCH 15/21] smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from create_file_unixpath() BUG: https://bugzilla.samba.org/show_bug.cgi?id=14730 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison (cherry picked from commit 300d851a89248ac9b220fbac55cd5daaebb7fbca) --- source3/smbd/open.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/source3/smbd/open.c b/source3/smbd/open.c index dd58e4f6071..fbaa951d430 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -5748,11 +5748,6 @@ static NTSTATUS create_file_unixpath(connection_struct *conn, if (ret == 0) { status = openat_pathref_fsp(conn->cwd_fsp, smb_fname_base); - if (NT_STATUS_EQUAL(status, - NT_STATUS_STOPPED_ON_SYMLINK)) - { - status = NT_STATUS_OBJECT_NAME_NOT_FOUND; - } if (!NT_STATUS_IS_OK(status)) { DBG_ERR("open_smb_fname_fsp [%s] failed: %s\n", smb_fname_str_dbg(smb_fname_base), -- 2.31.1 From aafe2995a8e81fdc1bd9646981a5471a4d0292ef Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Tue, 2 Feb 2021 15:57:26 +0100 Subject: [PATCH 16/21] smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from reply_search() BUG: https://bugzilla.samba.org/show_bug.cgi?id=14730 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison (cherry picked from commit 6c2dad2aaef5eab75f3fe14219e9eca6724d6c99) --- source3/smbd/reply.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 194905e8c63..ccc675cf4f3 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -1834,9 +1834,6 @@ void reply_search(struct smb_request *req) } nt_status = openat_pathref_fsp(conn->cwd_fsp, smb_dname); - if (NT_STATUS_EQUAL(nt_status, NT_STATUS_STOPPED_ON_SYMLINK)) { - nt_status = NT_STATUS_OBJECT_NAME_NOT_FOUND; - } if (!NT_STATUS_IS_OK(nt_status)) { reply_nterror(req, nt_status); goto out; -- 2.31.1 From d6cfd5c11ce6d990c30ee49f42c41113e87c315d Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Tue, 2 Feb 2021 15:58:30 +0100 Subject: [PATCH 17/21] smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from rename_internals() BUG: https://bugzilla.samba.org/show_bug.cgi?id=14730 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison (cherry picked from commit f21eb28cb8737d3125e4c0c65545f93dd7ea863f) --- source3/smbd/reply.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index ccc675cf4f3..3969ed6dabf 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -8045,9 +8045,6 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx, } status = openat_pathref_fsp(conn->cwd_fsp, smb_fname_src); - if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) { - status = NT_STATUS_OBJECT_NAME_NOT_FOUND; - } if (!NT_STATUS_IS_OK(status)) { goto out; } -- 2.31.1 From bdd1030feb765cb0f75fc86c639e0eccaef65888 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Tue, 2 Feb 2021 15:58:42 +0100 Subject: [PATCH 18/21] smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from rename_internals() BUG: https://bugzilla.samba.org/show_bug.cgi?id=14730 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison (cherry picked from commit 8999c7d69c6312c7e7bef93417ecef93ddbdabf5) --- source3/smbd/reply.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 3969ed6dabf..d2a5fa6f6dc 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -8210,9 +8210,6 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx, vfs_stat(conn, smb_fname_src); status = openat_pathref_fsp(conn->cwd_fsp, smb_fname_src); - if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) { - status = NT_STATUS_OBJECT_NAME_NOT_FOUND; - } if (!NT_STATUS_IS_OK(status)) { DBG_INFO("openat_pathref_fsp [%s] failed: %s\n", smb_fname_str_dbg(smb_fname_src), -- 2.31.1 From f8985c701749348be5e25bd9d6cecbacdd1948a2 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Tue, 2 Feb 2021 15:58:57 +0100 Subject: [PATCH 19/21] smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from copy_file() BUG: https://bugzilla.samba.org/show_bug.cgi?id=14730 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison (cherry picked from commit 544767f72df366baf50be6d841e36dbcbe9f4065) --- source3/smbd/reply.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index d2a5fa6f6dc..7bfa3192404 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -8519,9 +8519,6 @@ NTSTATUS copy_file(TALLOC_CTX *ctx, } status = openat_pathref_fsp(conn->cwd_fsp, smb_fname_src); - if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) { - status = NT_STATUS_OBJECT_NAME_NOT_FOUND; - } if (!NT_STATUS_IS_OK(status)) { goto out; } -- 2.31.1 From bb74cd8eab6c7fc620dab272e4e2a725890c47ce Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Tue, 2 Feb 2021 16:00:32 +0100 Subject: [PATCH 20/21] smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from copy_file() BUG: https://bugzilla.samba.org/show_bug.cgi?id=14730 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison (cherry picked from commit 5898f5769e0b126cca33ba0002f1e4c3eb80d21a) --- source3/smbd/reply.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 7bfa3192404..f33326564f7 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -8568,10 +8568,6 @@ NTSTATUS copy_file(TALLOC_CTX *ctx, } status = openat_pathref_fsp(conn->cwd_fsp, smb_fname_dst); - if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) { - status = NT_STATUS_OBJECT_NAME_NOT_FOUND; - goto out; - } if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { -- 2.31.1 From 5999b90608184bed375cc8de45799b8b119d306c Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Tue, 2 Feb 2021 16:01:19 +0100 Subject: [PATCH 21/21] smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from call_trans2findfirst() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=14730 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison Autobuild-User(master): Ralph Böhme Autobuild-Date(master): Fri Feb 5 07:26:44 UTC 2021 on sn-devel-184 (cherry picked from commit 1b3d70e9ae95892a70bd0f46ae5bf733c1bc9548) --- source3/smbd/trans2.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 7196b0fcc72..fac45df586e 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -2963,9 +2963,6 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd } ntstatus = openat_pathref_fsp(conn->cwd_fsp, smb_dname); - if (NT_STATUS_EQUAL(ntstatus, NT_STATUS_STOPPED_ON_SYMLINK)) { - ntstatus = NT_STATUS_OBJECT_NAME_NOT_FOUND; - } if (!NT_STATUS_IS_OK(ntstatus)) { reply_nterror(req, ntstatus); goto out; -- 2.31.1