1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 /*
7 * Test for NTFS File Permissions being correctly changed to match the new
8 * directory upon moving a file. (Bug 224692.)
9 */
10
11 #include "../TestHarness.h"
12 #include "nsEmbedString.h"
13 #include "nsIFile.h"
14 #include <windows.h>
15 #include <aclapi.h>
16
17 #define BUFFSIZE 512
18
19
20
TestPermissions()21 nsresult TestPermissions()
22 {
23
24 nsresult rv; // Return value
25
26 // File variables
27 HANDLE tempFileHandle;
28 nsCOMPtr<nsIFile> tempFile;
29 nsCOMPtr<nsIFile> tempDirectory1;
30 nsCOMPtr<nsIFile> tempDirectory2;
31 WCHAR filePath[MAX_PATH];
32 WCHAR dir1Path[MAX_PATH];
33 WCHAR dir2Path[MAX_PATH];
34
35 // Security variables
36 DWORD result;
37 PSID everyoneSID = nullptr, adminSID = nullptr;
38 PACL dirACL = nullptr, fileACL = nullptr;
39 PSECURITY_DESCRIPTOR dirSD = nullptr, fileSD = nullptr;
40 EXPLICIT_ACCESS ea[2];
41 SID_IDENTIFIER_AUTHORITY SIDAuthWorld =
42 SECURITY_WORLD_SID_AUTHORITY;
43 SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY;
44 SECURITY_ATTRIBUTES sa;
45 TRUSTEE everyoneTrustee;
46 ACCESS_MASK everyoneRights;
47
48 // Create a well-known SID for the Everyone group.
49 if(!AllocateAndInitializeSid(&SIDAuthWorld, 1,
50 SECURITY_WORLD_RID,
51 0, 0, 0, 0, 0, 0, 0,
52 &everyoneSID))
53 {
54 fail("NTFS Permissions: AllocateAndInitializeSid Error");
55 return NS_ERROR_FAILURE;
56 }
57
58 // Create a SID for the Administrators group.
59 if(! AllocateAndInitializeSid(&SIDAuthNT, 2,
60 SECURITY_BUILTIN_DOMAIN_RID,
61 DOMAIN_ALIAS_RID_ADMINS,
62 0, 0, 0, 0, 0, 0,
63 &adminSID))
64 {
65 fail("NTFS Permissions: AllocateAndInitializeSid Error");
66 return NS_ERROR_FAILURE;
67 }
68
69 // Initialize an EXPLICIT_ACCESS structure for an ACE.
70 // The ACE will allow Everyone read access to the directory.
71 ZeroMemory(&ea, 2 * sizeof(EXPLICIT_ACCESS));
72 ea[0].grfAccessPermissions = GENERIC_READ;
73 ea[0].grfAccessMode = SET_ACCESS;
74 ea[0].grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT;
75 ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
76 ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
77 ea[0].Trustee.ptstrName = (LPTSTR) everyoneSID;
78
79 // Initialize an EXPLICIT_ACCESS structure for an ACE.
80 // The ACE will allow the Administrators group full access
81 ea[1].grfAccessPermissions = GENERIC_ALL | STANDARD_RIGHTS_ALL;
82 ea[1].grfAccessMode = SET_ACCESS;
83 ea[1].grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT;
84 ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
85 ea[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
86 ea[1].Trustee.ptstrName = (LPTSTR) adminSID;
87
88 // Create a new ACL that contains the new ACEs.
89 result = SetEntriesInAcl(2, ea, nullptr, &dirACL);
90 if (ERROR_SUCCESS != result)
91 {
92 fail("NTFS Permissions: SetEntriesInAcl Error");
93 return NS_ERROR_FAILURE;
94 }
95
96 // Initialize a security descriptor.
97 dirSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR,
98 SECURITY_DESCRIPTOR_MIN_LENGTH);
99 if (nullptr == dirSD)
100 {
101 fail("NTFS Permissions: LocalAlloc Error");
102 return NS_ERROR_FAILURE;
103 }
104
105 if (!InitializeSecurityDescriptor(dirSD,
106 SECURITY_DESCRIPTOR_REVISION))
107 {
108 fail("NTFS Permissions: InitializeSecurityDescriptor Error");
109 return NS_ERROR_FAILURE;
110 }
111
112 // Add the ACL to the security descriptor.
113 if (!SetSecurityDescriptorDacl(dirSD, true, dirACL, false))
114 {
115 fail("NTFS Permissions: SetSecurityDescriptorDacl Error");
116 return NS_ERROR_FAILURE;
117 }
118
119 // Initialize a security attributes structure.
120 sa.nLength = sizeof (SECURITY_ATTRIBUTES);
121 sa.lpSecurityDescriptor = dirSD;
122 sa.bInheritHandle = false;
123
124 // Create and open first temporary directory
125 if(!CreateDirectoryW(L".\\NTFSPERMTEMP1", &sa))
126 {
127 fail("NTFS Permissions: Creating Temporary Directory");
128 return NS_ERROR_FAILURE;
129 }
130
131 GetFullPathNameW((LPCWSTR)L".\\NTFSPERMTEMP1", MAX_PATH, dir1Path,
132 nullptr);
133
134 rv = NS_NewLocalFile(nsEmbedString(dir1Path), false,
135 getter_AddRefs(tempDirectory1));
136 if (NS_FAILED(rv))
137 {
138 fail("NTFS Permissions: Opening Temporary Directory 1");
139 return rv;
140 }
141
142
143 // Create and open temporary file
144 tempFileHandle = CreateFileW(L".\\NTFSPERMTEMP1\\NTFSPerm.tmp",
145 GENERIC_READ | GENERIC_WRITE,
146 0,
147 nullptr, //default security
148 CREATE_ALWAYS,
149 FILE_ATTRIBUTE_NORMAL,
150 nullptr);
151
152 if(tempFileHandle == INVALID_HANDLE_VALUE)
153 {
154 fail("NTFS Permissions: Creating Temporary File");
155 return NS_ERROR_FAILURE;
156 }
157
158 CloseHandle(tempFileHandle);
159
160 GetFullPathNameW((LPCWSTR)L".\\NTFSPERMTEMP1\\NTFSPerm.tmp",
161 MAX_PATH, filePath, nullptr);
162
163 rv = NS_NewLocalFile(nsEmbedString(filePath), false,
164 getter_AddRefs(tempFile));
165 if (NS_FAILED(rv))
166 {
167 fail("NTFS Permissions: Opening Temporary File");
168 return rv;
169 }
170
171 // Update Everyone Explict_Acess to full access.
172 ea[0].grfAccessPermissions = GENERIC_ALL | STANDARD_RIGHTS_ALL;
173
174 // Update the ACL to contain the new ACEs.
175 result = SetEntriesInAcl(2, ea, nullptr, &dirACL);
176 if (ERROR_SUCCESS != result)
177 {
178 fail("NTFS Permissions: SetEntriesInAcl 2 Error");
179 return NS_ERROR_FAILURE;
180 }
181
182 // Add the new ACL to the security descriptor.
183 if (!SetSecurityDescriptorDacl(dirSD, true, dirACL, false))
184 {
185 fail("NTFS Permissions: SetSecurityDescriptorDacl 2 Error");
186 return NS_ERROR_FAILURE;
187 }
188
189 // Create and open second temporary directory
190 if(!CreateDirectoryW(L".\\NTFSPERMTEMP2", &sa))
191 {
192 fail("NTFS Permissions: Creating Temporary Directory 2");
193 return NS_ERROR_FAILURE;
194 }
195
196 GetFullPathNameW((LPCWSTR)L".\\NTFSPERMTEMP2", MAX_PATH, dir2Path,
197 nullptr);
198
199 rv = NS_NewLocalFile(nsEmbedString(dir2Path), false,
200 getter_AddRefs(tempDirectory2));
201 if (NS_FAILED(rv))
202 {
203 fail("NTFS Permissions: Opening Temporary Directory 2");
204 return rv;
205 }
206
207 // Move the file.
208 rv = tempFile->MoveTo(tempDirectory2, EmptyString());
209
210 if (NS_FAILED(rv))
211 {
212 fail("NTFS Permissions: Moving");
213 return rv;
214 }
215
216 // Access the ACL of the file
217 result = GetNamedSecurityInfoW(L".\\NTFSPERMTEMP2\\NTFSPerm.tmp",
218 SE_FILE_OBJECT,
219 DACL_SECURITY_INFORMATION |
220 UNPROTECTED_DACL_SECURITY_INFORMATION,
221 nullptr, nullptr, &fileACL, nullptr,
222 &fileSD);
223 if (ERROR_SUCCESS != result)
224 {
225 fail("NTFS Permissions: GetNamedSecurityDescriptor Error");
226 return NS_ERROR_FAILURE;
227 }
228
229 // Build a trustee representing "Everyone"
230 BuildTrusteeWithSid(&everyoneTrustee, everyoneSID);
231
232 // Get Everyone's effective rights.
233 result = GetEffectiveRightsFromAcl(fileACL, &everyoneTrustee,
234 &everyoneRights);
235 if (ERROR_SUCCESS != result)
236 {
237 fail("NTFS Permissions: GetEffectiveRightsFromAcl Error");
238 return NS_ERROR_FAILURE;
239 }
240
241 // Check for delete access, which we won't have unless permissions have
242 // updated
243 if((everyoneRights & DELETE) == (DELETE))
244 {
245 passed("NTFS Permissions Test");
246 rv = NS_OK;
247 }
248 else
249 {
250 fail("NTFS Permissions: Access check.");
251 rv = NS_ERROR_FAILURE;
252 }
253
254 // Cleanup
255 if (everyoneSID)
256 FreeSid(everyoneSID);
257 if (adminSID)
258 FreeSid(adminSID);
259 if (dirACL)
260 LocalFree(dirACL);
261 if (dirSD)
262 LocalFree(dirSD);
263 if(fileACL)
264 LocalFree(fileACL);
265
266 tempDirectory1->Remove(true);
267 tempDirectory2->Remove(true);
268
269 return rv;
270 }
271
main(int argc,char ** argv)272 int main(int argc, char** argv)
273 {
274 ScopedXPCOM xpcom("NTFSPermissionsTests"); // name for tests being run
275 if (xpcom.failed())
276 return 1;
277
278 int rv = 0;
279
280 if(NS_FAILED(TestPermissions()))
281 rv = 1;
282
283 return rv;
284
285 }
286
287