[SCM] Samba Shared Repository - branch v3-5-test updated

Jeremy Allison jra at samba.org
Mon Nov 30 17:53:59 MST 2009


The branch, v3-5-test has been updated
       via  70c4293... Fix bug 6938 : No hook exists to check creation rights when using acl_xattr module Fix ACL modules to test for permissions on open/mkdir/opendir. Ensure that underlying ACLs are returned for directories/files with no Windows xattr or tdb acls stored. Jeremy. (cherry picked from commit bdc8c9d37ca478f74127628ab03bb68cd72bff63)
      from  d3339cd... drsuapi: fix build warning of NDR size calculation of drsuapi_DsReplicaObjectIdentifier3Binary.

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-5-test


- Log -----------------------------------------------------------------
commit 70c4293644b623e031dc4e086c52c929faab00a9
Author: Jeremy Allison <jra at samba.org>
Date:   Mon Nov 30 16:50:34 2009 -0800

    Fix bug 6938 : No hook exists to check creation rights when using acl_xattr module
    Fix ACL modules to test for permissions on open/mkdir/opendir.
    Ensure that underlying ACLs are returned for directories/files with
    no Windows xattr or tdb acls stored.
    Jeremy.
    (cherry picked from commit bdc8c9d37ca478f74127628ab03bb68cd72bff63)

-----------------------------------------------------------------------

Summary of changes:
 source3/modules/vfs_acl_common.c |  109 +++++++++++++++++++++++++++++++++++---
 source3/modules/vfs_acl_tdb.c    |    1 +
 source3/modules/vfs_acl_xattr.c  |    1 +
 3 files changed, 104 insertions(+), 7 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/modules/vfs_acl_common.c b/source3/modules/vfs_acl_common.c
index 0bb0bca..0919dcc 100644
--- a/source3/modules/vfs_acl_common.c
+++ b/source3/modules/vfs_acl_common.c
@@ -186,6 +186,20 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle,
 	status = get_acl_blob(talloc_tos(), handle, fsp, name, &blob);
 	if (!NT_STATUS_IS_OK(status)) {
 		DEBUG(10, ("get_acl_blob returned %s\n", nt_errstr(status)));
+		if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
+			/* Pull the ACL from the underlying system. */
+			if (fsp) {
+				status = SMB_VFS_NEXT_FGET_NT_ACL(handle,
+								fsp,
+								security_info,
+								ppdesc);
+			} else {
+				status = SMB_VFS_NEXT_GET_NT_ACL(handle,
+								name,
+								security_info,
+								ppdesc);
+			}
+		}
 		return status;
 	}
 
@@ -478,6 +492,51 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle,
 	}
 }
 
+static NTSTATUS check_parent_acl_common(vfs_handle_struct *handle,
+				const char *path,
+				uint32_t access_mask)
+{
+	char *parent_name = NULL;
+	struct security_descriptor *parent_desc = NULL;
+	uint32_t access_granted = 0;
+	NTSTATUS status;
+
+	if (!parent_dirname(talloc_tos(), path, &parent_name, NULL)) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	status = SMB_VFS_GET_NT_ACL(handle->conn,
+					parent_name,
+					(OWNER_SECURITY_INFORMATION |
+					 GROUP_SECURITY_INFORMATION |
+					 DACL_SECURITY_INFORMATION),
+					&parent_desc);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(0,("check_parent_acl_common: SMB_VFS_GET_NT_ACL "
+			"on directory %s for "
+			"path %s returned %s\n",
+			parent_name,
+			path,
+			nt_errstr(status) ));
+		return status;
+	}
+	status = smb1_file_se_access_check(parent_desc,
+					handle->conn->server_info->ptok,
+					access_mask,
+					&access_granted);
+	if(!NT_STATUS_IS_OK(status)) {
+		DEBUG(0,("check_parent_acl_common: access check "
+			"on directory %s for "
+			"path %s for mask 0x%x returned %s\n",
+			parent_name,
+			path,
+			access_mask,
+			nt_errstr(status) ));
+		return status;
+	}
+	return NT_STATUS_OK;
+}
+
 /*********************************************************************
  Check ACL on open. For new files inherit from parent directory.
 *********************************************************************/
