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

Jeremy Allison jra at samba.org
Wed Dec 23 18:26:26 MST 2009


The branch, v3-5-test has been updated
       via  c5fa822... Attempt to fix one of the last two bugs with the full Windows ACL support.
       via  ddf5ce0... The posix acl version of set_nt_acl() could set the stat_ex struct in the fsp->fsp_name pointer incorrectly for a directory.
      from  091360d... doc: update mount.cifs man page with nounix option

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


- Log -----------------------------------------------------------------
commit c5fa822d59b55b8f62e3c619004e9fb2005879eb
Author: Jeremy Allison <jra at samba.org>
Date:   Wed Dec 23 17:19:22 2009 -0800

    Attempt to fix one of the last two bugs with the full Windows ACL support.
    
    When returning an underlying ACL on a directory, normally on a
    POSIX system it has no inheritable entries, which breaks the
    Windows ACL when a user does a get/set of a Windows ACL on a
    POSIX directory with no existing stored Windows ACL from
    the Windows ACL editor. What happens is any new entry added
    by the user gets set inheritable, but none of the others
    entries are (as returned by default). So any new files then
    only inherit the single new ACE entry (the one marked inheritable
    by the ACL editor).
    
    Fix this by faking up a default 3 element inheritable ACL that
    represents what a user creating a POSIX file or directory will
    get by default from the smbd code.
    
    Jeremy.
    (cherry picked from commit 6dcbb84d485b8a8ccf0c3a70d9f5f7e951aaf1c6)

commit ddf5ce0073127c9c708bba8a3e7470e4ef6b77ac
Author: Jeremy Allison <jra at samba.org>
Date:   Wed Dec 23 17:17:48 2009 -0800

    The posix acl version of set_nt_acl() could set the stat_ex
    struct in the fsp->fsp_name pointer incorrectly for a directory.
    
    Fix this. Make map_canon_ace_perms() public.
    
    Jeremy.
    (cherry picked from commit 3d85b1ebe5e3484250b6810f1a45c1ba5a4900f7)

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

Summary of changes:
 source3/include/proto.h          |    4 ++
 source3/modules/vfs_acl_common.c |  106 ++++++++++++++++++++++++++++++++++++++
 source3/smbd/posix_acls.c        |   22 +++++---
 3 files changed, 125 insertions(+), 7 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/include/proto.h b/source3/include/proto.h
index b6c10ea..64abad7 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -6719,6 +6719,10 @@ void reply_pipe_close(connection_struct *conn, struct smb_request *req);
 
 void create_file_sids(const SMB_STRUCT_STAT *psbuf, DOM_SID *powner_sid, DOM_SID *pgroup_sid);
 bool nt4_compatible_acls(void);
