From: Volker Lendecke Date: Wed, 10 Sep 2025 16:12:22 +0000 (+0200) Subject: smbd: Change open_rootdir_pathref_fsp() to return a smb_filename X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fccdc1be9933f7768b7ded582970d3c26350cf29;p=thirdparty%2Fsamba.git smbd: Change open_rootdir_pathref_fsp() to return a smb_filename Simpler and safer to close in the caller, and openat_pathref_fsp_rootdir() can use openat_pathref_fsp_simple_openat(). De-duplicate some logic. Signed-off-by: Volker Lendecke Reviewed-by: Ralph Boehme --- diff --git a/source3/modules/vfs_fake_acls.c b/source3/modules/vfs_fake_acls.c index 9c12af42d50..79328da74d9 100644 --- a/source3/modules/vfs_fake_acls.c +++ b/source3/modules/vfs_fake_acls.c @@ -100,7 +100,7 @@ static int fake_acls_fstatat(struct vfs_handle_struct *handle, connection_struct *conn = handle->conn; int ret = -1; struct in_pathref_data *prd = NULL; - struct files_struct *root_fsp = NULL; + struct smb_filename *rootdir = NULL; struct files_struct *new_dirfsp = NULL; struct smb_filename *smb_fname = NULL; struct smb_filename *new_relname = NULL; @@ -150,13 +150,15 @@ static int fake_acls_fstatat(struct vfs_handle_struct *handle, * paths, make this relative to "/" */ base_name += 1; - status = open_rootdir_pathref_fsp(conn, &root_fsp); + status = openat_pathref_fsp_rootdir(talloc_tos(), + conn, + &rootdir); if (!NT_STATUS_IS_OK(status)) { prd->calling_pathref_fsp = false; errno = ENOENT; return -1; } - dirfsp = root_fsp; + dirfsp = rootdir->fsp; } if (ISDOT(base_name)) { @@ -212,11 +214,7 @@ static int fake_acls_fstatat(struct vfs_handle_struct *handle, &sbuf->st_ex_uid, &sbuf->st_ex_gid); - if (root_fsp != NULL) { - fd_close(root_fsp); - file_free(NULL, root_fsp); - root_fsp = NULL; - } + TALLOC_FREE(rootdir); fd_close(new_dirfsp); file_free(NULL, new_dirfsp); new_dirfsp = NULL; diff --git a/source3/smbd/files.c b/source3/smbd/files.c index 178a8f96c5d..33366102774 100644 --- a/source3/smbd/files.c +++ b/source3/smbd/files.c @@ -694,61 +694,21 @@ static NTSTATUS openat_pathref_fsp_simple_openat(TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } -NTSTATUS open_rootdir_pathref_fsp(connection_struct *conn, - struct files_struct **_fsp) +NTSTATUS openat_pathref_fsp_rootdir(TALLOC_CTX *mem_ctx, + struct connection_struct *conn, + struct smb_filename **_root) { - struct smb_filename slash = { .base_name = discard_const_p(char, "/") }; - struct vfs_open_how how = { .flags = O_RDONLY|O_DIRECTORY, }; - struct files_struct *fsp = NULL; + struct smb_filename *root = NULL; NTSTATUS status; - int fd; - bool ok; - - fsp = fsp_new(conn, conn); - if (fsp == NULL) { - return NT_STATUS_NO_MEMORY; - } - GetTimeOfDay(&fsp->open_time); - ZERO_STRUCT(conn->sconn->fsp_fi_cache); - fsp->fsp_flags.is_pathref = true; - - ok = fsp_set_smb_fname(fsp, &slash); - if (!ok) { - status = NT_STATUS_NO_MEMORY; - goto fail; - } - - fd = SMB_VFS_OPENAT(conn, - conn->cwd_fsp, - fsp->fsp_name, - fsp, - &how); - if (fd == -1) { - status = map_nt_error_from_unix(errno); - goto fail; - } - fsp_set_fd(fsp, fd); - status = vfs_stat_fsp(fsp); + status = openat_pathref_fsp_simple_openat( + mem_ctx, conn->cwd_fsp, "/", 0, &root); if (!NT_STATUS_IS_OK(status)) { - DBG_DEBUG("vfs_stat_fsp(\"/\") failed: %s\n", nt_errstr(status)); - goto close_fail; - } - fsp->fsp_flags.is_directory = S_ISDIR(fsp->fsp_name->st.st_ex_mode); - if (!fsp->fsp_flags.is_directory) { - DBG_DEBUG("\"/\" not a directory\n"); - status = NT_STATUS_UNEXPECTED_IO_ERROR; - goto close_fail; + return status; } - fsp->file_id = vfs_file_id_from_sbuf(conn, &fsp->fsp_name->st); - *_fsp = fsp; - return NT_STATUS_OK; -close_fail: - fd_close(fsp); -fail: - file_free(NULL, fsp); - return status; + *_root = root; + return NT_STATUS_OK; } /* diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 26d305a97e9..5294d0c9c9d 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -475,7 +475,7 @@ NTSTATUS fd_openat(const struct files_struct *dirfsp, struct files_struct *dirfsp_conv = NULL; struct smb_filename *smb_fname_conv = NULL; struct smb_filename *smb_fname_rel = NULL; - struct files_struct *root_fsp = NULL; + struct smb_filename *rootdir = NULL; const char *name_in = smb_fname->base_name; int fd; @@ -532,11 +532,13 @@ NTSTATUS fd_openat(const struct files_struct *dirfsp, * paths, make this relative to "/" */ name_in += 1; - status = open_rootdir_pathref_fsp(conn, &root_fsp); + status = openat_pathref_fsp_rootdir(talloc_tos(), + conn, + &rootdir); if (!NT_STATUS_IS_OK(status)) { return status; } - dirfsp = root_fsp; + dirfsp = rootdir->fsp; } if (ISDOT(name_in)) { @@ -558,11 +560,7 @@ NTSTATUS fd_openat(const struct files_struct *dirfsp, &smb_fname_rel); dirfsp = NULL; - if (root_fsp != NULL) { - fd_close(root_fsp); - file_free(NULL, root_fsp); - root_fsp = NULL; - } + TALLOC_FREE(rootdir); if (!NT_STATUS_IS_OK(status)) { DBG_DEBUG("filename_convert_dirfsp_rel returned %s\n", diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h index 6a7a524cfc5..34dcd964e9f 100644 --- a/source3/smbd/proto.h +++ b/source3/smbd/proto.h @@ -370,8 +370,9 @@ NTSTATUS open_internal_dirfsp(connection_struct *conn, int open_flags, struct files_struct **_fsp); -NTSTATUS open_rootdir_pathref_fsp(connection_struct *conn, - struct files_struct **_fsp); +NTSTATUS openat_pathref_fsp_rootdir(TALLOC_CTX *mem_ctx, + struct connection_struct *conn, + struct smb_filename **_root); NTSTATUS openat_pathref_fsp(const struct files_struct *dirfsp, struct smb_filename *smb_fname); NTSTATUS open_stream_pathref_fsp(