1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-26 18:50:30 +03:00

smbd: Pass dirfsp instead of a parent filename to unix_mode

This converts a STAT (with potential symlink race problems) into an
FSTAT on the O_PATH fd we have for the directory

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
This commit is contained in:
Volker Lendecke 2022-03-03 11:52:12 +01:00 committed by Ralph Boehme
parent be6cc4cc23
commit f60ca2e2f3
3 changed files with 23 additions and 12 deletions

View File

@ -106,7 +106,7 @@ static uint32_t filter_mode_by_protocol(uint32_t mode)
mode_t unix_mode(connection_struct *conn, int dosmode,
const struct smb_filename *smb_fname,
struct smb_filename *smb_fname_parent)
struct files_struct *parent_dirfsp)
{
mode_t result = (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH);
mode_t dir_mode = 0; /* Mode of the inherit_from directory if
@ -116,20 +116,24 @@ mode_t unix_mode(connection_struct *conn, int dosmode,
result &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
}
if ((smb_fname_parent != NULL) && lp_inherit_permissions(SNUM(conn))) {
if ((parent_dirfsp != NULL) && lp_inherit_permissions(SNUM(conn))) {
struct stat_ex sbuf = { .st_ex_nlink = 0, };
int ret;
DBG_DEBUG("[%s] inheriting from [%s]\n",
smb_fname_str_dbg(smb_fname),
smb_fname_str_dbg(smb_fname_parent));
smb_fname_str_dbg(parent_dirfsp->fsp_name));
if (SMB_VFS_STAT(conn, smb_fname_parent) != 0) {
DBG_ERR("stat failed [%s]: %s\n",
smb_fname_str_dbg(smb_fname_parent),
ret = SMB_VFS_FSTAT(parent_dirfsp, &sbuf);
if (ret != 0) {
DBG_ERR("fstat failed [%s]: %s\n",
smb_fname_str_dbg(parent_dirfsp->fsp_name),
strerror(errno));
return(0); /* *** shouldn't happen! *** */
}
/* Save for later - but explicitly remove setuid bit for safety. */
dir_mode = smb_fname_parent->st.st_ex_mode & ~S_ISUID;
dir_mode = sbuf.st_ex_mode & ~S_ISUID;
DEBUG(2,("unix_mode(%s) inherit mode %o\n",
smb_fname_str_dbg(smb_fname), (int)dir_mode));
/* Clear "result" */
@ -973,7 +977,11 @@ int file_set_dosmode(connection_struct *conn,
}
/* Fall back to UNIX modes. */
unixmode = unix_mode(conn, dosmode, smb_fname, parent_dir);
unixmode = unix_mode(
conn,
dosmode,
smb_fname,
parent_dir != NULL ? parent_dir->fsp : NULL);
/* preserve the file type bits */
mask |= S_IFMT;

View File

@ -3513,8 +3513,11 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
/* We add FILE_ATTRIBUTE_ARCHIVE to this as this mode is only used if the file is
* created new. */
unx_mode = unix_mode(conn, new_dos_attributes | FILE_ATTRIBUTE_ARCHIVE,
smb_fname, parent_dir_fname);
unx_mode = unix_mode(
conn,
new_dos_attributes | FILE_ATTRIBUTE_ARCHIVE,
smb_fname,
parent_dir_fname->fsp);
}
DEBUG(10, ("open_file_ntcreate: fname=%s, dos_attrs=0x%x "
@ -4269,7 +4272,7 @@ static NTSTATUS mkdir_internal(connection_struct *conn,
mode = unix_mode(conn,
FILE_ATTRIBUTE_DIRECTORY,
smb_dname,
parent_dir_fname);
parent_dir_fname->fsp);
}
status = check_parent_access_fsp(parent_dir_fname->fsp, access_mask);

View File

@ -265,7 +265,7 @@ bool smbd_setup_mdns_registration(struct tevent_context *ev,
mode_t unix_mode(connection_struct *conn, int dosmode,
const struct smb_filename *smb_fname,
struct smb_filename *smb_fname_parent);
struct files_struct *parent_dirfsp);
uint32_t dos_mode_msdfs(connection_struct *conn,
const struct smb_filename *smb_fname);
uint32_t fdos_mode(struct files_struct *fsp);