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