From: Volker Lendecke Date: Wed, 17 Sep 2025 13:46:51 +0000 (-0700) Subject: smbd: Pass fsp instead of filename for parent to file_set_dosmode X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=97b6efc398b863316ec9ee704a94a9dad4409c4d;p=thirdparty%2Fsamba.git smbd: Pass fsp instead of filename for parent to file_set_dosmode Avoids a call to PARENT_PATHNAME in copy_internals() Signed-off-by: Volker Lendecke Reviewed-by: Ralph Boehme --- diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 331eac83ab8..3eed2bd362a 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -924,7 +924,7 @@ NTSTATUS dos_mode_at_recv(struct tevent_req *req, uint32_t *dosmode) int file_set_dosmode(connection_struct *conn, struct smb_filename *smb_fname, uint32_t dosmode, - struct smb_filename *parent_dir, + struct files_struct *dirfsp, bool newfile) { int mask=0; @@ -995,11 +995,7 @@ int file_set_dosmode(connection_struct *conn, } /* Fall back to UNIX modes. */ - unixmode = unix_mode( - conn, - dosmode, - smb_fname, - parent_dir != NULL ? parent_dir->fsp : NULL); + unixmode = unix_mode(conn, dosmode, smb_fname, dirfsp); /* preserve the file type bits */ mask |= S_IFMT; diff --git a/source3/smbd/open.c b/source3/smbd/open.c index a26cf653612..e62206c71e6 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -3538,7 +3538,7 @@ static void possibly_set_archive(struct connection_struct *conn, ret = file_set_dosmode(conn, smb_fname, dosattrs | FILE_ATTRIBUTE_ARCHIVE, - parent_dir_fname, + parent_dir_fname->fsp, true); if (ret != 0) { return; @@ -4664,7 +4664,7 @@ mkdir_first: file_set_dosmode(conn, smb_dname, file_attributes | FILE_ATTRIBUTE_DIRECTORY, - parent_dir_fname, + parent_dir_fname->fsp, true); } diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h index 3529274c833..853eb0e00b1 100644 --- a/source3/smbd/proto.h +++ b/source3/smbd/proto.h @@ -221,7 +221,7 @@ NTSTATUS dos_mode_at_recv(struct tevent_req *req, uint32_t *dosmode); int file_set_dosmode(connection_struct *conn, struct smb_filename *smb_fname, uint32_t dosmode, - struct smb_filename *parent_dir, + struct files_struct *dirfsp, bool newfile); NTSTATUS file_set_sparse(connection_struct *conn, struct files_struct *fsp, diff --git a/source3/smbd/smb2_nttrans.c b/source3/smbd/smb2_nttrans.c index 17eeb93fa36..32ec5a9b5c8 100644 --- a/source3/smbd/smb2_nttrans.c +++ b/source3/smbd/smb2_nttrans.c @@ -286,7 +286,6 @@ NTSTATUS copy_internals(TALLOC_CTX *ctx, int info; off_t ret=-1; NTSTATUS status = NT_STATUS_OK; - struct smb_filename *parent = NULL; if (!CAN_WRITE(conn)) { status = NT_STATUS_MEDIA_WRITE_PROTECTED; @@ -404,18 +403,10 @@ NTSTATUS copy_internals(TALLOC_CTX *ctx, creates the file. This isn't the correct thing to do in the copy case. JRA */ - status = SMB_VFS_PARENT_PATHNAME(conn, - talloc_tos(), - smb_fname_dst, - &parent, - NULL); - if (!NT_STATUS_IS_OK(status)) { - goto out; - } if (smb_fname_dst->fsp == NULL) { struct smb_filename *pathref = NULL; - status = synthetic_pathref(parent, + status = synthetic_pathref(ctx, conn->cwd_fsp, smb_fname_dst->base_name, smb_fname_dst->stream_name, @@ -426,16 +417,15 @@ NTSTATUS copy_internals(TALLOC_CTX *ctx, /* should we handle NT_STATUS_OBJECT_NAME_NOT_FOUND specially here ???? */ if (!NT_STATUS_IS_OK(status)) { - TALLOC_FREE(parent); goto out; } - file_set_dosmode(conn, pathref, fattr, parent, false); + file_set_dosmode(conn, pathref, fattr, dst_dirfsp, false); smb_fname_dst->st.st_ex_mode = pathref->st.st_ex_mode; TALLOC_FREE(pathref); } else { - file_set_dosmode(conn, smb_fname_dst, fattr, parent, false); + file_set_dosmode( + conn, smb_fname_dst, fattr, dst_dirfsp, false); } - TALLOC_FREE(parent); if (ret < (off_t)smb_fname_src->st.st_ex_size) { status = NT_STATUS_DISK_FULL;