diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/include/proto.h | 3 | ||||
-rw-r--r-- | source3/modules/onefs_acl.c | 15 | ||||
-rw-r--r-- | source3/modules/onefs_open.c | 6 | ||||
-rw-r--r-- | source3/smbd/dosmode.c | 40 | ||||
-rw-r--r-- | source3/smbd/open.c | 6 | ||||
-rw-r--r-- | source3/smbd/posix_acls.c | 21 |
6 files changed, 67 insertions, 24 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h index f835da2ab8..ef252c2846 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -6234,7 +6234,8 @@ bool smbd_setup_mdns_registration(struct tevent_context *ev, /* The following definitions come from smbd/dosmode.c */ -mode_t unix_mode(connection_struct *conn, int dosmode, const char *fname, +mode_t unix_mode(connection_struct *conn, int dosmode, + const struct smb_filename *smb_fname, const char *inherit_from_dir); uint32 dos_mode_msdfs(connection_struct *conn, const char *path, const SMB_STRUCT_STAT *sbuf); int dos_attributes_to_stat_dos_flags(uint32_t dosmode); diff --git a/source3/modules/onefs_acl.c b/source3/modules/onefs_acl.c index 81bdfd26cc..5c72d10a6b 100644 --- a/source3/modules/onefs_acl.c +++ b/source3/modules/onefs_acl.c @@ -542,14 +542,25 @@ static bool add_sfs_aces(files_struct *fsp, struct ifs_security_descriptor *sd) /* Only continue if this is a synthetic ACL and a directory. */ if (S_ISDIR(sbuf.st_ex_mode) && (sbuf.st_ex_flags & SF_HASNTFSACL) == 0) { + struct smb_filename *smb_fname = NULL; struct ifs_ace new_aces[6]; struct ifs_ace *old_aces; int i, num_aces_to_add = 0; mode_t file_mode = 0, dir_mode = 0; + NTSTATUS status; + + status = create_synthetic_smb_fname_split(talloc_tos(), + fsp->fsp_name, NULL, + &smb_fname); + if (!NT_STATUS_IS_OK(status)) { + return false; + } /* Use existing samba logic to derive the mode bits. */ - file_mode = unix_mode(fsp->conn, 0, fsp->fsp_name, false); - dir_mode = unix_mode(fsp->conn, aDIR, fsp->fsp_name, false); + file_mode = unix_mode(fsp->conn, 0, smb_fname, NULL); + dir_mode = unix_mode(fsp->conn, aDIR, smb_fname, NULL); + + TALLOC_FREE(smb_fname); /* Initialize ACEs. */ new_aces[0] = onefs_init_ace(fsp->conn, file_mode, false, USR); diff --git a/source3/modules/onefs_open.c b/source3/modules/onefs_open.c index da7d413073..20ce814518 100644 --- a/source3/modules/onefs_open.c +++ b/source3/modules/onefs_open.c @@ -504,8 +504,8 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn, } else { /* We add aARCH to this as this mode is only used if the file is * created new. */ - unx_mode = unix_mode(conn, new_dos_attributes | aARCH, fname, - parent_dir); + unx_mode = unix_mode(conn, new_dos_attributes | aARCH, + smb_fname, parent_dir); } DEBUG(10,("onefs_open_file_ntcreate: fname=%s, dos_attrs=0x%x " @@ -1444,7 +1444,7 @@ static NTSTATUS onefs_open_directory(connection_struct *conn, mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS); file_attributes = 0; } else { - mode = unix_mode(conn, aDIR, smb_dname->base_name, parent_dir); + mode = unix_mode(conn, aDIR, smb_dname, parent_dir); } /* diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 9d44eeec7d..9bd097c0bb 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -64,7 +64,8 @@ static int set_link_read_only_flag(const SMB_STRUCT_STAT *const sbuf) } ****************************************************************************/ -mode_t unix_mode(connection_struct *conn, int dosmode, const char *fname, +mode_t unix_mode(connection_struct *conn, int dosmode, + const struct smb_filename *smb_fname, const char *inherit_from_dir) { mode_t result = (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH); @@ -75,23 +76,39 @@ mode_t unix_mode(connection_struct *conn, int dosmode, const char *fname, result &= ~(S_IWUSR | S_IWGRP | S_IWOTH); } - if (fname && (inherit_from_dir != NULL) - && lp_inherit_perms(SNUM(conn))) { - SMB_STRUCT_STAT sbuf; + if ((inherit_from_dir != NULL) && lp_inherit_perms(SNUM(conn))) { + struct smb_filename *smb_fname_parent = NULL; + NTSTATUS status; - DEBUG(2, ("unix_mode(%s) inheriting from %s\n", fname, + DEBUG(2, ("unix_mode(%s) inheriting from %s\n", + smb_fname_str_dbg(smb_fname), inherit_from_dir)); - if (vfs_stat_smb_fname(conn, inherit_from_dir, &sbuf) != 0) { - DEBUG(4,("unix_mode(%s) failed, [dir %s]: %s\n", fname, + + status = create_synthetic_smb_fname(talloc_tos(), + inherit_from_dir, NULL, + NULL, &smb_fname_parent); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1,("unix_mode(%s) failed, [dir %s]: %s\n", + smb_fname_str_dbg(smb_fname), + inherit_from_dir, nt_errstr(status))); + return(0); + } + + if (SMB_VFS_STAT(conn, smb_fname_parent) != 0) { + DEBUG(4,("unix_mode(%s) failed, [dir %s]: %s\n", + smb_fname_str_dbg(smb_fname), inherit_from_dir, strerror(errno))); + TALLOC_FREE(smb_fname_parent); return(0); /* *** shouldn't happen! *** */ } /* Save for later - but explicitly remove setuid bit for safety. */ - dir_mode = sbuf.st_ex_mode & ~S_ISUID; - DEBUG(2,("unix_mode(%s) inherit mode %o\n",fname,(int)dir_mode)); + dir_mode = smb_fname_parent->st.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" */ result = 0; + TALLOC_FREE(smb_fname_parent); } if (IS_DOS_DIR(dosmode)) { @@ -132,7 +149,8 @@ mode_t unix_mode(connection_struct *conn, int dosmode, const char *fname, } } - DEBUG(3,("unix_mode(%s) returning 0%o\n",fname,(int)result )); + DEBUG(3,("unix_mode(%s) returning 0%o\n", smb_fname_str_dbg(smb_fname), + (int)result)); return(result); } @@ -635,7 +653,7 @@ int file_set_dosmode(connection_struct *conn, struct smb_filename *smb_fname, return 0; } - unixmode = unix_mode(conn,dosmode,fname, parent_dir); + unixmode = unix_mode(conn, dosmode, smb_fname, parent_dir); /* preserve the s bits */ mask |= (S_ISUID | S_ISGID); diff --git a/source3/smbd/open.c b/source3/smbd/open.c index e93485b3d8..a58cffa257 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -1513,8 +1513,8 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn, } else { /* We add aARCH to this as this mode is only used if the file is * created new. */ - unx_mode = unix_mode(conn, new_dos_attributes | aARCH, fname, - parent_dir); + unx_mode = unix_mode(conn, new_dos_attributes | aARCH, + smb_fname, parent_dir); } DEBUG(10, ("open_file_ntcreate: fname=%s, dos_attrs=0x%x " @@ -2362,7 +2362,7 @@ static NTSTATUS mkdir_internal(connection_struct *conn, posix_open = true; mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS); } else { - mode = unix_mode(conn, aDIR, smb_dname->base_name, parent_dir); + mode = unix_mode(conn, aDIR, smb_dname, parent_dir); } if (SMB_VFS_MKDIR(conn, smb_dname->base_name, mode) != 0) { diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index 627ca2e171..0c7f4b7bb7 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -2166,10 +2166,23 @@ static mode_t create_default_mode(files_struct *fsp, bool interitable_mode) int snum = SNUM(fsp->conn); mode_t and_bits = (mode_t)0; mode_t or_bits = (mode_t)0; - mode_t mode = interitable_mode - ? unix_mode( fsp->conn, FILE_ATTRIBUTE_ARCHIVE, fsp->fsp_name, - NULL ) - : S_IRUSR; + mode_t mode; + + if (interitable_mode) { + struct smb_filename *smb_fname = NULL; + NTSTATUS status; + + status = create_synthetic_smb_fname_split(talloc_tos(), + fsp->fsp_name, NULL, + &smb_fname); + if (!NT_STATUS_IS_OK(status)) { + return 0; + } + mode = unix_mode(fsp->conn, FILE_ATTRIBUTE_ARCHIVE, smb_fname, + NULL); + } else { + mode = S_IRUSR; + } if (fsp->is_directory) mode |= (S_IWUSR|S_IXUSR); |