@@ -504,8 +563,7 @@ static int open_acl_common(vfs_handle_struct *handle,
 	status = get_full_smb_filename(talloc_tos(), smb_fname,
 				       &fname);
 	if (!NT_STATUS_IS_OK(status)) {
-		errno = map_errno_from_nt_status(status);
-		return -1;
+		goto err;
 	}
 
 	status = get_nt_acl_internal(handle,
@@ -526,11 +584,21 @@ static int open_acl_common(vfs_handle_struct *handle,
 				"refused with error %s\n",
 				smb_fname_str_dbg(smb_fname),
 				nt_errstr(status) ));
-			errno = map_errno_from_nt_status(status);
-			return -1;
+			goto err;
 		}
         } else if (NT_STATUS_EQUAL(status,NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
 		file_existed = false;
+		/*
+		 * If O_CREAT is true then we're trying to create a file.
+		 * Check the parent directory ACL will allow this.
+		 */
+		if (flags & O_CREAT) {
+			status = check_parent_acl_common(handle, fname,
+					SEC_DIR_ADD_FILE);
+			if (!NT_STATUS_IS_OK(status)) {
+				goto err;
+			}
+		}
 	}
 
 	DEBUG(10,("open_acl_xattr: get_nt_acl_attr_internal for "
@@ -544,21 +612,38 @@ static int open_acl_common(vfs_handle_struct *handle,
 		/* File was created. Inherit from parent directory. */
 		status = fsp_set_smb_fname(fsp, smb_fname);
 		if (!NT_STATUS_IS_OK(status)) {
-			errno = map_errno_from_nt_status(status);
-			return -1;
+			goto err;
 		}
 		inherit_new_acl(handle, smb_fname, fsp, false);
 	}
 
 	return fsp->fh->fd;
+
+  err:
+
+	errno = map_errno_from_nt_status(status);
+	return -1;
 }
 
 static int mkdir_acl_common(vfs_handle_struct *handle, const char *path, mode_t mode)
 {
 	struct smb_filename *smb_fname = NULL;
-	int ret = SMB_VFS_NEXT_MKDIR(handle, path, mode);
+	int ret;
 	NTSTATUS status;
+	SMB_STRUCT_STAT sbuf;
 
+	ret = vfs_stat_smb_fname(handle->conn, path, &sbuf);
+	if (ret == -1 && errno == ENOENT) {
+		/* We're creating a new directory. */
+		status = check_parent_acl_common(handle, path,
+				SEC_DIR_ADD_SUBDIR);
+		if (!NT_STATUS_IS_OK(status)) {
+			errno = map_errno_from_nt_status(status);
+			return -1;
+		}
+	}
+
+	ret = SMB_VFS_NEXT_MKDIR(handle, path, mode);
 	if (ret == -1) {
 		return ret;
 	}
@@ -691,3 +776,13 @@ static NTSTATUS fset_nt_acl_common(vfs_handle_struct *handle, files_struct *fsp,
 
 	return NT_STATUS_OK;
 }
+
+static SMB_STRUCT_DIR *opendir_acl_common(vfs_handle_struct *handle,
+			const char *fname, const char *mask, uint32 attr)
+{
+	NTSTATUS status = check_parent_acl_common(handle, fname, SEC_DIR_LIST);
+
+	if (!NT_STATUS_IS_OK(status)) {
+	}
+	return SMB_VFS_NEXT_OPENDIR(handle, fname, mask, attr);
+}
diff --git a/source3/modules/vfs_acl_tdb.c b/source3/modules/vfs_acl_tdb.c
index e9d0f90..f9e766d 100644
--- a/source3/modules/vfs_acl_tdb.c
+++ b/source3/modules/vfs_acl_tdb.c
@@ -461,6 +461,7 @@ static int sys_acl_set_fd_tdb(vfs_handle_struct *handle,
 
 static struct vfs_fn_pointers vfs_acl_tdb_fns = {
 	.connect_fn = connect_acl_tdb,
+	.opendir = opendir_acl_common,
 	.mkdir = mkdir_acl_common,
 	.open = open_acl_common,
 	.unlink = unlink_acl_tdb,
diff --git a/source3/modules/vfs_acl_xattr.c b/source3/modules/vfs_acl_xattr.c
index 5e51a68..c1812b9 100644
--- a/source3/modules/vfs_acl_xattr.c
+++ b/source3/modules/vfs_acl_xattr.c
@@ -232,6 +232,7 @@ static int connect_acl_xattr(struct vfs_handle_struct *handle,
 
 static struct vfs_fn_pointers vfs_acl_xattr_fns = {
 	.connect_fn = connect_acl_xattr,
+	.opendir = opendir_acl_common,
 	.mkdir = mkdir_acl_common,
 	.open = open_acl_common,
 	.fget_nt_acl = fget_nt_acl_common,


-- 
Samba Shared Repository


More information about the samba-cvs mailing list