[FORMATTING] No code changes!
[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 if (RequestedInformation &
342 (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION))
343 {
344 AccessMask |= READ_CONTROL;
345 }
346
347 if (RequestedInformation & SACL_SECURITY_INFORMATION)
348 {
349 AccessMask |= ACCESS_SYSTEM_SECURITY;
350 }
351
352 if (!RtlDosPathNameToNtPathName_U(lpFileName,
353 &FileName,
354 NULL,
355 NULL))
356 {
357 ERR("Invalid path\n");
358 SetLastError(ERROR_INVALID_NAME);
359 return FALSE;
360 }
361
362 InitializeObjectAttributes(&ObjectAttributes,
363 &FileName,
364 OBJ_CASE_INSENSITIVE,
365 NULL,
366 NULL);
367
368 Status = NtOpenFile(&FileHandle,
369 AccessMask,
370 &ObjectAttributes,
371 &StatusBlock,
372 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
373 0);
374
375 RtlFreeHeap(RtlGetProcessHeap(),
376 0,
377 FileName.Buffer);
378
379 if (!NT_SUCCESS(Status))
380 {
381 ERR("NtOpenFile() failed (Status %lx)\n", Status);
382 SetLastError(RtlNtStatusToDosError(Status));
383 return FALSE;
384 }
385
386 Status = NtQuerySecurityObject(FileHandle,
387 RequestedInformation,
388 pSecurityDescriptor,
389 nLength,
390 lpnLengthNeeded);
391 NtClose(FileHandle);
392 if (!NT_SUCCESS(Status))
393 {
394 ERR("NtQuerySecurityObject() failed (Status %lx)\n", Status);
395 SetLastError(RtlNtStatusToDosError(Status));
396 return FALSE;
397 }
398
399 return TRUE;
400 }
401
402
403 /*
404 * @implemented
405 */
406 BOOL
407 STDCALL
408 GetKernelObjectSecurity(HANDLE Handle,
409 SECURITY_INFORMATION RequestedInformation,
410 PSECURITY_DESCRIPTOR pSecurityDescriptor,
411 DWORD nLength,
412 LPDWORD lpnLengthNeeded)
413 {
414 NTSTATUS Status;
415
416 Status = NtQuerySecurityObject(Handle,
417 RequestedInformation,
418 pSecurityDescriptor,
419 nLength,
420 lpnLengthNeeded);
421 if (!NT_SUCCESS(Status))
422 {
423 SetLastError(RtlNtStatusToDosError(Status));
424 return FALSE;
425 }
426
427 return TRUE;
428 }
429
430
431 /******************************************************************************
432 * SetFileSecurityA [ADVAPI32.@]
433 * Sets the security of a file or directory
434 *
435 * @implemented
436 */
437 BOOL
438 STDCALL
439 SetFileSecurityA(LPCSTR lpFileName,
440 SECURITY_INFORMATION SecurityInformation,
441 PSECURITY_DESCRIPTOR pSecurityDescriptor)
442 {
443 UNICODE_STRING FileName;
444 NTSTATUS Status;
445 BOOL bResult;
446
447 Status = RtlCreateUnicodeStringFromAsciiz(&FileName,
448 (LPSTR)lpFileName);
449 if (!NT_SUCCESS(Status))
450 {
451 SetLastError(RtlNtStatusToDosError(Status));
452 return FALSE;
453 }
454
455 bResult = SetFileSecurityW(FileName.Buffer,
456 SecurityInformation,
457 pSecurityDescriptor);
458
459 RtlFreeUnicodeString(&FileName);
460
461 return bResult;
462 }
463
464
465 /******************************************************************************
466 * SetFileSecurityW [ADVAPI32.@]
467 * Sets the security of a file or directory
468 *
469 * @implemented
470 */
471 BOOL
472 STDCALL
473 SetFileSecurityW(LPCWSTR lpFileName,
474 SECURITY_INFORMATION SecurityInformation,
475 PSECURITY_DESCRIPTOR pSecurityDescriptor)
476 {
477 OBJECT_ATTRIBUTES ObjectAttributes;
478 IO_STATUS_BLOCK StatusBlock;
479 UNICODE_STRING FileName;
480 ULONG AccessMask = 0;
481 HANDLE FileHandle;
482 NTSTATUS Status;
483
484 TRACE("SetFileSecurityW() called\n");
485
486 if (SecurityInformation &
487 (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION))
488 {
489 AccessMask |= WRITE_OWNER;
490 }
491
492 if (SecurityInformation & DACL_SECURITY_INFORMATION)
493 {
494 AccessMask |= WRITE_DAC;
495 }
496
497 if (SecurityInformation & SACL_SECURITY_INFORMATION)
498 {
499 AccessMask |= ACCESS_SYSTEM_SECURITY;
500 }
501
502 if (!RtlDosPathNameToNtPathName_U(lpFileName,
503 &FileName,
504 NULL,
505 NULL))
506 {
507 ERR("Invalid path\n");
508 SetLastError(ERROR_INVALID_NAME);
509 return FALSE;
510 }
511
512 InitializeObjectAttributes(&ObjectAttributes,
513 &FileName,
514 OBJ_CASE_INSENSITIVE,
515 NULL,
516 NULL);
517
518 Status = NtOpenFile(&FileHandle,
519 AccessMask,
520 &ObjectAttributes,
521 &StatusBlock,
522 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
523 0);
524
525 RtlFreeHeap(RtlGetProcessHeap(),
526 0,
527 FileName.Buffer);
528
529 if (!NT_SUCCESS(Status))
530 {
531 ERR("NtOpenFile() failed (Status %lx)\n", Status);
532 SetLastError(RtlNtStatusToDosError(Status));
533 return FALSE;
534 }
535
536 Status = NtSetSecurityObject(FileHandle,
537 SecurityInformation,
538 pSecurityDescriptor);
539 NtClose(FileHandle);
540
541 if (!NT_SUCCESS(Status))
542 {
543 ERR("NtSetSecurityObject() failed (Status %lx)\n", Status);
544 SetLastError(RtlNtStatusToDosError(Status));
545 return FALSE;
546 }
547
548 return TRUE;
549 }
550
551
552 /*
553 * @implemented
554 */
555 BOOL
556 STDCALL
557 SetKernelObjectSecurity(HANDLE Handle,
558 SECURITY_INFORMATION SecurityInformation,
559 PSECURITY_DESCRIPTOR SecurityDescriptor)
560 {
561 NTSTATUS Status;
562
563 Status = NtSetSecurityObject(Handle,
564 SecurityInformation,
565 SecurityDescriptor);
566 if (!NT_SUCCESS(Status))
567 {
568 SetLastError(RtlNtStatusToDosError(Status));
569 return FALSE;
570 }
571
572 return TRUE;
573 }
574
575
576 /*
577 * @implemented
578 */
579 BOOL
580 WINAPI
581 ImpersonateAnonymousToken(IN HANDLE ThreadHandle)
582 {
583 NTSTATUS Status;
584
585 Status = NtImpersonateAnonymousToken(ThreadHandle);
586 if (!NT_SUCCESS(Status))
587 {
588 SetLastError(RtlNtStatusToDosError(Status));
589 return FALSE;
590 }
591
592 return TRUE;
593 }
594
595
596 /*
597 * @implemented
598 */
599 BOOL
600 STDCALL
601 ImpersonateLoggedOnUser(HANDLE hToken)
602 {
603 SECURITY_QUALITY_OF_SERVICE Qos;
604 OBJECT_ATTRIBUTES ObjectAttributes;
605 HANDLE NewToken;
606 TOKEN_TYPE Type;
607 ULONG ReturnLength;
608 BOOL Duplicated;
609 NTSTATUS Status;
610
611 /* Get the token type */
612 Status = NtQueryInformationToken(hToken,
613 TokenType,
614 &Type,
615 sizeof(TOKEN_TYPE),
616 &ReturnLength);
617 if (!NT_SUCCESS(Status))
618 {
619 SetLastError(RtlNtStatusToDosError(Status));
620 return FALSE;
621 }
622
623 if (Type == TokenPrimary)
624 {
625 /* Create a duplicate impersonation token */
626 Qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
627 Qos.ImpersonationLevel = SecurityImpersonation;
628 Qos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
629 Qos.EffectiveOnly = FALSE;
630
631 ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
632 ObjectAttributes.RootDirectory = NULL;
633 ObjectAttributes.ObjectName = NULL;
634 ObjectAttributes.Attributes = 0;
635 ObjectAttributes.SecurityDescriptor = NULL;
636 ObjectAttributes.SecurityQualityOfService = &Qos;
637
638 Status = NtDuplicateToken(hToken,
639 TOKEN_IMPERSONATE | TOKEN_QUERY,
640 &ObjectAttributes,
641 FALSE,
642 TokenImpersonation,
643 &NewToken);
644 if (!NT_SUCCESS(Status))
645 {
646 SetLastError(RtlNtStatusToDosError(Status));
647 return FALSE;
648 }
649
650 Duplicated = TRUE;
651 }
652 else
653 {
654 /* User the original impersonation token */
655 NewToken = hToken;
656 Duplicated = FALSE;
657 }
658
659 /* Impersonate the the current thread */
660 Status = NtSetInformationThread(NtCurrentThread(),
661 ThreadImpersonationToken,
662 &NewToken,
663 sizeof(HANDLE));
664
665 if (Duplicated == TRUE)
666 {
667 NtClose(NewToken);
668 }
669
670 if (!NT_SUCCESS(Status))
671 {
672 SetLastError(RtlNtStatusToDosError(Status));
673 return FALSE;
674 }
675
676 return TRUE;
677 }
678
679
680 /*
681 * @implemented
682 */
683 BOOL
684 STDCALL
685 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
686 {
687 NTSTATUS Status;
688
689 Status = RtlImpersonateSelf(ImpersonationLevel);
690 if (!NT_SUCCESS(Status))
691 {
692 SetLastError(RtlNtStatusToDosError(Status));
693 return FALSE;
694 }
695
696 return TRUE;
697 }
698
699
700 /*
701 * @implemented
702 */
703 BOOL
704 STDCALL
705 RevertToSelf(VOID)
706 {
707 NTSTATUS Status;
708 HANDLE Token = NULL;
709
710 Status = NtSetInformationThread(NtCurrentThread(),
711 ThreadImpersonationToken,
712 &Token,
713 sizeof(HANDLE));
714 if (!NT_SUCCESS(Status))
715 {
716 SetLastError(RtlNtStatusToDosError(Status));
717 return FALSE;
718 }
719
720 return TRUE;
721 }
722
723
724 /******************************************************************************
725 * GetUserNameA [ADVAPI32.@]
726 *
727 * Get the current user name.
728 *
729 * PARAMS
730 * lpszName [O] Destination for the user name.
731 * lpSize [I/O] Size of lpszName.
732 *
733 *
734 * @implemented
735 */
736 BOOL
737 WINAPI
738 GetUserNameA(LPSTR lpszName,
739 LPDWORD lpSize)
740 {
741 UNICODE_STRING NameW;
742 ANSI_STRING NameA;
743 BOOL Ret;
744
745 /* apparently Win doesn't check whether lpSize is valid at all! */
746
747 NameW.MaximumLength = (*lpSize) * sizeof(WCHAR);
748 NameW.Buffer = LocalAlloc(LMEM_FIXED, NameW.MaximumLength);
749 if(NameW.Buffer == NULL)
750 {
751 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
752 return FALSE;
753 }
754
755 NameA.Length = 0;
756 NameA.MaximumLength = ((*lpSize) < 0xFFFF ? (USHORT)(*lpSize) : 0xFFFF);
757 NameA.Buffer = lpszName;
758
759 Ret = GetUserNameW(NameW.Buffer,
760 lpSize);
761 if(Ret)
762 {
763 NameW.Length = (*lpSize - 1) * sizeof(WCHAR);
764 RtlUnicodeStringToAnsiString(&NameA, &NameW, FALSE);
765
766 *lpSize = NameA.Length + 1;
767 }
768
769 LocalFree(NameW.Buffer);
770
771 return Ret;
772 }
773
774
775 /******************************************************************************
776 * GetUserNameW [ADVAPI32.@]
777 *
778 * See GetUserNameA.
779 *
780 * @implemented
781 */
782 BOOL
783 WINAPI
784 GetUserNameW(LPWSTR lpszName,
785 LPDWORD lpSize )
786 {
787 HANDLE hToken = INVALID_HANDLE_VALUE;
788 DWORD tu_len = 0;
789 char* tu_buf = NULL;
790 TOKEN_USER* token_user = NULL;
791 DWORD an_len = 0;
792 SID_NAME_USE snu = SidTypeUser;
793 WCHAR* domain_name = NULL;
794 DWORD dn_len = 0;
795
796 if ( !OpenThreadToken ( GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken ) )
797 {
798 DWORD dwLastError = GetLastError();
799 if ( dwLastError != ERROR_NO_TOKEN
800 && dwLastError != ERROR_NO_IMPERSONATION_TOKEN )
801 {
802 /* don't call SetLastError(),
803 as OpenThreadToken() ought to have set one */
804 return FALSE;
805 }
806 if ( !OpenProcessToken ( GetCurrentProcess(), TOKEN_QUERY, &hToken ) )
807 {
808 /* don't call SetLastError(),
809 as OpenProcessToken() ought to have set one */
810 return FALSE;
811 }
812 }
813 tu_buf = LocalAlloc ( LMEM_FIXED, 36 );
814 if ( !tu_buf )
815 {
816 SetLastError ( ERROR_NOT_ENOUGH_MEMORY );
817 CloseHandle ( hToken );
818 return FALSE;
819 }
820 if ( !GetTokenInformation ( hToken, TokenUser, tu_buf, 36, &tu_len ) || tu_len > 36 )
821 {
822 LocalFree ( tu_buf );
823 tu_buf = LocalAlloc ( LMEM_FIXED, tu_len );
824 if ( !tu_buf )
825 {
826 SetLastError ( ERROR_NOT_ENOUGH_MEMORY );
827 CloseHandle ( hToken );
828 return FALSE;
829 }
830 if ( !GetTokenInformation ( hToken, TokenUser, tu_buf, tu_len, &tu_len ) )
831 {
832 /* don't call SetLastError(),
833 as GetTokenInformation() ought to have set one */
834 LocalFree ( tu_buf );
835 CloseHandle ( hToken );
836 return FALSE;
837 }
838 }
839 CloseHandle ( hToken );
840 token_user = (TOKEN_USER*)tu_buf;
841
842 an_len = *lpSize;
843 dn_len = 32;
844 domain_name = LocalAlloc ( LMEM_FIXED, dn_len * sizeof(WCHAR) );
845 if ( !domain_name )
846 {
847 LocalFree ( tu_buf );
848 SetLastError ( ERROR_NOT_ENOUGH_MEMORY );
849 return FALSE;
850 }
851 if ( !LookupAccountSidW ( NULL, token_user->User.Sid, lpszName, &an_len, domain_name, &dn_len, &snu )
852 || dn_len > 32 )
853 {
854 if ( dn_len > 32 )
855 {
856 LocalFree ( domain_name );
857 domain_name = LocalAlloc ( LMEM_FIXED, dn_len * sizeof(WCHAR) );
858 if ( !domain_name )
859 {
860 LocalFree ( tu_buf );
861 SetLastError ( ERROR_NOT_ENOUGH_MEMORY );
862 return FALSE;
863 }
864 }
865 an_len = *lpSize;
866 if ( !LookupAccountSidW ( NULL, token_user->User.Sid, lpszName, &an_len, domain_name, &dn_len, &snu ) )
867 {
868 /* don't call SetLastError(),
869 as LookupAccountSid() ought to have set one */
870 LocalFree ( domain_name );
871 LocalFree ( tu_buf );
872 *lpSize = an_len;
873 return FALSE;
874 }
875 }
876
877 LocalFree ( domain_name );
878 LocalFree ( tu_buf );
879 *lpSize = an_len + 1;
880 return TRUE;
881 }
882
883
884 /******************************************************************************
885 * LookupAccountSidA [ADVAPI32.@]
886 *
887 * @implemented
888 */
889 BOOL
890 STDCALL
891 LookupAccountSidA(LPCSTR lpSystemName,
892 PSID lpSid,
893 LPSTR lpName,
894 LPDWORD cchName,
895 LPSTR lpReferencedDomainName,
896 LPDWORD cchReferencedDomainName,
897 PSID_NAME_USE peUse)
898 {
899 UNICODE_STRING NameW, ReferencedDomainNameW, SystemNameW;
900 DWORD szName, szReferencedDomainName;
901 BOOL Ret;
902
903 /*
904 * save the buffer sizes the caller passed to us, as they may get modified and
905 * we require the original values when converting back to ansi
906 */
907 szName = *cchName;
908 szReferencedDomainName = *cchReferencedDomainName;
909
910 /*
911 * allocate buffers for the unicode strings to receive
912 */
913
914 if(szName > 0)
915 {
916 NameW.Length = 0;
917 NameW.MaximumLength = szName * sizeof(WCHAR);
918 NameW.Buffer = (PWSTR)LocalAlloc(LMEM_FIXED, NameW.MaximumLength);
919 if(NameW.Buffer == NULL)
920 {
921 SetLastError(ERROR_OUTOFMEMORY);
922 return FALSE;
923 }
924 }
925 else
926 NameW.Buffer = NULL;
927
928 if(szReferencedDomainName > 0)
929 {
930 ReferencedDomainNameW.Length = 0;
931 ReferencedDomainNameW.MaximumLength = szReferencedDomainName * sizeof(WCHAR);
932 ReferencedDomainNameW.Buffer = (PWSTR)LocalAlloc(LMEM_FIXED, ReferencedDomainNameW.MaximumLength);
933 if(ReferencedDomainNameW.Buffer == NULL)
934 {
935 if(szName > 0)
936 {
937 LocalFree(NameW.Buffer);
938 }
939 SetLastError(ERROR_OUTOFMEMORY);
940 return FALSE;
941 }
942 }
943 else
944 ReferencedDomainNameW.Buffer = NULL;
945
946 /*
947 * convert the system name to unicode - if present
948 */
949
950 if(lpSystemName != NULL)
951 {
952 ANSI_STRING SystemNameA;
953
954 RtlInitAnsiString(&SystemNameA, lpSystemName);
955 RtlAnsiStringToUnicodeString(&SystemNameW, &SystemNameA, TRUE);
956 }
957 else
958 SystemNameW.Buffer = NULL;
959
960 /*
961 * it's time to call the unicode version
962 */
963
964 Ret = LookupAccountSidW(SystemNameW.Buffer,
965 lpSid,
966 NameW.Buffer,
967 cchName,
968 ReferencedDomainNameW.Buffer,
969 cchReferencedDomainName,
970 peUse);
971 if(Ret)
972 {
973 /*
974 * convert unicode strings back to ansi, don't forget that we can't convert
975 * more than 0xFFFF (USHORT) characters! Also don't forget to explicitly
976 * terminate the converted string, the Rtl functions don't do that!
977 */
978 if(lpName != NULL)
979 {
980 ANSI_STRING NameA;
981
982 NameA.Length = 0;
983 NameA.MaximumLength = ((szName <= 0xFFFF) ? (USHORT)szName : 0xFFFF);
984 NameA.Buffer = lpName;
985
986 RtlUnicodeStringToAnsiString(&NameA, &NameW, FALSE);
987 NameA.Buffer[NameA.Length] = '\0';
988 }
989
990 if(lpReferencedDomainName != NULL)
991 {
992 ANSI_STRING ReferencedDomainNameA;
993
994 ReferencedDomainNameA.Length = 0;
995 ReferencedDomainNameA.MaximumLength = ((szReferencedDomainName <= 0xFFFF) ?
996 (USHORT)szReferencedDomainName : 0xFFFF);
997 ReferencedDomainNameA.Buffer = lpReferencedDomainName;
998
999 RtlUnicodeStringToAnsiString(&ReferencedDomainNameA, &ReferencedDomainNameW, FALSE);
1000 ReferencedDomainNameA.Buffer[ReferencedDomainNameA.Length] = '\0';
1001 }
1002 }
1003
1004 /*
1005 * free previously allocated buffers
1006 */
1007
1008 if(SystemNameW.Buffer != NULL)
1009 {
1010 RtlFreeUnicodeString(&SystemNameW);
1011 }
1012 if(NameW.Buffer != NULL)
1013 {
1014 LocalFree(NameW.Buffer);
1015 }
1016 if(ReferencedDomainNameW.Buffer != NULL)
1017 {
1018 LocalFree(ReferencedDomainNameW.Buffer);
1019 }
1020
1021 return Ret;
1022 }
1023
1024
1025 /******************************************************************************
1026 * LookupAccountSidW [ADVAPI32.@]
1027 *
1028 * @implemented
1029 */
1030 BOOL WINAPI
1031 LookupAccountSidW(LPCWSTR pSystemName,
1032 PSID pSid,
1033 LPWSTR pAccountName,
1034 LPDWORD pdwAccountName,
1035 LPWSTR pDomainName,
1036 LPDWORD pdwDomainName,
1037 PSID_NAME_USE peUse)
1038 {
1039 LSA_UNICODE_STRING SystemName;
1040 LSA_OBJECT_ATTRIBUTES ObjectAttributes = {0};
1041 LSA_HANDLE PolicyHandle = NULL;
1042 NTSTATUS Status;
1043 PLSA_REFERENCED_DOMAIN_LIST ReferencedDomain = NULL;
1044 PLSA_TRANSLATED_NAME TranslatedName = NULL;
1045 BOOL ret;
1046
1047 RtlInitUnicodeString ( &SystemName, pSystemName );
1048 Status = LsaOpenPolicy ( &SystemName, &ObjectAttributes, POLICY_LOOKUP_NAMES, &PolicyHandle );
1049 if ( !NT_SUCCESS(Status) )
1050 {
1051 SetLastError ( LsaNtStatusToWinError(Status) );
1052 return FALSE;
1053 }
1054 Status = LsaLookupSids ( PolicyHandle, 1, &pSid, &ReferencedDomain, &TranslatedName );
1055
1056 LsaClose ( PolicyHandle );
1057
1058 if ( !NT_SUCCESS(Status) || Status == STATUS_SOME_NOT_MAPPED )
1059 {
1060 SetLastError ( LsaNtStatusToWinError(Status) );
1061 ret = FALSE;
1062 }
1063 else
1064 {
1065 ret = TRUE;
1066 if ( TranslatedName )
1067 {
1068 DWORD dwSrcLen = TranslatedName->Name.Length / sizeof(WCHAR);
1069 if ( *pdwAccountName <= dwSrcLen )
1070 {
1071 *pdwAccountName = dwSrcLen + 1;
1072 ret = FALSE;
1073 }
1074 else
1075 {
1076 *pdwAccountName = dwSrcLen;
1077 if (pAccountName)
1078 {
1079 RtlCopyMemory ( pAccountName, TranslatedName->Name.Buffer, TranslatedName->Name.Length );
1080 pAccountName[TranslatedName->Name.Length / sizeof(WCHAR)] = L'\0';
1081 }
1082 }
1083 if ( peUse )
1084 *peUse = TranslatedName->Use;
1085 }
1086
1087 if ( ReferencedDomain )
1088 {
1089 if ( ReferencedDomain->Entries > 0 )
1090 {
1091 DWORD dwSrcLen = ReferencedDomain->Domains[0].Name.Length / sizeof(WCHAR);
1092 if ( *pdwDomainName <= dwSrcLen )
1093 {
1094 *pdwDomainName = dwSrcLen + 1;
1095 ret = FALSE;
1096 }
1097 else
1098 {
1099 *pdwDomainName = dwSrcLen;
1100 RtlCopyMemory ( pDomainName, ReferencedDomain->Domains[0].Name.Buffer, ReferencedDomain->Domains[0].Name.Length );
1101 pDomainName[ReferencedDomain->Domains[0].Name.Length / sizeof(WCHAR)] = L'\0';
1102 }
1103 }
1104 }
1105
1106 if ( !ret )
1107 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1108 }
1109
1110 if ( ReferencedDomain )
1111 LsaFreeMemory ( ReferencedDomain );
1112 if ( TranslatedName )
1113 LsaFreeMemory ( TranslatedName );
1114
1115 return ret;
1116 }
1117
1118
1119
1120 /******************************************************************************
1121 * LookupAccountNameA [ADVAPI32.@]
1122 *
1123 * @implemented
1124 */
1125 BOOL
1126 STDCALL
1127 LookupAccountNameA(LPCSTR SystemName,
1128 LPCSTR AccountName,
1129 PSID Sid,
1130 LPDWORD SidLength,
1131 LPSTR ReferencedDomainName,
1132 LPDWORD hReferencedDomainNameLength,
1133 PSID_NAME_USE SidNameUse)
1134 {
1135 BOOL ret;
1136 UNICODE_STRING lpSystemW;
1137 UNICODE_STRING lpAccountW;
1138 LPWSTR lpReferencedDomainNameW = NULL;
1139
1140 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, SystemName);
1141 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, AccountName);
1142
1143 if (ReferencedDomainName)
1144 lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(),
1145 0,
1146 *hReferencedDomainNameLength * sizeof(WCHAR));
1147
1148 ret = LookupAccountNameW(lpSystemW.Buffer,
1149 lpAccountW.Buffer,
1150 Sid,
1151 SidLength,
1152 lpReferencedDomainNameW,
1153 hReferencedDomainNameLength,
1154 SidNameUse);
1155
1156 if (ret && lpReferencedDomainNameW)
1157 {
1158 WideCharToMultiByte(CP_ACP,
1159 0,
1160 lpReferencedDomainNameW,
1161 *hReferencedDomainNameLength,
1162 ReferencedDomainName,
1163 *hReferencedDomainNameLength,
1164 NULL,
1165 NULL);
1166 }
1167
1168 RtlFreeUnicodeString(&lpSystemW);
1169 RtlFreeUnicodeString(&lpAccountW);
1170 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
1171
1172 return ret;
1173 }
1174
1175
1176 /******************************************************************************
1177 * LookupAccountNameW [ADVAPI32.@]
1178 *
1179 * @unimplemented
1180 */
1181 BOOL
1182 WINAPI
1183 LookupAccountNameW(LPCWSTR lpSystemName,
1184 LPCWSTR lpAccountName,
1185 PSID Sid,
1186 LPDWORD cbSid,
1187 LPWSTR ReferencedDomainName,
1188 LPDWORD cchReferencedDomainName,
1189 PSID_NAME_USE peUse)
1190 {
1191 /* Default implementation: Always return a default SID */
1192 SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
1193 BOOL ret;
1194 PSID pSid;
1195 static const WCHAR dm[] = {'D','O','M','A','I','N',0};
1196 unsigned int i;
1197
1198 TRACE("%s %s %p %p %p %p %p - stub\n", lpSystemName, lpAccountName,
1199 Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
1200
1201 for (i = 0; i < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); i++)
1202 {
1203 if (!wcscmp(lpAccountName, ACCOUNT_SIDS[i].account))
1204 {
1205 if (*cchReferencedDomainName)
1206 *ReferencedDomainName = '\0';
1207 *cchReferencedDomainName = 0;
1208 *peUse = SidTypeWellKnownGroup;
1209 return CreateWellKnownSid(ACCOUNT_SIDS[i].type, NULL, Sid, cbSid);
1210 }
1211 }
1212
1213 ret = AllocateAndInitializeSid(&identifierAuthority,
1214 2,
1215 SECURITY_BUILTIN_DOMAIN_RID,
1216 DOMAIN_ALIAS_RID_ADMINS,
1217 0, 0, 0, 0, 0, 0,
1218 &pSid);
1219
1220 if (!ret)
1221 return FALSE;
1222
1223 if (!RtlValidSid(pSid))
1224 {
1225 FreeSid(pSid);
1226 return FALSE;
1227 }
1228
1229 if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
1230 CopySid(*cbSid, Sid, pSid);
1231
1232 if (*cbSid < GetLengthSid(pSid))
1233 {
1234 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1235 ret = FALSE;
1236 }
1237
1238 *cbSid = GetLengthSid(pSid);
1239
1240 if (ReferencedDomainName != NULL && (*cchReferencedDomainName > wcslen(dm)))
1241 wcscpy(ReferencedDomainName, dm);
1242
1243 if (*cchReferencedDomainName <= wcslen(dm))
1244 {
1245 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1246 ret = FALSE;
1247 }
1248
1249 *cchReferencedDomainName = wcslen(dm)+1;
1250
1251 FreeSid(pSid);
1252
1253 return ret;
1254 }
1255
1256
1257 /**********************************************************************
1258 * LookupPrivilegeValueA EXPORTED
1259 *
1260 * @implemented
1261 */
1262 BOOL
1263 STDCALL
1264 LookupPrivilegeValueA(LPCSTR lpSystemName,
1265 LPCSTR lpName,
1266 PLUID lpLuid)
1267 {
1268 UNICODE_STRING SystemName;
1269 UNICODE_STRING Name;
1270 BOOL Result;
1271
1272 /* Remote system? */
1273 if (lpSystemName != NULL)
1274 {
1275 RtlCreateUnicodeStringFromAsciiz(&SystemName,
1276 (LPSTR)lpSystemName);
1277 }
1278
1279 /* Check the privilege name is not NULL */
1280 if (lpName == NULL)
1281 {
1282 SetLastError(ERROR_INVALID_PARAMETER);
1283 return FALSE;
1284 }
1285
1286 RtlCreateUnicodeStringFromAsciiz(&Name,
1287 (LPSTR)lpName);
1288
1289 Result = LookupPrivilegeValueW((lpSystemName != NULL) ? SystemName.Buffer : NULL,
1290 Name.Buffer,
1291 lpLuid);
1292
1293 RtlFreeUnicodeString(&Name);
1294
1295 /* Remote system? */
1296 if (lpSystemName != NULL)
1297 {
1298 RtlFreeUnicodeString(&SystemName);
1299 }
1300
1301 return Result;
1302 }
1303
1304
1305 /**********************************************************************
1306 * LookupPrivilegeValueW EXPORTED
1307 *
1308 * @unimplemented
1309 */
1310 BOOL
1311 STDCALL
1312 LookupPrivilegeValueW(LPCWSTR SystemName,
1313 LPCWSTR PrivName,
1314 PLUID Luid)
1315 {
1316 static const WCHAR * const DefaultPrivNames[] =
1317 {
1318 L"SeCreateTokenPrivilege",
1319 L"SeAssignPrimaryTokenPrivilege",
1320 L"SeLockMemoryPrivilege",
1321 L"SeIncreaseQuotaPrivilege",
1322 L"SeUnsolicitedInputPrivilege",
1323 L"SeMachineAccountPrivilege",
1324 L"SeTcbPrivilege",
1325 L"SeSecurityPrivilege",
1326 L"SeTakeOwnershipPrivilege",
1327 L"SeLoadDriverPrivilege",
1328 L"SeSystemProfilePrivilege",
1329 L"SeSystemtimePrivilege",
1330 L"SeProfileSingleProcessPrivilege",
1331 L"SeIncreaseBasePriorityPrivilege",
1332 L"SeCreatePagefilePrivilege",
1333 L"SeCreatePermanentPrivilege",
1334 L"SeBackupPrivilege",
1335 L"SeRestorePrivilege",
1336 L"SeShutdownPrivilege",
1337 L"SeDebugPrivilege",
1338 L"SeAuditPrivilege",
1339 L"SeSystemEnvironmentPrivilege",
1340 L"SeChangeNotifyPrivilege",
1341 L"SeRemoteShutdownPrivilege",
1342 L"SeUndockPrivilege",
1343 L"SeSyncAgentPrivilege",
1344 L"SeEnableDelegationPrivilege",
1345 L"SeManageVolumePrivilege",
1346 L"SeImpersonatePrivilege",
1347 L"SeCreateGlobalPrivilege"
1348 };
1349 unsigned Priv;
1350
1351 if (NULL != SystemName && L'\0' != *SystemName)
1352 {
1353 FIXME("LookupPrivilegeValueW: not implemented for remote system\n");
1354 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1355 return FALSE;
1356 }
1357
1358 for (Priv = 0; Priv < sizeof(DefaultPrivNames) / sizeof(DefaultPrivNames[0]); Priv++)
1359 {
1360 if (0 == wcscmp(PrivName, DefaultPrivNames[Priv]))
1361 {
1362 Luid->LowPart = Priv + 1;
1363 Luid->HighPart = 0;
1364 return TRUE;
1365 }
1366 }
1367
1368 WARN("LookupPrivilegeValueW: no such privilege %S\n", PrivName);
1369 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1370 return FALSE;
1371 }
1372
1373
1374 /**********************************************************************
1375 * LookupPrivilegeDisplayNameA EXPORTED
1376 *
1377 * @unimplemented
1378 */
1379 BOOL
1380 STDCALL
1381 LookupPrivilegeDisplayNameA(LPCSTR lpSystemName,
1382 LPCSTR lpName,
1383 LPSTR lpDisplayName,
1384 LPDWORD cbDisplayName,
1385 LPDWORD lpLanguageId)
1386 {
1387 FIXME("%s() not implemented!\n", __FUNCTION__);
1388 SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
1389 return FALSE;
1390 }
1391
1392
1393 /**********************************************************************
1394 * LookupPrivilegeDisplayNameW EXPORTED
1395 *
1396 * @unimplemented
1397 */
1398 BOOL
1399 STDCALL
1400 LookupPrivilegeDisplayNameW(LPCWSTR lpSystemName,
1401 LPCWSTR lpName,
1402 LPWSTR lpDisplayName,
1403 LPDWORD cbDisplayName,
1404 LPDWORD lpLanguageId)
1405 {
1406 FIXME("%s() not implemented!\n", __FUNCTION__);
1407 SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
1408 return FALSE;
1409 }
1410
1411
1412 /**********************************************************************
1413 * LookupPrivilegeNameA EXPORTED
1414 *
1415 * @unimplemented
1416 */
1417 BOOL
1418 STDCALL
1419 LookupPrivilegeNameA(LPCSTR lpSystemName,
1420 PLUID lpLuid,
1421 LPSTR lpName,
1422 LPDWORD cbName)
1423 {
1424 FIXME("%s() not implemented!\n", __FUNCTION__);
1425 SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
1426 return FALSE;
1427 }
1428
1429
1430 /**********************************************************************
1431 * LookupPrivilegeNameW EXPORTED
1432 *
1433 * @unimplemented
1434 */
1435 BOOL
1436 STDCALL
1437 LookupPrivilegeNameW(LPCWSTR lpSystemName,
1438 PLUID lpLuid,
1439 LPWSTR lpName,
1440 LPDWORD cbName)
1441 {
1442 FIXME("%s() not implemented!\n", __FUNCTION__);
1443 SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
1444 return FALSE;
1445 }
1446
1447
1448 static DWORD
1449 pGetSecurityInfoCheck(SECURITY_INFORMATION SecurityInfo,
1450 PSID *ppsidOwner,
1451 PSID *ppsidGroup,
1452 PACL *ppDacl,
1453 PACL *ppSacl,
1454 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
1455 {
1456 if ((SecurityInfo & (OWNER_SECURITY_INFORMATION |
1457 GROUP_SECURITY_INFORMATION |
1458 DACL_SECURITY_INFORMATION |
1459 SACL_SECURITY_INFORMATION)) &&
1460 ppSecurityDescriptor == NULL)
1461 {
1462 /* if one of the SIDs or ACLs are present, the security descriptor
1463 most not be NULL */
1464 return ERROR_INVALID_PARAMETER;
1465 }
1466 else
1467 {
1468 /* reset the pointers unless they're ignored */
1469 if ((SecurityInfo & OWNER_SECURITY_INFORMATION) &&
1470 ppsidOwner != NULL)
1471 {
1472 *ppsidOwner = NULL;
1473 }
1474 if ((SecurityInfo & GROUP_SECURITY_INFORMATION) &&
1475 ppsidGroup != NULL)
1476 {
1477 *ppsidGroup = NULL;
1478 }
1479 if ((SecurityInfo & DACL_SECURITY_INFORMATION) &&
1480 ppDacl != NULL)
1481 {
1482 *ppDacl = NULL;
1483 }
1484 if ((SecurityInfo & SACL_SECURITY_INFORMATION) &&
1485 ppSacl != NULL)
1486 {
1487 *ppSacl = NULL;
1488 }
1489
1490 if (SecurityInfo & (OWNER_SECURITY_INFORMATION |
1491 GROUP_SECURITY_INFORMATION |
1492 DACL_SECURITY_INFORMATION |
1493 SACL_SECURITY_INFORMATION))
1494 {
1495 *ppSecurityDescriptor = NULL;
1496 }
1497
1498 return ERROR_SUCCESS;
1499 }
1500 }
1501
1502
1503 static DWORD
1504 pSetSecurityInfoCheck(PSECURITY_DESCRIPTOR pSecurityDescriptor,
1505 SECURITY_INFORMATION SecurityInfo,
1506 PSID psidOwner,
1507 PSID psidGroup,
1508 PACL pDacl,
1509 PACL pSacl)
1510 {
1511 /* initialize a security descriptor on the stack */
1512 if (!InitializeSecurityDescriptor(pSecurityDescriptor,
1513 SECURITY_DESCRIPTOR_REVISION))
1514 {
1515 return GetLastError();
1516 }
1517
1518 if (SecurityInfo & OWNER_SECURITY_INFORMATION)
1519 {
1520 if (RtlValidSid(psidOwner))
1521 {
1522 if (!SetSecurityDescriptorOwner(pSecurityDescriptor,
1523 psidOwner,
1524 FALSE))
1525 {
1526 return GetLastError();
1527 }
1528 }
1529 else
1530 {
1531 return ERROR_INVALID_PARAMETER;
1532 }
1533 }
1534
1535 if (SecurityInfo & GROUP_SECURITY_INFORMATION)
1536 {
1537 if (RtlValidSid(psidGroup))
1538 {
1539 if (!SetSecurityDescriptorGroup(pSecurityDescriptor,
1540 psidGroup,
1541 FALSE))
1542 {
1543 return GetLastError();
1544 }
1545 }
1546 else
1547 {
1548 return ERROR_INVALID_PARAMETER;
1549 }
1550 }
1551
1552 if (SecurityInfo & DACL_SECURITY_INFORMATION)
1553 {
1554 if (pDacl != NULL)
1555 {
1556 if (SetSecurityDescriptorDacl(pSecurityDescriptor,
1557 TRUE,
1558 pDacl,
1559 FALSE))
1560 {
1561 /* check if the DACL needs to be protected from being
1562 modified by inheritable ACEs */
1563 if (SecurityInfo & PROTECTED_DACL_SECURITY_INFORMATION)
1564 {
1565 goto ProtectDacl;
1566 }
1567 }
1568 else
1569 {
1570 return GetLastError();
1571 }
1572 }
1573 else
1574 {
1575 ProtectDacl:
1576 /* protect the DACL from being modified by inheritable ACEs */
1577 if (!SetSecurityDescriptorControl(pSecurityDescriptor,
1578 SE_DACL_PROTECTED,
1579 SE_DACL_PROTECTED))
1580 {
1581 return GetLastError();
1582 }
1583 }
1584 }
1585
1586 if (SecurityInfo & SACL_SECURITY_INFORMATION)
1587 {
1588 if (pSacl != NULL)
1589 {
1590 if (SetSecurityDescriptorSacl(pSecurityDescriptor,
1591 TRUE,
1592 pSacl,
1593 FALSE))
1594 {
1595 /* check if the SACL needs to be protected from being
1596 modified by inheritable ACEs */
1597 if (SecurityInfo & PROTECTED_SACL_SECURITY_INFORMATION)
1598 {
1599 goto ProtectSacl;
1600 }
1601 }
1602 else
1603 {
1604 return GetLastError();
1605 }
1606 }
1607 else
1608 {
1609 ProtectSacl:
1610 /* protect the SACL from being modified by inheritable ACEs */
1611 if (!SetSecurityDescriptorControl(pSecurityDescriptor,
1612 SE_SACL_PROTECTED,
1613 SE_SACL_PROTECTED))
1614 {
1615 return GetLastError();
1616 }
1617 }
1618 }
1619
1620 return ERROR_SUCCESS;
1621 }
1622
1623
1624 /**********************************************************************
1625 * GetNamedSecurityInfoW EXPORTED
1626 *
1627 * @implemented
1628 */
1629 DWORD
1630 STDCALL
1631 GetNamedSecurityInfoW(LPWSTR pObjectName,
1632 SE_OBJECT_TYPE ObjectType,
1633 SECURITY_INFORMATION SecurityInfo,
1634 PSID *ppsidOwner,
1635 PSID *ppsidGroup,
1636 PACL *ppDacl,
1637 PACL *ppSacl,
1638 PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
1639 {
1640 DWORD ErrorCode;
1641
1642 if (pObjectName != NULL)
1643 {
1644 ErrorCode = CheckNtMartaPresent();
1645 if (ErrorCode == ERROR_SUCCESS)
1646 {
1647 ErrorCode = pGetSecurityInfoCheck(SecurityInfo,
1648 ppsidOwner,
1649 ppsidGroup,
1650 ppDacl,
1651 ppSacl,
1652 ppSecurityDescriptor);
1653
1654 if (ErrorCode == ERROR_SUCCESS)
1655 {
1656 /* call the MARTA provider */
1657 ErrorCode = AccRewriteGetNamedRights(pObjectName,
1658 ObjectType,
1659 SecurityInfo,
1660 ppsidOwner,
1661 ppsidGroup,
1662 ppDacl,
1663 ppSacl,
1664 ppSecurityDescriptor);
1665 }
1666 }
1667 }
1668 else
1669 ErrorCode = ERROR_INVALID_PARAMETER;
1670
1671 return ErrorCode;
1672 }
1673
1674
1675 /**********************************************************************
1676 * GetNamedSecurityInfoA EXPORTED
1677 *
1678 * @implemented
1679 */
1680 DWORD
1681 STDCALL
1682 GetNamedSecurityInfoA(LPSTR pObjectName,
1683 SE_OBJECT_TYPE ObjectType,
1684 SECURITY_INFORMATION SecurityInfo,
1685 PSID *ppsidOwner,
1686 PSID *ppsidGroup,
1687 PACL *ppDacl,
1688 PACL *ppSacl,
1689 PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
1690 {
1691 UNICODE_STRING ObjectName;
1692 NTSTATUS Status;
1693 DWORD Ret;
1694
1695 Status = RtlCreateUnicodeStringFromAsciiz(&ObjectName,
1696 pObjectName);
1697 if (!NT_SUCCESS(Status))
1698 {
1699 return RtlNtStatusToDosError(Status);
1700 }
1701
1702 Ret = GetNamedSecurityInfoW(ObjectName.Buffer,
1703 ObjectType,
1704 SecurityInfo,
1705 ppsidOwner,
1706 ppsidGroup,
1707 ppDacl,
1708 ppSacl,
1709 ppSecurityDescriptor);
1710
1711 RtlFreeUnicodeString(&ObjectName);
1712
1713 return Ret;
1714 }
1715
1716
1717 /**********************************************************************
1718 * SetNamedSecurityInfoW EXPORTED
1719 *
1720 * @implemented
1721 */
1722 DWORD
1723 STDCALL
1724 SetNamedSecurityInfoW(LPWSTR pObjectName,
1725 SE_OBJECT_TYPE ObjectType,
1726 SECURITY_INFORMATION SecurityInfo,
1727 PSID psidOwner,
1728 PSID psidGroup,
1729 PACL pDacl,
1730 PACL pSacl)
1731 {
1732 DWORD ErrorCode;
1733
1734 if (pObjectName != NULL)
1735 {
1736 ErrorCode = CheckNtMartaPresent();
1737 if (ErrorCode == ERROR_SUCCESS)
1738 {
1739 SECURITY_DESCRIPTOR SecurityDescriptor;
1740
1741 ErrorCode = pSetSecurityInfoCheck(&SecurityDescriptor,
1742 SecurityInfo,
1743 psidOwner,
1744 psidGroup,
1745 pDacl,
1746 pSacl);
1747
1748 if (ErrorCode == ERROR_SUCCESS)
1749 {
1750 /* call the MARTA provider */
1751 ErrorCode = AccRewriteSetNamedRights(pObjectName,
1752 ObjectType,
1753 SecurityInfo,
1754 &SecurityDescriptor);
1755 }
1756 }
1757 }
1758 else
1759 ErrorCode = ERROR_INVALID_PARAMETER;
1760
1761 return ErrorCode;
1762 }
1763
1764
1765 /**********************************************************************
1766 * SetNamedSecurityInfoA EXPORTED
1767 *
1768 * @implemented
1769 */
1770 DWORD
1771 STDCALL
1772 SetNamedSecurityInfoA(LPSTR pObjectName,
1773 SE_OBJECT_TYPE ObjectType,
1774 SECURITY_INFORMATION SecurityInfo,
1775 PSID psidOwner,
1776 PSID psidGroup,
1777 PACL pDacl,
1778 PACL pSacl)
1779 {
1780 UNICODE_STRING ObjectName;
1781 NTSTATUS Status;
1782 DWORD Ret;
1783
1784 Status = RtlCreateUnicodeStringFromAsciiz(&ObjectName,
1785 pObjectName);
1786 if (!NT_SUCCESS(Status))
1787 {
1788 return RtlNtStatusToDosError(Status);
1789 }
1790
1791 Ret = SetNamedSecurityInfoW(ObjectName.Buffer,
1792 ObjectType,
1793 SecurityInfo,
1794 psidOwner,
1795 psidGroup,
1796 pDacl,
1797 pSacl);
1798
1799 RtlFreeUnicodeString(&ObjectName);
1800
1801 return Ret;
1802 }
1803
1804
1805 /**********************************************************************
1806 * GetSecurityInfo EXPORTED
1807 *
1808 * @implemented
1809 */
1810 DWORD
1811 STDCALL
1812 GetSecurityInfo(HANDLE handle,
1813 SE_OBJECT_TYPE ObjectType,
1814 SECURITY_INFORMATION SecurityInfo,
1815 PSID *ppsidOwner,
1816 PSID *ppsidGroup,
1817 PACL *ppDacl,
1818 PACL *ppSacl,
1819 PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
1820 {
1821 DWORD ErrorCode;
1822
1823 if (handle != NULL)
1824 {
1825 ErrorCode = CheckNtMartaPresent();
1826 if (ErrorCode == ERROR_SUCCESS)
1827 {
1828 ErrorCode = pGetSecurityInfoCheck(SecurityInfo,
1829 ppsidOwner,
1830 ppsidGroup,
1831 ppDacl,
1832 ppSacl,
1833 ppSecurityDescriptor);
1834
1835 if (ErrorCode == ERROR_SUCCESS)
1836 {
1837 /* call the MARTA provider */
1838 ErrorCode = AccRewriteGetHandleRights(handle,
1839 ObjectType,
1840 SecurityInfo,
1841 ppsidOwner,
1842 ppsidGroup,
1843 ppDacl,
1844 ppSacl,
1845 ppSecurityDescriptor);
1846 }
1847 }
1848 }
1849 else
1850 ErrorCode = ERROR_INVALID_HANDLE;
1851
1852 return ErrorCode;
1853 }
1854
1855
1856 /**********************************************************************
1857 * SetSecurityInfo EXPORTED
1858 *
1859 * @implemented
1860 */
1861 DWORD
1862 WINAPI
1863 SetSecurityInfo(HANDLE handle,
1864 SE_OBJECT_TYPE ObjectType,
1865 SECURITY_INFORMATION SecurityInfo,
1866 PSID psidOwner,
1867 PSID psidGroup,
1868 PACL pDacl,
1869 PACL pSacl)
1870 {
1871 DWORD ErrorCode;
1872
1873 if (handle != NULL)
1874 {
1875 ErrorCode = CheckNtMartaPresent();
1876 if (ErrorCode == ERROR_SUCCESS)
1877 {
1878 SECURITY_DESCRIPTOR SecurityDescriptor;
1879
1880 ErrorCode = pSetSecurityInfoCheck(&SecurityDescriptor,
1881 SecurityInfo,
1882 psidOwner,
1883 psidGroup,
1884 pDacl,
1885 pSacl);
1886
1887 if (ErrorCode == ERROR_SUCCESS)
1888 {
1889 /* call the MARTA provider */
1890 ErrorCode = AccRewriteSetHandleRights(handle,
1891 ObjectType,
1892 SecurityInfo,
1893 &SecurityDescriptor);
1894 }
1895 }
1896 }
1897 else
1898 ErrorCode = ERROR_INVALID_HANDLE;
1899
1900 return ErrorCode;
1901 }
1902
1903
1904 /******************************************************************************
1905 * GetSecurityInfoExW EXPORTED
1906 */
1907 DWORD
1908 WINAPI
1909 GetSecurityInfoExA(HANDLE hObject,
1910 SE_OBJECT_TYPE ObjectType,
1911 SECURITY_INFORMATION SecurityInfo,
1912 LPCSTR lpProvider,
1913 LPCSTR lpProperty,
1914 PACTRL_ACCESSA *ppAccessList,
1915 PACTRL_AUDITA *ppAuditList,
1916 LPSTR *lppOwner,
1917 LPSTR *lppGroup)
1918 {
1919 FIXME("%s() not implemented!\n", __FUNCTION__);
1920 return ERROR_BAD_PROVIDER;
1921 }
1922
1923
1924 /******************************************************************************
1925 * GetSecurityInfoExW EXPORTED
1926 */
1927 DWORD
1928 WINAPI
1929 GetSecurityInfoExW(HANDLE hObject,
1930 SE_OBJECT_TYPE ObjectType,
1931 SECURITY_INFORMATION SecurityInfo,
1932 LPCWSTR lpProvider,
1933 LPCWSTR lpProperty,
1934 PACTRL_ACCESSW *ppAccessList,
1935 PACTRL_AUDITW *ppAuditList,
1936 LPWSTR *lppOwner,
1937 LPWSTR *lppGroup)
1938 {
1939 FIXME("%s() not implemented!\n", __FUNCTION__);
1940 return ERROR_BAD_PROVIDER;
1941 }
1942
1943
1944 /**********************************************************************
1945 * ImpersonateNamedPipeClient EXPORTED
1946 *
1947 * @implemented
1948 */
1949 BOOL
1950 STDCALL
1951 ImpersonateNamedPipeClient(HANDLE hNamedPipe)
1952 {
1953 IO_STATUS_BLOCK StatusBlock;
1954 NTSTATUS Status;
1955
1956 TRACE("ImpersonateNamedPipeClient() called\n");
1957
1958 Status = NtFsControlFile(hNamedPipe,
1959 NULL,
1960 NULL,
1961 NULL,
1962 &StatusBlock,
1963 FSCTL_PIPE_IMPERSONATE,
1964 NULL,
1965 0,
1966 NULL,
1967 0);
1968 if (!NT_SUCCESS(Status))
1969 {
1970 SetLastError(RtlNtStatusToDosError(Status));
1971 return FALSE;
1972 }
1973
1974 return TRUE;
1975 }
1976
1977
1978 /*
1979 * @implemented
1980 */
1981 BOOL
1982 STDCALL
1983 CreatePrivateObjectSecurity(PSECURITY_DESCRIPTOR ParentDescriptor,
1984 PSECURITY_DESCRIPTOR CreatorDescriptor,
1985 PSECURITY_DESCRIPTOR *NewDescriptor,
1986 BOOL IsDirectoryObject,
1987 HANDLE Token,
1988 PGENERIC_MAPPING GenericMapping)
1989 {
1990 NTSTATUS Status;
1991
1992 Status = RtlNewSecurityObject(ParentDescriptor,
1993 CreatorDescriptor,
1994 NewDescriptor,
1995 IsDirectoryObject,
1996 Token,
1997 GenericMapping);
1998 if (!NT_SUCCESS(Status))
1999 {
2000 SetLastError(RtlNtStatusToDosError(Status));
2001 return FALSE;
2002 }
2003
2004 return TRUE;
2005 }
2006
2007
2008 /*
2009 * @unimplemented
2010 */
2011 BOOL
2012 STDCALL
2013 CreatePrivateObjectSecurityEx(PSECURITY_DESCRIPTOR ParentDescriptor,
2014 PSECURITY_DESCRIPTOR CreatorDescriptor,
2015 PSECURITY_DESCRIPTOR* NewDescriptor,
2016 GUID* ObjectType,
2017 BOOL IsContainerObject,
2018 ULONG AutoInheritFlags,
2019 HANDLE Token,
2020 PGENERIC_MAPPING GenericMapping)
2021 {
2022 FIXME("%s() not implemented!\n", __FUNCTION__);
2023 return FALSE;
2024 }
2025
2026
2027 /*
2028 * @unimplemented
2029 */
2030 BOOL
2031 STDCALL
2032 CreatePrivateObjectSecurityWithMultipleInheritance(PSECURITY_DESCRIPTOR ParentDescriptor,
2033 PSECURITY_DESCRIPTOR CreatorDescriptor,
2034 PSECURITY_DESCRIPTOR* NewDescriptor,
2035 GUID** ObjectTypes,
2036 ULONG GuidCount,
2037 BOOL IsContainerObject,
2038 ULONG AutoInheritFlags,
2039 HANDLE Token,
2040 PGENERIC_MAPPING GenericMapping)
2041 {
2042 FIXME("%s() not implemented!\n", __FUNCTION__);
2043 return FALSE;
2044 }
2045
2046
2047 /*
2048 * @implemented
2049 */
2050 BOOL
2051 STDCALL
2052 DestroyPrivateObjectSecurity(PSECURITY_DESCRIPTOR *ObjectDescriptor)
2053 {
2054 NTSTATUS Status;
2055
2056 Status = RtlDeleteSecurityObject(ObjectDescriptor);
2057 if (!NT_SUCCESS(Status))
2058 {
2059 SetLastError(RtlNtStatusToDosError(Status));
2060 return FALSE;
2061 }
2062
2063 return TRUE;
2064 }
2065
2066
2067 /*
2068 * @implemented
2069 */
2070 BOOL
2071 STDCALL
2072 GetPrivateObjectSecurity(PSECURITY_DESCRIPTOR ObjectDescriptor,
2073 SECURITY_INFORMATION SecurityInformation,
2074 PSECURITY_DESCRIPTOR ResultantDescriptor,
2075 DWORD DescriptorLength,
2076 PDWORD ReturnLength)
2077 {
2078 NTSTATUS Status;
2079
2080 Status = RtlQuerySecurityObject(ObjectDescriptor,
2081 SecurityInformation,
2082 ResultantDescriptor,
2083 DescriptorLength,
2084 ReturnLength);
2085 if (!NT_SUCCESS(Status))
2086 {
2087 SetLastError(RtlNtStatusToDosError(Status));
2088 return FALSE;
2089 }
2090
2091 return TRUE;
2092 }
2093
2094
2095 /*
2096 * @implemented
2097 */
2098 BOOL
2099 STDCALL
2100 SetPrivateObjectSecurity(SECURITY_INFORMATION SecurityInformation,
2101 PSECURITY_DESCRIPTOR ModificationDescriptor,
2102 PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
2103 PGENERIC_MAPPING GenericMapping,
2104 HANDLE Token)
2105 {
2106 NTSTATUS Status;
2107
2108 Status = RtlSetSecurityObject(SecurityInformation,
2109 ModificationDescriptor,
2110 ObjectsSecurityDescriptor,
2111 GenericMapping,
2112 Token);
2113 if (!NT_SUCCESS(Status))
2114 {
2115 SetLastError(RtlNtStatusToDosError(Status));
2116 return FALSE;
2117 }
2118
2119 return TRUE;
2120 }
2121
2122
2123 /*
2124 * @implemented
2125 */
2126 DWORD
2127 STDCALL
2128 TreeResetNamedSecurityInfoW(LPWSTR pObjectName,
2129 SE_OBJECT_TYPE ObjectType,
2130 SECURITY_INFORMATION SecurityInfo,
2131 PSID pOwner,
2132 PSID pGroup,
2133 PACL pDacl,
2134 PACL pSacl,
2135 BOOL KeepExplicit,
2136 FN_PROGRESSW fnProgress,
2137 PROG_INVOKE_SETTING ProgressInvokeSetting,
2138 PVOID Args)
2139 {
2140 DWORD ErrorCode;
2141
2142 if (pObjectName != NULL)
2143 {
2144 ErrorCode = CheckNtMartaPresent();
2145 if (ErrorCode == ERROR_SUCCESS)
2146 {
2147 switch (ObjectType)
2148 {
2149 case SE_FILE_OBJECT:
2150 case SE_REGISTRY_KEY:
2151 {
2152 /* check the SecurityInfo flags for sanity (both, the protected
2153 and unprotected dacl/sacl flag must not be passed together) */
2154 if (((SecurityInfo & DACL_SECURITY_INFORMATION) &&
2155 (SecurityInfo & (PROTECTED_DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION)) ==
2156 (PROTECTED_DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION))
2157
2158 ||
2159
2160 ((SecurityInfo & SACL_SECURITY_INFORMATION) &&
2161 (SecurityInfo & (PROTECTED_SACL_SECURITY_INFORMATION | UNPROTECTED_SACL_SECURITY_INFORMATION)) ==
2162 (PROTECTED_SACL_SECURITY_INFORMATION | UNPROTECTED_SACL_SECURITY_INFORMATION)))
2163 {
2164 ErrorCode = ERROR_INVALID_PARAMETER;
2165 break;
2166 }
2167
2168 /* call the MARTA provider */
2169 ErrorCode = AccTreeResetNamedSecurityInfo(pObjectName,
2170 ObjectType,
2171 SecurityInfo,
2172 pOwner,
2173 pGroup,
2174 pDacl,
2175 pSacl,
2176 KeepExplicit,
2177 fnProgress,
2178 ProgressInvokeSetting,
2179 Args);
2180 break;
2181 }
2182
2183 default:
2184 /* object type not supported */
2185 ErrorCode = ERROR_INVALID_PARAMETER;
2186 break;
2187 }
2188 }
2189 }
2190 else
2191 ErrorCode = ERROR_INVALID_PARAMETER;
2192
2193 return ErrorCode;
2194 }
2195
2196 #ifdef HAS_FN_PROGRESSW
2197
2198 typedef struct _INERNAL_FNPROGRESSW_DATA
2199 {
2200 FN_PROGRESSA fnProgress;
2201 PVOID Args;
2202 } INERNAL_FNPROGRESSW_DATA, *PINERNAL_FNPROGRESSW_DATA;
2203
2204 static VOID STDCALL
2205 InternalfnProgressW(LPWSTR pObjectName,
2206 DWORD Status,
2207 PPROG_INVOKE_SETTING pInvokeSetting,
2208 PVOID Args,
2209 BOOL SecuritySet)
2210 {
2211 PINERNAL_FNPROGRESSW_DATA pifnProgressData = (PINERNAL_FNPROGRESSW_DATA)Args;
2212 INT ObjectNameSize;
2213 LPSTR pObjectNameA;
2214
2215 ObjectNameSize = WideCharToMultiByte(CP_ACP,
2216 0,
2217 pObjectName,
2218 -1,
2219 NULL,
2220 0,
2221 NULL,
2222 NULL);
2223
2224 if (ObjectNameSize > 0)
2225 {
2226 pObjectNameA = RtlAllocateHeap(RtlGetProcessHeap(),
2227 0,
2228 ObjectNameSize);
2229 if (pObjectNameA != NULL)
2230 {
2231 pObjectNameA[0] = '\0';
2232 WideCharToMultiByte(CP_ACP,
2233 0,
2234 pObjectName,
2235 -1,
2236 pObjectNameA,
2237 ObjectNameSize,
2238 NULL,
2239 NULL);
2240
2241 pifnProgressData->fnProgress((LPWSTR)pObjectNameA, /* FIXME: wrong cast!! */
2242 Status,
2243 pInvokeSetting,
2244 pifnProgressData->Args,
2245 SecuritySet);
2246
2247 RtlFreeHeap(RtlGetProcessHeap(),
2248 0,
2249 pObjectNameA);
2250 }
2251 }
2252 }
2253 #endif
2254
2255
2256 /*
2257 * @implemented
2258 */
2259 DWORD
2260 STDCALL
2261 TreeResetNamedSecurityInfoA(LPSTR pObjectName,
2262 SE_OBJECT_TYPE ObjectType,
2263 SECURITY_INFORMATION SecurityInfo,
2264 PSID pOwner,
2265 PSID pGroup,
2266 PACL pDacl,
2267 PACL pSacl,
2268 BOOL KeepExplicit,
2269 FN_PROGRESSA fnProgress,
2270 PROG_INVOKE_SETTING ProgressInvokeSetting,
2271 PVOID Args)
2272 {
2273 #ifndef HAS_FN_PROGRESSW
2274 /* That's all this function does, at least up to w2k3... Even MS was too
2275 lazy to implement it... */
2276 return ERROR_CALL_NOT_IMPLEMENTED;
2277 #else
2278 INERNAL_FNPROGRESSW_DATA ifnProgressData;
2279 UNICODE_STRING ObjectName;
2280 NTSTATUS Status;
2281 DWORD Ret;
2282
2283 Status = RtlCreateUnicodeStringFromAsciiz(&ObjectName,
2284 pObjectName);
2285 if (!NT_SUCCESS(Status))
2286 {
2287 return RtlNtStatusToDosError(Status);
2288 }
2289
2290 ifnProgressData.fnProgress = fnProgress;
2291 ifnProgressData.Args = Args;
2292
2293 Ret = TreeResetNamedSecurityInfoW(ObjectName.Buffer,
2294 ObjectType,
2295 SecurityInfo,
2296 pOwner,
2297 pGroup,
2298 pDacl,
2299 pSacl,
2300 KeepExplicit,
2301 (fnProgress != NULL ? InternalfnProgressW : NULL),
2302 ProgressInvokeSetting,
2303 &ifnProgressData);
2304
2305 RtlFreeUnicodeString(&ObjectName);
2306
2307 return Ret;
2308 #endif
2309 }
2310
2311 /* EOF */