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:
parent
be6cc4cc23
commit
f60ca2e2f3
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user