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