diff options
Diffstat (limited to 'xpcom/tests/windows/TestNTFSPermissions.cpp')
-rw-r--r-- | xpcom/tests/windows/TestNTFSPermissions.cpp | 286 |
1 files changed, 286 insertions, 0 deletions
diff --git a/xpcom/tests/windows/TestNTFSPermissions.cpp b/xpcom/tests/windows/TestNTFSPermissions.cpp new file mode 100644 index 000000000..062a9e650 --- /dev/null +++ b/xpcom/tests/windows/TestNTFSPermissions.cpp @@ -0,0 +1,286 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Test for NTFS File Permissions being correctly changed to match the new + * directory upon moving a file. (Bug 224692.) + */ + +#include "../TestHarness.h" +#include "nsEmbedString.h" +#include "nsIFile.h" +#include <windows.h> +#include <aclapi.h> + +#define BUFFSIZE 512 + + + +nsresult TestPermissions() +{ + + nsresult rv; // Return value + + // File variables + HANDLE tempFileHandle; + nsCOMPtr<nsIFile> tempFile; + nsCOMPtr<nsIFile> tempDirectory1; + nsCOMPtr<nsIFile> tempDirectory2; + WCHAR filePath[MAX_PATH]; + WCHAR dir1Path[MAX_PATH]; + WCHAR dir2Path[MAX_PATH]; + + // Security variables + DWORD result; + PSID everyoneSID = nullptr, adminSID = nullptr; + PACL dirACL = nullptr, fileACL = nullptr; + PSECURITY_DESCRIPTOR dirSD = nullptr, fileSD = nullptr; + EXPLICIT_ACCESS ea[2]; + SID_IDENTIFIER_AUTHORITY SIDAuthWorld = + SECURITY_WORLD_SID_AUTHORITY; + SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY; + SECURITY_ATTRIBUTES sa; + TRUSTEE everyoneTrustee; + ACCESS_MASK everyoneRights; + + // Create a well-known SID for the Everyone group. + if(!AllocateAndInitializeSid(&SIDAuthWorld, 1, + SECURITY_WORLD_RID, + 0, 0, 0, 0, 0, 0, 0, + &everyoneSID)) + { + fail("NTFS Permissions: AllocateAndInitializeSid Error"); + return NS_ERROR_FAILURE; + } + + // Create a SID for the Administrators group. + if(! AllocateAndInitializeSid(&SIDAuthNT, 2, + SECURITY_BUILTIN_DOMAIN_RID, + DOMAIN_ALIAS_RID_ADMINS, + 0, 0, 0, 0, 0, 0, + &adminSID)) + { + fail("NTFS Permissions: AllocateAndInitializeSid Error"); + return NS_ERROR_FAILURE; + } + + // Initialize an EXPLICIT_ACCESS structure for an ACE. + // The ACE will allow Everyone read access to the directory. + ZeroMemory(&ea, 2 * sizeof(EXPLICIT_ACCESS)); + ea[0].grfAccessPermissions = GENERIC_READ; + ea[0].grfAccessMode = SET_ACCESS; + ea[0].grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT; + ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID; + ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; + ea[0].Trustee.ptstrName = (LPTSTR) everyoneSID; + + // Initialize an EXPLICIT_ACCESS structure for an ACE. + // The ACE will allow the Administrators group full access + ea[1].grfAccessPermissions = GENERIC_ALL | STANDARD_RIGHTS_ALL; + ea[1].grfAccessMode = SET_ACCESS; + ea[1].grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT; + ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID; + ea[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP; + ea[1].Trustee.ptstrName = (LPTSTR) adminSID; + + // Create a new ACL that contains the new ACEs. + result = SetEntriesInAcl(2, ea, nullptr, &dirACL); + if (ERROR_SUCCESS != result) + { + fail("NTFS Permissions: SetEntriesInAcl Error"); + return NS_ERROR_FAILURE; + } + + // Initialize a security descriptor. + dirSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, + SECURITY_DESCRIPTOR_MIN_LENGTH); + if (nullptr == dirSD) + { + fail("NTFS Permissions: LocalAlloc Error"); + return NS_ERROR_FAILURE; + } + + if (!InitializeSecurityDescriptor(dirSD, + SECURITY_DESCRIPTOR_REVISION)) + { + fail("NTFS Permissions: InitializeSecurityDescriptor Error"); + return NS_ERROR_FAILURE; + } + + // Add the ACL to the security descriptor. + if (!SetSecurityDescriptorDacl(dirSD, true, dirACL, false)) + { + fail("NTFS Permissions: SetSecurityDescriptorDacl Error"); + return NS_ERROR_FAILURE; + } + + // Initialize a security attributes structure. + sa.nLength = sizeof (SECURITY_ATTRIBUTES); + sa.lpSecurityDescriptor = dirSD; + sa.bInheritHandle = false; + + // Create and open first temporary directory + if(!CreateDirectoryW(L".\\NTFSPERMTEMP1", &sa)) + { + fail("NTFS Permissions: Creating Temporary Directory"); + return NS_ERROR_FAILURE; + } + + GetFullPathNameW((LPCWSTR)L".\\NTFSPERMTEMP1", MAX_PATH, dir1Path, + nullptr); + + rv = NS_NewLocalFile(nsEmbedString(dir1Path), false, + getter_AddRefs(tempDirectory1)); + if (NS_FAILED(rv)) + { + fail("NTFS Permissions: Opening Temporary Directory 1"); + return rv; + } + + + // Create and open temporary file + tempFileHandle = CreateFileW(L".\\NTFSPERMTEMP1\\NTFSPerm.tmp", + GENERIC_READ | GENERIC_WRITE, + 0, + nullptr, //default security + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + nullptr); + + if(tempFileHandle == INVALID_HANDLE_VALUE) + { + fail("NTFS Permissions: Creating Temporary File"); + return NS_ERROR_FAILURE; + } + + CloseHandle(tempFileHandle); + + GetFullPathNameW((LPCWSTR)L".\\NTFSPERMTEMP1\\NTFSPerm.tmp", + MAX_PATH, filePath, nullptr); + + rv = NS_NewLocalFile(nsEmbedString(filePath), false, + getter_AddRefs(tempFile)); + if (NS_FAILED(rv)) + { + fail("NTFS Permissions: Opening Temporary File"); + return rv; + } + + // Update Everyone Explict_Acess to full access. + ea[0].grfAccessPermissions = GENERIC_ALL | STANDARD_RIGHTS_ALL; + + // Update the ACL to contain the new ACEs. + result = SetEntriesInAcl(2, ea, nullptr, &dirACL); + if (ERROR_SUCCESS != result) + { + fail("NTFS Permissions: SetEntriesInAcl 2 Error"); + return NS_ERROR_FAILURE; + } + + // Add the new ACL to the security descriptor. + if (!SetSecurityDescriptorDacl(dirSD, true, dirACL, false)) + { + fail("NTFS Permissions: SetSecurityDescriptorDacl 2 Error"); + return NS_ERROR_FAILURE; + } + + // Create and open second temporary directory + if(!CreateDirectoryW(L".\\NTFSPERMTEMP2", &sa)) + { + fail("NTFS Permissions: Creating Temporary Directory 2"); + return NS_ERROR_FAILURE; + } + + GetFullPathNameW((LPCWSTR)L".\\NTFSPERMTEMP2", MAX_PATH, dir2Path, + nullptr); + + rv = NS_NewLocalFile(nsEmbedString(dir2Path), false, + getter_AddRefs(tempDirectory2)); + if (NS_FAILED(rv)) + { + fail("NTFS Permissions: Opening Temporary Directory 2"); + return rv; + } + + // Move the file. + rv = tempFile->MoveTo(tempDirectory2, EmptyString()); + + if (NS_FAILED(rv)) + { + fail("NTFS Permissions: Moving"); + return rv; + } + + // Access the ACL of the file + result = GetNamedSecurityInfoW(L".\\NTFSPERMTEMP2\\NTFSPerm.tmp", + SE_FILE_OBJECT, + DACL_SECURITY_INFORMATION | + UNPROTECTED_DACL_SECURITY_INFORMATION, + nullptr, nullptr, &fileACL, nullptr, + &fileSD); + if (ERROR_SUCCESS != result) + { + fail("NTFS Permissions: GetNamedSecurityDescriptor Error"); + return NS_ERROR_FAILURE; + } + + // Build a trustee representing "Everyone" + BuildTrusteeWithSid(&everyoneTrustee, everyoneSID); + + // Get Everyone's effective rights. + result = GetEffectiveRightsFromAcl(fileACL, &everyoneTrustee, + &everyoneRights); + if (ERROR_SUCCESS != result) + { + fail("NTFS Permissions: GetEffectiveRightsFromAcl Error"); + return NS_ERROR_FAILURE; + } + + // Check for delete access, which we won't have unless permissions have + // updated + if((everyoneRights & DELETE) == (DELETE)) + { + passed("NTFS Permissions Test"); + rv = NS_OK; + } + else + { + fail("NTFS Permissions: Access check."); + rv = NS_ERROR_FAILURE; + } + + // Cleanup + if (everyoneSID) + FreeSid(everyoneSID); + if (adminSID) + FreeSid(adminSID); + if (dirACL) + LocalFree(dirACL); + if (dirSD) + LocalFree(dirSD); + if(fileACL) + LocalFree(fileACL); + + tempDirectory1->Remove(true); + tempDirectory2->Remove(true); + + return rv; +} + +int main(int argc, char** argv) +{ + ScopedXPCOM xpcom("NTFSPermissionsTests"); // name for tests being run + if (xpcom.failed()) + return 1; + + int rv = 0; + + if(NS_FAILED(TestPermissions())) + rv = 1; + + return rv; + +} + |