+uint32_t map_canon_ace_perms(int snum,
+                                enum security_ace_type *pacl_type,
+                                mode_t perms,
+                                bool directory_ace);
 NTSTATUS unpack_nt_owners(int snum, uid_t *puser, gid_t *pgrp, uint32 security_info_sent, const SEC_DESC *psd);
 SMB_ACL_T free_empty_sys_acl(connection_struct *conn, SMB_ACL_T the_acl);
 NTSTATUS posix_fget_nt_acl(struct files_struct *fsp, uint32_t security_info,
diff --git a/source3/modules/vfs_acl_common.c b/source3/modules/vfs_acl_common.c
index 06bcfb8..1eec448 100644
--- a/source3/modules/vfs_acl_common.c
+++ b/source3/modules/vfs_acl_common.c
@@ -157,6 +157,85 @@ static NTSTATUS create_acl_blob(const struct security_descriptor *psd,
 }
 
 /*******************************************************************
+ Add in 3 inheritable components for a non-inheritable directory ACL.
+ CREATOR_OWNER/CREATOR_GROUP/WORLD.
+*******************************************************************/
+
+static void add_directory_inheritable_components(vfs_handle_struct *handle,
+                                const char *name,
+				SMB_STRUCT_STAT *psbuf,
+				struct security_descriptor *psd)
+{
+	struct connection_struct *conn = handle->conn;
+	int num_aces = (psd->dacl ? psd->dacl->num_aces : 0);
+	struct smb_filename smb_fname;
+	enum security_ace_type acl_type;
+	uint32_t access_mask;
+	mode_t dir_mode;
+	mode_t file_mode;
+	mode_t mode;
+	struct security_ace *new_ace_list = TALLOC_ZERO_ARRAY(talloc_tos(),
+						struct security_ace,
+						num_aces + 3);
+
+	if (new_ace_list == NULL) {
+		return;
+	}
+
+	/* Fake a quick smb_filename. */
+	ZERO_STRUCT(smb_fname);
+	smb_fname.st = *psbuf;
+	smb_fname.base_name = CONST_DISCARD(char *, name);
+
+	dir_mode = unix_mode(conn,
+			FILE_ATTRIBUTE_DIRECTORY, &smb_fname, NULL);
+	file_mode = unix_mode(conn,
+			FILE_ATTRIBUTE_ARCHIVE, &smb_fname, NULL);
+
+	mode = dir_mode | file_mode;
+
+	DEBUG(10, ("add_directory_inheritable_components: directory %s, "
+		"mode = 0%o\n",
+		name,
+		(unsigned int)mode ));
+
+	if (num_aces) {
+		memcpy(new_ace_list, psd->dacl->aces,
+			num_aces * sizeof(struct security_ace));
+	}
+	access_mask = map_canon_ace_perms(SNUM(conn), &acl_type,
+				mode & 0700, false);
+
+	init_sec_ace(&new_ace_list[num_aces],
+			&global_sid_Creator_Owner,
+			acl_type,
+			access_mask,
+			SEC_ACE_FLAG_CONTAINER_INHERIT|
+				SEC_ACE_FLAG_OBJECT_INHERIT|
+				SEC_ACE_FLAG_INHERIT_ONLY);
+	access_mask = map_canon_ace_perms(SNUM(conn), &acl_type,
+				(mode << 3) & 0700, false);
+	init_sec_ace(&new_ace_list[num_aces+1],
+			&global_sid_Creator_Group,
+			acl_type,
+			access_mask,
+			SEC_ACE_FLAG_CONTAINER_INHERIT|
+				SEC_ACE_FLAG_OBJECT_INHERIT|
+				SEC_ACE_FLAG_INHERIT_ONLY);
+	access_mask = map_canon_ace_perms(SNUM(conn), &acl_type,
+				(mode << 6) & 0700, false);
+	init_sec_ace(&new_ace_list[num_aces+2],
+			&global_sid_World,
+			acl_type,
+			access_mask,
+			SEC_ACE_FLAG_CONTAINER_INHERIT|
+				SEC_ACE_FLAG_OBJECT_INHERIT|
+				SEC_ACE_FLAG_INHERIT_ONLY);
+	psd->dacl->aces = new_ace_list;
+	psd->dacl->num_aces += 3;
+}
+
+/*******************************************************************
  Pull a DATA_BLOB from an xattr given a pathname.
  If the hash doesn't match, or doesn't exist - return the underlying
  filesystem sd.
@@ -261,6 +340,33 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle,
 		/* We're returning the blob, throw
  		 * away the filesystem SD. */
 		TALLOC_FREE(pdesc_next);
+	} else {
+		SMB_STRUCT_STAT sbuf;
+		SMB_STRUCT_STAT *psbuf = &sbuf;
+		bool is_directory = false;
+		/*
+		 * We're returning the underlying ACL from the
+		 * filesystem. If it's a directory, and has no
+		 * inheritable ACE entries we have to fake them.
+		 */
+		if (fsp) {
+			is_directory = fsp->is_directory;
+			psbuf = &fsp->fsp_name->st;
+		} else {
+			if (vfs_stat_smb_fname(handle->conn,
+						name,
+						&sbuf) == 0) {
+				is_directory = S_ISDIR(sbuf.st_ex_mode);
+			}
+		}
+		if (is_directory &&
+				!sd_has_inheritable_components(psd,
+							true)) {
+			add_directory_inheritable_components(handle,
+							name,
+							psbuf,
+							psd);
+		}
 	}
 
 	if (!(security_info & OWNER_SECURITY_INFORMATION)) {
diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index 65d0929..8280538 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -1068,7 +1068,7 @@ bool nt4_compatible_acls(void)
  not get. Deny entries are implicit on get with ace->perms = 0.
 ****************************************************************************/
 
-static uint32_t map_canon_ace_perms(int snum,
+uint32_t map_canon_ace_perms(int snum,
 				enum security_ace_type *pacl_type,
 				mode_t perms,
 				bool directory_ace)
@@ -1570,7 +1570,7 @@ static bool dup_owning_ace(canon_ace *dir_ace, canon_ace *ace)
 ****************************************************************************/
 
 static bool create_canon_ace_lists(files_struct *fsp,
-					SMB_STRUCT_STAT *pst,
+					const SMB_STRUCT_STAT *pst,
 					DOM_SID *pfile_owner_sid,
 					DOM_SID *pfile_grp_sid,
 					canon_ace **ppfile_ace,
@@ -2305,7 +2305,7 @@ static mode_t create_default_mode(files_struct *fsp, bool interitable_mode)
 ****************************************************************************/
 
 static bool unpack_canon_ace(files_struct *fsp,
-				SMB_STRUCT_STAT *pst,
+				const SMB_STRUCT_STAT *pst,
 				DOM_SID *pfile_owner_sid,
 				DOM_SID *pfile_grp_sid,
 				canon_ace **ppfile_ace,
@@ -2313,6 +2313,7 @@ static bool unpack_canon_ace(files_struct *fsp,
 				uint32 security_info_sent,
 				const SEC_DESC *psd)
 {
+	SMB_STRUCT_STAT st;
 	canon_ace *file_ace = NULL;
 	canon_ace *dir_ace = NULL;
 
@@ -2376,14 +2377,17 @@ static bool unpack_canon_ace(files_struct *fsp,
 
 	print_canon_ace_list( "file ace - before valid", file_ace);
 
+	st = *pst;
+
 	/*
 	 * A default 3 element mode entry for a file should be r-- --- ---.
 	 * A default 3 element mode entry for a directory should be rwx --- ---.
 	 */
 
-	pst->st_ex_mode = create_default_mode(fsp, False);
+	st.st_ex_mode = create_default_mode(fsp, False);
 
-	if (!ensure_canon_entry_valid(&file_ace, fsp->conn->params, fsp->is_directory, pfile_owner_sid, pfile_grp_sid, pst, True)) {
+	if (!ensure_canon_entry_valid(&file_ace, fsp->conn->params,
+			fsp->is_directory, pfile_owner_sid, pfile_grp_sid, &st, True)) {
 		free_canon_ace_list(file_ace);
 		free_canon_ace_list(dir_ace);
 		return False;
@@ -2397,9 +2401,10 @@ static bool unpack_canon_ace(files_struct *fsp,
 	 * it's a directory.
 	 */
 
-	pst->st_ex_mode = create_default_mode(fsp, True);
+	st.st_ex_mode = create_default_mode(fsp, True);
 
-	if (dir_ace && !ensure_canon_entry_valid(&dir_ace, fsp->conn->params, fsp->is_directory, pfile_owner_sid, pfile_grp_sid, pst, True)) {
+	if (dir_ace && !ensure_canon_entry_valid(&dir_ace, fsp->conn->params,
+			fsp->is_directory, pfile_owner_sid, pfile_grp_sid, &st, True)) {
 		free_canon_ace_list(file_ace);
 		free_canon_ace_list(dir_ace);
 		return False;
@@ -4086,6 +4091,9 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
 	free_canon_ace_list(file_ace_list);
 	free_canon_ace_list(dir_ace_list);
 
+	/* Ensure the stat struct in the fsp is correct. */
+	status = vfs_stat_fsp(fsp);
+
 	return NT_STATUS_OK;
 }
 


-- 
Samba Shared Repository


More information about the samba-cvs mailing list