From: Sebastian Lackner Subject: [1/4] server: Allow to open files without any permission bits. (try 2) Message-Id: <551DF3D7.1070803@fds-team.de> Date: Fri, 03 Apr 2015 03:58:47 +0200 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(-) From 075ce189a59dbc780b4846b4b135c97d8ca9295e Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Thu, 2 Apr 2015 09:42:40 +0200 Subject: server: Allow to open files without any permission bits. --- 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 3789d72..84a218e 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