From: Volker Lendecke Date: Fri, 11 Oct 2024 12:56:21 +0000 (+0200) Subject: smbd: Add open_rootdir_pathref_fsp() X-Git-Tag: tdb-1.4.13~520 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=56e3a8e3f80533a972913ed4a0efe7c98185e57e;p=thirdparty%2Fsamba.git smbd: Add open_rootdir_pathref_fsp() Get a pathref handle on the file system root. This will serve as "basedir" for filename_convert_dirfsp_rel() to turn an absolute path into one relative to the handle created here. Signed-off-by: Volker Lendecke Reviewed-by: Ralph Boehme --- diff --git a/source3/smbd/files.c b/source3/smbd/files.c index d739de6637e..2100db5eaee 100644 --- a/source3/smbd/files.c +++ b/source3/smbd/files.c @@ -590,6 +590,62 @@ fail: return status; } +NTSTATUS open_rootdir_pathref_fsp(connection_struct *conn, + struct files_struct **_fsp) +{ + 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; + NTSTATUS status; + int fd; + + status = fsp_new(conn, conn, &fsp); + if (!NT_STATUS_IS_OK(status)) { + goto fail; + } + GetTimeOfDay(&fsp->open_time); + fsp_set_gen_id(fsp); + ZERO_STRUCT(conn->sconn->fsp_fi_cache); + fsp->fsp_flags.is_pathref = true; + + status = fsp_set_smb_fname(fsp, &slash); + if (!NT_STATUS_IS_OK(status)) { + 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); + 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; + } + 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; +} + /* * Open a stream given an already opened base_fsp. Avoid * non_widelink_open: This is only valid for the case where we have a diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h index eb584f3d1ff..4a3d8259160 100644 --- a/source3/smbd/proto.h +++ b/source3/smbd/proto.h @@ -367,6 +367,8 @@ 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(const struct files_struct *dirfsp, struct smb_filename *smb_fname); NTSTATUS open_stream_pathref_fsp(