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