import LookupPrivilegeNameA from wine
[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(&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(&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(&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 cchName)
1400 {
1401 UNICODE_STRING lpSystemNameW;
1402 BOOL ret;
1403 DWORD wLen = 0;
1404
1405 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1406
1407 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1408 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1409 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1410 {
1411 LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1412
1413 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1414 &wLen);
1415 if (ret)
1416 {
1417 /* Windows crashes if cchName is NULL, so will I */
1418 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1419 *cchName, NULL, NULL);
1420
1421 if (len == 0)
1422 {
1423 /* WideCharToMultiByte failed */
1424 ret = FALSE;
1425 }
1426 else if (len > *cchName)
1427 {
1428 *cchName = len;
1429 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1430 ret = FALSE;
1431 }
1432 else
1433 {
1434 /* WideCharToMultiByte succeeded, output length needs to be
1435 * length not including NULL terminator
1436 */
1437 *cchName = len - 1;
1438 }
1439 }
1440 HeapFree(GetProcessHeap(), 0, lpNameW);
1441 }
1442 RtlFreeUnicodeString(&lpSystemNameW);
1443 return ret;
1444 }
1445
1446
1447 /**********************************************************************
1448 * LookupPrivilegeNameW EXPORTED
1449 *
1450 * @unimplemented
1451 */
1452 BOOL
1453 STDCALL
1454 LookupPrivilegeNameW(LPCWSTR lpSystemName,
1455 PLUID lpLuid,
1456 LPWSTR lpName,
1457 LPDWORD cbName)
1458 {
1459 FIXME("%s() not implemented!\n", __FUNCTION__);
1460 SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
1461 return FALSE;
1462 }
1463
1464
1465 static DWORD
1466 pGetSecurityInfoCheck(SECURITY_INFORMATION SecurityInfo,
1467 PSID *ppsidOwner,
1468 PSID *ppsidGroup,
1469 PACL *ppDacl,
1470 PACL *ppSacl,
1471 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
1472 {
1473 if ((SecurityInfo & (OWNER_SECURITY_INFORMATION |
1474 GROUP_SECURITY_INFORMATION |
1475 DACL_SECURITY_INFORMATION |
1476 SACL_SECURITY_INFORMATION)) &&
1477 ppSecurityDescriptor == NULL)
1478 {
1479 /* if one of the SIDs or ACLs are present, the security descriptor
1480 most not be NULL */
1481 return ERROR_INVALID_PARAMETER;
1482 }
1483 else
1484 {
1485 /* reset the pointers unless they're ignored */
1486 if ((SecurityInfo & OWNER_SECURITY_INFORMATION) &&
1487 ppsidOwner != NULL)
1488 {
1489 *ppsidOwner = NULL;
1490 }
1491 if ((SecurityInfo & GROUP_SECURITY_INFORMATION) &&
1492 ppsidGroup != NULL)
1493 {
1494 *ppsidGroup = NULL;
1495 }
1496 if ((SecurityInfo & DACL_SECURITY_INFORMATION) &&
1497 ppDacl != NULL)
1498 {
1499 *ppDacl = NULL;
1500 }
1501 if ((SecurityInfo & SACL_SECURITY_INFORMATION) &&
1502 ppSacl != NULL)
1503 {
1504 *ppSacl = NULL;
1505 }
1506
1507 if (SecurityInfo & (OWNER_SECURITY_INFORMATION |
1508 GROUP_SECURITY_INFORMATION |
1509 DACL_SECURITY_INFORMATION |
1510 SACL_SECURITY_INFORMATION))
1511 {
1512 *ppSecurityDescriptor = NULL;
1513 }
1514
1515 return ERROR_SUCCESS;
1516 }
1517 }
1518
1519
1520 static DWORD
1521 pSetSecurityInfoCheck(PSECURITY_DESCRIPTOR pSecurityDescriptor,
1522 SECURITY_INFORMATION SecurityInfo,
1523 PSID psidOwner,
1524 PSID psidGroup,
1525 PACL pDacl,
1526 PACL pSacl)
1527 {
1528 /* initialize a security descriptor on the stack */
1529 if (!InitializeSecurityDescriptor(pSecurityDescriptor,
1530 SECURITY_DESCRIPTOR_REVISION))
1531 {
1532 return GetLastError();
1533 }
1534
1535 if (SecurityInfo & OWNER_SECURITY_INFORMATION)
1536 {
1537 if (RtlValidSid(psidOwner))
1538 {
1539 if (!SetSecurityDescriptorOwner(pSecurityDescriptor,
1540 psidOwner,
1541 FALSE))
1542 {
1543 return GetLastError();
1544 }
1545 }
1546 else
1547 {
1548 return ERROR_INVALID_PARAMETER;
1549 }
1550 }
1551
1552 if (SecurityInfo & GROUP_SECURITY_INFORMATION)
1553 {
1554 if (RtlValidSid(psidGroup))
1555 {
1556 if (!SetSecurityDescriptorGroup(pSecurityDescriptor,
1557 psidGroup,
1558 FALSE))
1559 {
1560 return GetLastError();
1561 }
1562 }
1563 else
1564 {
1565 return ERROR_INVALID_PARAMETER;
1566 }
1567 }
1568
1569 if (SecurityInfo & DACL_SECURITY_INFORMATION)
1570 {
1571 if (pDacl != NULL)
1572 {
1573 if (SetSecurityDescriptorDacl(pSecurityDescriptor,
1574 TRUE,
1575 pDacl,
1576 FALSE))
1577 {
1578 /* check if the DACL needs to be protected from being
1579 modified by inheritable ACEs */
1580 if (SecurityInfo & PROTECTED_DACL_SECURITY_INFORMATION)
1581 {
1582 goto ProtectDacl;
1583 }
1584 }
1585 else
1586 {
1587 return GetLastError();
1588 }
1589 }
1590 else
1591 {
1592 ProtectDacl:
1593 /* protect the DACL from being modified by inheritable ACEs */
1594 if (!SetSecurityDescriptorControl(pSecurityDescriptor,
1595 SE_DACL_PROTECTED,
1596 SE_DACL_PROTECTED))
1597 {
1598 return GetLastError();
1599 }
1600 }
1601 }
1602
1603 if (SecurityInfo & SACL_SECURITY_INFORMATION)
1604 {
1605 if (pSacl != NULL)
1606 {
1607 if (SetSecurityDescriptorSacl(pSecurityDescriptor,
1608 TRUE,
1609 pSacl,
1610 FALSE))
1611 {
1612 /* check if the SACL needs to be protected from being
1613 modified by inheritable ACEs */
1614 if (SecurityInfo & PROTECTED_SACL_SECURITY_INFORMATION)
1615 {
1616 goto ProtectSacl;
1617 }
1618 }
1619 else
1620 {
1621 return GetLastError();
1622 }
1623 }
1624 else
1625 {
1626 ProtectSacl:
1627 /* protect the SACL from being modified by inheritable ACEs */
1628 if (!SetSecurityDescriptorControl(pSecurityDescriptor,
1629 SE_SACL_PROTECTED,
1630 SE_SACL_PROTECTED))
1631 {
1632 return GetLastError();
1633 }
1634 }
1635 }
1636
1637 return ERROR_SUCCESS;
1638 }
1639
1640
1641 /**********************************************************************
1642 * GetNamedSecurityInfoW EXPORTED
1643 *
1644 * @implemented
1645 */
1646 DWORD
1647 STDCALL
1648 GetNamedSecurityInfoW(LPWSTR pObjectName,
1649 SE_OBJECT_TYPE ObjectType,
1650 SECURITY_INFORMATION SecurityInfo,
1651 PSID *ppsidOwner,
1652 PSID *ppsidGroup,
1653 PACL *ppDacl,
1654 PACL *ppSacl,
1655 PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
1656 {
1657 DWORD ErrorCode;
1658
1659 if (pObjectName != NULL)
1660 {
1661 ErrorCode = CheckNtMartaPresent();
1662 if (ErrorCode == ERROR_SUCCESS)
1663 {
1664 ErrorCode = pGetSecurityInfoCheck(SecurityInfo,
1665 ppsidOwner,
1666 ppsidGroup,
1667 ppDacl,
1668 ppSacl,
1669 ppSecurityDescriptor);
1670
1671 if (ErrorCode == ERROR_SUCCESS)
1672 {
1673 /* call the MARTA provider */
1674 ErrorCode = AccRewriteGetNamedRights(pObjectName,
1675 ObjectType,
1676 SecurityInfo,
1677 ppsidOwner,
1678 ppsidGroup,
1679 ppDacl,
1680 ppSacl,
1681 ppSecurityDescriptor);
1682 }
1683 }
1684 }
1685 else
1686 ErrorCode = ERROR_INVALID_PARAMETER;
1687
1688 return ErrorCode;
1689 }
1690
1691
1692 /**********************************************************************
1693 * GetNamedSecurityInfoA EXPORTED
1694 *
1695 * @implemented
1696 */
1697 DWORD
1698 STDCALL
1699 GetNamedSecurityInfoA(LPSTR pObjectName,
1700 SE_OBJECT_TYPE ObjectType,
1701 SECURITY_INFORMATION SecurityInfo,
1702 PSID *ppsidOwner,
1703 PSID *ppsidGroup,
1704 PACL *ppDacl,
1705 PACL *ppSacl,
1706 PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
1707 {
1708 UNICODE_STRING ObjectName;
1709 NTSTATUS Status;
1710 DWORD Ret;
1711
1712 Status = RtlCreateUnicodeStringFromAsciiz(&ObjectName,
1713 pObjectName);
1714 if (!NT_SUCCESS(Status))
1715 {
1716 return RtlNtStatusToDosError(Status);
1717 }
1718
1719 Ret = GetNamedSecurityInfoW(ObjectName.Buffer,
1720 ObjectType,
1721 SecurityInfo,
1722 ppsidOwner,
1723 ppsidGroup,
1724 ppDacl,
1725 ppSacl,
1726 ppSecurityDescriptor);
1727
1728 RtlFreeUnicodeString(&ObjectName);
1729
1730 return Ret;
1731 }
1732
1733
1734 /**********************************************************************
1735 * SetNamedSecurityInfoW EXPORTED
1736 *
1737 * @implemented
1738 */
1739 DWORD
1740 STDCALL
1741 SetNamedSecurityInfoW(LPWSTR pObjectName,
1742 SE_OBJECT_TYPE ObjectType,
1743 SECURITY_INFORMATION SecurityInfo,
1744 PSID psidOwner,
1745 PSID psidGroup,
1746 PACL pDacl,
1747 PACL pSacl)
1748 {
1749 DWORD ErrorCode;
1750
1751 if (pObjectName != NULL)
1752 {
1753 ErrorCode = CheckNtMartaPresent();
1754 if (ErrorCode == ERROR_SUCCESS)
1755 {
1756 SECURITY_DESCRIPTOR SecurityDescriptor;
1757
1758 ErrorCode = pSetSecurityInfoCheck(&SecurityDescriptor,
1759 SecurityInfo,
1760 psidOwner,
1761 psidGroup,
1762 pDacl,
1763 pSacl);
1764
1765 if (ErrorCode == ERROR_SUCCESS)
1766 {
1767 /* call the MARTA provider */
1768 ErrorCode = AccRewriteSetNamedRights(pObjectName,
1769 ObjectType,
1770 SecurityInfo,
1771 &SecurityDescriptor);
1772 }
1773 }
1774 }
1775 else
1776 ErrorCode = ERROR_INVALID_PARAMETER;
1777
1778 return ErrorCode;
1779 }
1780
1781
1782 /**********************************************************************
1783 * SetNamedSecurityInfoA EXPORTED
1784 *
1785 * @implemented
1786 */
1787 DWORD
1788 STDCALL
1789 SetNamedSecurityInfoA(LPSTR pObjectName,
1790 SE_OBJECT_TYPE ObjectType,
1791 SECURITY_INFORMATION SecurityInfo,
1792 PSID psidOwner,
1793 PSID psidGroup,
1794 PACL pDacl,
1795 PACL pSacl)
1796 {
1797 UNICODE_STRING ObjectName;
1798 NTSTATUS Status;
1799 DWORD Ret;
1800
1801 Status = RtlCreateUnicodeStringFromAsciiz(&ObjectName,
1802 pObjectName);
1803 if (!NT_SUCCESS(Status))
1804 {
1805 return RtlNtStatusToDosError(Status);
1806 }
1807
1808 Ret = SetNamedSecurityInfoW(ObjectName.Buffer,
1809 ObjectType,
1810 SecurityInfo,
1811 psidOwner,
1812 psidGroup,
1813 pDacl,
1814 pSacl);
1815
1816 RtlFreeUnicodeString(&ObjectName);
1817
1818 return Ret;
1819 }
1820
1821
1822 /**********************************************************************
1823 * GetSecurityInfo EXPORTED
1824 *
1825 * @implemented
1826 */
1827 DWORD
1828 STDCALL
1829 GetSecurityInfo(HANDLE handle,
1830 SE_OBJECT_TYPE ObjectType,
1831 SECURITY_INFORMATION SecurityInfo,
1832 PSID *ppsidOwner,
1833 PSID *ppsidGroup,
1834 PACL *ppDacl,
1835 PACL *ppSacl,
1836 PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
1837 {
1838 DWORD ErrorCode;
1839
1840 if (handle != NULL)
1841 {
1842 ErrorCode = CheckNtMartaPresent();
1843 if (ErrorCode == ERROR_SUCCESS)
1844 {
1845 ErrorCode = pGetSecurityInfoCheck(SecurityInfo,
1846 ppsidOwner,
1847 ppsidGroup,
1848 ppDacl,
1849 ppSacl,
1850 ppSecurityDescriptor);
1851
1852 if (ErrorCode == ERROR_SUCCESS)
1853 {
1854 /* call the MARTA provider */
1855 ErrorCode = AccRewriteGetHandleRights(handle,
1856 ObjectType,
1857 SecurityInfo,
1858 ppsidOwner,
1859 ppsidGroup,
1860 ppDacl,
1861 ppSacl,
1862 ppSecurityDescriptor);
1863 }
1864 }
1865 }
1866 else
1867 ErrorCode = ERROR_INVALID_HANDLE;
1868
1869 return ErrorCode;
1870 }
1871
1872
1873 /**********************************************************************
1874 * SetSecurityInfo EXPORTED
1875 *
1876 * @implemented
1877 */
1878 DWORD
1879 WINAPI
1880 SetSecurityInfo(HANDLE handle,
1881 SE_OBJECT_TYPE ObjectType,
1882 SECURITY_INFORMATION SecurityInfo,
1883 PSID psidOwner,
1884 PSID psidGroup,
1885 PACL pDacl,
1886 PACL pSacl)
1887 {
1888 DWORD ErrorCode;
1889
1890 if (handle != NULL)
1891 {
1892 ErrorCode = CheckNtMartaPresent();
1893 if (ErrorCode == ERROR_SUCCESS)
1894 {
1895 SECURITY_DESCRIPTOR SecurityDescriptor;
1896
1897 ErrorCode = pSetSecurityInfoCheck(&SecurityDescriptor,
1898 SecurityInfo,
1899 psidOwner,
1900 psidGroup,
1901 pDacl,
1902 pSacl);
1903
1904 if (ErrorCode == ERROR_SUCCESS)
1905 {
1906 /* call the MARTA provider */
1907 ErrorCode = AccRewriteSetHandleRights(handle,
1908 ObjectType,
1909 SecurityInfo,
1910 &SecurityDescriptor);
1911 }
1912 }
1913 }
1914 else
1915 ErrorCode = ERROR_INVALID_HANDLE;
1916
1917 return ErrorCode;
1918 }
1919
1920
1921 /******************************************************************************
1922 * GetSecurityInfoExW EXPORTED
1923 */
1924 DWORD
1925 WINAPI
1926 GetSecurityInfoExA(HANDLE hObject,
1927 SE_OBJECT_TYPE ObjectType,
1928 SECURITY_INFORMATION SecurityInfo,
1929 LPCSTR lpProvider,
1930 LPCSTR lpProperty,
1931 PACTRL_ACCESSA *ppAccessList,
1932 PACTRL_AUDITA *ppAuditList,
1933 LPSTR *lppOwner,
1934 LPSTR *lppGroup)
1935 {
1936 FIXME("%s() not implemented!\n", __FUNCTION__);
1937 return ERROR_BAD_PROVIDER;
1938 }
1939
1940
1941 /******************************************************************************
1942 * GetSecurityInfoExW EXPORTED
1943 */
1944 DWORD
1945 WINAPI
1946 GetSecurityInfoExW(HANDLE hObject,
1947 SE_OBJECT_TYPE ObjectType,
1948 SECURITY_INFORMATION SecurityInfo,
1949 LPCWSTR lpProvider,
1950 LPCWSTR lpProperty,
1951 PACTRL_ACCESSW *ppAccessList,
1952 PACTRL_AUDITW *ppAuditList,
1953 LPWSTR *lppOwner,
1954 LPWSTR *lppGroup)
1955 {
1956 FIXME("%s() not implemented!\n", __FUNCTION__);
1957 return ERROR_BAD_PROVIDER;
1958 }
1959
1960
1961 /**********************************************************************
1962 * ImpersonateNamedPipeClient EXPORTED
1963 *
1964 * @implemented
1965 */
1966 BOOL
1967 STDCALL
1968 ImpersonateNamedPipeClient(HANDLE hNamedPipe)
1969 {
1970 IO_STATUS_BLOCK StatusBlock;
1971 NTSTATUS Status;
1972
1973 TRACE("ImpersonateNamedPipeClient() called\n");
1974
1975 Status = NtFsControlFile(hNamedPipe,
1976 NULL,
1977 NULL,
1978 NULL,
1979 &StatusBlock,
1980 FSCTL_PIPE_IMPERSONATE,
1981 NULL,
1982 0,
1983 NULL,
1984 0);
1985 if (!NT_SUCCESS(Status))
1986 {
1987 SetLastError(RtlNtStatusToDosError(Status));
1988 return FALSE;
1989 }
1990
1991 return TRUE;
1992 }
1993
1994
1995 /*
1996 * @implemented
1997 */
1998 BOOL
1999 STDCALL
2000 CreatePrivateObjectSecurity(PSECURITY_DESCRIPTOR ParentDescriptor,
2001 PSECURITY_DESCRIPTOR CreatorDescriptor,
2002 PSECURITY_DESCRIPTOR *NewDescriptor,
2003 BOOL IsDirectoryObject,
2004 HANDLE Token,
2005 PGENERIC_MAPPING GenericMapping)
2006 {
2007 NTSTATUS Status;
2008
2009 Status = RtlNewSecurityObject(ParentDescriptor,
2010 CreatorDescriptor,
2011 NewDescriptor,
2012 IsDirectoryObject,
2013 Token,
2014 GenericMapping);
2015 if (!NT_SUCCESS(Status))
2016 {
2017 SetLastError(RtlNtStatusToDosError(Status));
2018 return FALSE;
2019 }
2020
2021 return TRUE;
2022 }
2023
2024
2025 /*
2026 * @unimplemented
2027 */
2028 BOOL
2029 STDCALL
2030 CreatePrivateObjectSecurityEx(PSECURITY_DESCRIPTOR ParentDescriptor,
2031 PSECURITY_DESCRIPTOR CreatorDescriptor,
2032 PSECURITY_DESCRIPTOR* NewDescriptor,
2033 GUID* ObjectType,
2034 BOOL IsContainerObject,
2035 ULONG AutoInheritFlags,
2036 HANDLE Token,
2037 PGENERIC_MAPPING GenericMapping)
2038 {
2039 FIXME("%s() not implemented!\n", __FUNCTION__);
2040 return FALSE;
2041 }
2042
2043
2044 /*
2045 * @unimplemented
2046 */
2047 BOOL
2048 STDCALL
2049 CreatePrivateObjectSecurityWithMultipleInheritance(PSECURITY_DESCRIPTOR ParentDescriptor,
2050 PSECURITY_DESCRIPTOR CreatorDescriptor,
2051 PSECURITY_DESCRIPTOR* NewDescriptor,
2052 GUID** ObjectTypes,
2053 ULONG GuidCount,
2054 BOOL IsContainerObject,
2055 ULONG AutoInheritFlags,
2056 HANDLE Token,
2057 PGENERIC_MAPPING GenericMapping)
2058 {
2059 FIXME("%s() not implemented!\n", __FUNCTION__);
2060 return FALSE;
2061 }
2062
2063
2064 /*
2065 * @implemented
2066 */
2067 BOOL
2068 STDCALL
2069 DestroyPrivateObjectSecurity(PSECURITY_DESCRIPTOR *ObjectDescriptor)
2070 {
2071 NTSTATUS Status;
2072
2073 Status = RtlDeleteSecurityObject(ObjectDescriptor);
2074 if (!NT_SUCCESS(Status))
2075 {
2076 SetLastError(RtlNtStatusToDosError(Status));
2077 return FALSE;
2078 }
2079
2080 return TRUE;
2081 }
2082
2083
2084 /*
2085 * @implemented
2086 */
2087 BOOL
2088 STDCALL
2089 GetPrivateObjectSecurity(PSECURITY_DESCRIPTOR ObjectDescriptor,
2090 SECURITY_INFORMATION SecurityInformation,
2091 PSECURITY_DESCRIPTOR ResultantDescriptor,
2092 DWORD DescriptorLength,
2093 PDWORD ReturnLength)
2094 {
2095 NTSTATUS Status;
2096
2097 Status = RtlQuerySecurityObject(ObjectDescriptor,
2098 SecurityInformation,
2099 ResultantDescriptor,
2100 DescriptorLength,
2101 ReturnLength);
2102 if (!NT_SUCCESS(Status))
2103 {
2104 SetLastError(RtlNtStatusToDosError(Status));
2105 return FALSE;
2106 }
2107
2108 return TRUE;
2109 }
2110
2111
2112 /*
2113 * @implemented
2114 */
2115 BOOL
2116 STDCALL
2117 SetPrivateObjectSecurity(SECURITY_INFORMATION SecurityInformation,
2118 PSECURITY_DESCRIPTOR ModificationDescriptor,
2119 PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
2120 PGENERIC_MAPPING GenericMapping,
2121 HANDLE Token)
2122 {
2123 NTSTATUS Status;
2124
2125 Status = RtlSetSecurityObject(SecurityInformation,
2126 ModificationDescriptor,
2127 ObjectsSecurityDescriptor,
2128 GenericMapping,
2129 Token);
2130 if (!NT_SUCCESS(Status))
2131 {
2132 SetLastError(RtlNtStatusToDosError(Status));
2133 return FALSE;
2134 }
2135
2136 return TRUE;
2137 }
2138
2139
2140 /*
2141 * @implemented
2142 */
2143 DWORD
2144 STDCALL
2145 TreeResetNamedSecurityInfoW(LPWSTR pObjectName,
2146 SE_OBJECT_TYPE ObjectType,
2147 SECURITY_INFORMATION SecurityInfo,
2148 PSID pOwner,
2149 PSID pGroup,
2150 PACL pDacl,
2151 PACL pSacl,
2152 BOOL KeepExplicit,
2153 FN_PROGRESSW fnProgress,
2154 PROG_INVOKE_SETTING ProgressInvokeSetting,
2155 PVOID Args)
2156 {
2157 DWORD ErrorCode;
2158
2159 if (pObjectName != NULL)
2160 {
2161 ErrorCode = CheckNtMartaPresent();
2162 if (ErrorCode == ERROR_SUCCESS)
2163 {
2164 switch (ObjectType)
2165 {
2166 case SE_FILE_OBJECT:
2167 case SE_REGISTRY_KEY:
2168 {
2169 /* check the SecurityInfo flags for sanity (both, the protected
2170 and unprotected dacl/sacl flag must not be passed together) */
2171 if (((SecurityInfo & DACL_SECURITY_INFORMATION) &&
2172 (SecurityInfo & (PROTECTED_DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION)) ==
2173 (PROTECTED_DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION))
2174
2175 ||
2176
2177 ((SecurityInfo & SACL_SECURITY_INFORMATION) &&
2178 (SecurityInfo & (PROTECTED_SACL_SECURITY_INFORMATION | UNPROTECTED_SACL_SECURITY_INFORMATION)) ==
2179 (PROTECTED_SACL_SECURITY_INFORMATION | UNPROTECTED_SACL_SECURITY_INFORMATION)))
2180 {
2181 ErrorCode = ERROR_INVALID_PARAMETER;
2182 break;
2183 }
2184
2185 /* call the MARTA provider */
2186 ErrorCode = AccTreeResetNamedSecurityInfo(pObjectName,
2187 ObjectType,
2188 SecurityInfo,
2189 pOwner,
2190 pGroup,
2191 pDacl,
2192 pSacl,
2193 KeepExplicit,
2194 fnProgress,
2195 ProgressInvokeSetting,
2196 Args);
2197 break;
2198 }
2199
2200 default:
2201 /* object type not supported */
2202 ErrorCode = ERROR_INVALID_PARAMETER;
2203 break;
2204 }
2205 }
2206 }
2207 else
2208 ErrorCode = ERROR_INVALID_PARAMETER;
2209
2210 return ErrorCode;
2211 }
2212
2213 #ifdef HAS_FN_PROGRESSW
2214
2215 typedef struct _INERNAL_FNPROGRESSW_DATA
2216 {
2217 FN_PROGRESSA fnProgress;
2218 PVOID Args;
2219 } INERNAL_FNPROGRESSW_DATA, *PINERNAL_FNPROGRESSW_DATA;
2220
2221 static VOID STDCALL
2222 InternalfnProgressW(LPWSTR pObjectName,
2223 DWORD Status,
2224 PPROG_INVOKE_SETTING pInvokeSetting,
2225 PVOID Args,
2226 BOOL SecuritySet)
2227 {
2228 PINERNAL_FNPROGRESSW_DATA pifnProgressData = (PINERNAL_FNPROGRESSW_DATA)Args;
2229 INT ObjectNameSize;
2230 LPSTR pObjectNameA;
2231
2232 ObjectNameSize = WideCharToMultiByte(CP_ACP,
2233 0,
2234 pObjectName,
2235 -1,
2236 NULL,
2237 0,
2238 NULL,
2239 NULL);
2240
2241 if (ObjectNameSize > 0)
2242 {
2243 pObjectNameA = RtlAllocateHeap(RtlGetProcessHeap(),
2244 0,
2245 ObjectNameSize);
2246 if (pObjectNameA != NULL)
2247 {
2248 pObjectNameA[0] = '\0';
2249 WideCharToMultiByte(CP_ACP,
2250 0,
2251 pObjectName,
2252 -1,
2253 pObjectNameA,
2254 ObjectNameSize,
2255 NULL,
2256 NULL);
2257
2258 pifnProgressData->fnProgress((LPWSTR)pObjectNameA, /* FIXME: wrong cast!! */
2259 Status,
2260 pInvokeSetting,
2261 pifnProgressData->Args,
2262 SecuritySet);
2263
2264 RtlFreeHeap(RtlGetProcessHeap(),
2265 0,
2266 pObjectNameA);
2267 }
2268 }
2269 }
2270 #endif
2271
2272
2273 /*
2274 * @implemented
2275 */
2276 DWORD
2277 STDCALL
2278 TreeResetNamedSecurityInfoA(LPSTR pObjectName,
2279 SE_OBJECT_TYPE ObjectType,
2280 SECURITY_INFORMATION SecurityInfo,
2281 PSID pOwner,
2282 PSID pGroup,
2283 PACL pDacl,
2284 PACL pSacl,
2285 BOOL KeepExplicit,
2286 FN_PROGRESSA fnProgress,
2287 PROG_INVOKE_SETTING ProgressInvokeSetting,
2288 PVOID Args)
2289 {
2290 #ifndef HAS_FN_PROGRESSW
2291 /* That's all this function does, at least up to w2k3... Even MS was too
2292 lazy to implement it... */
2293 return ERROR_CALL_NOT_IMPLEMENTED;
2294 #else
2295 INERNAL_FNPROGRESSW_DATA ifnProgressData;
2296 UNICODE_STRING ObjectName;
2297 NTSTATUS Status;
2298 DWORD Ret;
2299
2300 Status = RtlCreateUnicodeStringFromAsciiz(&ObjectName,
2301 pObjectName);
2302 if (!NT_SUCCESS(Status))
2303 {
2304 return RtlNtStatusToDosError(Status);
2305 }
2306
2307 ifnProgressData.fnProgress = fnProgress;
2308 ifnProgressData.Args = Args;
2309
2310 Ret = TreeResetNamedSecurityInfoW(ObjectName.Buffer,
2311 ObjectType,
2312 SecurityInfo,
2313 pOwner,
2314 pGroup,
2315 pDacl,
2316 pSacl,
2317 KeepExplicit,
2318 (fnProgress != NULL ? InternalfnProgressW : NULL),
2319 ProgressInvokeSetting,
2320 &ifnProgressData);
2321
2322 RtlFreeUnicodeString(&ObjectName);
2323
2324 return Ret;
2325 #endif
2326 }
2327
2328 /* EOF */