diff options
Diffstat (limited to 'source3/modules')
-rw-r--r-- | source3/modules/onefs_open.c | 4 | ||||
-rw-r--r-- | source3/modules/vfs_acl_common.c | 123 | ||||
-rw-r--r-- | source3/modules/vfs_acl_tdb.c | 8 | ||||
-rw-r--r-- | source3/modules/vfs_acl_xattr.c | 14 | ||||
-rw-r--r-- | source3/modules/vfs_default.c | 20 | ||||
-rw-r--r-- | source3/modules/vfs_gpfs.c | 12 | ||||
-rw-r--r-- | source3/modules/vfs_scannedonly.c | 8 |
7 files changed, 124 insertions, 65 deletions
diff --git a/source3/modules/onefs_open.c b/source3/modules/onefs_open.c index 2b4e106f91..a3b919fac6 100644 --- a/source3/modules/onefs_open.c +++ b/source3/modules/onefs_open.c @@ -2094,11 +2094,13 @@ NTSTATUS onefs_create_file(vfs_handle_struct *handle, /* Get the file name if root_dir_fid was specified. */ if (root_dir_fid != 0) { + struct smb_filename *smb_fname_out = NULL; status = get_relative_fid_filename(conn, req, root_dir_fid, - smb_fname); + smb_fname, &smb_fname_out); if (!NT_STATUS_IS_OK(status)) { goto fail; } + smb_fname = smb_fname_out; } /* All file access must go through check_name() */ diff --git a/source3/modules/vfs_acl_common.c b/source3/modules/vfs_acl_common.c index abc4a62696..f1884f5a10 100644 --- a/source3/modules/vfs_acl_common.c +++ b/source3/modules/vfs_acl_common.c @@ -254,6 +254,10 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle, uint8_t hash_tmp[XATTR_SD_HASH_SIZE]; struct security_descriptor *psd = NULL; struct security_descriptor *pdesc_next = NULL; + bool ignore_file_system_acl = lp_parm_bool(SNUM(handle->conn), + ACL_MODULE_NAME, + "ignore system acls", + false); if (fsp && name == NULL) { name = fsp->fsp_name->base_name; @@ -317,6 +321,9 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle, goto out; } + if (ignore_file_system_acl) { + goto out; + } status = hash_sd_sha256(pdesc_next, hash_tmp); if (!NT_STATUS_IS_OK(status)) { @@ -327,6 +334,9 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle, if (memcmp(&hash[0], &hash_tmp[0], XATTR_SD_HASH_SIZE) == 0) { /* Hash matches, return blob sd. */ + DEBUG(10, ("get_nt_acl_internal: blob hash " + "matches for file %s\n", + name )); goto out; } @@ -350,22 +360,44 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle, * inheritable ACE entries we have to fake them. */ if (fsp) { - is_directory = fsp->is_directory; + status = vfs_stat_fsp(fsp); + if (!NT_STATUS_IS_OK(status)) { + return status; + } psbuf = &fsp->fsp_name->st; } else { - if (vfs_stat_smb_fname(handle->conn, + int ret = vfs_stat_smb_fname(handle->conn, name, - &sbuf) == 0) { - is_directory = S_ISDIR(sbuf.st_ex_mode); + &sbuf); + if (ret == -1) { + return map_nt_error_from_unix(errno); } } - if (is_directory && + is_directory = S_ISDIR(sbuf.st_ex_mode); + + if (ignore_file_system_acl) { + TALLOC_FREE(pdesc_next); + status = make_default_filesystem_acl(talloc_tos(), + name, + psbuf, + &psd); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + } else { + if (is_directory && !sd_has_inheritable_components(psd, true)) { - add_directory_inheritable_components(handle, + add_directory_inheritable_components(handle, name, psbuf, psd); + } + /* The underlying POSIX module always sets + the ~SEC_DESC_DACL_PROTECTED bit, as ACLs + can't be inherited in this way under POSIX. + Remove it for Windows-style ACLs. */ + psd->type &= ~SEC_DESC_DACL_PROTECTED; } } @@ -384,6 +416,13 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle, TALLOC_FREE(blob.data); *ppdesc = psd; + + if (DEBUGLEVEL >= 10) { + DEBUG(10,("get_nt_acl_internal: returning acl for %s is:\n", + name )); + NDR_PRINT_DEBUG(security_descriptor, psd); + } + return NT_STATUS_OK; } @@ -660,61 +699,47 @@ static NTSTATUS get_nt_acl_common(vfs_handle_struct *handle, *********************************************************************/ static NTSTATUS fset_nt_acl_common(vfs_handle_struct *handle, files_struct *fsp, - uint32_t security_info_sent, const struct security_descriptor *psd) + uint32_t security_info_sent, const struct security_descriptor *orig_psd) { NTSTATUS status; DATA_BLOB blob; struct security_descriptor *pdesc_next = NULL; + struct security_descriptor *psd = NULL; uint8_t hash[XATTR_SD_HASH_SIZE]; if (DEBUGLEVEL >= 10) { DEBUG(10,("fset_nt_acl_xattr: incoming sd for file %s\n", fsp_str_dbg(fsp))); NDR_PRINT_DEBUG(security_descriptor, - CONST_DISCARD(struct security_descriptor *,psd)); + CONST_DISCARD(struct security_descriptor *,orig_psd)); } - /* Ensure we have OWNER/GROUP/DACL set. */ - - if ((security_info_sent & (OWNER_SECURITY_INFORMATION| - GROUP_SECURITY_INFORMATION| - DACL_SECURITY_INFORMATION)) != - (OWNER_SECURITY_INFORMATION| - GROUP_SECURITY_INFORMATION| - DACL_SECURITY_INFORMATION)) { - /* No we don't - read from the existing SD. */ - struct security_descriptor *nc_psd = NULL; + status = get_nt_acl_internal(handle, fsp, + NULL, + SECINFO_OWNER|SECINFO_GROUP|SECINFO_DACL|SECINFO_SACL, + &psd); - status = get_nt_acl_internal(handle, fsp, - NULL, - (OWNER_SECURITY_INFORMATION| - GROUP_SECURITY_INFORMATION| - DACL_SECURITY_INFORMATION), - &nc_psd); - - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - /* This is safe as nc_psd is discarded at fn exit. */ - if (security_info_sent & OWNER_SECURITY_INFORMATION) { - nc_psd->owner_sid = psd->owner_sid; - } - security_info_sent |= OWNER_SECURITY_INFORMATION; + if (!NT_STATUS_IS_OK(status)) { + return status; + } - if (security_info_sent & GROUP_SECURITY_INFORMATION) { - nc_psd->group_sid = psd->group_sid; - } - security_info_sent |= GROUP_SECURITY_INFORMATION; + psd->revision = orig_psd->revision; + /* All our SD's are self relative. */ + psd->type = orig_psd->type | SEC_DESC_SELF_RELATIVE; - if (security_info_sent & DACL_SECURITY_INFORMATION) { - nc_psd->dacl = dup_sec_acl(talloc_tos(), psd->dacl); - if (nc_psd->dacl == NULL) { - return NT_STATUS_NO_MEMORY; - } - } - security_info_sent |= DACL_SECURITY_INFORMATION; - psd = nc_psd; + if ((security_info_sent & SECINFO_OWNER) && (orig_psd->owner_sid != NULL)) { + psd->owner_sid = orig_psd->owner_sid; + } + if ((security_info_sent & SECINFO_GROUP) && (orig_psd->group_sid != NULL)) { + psd->group_sid = orig_psd->group_sid; + } + if (security_info_sent & SECINFO_DACL) { + psd->dacl = orig_psd->dacl; + psd->type |= SEC_DESC_DACL_PRESENT; + } + if (security_info_sent & SECINFO_SACL) { + psd->sacl = orig_psd->sacl; + psd->type |= SEC_DESC_SACL_PRESENT; } status = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd); @@ -901,6 +926,10 @@ static NTSTATUS create_file_acl_common(struct vfs_handle_struct *handle, result, &info); + if (!NT_STATUS_IS_OK(status)) { + goto out; + } + if (info != FILE_WAS_CREATED) { /* File/directory was opened, not created. */ goto out; @@ -908,7 +937,7 @@ static NTSTATUS create_file_acl_common(struct vfs_handle_struct *handle, fsp = *result; - if (!NT_STATUS_IS_OK(status) || fsp == NULL) { + if (fsp == NULL) { /* Only handle success. */ goto out; } diff --git a/source3/modules/vfs_acl_tdb.c b/source3/modules/vfs_acl_tdb.c index 8da0d1e3ee..b26208c377 100644 --- a/source3/modules/vfs_acl_tdb.c +++ b/source3/modules/vfs_acl_tdb.c @@ -28,6 +28,7 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_VFS +#define ACL_MODULE_NAME "acl_tdb" #include "modules/vfs_acl_common.c" static unsigned int ref_count; @@ -314,13 +315,16 @@ static int connect_acl_tdb(struct vfs_handle_struct *handle, return -1; } - /* Ensure we have "inherit acls = yes" if we're + /* Ensure we have the parameters correct if we're * using this module. */ DEBUG(2,("connect_acl_tdb: setting 'inherit acls = true' " - "and 'dos filemode = true' for service %s\n", + "'dos filemode = true' and " + "'force unknown acl user = true' for service %s\n", service )); + lp_do_parameter(SNUM(handle->conn), "inherit acls", "true"); lp_do_parameter(SNUM(handle->conn), "dos filemode", "true"); + lp_do_parameter(SNUM(handle->conn), "force unknown acl user", "true"); return 0; } diff --git a/source3/modules/vfs_acl_xattr.c b/source3/modules/vfs_acl_xattr.c index 18f2d42784..46e282d349 100644 --- a/source3/modules/vfs_acl_xattr.c +++ b/source3/modules/vfs_acl_xattr.c @@ -29,6 +29,8 @@ #define DBGC_CLASS DBGC_VFS /* Pull in the common functions. */ +#define ACL_MODULE_NAME "acl_xattr" + #include "modules/vfs_acl_common.c" /******************************************************************* @@ -183,14 +185,16 @@ static int connect_acl_xattr(struct vfs_handle_struct *handle, return ret; } - /* Ensure we have "inherit acls = yes" if we're - * using this module. */ - DEBUG(2,("connect_acl_xattr: setting 'inherit acls = true' " - "and 'dos filemode = true' for service %s\n", - service )); + /* Ensure we have the parameters correct if we're + * using this module. */ + DEBUG(2,("connect_acl_xattr: setting 'inherit acls = true' " + "'dos filemode = true' and " + "'force unknown acl user = true' for service %s\n", + service )); lp_do_parameter(SNUM(handle->conn), "inherit acls", "true"); lp_do_parameter(SNUM(handle->conn), "dos filemode", "true"); + lp_do_parameter(SNUM(handle->conn), "force unknown acl user", "true"); return 0; } diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index 6e2a5712c8..60b85d9730 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -217,7 +217,7 @@ static int vfswrap_mkdir(vfs_handle_struct *handle, const char *path, mode_t mo if (lp_inherit_acls(SNUM(handle->conn)) && parent_dirname(talloc_tos(), path, &parent, NULL) && (has_dacl = directory_has_default_acl(handle->conn, parent))) - mode = 0777; + mode = (0777 & lp_dir_mask(SNUM(handle->conn))); TALLOC_FREE(parent); @@ -898,7 +898,11 @@ static int vfswrap_ntimes(vfs_handle_struct *handle, } else { result = utimensat(AT_FDCWD, smb_fname->base_name, NULL, 0); } -#elif defined(HAVE_UTIMES) + if (!((result == -1) && (errno == ENOSYS))) { + goto out; + } +#endif +#if defined(HAVE_UTIMES) if (ft != NULL) { struct timeval tv[2]; tv[0] = convert_timespec_to_timeval(ft->atime); @@ -907,7 +911,11 @@ static int vfswrap_ntimes(vfs_handle_struct *handle, } else { result = utimes(smb_fname->base_name, NULL); } -#elif defined(HAVE_UTIME) + if (!((result == -1) && (errno == ENOSYS))) { + goto out; + } +#endif +#if defined(HAVE_UTIME) if (ft != NULL) { struct utimbuf times; times.actime = convert_timespec_to_time_t(ft->atime); @@ -916,10 +924,12 @@ static int vfswrap_ntimes(vfs_handle_struct *handle, } else { result = utime(smb_fname->base_name, NULL); } -#else + if (!((result == -1) && (errno == ENOSYS))) { + goto out; + } +#endif errno = ENOSYS; result = -1; -#endif out: END_PROFILE(syscall_ntimes); diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index 7c481d6ba0..262d1679a8 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -939,6 +939,11 @@ static int gpfs_set_xattr(struct vfs_handle_struct *handle, const char *path, ret = set_gpfs_winattrs(CONST_DISCARD(char *, path), GPFS_WINATTR_SET_ATTRS, &attrs); if ( ret == -1){ + if (errno == ENOSYS) { + return SMB_VFS_NEXT_SETXATTR(handle, path, name, value, + size, flags); + } + DEBUG(1, ("gpfs_set_xattr:Set GPFS attributes failed %d\n",ret)); return -1; } @@ -964,6 +969,11 @@ static ssize_t gpfs_get_xattr(struct vfs_handle_struct *handle, const char *pat ret = get_gpfs_winattrs(CONST_DISCARD(char *, path), &attrs); if ( ret == -1){ + if (errno == ENOSYS) { + return SMB_VFS_NEXT_GETXATTR(handle, path, name, value, + size); + } + DEBUG(1, ("gpfs_get_xattr: Get GPFS attributes failed: %d\n",ret)); return -1; } @@ -1095,7 +1105,7 @@ static int vfs_gpfs_ntimes(struct vfs_handle_struct *handle, ret = set_gpfs_winattrs(CONST_DISCARD(char *, path), GPFS_WINATTR_SET_CREATION_TIME, &attrs); - if(ret == -1){ + if(ret == -1 && errno != ENOSYS){ DEBUG(1,("vfs_gpfs_ntimes: set GPFS ntimes failed %d\n",ret)); return -1; } diff --git a/source3/modules/vfs_scannedonly.c b/source3/modules/vfs_scannedonly.c index 12077f374d..7b4b42b13b 100644 --- a/source3/modules/vfs_scannedonly.c +++ b/source3/modules/vfs_scannedonly.c @@ -426,8 +426,8 @@ static bool scannedonly_allow_access(vfs_handle_struct * handle, retval = SMB_VFS_NEXT_STAT(handle, cache_smb_fname); } if (retval == 0 && VALID_STAT(cache_smb_fname->st)) { - if (timespec_is_newer(&smb_fname->st.st_ex_mtime, - &cache_smb_fname->st.st_ex_mtime)) { + if (timespec_is_newer(&smb_fname->st.st_ex_ctime, + &cache_smb_fname->st.st_ex_ctime)) { talloc_free(cache_smb_fname); return true; } @@ -489,8 +489,8 @@ static bool scannedonly_allow_access(vfs_handle_struct * handle, } /* still no cachefile, or still too old, return 0 */ if (retval != 0 - || !timespec_is_newer(&smb_fname->st.st_ex_mtime, - &cache_smb_fname->st.st_ex_mtime)) { + || !timespec_is_newer(&smb_fname->st.st_ex_ctime, + &cache_smb_fname->st.st_ex_ctime)) { DEBUG(SCANNEDONLY_DEBUG, ("retval=%d, return 0\n",retval)); return false; |