From: "Erich E. Hoover" Subject: [PATCH 3/5] ntdll: Inherit security attributes from parent directories. Message-Id: Date: Thu, 1 Nov 2012 22:44:08 -0600 This patch changes the behavior of security attributes such that when a file is being created and no attributes are specified then the attributes are copied from the parent directory. PlayReady requires this to occur so that the individualization file gets the appropriate permissions from the parent folder (770). From 6c3036e605d5964d5f48f3f75e777796693a72b4 Mon Sep 17 00:00:00 2001 From: Erich Hoover Date: Thu, 1 Nov 2012 22:26:30 -0600 Subject: ntdll: Inherit security attributes from parent directories. --- dlls/ntdll/file.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c index 234ed7e..1c90a71 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c @@ -150,10 +150,53 @@ static NTSTATUS FILE_CreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATT { struct security_descriptor *sd; struct object_attributes objattr; + PSECURITY_DESCRIPTOR parentsd = NULL, psd; objattr.rootdir = wine_server_obj_handle( attr->RootDirectory ); objattr.name_len = 0; - io->u.Status = NTDLL_create_struct_sd( attr->SecurityDescriptor, &sd, &objattr.sd_len ); + psd = attr->SecurityDescriptor; + if (!attr->SecurityDescriptor && (disposition == FILE_CREATE||disposition == FILE_OVERWRITE_IF)) + { + SECURITY_INFORMATION info = OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION + |DACL_SECURITY_INFORMATION|SACL_SECURITY_INFORMATION; + WCHAR *p, parent[MAX_PATH]; + OBJECT_ATTRIBUTES pattr; + UNICODE_STRING parentW; + IO_STATUS_BLOCK io; + NTSTATUS status; + HANDLE hparent; + ULONG n1, n2; + + parentW.Buffer = parent; + parentW.Length = attr->ObjectName->Length; + memcpy(parentW.Buffer, attr->ObjectName->Buffer, attr->ObjectName->Length); + if ((p = strrchrW(parent, '\\')) != NULL) + { + p[0] = 0; + parentW.Length = (p-parent)*sizeof(WCHAR); + } + memset(&pattr, 0x0, sizeof(pattr)); + pattr.Length = sizeof(pattr); + pattr.Attributes = OBJ_CASE_INSENSITIVE; + pattr.ObjectName = &parentW; + status = FILE_CreateFile( &hparent, READ_CONTROL|ACCESS_SYSTEM_SECURITY, &pattr, &io, NULL, + FILE_FLAG_BACKUP_SEMANTICS, + FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, + FILE_OPEN_FOR_BACKUP_INTENT, NULL, 0 ); + if (status == STATUS_SUCCESS) + status = NtQuerySecurityObject( hparent, info, NULL, 0, &n1 ); + if (status == STATUS_BUFFER_TOO_SMALL && (parentsd = RtlAllocateHeap( GetProcessHeap(), 0, n1 )) != NULL) + status = NtQuerySecurityObject( hparent, info, parentsd, n1, &n2 ); + if (status == STATUS_SUCCESS) + status = NtQuerySecurityObject( hparent, info, parentsd, n1, &n2 ); + if (hparent != INVALID_HANDLE_VALUE) + NtClose( hparent ); + if (status == STATUS_SUCCESS) + psd = parentsd; + } + io->u.Status = NTDLL_create_struct_sd( psd, &sd, &objattr.sd_len ); + if (!attr->SecurityDescriptor) + RtlFreeHeap( GetProcessHeap(), 0, parentsd ); if (io->u.Status != STATUS_SUCCESS) { RtlFreeAnsiString( &unix_name ); -- 1.7.9.5