Added patch to allow to open files/directories without any access rights in order to query attributes.

This commit is contained in:
Sebastian Lackner
2015-04-03 18:36:35 +02:00
parent 70ca8ccdee
commit da14f3201a
12 changed files with 414 additions and 17 deletions

View File

@@ -0,0 +1,117 @@
From 79e9440272eed16300dc4aacc96765a24841a705 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Fri, 3 Apr 2015 03:58:47 +0200
Subject: server: Allow to open files without any permission bits. (try 2)
Changes in v2:
* As suggested by Piotr, fix the problem for both files and directories.
* Pay attention to requested access attributes - this fixes a couple more todo_wine's.
---
dlls/advapi32/tests/security.c | 32 ++++++++++++--------------------
server/fd.c | 21 +++++++++++++++++++++
2 files changed, 33 insertions(+), 20 deletions(-)
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
index 466100d..329ae09 100644
--- a/dlls/advapi32/tests/security.c
+++ b/dlls/advapi32/tests/security.c
@@ -3319,17 +3319,13 @@ static void test_CreateDirectoryA(void)
error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
(PSID *)&owner, NULL, &pDacl, NULL, &pSD);
- todo_wine
ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n", error);
- if (error == ERROR_SUCCESS)
- {
- 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);
- }
+ 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);
CloseHandle(hTemp);
/* Test inheritance of ACLs in NtCreateFile without security descriptor */
@@ -3399,17 +3395,13 @@ static void test_CreateDirectoryA(void)
error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
(PSID *)&owner, NULL, &pDacl, NULL, &pSD);
- todo_wine
ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n", error);
- if (error == ERROR_SUCCESS)
- {
- 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);
- }
+ 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);
CloseHandle(hTemp);
done:
diff --git a/server/fd.c b/server/fd.c
index e3b722c..3afb89a 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -1741,6 +1741,7 @@ struct fd *open_fd( struct fd *root, const char *name, int flags, mode_t *mode,
const char *unlink_name = "";
int root_fd = -1;
int rw_mode;
+ int do_chmod = 0;
if (((options & FILE_DELETE_ON_CLOSE) && !(access & DELETE)) ||
((options & FILE_DIRECTORY_FILE) && (flags & O_TRUNC)))
@@ -1801,16 +1802,36 @@ struct fd *open_fd( struct fd *root, const char *name, int flags, mode_t *mode,
if ((access & FILE_UNIX_WRITE_ACCESS) || (flags & O_CREAT))
fd->unix_fd = open( name, O_RDONLY | (flags & ~(O_TRUNC | O_CREAT | O_EXCL)), *mode );
}
+ else if (errno == EACCES)
+ {
+ /* try to change permissions temporarily to open a file descriptor */
+ if (!(access & (FILE_UNIX_WRITE_ACCESS | FILE_UNIX_READ_ACCESS | DELETE)) &&
+ !stat( name, &st ) && st.st_uid == getuid() &&
+ !chmod( name, st.st_mode | S_IRUSR ))
+ {
+ fd->unix_fd = open( name, O_RDONLY | (flags & ~(O_TRUNC | O_CREAT | O_EXCL)), *mode );
+ *mode = st.st_mode;
+ do_chmod = 1;
+ }
+ else
+ {
+ set_error( STATUS_ACCESS_DENIED );
+ goto error;
+ }
+ }
if (fd->unix_fd == -1)
{
file_set_error();
+ if (do_chmod) chmod( name, *mode );
goto error;
}
}
closed_fd->unix_fd = fd->unix_fd;
closed_fd->unlink[0] = 0;
+
+ if (do_chmod) fchmod( fd->unix_fd, *mode );
fstat( fd->unix_fd, &st );
*mode = st.st_mode;
--
2.3.3

View File

