From: Ralph Boehme Date: Fri, 30 Jul 2021 13:17:44 +0000 (+0200) Subject: smbd: avoid calling creating a pathref in smb_set_file_dosmode() X-Git-Tag: ldb-2.5.0~834 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bcd6bed7b8611654a7e9752b258541f89414b020;p=thirdparty%2Fsamba.git smbd: avoid calling creating a pathref in smb_set_file_dosmode() We already have a fsp with a valid fsp->base_fsp if it's a stream. Also remove the struct smb_filename arg, it's not needed, the only caller already checks for a valid fsp. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14771 Signed-off-by: Ralph Boehme Reviewed-by: Christof Schmitt --- diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index b9e2786eda6..a6bd232f679 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -6655,61 +6655,48 @@ NTSTATUS smb_set_file_time(connection_struct *conn, static NTSTATUS smb_set_file_dosmode(connection_struct *conn, struct files_struct *fsp, - struct smb_filename *smb_fname, uint32_t dosmode) { - struct smb_filename *smb_fname_base; - NTSTATUS status; + struct files_struct *dos_fsp = NULL; + uint32_t current_dosmode; + int ret; - if (!VALID_STAT(smb_fname->st)) { + if (!VALID_STAT(fsp->fsp_name->st)) { return NT_STATUS_OBJECT_NAME_NOT_FOUND; } - /* Always operate on the base_name, even if a stream was passed in. */ - status = synthetic_pathref(talloc_tos(), - conn->cwd_fsp, - smb_fname->base_name, - NULL, - NULL, - smb_fname->twrp, - smb_fname->flags, - &smb_fname_base); - - /* do we handle link as non error here ? */ - if (!NT_STATUS_IS_OK(status)) { - return status; - } + dos_fsp = fsp->base_fsp != NULL ? fsp->base_fsp : fsp; - if (dosmode) { - if (S_ISDIR(smb_fname_base->st.st_ex_mode)) { + if (dosmode != 0) { + if (S_ISDIR(fsp->fsp_name->st.st_ex_mode)) { dosmode |= FILE_ATTRIBUTE_DIRECTORY; } else { dosmode &= ~FILE_ATTRIBUTE_DIRECTORY; } } - DEBUG(6,("smb_set_file_dosmode: dosmode: 0x%x\n", (unsigned int)dosmode)); + DBG_DEBUG("dosmode: 0x%" PRIx32 "\n", dosmode); /* check the mode isn't different, before changing it */ - if ((dosmode != 0) && (dosmode != fdos_mode(fsp))) { - DEBUG(10,("smb_set_file_dosmode: file %s : setting dos mode " - "0x%x\n", smb_fname_str_dbg(smb_fname_base), - (unsigned int)dosmode)); - - if(file_set_dosmode(conn, smb_fname_base, dosmode, NULL, - false)) { - DEBUG(2,("smb_set_file_dosmode: file_set_dosmode of " - "%s failed (%s)\n", - smb_fname_str_dbg(smb_fname_base), - strerror(errno))); - status = map_nt_error_from_unix(errno); - goto out; - } + if (dosmode == 0) { + return NT_STATUS_OK; } - status = NT_STATUS_OK; - out: - TALLOC_FREE(smb_fname_base); - return status; + current_dosmode = fdos_mode(dos_fsp); + if (dosmode == current_dosmode) { + return NT_STATUS_OK; + } + + DBG_DEBUG("file %s : setting dos mode 0x%" PRIx32 "\n", + fsp_str_dbg(dos_fsp), dosmode); + + ret = file_set_dosmode(conn, dos_fsp->fsp_name, dosmode, NULL, false); + if (ret != 0) { + DBG_WARNING("file_set_dosmode of %s failed: %s\n", + fsp_str_dbg(dos_fsp), strerror(errno)); + return map_nt_error_from_unix(errno); + } + + return NT_STATUS_OK; } /**************************************************************************** @@ -7912,7 +7899,7 @@ static NTSTATUS smb_set_file_basic_info(connection_struct *conn, /* Set the attributes */ dosmode = IVAL(pdata,32); - status = smb_set_file_dosmode(conn, fsp, smb_fname, dosmode); + status = smb_set_file_dosmode(conn, fsp, dosmode); if (!NT_STATUS_IS_OK(status)) { return status; }