Merge to trunk HEAD(r36856)
[reactos.git] / reactos / dll / win32 / advapi32 / sec / misc.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/advapi32/sec/misc.c
5 * PURPOSE: Miscellaneous security functions (some ported from Wine)
6 */
7
8 #include <advapi32.h>
9 #include "wine/debug.h"
10
11 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
12
13 /* Needed for LookupAccountNameW implementation from Wine */
14
15 typedef struct _AccountSid
16 {
17 WELL_KNOWN_SID_TYPE type;
18 LPCWSTR account;
19 LPCWSTR domain;
20 SID_NAME_USE name_use;
21 } AccountSid;
22
23 static const WCHAR Account_Operators[] = { 'A','c','c','o','u','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
24 static const WCHAR Administrator[] = {'A','d','m','i','n','i','s','t','r','a','t','o','r',0 };
25 static const WCHAR Administrators[] = { 'A','d','m','i','n','i','s','t','r','a','t','o','r','s',0 };
26 static const WCHAR ANONYMOUS_LOGON[] = { 'A','N','O','N','Y','M','O','U','S',' ','L','O','G','O','N',0 };
27 static const WCHAR Authenticated_Users[] = { 'A','u','t','h','e','n','t','i','c','a','t','e','d',' ','U','s','e','r','s',0 };
28 static const WCHAR Backup_Operators[] = { 'B','a','c','k','u','p',' ','O','p','e','r','a','t','o','r','s',0 };
29 static const WCHAR BATCH[] = { 'B','A','T','C','H',0 };
30 static const WCHAR Blank[] = { 0 };
31 static const WCHAR BUILTIN[] = { 'B','U','I','L','T','I','N',0 };
32 static const WCHAR Cert_Publishers[] = { 'C','e','r','t',' ','P','u','b','l','i','s','h','e','r','s',0 };
33 static const WCHAR CREATOR_GROUP[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',0 };
34 static const WCHAR CREATOR_GROUP_SERVER[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',' ','S','E','R','V','E','R',0 };
35 static const WCHAR CREATOR_OWNER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',0 };
36 static const WCHAR CREATOR_OWNER_SERVER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',' ','S','E','R','V','E','R',0 };
37 static const WCHAR DIALUP[] = { 'D','I','A','L','U','P',0 };
38 static const WCHAR Digest_Authentication[] = { 'D','i','g','e','s','t',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
39 static const WCHAR DOMAIN[] = {'D','O','M','A','I','N',0};
40 static const WCHAR Domain_Admins[] = { 'D','o','m','a','i','n',' ','A','d','m','i','n','s',0 };
41 static const WCHAR Domain_Computers[] = { 'D','o','m','a','i','n',' ','C','o','m','p','u','t','e','r','s',0 };
42 static const WCHAR Domain_Controllers[] = { 'D','o','m','a','i','n',' ','C','o','n','t','r','o','l','l','e','r','s',0 };
43 static const WCHAR Domain_Guests[] = { 'D','o','m','a','i','n',' ','G','u','e','s','t','s',0 };
44 static const WCHAR Domain_Users[] = { 'D','o','m','a','i','n',' ','U','s','e','r','s',0 };
45 static const WCHAR Enterprise_Admins[] = { 'E','n','t','e','r','p','r','i','s','e',' ','A','d','m','i','n','s',0 };
46 static const WCHAR ENTERPRISE_DOMAIN_CONTROLLERS[] = { 'E','N','T','E','R','P','R','I','S','E',' ','D','O','M','A','I','N',' ','C','O','N','T','R','O','L','L','E','R','S',0 };
47 static const WCHAR Everyone[] = { 'E','v','e','r','y','o','n','e',0 };
48 static const WCHAR Group_Policy_Creator_Owners[] = { 'G','r','o','u','p',' ','P','o','l','i','c','y',' ','C','r','e','a','t','o','r',' ','O','w','n','e','r','s',0 };
49 static const WCHAR Guest[] = { 'G','u','e','s','t',0 };
50 static const WCHAR Guests[] = { 'G','u','e','s','t','s',0 };
51 static const WCHAR INTERACTIVE[] = { 'I','N','T','E','R','A','C','T','I','V','E',0 };
52 static const WCHAR LOCAL[] = { 'L','O','C','A','L',0 };
53 static const WCHAR LOCAL_SERVICE[] = { 'L','O','C','A','L',' ','S','E','R','V','I','C','E',0 };
54 static const WCHAR NETWORK[] = { 'N','E','T','W','O','R','K',0 };
55 static const WCHAR Network_Configuration_Operators[] = { 'N','e','t','w','o','r','k',' ','C','o','n','f','i','g','u','r','a','t','i','o','n',' ','O','p','e','r','a','t','o','r','s',0 };
56 static const WCHAR NETWORK_SERVICE[] = { 'N','E','T','W','O','R','K',' ','S','E','R','V','I','C','E',0 };
57 static const WCHAR NT_AUTHORITY[] = { 'N','T',' ','A','U','T','H','O','R','I','T','Y',0 };
58 static const WCHAR NT_Pseudo_Domain[] = { 'N','T',' ','P','s','e','u','d','o',' ','D','o','m','a','i','n',0 };
59 static const WCHAR NTML_Authentication[] = { 'N','T','M','L',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
60 static const WCHAR NULL_SID[] = { 'N','U','L','L',' ','S','I','D',0 };
61 static const WCHAR Other_Organization[] = { 'O','t','h','e','r',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
62 static const WCHAR Performance_Log_Users[] = { 'P','e','r','f','o','r','m','a','n','c','e',' ','L','o','g',' ','U','s','e','r','s',0 };
63 static const WCHAR Performance_Monitor_Users[] = { 'P','e','r','f','o','r','m','a','n','c','e',' ','M','o','n','i','t','o','r',' ','U','s','e','r','s',0 };
64 static const WCHAR Power_Users[] = { 'P','o','w','e','r',' ','U','s','e','r','s',0 };
65 static const WCHAR Pre_Windows_2000_Compatible_Access[] = { 'P','r','e','-','W','i','n','d','o','w','s',' ','2','0','0','0',' ','C','o','m','p','a','t','i','b','l','e',' ','A','c','c','e','s','s',0 };
66 static const WCHAR Print_Operators[] = { 'P','r','i','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
67 static const WCHAR PROXY[] = { 'P','R','O','X','Y',0 };
68 static const WCHAR RAS_and_IAS_Servers[] = { 'R','A','S',' ','a','n','d',' ','I','A','S',' ','S','e','r','v','e','r','s',0 };
69 static const WCHAR Remote_Desktop_Users[] = { 'R','e','m','o','t','e',' ','D','e','s','k','t','o','p',' ','U','s','e','r','s',0 };
70 static const WCHAR REMOTE_INTERACTIVE_LOGON[] = { 'R','E','M','O','T','E',' ','I','N','T','E','R','A','C','T','I','V','E',' ','L','O','G','O','N',0 };
71 static const WCHAR Replicators[] = { 'R','e','p','l','i','c','a','t','o','r','s',0 };
72 static const WCHAR RESTRICTED[] = { 'R','E','S','T','R','I','C','T','E','D',0 };
73 static const WCHAR SChannel_Authentication[] = { 'S','C','h','a','n','n','e','l',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
74 static const WCHAR Schema_Admins[] = { 'S','c','h','e','m','a',' ','A','d','m','i','n','s',0 };
75 static const WCHAR SELF[] = { 'S','E','L','F',0 };
76 static const WCHAR Server_Operators[] = { 'S','e','r','v','e','r',' ','O','p','e','r','a','t','o','r','s',0 };
77 static const WCHAR SERVICE[] = { 'S','E','R','V','I','C','E',0 };
78 static const WCHAR SYSTEM[] = { 'S','Y','S','T','E','M',0 };
79 static const WCHAR TERMINAL_SERVER_USER[] = { 'T','E','R','M','I','N','A','L',' ','S','E','R','V','E','R',' ','U','S','E','R',0 };
80 static const WCHAR This_Organization[] = { 'T','h','i','s',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
81 static const WCHAR Users[] = { 'U','s','e','r','s',0 };
82
83 static const AccountSid ACCOUNT_SIDS[] = {
84 { WinNullSid, NULL_SID, Blank, SidTypeWellKnownGroup },
85 { WinWorldSid, Everyone, Blank, SidTypeWellKnownGroup },
86 { WinLocalSid, LOCAL, Blank, SidTypeWellKnownGroup },
87 { WinCreatorOwnerSid, CREATOR_OWNER, Blank, SidTypeWellKnownGroup },
88 { WinCreatorGroupSid, CREATOR_GROUP, Blank, SidTypeWellKnownGroup },
89 { WinCreatorOwnerServerSid, CREATOR_OWNER_SERVER, Blank, SidTypeWellKnownGroup },
90 { WinCreatorGroupServerSid, CREATOR_GROUP_SERVER, Blank, SidTypeWellKnownGroup },
91 { WinNtAuthoritySid, NT_Pseudo_Domain, NT_Pseudo_Domain, SidTypeDomain },
92 { WinDialupSid, DIALUP, NT_AUTHORITY, SidTypeWellKnownGroup },
93 { WinNetworkSid, NETWORK, NT_AUTHORITY, SidTypeWellKnownGroup },
94 { WinBatchSid, BATCH, NT_AUTHORITY, SidTypeWellKnownGroup },
95 { WinInteractiveSid, INTERACTIVE, NT_AUTHORITY, SidTypeWellKnownGroup },
96 { WinServiceSid, SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
97 { WinAnonymousSid, ANONYMOUS_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
98 { WinProxySid, PROXY, NT_AUTHORITY, SidTypeWellKnownGroup },
99 { WinEnterpriseControllersSid, ENTERPRISE_DOMAIN_CONTROLLERS, NT_AUTHORITY, SidTypeWellKnownGroup },
100 { WinSelfSid, SELF, NT_AUTHORITY, SidTypeWellKnownGroup },
101 { WinAuthenticatedUserSid, Authenticated_Users, NT_AUTHORITY, SidTypeWellKnownGroup },
102 { WinRestrictedCodeSid, RESTRICTED, NT_AUTHORITY, SidTypeWellKnownGroup },
103 { WinTerminalServerSid, TERMINAL_SERVER_USER, NT_AUTHORITY, SidTypeWellKnownGroup },
104 { WinRemoteLogonIdSid, REMOTE_INTERACTIVE_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
105 { WinLocalSystemSid, SYSTEM, NT_AUTHORITY, SidTypeWellKnownGroup },
106 { WinLocalServiceSid, LOCAL_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
107 { WinNetworkServiceSid, NETWORK_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
108 { WinBuiltinDomainSid, BUILTIN, BUILTIN, SidTypeDomain },
109 { WinBuiltinAdministratorsSid, Administrators, BUILTIN, SidTypeAlias },
110 { WinBuiltinUsersSid, Users, BUILTIN, SidTypeAlias },
111 { WinBuiltinGuestsSid, Guests, BUILTIN, SidTypeAlias },
112 { WinBuiltinPowerUsersSid, Power_Users, BUILTIN, SidTypeAlias },
113 { WinBuiltinAccountOperatorsSid, Account_Operators, BUILTIN, SidTypeAlias },
114 { WinBuiltinSystemOperatorsSid, Server_Operators, BUILTIN, SidTypeAlias },
115 { WinBuiltinPrintOperatorsSid, Print_Operators, BUILTIN, SidTypeAlias },
116 { WinBuiltinBackupOperatorsSid, Backup_Operators, BUILTIN, SidTypeAlias },
117 { WinBuiltinReplicatorSid, Replicators, BUILTIN, SidTypeAlias },
118 { WinBuiltinPreWindows2000CompatibleAccessSid, Pre_Windows_2000_Compatible_Access, BUILTIN, SidTypeAlias },
119 { WinBuiltinRemoteDesktopUsersSid, Remote_Desktop_Users, BUILTIN, SidTypeAlias },
120 { WinBuiltinNetworkConfigurationOperatorsSid, Network_Configuration_Operators, BUILTIN, SidTypeAlias },
121 { WinNTLMAuthenticationSid, NTML_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
122 { WinDigestAuthenticationSid, Digest_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
123 { WinSChannelAuthenticationSid, SChannel_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
124 { WinThisOrganizationSid, This_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
125 { WinOtherOrganizationSid, Other_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
126 { WinBuiltinPerfMonitoringUsersSid, Performance_Monitor_Users, BUILTIN, SidTypeAlias },
127 { WinBuiltinPerfLoggingUsersSid, Performance_Log_Users, BUILTIN, SidTypeAlias },
128 };
129
130 /* Interface to ntmarta.dll ***************************************************/
131
132 NTMARTA NtMartaStatic = { 0 };
133 static PNTMARTA NtMarta = NULL;
134
135 #define FindNtMartaProc(Name) \
136 NtMartaStatic.Name = (PVOID)GetProcAddress(NtMartaStatic.hDllInstance, \
137 "Acc" # Name ); \
138 if (NtMartaStatic.Name == NULL) \
139 { \
140 return GetLastError(); \
141 }
142
143
144 static DWORD
145 LoadAndInitializeNtMarta(VOID)
146 {
147 /* this code may be executed simultaneously by multiple threads in case they're
148 trying to initialize the interface at the same time, but that's no problem
149 because the pointers returned by GetProcAddress will be the same. However,
150 only one of the threads will change the NtMarta pointer to the NtMartaStatic
151 structure, the others threads will detect that there were other threads
152 initializing the structure faster and will release the reference to the
153 DLL */
154
155 NtMartaStatic.hDllInstance = LoadLibraryW(L"ntmarta.dll");
156 if (NtMartaStatic.hDllInstance == NULL)
157 {
158 return GetLastError();
159 }
160
161 #if 0
162 FindNtMartaProc(LookupAccountTrustee);
163 FindNtMartaProc(LookupAccountName);
164 FindNtMartaProc(LookupAccountSid);
165 FindNtMartaProc(SetEntriesInAList);
166 FindNtMartaProc(ConvertAccessToSecurityDescriptor);
167 FindNtMartaProc(ConvertSDToAccess);
168 FindNtMartaProc(ConvertAclToAccess);
169 FindNtMartaProc(GetAccessForTrustee);
170 FindNtMartaProc(GetExplicitEntries);
171 #endif
172 FindNtMartaProc(RewriteGetNamedRights);
173 FindNtMartaProc(RewriteSetNamedRights);
174 FindNtMartaProc(RewriteGetHandleRights);
175 FindNtMartaProc(RewriteSetHandleRights);
176 FindNtMartaProc(RewriteSetEntriesInAcl);
177 FindNtMartaProc(RewriteGetExplicitEntriesFromAcl);
178 FindNtMartaProc(TreeResetNamedSecurityInfo);
179 FindNtMartaProc(GetInheritanceSource);
180 FindNtMartaProc(FreeIndexArray);
181
182 return ERROR_SUCCESS;
183 }
184
185
186 DWORD
187 CheckNtMartaPresent(VOID)
188 {
189 DWORD ErrorCode;
190
191 if (InterlockedCompareExchangePointer((PVOID)&NtMarta,
192 NULL,
193 NULL) == NULL)
194 {
195 /* we're the first one trying to use ntmarta, initialize it and change
196 the pointer after initialization */
197 ErrorCode = LoadAndInitializeNtMarta();
198
199 if (ErrorCode == ERROR_SUCCESS)
200 {
201 /* try change the NtMarta pointer */
202 if (InterlockedCompareExchangePointer((PVOID)&NtMarta,
203 &NtMartaStatic,
204 NULL) != NULL)
205 {
206 /* another thread initialized ntmarta in the meanwhile, release
207 the reference of the dll loaded. */
208 FreeLibrary(NtMartaStatic.hDllInstance);
209 }
210 }
211 #if DBG
212 else
213 {
214 ERR("Failed to initialize ntmarta.dll! Error: 0x%x", ErrorCode);
215 }
216 #endif
217 }
218 else
219 {
220 /* ntmarta was already initialized */
221 ErrorCode = ERROR_SUCCESS;
222 }
223
224 return ErrorCode;
225 }
226
227
228 VOID
229 UnloadNtMarta(VOID)
230 {
231 if (InterlockedExchangePointer((PVOID)&NtMarta,
232 NULL) != NULL)
233 {
234 FreeLibrary(NtMartaStatic.hDllInstance);
235 }
236 }
237
238
239 /******************************************************************************/
240
241 /*
242 * @implemented
243 */
244 BOOL
245 STDCALL
246 AreAllAccessesGranted(DWORD GrantedAccess,
247 DWORD DesiredAccess)
248 {
249 return (BOOL)RtlAreAllAccessesGranted(GrantedAccess,
250 DesiredAccess);
251 }
252
253
254 /*
255 * @implemented
256 */
257 BOOL
258 STDCALL
259 AreAnyAccessesGranted(DWORD GrantedAccess,
260 DWORD DesiredAccess)
261 {
262 return (BOOL)RtlAreAnyAccessesGranted(GrantedAccess,
263 DesiredAccess);
264 }
265
266
267 /******************************************************************************
268 * GetFileSecurityA [ADVAPI32.@]
269 *
270 * Obtains Specified information about the security of a file or directory.
271 *
272 * PARAMS
273 * lpFileName [I] Name of the file to get info for
274 * RequestedInformation [I] SE_ flags from "winnt.h"
275 * pSecurityDescriptor [O] Destination for security information
276 * nLength [I] Length of pSecurityDescriptor
277 * lpnLengthNeeded [O] Destination for length of returned security information
278 *
279 * RETURNS
280 * Success: TRUE. pSecurityDescriptor contains the requested information.
281 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
282 *
283 * NOTES
284 * The information returned is constrained by the callers access rights and
285 * privileges.
286 *
287 * @implemented
288 */
289 BOOL
290 WINAPI
291 GetFileSecurityA(LPCSTR lpFileName,
292 SECURITY_INFORMATION RequestedInformation,
293 PSECURITY_DESCRIPTOR pSecurityDescriptor,
294 DWORD nLength,
295 LPDWORD lpnLengthNeeded)
296 {
297 UNICODE_STRING FileName;
298 NTSTATUS Status;
299 BOOL bResult;
300
301 Status = RtlCreateUnicodeStringFromAsciiz(&FileName,
302 (LPSTR)lpFileName);
303 if (!NT_SUCCESS(Status))
304 {
305 SetLastError(RtlNtStatusToDosError(Status));
306 return FALSE;
307 }
308
309 bResult = GetFileSecurityW(FileName.Buffer,
310 RequestedInformation,
311 pSecurityDescriptor,
312 nLength,
313 lpnLengthNeeded);
314
315 RtlFreeUnicodeString(&FileName);
316
317 return bResult;
318 }
319
320
321 /*
322 * @implemented
323 */
324 BOOL
325 WINAPI
326 GetFileSecurityW(LPCWSTR lpFileName,
327 SECURITY_INFORMATION RequestedInformation,
328 PSECURITY_DESCRIPTOR pSecurityDescriptor,
329 DWORD nLength,
330 LPDWORD lpnLengthNeeded)
331 {
332 OBJECT_ATTRIBUTES ObjectAttributes;
333 IO_STATUS_BLOCK StatusBlock;
334 UNICODE_STRING FileName;
335 ULONG AccessMask = 0;
336 HANDLE FileHandle;
337 NTSTATUS Status;
338
339 TRACE("GetFileSecurityW() called\n");
340
341 QuerySecurityAccessMask(RequestedInformation, &AccessMask);
342
343 if (!RtlDosPathNameToNtPathName_U(lpFileName,
344 &FileName,
345 NULL,
346 NULL))
347 {
348 ERR("Invalid path\n");
349 SetLastError(ERROR_INVALID_NAME);
350 return FALSE;
351 }
352
353 InitializeObjectAttributes(&ObjectAttributes,
354 &FileName,
355 OBJ_CASE_INSENSITIVE,
356 NULL,
357 NULL);
358
359 Status = NtOpenFile(&FileHandle,
360 AccessMask,
361 &ObjectAttributes,
362 &StatusBlock,
363 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
364 0);
365
366 RtlFreeHeap(RtlGetProcessHeap(),
367 0,
368 FileName.Buffer);
369
370 if (!NT_SUCCESS(Status))
371 {
372 ERR("NtOpenFile() failed (Status %lx)\n", Status);
373 SetLastError(RtlNtStatusToDosError(Status));
374 return FALSE;
375 }
376
377 Status = NtQuerySecurityObject(FileHandle,
378 RequestedInformation,
379 pSecurityDescriptor,
380 nLength,
381 lpnLengthNeeded);
382 NtClose(FileHandle);
383 if (!NT_SUCCESS(Status))
384 {
385 ERR("NtQuerySecurityObject() failed (Status %lx)\n", Status);
386 SetLastError(RtlNtStatusToDosError(Status));
387 return FALSE;
388 }
389
390 return TRUE;
391 }
392
393
394 /*
395 * @implemented
396 */
397 BOOL
398 STDCALL
399 GetKernelObjectSecurity(HANDLE Handle,
400 SECURITY_INFORMATION RequestedInformation,
401 PSECURITY_DESCRIPTOR pSecurityDescriptor,
402 DWORD nLength,
403 LPDWORD lpnLengthNeeded)
404 {
405 NTSTATUS Status;
406
407 Status = NtQuerySecurityObject(Handle,
408 RequestedInformation,
409 pSecurityDescriptor,
410 nLength,
411 lpnLengthNeeded);
412 if (!NT_SUCCESS(Status))
413 {
414 SetLastError(RtlNtStatusToDosError(Status));
415 return FALSE;
416 }
417
418 return TRUE;
419 }
420
421
422 /******************************************************************************
423 * SetFileSecurityA [ADVAPI32.@]
424 * Sets the security of a file or directory
425 *
426 * @implemented
427 */
428 BOOL
429 STDCALL
430 SetFileSecurityA(LPCSTR lpFileName,
431 SECURITY_INFORMATION SecurityInformation,
432 PSECURITY_DESCRIPTOR pSecurityDescriptor)
433 {
434 UNICODE_STRING FileName;
435 NTSTATUS Status;
436 BOOL bResult;
437
438 Status = RtlCreateUnicodeStringFromAsciiz(&FileName,
439 (LPSTR)lpFileName);
440 if (!NT_SUCCESS(Status))
441 {
442 SetLastError(RtlNtStatusToDosError(Status));
443 return FALSE;
444 }
445
446 bResult = SetFileSecurityW(FileName.Buffer,
447 SecurityInformation,
448 pSecurityDescriptor);
449
450 RtlFreeUnicodeString(&FileName);
451
452 return bResult;
453 }
454
455
456 /******************************************************************************
457 * SetFileSecurityW [ADVAPI32.@]
458 * Sets the security of a file or directory
459 *
460 * @implemented
461 */
462 BOOL
463 STDCALL
464 SetFileSecurityW(LPCWSTR lpFileName,
465 SECURITY_INFORMATION SecurityInformation,
466 PSECURITY_DESCRIPTOR pSecurityDescriptor)
467 {
468 OBJECT_ATTRIBUTES ObjectAttributes;
469 IO_STATUS_BLOCK StatusBlock;
470 UNICODE_STRING FileName;
471 ULONG AccessMask = 0;
472 HANDLE FileHandle;
473 NTSTATUS Status;
474
475 TRACE("SetFileSecurityW() called\n");
476
477 SetSecurityAccessMask(SecurityInformation, &AccessMask);
478
479 if (!RtlDosPathNameToNtPathName_U(lpFileName,
480 &FileName,
481 NULL,
482 NULL))
483 {
484 ERR("Invalid path\n");
485 SetLastError(ERROR_INVALID_NAME);
486 return FALSE;
487 }
488
489 InitializeObjectAttributes(&ObjectAttributes,
490 &FileName,
491 OBJ_CASE_INSENSITIVE,
492 NULL,
493 NULL);
494
495 Status = NtOpenFile(&FileHandle,
496 AccessMask,
497 &ObjectAttributes,
498 &StatusBlock,
499 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
500 0);
501
502 RtlFreeHeap(RtlGetProcessHeap(),
503 0,
504 FileName.Buffer);
505
506 if (!NT_SUCCESS(Status))
507 {
508 ERR("NtOpenFile() failed (Status %lx)\n", Status);
509 SetLastError(RtlNtStatusToDosError(Status));
510 return FALSE;
511 }
512
513 Status = NtSetSecurityObject(FileHandle,
514 SecurityInformation,
515 pSecurityDescriptor);
516 NtClose(FileHandle);
517
518 if (!NT_SUCCESS(Status))
519 {
520 ERR("NtSetSecurityObject() failed (Status %lx)\n", Status);
521 SetLastError(RtlNtStatusToDosError(Status));
522 return FALSE;
523 }
524
525 return TRUE;
526 }
527
528
529 /*
530 * @implemented
531 */
532 BOOL
533 STDCALL
534 SetKernelObjectSecurity(HANDLE Handle,
535 SECURITY_INFORMATION SecurityInformation,
536 PSECURITY_DESCRIPTOR SecurityDescriptor)
537 {
538 NTSTATUS Status;
539
540 Status = NtSetSecurityObject(Handle,
541 SecurityInformation,
542 SecurityDescriptor);
543 if (!NT_SUCCESS(Status))
544 {
545 SetLastError(RtlNtStatusToDosError(Status));
546 return FALSE;
547 }
548
549 return TRUE;
550 }
551
552
553 /*
554 * @implemented
555 */
556 BOOL
557 WINAPI
558 ImpersonateAnonymousToken(IN HANDLE ThreadHandle)
559 {
560 NTSTATUS Status;
561
562 Status = NtImpersonateAnonymousToken(ThreadHandle);
563 if (!NT_SUCCESS(Status))
564 {
565 SetLastError(RtlNtStatusToDosError(Status));
566 return FALSE;
567 }
568
569 return TRUE;
570 }
571
572
573 /*
574 * @implemented
575 */
576 BOOL
577 STDCALL
578 ImpersonateLoggedOnUser(HANDLE hToken)
579 {
580 SECURITY_QUALITY_OF_SERVICE Qos;
581 OBJECT_ATTRIBUTES ObjectAttributes;
582 HANDLE NewToken;
583 TOKEN_TYPE Type;
584 ULONG ReturnLength;
585 BOOL Duplicated;
586 NTSTATUS Status;
587
588 /* Get the token type */
589 Status = NtQueryInformationToken(hToken,
590 TokenType,
591 &Type,
592 sizeof(TOKEN_TYPE),
593 &ReturnLength);
594 if (!NT_SUCCESS(Status))
595 {
596 SetLastError(RtlNtStatusToDosError(Status));
597 return FALSE;
598 }
599
600 if (Type == TokenPrimary)
601 {
602 /* Create a duplicate impersonation token */
603 Qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
604 Qos.ImpersonationLevel = SecurityImpersonation;
605 Qos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
606 Qos.EffectiveOnly = FALSE;
607
608 ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
609 ObjectAttributes.RootDirectory = NULL;
610 ObjectAttributes.ObjectName = NULL;
611 ObjectAttributes.Attributes = 0;
612 ObjectAttributes.SecurityDescriptor = NULL;
613 ObjectAttributes.SecurityQualityOfService = &Qos;
614
615 Status = NtDuplicateToken(hToken,
616 TOKEN_IMPERSONATE | TOKEN_QUERY,
617 &ObjectAttributes,
618 FALSE,
619 TokenImpersonation,
620 &NewToken);
621 if (!NT_SUCCESS(Status))
622 {
623 SetLastError(RtlNtStatusToDosError(Status));
624 return FALSE;
625 }
626
627 Duplicated = TRUE;
628 }
629 else
630 {
631 /* User the original impersonation token */
632 NewToken = hToken;
633 Duplicated = FALSE;
634 }
635
636 /* Impersonate the the current thread */
637 Status = NtSetInformationThread(NtCurrentThread(),
638 ThreadImpersonationToken,
639 &NewToken,
640 sizeof(HANDLE));
641
642 if (Duplicated == TRUE)
643 {
644 NtClose(NewToken);
645 }
646
647 if (!NT_SUCCESS(Status))
648 {
649 SetLastError(RtlNtStatusToDosError(Status));
650 return FALSE;
651 }
652
653 return TRUE;
654 }
655
656
657 /*
658 * @implemented
659 */
660 BOOL
661 STDCALL
662 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
663 {
664 NTSTATUS Status;
665
666 Status = RtlImpersonateSelf(ImpersonationLevel);
667 if (!NT_SUCCESS(Status))
668 {
669 SetLastError(RtlNtStatusToDosError(Status));
670 return FALSE;
671 }
672
673 return TRUE;
674 }
675
676
677 /*
678 * @implemented
679 */
680 BOOL
681 STDCALL
682 RevertToSelf(VOID)
683 {
684 NTSTATUS Status;
685 HANDLE Token = NULL;
686
687 Status = NtSetInformationThread(NtCurrentThread(),
688 ThreadImpersonationToken,
689 &Token,
690 sizeof(HANDLE));
691 if (!NT_SUCCESS(Status))
692 {
693 SetLastError(RtlNtStatusToDosError(Status));
694 return FALSE;
695 }
696
697 return TRUE;
698 }
699
700
701 /******************************************************************************
702 * GetUserNameA [ADVAPI32.@]
703 *
704 * Get the current user name.
705 *
706 * PARAMS
707 * lpszName [O] Destination for the user name.
708 * lpSize [I/O] Size of lpszName.
709 *
710 *
711 * @implemented
712 */
713 BOOL
714 WINAPI
715 GetUserNameA(LPSTR lpszName,
716 LPDWORD lpSize)
717 {
718 UNICODE_STRING NameW;
719 ANSI_STRING NameA;
720 BOOL Ret;
721
722 /* apparently Win doesn't check whether lpSize is valid at all! */
723
724 NameW.MaximumLength = (*lpSize) * sizeof(WCHAR);
725 NameW.Buffer = LocalAlloc(LMEM_FIXED, NameW.MaximumLength);
726 if(NameW.Buffer == NULL)
727 {
728 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
729 return FALSE;
730 }
731
732 NameA.Length = 0;
733 NameA.MaximumLength = ((*lpSize) < 0xFFFF ? (USHORT)(*lpSize) : 0xFFFF);
734 NameA.Buffer = lpszName;
735
736 Ret = GetUserNameW(NameW.Buffer,
737 lpSize);
738 if(Ret)
739 {
740 NameW.Length = (*lpSize - 1) * sizeof(WCHAR);
741 RtlUnicodeStringToAnsiString(&NameA, &NameW, FALSE);
742
743 *lpSize = NameA.Length + 1;
744 }
745
746 LocalFree(NameW.Buffer);
747
748 return Ret;
749 }
750
751
752 /******************************************************************************
753 * GetUserNameW [ADVAPI32.@]
754 *
755 * See GetUserNameA.
756 *
757 * @implemented
758 */
759 BOOL
760 WINAPI
761 GetUserNameW(LPWSTR lpszName,
762 LPDWORD lpSize )
763 {
764 HANDLE hToken = INVALID_HANDLE_VALUE;
765 DWORD tu_len = 0;
766 char* tu_buf = NULL;
767 TOKEN_USER* token_user = NULL;
768 DWORD an_len = 0;
769 SID_NAME_USE snu = SidTypeUser;
770 WCHAR* domain_name = NULL;
771 DWORD dn_len = 0;
772
773 if ( !OpenThreadToken ( GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken ) )
774 {
775 DWORD dwLastError = GetLastError();
776 if ( dwLastError != ERROR_NO_TOKEN
777 && dwLastError != ERROR_NO_IMPERSONATION_TOKEN )
778 {
779 /* don't call SetLastError(),
780 as OpenThreadToken() ought to have set one */
781 return FALSE;
782 }
783 if ( !OpenProcessToken ( GetCurrentProcess(), TOKEN_QUERY, &hToken ) )
784 {
785 /* don't call SetLastError(),
786 as OpenProcessToken() ought to have set one */
787 return FALSE;
788 }
789 }
790 tu_buf = LocalAlloc ( LMEM_FIXED, 36 );
791 if ( !tu_buf )
792 {
793 SetLastError ( ERROR_NOT_ENOUGH_MEMORY );
794 CloseHandle ( hToken );
795 return FALSE;
796 }
797 if ( !GetTokenInformation ( hToken, TokenUser, tu_buf, 36, &tu_len ) || tu_len > 36 )
798 {
799 LocalFree ( tu_buf );
800 tu_buf = LocalAlloc ( LMEM_FIXED, tu_len );
801 if ( !tu_buf )
802 {
803 SetLastError ( ERROR_NOT_ENOUGH_MEMORY );
804 CloseHandle ( hToken );
805 return FALSE;
806 }
807 if ( !GetTokenInformation ( hToken, TokenUser, tu_buf, tu_len, &tu_len ) )
808 {
809 /* don't call SetLastError(),
810 as GetTokenInformation() ought to have set one */
811 LocalFree ( tu_buf );
812 CloseHandle ( hToken );
813 return FALSE;
814 }
815 }
816 CloseHandle ( hToken );
817 token_user = (TOKEN_USER*)tu_buf;
818
819 an_len = *lpSize;
820 dn_len = 32;
821 domain_name = LocalAlloc ( LMEM_FIXED, dn_len * sizeof(WCHAR) );
822 if ( !domain_name )
823 {
824 LocalFree ( tu_buf );
825 SetLastError ( ERROR_NOT_ENOUGH_MEMORY );
826 return FALSE;
827 }
828 if ( !LookupAccountSidW ( NULL, token_user->User.Sid, lpszName, &an_len, domain_name, &dn_len, &snu )
829 || dn_len > 32 )
830 {
831 if ( dn_len > 32 )
832 {
833 LocalFree ( domain_name );
834 domain_name = LocalAlloc ( LMEM_FIXED, dn_len * sizeof(WCHAR) );
835 if ( !domain_name )
836 {
837 LocalFree ( tu_buf );
838 SetLastError ( ERROR_NOT_ENOUGH_MEMORY );
839 return FALSE;
840 }
841 }
842 an_len = *lpSize;
843 if ( !LookupAccountSidW ( NULL, token_user->User.Sid, lpszName, &an_len, domain_name, &dn_len, &snu ) )
844 {
845 /* don't call SetLastError(),
846 as LookupAccountSid() ought to have set one */
847 LocalFree ( domain_name );
848 LocalFree ( tu_buf );
849 *lpSize = an_len;
850 return FALSE;
851 }
852 }
853
854 LocalFree ( domain_name );
855 LocalFree ( tu_buf );
856 *lpSize = an_len + 1;
857 return TRUE;
858 }
859
860
861 /******************************************************************************
862 * LookupAccountSidA [ADVAPI32.@]
863 *
864 * @implemented
865 */
866 BOOL
867 STDCALL
868 LookupAccountSidA(LPCSTR lpSystemName,
869 PSID lpSid,
870 LPSTR lpName,
871 LPDWORD cchName,
872 LPSTR lpReferencedDomainName,
873 LPDWORD cchReferencedDomainName,
874 PSID_NAME_USE peUse)
875 {
876 UNICODE_STRING NameW, ReferencedDomainNameW, SystemNameW;
877 DWORD szName, szReferencedDomainName;
878 BOOL Ret;
879
880 /*
881 * save the buffer sizes the caller passed to us, as they may get modified and
882 * we require the original values when converting back to ansi
883 */
884 szName = *cchName;
885 szReferencedDomainName = *cchReferencedDomainName;
886
887 /*
888 * allocate buffers for the unicode strings to receive
889 */
890
891 if(szName > 0)
892 {
893 NameW.Length = 0;
894 NameW.MaximumLength = szName * sizeof(WCHAR);
895 NameW.Buffer = (PWSTR)LocalAlloc(LMEM_FIXED, NameW.MaximumLength);
896 if(NameW.Buffer == NULL)
897 {
898 SetLastError(ERROR_OUTOFMEMORY);
899 return FALSE;
900 }
901 }
902 else
903 NameW.Buffer = NULL;
904
905 if(szReferencedDomainName > 0)
906 {
907 ReferencedDomainNameW.Length = 0;
908 ReferencedDomainNameW.MaximumLength = szReferencedDomainName * sizeof(WCHAR);
909 ReferencedDomainNameW.Buffer = (PWSTR)LocalAlloc(LMEM_FIXED, ReferencedDomainNameW.MaximumLength);
910 if(ReferencedDomainNameW.Buffer == NULL)
911 {
912 if(szName > 0)
913 {
914 LocalFree(NameW.Buffer);
915 }
916 SetLastError(ERROR_OUTOFMEMORY);
917 return FALSE;
918 }
919 }
920 else
921 ReferencedDomainNameW.Buffer = NULL;
922
923 /*
924 * convert the system name to unicode - if present
925 */
926
927 if(lpSystemName != NULL)
928 {
929 ANSI_STRING SystemNameA;
930
931 RtlInitAnsiString(&SystemNameA, lpSystemName);
932 RtlAnsiStringToUnicodeString(&SystemNameW, &SystemNameA, TRUE);
933 }
934 else
935 SystemNameW.Buffer = NULL;
936
937 /*
938 * it's time to call the unicode version
939 */
940
941 Ret = LookupAccountSidW(SystemNameW.Buffer,
942 lpSid,
943 NameW.Buffer,
944 cchName,
945 ReferencedDomainNameW.Buffer,
946 cchReferencedDomainName,
947 peUse);
948 if(Ret)
949 {
950 /*
951 * convert unicode strings back to ansi, don't forget that we can't convert
952 * more than 0xFFFF (USHORT) characters! Also don't forget to explicitly
953 * terminate the converted string, the Rtl functions don't do that!
954 */
955 if(lpName != NULL)
956 {
957 ANSI_STRING NameA;
958
959 NameA.Length = 0;
960 NameA.MaximumLength = ((szName <= 0xFFFF) ? (USHORT)szName : 0xFFFF);
961 NameA.Buffer = lpName;
962
963 RtlUnicodeStringToAnsiString(&NameA, &NameW, FALSE);
964 NameA.Buffer[NameA.Length] = '\0';
965 }
966
967 if(lpReferencedDomainName != NULL)
968 {
969 ANSI_STRING ReferencedDomainNameA;
970
971 ReferencedDomainNameA.Length = 0;
972 ReferencedDomainNameA.MaximumLength = ((szReferencedDomainName <= 0xFFFF) ?
973 (USHORT)szReferencedDomainName : 0xFFFF);
974 ReferencedDomainNameA.Buffer = lpReferencedDomainName;
975
976 RtlUnicodeStringToAnsiString(&ReferencedDomainNameA, &ReferencedDomainNameW, FALSE);
977 ReferencedDomainNameA.Buffer[ReferencedDomainNameA.Length] = '\0';
978 }
979 }
980
981 /*
982 * free previously allocated buffers
983 */
984
985 if(SystemNameW.Buffer != NULL)
986 {
987 RtlFreeUnicodeString(&SystemNameW);
988 }
989 if(NameW.Buffer != NULL)
990 {
991 LocalFree(NameW.Buffer);
992 }
993 if(ReferencedDomainNameW.Buffer != NULL)
994 {
995 LocalFree(ReferencedDomainNameW.Buffer);
996 }
997
998 return Ret;
999 }
1000
1001
1002 /******************************************************************************
1003 * LookupAccountSidW [ADVAPI32.@]
1004 *
1005 * @implemented
1006 */
1007 BOOL WINAPI
1008 LookupAccountSidW(LPCWSTR pSystemName,
1009 PSID pSid,
1010 LPWSTR pAccountName,
1011 LPDWORD pdwAccountName,
1012 LPWSTR pDomainName,
1013 LPDWORD pdwDomainName,
1014 PSID_NAME_USE peUse)
1015 {
1016 LSA_UNICODE_STRING SystemName;
1017 LSA_OBJECT_ATTRIBUTES ObjectAttributes = {0};
1018 LSA_HANDLE PolicyHandle = NULL;
1019 NTSTATUS Status;
1020 PLSA_REFERENCED_DOMAIN_LIST ReferencedDomain = NULL;
1021 PLSA_TRANSLATED_NAME TranslatedName = NULL;
1022 BOOL ret;
1023
1024 RtlInitUnicodeString ( &SystemName, pSystemName );
1025 Status = LsaOpenPolicy ( &SystemName, &ObjectAttributes, POLICY_LOOKUP_NAMES, &PolicyHandle );
1026 if ( !NT_SUCCESS(Status) )
1027 {
1028 SetLastError ( LsaNtStatusToWinError(Status) );
1029 return FALSE;
1030 }
1031 Status = LsaLookupSids ( PolicyHandle, 1, &pSid, &ReferencedDomain, &TranslatedName );
1032
1033 LsaClose ( PolicyHandle );
1034
1035 if ( !NT_SUCCESS(Status) || Status == STATUS_SOME_NOT_MAPPED )
1036 {
1037 SetLastError ( LsaNtStatusToWinError(Status) );
1038 ret = FALSE;
1039 }
1040 else
1041 {
1042 ret = TRUE;
1043 if ( TranslatedName )
1044 {
1045 DWORD dwSrcLen = TranslatedName->Name.Length / sizeof(WCHAR);
1046 if ( *pdwAccountName <= dwSrcLen )
1047 {
1048 *pdwAccountName = dwSrcLen + 1;
1049 ret = FALSE;
1050 }
1051 else
1052 {
1053 *pdwAccountName = dwSrcLen;
1054 if (pAccountName)
1055 {
1056 RtlCopyMemory ( pAccountName, TranslatedName->Name.Buffer, TranslatedName->Name.Length );
1057 pAccountName[TranslatedName->Name.Length / sizeof(WCHAR)] = L'\0';
1058 }
1059 }
1060 if ( peUse )
1061 *peUse = TranslatedName->Use;
1062 }
1063
1064 if ( ReferencedDomain )
1065 {
1066 if ( ReferencedDomain->Entries > 0 )
1067 {
1068 DWORD dwSrcLen = ReferencedDomain->Domains[0].Name.Length / sizeof(WCHAR);
1069 if ( *pdwDomainName <= dwSrcLen )
1070 {
1071 *pdwDomainName = dwSrcLen + 1;
1072 ret = FALSE;
1073 }
1074 else
1075 {
1076 *pdwDomainName = dwSrcLen;
1077 RtlCopyMemory ( pDomainName, ReferencedDomain->Domains[0].Name.Buffer, ReferencedDomain->Domains[0].Name.Length );
1078 pDomainName[ReferencedDomain->Domains[0].Name.Length / sizeof(WCHAR)] = L'\0';
1079 }
1080 }
1081 }
1082
1083 if ( !ret )
1084 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1085 }
1086
1087 if ( ReferencedDomain )
1088 LsaFreeMemory ( ReferencedDomain );
1089 if ( TranslatedName )
1090 LsaFreeMemory ( TranslatedName );
1091
1092 return ret;
1093 }
1094
1095
1096
1097 /******************************************************************************
1098 * LookupAccountNameA [ADVAPI32.@]
1099 *
1100 * @implemented
1101 */
1102 BOOL
1103 STDCALL
1104 LookupAccountNameA(LPCSTR SystemName,
1105 LPCSTR AccountName,
1106 PSID Sid,
1107 LPDWORD SidLength,
1108 LPSTR ReferencedDomainName,
1109 LPDWORD hReferencedDomainNameLength,
1110 PSID_NAME_USE SidNameUse)
1111 {
1112 BOOL ret;
1113 UNICODE_STRING lpSystemW;
1114 UNICODE_STRING lpAccountW;
1115 LPWSTR lpReferencedDomainNameW = NULL;
1116
1117 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, SystemName);
1118 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, AccountName);
1119
1120 if (ReferencedDomainName)
1121 lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(),
1122 0,
1123 *hReferencedDomainNameLength * sizeof(WCHAR));
1124
1125 ret = LookupAccountNameW(lpSystemW.Buffer,
1126 lpAccountW.Buffer,
1127 Sid,
1128 SidLength,
1129 lpReferencedDomainNameW,
1130 hReferencedDomainNameLength,
1131 SidNameUse);
1132
1133 if (ret && lpReferencedDomainNameW)
1134 {
1135 WideCharToMultiByte(CP_ACP,
1136 0,
1137 lpReferencedDomainNameW,
1138 *hReferencedDomainNameLength,
1139 ReferencedDomainName,
1140 *hReferencedDomainNameLength,
1141 NULL,
1142 NULL);
1143 }
1144
1145 RtlFreeUnicodeString(&lpSystemW);
1146 RtlFreeUnicodeString(&lpAccountW);
1147 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
1148
1149 return ret;
1150 }
1151
1152
1153 /******************************************************************************
1154 * LookupAccountNameW [ADVAPI32.@]
1155 *
1156 * @unimplemented
1157 */
1158 BOOL
1159 WINAPI
1160 LookupAccountNameW(LPCWSTR lpSystemName,
1161 LPCWSTR lpAccountName,
1162 PSID Sid,
1163 LPDWORD cbSid,
1164 LPWSTR ReferencedDomainName,
1165 LPDWORD cchReferencedDomainName,
1166 PSID_NAME_USE peUse)
1167 {
1168 /* Default implementation: Always return a default SID */
1169 SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
1170 BOOL ret;
1171 PSID pSid;
1172 static const WCHAR dm[] = {'D','O','M','A','I','N',0};
1173 unsigned int i;
1174
1175 TRACE("%s %s %p %p %p %p %p - stub\n", lpSystemName, lpAccountName,
1176 Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
1177
1178 for (i = 0; i < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); i++)
1179 {
1180 if (!wcscmp(lpAccountName, ACCOUNT_SIDS[i].account))
1181 {
1182 if (*cchReferencedDomainName)
1183 *ReferencedDomainName = '\0';
1184 *cchReferencedDomainName = 0;
1185 *peUse = SidTypeWellKnownGroup;
1186 return CreateWellKnownSid(ACCOUNT_SIDS[i].type, NULL, Sid, cbSid);
1187 }
1188 }
1189
1190 ret = AllocateAndInitializeSid(&identifierAuthority,
1191 2,
1192 SECURITY_BUILTIN_DOMAIN_RID,
1193 DOMAIN_ALIAS_RID_ADMINS,
1194 0, 0, 0, 0, 0, 0,
1195 &pSid);
1196
1197 if (!ret)
1198 return FALSE;
1199
1200 if (!RtlValidSid(pSid))
1201 {
1202 FreeSid(pSid);
1203 return FALSE;
1204 }
1205
1206 if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
1207 CopySid(*cbSid, Sid, pSid);
1208
1209 if (*cbSid < GetLengthSid(pSid))
1210 {
1211 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1212 ret = FALSE;
1213 }
1214
1215 *cbSid = GetLengthSid(pSid);
1216
1217 if (ReferencedDomainName != NULL && (*cchReferencedDomainName > wcslen(dm)))
1218 wcscpy(ReferencedDomainName, dm);
1219
1220 if (*cchReferencedDomainName <= wcslen(dm))
1221 {
1222 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1223 ret = FALSE;
1224 }
1225
1226 *cchReferencedDomainName = wcslen(dm)+1;
1227
1228 FreeSid(pSid);
1229
1230 return ret;
1231 }
1232
1233
1234 /**********************************************************************
1235 * LookupPrivilegeValueA EXPORTED
1236 *
1237 * @implemented
1238 */
1239 BOOL
1240 STDCALL
1241 LookupPrivilegeValueA(LPCSTR lpSystemName,
1242 LPCSTR lpName,
1243 PLUID lpLuid)
1244 {
1245 UNICODE_STRING SystemName;
1246 UNICODE_STRING Name;
1247 BOOL Result;
1248
1249 /* Remote system? */
1250 if (lpSystemName != NULL)
1251 {
1252 RtlCreateUnicodeStringFromAsciiz(&SystemName,
1253 (LPSTR)lpSystemName);
1254 }
1255
1256 /* Check the privilege name is not NULL */
1257 if (lpName == NULL)
1258 {
1259 SetLastError(ERROR_INVALID_PARAMETER);
1260 return FALSE;
1261 }
1262
1263 RtlCreateUnicodeStringFromAsciiz(&Name,
1264 (LPSTR)lpName);
1265
1266 Result = LookupPrivilegeValueW((lpSystemName != NULL) ? SystemName.Buffer : NULL,
1267 Name.Buffer,
1268 lpLuid);
1269
1270 RtlFreeUnicodeString(&Name);
1271
1272 /* Remote system? */
1273 if (lpSystemName != NULL)
1274 {
1275 RtlFreeUnicodeString(&SystemName);
1276 }
1277
1278 return Result;
1279 }
1280
1281
1282 /**********************************************************************
1283 * LookupPrivilegeValueW EXPORTED
1284 *
1285 * @unimplemented
1286 */
1287 BOOL
1288 STDCALL
1289 LookupPrivilegeValueW(LPCWSTR SystemName,
1290 LPCWSTR PrivName,
1291 PLUID Luid)
1292 {
1293 static const WCHAR * const DefaultPrivNames[] =
1294 {
1295 L"SeCreateTokenPrivilege",
1296 L"SeAssignPrimaryTokenPrivilege",
1297 L"SeLockMemoryPrivilege",
1298 L"SeIncreaseQuotaPrivilege",
1299 L"SeUnsolicitedInputPrivilege",
1300 L"SeMachineAccountPrivilege",
1301 L"SeTcbPrivilege",
1302 L"SeSecurityPrivilege",
1303 L"SeTakeOwnershipPrivilege",
1304 L"SeLoadDriverPrivilege",
1305 L"SeSystemProfilePrivilege",
1306 L"SeSystemtimePrivilege",
1307 L"SeProfileSingleProcessPrivilege",
1308 L"SeIncreaseBasePriorityPrivilege",
1309 L"SeCreatePagefilePrivilege",
1310 L"SeCreatePermanentPrivilege",
1311 L"SeBackupPrivilege",
1312 L"SeRestorePrivilege",
1313 L"SeShutdownPrivilege",
1314 L"SeDebugPrivilege",
1315 L"SeAuditPrivilege",
1316 L"SeSystemEnvironmentPrivilege",
1317 L"SeChangeNotifyPrivilege",
1318 L"SeRemoteShutdownPrivilege",
1319 L"SeUndockPrivilege",
1320 L"SeSyncAgentPrivilege",
1321 L"SeEnableDelegationPrivilege",
1322 L"SeManageVolumePrivilege",
1323 L"SeImpersonatePrivilege",
1324 L"SeCreateGlobalPrivilege"
1325 };
1326 unsigned Priv;
1327
1328 if (NULL != SystemName && L'\0' != *SystemName)
1329 {
1330 FIXME("LookupPrivilegeValueW: not implemented for remote system\n");
1331 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1332 return FALSE;
1333 }
1334
1335 for (Priv = 0; Priv < sizeof(DefaultPrivNames) / sizeof(DefaultPrivNames[0]); Priv++)
1336 {
1337 if (0 == wcscmp(PrivName, DefaultPrivNames[Priv]))
1338 {
1339 Luid->LowPart = Priv + 1;
1340 Luid->HighPart = 0;
1341 return TRUE;
1342 }
1343 }
1344
1345 WARN("LookupPrivilegeValueW: no such privilege %S\n", PrivName);
1346 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1347 return FALSE;
1348 }
1349
1350
1351 /**********************************************************************
1352 * LookupPrivilegeDisplayNameA EXPORTED
1353 *
1354 * @unimplemented
1355 */
1356 BOOL
1357 STDCALL
1358 LookupPrivilegeDisplayNameA(LPCSTR lpSystemName,
1359 LPCSTR lpName,
1360 LPSTR lpDisplayName,
1361 LPDWORD cbDisplayName,
1362 LPDWORD lpLanguageId)
1363 {
1364 FIXME("%s() not implemented!\n", __FUNCTION__);
1365 SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
1366 return FALSE;
1367 }
1368
1369
1370 /**********************************************************************
1371 * LookupPrivilegeDisplayNameW EXPORTED
1372 *
1373 * @unimplemented
1374 */
1375 BOOL
1376 STDCALL
1377 LookupPrivilegeDisplayNameW(LPCWSTR lpSystemName,
1378 LPCWSTR lpName,
1379 LPWSTR lpDisplayName,
1380 LPDWORD cbDisplayName,
1381 LPDWORD lpLanguageId)
1382 {
1383 FIXME("%s() not implemented!\n", __FUNCTION__);
1384 SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
1385 return FALSE;
1386 }
1387
1388
1389 /**********************************************************************
1390 * LookupPrivilegeNameA EXPORTED
1391 *
1392 * @unimplemented
1393 */
1394 BOOL
1395 STDCALL
1396 LookupPrivilegeNameA(LPCSTR lpSystemName,
1397 PLUID lpLuid,
1398 LPSTR lpName,
1399 LPDWORD cbName)
1400 {
1401 FIXME("%s() not implemented!\n", __FUNCTION__);
1402 SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
1403 return FALSE;
1404 }
1405
1406
1407 /**********************************************************************
1408 * LookupPrivilegeNameW EXPORTED
1409 *
1410 * @unimplemented
1411 */
1412 BOOL
1413 STDCALL
1414 LookupPrivilegeNameW(LPCWSTR lpSystemName,
1415 PLUID lpLuid,
1416 LPWSTR lpName,
1417 LPDWORD cbName)
1418 {
1419 FIXME("%s() not implemented!\n", __FUNCTION__);
1420 SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
1421 return FALSE;
1422 }
1423
1424
1425 static DWORD
1426 pGetSecurityInfoCheck(SECURITY_INFORMATION SecurityInfo,
1427 PSID *ppsidOwner,
1428 PSID *ppsidGroup,
1429 PACL *ppDacl,
1430 PACL *ppSacl,
1431 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
1432 {
1433 if ((SecurityInfo & (OWNER_SECURITY_INFORMATION |
1434 GROUP_SECURITY_INFORMATION |
1435 DACL_SECURITY_INFORMATION |
1436 SACL_SECURITY_INFORMATION)) &&
1437 ppSecurityDescriptor == NULL)
1438 {
1439 /* if one of the SIDs or ACLs are present, the security descriptor
1440 most not be NULL */
1441 return ERROR_INVALID_PARAMETER;
1442 }
1443 else
1444 {
1445 /* reset the pointers unless they're ignored */
1446 if ((SecurityInfo & OWNER_SECURITY_INFORMATION) &&
1447 ppsidOwner != NULL)
1448 {
1449 *ppsidOwner = NULL;
1450 }
1451 if ((SecurityInfo & GROUP_SECURITY_INFORMATION) &&
1452 ppsidGroup != NULL)
1453 {
1454 *ppsidGroup = NULL;
1455 }
1456 if ((SecurityInfo & DACL_SECURITY_INFORMATION) &&
1457 ppDacl != NULL)
1458 {
1459 *ppDacl = NULL;
1460 }
1461 if ((SecurityInfo & SACL_SECURITY_INFORMATION) &&
1462 ppSacl != NULL)
1463 {
1464 *ppSacl = NULL;
1465 }
1466
1467 if (SecurityInfo & (OWNER_SECURITY_INFORMATION |
1468 GROUP_SECURITY_INFORMATION |
1469 DACL_SECURITY_INFORMATION |
1470 SACL_SECURITY_INFORMATION))
1471 {
1472 *ppSecurityDescriptor = NULL;
1473 }
1474
1475 return ERROR_SUCCESS;
1476 }
1477 }
1478
1479
1480 static DWORD
1481 pSetSecurityInfoCheck(PSECURITY_DESCRIPTOR pSecurityDescriptor,
1482 SECURITY_INFORMATION SecurityInfo,
1483 PSID psidOwner,
1484 PSID psidGroup,
1485 PACL pDacl,
1486 PACL pSacl)
1487 {
1488 /* initialize a security descriptor on the stack */
1489 if (!InitializeSecurityDescriptor(pSecurityDescriptor,
1490 SECURITY_DESCRIPTOR_REVISION))
1491 {
1492 return GetLastError();
1493 }
1494
1495 if (SecurityInfo & OWNER_SECURITY_INFORMATION)
1496 {
1497 if (RtlValidSid(psidOwner))
1498 {
1499 if (!SetSecurityDescriptorOwner(pSecurityDescriptor,
1500 psidOwner,
1501 FALSE))
1502 {
1503 return GetLastError();
1504 }
1505 }
1506 else
1507 {
1508 return ERROR_INVALID_PARAMETER;
1509 }
1510 }
1511
1512 if (SecurityInfo & GROUP_SECURITY_INFORMATION)
1513 {
1514 if (RtlValidSid(psidGroup))
1515 {
1516 if (!SetSecurityDescriptorGroup(pSecurityDescriptor,
1517 psidGroup,
1518 FALSE))
1519 {
1520 return GetLastError();
1521 }
1522 }
1523 else
1524 {
1525 return ERROR_INVALID_PARAMETER;
1526 }
1527 }
1528
1529 if (SecurityInfo & DACL_SECURITY_INFORMATION)
1530 {
1531 if (pDacl != NULL)
1532 {
1533 if (SetSecurityDescriptorDacl(pSecurityDescriptor,
1534 TRUE,
1535 pDacl,
1536 FALSE))
1537 {
1538 /* check if the DACL needs to be protected from being
1539 modified by inheritable ACEs */
1540 if (SecurityInfo & PROTECTED_DACL_SECURITY_INFORMATION)
1541 {
1542 goto ProtectDacl;
1543 }
1544 }
1545 else
1546 {
1547 return GetLastError();
1548 }
1549 }
1550 else
1551 {
1552 ProtectDacl:
1553 /* protect the DACL from being modified by inheritable ACEs */
1554 if (!SetSecurityDescriptorControl(pSecurityDescriptor,
1555 SE_DACL_PROTECTED,
1556 SE_DACL_PROTECTED))
1557 {
1558 return GetLastError();
1559 }
1560 }
1561 }
1562
1563 if (SecurityInfo & SACL_SECURITY_INFORMATION)
1564 {
1565 if (pSacl != NULL)
1566 {
1567 if (SetSecurityDescriptorSacl(pSecurityDescriptor,
1568 TRUE,
1569 pSacl,
1570 FALSE))
1571 {
1572 /* check if the SACL needs to be protected from being
1573 modified by inheritable ACEs */
1574 if (SecurityInfo & PROTECTED_SACL_SECURITY_INFORMATION)
1575 {
1576 goto ProtectSacl;
1577 }
1578 }
1579 else
1580 {
1581 return GetLastError();
1582 }
1583 }
1584 else
1585 {
1586 ProtectSacl:
1587 /* protect the SACL from being modified by inheritable ACEs */
1588 if (!SetSecurityDescriptorControl(pSecurityDescriptor,
1589 SE_SACL_PROTECTED,
1590 SE_SACL_PROTECTED))
1591 {
1592 return GetLastError();
1593 }
1594 }
1595 }
1596
1597 return ERROR_SUCCESS;
1598 }
1599
1600
1601 /**********************************************************************
1602 * GetNamedSecurityInfoW EXPORTED
1603 *
1604 * @implemented
1605 */
1606 DWORD
1607 STDCALL
1608 GetNamedSecurityInfoW(LPWSTR pObjectName,
1609 SE_OBJECT_TYPE ObjectType,
1610 SECURITY_INFORMATION SecurityInfo,
1611 PSID *ppsidOwner,
1612 PSID *ppsidGroup,
1613 PACL *ppDacl,
1614 PACL *ppSacl,
1615 PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
1616 {
1617 DWORD ErrorCode;
1618
1619 if (pObjectName != NULL)
1620 {
1621 ErrorCode = CheckNtMartaPresent();
1622 if (ErrorCode == ERROR_SUCCESS)
1623 {
1624 ErrorCode = pGetSecurityInfoCheck(SecurityInfo,
1625 ppsidOwner,
1626 ppsidGroup,
1627 ppDacl,
1628 ppSacl,
1629 ppSecurityDescriptor);
1630
1631 if (ErrorCode == ERROR_SUCCESS)
1632 {
1633 /* call the MARTA provider */
1634 ErrorCode = AccRewriteGetNamedRights(pObjectName,
1635 ObjectType,
1636 SecurityInfo,
1637 ppsidOwner,
1638 ppsidGroup,
1639 ppDacl,
1640 ppSacl,
1641 ppSecurityDescriptor);
1642 }
1643 }
1644 }
1645 else
1646 ErrorCode = ERROR_INVALID_PARAMETER;
1647
1648 return ErrorCode;
1649 }
1650
1651
1652 /**********************************************************************
1653 * GetNamedSecurityInfoA EXPORTED
1654 *
1655 * @implemented
1656 */
1657 DWORD
1658 STDCALL
1659 GetNamedSecurityInfoA(LPSTR pObjectName,
1660 SE_OBJECT_TYPE ObjectType,
1661 SECURITY_INFORMATION SecurityInfo,
1662 PSID *ppsidOwner,
1663 PSID *ppsidGroup,
1664 PACL *ppDacl,
1665 PACL *ppSacl,
1666 PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
1667 {
1668 UNICODE_STRING ObjectName;
1669 NTSTATUS Status;
1670 DWORD Ret;
1671
1672 Status = RtlCreateUnicodeStringFromAsciiz(&ObjectName,
1673 pObjectName);
1674 if (!NT_SUCCESS(Status))
1675 {
1676 return RtlNtStatusToDosError(Status);
1677 }
1678
1679 Ret = GetNamedSecurityInfoW(ObjectName.Buffer,
1680 ObjectType,
1681 SecurityInfo,
1682 ppsidOwner,
1683 ppsidGroup,
1684 ppDacl,
1685 ppSacl,
1686 ppSecurityDescriptor);
1687
1688 RtlFreeUnicodeString(&ObjectName);
1689
1690 return Ret;
1691 }
1692
1693
1694 /**********************************************************************
1695 * SetNamedSecurityInfoW EXPORTED
1696 *
1697 * @implemented
1698 */
1699 DWORD
1700 STDCALL
1701 SetNamedSecurityInfoW(LPWSTR pObjectName,
1702 SE_OBJECT_TYPE ObjectType,
1703 SECURITY_INFORMATION SecurityInfo,
1704 PSID psidOwner,
1705 PSID psidGroup,
1706 PACL pDacl,
1707 PACL pSacl)
1708 {
1709 DWORD ErrorCode;
1710
1711 if (pObjectName != NULL)
1712 {
1713 ErrorCode = CheckNtMartaPresent();
1714 if (ErrorCode == ERROR_SUCCESS)
1715 {
1716 SECURITY_DESCRIPTOR SecurityDescriptor;
1717
1718 ErrorCode = pSetSecurityInfoCheck(&SecurityDescriptor,
1719 SecurityInfo,
1720 psidOwner,
1721 psidGroup,
1722 pDacl,
1723 pSacl);
1724
1725 if (ErrorCode == ERROR_SUCCESS)
1726 {
1727 /* call the MARTA provider */
1728 ErrorCode = AccRewriteSetNamedRights(pObjectName,
1729 ObjectType,
1730 SecurityInfo,
1731 &SecurityDescriptor);
1732 }
1733 }
1734 }
1735 else
1736 ErrorCode = ERROR_INVALID_PARAMETER;
1737
1738 return ErrorCode;
1739 }
1740
1741
1742 /**********************************************************************
1743 * SetNamedSecurityInfoA EXPORTED
1744 *
1745 * @implemented
1746 */
1747 DWORD
1748 STDCALL
1749 SetNamedSecurityInfoA(LPSTR pObjectName,
1750 SE_OBJECT_TYPE ObjectType,
1751 SECURITY_INFORMATION SecurityInfo,
1752 PSID psidOwner,
1753 PSID psidGroup,
1754 PACL pDacl,
1755 PACL pSacl)
1756 {
1757 UNICODE_STRING ObjectName;
1758 NTSTATUS Status;
1759 DWORD Ret;
1760
1761 Status = RtlCreateUnicodeStringFromAsciiz(&ObjectName,
1762 pObjectName);
1763 if (!NT_SUCCESS(Status))
1764 {
1765 return RtlNtStatusToDosError(Status);
1766 }
1767
1768 Ret = SetNamedSecurityInfoW(ObjectName.Buffer,
1769 ObjectType,
1770 SecurityInfo,
1771 psidOwner,
1772 psidGroup,
1773 pDacl,
1774 pSacl);
1775
1776 RtlFreeUnicodeString(&ObjectName);
1777
1778 return Ret;
1779 }
1780
1781
1782 /**********************************************************************
1783 * GetSecurityInfo EXPORTED
1784 *
1785 * @implemented
1786 */
1787 DWORD
1788 STDCALL
1789 GetSecurityInfo(HANDLE handle,
1790 SE_OBJECT_TYPE ObjectType,
1791 SECURITY_INFORMATION SecurityInfo,
1792 PSID *ppsidOwner,
1793 PSID *ppsidGroup,
1794 PACL *ppDacl,
1795 PACL *ppSacl,
1796 PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
1797 {
1798 DWORD ErrorCode;
1799
1800 if (handle != NULL)
1801 {
1802 ErrorCode = CheckNtMartaPresent();
1803 if (ErrorCode == ERROR_SUCCESS)
1804 {
1805 ErrorCode = pGetSecurityInfoCheck(SecurityInfo,
1806 ppsidOwner,
1807 ppsidGroup,
1808 ppDacl,
1809 ppSacl,
1810 ppSecurityDescriptor);
1811
1812 if (ErrorCode == ERROR_SUCCESS)
1813 {
1814 /* call the MARTA provider */
1815 ErrorCode = AccRewriteGetHandleRights(handle,
1816 ObjectType,
1817 SecurityInfo,
1818 ppsidOwner,
1819 ppsidGroup,
1820 ppDacl,
1821 ppSacl,
1822 ppSecurityDescriptor);
1823 }
1824 }
1825 }
1826 else
1827 ErrorCode = ERROR_INVALID_HANDLE;
1828
1829 return ErrorCode;
1830 }
1831
1832
1833 /**********************************************************************
1834 * SetSecurityInfo EXPORTED
1835 *
1836 * @implemented
1837 */
1838 DWORD
1839 WINAPI
1840 SetSecurityInfo(HANDLE handle,
1841 SE_OBJECT_TYPE ObjectType,
1842 SECURITY_INFORMATION SecurityInfo,
1843 PSID psidOwner,
1844 PSID psidGroup,
1845 PACL pDacl,
1846 PACL pSacl)
1847 {
1848 DWORD ErrorCode;
1849
1850 if (handle != NULL)
1851 {
1852 ErrorCode = CheckNtMartaPresent();
1853 if (ErrorCode == ERROR_SUCCESS)
1854 {
1855 SECURITY_DESCRIPTOR SecurityDescriptor;
1856
1857 ErrorCode = pSetSecurityInfoCheck(&SecurityDescriptor,
1858 SecurityInfo,
1859 psidOwner,
1860 psidGroup,
1861 pDacl,
1862 pSacl);
1863
1864 if (ErrorCode == ERROR_SUCCESS)
1865 {
1866 /* call the MARTA provider */
1867 ErrorCode = AccRewriteSetHandleRights(handle,
1868 ObjectType,
1869 SecurityInfo,
1870 &SecurityDescriptor);
1871 }
1872 }
1873 }
1874 else
1875 ErrorCode = ERROR_INVALID_HANDLE;
1876
1877 return ErrorCode;
1878 }
1879
1880
1881 /******************************************************************************
1882 * GetSecurityInfoExW EXPORTED
1883 */
1884 DWORD
1885 WINAPI
1886 GetSecurityInfoExA(HANDLE hObject,
1887 SE_OBJECT_TYPE ObjectType,
1888 SECURITY_INFORMATION SecurityInfo,
1889 LPCSTR lpProvider,
1890 LPCSTR lpProperty,
1891 PACTRL_ACCESSA *ppAccessList,
1892 PACTRL_AUDITA *ppAuditList,
1893 LPSTR *lppOwner,
1894 LPSTR *lppGroup)
1895 {
1896 FIXME("%s() not implemented!\n", __FUNCTION__);
1897 return ERROR_BAD_PROVIDER;
1898 }
1899
1900
1901 /******************************************************************************
1902 * GetSecurityInfoExW EXPORTED
1903 */
1904 DWORD
1905 WINAPI
1906 GetSecurityInfoExW(HANDLE hObject,
1907 SE_OBJECT_TYPE ObjectType,
1908 SECURITY_INFORMATION SecurityInfo,
1909 LPCWSTR lpProvider,
1910 LPCWSTR lpProperty,
1911 PACTRL_ACCESSW *ppAccessList,
1912 PACTRL_AUDITW *ppAuditList,
1913 LPWSTR *lppOwner,
1914 LPWSTR *lppGroup)
1915 {
1916 FIXME("%s() not implemented!\n", __FUNCTION__);
1917 return ERROR_BAD_PROVIDER;
1918 }
1919
1920
1921 /**********************************************************************
1922 * ImpersonateNamedPipeClient EXPORTED
1923 *
1924 * @implemented
1925 */
1926 BOOL
1927 STDCALL
1928 ImpersonateNamedPipeClient(HANDLE hNamedPipe)
1929 {
1930 IO_STATUS_BLOCK StatusBlock;
1931 NTSTATUS Status;
1932
1933 TRACE("ImpersonateNamedPipeClient() called\n");
1934
1935 Status = NtFsControlFile(hNamedPipe,
1936 NULL,
1937 NULL,
1938 NULL,
1939 &StatusBlock,
1940 FSCTL_PIPE_IMPERSONATE,
1941 NULL,
1942 0,
1943 NULL,
1944 0);
1945 if (!NT_SUCCESS(Status))
1946 {
1947 SetLastError(RtlNtStatusToDosError(Status));
1948 return FALSE;
1949 }
1950
1951 return TRUE;
1952 }
1953
1954
1955 /*
1956 * @implemented
1957 */
1958 BOOL
1959 STDCALL
1960 CreatePrivateObjectSecurity(PSECURITY_DESCRIPTOR ParentDescriptor,
1961 PSECURITY_DESCRIPTOR CreatorDescriptor,
1962 PSECURITY_DESCRIPTOR *NewDescriptor,
1963 BOOL IsDirectoryObject,
1964 HANDLE Token,
1965 PGENERIC_MAPPING GenericMapping)
1966 {
1967 NTSTATUS Status;
1968
1969 Status = RtlNewSecurityObject(ParentDescriptor,
1970 CreatorDescriptor,
1971 NewDescriptor,
1972 IsDirectoryObject,
1973 Token,
1974 GenericMapping);
1975 if (!NT_SUCCESS(Status))
1976 {
1977 SetLastError(RtlNtStatusToDosError(Status));
1978 return FALSE;
1979 }
1980
1981 return TRUE;
1982 }
1983
1984
1985 /*
1986 * @unimplemented
1987 */
1988 BOOL
1989 STDCALL
1990 CreatePrivateObjectSecurityEx(PSECURITY_DESCRIPTOR ParentDescriptor,
1991 PSECURITY_DESCRIPTOR CreatorDescriptor,
1992 PSECURITY_DESCRIPTOR* NewDescriptor,
1993 GUID* ObjectType,
1994 BOOL IsContainerObject,
1995 ULONG AutoInheritFlags,
1996 HANDLE Token,
1997 PGENERIC_MAPPING GenericMapping)
1998 {
1999 FIXME("%s() not implemented!\n", __FUNCTION__);
2000 return FALSE;
2001 }
2002
2003
2004 /*
2005 * @unimplemented
2006 */
2007 BOOL
2008 STDCALL
2009 CreatePrivateObjectSecurityWithMultipleInheritance(PSECURITY_DESCRIPTOR ParentDescriptor,
2010 PSECURITY_DESCRIPTOR CreatorDescriptor,
2011 PSECURITY_DESCRIPTOR* NewDescriptor,
2012 GUID** ObjectTypes,
2013 ULONG GuidCount,
2014 BOOL IsContainerObject,
2015 ULONG AutoInheritFlags,
2016 HANDLE Token,
2017 PGENERIC_MAPPING GenericMapping)
2018 {
2019 FIXME("%s() not implemented!\n", __FUNCTION__);
2020 return FALSE;
2021 }
2022
2023
2024 /*
2025 * @implemented
2026 */
2027 BOOL
2028 STDCALL
2029 DestroyPrivateObjectSecurity(PSECURITY_DESCRIPTOR *ObjectDescriptor)
2030 {
2031 NTSTATUS Status;
2032
2033 Status = RtlDeleteSecurityObject(ObjectDescriptor);
2034 if (!NT_SUCCESS(Status))
2035 {
2036 SetLastError(RtlNtStatusToDosError(Status));
2037 return FALSE;
2038 }
2039
2040 return TRUE;
2041 }
2042
2043
2044 /*
2045 * @implemented
2046 */
2047 BOOL
2048 STDCALL
2049 GetPrivateObjectSecurity(PSECURITY_DESCRIPTOR ObjectDescriptor,
2050 SECURITY_INFORMATION SecurityInformation,
2051 PSECURITY_DESCRIPTOR ResultantDescriptor,
2052 DWORD DescriptorLength,
2053 PDWORD ReturnLength)
2054 {
2055 NTSTATUS Status;
2056
2057 Status = RtlQuerySecurityObject(ObjectDescriptor,
2058 SecurityInformation,
2059 ResultantDescriptor,
2060 DescriptorLength,
2061 ReturnLength);
2062 if (!NT_SUCCESS(Status))
2063 {
2064 SetLastError(RtlNtStatusToDosError(Status));
2065 return FALSE;
2066 }
2067
2068 return TRUE;
2069 }
2070
2071
2072 /*
2073 * @implemented
2074 */
2075 BOOL
2076 STDCALL
2077 SetPrivateObjectSecurity(SECURITY_INFORMATION SecurityInformation,
2078 PSECURITY_DESCRIPTOR ModificationDescriptor,
2079 PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
2080 PGENERIC_MAPPING GenericMapping,
2081 HANDLE Token)
2082 {
2083 NTSTATUS Status;
2084
2085 Status = RtlSetSecurityObject(SecurityInformation,
2086 ModificationDescriptor,
2087 ObjectsSecurityDescriptor,
2088 GenericMapping,
2089 Token);
2090 if (!NT_SUCCESS(Status))
2091 {
2092 SetLastError(RtlNtStatusToDosError(Status));
2093 return FALSE;
2094 }
2095
2096 return TRUE;
2097 }
2098
2099
2100 /*
2101 * @implemented
2102 */
2103 DWORD
2104 STDCALL
2105 TreeResetNamedSecurityInfoW(LPWSTR pObjectName,
2106 SE_OBJECT_TYPE ObjectType,
2107 SECURITY_INFORMATION SecurityInfo,
2108 PSID pOwner,
2109 PSID pGroup,
2110 PACL pDacl,
2111 PACL pSacl,
2112 BOOL KeepExplicit,
2113 FN_PROGRESSW fnProgress,
2114 PROG_INVOKE_SETTING ProgressInvokeSetting,
2115 PVOID Args)
2116 {
2117 DWORD ErrorCode;
2118
2119 if (pObjectName != NULL)
2120 {
2121 ErrorCode = CheckNtMartaPresent();
2122 if (ErrorCode == ERROR_SUCCESS)
2123 {
2124 switch (ObjectType)
2125 {
2126 case SE_FILE_OBJECT:
2127 case SE_REGISTRY_KEY:
2128 {
2129 /* check the SecurityInfo flags for sanity (both, the protected
2130 and unprotected dacl/sacl flag must not be passed together) */
2131 if (((SecurityInfo & DACL_SECURITY_INFORMATION) &&
2132 (SecurityInfo & (PROTECTED_DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION)) ==
2133 (PROTECTED_DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION))
2134
2135 ||
2136
2137 ((SecurityInfo & SACL_SECURITY_INFORMATION) &&
2138 (SecurityInfo & (PROTECTED_SACL_SECURITY_INFORMATION | UNPROTECTED_SACL_SECURITY_INFORMATION)) ==
2139 (PROTECTED_SACL_SECURITY_INFORMATION | UNPROTECTED_SACL_SECURITY_INFORMATION)))
2140 {
2141 ErrorCode = ERROR_INVALID_PARAMETER;
2142 break;
2143 }
2144
2145 /* call the MARTA provider */
2146 ErrorCode = AccTreeResetNamedSecurityInfo(pObjectName,
2147 ObjectType,
2148 SecurityInfo,
2149 pOwner,
2150 pGroup,
2151 pDacl,
2152 pSacl,
2153 KeepExplicit,
2154 fnProgress,
2155 ProgressInvokeSetting,
2156 Args);
2157 break;
2158 }
2159
2160 default:
2161 /* object type not supported */
2162 ErrorCode = ERROR_INVALID_PARAMETER;
2163 break;
2164 }
2165 }
2166 }
2167 else
2168 ErrorCode = ERROR_INVALID_PARAMETER;
2169
2170 return ErrorCode;
2171 }
2172
2173 #ifdef HAS_FN_PROGRESSW
2174
2175 typedef struct _INERNAL_FNPROGRESSW_DATA
2176 {
2177 FN_PROGRESSA fnProgress;
2178 PVOID Args;
2179 } INERNAL_FNPROGRESSW_DATA, *PINERNAL_FNPROGRESSW_DATA;
2180
2181 static VOID STDCALL
2182 InternalfnProgressW(LPWSTR pObjectName,
2183 DWORD Status,
2184 PPROG_INVOKE_SETTING pInvokeSetting,
2185 PVOID Args,
2186 BOOL SecuritySet)
2187 {
2188 PINERNAL_FNPROGRESSW_DATA pifnProgressData = (PINERNAL_FNPROGRESSW_DATA)Args;
2189 INT ObjectNameSize;
2190 LPSTR pObjectNameA;
2191
2192 ObjectNameSize = WideCharToMultiByte(CP_ACP,
2193 0,
2194 pObjectName,
2195 -1,
2196 NULL,
2197 0,
2198 NULL,
2199 NULL);
2200
2201 if (ObjectNameSize > 0)
2202 {
2203 pObjectNameA = RtlAllocateHeap(RtlGetProcessHeap(),
2204 0,
2205 ObjectNameSize);
2206 if (pObjectNameA != NULL)
2207 {
2208 pObjectNameA[0] = '\0';
2209 WideCharToMultiByte(CP_ACP,
2210 0,
2211 pObjectName,
2212 -1,
2213 pObjectNameA,
2214 ObjectNameSize,
2215 NULL,
2216 NULL);
2217
2218 pifnProgressData->fnProgress((LPWSTR)pObjectNameA, /* FIXME: wrong cast!! */
2219 Status,
2220 pInvokeSetting,
2221 pifnProgressData->Args,
2222 SecuritySet);
2223
2224 RtlFreeHeap(RtlGetProcessHeap(),
2225 0,
2226 pObjectNameA);
2227 }
2228 }
2229 }
2230 #endif
2231
2232
2233 /*
2234 * @implemented
2235 */
2236 DWORD
2237 STDCALL
2238 TreeResetNamedSecurityInfoA(LPSTR pObjectName,
2239 SE_OBJECT_TYPE ObjectType,
2240 SECURITY_INFORMATION SecurityInfo,
2241 PSID pOwner,
2242 PSID pGroup,
2243 PACL pDacl,
2244 PACL pSacl,
2245 BOOL KeepExplicit,
2246 FN_PROGRESSA fnProgress,
2247 PROG_INVOKE_SETTING ProgressInvokeSetting,
2248 PVOID Args)
2249 {
2250 #ifndef HAS_FN_PROGRESSW
2251 /* That's all this function does, at least up to w2k3... Even MS was too
2252 lazy to implement it... */
2253 return ERROR_CALL_NOT_IMPLEMENTED;
2254 #else
2255 INERNAL_FNPROGRESSW_DATA ifnProgressData;
2256 UNICODE_STRING ObjectName;
2257 NTSTATUS Status;
2258 DWORD Ret;
2259
2260 Status = RtlCreateUnicodeStringFromAsciiz(&ObjectName,
2261 pObjectName);
2262 if (!NT_SUCCESS(Status))
2263 {
2264 return RtlNtStatusToDosError(Status);
2265 }
2266
2267 ifnProgressData.fnProgress = fnProgress;
2268 ifnProgressData.Args = Args;
2269
2270 Ret = TreeResetNamedSecurityInfoW(ObjectName.Buffer,
2271 ObjectType,
2272 SecurityInfo,
2273 pOwner,
2274 pGroup,
2275 pDacl,
2276 pSacl,
2277 KeepExplicit,
2278 (fnProgress != NULL ? InternalfnProgressW : NULL),
2279 ProgressInvokeSetting,
2280 &ifnProgressData);
2281
2282 RtlFreeUnicodeString(&ObjectName);
2283
2284 return Ret;
2285 #endif
2286 }
2287
2288 /* EOF */