@@ -0,0 +1,31 @@
From 9443494239616a5a9f1e7d5711324c435d04e035 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Fri, 3 Apr 2015 03:58:53 +0200
Subject: server: When creating new directories temporarily give
read-permissions until they are opened.
---
server/fd.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/server/fd.c b/server/fd.c
index 3afb89a..9a4aac4 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -1774,7 +1774,12 @@ struct fd *open_fd( struct fd *root, const char *name, int flags, mode_t *mode,
/* create the directory if needed */
if ((options & FILE_DIRECTORY_FILE) && (flags & O_CREAT))
{
- if (mkdir( name, *mode ) == -1)
+ if (mkdir( name, *mode | S_IRUSR ) != -1)
+ {
+ /* remove S_IRUSR later, after we have opened the directory */
+ do_chmod = !(*mode & S_IRUSR);
+ }
+ else
{
if (errno != EEXIST || (flags & O_EXCL))
{
--
2.3.3

View File

@@ -0,0 +1,93 @@
From 0c188a73bf19cbdb18c61d0a8417e9557c3daf59 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Fri, 3 Apr 2015 03:58:59 +0200
Subject: advapi32/tests: Add tests for ACL inheritance in CreateDirectoryA.
---
dlls/advapi32/tests/security.c | 70 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 70 insertions(+)
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
index 329ae09..36ef972 100644
--- a/dlls/advapi32/tests/security.c
+++ b/dlls/advapi32/tests/security.c
@@ -3404,6 +3404,76 @@ static void test_CreateDirectoryA(void)
LocalFree(pSD);
CloseHandle(hTemp);
+ /* Test inheritance of ACLs in CreateDirectory without security descriptor */
+ strcpy(tmpfile, tmpdir);
+ lstrcatA(tmpfile, "/tmpdir");
+ bret = CreateDirectoryA(tmpfile, NULL);
+ ok(bret == TRUE, "CreateDirectoryA failed with error %u\n", GetLastError());
+
+ error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
+ OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
+ (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,
+ OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERITED_ACE,
+ 0x1f01ff, TRUE, TRUE, TRUE, __LINE__);
+ LocalFree(pSD);
+ bret = RemoveDirectoryA(tmpfile);
+ ok(bret == TRUE, "RemoveDirectoryA failed with error %u\n", GetLastError());
+
+ /* Test inheritance of ACLs in CreateDirectory with security descriptor */
+ pSD = &sd;
+ 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");
+
+ strcpy(tmpfile, tmpdir);
+ lstrcatA(tmpfile, "/tmpdir1");
+
+ sa.nLength = sizeof(sa);
+ sa.lpSecurityDescriptor = pSD;
+ sa.bInheritHandle = TRUE;
+ bret = CreateDirectoryA(tmpfile, &sa);
+ ok(bret == TRUE, "CreateDirectoryA failed with error %u\n", GetLastError());
+ HeapFree(GetProcessHeap(), 0, pDacl);
+
+ error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
+ OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
+ (PSID *)&owner, NULL, &pDacl, NULL, &pSD);
+ 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);
+
+ SetLastError(0xdeadbeef);
+ bret = RemoveDirectoryA(tmpfile);
+ error = GetLastError();
+ ok(bret == FALSE, "RemoveDirectoryA unexpected succeeded\n");
+ ok(error == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %u\n", error);
+
+ pSD = &sd;
+ InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
+ pDacl = HeapAlloc(GetProcessHeap(), 0, 100);
+ 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 = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
+ ok(bret, "Failed to add ACL to security desciptor.\n");
+ error = pSetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL,
+ NULL, pDacl, NULL);
+ ok(error == ERROR_SUCCESS, "SetNamedSecurityInfoA failed with error %u\n", error);
+ HeapFree(GetProcessHeap(), 0, pDacl);
+
+ bret = RemoveDirectoryA(tmpfile);
+ ok(bret == TRUE, "RemoveDirectoryA failed with error %u\n", GetLastError());
+
done:
HeapFree(GetProcessHeap(), 0, user);
bret = RemoveDirectoryA(tmpdir);
--
2.3.3

View File

@@ -0,0 +1,100 @@
From 39e8ae54cb3e8dcd4ef48e190f96b6dd48b40969 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Fri, 3 Apr 2015 03:59:05 +0200
Subject: advapi32/tests: Add ACL inheritance tests for creating subdirectories
with NtCreateFile.
---
dlls/advapi32/tests/security.c | 76 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 76 insertions(+)
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
index 36ef972..a0532f6 100644
--- a/dlls/advapi32/tests/security.c
+++ b/dlls/advapi32/tests/security.c
@@ -3474,6 +3474,82 @@ static void test_CreateDirectoryA(void)
bret = RemoveDirectoryA(tmpfile);
ok(bret == TRUE, "RemoveDirectoryA failed with error %u\n", GetLastError());
+ /* Test inheritance of ACLs in NtCreateFile(..., FILE_DIRECTORY_FILE, ...) without security descriptor */
+ strcpy(tmpfile, tmpdir);
+ lstrcatA(tmpfile, "/tmpdir");
+ get_nt_pathW(tmpfile, &tmpfileW);
+
+ attr.Length = sizeof(attr);
+ attr.RootDirectory = 0;
+ attr.ObjectName = &tmpfileW;
+ attr.Attributes = OBJ_CASE_INSENSITIVE;
+ attr.SecurityDescriptor = NULL;
+ attr.SecurityQualityOfService = NULL;
+
+ status = pNtCreateFile(&hTemp, GENERIC_READ | DELETE, &attr, &io, NULL, FILE_ATTRIBUTE_NORMAL,
+ FILE_SHARE_READ, FILE_CREATE, FILE_DIRECTORY_FILE | FILE_DELETE_ON_CLOSE, NULL, 0);
+ ok(!status, "NtCreateFile failed with %08x\n", status);
+ RtlFreeUnicodeString(&tmpfileW);
+
+ error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
+ OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
+ (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,
+ OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERITED_ACE,
+ 0x1f01ff, TRUE, TRUE, TRUE, __LINE__);
+ LocalFree(pSD);
+ CloseHandle(hTemp);
+
+ /* Test inheritance of ACLs in NtCreateFile(..., FILE_DIRECTORY_FILE, ...) with security descriptor */
+ pSD = &sd;
+ 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");
+
+ strcpy(tmpfile, tmpdir);
+ lstrcatA(tmpfile, "/tmpdir2");
+ get_nt_pathW(tmpfile, &tmpfileW);
+
+ attr.Length = sizeof(attr);
+ attr.RootDirectory = 0;
+ attr.ObjectName = &tmpfileW;
+ attr.Attributes = OBJ_CASE_INSENSITIVE;
+ attr.SecurityDescriptor = pSD;
+ attr.SecurityQualityOfService = NULL;
+
+ status = pNtCreateFile(&hTemp, GENERIC_READ | DELETE, &attr, &io, NULL, FILE_ATTRIBUTE_NORMAL,
+ FILE_SHARE_READ, FILE_CREATE, FILE_DIRECTORY_FILE | FILE_DELETE_ON_CLOSE, NULL, 0);
+ ok(!status, "NtCreateFile failed with %08x\n", status);
+ RtlFreeUnicodeString(&tmpfileW);
+ HeapFree(GetProcessHeap(), 0, pDacl);
+
+ error = pGetSecurityInfo(hTemp, SE_FILE_OBJECT,
+ OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
+ (PSID *)&owner, NULL, &pDacl, NULL, &pSD);
+ 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);
+
+ error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
+ OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
+ (PSID *)&owner, NULL, &pDacl, NULL, &pSD);
+ 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);
+ CloseHandle(hTemp);
+
done:
HeapFree(GetProcessHeap(), 0, user);
bret = RemoveDirectoryA(tmpdir);
--
2.3.3

View File

@@ -0,0 +1 @@
Fixes: Allow to open files/directories without any access rights in order to query attributes