summaryrefslogtreecommitdiff
path: root/source3/modules
diff options
context:
space:
mode:
Diffstat (limited to 'source3/modules')
-rw-r--r--source3/modules/onefs_open.c4
-rw-r--r--source3/modules/vfs_acl_common.c123
-rw-r--r--source3/modules/vfs_acl_tdb.c8
-rw-r--r--source3/modules/vfs_acl_xattr.c14
-rw-r--r--source3/modules/vfs_default.c20
-rw-r--r--source3/modules/vfs_gpfs.c12
-rw-r--r--source3/modules/vfs_scannedonly.c8
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;