1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/xpcom/tests/windows/TestNTFSPermissions.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,286 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +/* 1.10 + * Test for NTFS File Permissions being correctly changed to match the new 1.11 + * directory upon moving a file. (Bug 224692.) 1.12 + */ 1.13 + 1.14 +#include "../TestHarness.h" 1.15 +#include "nsEmbedString.h" 1.16 +#include "nsIFile.h" 1.17 +#include <windows.h> 1.18 +#include <aclapi.h> 1.19 + 1.20 +#define BUFFSIZE 512 1.21 + 1.22 + 1.23 + 1.24 +nsresult TestPermissions() 1.25 +{ 1.26 + 1.27 + nsresult rv; // Return value 1.28 + 1.29 + // File variables 1.30 + HANDLE tempFileHandle; 1.31 + nsCOMPtr<nsIFile> tempFile; 1.32 + nsCOMPtr<nsIFile> tempDirectory1; 1.33 + nsCOMPtr<nsIFile> tempDirectory2; 1.34 + WCHAR filePath[MAX_PATH]; 1.35 + WCHAR dir1Path[MAX_PATH]; 1.36 + WCHAR dir2Path[MAX_PATH]; 1.37 + 1.38 + // Security variables 1.39 + DWORD result; 1.40 + PSID everyoneSID = nullptr, adminSID = nullptr; 1.41 + PACL dirACL = nullptr, fileACL = nullptr; 1.42 + PSECURITY_DESCRIPTOR dirSD = nullptr, fileSD = nullptr; 1.43 + EXPLICIT_ACCESS ea[2]; 1.44 + SID_IDENTIFIER_AUTHORITY SIDAuthWorld = 1.45 + SECURITY_WORLD_SID_AUTHORITY; 1.46 + SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY; 1.47 + SECURITY_ATTRIBUTES sa; 1.48 + TRUSTEE everyoneTrustee; 1.49 + ACCESS_MASK everyoneRights; 1.50 + 1.51 + // Create a well-known SID for the Everyone group. 1.52 + if(!AllocateAndInitializeSid(&SIDAuthWorld, 1, 1.53 + SECURITY_WORLD_RID, 1.54 + 0, 0, 0, 0, 0, 0, 0, 1.55 + &everyoneSID)) 1.56 + { 1.57 + fail("NTFS Permissions: AllocateAndInitializeSid Error"); 1.58 + return NS_ERROR_FAILURE; 1.59 + } 1.60 + 1.61 + // Create a SID for the Administrators group. 1.62 + if(! AllocateAndInitializeSid(&SIDAuthNT, 2, 1.63 + SECURITY_BUILTIN_DOMAIN_RID, 1.64 + DOMAIN_ALIAS_RID_ADMINS, 1.65 + 0, 0, 0, 0, 0, 0, 1.66 + &adminSID)) 1.67 + { 1.68 + fail("NTFS Permissions: AllocateAndInitializeSid Error"); 1.69 + return NS_ERROR_FAILURE; 1.70 + } 1.71 + 1.72 + // Initialize an EXPLICIT_ACCESS structure for an ACE. 1.73 + // The ACE will allow Everyone read access to the directory. 1.74 + ZeroMemory(&ea, 2 * sizeof(EXPLICIT_ACCESS)); 1.75 + ea[0].grfAccessPermissions = GENERIC_READ; 1.76 + ea[0].grfAccessMode = SET_ACCESS; 1.77 + ea[0].grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT; 1.78 + ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID; 1.79 + ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; 1.80 + ea[0].Trustee.ptstrName = (LPTSTR) everyoneSID; 1.81 + 1.82 + // Initialize an EXPLICIT_ACCESS structure for an ACE. 1.83 + // The ACE will allow the Administrators group full access 1.84 + ea[1].grfAccessPermissions = GENERIC_ALL | STANDARD_RIGHTS_ALL; 1.85 + ea[1].grfAccessMode = SET_ACCESS; 1.86 + ea[1].grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT; 1.87 + ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID; 1.88 + ea[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP; 1.89 + ea[1].Trustee.ptstrName = (LPTSTR) adminSID; 1.90 + 1.91 + // Create a new ACL that contains the new ACEs. 1.92 + result = SetEntriesInAcl(2, ea, nullptr, &dirACL); 1.93 + if (ERROR_SUCCESS != result) 1.94 + { 1.95 + fail("NTFS Permissions: SetEntriesInAcl Error"); 1.96 + return NS_ERROR_FAILURE; 1.97 + } 1.98 + 1.99 + // Initialize a security descriptor. 1.100 + dirSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, 1.101 + SECURITY_DESCRIPTOR_MIN_LENGTH); 1.102 + if (nullptr == dirSD) 1.103 + { 1.104 + fail("NTFS Permissions: LocalAlloc Error"); 1.105 + return NS_ERROR_FAILURE; 1.106 + } 1.107 + 1.108 + if (!InitializeSecurityDescriptor(dirSD, 1.109 + SECURITY_DESCRIPTOR_REVISION)) 1.110 + { 1.111 + fail("NTFS Permissions: InitializeSecurityDescriptor Error"); 1.112 + return NS_ERROR_FAILURE; 1.113 + } 1.114 + 1.115 + // Add the ACL to the security descriptor. 1.116 + if (!SetSecurityDescriptorDacl(dirSD, true, dirACL, false)) 1.117 + { 1.118 + fail("NTFS Permissions: SetSecurityDescriptorDacl Error"); 1.119 + return NS_ERROR_FAILURE; 1.120 + } 1.121 + 1.122 + // Initialize a security attributes structure. 1.123 + sa.nLength = sizeof (SECURITY_ATTRIBUTES); 1.124 + sa.lpSecurityDescriptor = dirSD; 1.125 + sa.bInheritHandle = false; 1.126 + 1.127 + // Create and open first temporary directory 1.128 + if(!CreateDirectoryW(L".\\NTFSPERMTEMP1", &sa)) 1.129 + { 1.130 + fail("NTFS Permissions: Creating Temporary Directory"); 1.131 + return NS_ERROR_FAILURE; 1.132 + } 1.133 + 1.134 + GetFullPathNameW((LPCWSTR)L".\\NTFSPERMTEMP1", MAX_PATH, dir1Path, 1.135 + nullptr); 1.136 + 1.137 + rv = NS_NewLocalFile(nsEmbedString(dir1Path), false, 1.138 + getter_AddRefs(tempDirectory1)); 1.139 + if (NS_FAILED(rv)) 1.140 + { 1.141 + fail("NTFS Permissions: Opening Temporary Directory 1"); 1.142 + return rv; 1.143 + } 1.144 + 1.145 + 1.146 + // Create and open temporary file 1.147 + tempFileHandle = CreateFileW(L".\\NTFSPERMTEMP1\\NTFSPerm.tmp", 1.148 + GENERIC_READ | GENERIC_WRITE, 1.149 + 0, 1.150 + nullptr, //default security 1.151 + CREATE_ALWAYS, 1.152 + FILE_ATTRIBUTE_NORMAL, 1.153 + nullptr); 1.154 + 1.155 + if(tempFileHandle == INVALID_HANDLE_VALUE) 1.156 + { 1.157 + fail("NTFS Permissions: Creating Temporary File"); 1.158 + return NS_ERROR_FAILURE; 1.159 + } 1.160 + 1.161 + CloseHandle(tempFileHandle); 1.162 + 1.163 + GetFullPathNameW((LPCWSTR)L".\\NTFSPERMTEMP1\\NTFSPerm.tmp", 1.164 + MAX_PATH, filePath, nullptr); 1.165 + 1.166 + rv = NS_NewLocalFile(nsEmbedString(filePath), false, 1.167 + getter_AddRefs(tempFile)); 1.168 + if (NS_FAILED(rv)) 1.169 + { 1.170 + fail("NTFS Permissions: Opening Temporary File"); 1.171 + return rv; 1.172 + } 1.173 + 1.174 + // Update Everyone Explict_Acess to full access. 1.175 + ea[0].grfAccessPermissions = GENERIC_ALL | STANDARD_RIGHTS_ALL; 1.176 + 1.177 + // Update the ACL to contain the new ACEs. 1.178 + result = SetEntriesInAcl(2, ea, nullptr, &dirACL); 1.179 + if (ERROR_SUCCESS != result) 1.180 + { 1.181 + fail("NTFS Permissions: SetEntriesInAcl 2 Error"); 1.182 + return NS_ERROR_FAILURE; 1.183 + } 1.184 + 1.185 + // Add the new ACL to the security descriptor. 1.186 + if (!SetSecurityDescriptorDacl(dirSD, true, dirACL, false)) 1.187 + { 1.188 + fail("NTFS Permissions: SetSecurityDescriptorDacl 2 Error"); 1.189 + return NS_ERROR_FAILURE; 1.190 + } 1.191 + 1.192 + // Create and open second temporary directory 1.193 + if(!CreateDirectoryW(L".\\NTFSPERMTEMP2", &sa)) 1.194 + { 1.195 + fail("NTFS Permissions: Creating Temporary Directory 2"); 1.196 + return NS_ERROR_FAILURE; 1.197 + } 1.198 + 1.199 + GetFullPathNameW((LPCWSTR)L".\\NTFSPERMTEMP2", MAX_PATH, dir2Path, 1.200 + nullptr); 1.201 + 1.202 + rv = NS_NewLocalFile(nsEmbedString(dir2Path), false, 1.203 + getter_AddRefs(tempDirectory2)); 1.204 + if (NS_FAILED(rv)) 1.205 + { 1.206 + fail("NTFS Permissions: Opening Temporary Directory 2"); 1.207 + return rv; 1.208 + } 1.209 + 1.210 + // Move the file. 1.211 + rv = tempFile->MoveTo(tempDirectory2, EmptyString()); 1.212 + 1.213 + if (NS_FAILED(rv)) 1.214 + { 1.215 + fail("NTFS Permissions: Moving"); 1.216 + return rv; 1.217 + } 1.218 + 1.219 + // Access the ACL of the file 1.220 + result = GetNamedSecurityInfoW(L".\\NTFSPERMTEMP2\\NTFSPerm.tmp", 1.221 + SE_FILE_OBJECT, 1.222 + DACL_SECURITY_INFORMATION | 1.223 + UNPROTECTED_DACL_SECURITY_INFORMATION, 1.224 + nullptr, nullptr, &fileACL, nullptr, 1.225 + &fileSD); 1.226 + if (ERROR_SUCCESS != result) 1.227 + { 1.228 + fail("NTFS Permissions: GetNamedSecurityDescriptor Error"); 1.229 + return NS_ERROR_FAILURE; 1.230 + } 1.231 + 1.232 + // Build a trustee representing "Everyone" 1.233 + BuildTrusteeWithSid(&everyoneTrustee, everyoneSID); 1.234 + 1.235 + // Get Everyone's effective rights. 1.236 + result = GetEffectiveRightsFromAcl(fileACL, &everyoneTrustee, 1.237 + &everyoneRights); 1.238 + if (ERROR_SUCCESS != result) 1.239 + { 1.240 + fail("NTFS Permissions: GetEffectiveRightsFromAcl Error"); 1.241 + return NS_ERROR_FAILURE; 1.242 + } 1.243 + 1.244 + // Check for delete access, which we won't have unless permissions have 1.245 + // updated 1.246 + if((everyoneRights & DELETE) == (DELETE)) 1.247 + { 1.248 + passed("NTFS Permissions Test"); 1.249 + rv = NS_OK; 1.250 + } 1.251 + else 1.252 + { 1.253 + fail("NTFS Permissions: Access check."); 1.254 + rv = NS_ERROR_FAILURE; 1.255 + } 1.256 + 1.257 + // Cleanup 1.258 + if (everyoneSID) 1.259 + FreeSid(everyoneSID); 1.260 + if (adminSID) 1.261 + FreeSid(adminSID); 1.262 + if (dirACL) 1.263 + LocalFree(dirACL); 1.264 + if (dirSD) 1.265 + LocalFree(dirSD); 1.266 + if(fileACL) 1.267 + LocalFree(fileACL); 1.268 + 1.269 + tempDirectory1->Remove(true); 1.270 + tempDirectory2->Remove(true); 1.271 + 1.272 + return rv; 1.273 +} 1.274 + 1.275 +int main(int argc, char** argv) 1.276 +{ 1.277 + ScopedXPCOM xpcom("NTFSPermissionsTests"); // name for tests being run 1.278 + if (xpcom.failed()) 1.279 + return 1; 1.280 + 1.281 + int rv = 0; 1.282 + 1.283 + if(NS_FAILED(TestPermissions())) 1.284 + rv = 1; 1.285 + 1.286 + return rv; 1.287 + 1.288 +} 1.289 +