The branch, master has been updated via 1b3d70e9ae9 smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from call_trans2findfirst() via 5898f5769e0 smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from copy_file() via 544767f72df smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from copy_file() via 8999c7d69c6 smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from rename_internals() via f21eb28cb87 smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from rename_internals() via 6c2dad2aaef smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from reply_search() via 300d851a892 smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from create_file_unixpath() via f121374514e smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from open_streams_for_delete() via fb82fac0f55 smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from parent_pathref() via 5479f76e174 smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from synthetic_pathref() via 0d454f34db5 smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from get_file_handle_for_metadata() via 6e7142ba6c7 net: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from openat_pathref_fsp() via 977f37643b2 smbd: don't return NT_STATUS_STOPPED_ON_SYMLINK in openat_pathref_fsp() via cd3d970c84b smbd: simplify error codepath in openat_pathref_fsp() via 48bc561d1a8 smbd: expect valid stat info in openat_pathref_fsp() via 87e97e1b519 smbd: stat path before calling openat_pathref_fsp() in smbd_dirptr_get_entry() via b3a0d6a1289 smbd: move smb_fname creation to earlier point in smbd_dirptr_get_entry() via c31fe2f9e7d smbd: stat path before calling openat_pathref_fsp() in open_pathref_base_fsp() via 91edc50dc0a smbd: remove a redundant fstat()in create_file_unixpath() via aa0ef26d1e9 smbd: call stat before openat_pathref_fsp() in create_file_unixpath() via e636e20f90d smbd: fix a resource leak in create_file_unixpath() via ab82dbc5ae4 smbd: stat path before calling openat_pathref_fsp() in unlink_internals() via 4f30c04462f s3/libadouble: stat path before calling openat_pathref_fsp() in ad_unconvert_open_ad() via d78964c40b5 smbd: don't overwrite _mode if neither a msdfs symlink nor get_dosmode is requested via 5572ae296e7 CI: verify a symlink has FILE_ATTRIBUTE_NORMAL set from 0bdbe50fac6 lib:util: Avoid free'ing our own pointer
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 1b3d70e9ae95892a70bd0f46ae5bf733c1bc9548 Author: Ralph Boehme <s...@samba.org> Date: Tue Feb 2 16:01:19 2021 +0100 smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from call_trans2findfirst() Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> Autobuild-User(master): Ralph Böhme <s...@samba.org> Autobuild-Date(master): Fri Feb 5 07:26:44 UTC 2021 on sn-devel-184 commit 5898f5769e0b126cca33ba0002f1e4c3eb80d21a Author: Ralph Boehme <s...@samba.org> Date: Tue Feb 2 16:00:32 2021 +0100 smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from copy_file() Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 544767f72df366baf50be6d841e36dbcbe9f4065 Author: Ralph Boehme <s...@samba.org> Date: Tue Feb 2 15:58:57 2021 +0100 smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from copy_file() Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 8999c7d69c6312c7e7bef93417ecef93ddbdabf5 Author: Ralph Boehme <s...@samba.org> Date: Tue Feb 2 15:58:42 2021 +0100 smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from rename_internals() Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit f21eb28cb8737d3125e4c0c65545f93dd7ea863f Author: Ralph Boehme <s...@samba.org> Date: Tue Feb 2 15:58:30 2021 +0100 smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from rename_internals() Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 6c2dad2aaef5eab75f3fe14219e9eca6724d6c99 Author: Ralph Boehme <s...@samba.org> Date: Tue Feb 2 15:57:26 2021 +0100 smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from reply_search() Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 300d851a89248ac9b220fbac55cd5daaebb7fbca Author: Ralph Boehme <s...@samba.org> Date: Tue Feb 2 15:57:09 2021 +0100 smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from create_file_unixpath() Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit f121374514ed6957b9c6d022a17cc4e5c8aea9a6 Author: Ralph Boehme <s...@samba.org> Date: Tue Feb 2 15:56:44 2021 +0100 smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from open_streams_for_delete() Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit fb82fac0f554ad140e0b0fd7efac84a7c3dfa2e2 Author: Ralph Boehme <s...@samba.org> Date: Tue Feb 2 15:56:26 2021 +0100 smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from parent_pathref() Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 5479f76e174cf7454da2bad3f903070a8de84043 Author: Ralph Boehme <s...@samba.org> Date: Tue Feb 2 15:56:16 2021 +0100 smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from synthetic_pathref() Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 0d454f34db52d2903c830e1f1acd56a9a1dca04b Author: Ralph Boehme <s...@samba.org> Date: Tue Feb 2 15:54:43 2021 +0100 smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from get_file_handle_for_metadata() Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 6e7142ba6c79c9c6f3ce299b6c7dd476cc229e6b Author: Ralph Boehme <s...@samba.org> Date: Tue Feb 2 15:54:02 2021 +0100 net: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from openat_pathref_fsp() Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 977f37643b223e164fbbf6c3ba1d37aa546ddb7d Author: Ralph Boehme <s...@samba.org> Date: Tue Feb 2 11:18:54 2021 +0100 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. Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit cd3d970c84b340630745bc555a86ac2d1306baac Author: Ralph Boehme <s...@samba.org> Date: Tue Feb 2 13:49:56 2021 +0100 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. Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 48bc561d1a8bb5ce99663b58a2e5e9aa344af96a Author: Ralph Boehme <s...@samba.org> Date: Mon Feb 1 10:17:13 2021 +0100 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. Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 87e97e1b519159b5f4c5ed4ef684783855e79ac3 Author: Ralph Boehme <s...@samba.org> Date: Mon Feb 1 12:09:39 2021 +0100 smbd: stat path before calling openat_pathref_fsp() in smbd_dirptr_get_entry() Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit b3a0d6a128989b593f135c425dd59351d13b6120 Author: Ralph Boehme <s...@samba.org> Date: Mon Feb 1 12:04:49 2021 +0100 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. Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit c31fe2f9e7d65409229b7ad73418793ab34d359d Author: Ralph Boehme <s...@samba.org> Date: Mon Feb 1 12:04:01 2021 +0100 smbd: stat path before calling openat_pathref_fsp() in open_pathref_base_fsp() Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 91edc50dc0aaa82d9ede7a7f8cf0f63312eb8503 Author: Ralph Boehme <s...@samba.org> Date: Mon Feb 1 12:03:08 2021 +0100 smbd: remove a redundant fstat()in create_file_unixpath() openat_pathref_fsp() deep inside already calls fstat(). Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit aa0ef26d1e9dcef0bcb47974d7cf60db922d7d08 Author: Ralph Boehme <s...@samba.org> Date: Mon Feb 1 12:01:22 2021 +0100 smbd: call stat before openat_pathref_fsp() in create_file_unixpath() Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit e636e20f90d4ee221ce6e20cab15a3cecb03850f Author: Ralph Boehme <s...@samba.org> Date: Mon Feb 1 12:01:01 2021 +0100 smbd: fix a resource leak in create_file_unixpath() Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit ab82dbc5ae43cdb661bf49627a84926163bc8998 Author: Ralph Boehme <s...@samba.org> Date: Mon Feb 1 12:00:35 2021 +0100 smbd: stat path before calling openat_pathref_fsp() in unlink_internals() Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 4f30c04462fb1536323606dd4216fe5e32458ba5 Author: Ralph Boehme <s...@samba.org> Date: Mon Feb 1 11:59:37 2021 +0100 s3/libadouble: stat path before calling openat_pathref_fsp() in ad_unconvert_open_ad() Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit d78964c40b5ca5ee0658c46d492b3dcd6f6b4b94 Author: Ralph Boehme <s...@samba.org> Date: Mon Feb 1 12:37:10 2021 +0100 smbd: don't overwrite _mode if neither a msdfs symlink nor get_dosmode is requested BUG: https://bugzilla.samba.org/show_bug.cgi?id=14629 Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 5572ae296e720a00ab438d7b50cfc458af631f69 Author: Ralph Boehme <s...@samba.org> Date: Mon Feb 1 14:44:03 2021 +0100 CI: verify a symlink has FILE_ATTRIBUTE_NORMAL set Not that it really makes sense to set FILE_ATTRIBUTE_NORMAL for symlinks in POSIX client context, but that's what we had before 4.14. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14629 Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> ----------------------------------------------------------------------- Summary of changes: source3/lib/adouble.c | 13 +++-- source3/smbd/dir.c | 116 ++++++++++++++++++++----------------------- source3/smbd/dosmode.c | 3 -- source3/smbd/filename.c | 15 ++---- source3/smbd/files.c | 53 ++++++++------------ source3/smbd/open.c | 40 ++++++--------- source3/smbd/reply.c | 34 ++++++------- source3/smbd/smb2_close.c | 5 +- source3/smbd/trans2.c | 19 ++++--- source3/torture/test_posix.c | 14 ++++++ source3/utils/net_vfs.c | 3 -- 11 files changed, 146 insertions(+), 169 deletions(-) Changeset truncated at 500 lines: diff --git a/source3/lib/adouble.c b/source3/lib/adouble.c index 3be6f353bd8..6fd290a31b8 100644 --- a/source3/lib/adouble.c +++ b/source3/lib/adouble.c @@ -1505,13 +1505,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 */ diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index f70bc6cc56d..9d5244e3c4e 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -798,6 +798,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; @@ -865,17 +866,60 @@ 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; + } + + 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) { TALLOC_FREE(dname); TALLOC_FREE(fname); - TALLOC_FREE(pathreal); + TALLOC_FREE(smb_fname); return false; } @@ -892,72 +936,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(pathreal); + 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(pathreal); - 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(pathreal); - 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; - } - - /* - * 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); @@ -969,7 +966,6 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx, TALLOC_FREE(smb_fname); TALLOC_FREE(dname); TALLOC_FREE(fname); - TALLOC_FREE(pathreal); continue; } @@ -978,7 +974,6 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx, TALLOC_FREE(smb_fname); TALLOC_FREE(dname); TALLOC_FREE(fname); - TALLOC_FREE(pathreal); continue; } @@ -997,7 +992,6 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx, TALLOC_FREE(smb_fname); TALLOC_FREE(dname); TALLOC_FREE(fname); - TALLOC_FREE(pathreal); continue; } @@ -1007,7 +1001,6 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx, TALLOC_FREE(smb_fname); TALLOC_FREE(dname); TALLOC_FREE(fname); - TALLOC_FREE(pathreal); continue; } @@ -1042,7 +1035,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; } 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; 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 448a284780b..3254d728ad6 100644 --- a/source3/smbd/files.c +++ b/source3/smbd/files.c @@ -392,6 +392,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, @@ -403,6 +404,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); @@ -432,7 +438,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; @@ -446,8 +451,12 @@ NTSTATUS openat_pathref_fsp(const struct files_struct *dirfsp, return NT_STATUS_OK; } - if (file_existed && S_ISLNK(smb_fname->st.st_ex_mode)) { - return NT_STATUS_STOPPED_ON_SYMLINK; + 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_OBJECT_NAME_NOT_FOUND; } status = fsp_new(conn, conn, &fsp); @@ -493,23 +502,9 @@ 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)) + 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 @@ -521,19 +516,17 @@ 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; } - if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { - goto fail; - } - - return NT_STATUS_OBJECT_NAME_NOT_FOUND; + goto fail; } - 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", @@ -660,9 +653,6 @@ NTSTATUS synthetic_pathref(TALLOC_CTX *mem_ctx, } status = openat_pathref_fsp(dirfsp, 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("opening [%s] failed\n", smb_fname_str_dbg(smb_fname)); @@ -715,9 +705,6 @@ NTSTATUS parent_pathref(TALLOC_CTX *mem_ctx, } status = openat_pathref_fsp(dirfsp, parent); - 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(parent); return status; diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 721a48f3b5a..92b0a507760 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -4978,9 +4978,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), @@ -5568,6 +5565,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, " @@ -5715,37 +5713,28 @@ 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; - - 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)); + if (ret == 0) { + status = openat_pathref_fsp(conn->cwd_fsp, + smb_fname_base); + 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; } /* @@ -5764,6 +5753,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; } } diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index c418f39cf3b..45a2a298f65 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; @@ -3281,6 +3278,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,10 +3455,23 @@ NTSTATUS unlink_internals(connection_struct *conn, goto out; } + ret = vfs_stat(conn, f); + if (ret != 0) { -- Samba Shared Repository