--- vfs_acl_xattr.c.orig 2009-11-23 13:14:38.000000000 -0800 +++ vfs_acl_xattr.c.tmp 2009-11-23 13:11:18.000000000 -0800 @@ -275,29 +275,61 @@ *********************************************************************/ static struct security_descriptor *default_file_sd(TALLOC_CTX *mem_ctx, - SMB_STRUCT_STAT *psbuf) + SMB_STRUCT_STAT *psbuf, + int force_inherit) { struct dom_sid owner_sid, group_sid; size_t sd_size; struct security_ace *pace = NULL; struct security_acl *pacl = NULL; + /* Create SID for Everyone user - leveraged this code from somewhere + * else in Samba. + */ + + struct dom_sid global_sid_World = /* Everyone */ + { 1, 1, {0,0,0,0,0,1}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; + uid_to_sid(&owner_sid, psbuf->st_uid); gid_to_sid(&group_sid, psbuf->st_gid); - pace = TALLOC_ARRAY(mem_ctx, struct security_ace, 2); + pace = TALLOC_ARRAY(mem_ctx, struct security_ace, 3); if (!pace) { return NULL; } + /* If force_inherit is set, this means we are initializing the ACEs for + * a container and that we want the ACEs for owner and system to be + * inheritable by their children (See Bug #6802). + */ + init_sec_ace(&pace[0], &owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, - SEC_RIGHTS_FILE_ALL, 0); - init_sec_ace(&pace[1], &global_sid_System, SEC_ACE_TYPE_ACCESS_ALLOWED, - SEC_RIGHTS_FILE_ALL, 0); + SEC_RIGHTS_FILE_ALL, (force_inherit ? + (SEC_ACE_FLAG_OBJECT_INHERIT| + SEC_ACE_FLAG_CONTAINER_INHERIT) : + 0)); + + /* Create ACE for Primary group. */ + + init_sec_ace(&pace[1], &group_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, + (force_inherit ? SEC_RIGHTS_FILE_READ| + SEC_RIGHTS_FILE_EXECUTE : + SEC_RIGHTS_FILE_READ), + (force_inherit ? + (SEC_ACE_FLAG_OBJECT_INHERIT| + SEC_ACE_FLAG_CONTAINER_INHERIT) : + 0)); + + /* Create ACE for Everyone user */ + init_sec_ace(&pace[2], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, + SEC_RIGHTS_FILE_READ, (force_inherit ? + (SEC_ACE_FLAG_OBJECT_INHERIT| + SEC_ACE_FLAG_CONTAINER_INHERIT) : + 0)); pacl = make_sec_acl(mem_ctx, NT4_ACL_REVISION, - 2, + 3, pace); if (!pacl) { return NULL; @@ -327,6 +359,7 @@ DATA_BLOB blob; size_t size; char *parent_name; + int force_inherit = 0; if (!parent_dirname(ctx, fname, &parent_name, NULL)) { return NT_STATUS_NO_MEMORY; @@ -390,7 +423,29 @@ if (ret == -1) { return map_nt_error_from_unix(errno); } - psd = default_file_sd(ctx, &sbuf); + + /* If we get here, we could have the following possibilities: + * 1. No ACLs exist on the parent container. + * 2. ACLs exist on the parent container but they were + * not inheritable. + * + * Check to see if case #1 occurred. + * + */ + if (container && + (parent_desc == NULL || parent_desc->dacl == NULL || + parent_desc->dacl->num_aces == 0)) { + + /* If no parent descriptor exists, then there were + * no ACLs on the parent and then we must create + * the ACLs on this newly created folder so that they + * will be inherited by their children (See Bug #6802). + */ + + force_inherit = 1; + } + + psd = default_file_sd(ctx, &sbuf, force_inherit); if (!psd) { return NT_STATUS_NO_MEMORY; } @@ -412,6 +467,8 @@ } } + + /********************************************************************* Check ACL on open. For new files inherit from parent directory. *********************************************************************/ @@ -425,6 +482,9 @@ uint32_t access_granted = 0; struct security_descriptor *pdesc = NULL; bool file_existed = true; + + DEBUG(10, ("XATTR OPEN OF %s\n", fname)); + NTSTATUS status = get_nt_acl_xattr_internal(handle, NULL, fname, @@ -455,9 +515,12 @@ fname, nt_errstr(status) )); + + fsp->fh->fd = SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode); if (!file_existed && fsp->fh->fd != -1) { + /* File was created. Inherit from parent directory. */ string_set(&fsp->fsp_name, fname); inherit_new_acl(handle, fname, fsp, false); @@ -631,6 +694,8 @@ return -1; } + + become_root(); SMB_VFS_REMOVEXATTR(handle->conn, name, XATTR_NTACL_NAME); unbecome_root(); @@ -653,6 +718,7 @@ return -1; } + become_root(); SMB_VFS_FREMOVEXATTR(fsp, XATTR_NTACL_NAME); unbecome_root(); @@ -660,6 +726,7 @@ return ret; } + /* VFS operations structure */ static vfs_op_tuple skel_op_tuples[] = @@ -676,7 +743,6 @@ /* POSIX ACL operations. */ {SMB_VFS_OP(sys_acl_set_file_xattr), SMB_VFS_OP_SYS_ACL_SET_FILE, SMB_VFS_LAYER_TRANSPARENT}, {SMB_VFS_OP(sys_acl_set_fd_xattr), SMB_VFS_OP_SYS_ACL_SET_FD, SMB_VFS_LAYER_TRANSPARENT}, - {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP} };