mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
server-{Stored,Inherited}_ACLs: Rework of ACL patches, use upstream code to inherit ACL attributes in advapi32 code.
This commit is contained in:
parent
96325cabed
commit
04e3ce9865
@ -1,216 +0,0 @@
|
||||
From e498b901443fffeb344b2dcc4627da4b520f0af9 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Fri, 27 Mar 2015 15:32:04 +0100
|
||||
Subject: Revert "advapi32: Add DACL inheritance support in SetSecurityInfo."
|
||||
|
||||
This reverts commit f974d726720eff4fcd7371bca95e6cdcc4b4a848.
|
||||
---
|
||||
dlls/advapi32/security.c | 130 +----------------------------------------
|
||||
dlls/advapi32/tests/security.c | 23 ++++----
|
||||
2 files changed, 14 insertions(+), 139 deletions(-)
|
||||
|
||||
diff --git a/dlls/advapi32/security.c b/dlls/advapi32/security.c
|
||||
index 2cd3f74..e8cdcc5 100644
|
||||
--- a/dlls/advapi32/security.c
|
||||
+++ b/dlls/advapi32/security.c
|
||||
@@ -4052,8 +4052,6 @@ DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
|
||||
}
|
||||
break;
|
||||
case SE_FILE_OBJECT:
|
||||
- if (SecurityInfo & DACL_SECURITY_INFORMATION)
|
||||
- access |= READ_CONTROL;
|
||||
if (!(err = get_security_file( pObjectName, access, &handle )))
|
||||
{
|
||||
err = SetSecurityInfo( handle, ObjectType, SecurityInfo, psidOwner, psidGroup, pDacl, pSacl );
|
||||
@@ -5731,7 +5729,6 @@ DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType,
|
||||
PSID psidGroup, PACL pDacl, PACL pSacl)
|
||||
{
|
||||
SECURITY_DESCRIPTOR sd;
|
||||
- PACL dacl = pDacl;
|
||||
NTSTATUS status;
|
||||
|
||||
if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
|
||||
@@ -5742,130 +5739,7 @@ DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType,
|
||||
if (SecurityInfo & GROUP_SECURITY_INFORMATION)
|
||||
SetSecurityDescriptorGroup(&sd, psidGroup, FALSE);
|
||||
if (SecurityInfo & DACL_SECURITY_INFORMATION)
|
||||
- {
|
||||
- if (ObjectType == SE_FILE_OBJECT && pDacl)
|
||||
- {
|
||||
- SECURITY_DESCRIPTOR_CONTROL control;
|
||||
- PSECURITY_DESCRIPTOR psd;
|
||||
- OBJECT_NAME_INFORMATION *name_info;
|
||||
- DWORD size, rev;
|
||||
-
|
||||
- status = NtQuerySecurityObject(handle, SecurityInfo, NULL, 0, &size);
|
||||
- if (status != STATUS_BUFFER_TOO_SMALL)
|
||||
- return RtlNtStatusToDosError(status);
|
||||
-
|
||||
- psd = heap_alloc(size);
|
||||
- if (!psd)
|
||||
- return ERROR_NOT_ENOUGH_MEMORY;
|
||||
-
|
||||
- status = NtQuerySecurityObject(handle, SecurityInfo, psd, size, &size);
|
||||
- if (status)
|
||||
- {
|
||||
- heap_free(psd);
|
||||
- return RtlNtStatusToDosError(status);
|
||||
- }
|
||||
-
|
||||
- status = RtlGetControlSecurityDescriptor(psd, &control, &rev);
|
||||
- heap_free(psd);
|
||||
- if (status)
|
||||
- return RtlNtStatusToDosError(status);
|
||||
- /* TODO: copy some control flags to new sd */
|
||||
-
|
||||
- /* inherit parent directory DACL */
|
||||
- if (!(control & SE_DACL_PROTECTED))
|
||||
- {
|
||||
- status = NtQueryObject(handle, ObjectNameInformation, NULL, 0, &size);
|
||||
- if (status != STATUS_INFO_LENGTH_MISMATCH)
|
||||
- return RtlNtStatusToDosError(status);
|
||||
-
|
||||
- name_info = heap_alloc(size);
|
||||
- if (!name_info)
|
||||
- return ERROR_NOT_ENOUGH_MEMORY;
|
||||
-
|
||||
- status = NtQueryObject(handle, ObjectNameInformation, name_info, size, NULL);
|
||||
- if (status)
|
||||
- {
|
||||
- heap_free(name_info);
|
||||
- return RtlNtStatusToDosError(status);
|
||||
- }
|
||||
-
|
||||
- for (name_info->Name.Length-=2; name_info->Name.Length>0; name_info->Name.Length-=2)
|
||||
- if (name_info->Name.Buffer[name_info->Name.Length/2-1]=='\\' ||
|
||||
- name_info->Name.Buffer[name_info->Name.Length/2-1]=='/')
|
||||
- break;
|
||||
- if (name_info->Name.Length)
|
||||
- {
|
||||
- OBJECT_ATTRIBUTES attr;
|
||||
- IO_STATUS_BLOCK io;
|
||||
- HANDLE parent;
|
||||
- PSECURITY_DESCRIPTOR parent_sd;
|
||||
- ACL *parent_dacl;
|
||||
- DWORD err = ERROR_ACCESS_DENIED;
|
||||
-
|
||||
- name_info->Name.Buffer[name_info->Name.Length/2] = 0;
|
||||
-
|
||||
- attr.Length = sizeof(attr);
|
||||
- attr.RootDirectory = 0;
|
||||
- attr.Attributes = 0;
|
||||
- attr.ObjectName = &name_info->Name;
|
||||
- attr.SecurityDescriptor = NULL;
|
||||
- status = NtOpenFile(&parent, READ_CONTROL, &attr, &io,
|
||||
- FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
|
||||
- FILE_OPEN_FOR_BACKUP_INTENT);
|
||||
- heap_free(name_info);
|
||||
- if (!status)
|
||||
- {
|
||||
- err = GetSecurityInfo(parent, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
|
||||
- NULL, NULL, &parent_dacl, NULL, &parent_sd);
|
||||
- CloseHandle(parent);
|
||||
- }
|
||||
-
|
||||
- if (!err)
|
||||
- {
|
||||
- int i;
|
||||
-
|
||||
- dacl = heap_alloc_zero(pDacl->AclSize+parent_dacl->AclSize);
|
||||
- if (!dacl)
|
||||
- {
|
||||
- LocalFree(parent_sd);
|
||||
- return ERROR_NOT_ENOUGH_MEMORY;
|
||||
- }
|
||||
- memcpy(dacl, pDacl, pDacl->AclSize);
|
||||
- dacl->AclSize = pDacl->AclSize+parent_dacl->AclSize;
|
||||
-
|
||||
- for (i=0; i<parent_dacl->AceCount; i++)
|
||||
- {
|
||||
- ACE_HEADER *ace;
|
||||
-
|
||||
- if (!GetAce(parent_dacl, i, (void*)&ace))
|
||||
- continue;
|
||||
- if (!(ace->AceFlags & (OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE)))
|
||||
- continue;
|
||||
- if ((ace->AceFlags & (OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE)) !=
|
||||
- (OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE))
|
||||
- {
|
||||
- FIXME("unsupported flags: %x\n", ace->AceFlags);
|
||||
- continue;
|
||||
- }
|
||||
-
|
||||
- if (ace->AceFlags & NO_PROPAGATE_INHERIT_ACE)
|
||||
- ace->AceFlags &= ~(OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE|NO_PROPAGATE_INHERIT_ACE);
|
||||
- ace->AceFlags &= ~INHERIT_ONLY_ACE;
|
||||
- ace->AceFlags |= INHERITED_ACE;
|
||||
-
|
||||
- if(!AddAce(dacl, ACL_REVISION, MAXDWORD, ace, ace->AceSize))
|
||||
- WARN("error adding inherited ACE\n");
|
||||
- }
|
||||
- LocalFree(parent_sd);
|
||||
- }
|
||||
- }
|
||||
- else
|
||||
- heap_free(name_info);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- SetSecurityDescriptorDacl(&sd, TRUE, dacl, FALSE);
|
||||
- }
|
||||
+ SetSecurityDescriptorDacl(&sd, TRUE, pDacl, FALSE);
|
||||
if (SecurityInfo & SACL_SECURITY_INFORMATION)
|
||||
SetSecurityDescriptorSacl(&sd, TRUE, pSacl, FALSE);
|
||||
|
||||
@@ -5879,8 +5753,6 @@ DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType,
|
||||
status = NtSetSecurityObject(handle, SecurityInfo, &sd);
|
||||
break;
|
||||
}
|
||||
- if (dacl != pDacl)
|
||||
- heap_free(dacl);
|
||||
return RtlNtStatusToDosError(status);
|
||||
}
|
||||
|
||||
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
|
||||
index 466100d..53fd643 100644
|
||||
--- a/dlls/advapi32/tests/security.c
|
||||
+++ b/dlls/advapi32/tests/security.c
|
||||
@@ -3615,22 +3615,25 @@ static void test_GetNamedSecurityInfoA(void)
|
||||
|
||||
error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
|
||||
NULL, NULL, &pDacl, NULL, &pSD);
|
||||
- ok(!error, "GetNamedSecurityInfo failed with error %d\n", error);
|
||||
+ todo_wine ok(!error, "GetNamedSecurityInfo failed with error %d\n", error);
|
||||
|
||||
- bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
|
||||
- ok(bret, "GetAclInformation failed\n");
|
||||
- if (acl_size.AceCount > 0)
|
||||
+ if (!error)
|
||||
{
|
||||
- bret = pGetAce(pDacl, 0, (VOID **)&ace);
|
||||
- ok(bret, "Failed to get ACE.\n");
|
||||
- todo_wine ok(((ACE_HEADER *)ace)->AceFlags & INHERITED_ACE,
|
||||
- "ACE has unexpected flags: 0x%x\n", ((ACE_HEADER *)ace)->AceFlags);
|
||||
+ bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
|
||||
+ ok(bret, "GetAclInformation failed\n");
|
||||
+ if (acl_size.AceCount > 0)
|
||||
+ {
|
||||
+ bret = pGetAce(pDacl, 0, (VOID **)&ace);
|
||||
+ ok(bret, "Failed to get ACE.\n");
|
||||
+ ok(((ACE_HEADER *)ace)->AceFlags & INHERITED_ACE,
|
||||
+ "ACE has unexpected flags: 0x%x\n", ((ACE_HEADER *)ace)->AceFlags);
|
||||
+ }
|
||||
+ LocalFree(pSD);
|
||||
}
|
||||
- LocalFree(pSD);
|
||||
|
||||
h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
|
||||
NULL, OPEN_EXISTING, 0, NULL);
|
||||
- ok(h != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
|
||||
+ todo_wine ok(h != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
|
||||
CloseHandle(h);
|
||||
|
||||
/* test setting NULL DACL */
|
||||
--
|
||||
2.3.3
|
||||
|
@ -1,75 +0,0 @@
|
||||
From eb05c44d59763b99851106cac937107f4c101639 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Fri, 27 Mar 2015 15:32:17 +0100
|
||||
Subject: Revert "advapi32/tests: Add test for mapping DACL to permission."
|
||||
|
||||
This reverts commit a4b12eb9f937202848b229ed15f2c7d1823b41da.
|
||||
---
|
||||
dlls/advapi32/tests/security.c | 36 ++----------------------------------
|
||||
1 file changed, 2 insertions(+), 34 deletions(-)
|
||||
|
||||
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
|
||||
index a12fb7b..91d8600 100644
|
||||
--- a/dlls/advapi32/tests/security.c
|
||||
+++ b/dlls/advapi32/tests/security.c
|
||||
@@ -3405,6 +3405,7 @@ static void test_GetNamedSecurityInfoA(void)
|
||||
"Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask);
|
||||
}
|
||||
LocalFree(pSD);
|
||||
+ HeapFree(GetProcessHeap(), 0, user);
|
||||
|
||||
/* show that setting empty DACL is not removing all file permissions */
|
||||
pDacl = HeapAlloc(GetProcessHeap(), 0, sizeof(ACL));
|
||||
@@ -3441,7 +3442,7 @@ static void test_GetNamedSecurityInfoA(void)
|
||||
/* NtSetSecurityObject doesn't inherit DACL entries */
|
||||
pSD = sd+sizeof(void*)-((ULONG_PTR)sd)%sizeof(void*);
|
||||
InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
|
||||
- pDacl = HeapAlloc(GetProcessHeap(), 0, 100);
|
||||
+ pDacl = HeapAlloc(GetProcessHeap(), 0, sizeof(ACL));
|
||||
bret = InitializeAcl(pDacl, sizeof(ACL), ACL_REVISION);
|
||||
ok(bret, "Failed to initialize ACL.\n");
|
||||
bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
|
||||
@@ -3472,40 +3473,7 @@ static void test_GetNamedSecurityInfoA(void)
|
||||
NULL, OPEN_EXISTING, 0, NULL);
|
||||
ok(h == INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
|
||||
CloseHandle(h);
|
||||
-
|
||||
- /* test if DACL is properly mapped to permission */
|
||||
- bret = InitializeAcl(pDacl, 100, ACL_REVISION);
|
||||
- ok(bret, "Failed to initialize ACL.\n");
|
||||
- bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid);
|
||||
- ok(bret, "Failed to add Current User to ACL.\n");
|
||||
- bret = pAddAccessDeniedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid);
|
||||
- ok(bret, "Failed to add Current User to ACL.\n");
|
||||
- bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
|
||||
- ok(bret, "Failed to add ACL to security desciptor.\n");
|
||||
- status = pNtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD);
|
||||
- ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %x\n", status);
|
||||
-
|
||||
- h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
|
||||
- NULL, OPEN_EXISTING, 0, NULL);
|
||||
- ok(h != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
|
||||
- CloseHandle(h);
|
||||
-
|
||||
- bret = InitializeAcl(pDacl, 100, ACL_REVISION);
|
||||
- ok(bret, "Failed to initialize ACL.\n");
|
||||
- bret = pAddAccessDeniedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid);
|
||||
- ok(bret, "Failed to add Current User to ACL.\n");
|
||||
- bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid);
|
||||
- ok(bret, "Failed to add Current User to ACL.\n");
|
||||
- bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
|
||||
- ok(bret, "Failed to add ACL to security desciptor.\n");
|
||||
- status = pNtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD);
|
||||
- ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %x\n", status);
|
||||
-
|
||||
- h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
|
||||
- NULL, OPEN_EXISTING, 0, NULL);
|
||||
- ok(h == INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
|
||||
HeapFree(GetProcessHeap(), 0, pDacl);
|
||||
- HeapFree(GetProcessHeap(), 0, user);
|
||||
CloseHandle(hTemp);
|
||||
|
||||
/* Test querying the ownership of a built-in registry key */
|
||||
--
|
||||
2.3.3
|
||||
|
@ -1,158 +0,0 @@
|
||||
From 0e64055fbe7f17de05328353457b93f720ef3bb7 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Fri, 27 Mar 2015 15:32:32 +0100
|
||||
Subject: Revert "advapi32: Add SetNamedSecurityInfo test with empty DACL."
|
||||
|
||||
This reverts commit 02c4f5bd275d70d1dcb48bf95775efa376b50c22.
|
||||
---
|
||||
dlls/advapi32/tests/security.c | 95 ++----------------------------------------
|
||||
1 file changed, 4 insertions(+), 91 deletions(-)
|
||||
|
||||
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
|
||||
index 00dd9e8..b19dbe8 100644
|
||||
--- a/dlls/advapi32/tests/security.c
|
||||
+++ b/dlls/advapi32/tests/security.c
|
||||
@@ -125,7 +125,6 @@ static BOOL (WINAPI *pCreateRestrictedToken)(HANDLE, DWORD, DWORD, PSID_AND_ATTR
|
||||
PLUID_AND_ATTRIBUTES, DWORD, PSID_AND_ATTRIBUTES, PHANDLE);
|
||||
static BOOL (WINAPI *pGetAclInformation)(PACL,LPVOID,DWORD,ACL_INFORMATION_CLASS);
|
||||
static BOOL (WINAPI *pGetAce)(PACL,DWORD,LPVOID*);
|
||||
-static NTSTATUS (WINAPI *pNtSetSecurityObject)(HANDLE,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR);
|
||||
static NTSTATUS (WINAPI *pNtCreateFile)(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES,PIO_STATUS_BLOCK,PLARGE_INTEGER,ULONG,ULONG,ULONG,ULONG,PVOID,ULONG);
|
||||
static BOOL (WINAPI *pRtlDosPathNameToNtPathName_U)(LPCWSTR,PUNICODE_STRING,PWSTR*,CURDIR*);
|
||||
static NTSTATUS (WINAPI *pRtlAnsiStringToUnicodeString)(PUNICODE_STRING,PCANSI_STRING,BOOLEAN);
|
||||
@@ -155,7 +154,6 @@ static void init(void)
|
||||
hntdll = GetModuleHandleA("ntdll.dll");
|
||||
pNtQueryObject = (void *)GetProcAddress( hntdll, "NtQueryObject" );
|
||||
pNtAccessCheck = (void *)GetProcAddress( hntdll, "NtAccessCheck" );
|
||||
- pNtSetSecurityObject = (void *)GetProcAddress(hntdll, "NtSetSecurityObject");
|
||||
pNtCreateFile = (void *)GetProcAddress(hntdll, "NtCreateFile");
|
||||
pRtlDosPathNameToNtPathName_U = (void *)GetProcAddress(hntdll, "RtlDosPathNameToNtPathName_U");
|
||||
pRtlAnsiStringToUnicodeString = (void *)GetProcAddress(hntdll, "RtlAnsiStringToUnicodeString");
|
||||
@@ -3429,7 +3427,7 @@ static void test_GetNamedSecurityInfoA(void)
|
||||
char invalid_path[] = "/an invalid file path";
|
||||
int users_ace_id = -1, admins_ace_id = -1, i;
|
||||
char software_key[] = "MACHINE\\Software";
|
||||
- char sd[SECURITY_DESCRIPTOR_MIN_LENGTH+sizeof(void*)];
|
||||
+ char sd[SECURITY_DESCRIPTOR_MIN_LENGTH];
|
||||
SECURITY_DESCRIPTOR_CONTROL control;
|
||||
ACL_SIZE_INFORMATION acl_size;
|
||||
CHAR windows_dir[MAX_PATH];
|
||||
@@ -3441,12 +3439,11 @@ static void test_GetNamedSecurityInfoA(void)
|
||||
BOOL owner_defaulted;
|
||||
BOOL group_defaulted;
|
||||
BOOL dacl_defaulted;
|
||||
- HANDLE token, hTemp, h;
|
||||
+ HANDLE token, hTemp;
|
||||
PSID owner, group;
|
||||
BOOL dacl_present;
|
||||
PACL pDacl;
|
||||
BYTE flags;
|
||||
- NTSTATUS status;
|
||||
|
||||
if (!pSetNamedSecurityInfoA || !pGetNamedSecurityInfoA || !pCreateWellKnownSid)
|
||||
{
|
||||
@@ -3551,8 +3548,8 @@ static void test_GetNamedSecurityInfoA(void)
|
||||
bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
|
||||
ok(bret, "Failed to add ACL to security desciptor.\n");
|
||||
GetTempFileNameA(".", "foo", 0, tmpfile);
|
||||
- hTemp = CreateFileA(tmpfile, WRITE_DAC|GENERIC_WRITE, FILE_SHARE_DELETE|FILE_SHARE_READ,
|
||||
- NULL, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, NULL);
|
||||
+ hTemp = CreateFileA(tmpfile, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING,
|
||||
+ FILE_FLAG_DELETE_ON_CLOSE, NULL);
|
||||
SetLastError(0xdeadbeef);
|
||||
error = pSetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL,
|
||||
NULL, pDacl, NULL);
|
||||
@@ -3604,90 +3601,6 @@ static void test_GetNamedSecurityInfoA(void)
|
||||
}
|
||||
LocalFree(pSD);
|
||||
HeapFree(GetProcessHeap(), 0, user);
|
||||
-
|
||||
- /* show that setting empty DACL is not removing all file permissions */
|
||||
- pDacl = HeapAlloc(GetProcessHeap(), 0, sizeof(ACL));
|
||||
- bret = InitializeAcl(pDacl, sizeof(ACL), ACL_REVISION);
|
||||
- ok(bret, "Failed to initialize ACL.\n");
|
||||
- error = pSetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
|
||||
- NULL, NULL, pDacl, NULL);
|
||||
- ok(!error, "SetNamedSecurityInfoA failed with error %d\n", error);
|
||||
- HeapFree(GetProcessHeap(), 0, pDacl);
|
||||
-
|
||||
- error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
|
||||
- NULL, NULL, &pDacl, NULL, &pSD);
|
||||
- todo_wine ok(!error, "GetNamedSecurityInfo failed with error %d\n", error);
|
||||
-
|
||||
- if (!error)
|
||||
- {
|
||||
- bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
|
||||
- ok(bret, "GetAclInformation failed\n");
|
||||
- if (acl_size.AceCount > 0)
|
||||
- {
|
||||
- bret = pGetAce(pDacl, 0, (VOID **)&ace);
|
||||
- ok(bret, "Failed to get ACE.\n");
|
||||
- ok(((ACE_HEADER *)ace)->AceFlags & INHERITED_ACE,
|
||||
- "ACE has unexpected flags: 0x%x\n", ((ACE_HEADER *)ace)->AceFlags);
|
||||
- }
|
||||
- LocalFree(pSD);
|
||||
- }
|
||||
-
|
||||
- h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
|
||||
- NULL, OPEN_EXISTING, 0, NULL);
|
||||
- todo_wine ok(h != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
|
||||
- CloseHandle(h);
|
||||
-
|
||||
- /* test setting NULL DACL */
|
||||
- error = pSetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
|
||||
- DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL);
|
||||
- ok(!error, "SetNamedSecurityInfoA failed with error %d\n", error);
|
||||
-
|
||||
- error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
|
||||
- NULL, NULL, &pDacl, NULL, &pSD);
|
||||
- ok(!error, "GetNamedSecurityInfo failed with error %d\n", error);
|
||||
- todo_wine ok(!pDacl, "pDacl != NULL\n");
|
||||
- LocalFree(pSD);
|
||||
-
|
||||
- h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
|
||||
- NULL, OPEN_EXISTING, 0, NULL);
|
||||
- ok(h != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
|
||||
- CloseHandle(h);
|
||||
-
|
||||
- /* NtSetSecurityObject doesn't inherit DACL entries */
|
||||
- pSD = sd+sizeof(void*)-((ULONG_PTR)sd)%sizeof(void*);
|
||||
- InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
|
||||
- pDacl = HeapAlloc(GetProcessHeap(), 0, sizeof(ACL));
|
||||
- bret = InitializeAcl(pDacl, sizeof(ACL), ACL_REVISION);
|
||||
- ok(bret, "Failed to initialize ACL.\n");
|
||||
- bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
|
||||
- ok(bret, "Failed to add ACL to security desciptor.\n");
|
||||
- status = pNtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD);
|
||||
- ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %x\n", status);
|
||||
-
|
||||
- h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
|
||||
- NULL, OPEN_EXISTING, 0, NULL);
|
||||
- ok(h == INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
|
||||
- CloseHandle(h);
|
||||
-
|
||||
- pSetSecurityDescriptorControl(pSD, SE_DACL_AUTO_INHERIT_REQ, SE_DACL_AUTO_INHERIT_REQ);
|
||||
- status = pNtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD);
|
||||
- ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %x\n", status);
|
||||
-
|
||||
- h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
|
||||
- NULL, OPEN_EXISTING, 0, NULL);
|
||||
- ok(h == INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
|
||||
- CloseHandle(h);
|
||||
-
|
||||
- pSetSecurityDescriptorControl(pSD, SE_DACL_AUTO_INHERIT_REQ|SE_DACL_AUTO_INHERITED,
|
||||
- SE_DACL_AUTO_INHERIT_REQ|SE_DACL_AUTO_INHERITED);
|
||||
- status = pNtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD);
|
||||
- ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %x\n", status);
|
||||
-
|
||||
- h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
|
||||
- NULL, OPEN_EXISTING, 0, NULL);
|
||||
- ok(h == INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
|
||||
- CloseHandle(h);
|
||||
- HeapFree(GetProcessHeap(), 0, pDacl);
|
||||
CloseHandle(hTemp);
|
||||
|
||||
/* Test querying the ownership of a built-in registry key */
|
||||
--
|
||||
2.3.3
|
||||
|
@ -67,7 +67,6 @@ patch_enable_all ()
|
||||
enable_Pipelight="$1"
|
||||
enable_Staging="$1"
|
||||
enable_advapi32_LsaLookupSids="$1"
|
||||
enable_advapi32_Revert_DACL="$1"
|
||||
enable_browseui_Progress_Dialog="$1"
|
||||
enable_combase_String="$1"
|
||||
enable_comctl32_LoadIconMetric="$1"
|
||||
@ -269,9 +268,6 @@ patch_enable ()
|
||||
advapi32-LsaLookupSids)
|
||||
enable_advapi32_LsaLookupSids="$2"
|
||||
;;
|
||||
advapi32-Revert_DACL)
|
||||
enable_advapi32_Revert_DACL="$2"
|
||||
;;
|
||||
browseui-Progress_Dialog)
|
||||
enable_browseui_Progress_Dialog="$2"
|
||||
;;
|
||||
@ -1096,16 +1092,12 @@ if test "$enable_server_Inherited_ACLs" -eq 1; then
|
||||
fi
|
||||
|
||||
if test "$enable_server_Stored_ACLs" -eq 1; then
|
||||
if test "$enable_advapi32_Revert_DACL" -gt 1; then
|
||||
abort "Patchset advapi32-Revert_DACL disabled, but server-Stored_ACLs depends on that."
|
||||
fi
|
||||
if test "$enable_ntdll_DOS_Attributes" -gt 1; then
|
||||
abort "Patchset ntdll-DOS_Attributes disabled, but server-Stored_ACLs depends on that."
|
||||
fi
|
||||
if test "$enable_server_File_Permissions" -gt 1; then
|
||||
abort "Patchset server-File_Permissions disabled, but server-Stored_ACLs depends on that."
|
||||
fi
|
||||
enable_advapi32_Revert_DACL=1
|
||||
enable_ntdll_DOS_Attributes=1
|
||||
enable_server_File_Permissions=1
|
||||
fi
|
||||
@ -1412,22 +1404,6 @@ if test "$enable_advapi32_LsaLookupSids" -eq 1; then
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset advapi32-Revert_DACL
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/advapi32/security.c, dlls/advapi32/tests/security.c
|
||||
# |
|
||||
if test "$enable_advapi32_Revert_DACL" -eq 1; then
|
||||
patch_apply advapi32-Revert_DACL/0001-Revert-advapi32-Add-DACL-inheritance-support-in-SetS.patch
|
||||
patch_apply advapi32-Revert_DACL/0002-Revert-advapi32-tests-Add-test-for-mapping-DACL-to-p.patch
|
||||
patch_apply advapi32-Revert_DACL/0003-Revert-advapi32-Add-SetNamedSecurityInfo-test-with-e.patch
|
||||
(
|
||||
echo '+ { "Sebastian Lackner", "Revert \"advapi32: Add DACL inheritance support in SetSecurityInfo.\".", 1 },';
|
||||
echo '+ { "Sebastian Lackner", "Revert \"advapi32/tests: Add test for mapping DACL to permission.\".", 1 },';
|
||||
echo '+ { "Sebastian Lackner", "Revert \"advapi32: Add SetNamedSecurityInfo test with empty DACL.\".", 1 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset browseui-Progress_Dialog
|
||||
# |
|
||||
# | Modified files:
|
||||
@ -3797,22 +3773,25 @@ fi
|
||||
# | * [#33576] Support for stored file ACLs
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/advapi32/tests/security.c, include/wine/port.h, server/change.c, server/file.c, server/file.h
|
||||
# | * dlls/advapi32/tests/security.c, include/wine/port.h, server/change.c, server/file.c, server/file.h, server/object.c,
|
||||
# | server/object.h
|
||||
# |
|
||||
if test "$enable_server_Stored_ACLs" -eq 1; then
|
||||
patch_apply server-Stored_ACLs/0001-server-Unify-the-storage-of-security-attributes-for-.patch
|
||||
patch_apply server-Stored_ACLs/0002-server-Unify-the-retrieval-of-security-attributes-fo.patch
|
||||
patch_apply server-Stored_ACLs/0003-server-Store-file-security-attributes-with-extended-.patch
|
||||
patch_apply server-Stored_ACLs/0004-server-Store-user-and-group-inside-stored-extended-f.patch
|
||||
patch_apply server-Stored_ACLs/0005-server-Retrieve-file-security-attributes-with-extend.patch
|
||||
patch_apply server-Stored_ACLs/0003-server-Add-a-helper-function-set_sd_from_token_inter.patch
|
||||
patch_apply server-Stored_ACLs/0004-server-Temporarily-store-the-full-security-descripto.patch
|
||||
patch_apply server-Stored_ACLs/0005-server-Store-file-security-attributes-with-extended-.patch
|
||||
patch_apply server-Stored_ACLs/0006-server-Convert-return-of-file-security-masks-with-ge.patch
|
||||
patch_apply server-Stored_ACLs/0007-server-Retrieve-file-security-attributes-with-extend.patch
|
||||
(
|
||||
echo '+ { "Erich E. Hoover", "server: Unify the storage of security attributes for files and directories.", 7 },';
|
||||
echo '+ { "Erich E. Hoover", "server: Unify the retrieval of security attributes for files and directories.", 7 },';
|
||||
echo '+ { "Erich E. Hoover", "server: Store file security attributes with extended file attributes.", 7 },';
|
||||
echo '+ { "Erich E. Hoover", "server: Store user and group inside stored extended file attribute information.", 7 },';
|
||||
echo '+ { "Erich E. Hoover", "server: Retrieve file security attributes with extended file attributes.", 7 },';
|
||||
echo '+ { "Sebastian Lackner", "server: Add a helper function set_sd_from_token_internal to merge two security descriptors.", 1 },';
|
||||
echo '+ { "Sebastian Lackner", "server: Temporarily store the full security descriptor for file objects.", 1 },';
|
||||
echo '+ { "Erich E. Hoover", "server: Store file security attributes with extended file attributes.", 8 },';
|
||||
echo '+ { "Erich E. Hoover", "server: Convert return of file security masks with generic access mappings.", 7 },';
|
||||
echo '+ { "Erich E. Hoover", "server: Retrieve file security attributes with extended file attributes.", 7 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
@ -3822,14 +3801,12 @@ fi
|
||||
# | * [#34406] Support for inherited file ACLs
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/advapi32/tests/security.c, include/winnt.h, server/fd.c, server/file.c, server/file.h
|
||||
# | * dlls/advapi32/tests/security.c, server/file.c
|
||||
# |
|
||||
if test "$enable_server_Inherited_ACLs" -eq 1; then
|
||||
patch_apply server-Inherited_ACLs/0001-server-Inherit-security-attributes-from-parent-direc.patch
|
||||
patch_apply server-Inherited_ACLs/0002-server-Inherit-security-attributes-from-parent-direc.patch
|
||||
(
|
||||
echo '+ { "Erich E. Hoover", "server: Inherit security attributes from parent directories on creation.", 7 },';
|
||||
echo '+ { "Erich E. Hoover", "server: Inherit security attributes from parent directories on SetSecurityInfo.", 7 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
|
@ -1,26 +1,26 @@
|
||||
From c7ee69405e7f18058ca0b1c05e8dfa7ee669df13 Mon Sep 17 00:00:00 2001
|
||||
From 5779586de8e1059d7f88edf45d5d9ed59eca1b46 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Fri, 18 Apr 2014 15:21:00 -0600
|
||||
Subject: server: Add compatibility code for handling the old method of storing
|
||||
ACLs. (try 6)
|
||||
|
||||
---
|
||||
server/file.c | 167 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
|
||||
1 file changed, 164 insertions(+), 3 deletions(-)
|
||||
server/file.c | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
|
||||
1 file changed, 167 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/server/file.c b/server/file.c
|
||||
index 146ea68..4c72775 100644
|
||||
index 617c373..9adca0d 100644
|
||||
--- a/server/file.c
|
||||
+++ b/server/file.c
|
||||
@@ -72,6 +72,7 @@ struct file
|
||||
|
||||
static unsigned int generic_file_map_access( unsigned int access );
|
||||
struct security_descriptor *get_xattr_sd( int fd );
|
||||
+struct security_descriptor *get_xattr_acls( int fd, const SID *user, const SID *group );
|
||||
static struct security_descriptor *get_xattr_sd( int fd );
|
||||
+static struct security_descriptor *get_xattr_acls( int fd, const SID *user, const SID *group );
|
||||
|
||||
static void file_dump( struct object *obj, int verbose );
|
||||
static struct fd *file_get_fd( struct object *obj );
|
||||
@@ -440,6 +441,7 @@ static struct security_descriptor *file_get_parent_sd( struct fd *root, const ch
|
||||
@@ -308,6 +309,7 @@ static struct security_descriptor *file_get_parent_sd( struct fd *root, const ch
|
||||
mode_t parent_mode = 0555;
|
||||
char *p, *parent_name;
|
||||
struct fd *parent_fd;
|
||||
@ -28,7 +28,7 @@ index 146ea68..4c72775 100644
|
||||
int unix_fd;
|
||||
|
||||
if (!(parent_name = mem_alloc( child_len + 1 ))) return NULL;
|
||||
@@ -472,6 +474,9 @@ static struct security_descriptor *file_get_parent_sd( struct fd *root, const ch
|
||||
@@ -340,6 +342,9 @@ static struct security_descriptor *file_get_parent_sd( struct fd *root, const ch
|
||||
if (unix_fd != -1)
|
||||
{
|
||||
parent_sd = get_xattr_sd( unix_fd );
|
||||
@ -38,11 +38,11 @@ index 146ea68..4c72775 100644
|
||||
if (parent_sd)
|
||||
{
|
||||
sd = inherit_sd( parent_sd, is_dir );
|
||||
@@ -759,6 +764,160 @@ struct security_descriptor *get_xattr_sd( int fd )
|
||||
return sd;
|
||||
@@ -623,6 +628,163 @@ static void convert_generic_sd( struct security_descriptor *sd )
|
||||
}
|
||||
}
|
||||
|
||||
+struct security_descriptor *get_xattr_acls( int fd, const SID *user, const SID *group )
|
||||
+static struct security_descriptor *get_xattr_acls( int fd, const SID *user, const SID *group )
|
||||
+{
|
||||
+ int dacl_size = sizeof(ACL), n;
|
||||
+ int offset, type, flags, mask, rev, ia, sa;
|
||||
@ -189,17 +189,20 @@ index 146ea68..4c72775 100644
|
||||
+ while (*p);
|
||||
+
|
||||
+ if (sd_is_valid( sd, n ))
|
||||
+ {
|
||||
+ convert_generic_sd( sd );
|
||||
+ return sd;
|
||||
+ }
|
||||
+
|
||||
+err:
|
||||
+ free( sd );
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
/* Convert generic rights into standard access rights */
|
||||
void convert_generic_sd( struct security_descriptor *sd )
|
||||
static struct security_descriptor *get_xattr_sd( int fd )
|
||||
{
|
||||
@@ -786,6 +945,7 @@ struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode
|
||||
struct security_descriptor *sd;
|
||||
@@ -652,6 +814,7 @@ struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode
|
||||
int unix_fd = get_unix_fd( fd );
|
||||
struct stat st;
|
||||
struct security_descriptor *sd;
|
||||
@ -207,22 +210,21 @@ index 146ea68..4c72775 100644
|
||||
|
||||
if (unix_fd == -1 || fstat( unix_fd, &st ) == -1)
|
||||
return obj->sd;
|
||||
@@ -795,11 +955,12 @@ struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode
|
||||
@@ -661,10 +824,11 @@ struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode
|
||||
(st.st_uid == *uid))
|
||||
return obj->sd;
|
||||
|
||||
+ user = security_unix_uid_to_sid( st.st_uid );
|
||||
+ group = token_get_primary_group( current->process->token );
|
||||
sd = get_xattr_sd( unix_fd );
|
||||
+ if (!sd) sd = get_xattr_acls( unix_fd, user, group );
|
||||
if (sd) convert_generic_sd( sd );
|
||||
- if (!sd) sd = mode_to_sd( st.st_mode,
|
||||
- security_unix_uid_to_sid( st.st_uid ),
|
||||
- token_get_primary_group( current->process->token ));
|
||||
+ if (!sd) sd = get_xattr_acls( unix_fd, user, group );
|
||||
+ if (!sd) sd = mode_to_sd( st.st_mode, user, group );
|
||||
if (!sd) return obj->sd;
|
||||
|
||||
*mode = st.st_mode;
|
||||
--
|
||||
2.3.2
|
||||
2.3.5
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 42b83b84ee0ff3b0a9d2439e1d0154287630f192 Mon Sep 17 00:00:00 2001
|
||||
From a6f078d87958db4e0eb404e7f7cc2d603b92869c Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Fri, 18 Apr 2014 14:08:36 -0600
|
||||
Subject: server: Inherit security attributes from parent directories on
|
||||
@ -10,10 +10,10 @@ Subject: server: Inherit security attributes from parent directories on
|
||||
2 files changed, 141 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
|
||||
index 4db46f5..c509d3c 100644
|
||||
index 945542e..403c637 100644
|
||||
--- a/dlls/advapi32/tests/security.c
|
||||
+++ b/dlls/advapi32/tests/security.c
|
||||
@@ -3278,7 +3278,7 @@ static void test_CreateDirectoryA(void)
|
||||
@@ -3280,7 +3280,7 @@ static void test_CreateDirectoryA(void)
|
||||
(PSID *)&owner, NULL, &pDacl, NULL, &pSD);
|
||||
ok(error == ERROR_SUCCESS, "Failed to get permissions on file\n");
|
||||
test_inherited_dacl(pDacl, admin_sid, user_sid, INHERITED_ACE,
|
||||
@ -22,7 +22,7 @@ index 4db46f5..c509d3c 100644
|
||||
LocalFree(pSD);
|
||||
CloseHandle(hTemp);
|
||||
|
||||
@@ -3348,7 +3348,7 @@ static void test_CreateDirectoryA(void)
|
||||
@@ -3349,7 +3349,7 @@ static void test_CreateDirectoryA(void)
|
||||
(PSID *)&owner, NULL, &pDacl, NULL, &pSD);
|
||||
ok(error == ERROR_SUCCESS, "Failed to get permissions on file\n");
|
||||
test_inherited_dacl(pDacl, admin_sid, user_sid, INHERITED_ACE,
|
||||
@ -50,22 +50,22 @@ index 4db46f5..c509d3c 100644
|
||||
CloseHandle(hTemp);
|
||||
|
||||
diff --git a/server/file.c b/server/file.c
|
||||
index b6435d1..43be63b 100644
|
||||
index 8bcf6ee..617c373 100644
|
||||
--- a/server/file.c
|
||||
+++ b/server/file.c
|
||||
@@ -71,6 +71,7 @@ struct file
|
||||
};
|
||||
|
||||
static unsigned int generic_file_map_access( unsigned int access );
|
||||
+struct security_descriptor *get_xattr_sd( int fd );
|
||||
+static struct security_descriptor *get_xattr_sd( int fd );
|
||||
|
||||
static void file_dump( struct object *obj, int verbose );
|
||||
static struct fd *file_get_fd( struct object *obj );
|
||||
@@ -252,11 +253,142 @@ void set_xattr_sd( int fd, const struct security_descriptor *sd, const SID *user
|
||||
@@ -220,11 +221,142 @@ static void set_xattr_sd( int fd, const struct security_descriptor *sd )
|
||||
xattr_fset( fd, WINE_XATTR_SD, buffer, len );
|
||||
}
|
||||
|
||||
+struct security_descriptor *inherit_sd( const struct security_descriptor *parent_sd, int is_dir )
|
||||
+static struct security_descriptor *inherit_sd( const struct security_descriptor *parent_sd, int is_dir )
|
||||
+{
|
||||
+ const DWORD inheritance_mask = INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
|
||||
+ struct security_descriptor *sd = NULL;
|
||||
@ -201,10 +201,10 @@ index b6435d1..43be63b 100644
|
||||
const struct security_descriptor *sd )
|
||||
{
|
||||
+ struct security_descriptor *temp_sd = NULL;
|
||||
const SID *owner = NULL, *group = NULL;
|
||||
struct object *obj = NULL;
|
||||
struct fd *fd;
|
||||
@@ -286,6 +418,10 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
|
||||
int flags;
|
||||
@@ -253,6 +385,10 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
|
||||
default: set_error( STATUS_INVALID_PARAMETER ); goto done;
|
||||
}
|
||||
|
||||
@ -214,8 +214,8 @@ index b6435d1..43be63b 100644
|
||||
+
|
||||
if (sd)
|
||||
{
|
||||
owner = sd_get_owner( sd );
|
||||
@@ -329,6 +465,7 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
|
||||
const SID *owner = sd_get_owner( sd );
|
||||
@@ -292,6 +428,7 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
|
||||
release_object( fd );
|
||||
|
||||
done:
|
||||
@ -224,5 +224,5 @@ index b6435d1..43be63b 100644
|
||||
return obj;
|
||||
}
|
||||
--
|
||||
2.3.3
|
||||
2.3.5
|
||||
|
||||
|
@ -1,342 +0,0 @@
|
||||
From cf51d788cce57b6c5f99bfc15e81790fb5d449c4 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Fri, 18 Apr 2014 14:10:49 -0600
|
||||
Subject: server: Inherit security attributes from parent directories on
|
||||
SetSecurityInfo. (try 7)
|
||||
|
||||
---
|
||||
dlls/advapi32/tests/security.c | 68 +++++++++++++++++++++
|
||||
include/winnt.h | 7 ++-
|
||||
server/fd.c | 13 +++-
|
||||
server/file.c | 133 +++++++++++++++++++++++++++++++++++++++--
|
||||
server/file.h | 1 +
|
||||
5 files changed, 213 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
|
||||
index 3e88c2e..952d001 100644
|
||||
--- a/dlls/advapi32/tests/security.c
|
||||
+++ b/dlls/advapi32/tests/security.c
|
||||
@@ -3440,6 +3440,74 @@ static void test_GetNamedSecurityInfoA(void)
|
||||
"Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask);
|
||||
}
|
||||
LocalFree(pSD);
|
||||
+ CloseHandle(hTemp);
|
||||
+
|
||||
+ /* Create security descriptor with no inheritance and test that it comes back the same */
|
||||
+ pSD = &sd;
|
||||
+ pDacl = HeapAlloc(GetProcessHeap(), 0, 100);
|
||||
+ InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
|
||||
+ pCreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, admin_sid, &sid_size);
|
||||
+ bret = InitializeAcl(pDacl, 100, ACL_REVISION);
|
||||
+ ok(bret, "Failed to initialize ACL.\n");
|
||||
+ bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid);
|
||||
+ ok(bret, "Failed to add Current User to ACL.\n");
|
||||
+ bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, admin_sid);
|
||||
+ ok(bret, "Failed to add Administrator Group to ACL.\n");
|
||||
+ bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
|
||||
+ ok(bret, "Failed to add ACL to security desciptor.\n");
|
||||
+ GetTempFileNameA(".", "foo", 0, tmpfile);
|
||||
+ hTemp = CreateFileA(tmpfile, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING,
|
||||
+ FILE_FLAG_DELETE_ON_CLOSE, NULL);
|
||||
+ SetLastError(0xdeadbeef);
|
||||
+ error = pSetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
|
||||
+ DACL_SECURITY_INFORMATION|PROTECTED_DACL_SECURITY_INFORMATION,
|
||||
+ NULL, NULL, pDacl, NULL);
|
||||
+ HeapFree(GetProcessHeap(), 0, pDacl);
|
||||
+ if (error != ERROR_SUCCESS && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
|
||||
+ {
|
||||
+ win_skip("SetNamedSecurityInfoA is not implemented\n");
|
||||
+ HeapFree(GetProcessHeap(), 0, user);
|
||||
+ CloseHandle(hTemp);
|
||||
+ return;
|
||||
+ }
|
||||
+ ok(!error, "SetNamedSecurityInfoA failed with error %d\n", error);
|
||||
+ SetLastError(0xdeadbeef);
|
||||
+ error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
|
||||
+ NULL, NULL, &pDacl, NULL, &pSD);
|
||||
+ if (error != ERROR_SUCCESS && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
|
||||
+ {
|
||||
+ win_skip("GetNamedSecurityInfoA is not implemented\n");
|
||||
+ HeapFree(GetProcessHeap(), 0, user);
|
||||
+ CloseHandle(hTemp);
|
||||
+ return;
|
||||
+ }
|
||||
+ ok(!error, "GetNamedSecurityInfo failed with error %d\n", error);
|
||||
+
|
||||
+ bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
|
||||
+ ok(bret, "GetAclInformation failed\n");
|
||||
+ if (acl_size.AceCount > 0)
|
||||
+ {
|
||||
+ bret = pGetAce(pDacl, 0, (VOID **)&ace);
|
||||
+ ok(bret, "Failed to get Current User ACE.\n");
|
||||
+ bret = EqualSid(&ace->SidStart, user_sid);
|
||||
+ ok(bret, "Current User ACE != Current User SID.\n");
|
||||
+ ok(((ACE_HEADER *)ace)->AceFlags == 0,
|
||||
+ "Current User ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
|
||||
+ ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n",
|
||||
+ ace->Mask);
|
||||
+ }
|
||||
+ if (acl_size.AceCount > 1)
|
||||
+ {
|
||||
+ bret = pGetAce(pDacl, 1, (VOID **)&ace);
|
||||
+ ok(bret, "Failed to get Administators Group ACE.\n");
|
||||
+ bret = EqualSid(&ace->SidStart, admin_sid);
|
||||
+ ok(bret || broken(!bret) /* win2k */, "Administators Group ACE != Administators Group SID.\n");
|
||||
+ ok(((ACE_HEADER *)ace)->AceFlags == 0,
|
||||
+ "Administators Group ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
|
||||
+ ok(ace->Mask == 0x1f01ff || broken(ace->Mask == GENERIC_ALL) /* win2k */,
|
||||
+ "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask);
|
||||
+ }
|
||||
+ LocalFree(pSD);
|
||||
HeapFree(GetProcessHeap(), 0, user);
|
||||
CloseHandle(hTemp);
|
||||
|
||||
diff --git a/include/winnt.h b/include/winnt.h
|
||||
index 709a93f..63882bb 100644
|
||||
--- a/include/winnt.h
|
||||
+++ b/include/winnt.h
|
||||
@@ -5078,14 +5078,15 @@ typedef struct _TAPE_GET_MEDIA_PARAMETERS {
|
||||
BOOLEAN WriteProtected;
|
||||
} TAPE_GET_MEDIA_PARAMETERS, *PTAPE_GET_MEDIA_PARAMETERS;
|
||||
|
||||
-/* ----------------------------- begin registry ----------------------------- */
|
||||
-
|
||||
-/* Registry security values */
|
||||
#define OWNER_SECURITY_INFORMATION 0x00000001
|
||||
#define GROUP_SECURITY_INFORMATION 0x00000002
|
||||
#define DACL_SECURITY_INFORMATION 0x00000004
|
||||
#define SACL_SECURITY_INFORMATION 0x00000008
|
||||
+#define PROTECTED_DACL_SECURITY_INFORMATION 0x80000000
|
||||
|
||||
+/* ----------------------------- begin registry ----------------------------- */
|
||||
+
|
||||
+/* Registry security values */
|
||||
#define REG_OPTION_RESERVED 0x00000000
|
||||
#define REG_OPTION_NON_VOLATILE 0x00000000
|
||||
#define REG_OPTION_VOLATILE 0x00000001
|
||||
diff --git a/server/fd.c b/server/fd.c
|
||||
index e3b722c..e6ec90a 100644
|
||||
--- a/server/fd.c
|
||||
+++ b/server/fd.c
|
||||
@@ -1634,6 +1634,16 @@ struct fd *alloc_pseudo_fd( const struct fd_ops *fd_user_ops, struct object *use
|
||||
return fd;
|
||||
}
|
||||
|
||||
+char *fd_get_unix_name( struct fd *obj )
|
||||
+{
|
||||
+ char *unix_name;
|
||||
+ if (!obj->unix_name) return NULL;
|
||||
+ unix_name = mem_alloc( strlen(obj->unix_name) + 1 );
|
||||
+ if (!unix_name) return NULL;
|
||||
+ strcpy( unix_name, obj->unix_name );
|
||||
+ return unix_name;
|
||||
+}
|
||||
+
|
||||
/* duplicate an fd object for a different user */
|
||||
struct fd *dup_fd_object( struct fd *orig, unsigned int access, unsigned int sharing, unsigned int options )
|
||||
{
|
||||
@@ -1647,8 +1657,7 @@ struct fd *dup_fd_object( struct fd *orig, unsigned int access, unsigned int sha
|
||||
|
||||
if (orig->unix_name)
|
||||
{
|
||||
- if (!(fd->unix_name = mem_alloc( strlen(orig->unix_name) + 1 ))) goto failed;
|
||||
- strcpy( fd->unix_name, orig->unix_name );
|
||||
+ if (!(fd->unix_name = fd_get_unix_name( orig ))) goto failed;
|
||||
}
|
||||
|
||||
if (orig->inode)
|
||||
diff --git a/server/file.c b/server/file.c
|
||||
index 431b8a1..a5d2de3 100644
|
||||
--- a/server/file.c
|
||||
+++ b/server/file.c
|
||||
@@ -329,6 +329,106 @@ struct security_descriptor *inherit_sd( const struct security_descriptor *parent
|
||||
return sd;
|
||||
}
|
||||
|
||||
+struct security_descriptor *file_combine_sds( const struct security_descriptor *parent_sd,
|
||||
+ const struct security_descriptor *child_sd )
|
||||
+{
|
||||
+ size_t dacl_size = sizeof(ACL), ace_count = 0;
|
||||
+ const struct security_descriptor *old_sd;
|
||||
+ struct security_descriptor *sd = NULL;
|
||||
+ const ACL *child_dacl, *parent_dacl;
|
||||
+ int child_present, parent_present;
|
||||
+ const SID *user, *group;
|
||||
+ const ACE_HEADER *old_ace;
|
||||
+ ACE_HEADER *ace;
|
||||
+ ACL *dacl;
|
||||
+ char *ptr;
|
||||
+ ULONG i;
|
||||
+
|
||||
+ child_dacl = sd_get_dacl( child_sd, &child_present );
|
||||
+ if (child_present && child_dacl)
|
||||
+ {
|
||||
+ old_ace = (const ACE_HEADER *)(child_dacl + 1);
|
||||
+ for (i = 0; i < child_dacl->AceCount; i++, old_ace = ace_next( old_ace ))
|
||||
+ {
|
||||
+ ace_count++;
|
||||
+ dacl_size += sizeof(ACE_HEADER) + old_ace->AceSize;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ parent_dacl = sd_get_dacl( parent_sd, &parent_present );
|
||||
+ if (parent_present && parent_dacl)
|
||||
+ {
|
||||
+ old_ace = (const ACE_HEADER *)(parent_dacl + 1);
|
||||
+ for (i = 0; i < parent_dacl->AceCount; i++, old_ace = ace_next( old_ace ))
|
||||
+ {
|
||||
+ ace_count++;
|
||||
+ dacl_size += sizeof(ACE_HEADER) + old_ace->AceSize;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if(!ace_count) return sd; /* No inheritance */
|
||||
+
|
||||
+ /* FIXME: should use set_info flags? */
|
||||
+ if (child_present && child_dacl)
|
||||
+ old_sd = child_sd;
|
||||
+ else
|
||||
+ old_sd = parent_sd;
|
||||
+
|
||||
+ /* Fill in the security descriptor so that it is compatible with our DACL */
|
||||
+ user = (const SID *)(old_sd + 1);
|
||||
+ group = (const SID *)((char *)(old_sd + 1) + old_sd->owner_len);
|
||||
+ sd = mem_alloc( sizeof(struct security_descriptor) + old_sd->owner_len
|
||||
+ + old_sd->group_len + dacl_size );
|
||||
+ if (!sd) return sd;
|
||||
+ sd->control = SE_DACL_PRESENT;
|
||||
+ sd->owner_len = old_sd->owner_len;
|
||||
+ sd->group_len = old_sd->group_len;
|
||||
+ sd->sacl_len = 0;
|
||||
+ sd->dacl_len = dacl_size;
|
||||
+ ptr = (char *)(sd + 1);
|
||||
+ memcpy( ptr, user, sd->owner_len );
|
||||
+ ptr += sd->owner_len;
|
||||
+ memcpy( ptr, group, sd->group_len );
|
||||
+ ptr += sd->group_len;
|
||||
+ dacl = (ACL *)ptr;
|
||||
+ dacl->AclRevision = ACL_REVISION;
|
||||
+ dacl->Sbz1 = 0;
|
||||
+ dacl->AclSize = dacl_size;
|
||||
+ dacl->AceCount = ace_count;
|
||||
+ dacl->Sbz2 = 0;
|
||||
+ ace = (ACE_HEADER *)(dacl + 1);
|
||||
+
|
||||
+ if (parent_present && parent_dacl)
|
||||
+ {
|
||||
+ /* Build the new DACL, inheriting from the parent's information */
|
||||
+ old_ace = (const ACE_HEADER *)(parent_dacl + 1);
|
||||
+ for (i = 0; i < parent_dacl->AceCount; i++, old_ace = ace_next( old_ace ))
|
||||
+ {
|
||||
+ ace->AceType = old_ace->AceType;
|
||||
+ ace->AceFlags = old_ace->AceFlags;
|
||||
+ ace->AceSize = old_ace->AceSize;
|
||||
+ memcpy( ace + 1, old_ace + 1, old_ace->AceSize - sizeof(ACE_HEADER));
|
||||
+ ace = (ACE_HEADER *)ace_next( ace );
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (child_present && child_dacl)
|
||||
+ {
|
||||
+ /* Build the new DACL, inheriting from the child's information */
|
||||
+ old_ace = (const ACE_HEADER *)(child_dacl + 1);
|
||||
+ for (i = 0; i < child_dacl->AceCount; i++, old_ace = ace_next( old_ace ))
|
||||
+ {
|
||||
+ ace->AceType = old_ace->AceType;
|
||||
+ ace->AceFlags = old_ace->AceFlags;
|
||||
+ ace->AceSize = old_ace->AceSize;
|
||||
+ memcpy( ace + 1, old_ace + 1, old_ace->AceSize - sizeof(ACE_HEADER));
|
||||
+ ace = (ACE_HEADER *)ace_next( ace );
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return sd;
|
||||
+}
|
||||
+
|
||||
static struct security_descriptor *file_get_parent_sd( struct fd *root, const char *child_name,
|
||||
int child_len, int is_dir )
|
||||
{
|
||||
@@ -800,20 +900,41 @@ mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner )
|
||||
int set_file_sd( struct object *obj, struct fd *fd, const struct security_descriptor *sd,
|
||||
unsigned int set_info )
|
||||
{
|
||||
+ struct security_descriptor *tmp_sd = NULL;
|
||||
int unix_fd = get_unix_fd( fd );
|
||||
const SID *owner, *group;
|
||||
struct stat st;
|
||||
mode_t mode;
|
||||
+ int ret = 1;
|
||||
|
||||
if (unix_fd == -1 || fstat( unix_fd, &st ) == -1) return 1;
|
||||
|
||||
+ if (!(set_info & PROTECTED_DACL_SECURITY_INFORMATION))
|
||||
+ {
|
||||
+ char *child_name = fd_get_unix_name( fd );
|
||||
+ if (child_name)
|
||||
+ {
|
||||
+ struct security_descriptor *parent_sd;
|
||||
+ parent_sd = file_get_parent_sd( NULL, child_name, strlen(child_name),
|
||||
+ S_ISDIR(st.st_mode) );
|
||||
+ free( child_name );
|
||||
+ if (parent_sd)
|
||||
+ {
|
||||
+ tmp_sd = file_combine_sds( parent_sd, sd );
|
||||
+ if (tmp_sd) sd = tmp_sd; /* only used combined sd if successful */
|
||||
+ free( parent_sd );
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (set_info & OWNER_SECURITY_INFORMATION)
|
||||
{
|
||||
owner = sd_get_owner( sd );
|
||||
if (!owner)
|
||||
{
|
||||
set_error( STATUS_INVALID_SECURITY_DESCR );
|
||||
- return 0;
|
||||
+ ret = 0;
|
||||
+ goto err;
|
||||
}
|
||||
if (!obj->sd || !security_equal_sid( owner, sd_get_owner( obj->sd ) ))
|
||||
{
|
||||
@@ -831,7 +952,8 @@ int set_file_sd( struct object *obj, struct fd *fd, const struct security_descri
|
||||
if (!group)
|
||||
{
|
||||
set_error( STATUS_INVALID_SECURITY_DESCR );
|
||||
- return 0;
|
||||
+ ret = 0;
|
||||
+ goto err;
|
||||
}
|
||||
if (!obj->sd || !security_equal_sid( group, sd_get_group( obj->sd ) ))
|
||||
{
|
||||
@@ -856,10 +978,13 @@ int set_file_sd( struct object *obj, struct fd *fd, const struct security_descri
|
||||
if (((st.st_mode ^ mode) & (S_IRWXU|S_IRWXG|S_IRWXO)) && fchmod( unix_fd, mode ) == -1)
|
||||
{
|
||||
file_set_error();
|
||||
- return 0;
|
||||
+ ret = 0;
|
||||
}
|
||||
}
|
||||
- return 1;
|
||||
+
|
||||
+err:
|
||||
+ free( tmp_sd );
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static int file_set_sd( struct object *obj, const struct security_descriptor *sd,
|
||||
diff --git a/server/file.h b/server/file.h
|
||||
index be25fb6..b43f329 100644
|
||||
--- a/server/file.h
|
||||
+++ b/server/file.h
|
||||
@@ -79,6 +79,7 @@ extern void allow_fd_caching( struct fd *fd );
|
||||
extern void set_fd_signaled( struct fd *fd, int signaled );
|
||||
extern int is_fd_signaled( struct fd *fd );
|
||||
|
||||
+extern char *fd_get_unix_name( struct fd *obj );
|
||||
extern int default_fd_signaled( struct object *obj, struct wait_queue_entry *entry );
|
||||
extern unsigned int default_fd_map_access( struct object *obj, unsigned int access );
|
||||
extern int default_fd_get_poll_events( struct fd *fd );
|
||||
--
|
||||
2.1.0
|
||||
|
@ -1,24 +1,23 @@
|
||||
From 0e4cf36464b0ec84af3baf7feea3813dae9475ba Mon Sep 17 00:00:00 2001
|
||||
From 1ea227122c6155c07d254826b03f76d4f95e876d Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Thu, 17 Apr 2014 16:07:46 -0600
|
||||
Subject: server: Unify the storage of security attributes for files and
|
||||
directories. (try 7)
|
||||
|
||||
---
|
||||
server/change.c | 46 ++++++----------------------------------------
|
||||
server/file.c | 25 +++++++++++++++++--------
|
||||
server/change.c | 45 ++++++---------------------------------------
|
||||
server/file.c | 34 ++++++++++++++++++++++------------
|
||||
server/file.h | 2 ++
|
||||
3 files changed, 25 insertions(+), 48 deletions(-)
|
||||
3 files changed, 30 insertions(+), 51 deletions(-)
|
||||
|
||||
diff --git a/server/change.c b/server/change.c
|
||||
index 3ac70a4..4f6ce81 100644
|
||||
index 3ac70a4..c2fe428 100644
|
||||
--- a/server/change.c
|
||||
+++ b/server/change.c
|
||||
@@ -320,49 +320,15 @@ static struct security_descriptor *dir_get_sd( struct object *obj )
|
||||
static int dir_set_sd( struct object *obj, const struct security_descriptor *sd,
|
||||
@@ -321,48 +321,15 @@ static int dir_set_sd( struct object *obj, const struct security_descriptor *sd,
|
||||
unsigned int set_info )
|
||||
{
|
||||
- struct dir *dir = (struct dir *)obj;
|
||||
struct dir *dir = (struct dir *)obj;
|
||||
- const SID *owner;
|
||||
- struct stat st;
|
||||
- mode_t mode;
|
||||
@ -64,14 +63,14 @@ index 3ac70a4..4f6ce81 100644
|
||||
- }
|
||||
- return 1;
|
||||
+ fd = dir_get_fd( obj );
|
||||
+ ret = set_file_sd( obj, fd, sd, set_info );
|
||||
+ ret = set_file_sd( obj, fd, &dir->mode, &dir->uid, sd, set_info );
|
||||
+ release_object( fd );
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static struct change_record *get_first_change_record( struct dir *dir )
|
||||
diff --git a/server/file.c b/server/file.c
|
||||
index c8c880b..9777af4 100644
|
||||
index aa5ff01..fed2e45 100644
|
||||
--- a/server/file.c
|
||||
+++ b/server/file.c
|
||||
@@ -544,18 +544,13 @@ mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner )
|
||||
@ -80,36 +79,52 @@ index c8c880b..9777af4 100644
|
||||
|
||||
-static int file_set_sd( struct object *obj, const struct security_descriptor *sd,
|
||||
- unsigned int set_info )
|
||||
+int set_file_sd( struct object *obj, struct fd *fd, const struct security_descriptor *sd,
|
||||
+ unsigned int set_info )
|
||||
+int set_file_sd( struct object *obj, struct fd *fd, mode_t *mode, uid_t *uid,
|
||||
+ const struct security_descriptor *sd, unsigned int set_info )
|
||||
{
|
||||
- struct file *file = (struct file *)obj;
|
||||
+ int unix_fd = get_unix_fd( fd );
|
||||
const SID *owner;
|
||||
struct stat st;
|
||||
mode_t mode;
|
||||
- mode_t mode;
|
||||
- int unix_fd;
|
||||
-
|
||||
- assert( obj->ops == &file_ops );
|
||||
-
|
||||
- unix_fd = get_file_unix_fd( file );
|
||||
+ mode_t new_mode;
|
||||
|
||||
if (unix_fd == -1 || fstat( unix_fd, &st ) == -1) return 1;
|
||||
|
||||
@@ -594,6 +589,20 @@ static int file_set_sd( struct object *obj, const struct security_descriptor *sd
|
||||
@@ -582,10 +577,10 @@ static int file_set_sd( struct object *obj, const struct security_descriptor *sd
|
||||
if (set_info & DACL_SECURITY_INFORMATION)
|
||||
{
|
||||
/* keep the bits that we don't map to access rights in the ACL */
|
||||
- mode = st.st_mode & (S_ISUID|S_ISGID|S_ISVTX);
|
||||
- mode |= sd_to_mode( sd, owner );
|
||||
+ new_mode = st.st_mode & (S_ISUID|S_ISGID|S_ISVTX);
|
||||
+ new_mode |= sd_to_mode( sd, owner );
|
||||
|
||||
- if (((st.st_mode ^ mode) & (S_IRWXU|S_IRWXG|S_IRWXO)) && fchmod( unix_fd, mode ) == -1)
|
||||
+ if (((st.st_mode ^ new_mode) & (S_IRWXU|S_IRWXG|S_IRWXO)) && fchmod( unix_fd, new_mode ) == -1)
|
||||
{
|
||||
file_set_error();
|
||||
return 0;
|
||||
@@ -594,6 +589,21 @@ static int file_set_sd( struct object *obj, const struct security_descriptor *sd
|
||||
return 1;
|
||||
}
|
||||
|
||||
+static int file_set_sd( struct object *obj, const struct security_descriptor *sd,
|
||||
+ unsigned int set_info )
|
||||
+{
|
||||
+ struct file *file = (struct file *)obj;
|
||||
+ struct fd *fd;
|
||||
+ int ret;
|
||||
+
|
||||
+ assert( obj->ops == &file_ops );
|
||||
+
|
||||
+ fd = file_get_fd( obj );
|
||||
+ ret = set_file_sd( obj, fd, sd, set_info );
|
||||
+ ret = set_file_sd( obj, fd, &file->mode, &file->uid, sd, set_info );
|
||||
+ release_object( fd );
|
||||
+ return ret;
|
||||
+}
|
||||
@ -118,18 +133,18 @@ index c8c880b..9777af4 100644
|
||||
{
|
||||
struct file *file = (struct file *)obj;
|
||||
diff --git a/server/file.h b/server/file.h
|
||||
index 85e4257..524a688 100644
|
||||
index 85e4257..d1365b0 100644
|
||||
--- a/server/file.h
|
||||
+++ b/server/file.h
|
||||
@@ -124,6 +124,8 @@ extern struct file *create_file_for_fd_obj( struct fd *fd, unsigned int access,
|
||||
extern void file_set_error(void);
|
||||
extern struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID *group );
|
||||
extern mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner );
|
||||
+extern int set_file_sd( struct object *obj, struct fd *fd, const struct security_descriptor *sd,
|
||||
+ unsigned int set_info );
|
||||
+extern int set_file_sd( struct object *obj, struct fd *fd, mode_t *mode, uid_t *uid,
|
||||
+ const struct security_descriptor *sd, unsigned int set_info );
|
||||
|
||||
/* file mapping functions */
|
||||
|
||||
--
|
||||
2.3.3
|
||||
2.3.5
|
||||
|
||||
|
@ -1,17 +1,17 @@
|
||||
From ba94c25ed29ed6d3fc1c49a13ddb5257f5b3f385 Mon Sep 17 00:00:00 2001
|
||||
From b09247d54146c50abd7cd9e7c44e88f341bd5a13 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Thu, 17 Apr 2014 16:07:50 -0600
|
||||
Subject: server: Unify the retrieval of security attributes for files and
|
||||
directories. (try 7)
|
||||
|
||||
---
|
||||
server/change.c | 32 +++++---------------------------
|
||||
server/file.c | 32 +++++++++++++++++++++-----------
|
||||
server/file.h | 2 ++
|
||||
server/change.c | 32 +++++---------------------------
|
||||
server/file.c | 32 +++++++++++++++++++++-----------
|
||||
server/file.h | 2 ++
|
||||
3 files changed, 28 insertions(+), 38 deletions(-)
|
||||
|
||||
diff --git a/server/change.c b/server/change.c
|
||||
index 4f6ce81..27dbe25 100644
|
||||
index c2fe428..29a48b3 100644
|
||||
--- a/server/change.c
|
||||
+++ b/server/change.c
|
||||
@@ -281,39 +281,17 @@ static struct fd *dir_get_fd( struct object *obj )
|
||||
@ -60,10 +60,10 @@ index 4f6ce81..27dbe25 100644
|
||||
}
|
||||
|
||||
diff --git a/server/file.c b/server/file.c
|
||||
index fb89272..1f008ea 100644
|
||||
index fed2e45..58906c0 100644
|
||||
--- a/server/file.c
|
||||
+++ b/server/file.c
|
||||
@@ -424,23 +424,19 @@ struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID
|
||||
@@ -428,23 +428,19 @@ struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID
|
||||
return sd;
|
||||
}
|
||||
|
||||
@ -92,7 +92,7 @@ index fb89272..1f008ea 100644
|
||||
return obj->sd;
|
||||
|
||||
sd = mode_to_sd( st.st_mode,
|
||||
@@ -448,13 +444,27 @@ static struct security_descriptor *file_get_sd( struct object *obj )
|
||||
@@ -452,13 +448,27 @@ static struct security_descriptor *file_get_sd( struct object *obj )
|
||||
token_get_primary_group( current->process->token ));
|
||||
if (!sd) return obj->sd;
|
||||
|
||||
@ -123,18 +123,18 @@ index fb89272..1f008ea 100644
|
||||
{
|
||||
mode_t mode = 0;
|
||||
diff --git a/server/file.h b/server/file.h
|
||||
index 76cb383..43a234f 100644
|
||||
index d1365b0..c866312 100644
|
||||
--- a/server/file.h
|
||||
+++ b/server/file.h
|
||||
@@ -124,6 +124,8 @@ extern struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, con
|
||||
@@ -126,6 +126,8 @@ extern struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, con
|
||||
extern mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner );
|
||||
extern int set_file_sd( struct object *obj, struct fd *fd, const struct security_descriptor *sd,
|
||||
unsigned int set_info );
|
||||
extern int set_file_sd( struct object *obj, struct fd *fd, mode_t *mode, uid_t *uid,
|
||||
const struct security_descriptor *sd, unsigned int set_info );
|
||||
+extern struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode_t *mode,
|
||||
+ uid_t *uid );
|
||||
|
||||
/* file mapping functions */
|
||||
|
||||
--
|
||||
1.7.9.5
|
||||
2.3.5
|
||||
|
||||
|
@ -0,0 +1,147 @@
|
||||
From 2703d701d65a588700494de3e36978ef12a3abe4 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Mon, 30 Mar 2015 12:32:34 +0200
|
||||
Subject: server: Add a helper function set_sd_from_token_internal to merge two
|
||||
security descriptors.
|
||||
|
||||
---
|
||||
server/object.c | 55 +++++++++++++++++++++++++++++++++++--------------------
|
||||
server/object.h | 3 +++
|
||||
2 files changed, 38 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/server/object.c b/server/object.c
|
||||
index 965c11c..d04fdb9 100644
|
||||
--- a/server/object.c
|
||||
+++ b/server/object.c
|
||||
@@ -425,8 +425,9 @@ struct security_descriptor *default_get_sd( struct object *obj )
|
||||
return obj->sd;
|
||||
}
|
||||
|
||||
-int set_sd_defaults_from_token( struct object *obj, const struct security_descriptor *sd,
|
||||
- unsigned int set_info, struct token *token )
|
||||
+struct security_descriptor *set_sd_from_token_internal( const struct security_descriptor *sd,
|
||||
+ const struct security_descriptor *old_sd,
|
||||
+ unsigned int set_info, struct token *token )
|
||||
{
|
||||
struct security_descriptor new_sd, *new_sd_ptr;
|
||||
int present;
|
||||
@@ -434,8 +435,6 @@ int set_sd_defaults_from_token( struct object *obj, const struct security_descri
|
||||
const ACL *sacl, *dacl;
|
||||
char *ptr;
|
||||
|
||||
- if (!set_info) return 1;
|
||||
-
|
||||
new_sd.control = sd->control & ~SE_SELF_RELATIVE;
|
||||
|
||||
if (set_info & OWNER_SECURITY_INFORMATION && sd->owner_len)
|
||||
@@ -443,10 +442,10 @@ int set_sd_defaults_from_token( struct object *obj, const struct security_descri
|
||||
owner = sd_get_owner( sd );
|
||||
new_sd.owner_len = sd->owner_len;
|
||||
}
|
||||
- else if (obj->sd && obj->sd->owner_len)
|
||||
+ else if (old_sd && old_sd->owner_len)
|
||||
{
|
||||
- owner = sd_get_owner( obj->sd );
|
||||
- new_sd.owner_len = obj->sd->owner_len;
|
||||
+ owner = sd_get_owner( old_sd );
|
||||
+ new_sd.owner_len = old_sd->owner_len;
|
||||
}
|
||||
else if (token)
|
||||
{
|
||||
@@ -460,10 +459,10 @@ int set_sd_defaults_from_token( struct object *obj, const struct security_descri
|
||||
group = sd_get_group( sd );
|
||||
new_sd.group_len = sd->group_len;
|
||||
}
|
||||
- else if (obj->sd && obj->sd->group_len)
|
||||
+ else if (old_sd && old_sd->group_len)
|
||||
{
|
||||
- group = sd_get_group( obj->sd );
|
||||
- new_sd.group_len = obj->sd->group_len;
|
||||
+ group = sd_get_group( old_sd );
|
||||
+ new_sd.group_len = old_sd->group_len;
|
||||
}
|
||||
else if (token)
|
||||
{
|
||||
@@ -478,10 +477,10 @@ int set_sd_defaults_from_token( struct object *obj, const struct security_descri
|
||||
new_sd.sacl_len = sd->sacl_len;
|
||||
else
|
||||
{
|
||||
- if (obj->sd) sacl = sd_get_sacl( obj->sd, &present );
|
||||
+ if (old_sd) sacl = sd_get_sacl( old_sd, &present );
|
||||
|
||||
- if (obj->sd && present)
|
||||
- new_sd.sacl_len = obj->sd->sacl_len;
|
||||
+ if (old_sd && present)
|
||||
+ new_sd.sacl_len = old_sd->sacl_len;
|
||||
else
|
||||
new_sd.sacl_len = 0;
|
||||
}
|
||||
@@ -492,10 +491,10 @@ int set_sd_defaults_from_token( struct object *obj, const struct security_descri
|
||||
new_sd.dacl_len = sd->dacl_len;
|
||||
else
|
||||
{
|
||||
- if (obj->sd) dacl = sd_get_dacl( obj->sd, &present );
|
||||
+ if (old_sd) dacl = sd_get_dacl( old_sd, &present );
|
||||
|
||||
- if (obj->sd && present)
|
||||
- new_sd.dacl_len = obj->sd->dacl_len;
|
||||
+ if (old_sd && present)
|
||||
+ new_sd.dacl_len = old_sd->dacl_len;
|
||||
else if (token)
|
||||
{
|
||||
dacl = token_get_default_dacl( token );
|
||||
@@ -506,7 +505,7 @@ int set_sd_defaults_from_token( struct object *obj, const struct security_descri
|
||||
|
||||
ptr = mem_alloc( sizeof(new_sd) + new_sd.owner_len + new_sd.group_len +
|
||||
new_sd.sacl_len + new_sd.dacl_len );
|
||||
- if (!ptr) return 0;
|
||||
+ if (!ptr) return NULL;
|
||||
new_sd_ptr = (struct security_descriptor*)ptr;
|
||||
|
||||
memcpy( ptr, &new_sd, sizeof(new_sd) );
|
||||
@@ -519,9 +518,25 @@ int set_sd_defaults_from_token( struct object *obj, const struct security_descri
|
||||
ptr += new_sd.sacl_len;
|
||||
memcpy( ptr, dacl, new_sd.dacl_len );
|
||||
|
||||
- free( obj->sd );
|
||||
- obj->sd = new_sd_ptr;
|
||||
- return 1;
|
||||
+ return new_sd_ptr;
|
||||
+}
|
||||
+
|
||||
+int set_sd_defaults_from_token( struct object *obj, const struct security_descriptor *sd,
|
||||
+ unsigned int set_info, struct token *token )
|
||||
+{
|
||||
+ struct security_descriptor *new_sd;
|
||||
+
|
||||
+ if (!set_info) return 1;
|
||||
+
|
||||
+ new_sd = set_sd_from_token_internal( sd, obj->sd, set_info, token );
|
||||
+ if (new_sd)
|
||||
+ {
|
||||
+ free( obj->sd );
|
||||
+ obj->sd = new_sd;
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
/** Set the security descriptor using the current primary token for defaults. */
|
||||
diff --git a/server/object.h b/server/object.h
|
||||
index 72b52ee..1444d74 100644
|
||||
--- a/server/object.h
|
||||
+++ b/server/object.h
|
||||
@@ -140,6 +140,9 @@ extern struct fd *no_get_fd( struct object *obj );
|
||||
extern unsigned int no_map_access( struct object *obj, unsigned int access );
|
||||
extern struct security_descriptor *default_get_sd( struct object *obj );
|
||||
extern int default_set_sd( struct object *obj, const struct security_descriptor *sd, unsigned int set_info );
|
||||
+extern struct security_descriptor *set_sd_from_token_internal( const struct security_descriptor *sd,
|
||||
+ const struct security_descriptor *old_sd,
|
||||
+ unsigned int set_info, struct token *token );
|
||||
extern int set_sd_defaults_from_token( struct object *obj, const struct security_descriptor *sd,
|
||||
unsigned int set_info, struct token *token );
|
||||
extern struct object *no_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attributes );
|
||||
--
|
||||
2.3.5
|
||||
|
@ -1,161 +0,0 @@
|
||||
From cd48ef93da9c34e4757d878403374edd0e616b64 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Fri, 18 Apr 2014 15:35:24 -0600
|
||||
Subject: server: Store user and group inside stored extended file attribute
|
||||
information. (try 7)
|
||||
|
||||
---
|
||||
server/file.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++-------
|
||||
1 file changed, 70 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/server/file.c b/server/file.c
|
||||
index 502951c..72d6d95 100644
|
||||
--- a/server/file.c
|
||||
+++ b/server/file.c
|
||||
@@ -187,10 +187,11 @@ static struct object *create_file_obj( struct fd *fd, unsigned int access, mode_
|
||||
return &file->obj;
|
||||
}
|
||||
|
||||
-void set_xattr_sd( int fd, const struct security_descriptor *sd )
|
||||
+void set_xattr_sd( int fd, const struct security_descriptor *sd, const SID *user, const SID *group )
|
||||
{
|
||||
- char buffer[XATTR_SIZE_MAX];
|
||||
- int present, len;
|
||||
+ char buffer[XATTR_SIZE_MAX], *dst_ptr = &buffer[2], *src_ptr = (char *)sd;
|
||||
+ int present, len, owner_len, group_len;
|
||||
+ struct security_descriptor *dst_sd;
|
||||
const ACL *dacl;
|
||||
|
||||
/* there's no point in storing the security descriptor if there's no DACL */
|
||||
@@ -198,14 +199,52 @@ void set_xattr_sd( int fd, const struct security_descriptor *sd )
|
||||
dacl = sd_get_dacl( sd, &present );
|
||||
if (!present || !dacl) return;
|
||||
|
||||
- len = 2 + sizeof(struct security_descriptor) + sd->owner_len + sd->group_len + sd->sacl_len
|
||||
+ /* make sure that we always store the ownership information */
|
||||
+ if (!sd->owner_len)
|
||||
+ owner_len = FIELD_OFFSET(SID, SubAuthority[user->SubAuthorityCount]);
|
||||
+ else
|
||||
+ owner_len = sd->owner_len;
|
||||
+ if (!sd->group_len)
|
||||
+ group_len = FIELD_OFFSET(SID, SubAuthority[group->SubAuthorityCount]);
|
||||
+ else
|
||||
+ group_len = sd->group_len;
|
||||
+ len = 2 + sizeof(struct security_descriptor) + owner_len + group_len + sd->sacl_len
|
||||
+ sd->dacl_len;
|
||||
if (len > XATTR_SIZE_MAX) return;
|
||||
|
||||
/* include the descriptor revision and resource manager control bits */
|
||||
buffer[0] = SECURITY_DESCRIPTOR_REVISION;
|
||||
buffer[1] = 0;
|
||||
- memcpy( &buffer[2], sd, len - 2 );
|
||||
+ memcpy( dst_ptr, sd, sizeof(struct security_descriptor) );
|
||||
+ dst_sd = (struct security_descriptor *)dst_ptr;
|
||||
+ dst_sd->owner_len = owner_len;
|
||||
+ dst_sd->group_len = group_len;
|
||||
+ src_ptr += sizeof(struct security_descriptor);
|
||||
+ dst_ptr += sizeof(struct security_descriptor);
|
||||
+ /* copy the appropriate ownership information (explicit or inferred) */
|
||||
+ if (sd->owner_len)
|
||||
+ {
|
||||
+ memcpy( dst_ptr, src_ptr, sd->owner_len );
|
||||
+ src_ptr += sd->owner_len;
|
||||
+ }
|
||||
+ else
|
||||
+ memcpy( dst_ptr, user, owner_len );
|
||||
+ dst_ptr += owner_len;
|
||||
+ if (sd->group_len)
|
||||
+ {
|
||||
+ memcpy( dst_ptr, src_ptr, sd->group_len );
|
||||
+ src_ptr += sd->group_len;
|
||||
+ }
|
||||
+ else
|
||||
+ memcpy( dst_ptr, group, group_len );
|
||||
+ dst_ptr += group_len;
|
||||
+ /* copy the ACL information (explicit only) */
|
||||
+ memcpy( dst_ptr, src_ptr, sd->sacl_len );
|
||||
+ src_ptr += sd->sacl_len;
|
||||
+ dst_ptr += sd->sacl_len;
|
||||
+ memcpy( dst_ptr, src_ptr, sd->dacl_len );
|
||||
+ src_ptr += sd->dacl_len;
|
||||
+ dst_ptr += sd->dacl_len;
|
||||
xattr_fset( fd, WINE_XATTR_SD, buffer, len );
|
||||
}
|
||||
|
||||
@@ -214,6 +253,7 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
|
||||
unsigned int options, unsigned int attrs,
|
||||
const struct security_descriptor *sd )
|
||||
{
|
||||
+ const SID *owner = NULL, *group = NULL;
|
||||
struct object *obj = NULL;
|
||||
struct fd *fd;
|
||||
int flags;
|
||||
@@ -244,9 +284,12 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
|
||||
|
||||
if (sd)
|
||||
{
|
||||
- const SID *owner = sd_get_owner( sd );
|
||||
+ owner = sd_get_owner( sd );
|
||||
if (!owner)
|
||||
owner = token_get_user( current->process->token );
|
||||
+ group = sd_get_group( sd );
|
||||
+ if (!group)
|
||||
+ group = token_get_primary_group( current->process->token );
|
||||
mode = sd_to_mode( sd, owner );
|
||||
}
|
||||
else if (options & FILE_DIRECTORY_FILE)
|
||||
@@ -270,7 +313,7 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
|
||||
/* FIXME: should set error to STATUS_OBJECT_NAME_COLLISION if file existed before */
|
||||
fd = open_fd( root, name, flags | O_NONBLOCK | O_LARGEFILE, &mode, access, sharing, options );
|
||||
if (!fd) goto done;
|
||||
- set_xattr_sd( get_unix_fd( fd ), sd );
|
||||
+ set_xattr_sd( get_unix_fd( fd ), sd, owner, group );
|
||||
|
||||
if (S_ISDIR(mode))
|
||||
obj = create_dir_obj( fd, access, mode );
|
||||
@@ -580,7 +623,7 @@ int set_file_sd( struct object *obj, struct fd *fd, const struct security_descri
|
||||
unsigned int set_info )
|
||||
{
|
||||
int unix_fd = get_unix_fd( fd );
|
||||
- const SID *owner;
|
||||
+ const SID *owner, *group;
|
||||
struct stat st;
|
||||
mode_t mode;
|
||||
|
||||
@@ -604,6 +647,24 @@ int set_file_sd( struct object *obj, struct fd *fd, const struct security_descri
|
||||
else
|
||||
owner = token_get_user( current->process->token );
|
||||
|
||||
+ if (set_info & GROUP_SECURITY_INFORMATION)
|
||||
+ {
|
||||
+ group = sd_get_group( sd );
|
||||
+ if (!group)
|
||||
+ {
|
||||
+ set_error( STATUS_INVALID_SECURITY_DESCR );
|
||||
+ return 0;
|
||||
+ }
|
||||
+ if (!obj->sd || !security_equal_sid( group, sd_get_group( obj->sd ) ))
|
||||
+ {
|
||||
+ /* FIXME: get Unix uid and call fchown */
|
||||
+ }
|
||||
+ }
|
||||
+ else if (obj->sd)
|
||||
+ group = sd_get_group( obj->sd );
|
||||
+ else
|
||||
+ group = token_get_primary_group( current->process->token );
|
||||
+
|
||||
/* group and sacl not supported */
|
||||
|
||||
if (set_info & DACL_SECURITY_INFORMATION)
|
||||
@@ -612,7 +673,7 @@ int set_file_sd( struct object *obj, struct fd *fd, const struct security_descri
|
||||
mode = st.st_mode & (S_ISUID|S_ISGID|S_ISVTX);
|
||||
mode |= sd_to_mode( sd, owner );
|
||||
|
||||
- set_xattr_sd( unix_fd, sd );
|
||||
+ set_xattr_sd( unix_fd, sd, owner, group );
|
||||
|
||||
if (((st.st_mode ^ mode) & (S_IRWXU|S_IRWXG|S_IRWXO)) && fchmod( unix_fd, mode ) == -1)
|
||||
{
|
||||
--
|
||||
1.7.9.5
|
||||
|
@ -0,0 +1,258 @@
|
||||
From 7a54a4e7c856d5df1075b55eaa823c9c1826fd0b Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Mon, 30 Mar 2015 12:50:21 +0200
|
||||
Subject: server: Temporarily store the full security descriptor for file
|
||||
objects.
|
||||
|
||||
---
|
||||
dlls/advapi32/tests/security.c | 15 +++----
|
||||
server/change.c | 8 +++-
|
||||
server/file.c | 88 ++++++++++++++++++++++++++++--------------
|
||||
server/file.h | 3 +-
|
||||
4 files changed, 74 insertions(+), 40 deletions(-)
|
||||
|
||||
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
|
||||
index a0532f6..f7ae089 100644
|
||||
--- a/dlls/advapi32/tests/security.c
|
||||
+++ b/dlls/advapi32/tests/security.c
|
||||
@@ -3311,7 +3311,6 @@ static void test_CreateDirectoryA(void)
|
||||
ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n", error);
|
||||
bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
|
||||
ok(bret, "GetAclInformation failed\n");
|
||||
- todo_wine
|
||||
ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%d != 0).\n",
|
||||
acl_size.AceCount);
|
||||
LocalFree(pSD);
|
||||
@@ -3387,7 +3386,6 @@ static void test_CreateDirectoryA(void)
|
||||
ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n", error);
|
||||
bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
|
||||
ok(bret, "GetAclInformation failed\n");
|
||||
- todo_wine
|
||||
ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%d != 0).\n",
|
||||
acl_size.AceCount);
|
||||
LocalFree(pSD);
|
||||
@@ -3533,7 +3531,6 @@ static void test_CreateDirectoryA(void)
|
||||
ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n", error);
|
||||
bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
|
||||
ok(bret, "GetAclInformation failed\n");
|
||||
- todo_wine
|
||||
ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%d != 0).\n",
|
||||
acl_size.AceCount);
|
||||
LocalFree(pSD);
|
||||
@@ -4501,22 +4498,22 @@ static void test_GetSecurityInfo(void)
|
||||
bret = pGetAce(pDacl, 0, (VOID **)&ace);
|
||||
ok(bret, "Failed to get Current User ACE.\n");
|
||||
bret = EqualSid(&ace->SidStart, user_sid);
|
||||
- todo_wine ok(bret, "Current User ACE != Current User SID.\n");
|
||||
+ ok(bret, "Current User ACE != Current User SID.\n");
|
||||
ok(((ACE_HEADER *)ace)->AceFlags == 0,
|
||||
"Current User ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
|
||||
- ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n",
|
||||
- ace->Mask);
|
||||
+ todo_wine ok(ace->Mask == 0x1f01ff,
|
||||
+ "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask);
|
||||
}
|
||||
if (acl_size.AceCount > 1)
|
||||
{
|
||||
bret = pGetAce(pDacl, 1, (VOID **)&ace);
|
||||
ok(bret, "Failed to get Administators Group ACE.\n");
|
||||
bret = EqualSid(&ace->SidStart, admin_sid);
|
||||
- todo_wine ok(bret, "Administators Group ACE != Administators Group SID.\n");
|
||||
+ ok(bret, "Administators Group ACE != Administators Group SID.\n");
|
||||
ok(((ACE_HEADER *)ace)->AceFlags == 0,
|
||||
"Administators Group ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
|
||||
- ok(ace->Mask == 0x1f01ff, "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n",
|
||||
- ace->Mask);
|
||||
+ todo_wine ok(ace->Mask == 0x1f01ff,
|
||||
+ "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask);
|
||||
}
|
||||
LocalFree(pSD);
|
||||
CloseHandle(obj);
|
||||
diff --git a/server/change.c b/server/change.c
|
||||
index 29a48b3..87b45f8 100644
|
||||
--- a/server/change.c
|
||||
+++ b/server/change.c
|
||||
@@ -1020,7 +1020,8 @@ static int dir_add_to_existing_notify( struct dir *dir )
|
||||
|
||||
#endif /* USE_INOTIFY */
|
||||
|
||||
-struct object *create_dir_obj( struct fd *fd, unsigned int access, mode_t mode )
|
||||
+struct object *create_dir_obj( struct fd *fd, unsigned int access, mode_t mode,
|
||||
+ const struct security_descriptor *sd )
|
||||
{
|
||||
struct dir *dir;
|
||||
|
||||
@@ -1039,6 +1040,11 @@ struct object *create_dir_obj( struct fd *fd, unsigned int access, mode_t mode )
|
||||
dir->uid = ~(uid_t)0;
|
||||
set_fd_user( fd, &dir_fd_ops, &dir->obj );
|
||||
|
||||
+ if (sd) dir_set_sd( &dir->obj, sd, OWNER_SECURITY_INFORMATION |
|
||||
+ GROUP_SECURITY_INFORMATION |
|
||||
+ DACL_SECURITY_INFORMATION |
|
||||
+ SACL_SECURITY_INFORMATION );
|
||||
+
|
||||
dir_add_to_existing_notify( dir );
|
||||
|
||||
return &dir->obj;
|
||||
diff --git a/server/file.c b/server/file.c
|
||||
index 58906c0..1b16526 100644
|
||||
--- a/server/file.c
|
||||
+++ b/server/file.c
|
||||
@@ -168,7 +168,8 @@ struct file *create_file_for_fd_obj( struct fd *fd, unsigned int access, unsigne
|
||||
return file;
|
||||
}
|
||||
|
||||
-static struct object *create_file_obj( struct fd *fd, unsigned int access, mode_t mode )
|
||||
+static struct object *create_file_obj( struct fd *fd, unsigned int access, mode_t mode,
|
||||
+ const struct security_descriptor *sd )
|
||||
{
|
||||
struct file *file = alloc_object( &file_ops );
|
||||
|
||||
@@ -179,6 +180,12 @@ static struct object *create_file_obj( struct fd *fd, unsigned int access, mode_
|
||||
file->fd = fd;
|
||||
grab_object( fd );
|
||||
set_fd_user( fd, &file_fd_ops, &file->obj );
|
||||
+
|
||||
+ if (sd) file_set_sd( &file->obj, sd, OWNER_SECURITY_INFORMATION |
|
||||
+ GROUP_SECURITY_INFORMATION |
|
||||
+ DACL_SECURITY_INFORMATION |
|
||||
+ SACL_SECURITY_INFORMATION );
|
||||
+
|
||||
return &file->obj;
|
||||
}
|
||||
|
||||
@@ -245,11 +252,11 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
|
||||
if (!fd) goto done;
|
||||
|
||||
if (S_ISDIR(mode))
|
||||
- obj = create_dir_obj( fd, access, mode );
|
||||
+ obj = create_dir_obj( fd, access, mode, sd );
|
||||
else if (S_ISCHR(mode) && is_serial_fd( fd ))
|
||||
obj = create_serial( fd );
|
||||
else
|
||||
- obj = create_file_obj( fd, access, mode );
|
||||
+ obj = create_file_obj( fd, access, mode, sd );
|
||||
|
||||
release_object( fd );
|
||||
|
||||
@@ -557,46 +564,66 @@ mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner )
|
||||
int set_file_sd( struct object *obj, struct fd *fd, mode_t *mode, uid_t *uid,
|
||||
const struct security_descriptor *sd, unsigned int set_info )
|
||||
{
|
||||
+ struct security_descriptor *new_sd;
|
||||
int unix_fd = get_unix_fd( fd );
|
||||
- const SID *owner;
|
||||
+ const SID *owner, *group;
|
||||
struct stat st;
|
||||
mode_t new_mode;
|
||||
|
||||
- if (unix_fd == -1 || fstat( unix_fd, &st ) == -1) return 1;
|
||||
+ if (!set_info || unix_fd == -1 || fstat( unix_fd, &st ) == -1) return 1;
|
||||
+ if (!obj->sd) get_file_sd( obj, fd, mode, uid );
|
||||
|
||||
- if (set_info & OWNER_SECURITY_INFORMATION)
|
||||
+ /* calculate the new sd, save to a temporary variable before assigning */
|
||||
+ new_sd = set_sd_from_token_internal( sd, obj->sd, set_info, current->process->token );
|
||||
+ if (new_sd)
|
||||
{
|
||||
- owner = sd_get_owner( sd );
|
||||
- if (!owner)
|
||||
+ if (set_info & OWNER_SECURITY_INFORMATION)
|
||||
{
|
||||
- set_error( STATUS_INVALID_SECURITY_DESCR );
|
||||
- return 0;
|
||||
+ owner = sd_get_owner( new_sd );
|
||||
+ assert( owner );
|
||||
+
|
||||
+ if (!obj->sd || !security_equal_sid( owner, sd_get_owner( obj->sd ) ))
|
||||
+ {
|
||||
+ /* FIXME: get Unix uid and call fchown */
|
||||
+ }
|
||||
}
|
||||
- if (!obj->sd || !security_equal_sid( owner, sd_get_owner( obj->sd ) ))
|
||||
+
|
||||
+ if (set_info & GROUP_SECURITY_INFORMATION)
|
||||
{
|
||||
- /* FIXME: get Unix uid and call fchown */
|
||||
+ group = sd_get_group( new_sd );
|
||||
+ assert( group );
|
||||
+
|
||||
+ if (!obj->sd || !security_equal_sid( group, sd_get_group( obj->sd ) ))
|
||||
+ {
|
||||
+ /* FIXME: get Unix uid and call fchown */
|
||||
+ }
|
||||
}
|
||||
- }
|
||||
- else if (obj->sd)
|
||||
- owner = sd_get_owner( obj->sd );
|
||||
- else
|
||||
- owner = token_get_user( current->process->token );
|
||||
|
||||
- /* group and sacl not supported */
|
||||
+ if (set_info & DACL_SECURITY_INFORMATION)
|
||||
+ {
|
||||
+ owner = sd_get_owner( new_sd );
|
||||
+ assert( owner );
|
||||
|
||||
- if (set_info & DACL_SECURITY_INFORMATION)
|
||||
- {
|
||||
- /* keep the bits that we don't map to access rights in the ACL */
|
||||
- new_mode = st.st_mode & (S_ISUID|S_ISGID|S_ISVTX);
|
||||
- new_mode |= sd_to_mode( sd, owner );
|
||||
+ /* keep the bits that we don't map to access rights in the ACL */
|
||||
+ new_mode = st.st_mode & (S_ISUID|S_ISGID|S_ISVTX);
|
||||
+ new_mode |= sd_to_mode( new_sd, owner );
|
||||
|
||||
- if (((st.st_mode ^ new_mode) & (S_IRWXU|S_IRWXG|S_IRWXO)) && fchmod( unix_fd, new_mode ) == -1)
|
||||
- {
|
||||
- file_set_error();
|
||||
- return 0;
|
||||
+ if (((st.st_mode ^ new_mode) & (S_IRWXU|S_IRWXG|S_IRWXO)) && fchmod( unix_fd, new_mode ) == -1)
|
||||
+ {
|
||||
+ free( new_sd );
|
||||
+ file_set_error();
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ *mode = new_mode;
|
||||
}
|
||||
+
|
||||
+ free( obj->sd );
|
||||
+ obj->sd = new_sd;
|
||||
+ return 1;
|
||||
}
|
||||
- return 1;
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static int file_set_sd( struct object *obj, const struct security_descriptor *sd,
|
||||
@@ -709,7 +736,10 @@ DECL_HANDLER(create_file)
|
||||
if ((file = create_file( root_fd, name, name_len, req->access, req->sharing,
|
||||
req->create, req->options, req->attrs, sd )))
|
||||
{
|
||||
- reply->handle = alloc_handle( current->process, file, req->access, req->attributes );
|
||||
+ if (get_error() == STATUS_OBJECT_NAME_EXISTS)
|
||||
+ reply->handle = alloc_handle( current->process, file, req->access, req->attributes );
|
||||
+ else
|
||||
+ reply->handle = alloc_handle_no_access_check( current->process, file, req->access, req->attributes );
|
||||
release_object( file );
|
||||
}
|
||||
if (root_fd) release_object( root_fd );
|
||||
diff --git a/server/file.h b/server/file.h
|
||||
index c866312..16883b2 100644
|
||||
--- a/server/file.h
|
||||
+++ b/server/file.h
|
||||
@@ -142,7 +142,8 @@ extern int get_page_size(void);
|
||||
|
||||
extern void do_change_notify( int unix_fd );
|
||||
extern void sigio_callback(void);
|
||||
-extern struct object *create_dir_obj( struct fd *fd, unsigned int access, mode_t mode );
|
||||
+extern struct object *create_dir_obj( struct fd *fd, unsigned int access, mode_t mode,
|
||||
+ const struct security_descriptor *sd );
|
||||
extern struct dir *get_dir_obj( struct process *process, obj_handle_t handle, unsigned int access );
|
||||
|
||||
/* completion */
|
||||
--
|
||||
2.3.5
|
||||
|
@ -1,213 +0,0 @@
|
||||
From fabc68cb1fd383d6f4eb31885a7aafbc572198af Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Fri, 18 Apr 2014 14:01:35 -0600
|
||||
Subject: server: Retrieve file security attributes with extended file
|
||||
attributes. (try 7)
|
||||
|
||||
---
|
||||
dlls/advapi32/tests/security.c | 61 +++++++++++++++++++++++++-----------------
|
||||
server/file.c | 26 +++++++++++++++---
|
||||
2 files changed, 59 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
|
||||
index d13e54d..29daf60 100644
|
||||
--- a/dlls/advapi32/tests/security.c
|
||||
+++ b/dlls/advapi32/tests/security.c
|
||||
@@ -3109,7 +3109,7 @@ static void get_nt_pathW(const char *name, UNICODE_STRING *nameW)
|
||||
}
|
||||
|
||||
static void test_inherited_dacl(PACL dacl, PSID admin_sid, PSID user_sid, DWORD flags, DWORD mask,
|
||||
- BOOL todo_count, BOOL todo_sid, BOOL todo_flags, int line)
|
||||
+ BOOL todo_count, BOOL todo_sid, BOOL todo_flags, BOOL todo_mask, int line)
|
||||
{
|
||||
ACL_SIZE_INFORMATION acl_size;
|
||||
ACCESS_ALLOWED_ACE *ace;
|
||||
@@ -3150,9 +3150,15 @@ static void test_inherited_dacl(PACL dacl, PSID admin_sid, PSID user_sid, DWORD
|
||||
"Current User ACE has unexpected flags (0x%x != 0x%x)\n",
|
||||
((ACE_HEADER *)ace)->AceFlags, flags);
|
||||
|
||||
- ok_(__FILE__, line)(ace->Mask == mask,
|
||||
- "Current User ACE has unexpected mask (0x%x != 0x%x)\n",
|
||||
- ace->Mask, mask);
|
||||
+ if (todo_mask)
|
||||
+ todo_wine
|
||||
+ ok_(__FILE__, line)(ace->Mask == mask,
|
||||
+ "Current User ACE has unexpected mask (0x%x != 0x%x)\n",
|
||||
+ ace->Mask, mask);
|
||||
+ else
|
||||
+ ok_(__FILE__, line)(ace->Mask == mask,
|
||||
+ "Current User ACE has unexpected mask (0x%x != 0x%x)\n",
|
||||
+ ace->Mask, mask);
|
||||
}
|
||||
if (acl_size.AceCount > 1)
|
||||
{
|
||||
@@ -3176,9 +3182,15 @@ static void test_inherited_dacl(PACL dacl, PSID admin_sid, PSID user_sid, DWORD
|
||||
"Administators Group ACE has unexpected flags (0x%x != 0x%x)\n",
|
||||
((ACE_HEADER *)ace)->AceFlags, flags);
|
||||
|
||||
- ok_(__FILE__, line)(ace->Mask == mask,
|
||||
- "Administators Group ACE has unexpected mask (0x%x != 0x%x)\n",
|
||||
- ace->Mask, mask);
|
||||
+ if (todo_mask)
|
||||
+ todo_wine
|
||||
+ ok_(__FILE__, line)(ace->Mask == mask,
|
||||
+ "Administators Group ACE has unexpected mask (0x%x != 0x%x)\n",
|
||||
+ ace->Mask, mask);
|
||||
+ else
|
||||
+ ok_(__FILE__, line)(ace->Mask == mask,
|
||||
+ "Administators Group ACE has unexpected mask (0x%x != 0x%x)\n",
|
||||
+ ace->Mask, mask);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3262,7 +3274,7 @@ static void test_CreateDirectoryA(void)
|
||||
}
|
||||
ok(!error, "GetNamedSecurityInfo failed with error %d\n", error);
|
||||
test_inherited_dacl(pDacl, admin_sid, user_sid, OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE,
|
||||
- 0x1f01ff, FALSE, TRUE, FALSE, __LINE__);
|
||||
+ 0x1f01ff, FALSE, FALSE, FALSE, TRUE, __LINE__);
|
||||
LocalFree(pSD);
|
||||
|
||||
/* Test inheritance of ACLs in CreateFile without security descriptor */
|
||||
@@ -3278,7 +3290,7 @@ static void test_CreateDirectoryA(void)
|
||||
(PSID *)&owner, NULL, &pDacl, NULL, &pSD);
|
||||
ok(error == ERROR_SUCCESS, "Failed to get permissions on file\n");
|
||||
test_inherited_dacl(pDacl, admin_sid, user_sid, INHERITED_ACE,
|
||||
- 0x1f01ff, TRUE, TRUE, TRUE, __LINE__);
|
||||
+ 0x1f01ff, TRUE, TRUE, TRUE, FALSE, __LINE__);
|
||||
LocalFree(pSD);
|
||||
CloseHandle(hTemp);
|
||||
|
||||
@@ -3348,7 +3360,7 @@ static void test_CreateDirectoryA(void)
|
||||
(PSID *)&owner, NULL, &pDacl, NULL, &pSD);
|
||||
ok(error == ERROR_SUCCESS, "Failed to get permissions on file\n");
|
||||
test_inherited_dacl(pDacl, admin_sid, user_sid, INHERITED_ACE,
|
||||
- 0x1f01ff, TRUE, TRUE, TRUE, __LINE__);
|
||||
+ 0x1f01ff, TRUE, TRUE, TRUE, FALSE, __LINE__);
|
||||
LocalFree(pSD);
|
||||
CloseHandle(hTemp);
|
||||
|
||||
@@ -3414,7 +3426,7 @@ static void test_CreateDirectoryA(void)
|
||||
ok(error == ERROR_SUCCESS, "Failed to get permissions on file\n");
|
||||
test_inherited_dacl(pDacl, admin_sid, user_sid,
|
||||
OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERITED_ACE,
|
||||
- 0x1f01ff, TRUE, TRUE, TRUE, __LINE__);
|
||||
+ 0x1f01ff, TRUE, TRUE, TRUE, FALSE, __LINE__);
|
||||
LocalFree(pSD);
|
||||
bret = RemoveDirectoryA(tmpfile);
|
||||
ok(bret == TRUE, "RemoveDirectoryA failed with error %u\n", GetLastError());
|
||||
@@ -3495,7 +3507,7 @@ static void test_CreateDirectoryA(void)
|
||||
ok(error == ERROR_SUCCESS, "Failed to get permissions on file\n");
|
||||
test_inherited_dacl(pDacl, admin_sid, user_sid,
|
||||
OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERITED_ACE,
|
||||
- 0x1f01ff, TRUE, TRUE, TRUE, __LINE__);
|
||||
+ 0x1f01ff, TRUE, TRUE, TRUE, FALSE, __LINE__);
|
||||
LocalFree(pSD);
|
||||
CloseHandle(hTemp);
|
||||
|
||||
@@ -3719,23 +3731,22 @@ static void test_GetNamedSecurityInfoA(void)
|
||||
bret = pGetAce(pDacl, 0, (VOID **)&ace);
|
||||
ok(bret, "Failed to get Current User ACE.\n");
|
||||
bret = EqualSid(&ace->SidStart, user_sid);
|
||||
- todo_wine ok(bret, "Current User ACE != Current User SID.\n");
|
||||
+ ok(bret, "Current User ACE != Current User SID.\n");
|
||||
ok(((ACE_HEADER *)ace)->AceFlags == 0,
|
||||
"Current User ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
|
||||
- ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n",
|
||||
- ace->Mask);
|
||||
+ todo_wine ok(ace->Mask == 0x1f01ff,
|
||||
+ "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask);
|
||||
}
|
||||
if (acl_size.AceCount > 1)
|
||||
{
|
||||
bret = pGetAce(pDacl, 1, (VOID **)&ace);
|
||||
ok(bret, "Failed to get Administators Group ACE.\n");
|
||||
bret = EqualSid(&ace->SidStart, admin_sid);
|
||||
- todo_wine ok(bret || broken(!bret) /* win2k */,
|
||||
- "Administators Group ACE != Administators Group SID.\n");
|
||||
+ ok(bret || broken(!bret) /* win2k */, "Administators Group ACE != Administators Group SID.\n");
|
||||
ok(((ACE_HEADER *)ace)->AceFlags == 0,
|
||||
"Administators Group ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
|
||||
- ok(ace->Mask == 0x1f01ff || broken(ace->Mask == GENERIC_ALL) /* win2k */,
|
||||
- "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask);
|
||||
+ todo_wine ok(ace->Mask == 0x1f01ff || broken(ace->Mask == GENERIC_ALL) /* win2k */,
|
||||
+ "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask);
|
||||
}
|
||||
LocalFree(pSD);
|
||||
HeapFree(GetProcessHeap(), 0, user);
|
||||
@@ -4385,22 +4396,22 @@ static void test_GetSecurityInfo(void)
|
||||
bret = pGetAce(pDacl, 0, (VOID **)&ace);
|
||||
ok(bret, "Failed to get Current User ACE.\n");
|
||||
bret = EqualSid(&ace->SidStart, user_sid);
|
||||
- todo_wine ok(bret, "Current User ACE != Current User SID.\n");
|
||||
+ ok(bret, "Current User ACE != Current User SID.\n");
|
||||
ok(((ACE_HEADER *)ace)->AceFlags == 0,
|
||||
"Current User ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
|
||||
- ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n",
|
||||
- ace->Mask);
|
||||
+ todo_wine ok(ace->Mask == 0x1f01ff,
|
||||
+ "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask);
|
||||
}
|
||||
if (acl_size.AceCount > 1)
|
||||
{
|
||||
bret = pGetAce(pDacl, 1, (VOID **)&ace);
|
||||
ok(bret, "Failed to get Administators Group ACE.\n");
|
||||
bret = EqualSid(&ace->SidStart, admin_sid);
|
||||
- todo_wine ok(bret, "Administators Group ACE != Administators Group SID.\n");
|
||||
+ ok(bret, "Administators Group ACE != Administators Group SID.\n");
|
||||
ok(((ACE_HEADER *)ace)->AceFlags == 0,
|
||||
"Administators Group ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
|
||||
- ok(ace->Mask == 0x1f01ff, "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n",
|
||||
- ace->Mask);
|
||||
+ todo_wine ok(ace->Mask == 0x1f01ff,
|
||||
+ "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask);
|
||||
}
|
||||
LocalFree(pSD);
|
||||
CloseHandle(obj);
|
||||
diff --git a/server/file.c b/server/file.c
|
||||
index 07971a1..828bd86 100644
|
||||
--- a/server/file.c
|
||||
+++ b/server/file.c
|
||||
@@ -503,6 +503,25 @@ struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID
|
||||
return sd;
|
||||
}
|
||||
|
||||
+struct security_descriptor *get_xattr_sd( int fd )
|
||||
+{
|
||||
+ struct security_descriptor *sd;
|
||||
+ char buffer[XATTR_SIZE_MAX];
|
||||
+ int n;
|
||||
+
|
||||
+ n = xattr_fget( fd, WINE_XATTR_SD, buffer, sizeof(buffer) );
|
||||
+ if (n == -1 || n < 2 + sizeof(struct security_descriptor)) return NULL;
|
||||
+
|
||||
+ /* validate that we can handle the descriptor */
|
||||
+ if (buffer[0] != SECURITY_DESCRIPTOR_REVISION || buffer[1] != 0 ||
|
||||
+ !sd_is_valid( (struct security_descriptor *)&buffer[2], n - 2 ))
|
||||
+ return NULL;
|
||||
+
|
||||
+ sd = mem_alloc( n - 2 );
|
||||
+ if (sd) memcpy( sd, &buffer[2], n - 2 );
|
||||
+ return sd;
|
||||
+}
|
||||
+
|
||||
struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode_t *mode,
|
||||
uid_t *uid )
|
||||
{
|
||||
@@ -518,9 +537,10 @@ struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode
|
||||
(st.st_uid == *uid))
|
||||
return obj->sd;
|
||||
|
||||
- sd = mode_to_sd( st.st_mode,
|
||||
- security_unix_uid_to_sid( st.st_uid ),
|
||||
- token_get_primary_group( current->process->token ));
|
||||
+ sd = get_xattr_sd( unix_fd );
|
||||
+ if (!sd) sd = mode_to_sd( st.st_mode,
|
||||
+ security_unix_uid_to_sid( st.st_uid ),
|
||||
+ token_get_primary_group( current->process->token ));
|
||||
if (!sd) return obj->sd;
|
||||
|
||||
*mode = st.st_mode;
|
||||
--
|
||||
2.3.3
|
||||
|
@ -1,12 +1,12 @@
|
||||
From 687e5f2a153a1fbbac2631bea088b0237f2d4a20 Mon Sep 17 00:00:00 2001
|
||||
From 03d4a144839cf0432612f3f031fce1725dacab4b Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Fri, 18 Apr 2014 15:34:47 -0600
|
||||
Subject: server: Store file security attributes with extended file
|
||||
attributes. (try 7)
|
||||
Date: Mon, 30 Mar 2015 13:04:23 +0200
|
||||
Subject: server: Store file security attributes with extended file attributes.
|
||||
(v8)
|
||||
|
||||
---
|
||||
include/wine/port.h | 3 +++
|
||||
server/file.c | 34 ++++++++++++++++++++++++++++++++++
|
||||
include/wine/port.h | 3 +++
|
||||
server/file.c | 34 ++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 37 insertions(+)
|
||||
|
||||
diff --git a/include/wine/port.h b/include/wine/port.h
|
||||
@ -24,7 +24,7 @@ index 9e2b8165..71be265 100644
|
||||
extern int xattr_fget( int filedes, const char *name, void *value, size_t size );
|
||||
extern int xattr_fremove( int filedes, const char *name );
|
||||
diff --git a/server/file.c b/server/file.c
|
||||
index 1f008ea..502951c 100644
|
||||
index 1b16526..ed7ddfc 100644
|
||||
--- a/server/file.c
|
||||
+++ b/server/file.c
|
||||
@@ -32,6 +32,7 @@
|
||||
@ -50,11 +50,11 @@ index 1f008ea..502951c 100644
|
||||
struct file
|
||||
{
|
||||
struct object obj; /* object header */
|
||||
@@ -178,6 +187,28 @@ static struct object *create_file_obj( struct fd *fd, unsigned int access, mode_
|
||||
@@ -189,6 +198,28 @@ static struct object *create_file_obj( struct fd *fd, unsigned int access, mode_
|
||||
return &file->obj;
|
||||
}
|
||||
|
||||
+void set_xattr_sd( int fd, const struct security_descriptor *sd )
|
||||
+static void set_xattr_sd( int fd, const struct security_descriptor *sd )
|
||||
+{
|
||||
+ char buffer[XATTR_SIZE_MAX];
|
||||
+ int present, len;
|
||||
@ -65,8 +65,8 @@ index 1f008ea..502951c 100644
|
||||
+ dacl = sd_get_dacl( sd, &present );
|
||||
+ if (!present || !dacl) return;
|
||||
+
|
||||
+ len = 2 + sizeof(struct security_descriptor) + sd->owner_len + sd->group_len + sd->sacl_len
|
||||
+ + sd->dacl_len;
|
||||
+ len = 2 + sizeof(struct security_descriptor) + sd->owner_len +
|
||||
+ sd->group_len + sd->sacl_len + sd->dacl_len;
|
||||
+ if (len > XATTR_SIZE_MAX) return;
|
||||
+
|
||||
+ /* include the descriptor revision and resource manager control bits */
|
||||
@ -79,23 +79,16 @@ index 1f008ea..502951c 100644
|
||||
static struct object *create_file( struct fd *root, const char *nameptr, data_size_t len,
|
||||
unsigned int access, unsigned int sharing, int create,
|
||||
unsigned int options, unsigned int attrs,
|
||||
@@ -239,6 +270,7 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
|
||||
/* FIXME: should set error to STATUS_OBJECT_NAME_COLLISION if file existed before */
|
||||
fd = open_fd( root, name, flags | O_NONBLOCK | O_LARGEFILE, &mode, access, sharing, options );
|
||||
if (!fd) goto done;
|
||||
+ set_xattr_sd( get_unix_fd( fd ), sd );
|
||||
@@ -618,6 +649,9 @@ int set_file_sd( struct object *obj, struct fd *fd, mode_t *mode, uid_t *uid,
|
||||
*mode = new_mode;
|
||||
}
|
||||
|
||||
if (S_ISDIR(mode))
|
||||
obj = create_dir_obj( fd, access, mode );
|
||||
@@ -580,6 +612,8 @@ int set_file_sd( struct object *obj, struct fd *fd, const struct security_descri
|
||||
mode = st.st_mode & (S_ISUID|S_ISGID|S_ISVTX);
|
||||
mode |= sd_to_mode( sd, owner );
|
||||
|
||||
+ set_xattr_sd( unix_fd, sd );
|
||||
+ /* extended attributes are set after the file mode, to ensure it stays in sync */
|
||||
+ set_xattr_sd( unix_fd, new_sd );
|
||||
+
|
||||
if (((st.st_mode ^ mode) & (S_IRWXU|S_IRWXG|S_IRWXO)) && fchmod( unix_fd, mode ) == -1)
|
||||
{
|
||||
file_set_error();
|
||||
free( obj->sd );
|
||||
obj->sd = new_sd;
|
||||
return 1;
|
||||
--
|
||||
1.7.9.5
|
||||
2.3.5
|
||||
|
@ -1,111 +1,19 @@
|
||||
From 0538266bd0f5f7c181b483da803dc6b84d53ec48 Mon Sep 17 00:00:00 2001
|
||||
From 5c19cb0685dd47e7eb36dce9729200b79da61b11 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Fri, 18 Apr 2014 14:05:32 -0600
|
||||
Subject: server: Convert return of file security masks with generic access
|
||||
mappings. (try 7)
|
||||
|
||||
---
|
||||
dlls/advapi32/tests/security.c | 52 ++++++++++++++++--------------------------
|
||||
server/file.c | 22 ++++++++++++++++++
|
||||
2 files changed, 42 insertions(+), 32 deletions(-)
|
||||
dlls/advapi32/tests/security.c | 6 +++---
|
||||
server/file.c | 23 +++++++++++++++++++++++
|
||||
2 files changed, 26 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
|
||||
index 29daf60..4db46f5 100644
|
||||
index f7ae089..0013c3c 100644
|
||||
--- a/dlls/advapi32/tests/security.c
|
||||
+++ b/dlls/advapi32/tests/security.c
|
||||
@@ -3109,7 +3109,7 @@ static void get_nt_pathW(const char *name, UNICODE_STRING *nameW)
|
||||
}
|
||||
|
||||
static void test_inherited_dacl(PACL dacl, PSID admin_sid, PSID user_sid, DWORD flags, DWORD mask,
|
||||
- BOOL todo_count, BOOL todo_sid, BOOL todo_flags, BOOL todo_mask, int line)
|
||||
+ BOOL todo_count, BOOL todo_sid, BOOL todo_flags, int line)
|
||||
{
|
||||
ACL_SIZE_INFORMATION acl_size;
|
||||
ACCESS_ALLOWED_ACE *ace;
|
||||
@@ -3150,15 +3150,9 @@ static void test_inherited_dacl(PACL dacl, PSID admin_sid, PSID user_sid, DWORD
|
||||
"Current User ACE has unexpected flags (0x%x != 0x%x)\n",
|
||||
((ACE_HEADER *)ace)->AceFlags, flags);
|
||||
|
||||
- if (todo_mask)
|
||||
- todo_wine
|
||||
- ok_(__FILE__, line)(ace->Mask == mask,
|
||||
- "Current User ACE has unexpected mask (0x%x != 0x%x)\n",
|
||||
- ace->Mask, mask);
|
||||
- else
|
||||
- ok_(__FILE__, line)(ace->Mask == mask,
|
||||
- "Current User ACE has unexpected mask (0x%x != 0x%x)\n",
|
||||
- ace->Mask, mask);
|
||||
+ ok_(__FILE__, line)(ace->Mask == mask,
|
||||
+ "Current User ACE has unexpected mask (0x%x != 0x%x)\n",
|
||||
+ ace->Mask, mask);
|
||||
}
|
||||
if (acl_size.AceCount > 1)
|
||||
{
|
||||
@@ -3182,15 +3176,9 @@ static void test_inherited_dacl(PACL dacl, PSID admin_sid, PSID user_sid, DWORD
|
||||
"Administators Group ACE has unexpected flags (0x%x != 0x%x)\n",
|
||||
((ACE_HEADER *)ace)->AceFlags, flags);
|
||||
|
||||
- if (todo_mask)
|
||||
- todo_wine
|
||||
- ok_(__FILE__, line)(ace->Mask == mask,
|
||||
- "Administators Group ACE has unexpected mask (0x%x != 0x%x)\n",
|
||||
- ace->Mask, mask);
|
||||
- else
|
||||
- ok_(__FILE__, line)(ace->Mask == mask,
|
||||
- "Administators Group ACE has unexpected mask (0x%x != 0x%x)\n",
|
||||
- ace->Mask, mask);
|
||||
+ ok_(__FILE__, line)(ace->Mask == mask,
|
||||
+ "Administators Group ACE has unexpected mask (0x%x != 0x%x)\n",
|
||||
+ ace->Mask, mask);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3274,7 +3262,7 @@ static void test_CreateDirectoryA(void)
|
||||
}
|
||||
ok(!error, "GetNamedSecurityInfo failed with error %d\n", error);
|
||||
test_inherited_dacl(pDacl, admin_sid, user_sid, OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE,
|
||||
- 0x1f01ff, FALSE, FALSE, FALSE, TRUE, __LINE__);
|
||||
+ 0x1f01ff, FALSE, FALSE, FALSE, __LINE__);
|
||||
LocalFree(pSD);
|
||||
|
||||
/* Test inheritance of ACLs in CreateFile without security descriptor */
|
||||
@@ -3290,7 +3278,7 @@ static void test_CreateDirectoryA(void)
|
||||
(PSID *)&owner, NULL, &pDacl, NULL, &pSD);
|
||||
ok(error == ERROR_SUCCESS, "Failed to get permissions on file\n");
|
||||
test_inherited_dacl(pDacl, admin_sid, user_sid, INHERITED_ACE,
|
||||
- 0x1f01ff, TRUE, TRUE, TRUE, FALSE, __LINE__);
|
||||
+ 0x1f01ff, TRUE, TRUE, TRUE, __LINE__);
|
||||
LocalFree(pSD);
|
||||
CloseHandle(hTemp);
|
||||
|
||||
@@ -3360,7 +3348,7 @@ static void test_CreateDirectoryA(void)
|
||||
(PSID *)&owner, NULL, &pDacl, NULL, &pSD);
|
||||
ok(error == ERROR_SUCCESS, "Failed to get permissions on file\n");
|
||||
test_inherited_dacl(pDacl, admin_sid, user_sid, INHERITED_ACE,
|
||||
- 0x1f01ff, TRUE, TRUE, TRUE, FALSE, __LINE__);
|
||||
+ 0x1f01ff, TRUE, TRUE, TRUE, __LINE__);
|
||||
LocalFree(pSD);
|
||||
CloseHandle(hTemp);
|
||||
|
||||
@@ -3426,7 +3414,7 @@ static void test_CreateDirectoryA(void)
|
||||
ok(error == ERROR_SUCCESS, "Failed to get permissions on file\n");
|
||||
test_inherited_dacl(pDacl, admin_sid, user_sid,
|
||||
OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERITED_ACE,
|
||||
- 0x1f01ff, TRUE, TRUE, TRUE, FALSE, __LINE__);
|
||||
+ 0x1f01ff, TRUE, TRUE, TRUE, __LINE__);
|
||||
LocalFree(pSD);
|
||||
bret = RemoveDirectoryA(tmpfile);
|
||||
ok(bret == TRUE, "RemoveDirectoryA failed with error %u\n", GetLastError());
|
||||
@@ -3507,7 +3495,7 @@ static void test_CreateDirectoryA(void)
|
||||
ok(error == ERROR_SUCCESS, "Failed to get permissions on file\n");
|
||||
test_inherited_dacl(pDacl, admin_sid, user_sid,
|
||||
OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERITED_ACE,
|
||||
- 0x1f01ff, TRUE, TRUE, TRUE, FALSE, __LINE__);
|
||||
+ 0x1f01ff, TRUE, TRUE, TRUE, __LINE__);
|
||||
LocalFree(pSD);
|
||||
CloseHandle(hTemp);
|
||||
|
||||
@@ -3734,8 +3722,8 @@ static void test_GetNamedSecurityInfoA(void)
|
||||
@@ -4501,8 +4501,8 @@ static void test_GetSecurityInfo(void)
|
||||
ok(bret, "Current User ACE != Current User SID.\n");
|
||||
ok(((ACE_HEADER *)ace)->AceFlags == 0,
|
||||
"Current User ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
|
||||
@ -116,49 +24,25 @@ index 29daf60..4db46f5 100644
|
||||
}
|
||||
if (acl_size.AceCount > 1)
|
||||
{
|
||||
@@ -3745,8 +3733,8 @@ static void test_GetNamedSecurityInfoA(void)
|
||||
ok(bret || broken(!bret) /* win2k */, "Administators Group ACE != Administators Group SID.\n");
|
||||
ok(((ACE_HEADER *)ace)->AceFlags == 0,
|
||||
"Administators Group ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
|
||||
- todo_wine ok(ace->Mask == 0x1f01ff || broken(ace->Mask == GENERIC_ALL) /* win2k */,
|
||||
- "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask);
|
||||
+ ok(ace->Mask == 0x1f01ff || broken(ace->Mask == GENERIC_ALL) /* win2k */,
|
||||
+ "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask);
|
||||
}
|
||||
LocalFree(pSD);
|
||||
HeapFree(GetProcessHeap(), 0, user);
|
||||
@@ -4399,8 +4387,8 @@ static void test_GetSecurityInfo(void)
|
||||
ok(bret, "Current User ACE != Current User SID.\n");
|
||||
ok(((ACE_HEADER *)ace)->AceFlags == 0,
|
||||
"Current User ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
|
||||
- todo_wine ok(ace->Mask == 0x1f01ff,
|
||||
- "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask);
|
||||
+ ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n",
|
||||
+ ace->Mask);
|
||||
}
|
||||
if (acl_size.AceCount > 1)
|
||||
{
|
||||
@@ -4410,8 +4398,8 @@ static void test_GetSecurityInfo(void)
|
||||
@@ -4512,7 +4512,7 @@ static void test_GetSecurityInfo(void)
|
||||
ok(bret, "Administators Group ACE != Administators Group SID.\n");
|
||||
ok(((ACE_HEADER *)ace)->AceFlags == 0,
|
||||
"Administators Group ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
|
||||
- todo_wine ok(ace->Mask == 0x1f01ff,
|
||||
- "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask);
|
||||
+ ok(ace->Mask == 0x1f01ff, "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n",
|
||||
+ ace->Mask);
|
||||
+ ok(ace->Mask == 0x1f01ff,
|
||||
"Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask);
|
||||
}
|
||||
LocalFree(pSD);
|
||||
CloseHandle(obj);
|
||||
diff --git a/server/file.c b/server/file.c
|
||||
index 828bd86..1a1ffa9 100644
|
||||
index ed7ddfc..6663927 100644
|
||||
--- a/server/file.c
|
||||
+++ b/server/file.c
|
||||
@@ -522,6 +522,27 @@ struct security_descriptor *get_xattr_sd( int fd )
|
||||
@@ -466,6 +466,26 @@ struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID
|
||||
return sd;
|
||||
}
|
||||
|
||||
+/* Convert generic rights into standard access rights */
|
||||
+void convert_generic_sd( struct security_descriptor *sd )
|
||||
+static void convert_generic_sd( struct security_descriptor *sd )
|
||||
+{
|
||||
+ const ACL *dacl;
|
||||
+ int present;
|
||||
@ -172,7 +56,6 @@ index 828bd86..1a1ffa9 100644
|
||||
+ for (i = 0; i < dacl->AceCount; i++, ace = ace_next( ace ))
|
||||
+ {
|
||||
+ DWORD *mask = (DWORD *)(ace + 1);
|
||||
+
|
||||
+ *mask = generic_file_map_access( *mask );
|
||||
+ }
|
||||
+ }
|
||||
@ -181,14 +64,16 @@ index 828bd86..1a1ffa9 100644
|
||||
struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode_t *mode,
|
||||
uid_t *uid )
|
||||
{
|
||||
@@ -538,6 +559,7 @@ struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode
|
||||
return obj->sd;
|
||||
|
||||
sd = get_xattr_sd( unix_fd );
|
||||
+ if (sd) convert_generic_sd( sd );
|
||||
if (!sd) sd = mode_to_sd( st.st_mode,
|
||||
security_unix_uid_to_sid( st.st_uid ),
|
||||
token_get_primary_group( current->process->token ));
|
||||
@@ -608,6 +628,9 @@ int set_file_sd( struct object *obj, struct fd *fd, mode_t *mode, uid_t *uid,
|
||||
new_sd = set_sd_from_token_internal( sd, obj->sd, set_info, current->process->token );
|
||||
if (new_sd)
|
||||
{
|
||||
+ /* convert generic rights into standard access rights */
|
||||
+ convert_generic_sd( new_sd );
|
||||
+
|
||||
if (set_info & OWNER_SECURITY_INFORMATION)
|
||||
{
|
||||
owner = sd_get_owner( new_sd );
|
||||
--
|
||||
2.3.3
|
||||
2.3.5
|
||||
|
||||
|
@ -0,0 +1,110 @@
|
||||
From ea6969acf3f5e79a39bb461f78b4f0785a2b8843 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Fri, 18 Apr 2014 14:01:35 -0600
|
||||
Subject: server: Retrieve file security attributes with extended file
|
||||
attributes. (try 7)
|
||||
|
||||
---
|
||||
dlls/advapi32/tests/security.c | 15 +++++++--------
|
||||
server/file.c | 30 +++++++++++++++++++++++++++---
|
||||
2 files changed, 34 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
|
||||
index 0013c3c..945542e 100644
|
||||
--- a/dlls/advapi32/tests/security.c
|
||||
+++ b/dlls/advapi32/tests/security.c
|
||||
@@ -3264,7 +3264,7 @@ static void test_CreateDirectoryA(void)
|
||||
}
|
||||
ok(!error, "GetNamedSecurityInfo failed with error %d\n", error);
|
||||
test_inherited_dacl(pDacl, admin_sid, user_sid, OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE,
|
||||
- 0x1f01ff, FALSE, TRUE, FALSE, __LINE__);
|
||||
+ 0x1f01ff, FALSE, FALSE, FALSE, __LINE__);
|
||||
LocalFree(pSD);
|
||||
|
||||
/* Test inheritance of ACLs in CreateFile without security descriptor */
|
||||
@@ -3719,19 +3719,18 @@ static void test_GetNamedSecurityInfoA(void)
|
||||
bret = pGetAce(pDacl, 0, (VOID **)&ace);
|
||||
ok(bret, "Failed to get Current User ACE.\n");
|
||||
bret = EqualSid(&ace->SidStart, user_sid);
|
||||
- todo_wine ok(bret, "Current User ACE != Current User SID.\n");
|
||||
+ ok(bret, "Current User ACE != Current User SID.\n");
|
||||
ok(((ACE_HEADER *)ace)->AceFlags == 0,
|
||||
"Current User ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
|
||||
- ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n",
|
||||
- ace->Mask);
|
||||
+ ok(ace->Mask == 0x1f01ff,
|
||||
+ "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask);
|
||||
}
|
||||
if (acl_size.AceCount > 1)
|
||||
{
|
||||
bret = pGetAce(pDacl, 1, (VOID **)&ace);
|
||||
ok(bret, "Failed to get Administators Group ACE.\n");
|
||||
bret = EqualSid(&ace->SidStart, admin_sid);
|
||||
- todo_wine ok(bret || broken(!bret) /* win2k */,
|
||||
- "Administators Group ACE != Administators Group SID.\n");
|
||||
+ ok(bret || broken(!bret) /* win2k */, "Administators Group ACE != Administators Group SID.\n");
|
||||
ok(((ACE_HEADER *)ace)->AceFlags == 0,
|
||||
"Administators Group ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
|
||||
ok(ace->Mask == 0x1f01ff || broken(ace->Mask == GENERIC_ALL) /* win2k */,
|
||||
@@ -3758,8 +3757,8 @@ static void test_GetNamedSecurityInfoA(void)
|
||||
{
|
||||
bret = pGetAce(pDacl, 0, (VOID **)&ace);
|
||||
ok(bret, "Failed to get ACE.\n");
|
||||
- todo_wine ok(((ACE_HEADER *)ace)->AceFlags & INHERITED_ACE,
|
||||
- "ACE has unexpected flags: 0x%x\n", ((ACE_HEADER *)ace)->AceFlags);
|
||||
+ ok(((ACE_HEADER *)ace)->AceFlags & INHERITED_ACE,
|
||||
+ "ACE has unexpected flags: 0x%x\n", ((ACE_HEADER *)ace)->AceFlags);
|
||||
}
|
||||
LocalFree(pSD);
|
||||
|
||||
diff --git a/server/file.c b/server/file.c
|
||||
index 6663927..8bcf6ee 100644
|
||||
--- a/server/file.c
|
||||
+++ b/server/file.c
|
||||
@@ -486,6 +486,29 @@ static void convert_generic_sd( struct security_descriptor *sd )
|
||||
}
|
||||
}
|
||||
|
||||
+static struct security_descriptor *get_xattr_sd( int fd )
|
||||
+{
|
||||
+ struct security_descriptor *sd;
|
||||
+ char buffer[XATTR_SIZE_MAX];
|
||||
+ int n;
|
||||
+
|
||||
+ n = xattr_fget( fd, WINE_XATTR_SD, buffer, sizeof(buffer) );
|
||||
+ if (n == -1 || n < 2 + sizeof(struct security_descriptor)) return NULL;
|
||||
+
|
||||
+ /* validate that we can handle the descriptor */
|
||||
+ if (buffer[0] != SECURITY_DESCRIPTOR_REVISION || buffer[1] != 0 ||
|
||||
+ !sd_is_valid( (struct security_descriptor *)&buffer[2], n - 2 ))
|
||||
+ return NULL;
|
||||
+
|
||||
+ sd = mem_alloc( n - 2 );
|
||||
+ if (sd)
|
||||
+ {
|
||||
+ memcpy( sd, &buffer[2], n - 2 );
|
||||
+ convert_generic_sd( sd ); /* for backwards compatibility */
|
||||
+ }
|
||||
+ return sd;
|
||||
+}
|
||||
+
|
||||
struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode_t *mode,
|
||||
uid_t *uid )
|
||||
{
|
||||
@@ -501,9 +524,10 @@ struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode
|
||||
(st.st_uid == *uid))
|
||||
return obj->sd;
|
||||
|
||||
- sd = mode_to_sd( st.st_mode,
|
||||
- security_unix_uid_to_sid( st.st_uid ),
|
||||
- token_get_primary_group( current->process->token ));
|
||||
+ sd = get_xattr_sd( unix_fd );
|
||||
+ if (!sd) sd = mode_to_sd( st.st_mode,
|
||||
+ security_unix_uid_to_sid( st.st_uid ),
|
||||
+ token_get_primary_group( current->process->token ));
|
||||
if (!sd) return obj->sd;
|
||||
|
||||
*mode = st.st_mode;
|
||||
--
|
||||
2.3.5
|
||||
|
@ -1,4 +1,3 @@
|
||||
Depends: advapi32-Revert_DACL
|
||||
Depends: ntdll-DOS_Attributes
|
||||
Depends: server-File_Permissions
|
||||
Fixes: [33576] Support for stored file ACLs
|
||||
|
Loading…
Reference in New Issue
Block a user