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