Sync with trunk (r48008)
[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 if ( !OpenProcessToken ( GetCurrentProcess(), TOKEN_QUERY, &hToken ) )
816 {
817 /* don't call SetLastError(),
818 as OpenProcessToken() ought to have set one */
819 return FALSE;
820 }
821 }
822 tu_buf = LocalAlloc ( LMEM_FIXED, 36 );
823 if ( !tu_buf )
824 {
825 SetLastError ( ERROR_NOT_ENOUGH_MEMORY );
826 CloseHandle ( hToken );
827 return FALSE;
828 }
829 if ( !GetTokenInformation ( hToken, TokenUser, tu_buf, 36, &tu_len ) || tu_len > 36 )
830 {
831 LocalFree ( tu_buf );
832 tu_buf = LocalAlloc ( LMEM_FIXED, tu_len );
833 if ( !tu_buf )
834 {
835 SetLastError ( ERROR_NOT_ENOUGH_MEMORY );
836 CloseHandle ( hToken );
837 return FALSE;
838 }
839 if ( !GetTokenInformation ( hToken, TokenUser, tu_buf, tu_len, &tu_len ) )
840 {
841 /* don't call SetLastError(),
842 as GetTokenInformation() ought to have set one */
843 LocalFree ( tu_buf );
844 CloseHandle ( hToken );
845 return FALSE;
846 }
847 }
848 CloseHandle ( hToken );
849 token_user = (TOKEN_USER*)tu_buf;
850
851 an_len = *lpSize;
852 dn_len = 32;
853 domain_name = LocalAlloc ( LMEM_FIXED, dn_len * sizeof(WCHAR) );
854 if ( !domain_name )
855 {
856 LocalFree ( tu_buf );
857 SetLastError ( ERROR_NOT_ENOUGH_MEMORY );
858 return FALSE;
859 }
860 if ( !LookupAccountSidW ( NULL, token_user->User.Sid, lpszName, &an_len, domain_name, &dn_len, &snu )
861 || dn_len > 32 )
862 {
863 if ( dn_len > 32 )
864 {
865 LocalFree ( domain_name );
866 domain_name = LocalAlloc ( LMEM_FIXED, dn_len * sizeof(WCHAR) );
867 if ( !domain_name )
868 {
869 LocalFree ( tu_buf );
870 SetLastError ( ERROR_NOT_ENOUGH_MEMORY );
871 return FALSE;
872 }
873 }
874 an_len = *lpSize;
875 if ( !LookupAccountSidW ( NULL, token_user->User.Sid, lpszName, &an_len, domain_name, &dn_len, &snu ) )
876 {
877 /* don't call SetLastError(),
878 as LookupAccountSid() ought to have set one */
879 LocalFree ( domain_name );
880 LocalFree ( tu_buf );
881 *lpSize = an_len;
882 return FALSE;
883 }
884 }
885
886 LocalFree ( domain_name );
887 LocalFree ( tu_buf );
888 *lpSize = an_len + 1;
889 return TRUE;
890 }
891
892
893 /******************************************************************************
894 * LookupAccountSidA [ADVAPI32.@]
895 *
896 * @implemented
897 */
898 BOOL
899 WINAPI
900 LookupAccountSidA(LPCSTR lpSystemName,
901 PSID lpSid,
902 LPSTR lpName,
903 LPDWORD cchName,
904 LPSTR lpReferencedDomainName,
905 LPDWORD cchReferencedDomainName,
906 PSID_NAME_USE peUse)
907 {
908 UNICODE_STRING NameW, ReferencedDomainNameW, SystemNameW;
909 DWORD szName, szReferencedDomainName;
910 BOOL Ret;
911
912 /*
913 * save the buffer sizes the caller passed to us, as they may get modified and
914 * we require the original values when converting back to ansi
915 */
916 szName = *cchName;
917 szReferencedDomainName = *cchReferencedDomainName;
918
919 /*
920 * allocate buffers for the unicode strings to receive
921 */
922
923 if(szName > 0)
924 {
925 NameW.Length = 0;
926 NameW.MaximumLength = szName * sizeof(WCHAR);
927 NameW.Buffer = (PWSTR)LocalAlloc(LMEM_FIXED, NameW.MaximumLength);
928 if(NameW.Buffer == NULL)
929 {
930 SetLastError(ERROR_OUTOFMEMORY);
931 return FALSE;
932 }
933 }
934 else
935 NameW.Buffer = NULL;
936
937 if(szReferencedDomainName > 0)
938 {
939 ReferencedDomainNameW.Length = 0;
940 ReferencedDomainNameW.MaximumLength = szReferencedDomainName * sizeof(WCHAR);
941 ReferencedDomainNameW.Buffer = (PWSTR)LocalAlloc(LMEM_FIXED, ReferencedDomainNameW.MaximumLength);
942 if(ReferencedDomainNameW.Buffer == NULL)
943 {
944 if(szName > 0)
945 {
946 LocalFree(NameW.Buffer);
947 }
948 SetLastError(ERROR_OUTOFMEMORY);
949 return FALSE;
950 }
951 }
952 else
953 ReferencedDomainNameW.Buffer = NULL;
954
955 /*
956 * convert the system name to unicode - if present
957 */
958
959 if(lpSystemName != NULL)
960 {
961 ANSI_STRING SystemNameA;
962
963 RtlInitAnsiString(&SystemNameA, lpSystemName);
964 RtlAnsiStringToUnicodeString(&SystemNameW, &SystemNameA, TRUE);
965 }
966 else
967 SystemNameW.Buffer = NULL;
968
969 /*
970 * it's time to call the unicode version
971 */
972
973 Ret = LookupAccountSidW(SystemNameW.Buffer,
974 lpSid,
975 NameW.Buffer,
976 cchName,
977 ReferencedDomainNameW.Buffer,
978 cchReferencedDomainName,
979 peUse);
980 if(Ret)
981 {
982 /*
983 * convert unicode strings back to ansi, don't forget that we can't convert
984 * more than 0xFFFF (USHORT) characters! Also don't forget to explicitly
985 * terminate the converted string, the Rtl functions don't do that!
986 */
987 if(lpName != NULL)
988 {
989 ANSI_STRING NameA;
990
991 NameA.Length = 0;
992 NameA.MaximumLength = ((szName <= 0xFFFF) ? (USHORT)szName : 0xFFFF);
993 NameA.Buffer = lpName;
994
995 RtlUnicodeStringToAnsiString(&NameA, &NameW, FALSE);
996 NameA.Buffer[NameA.Length] = '\0';
997 }
998
999 if(lpReferencedDomainName != NULL)
1000 {
1001 ANSI_STRING ReferencedDomainNameA;
1002
1003 ReferencedDomainNameA.Length = 0;
1004 ReferencedDomainNameA.MaximumLength = ((szReferencedDomainName <= 0xFFFF) ?
1005 (USHORT)szReferencedDomainName : 0xFFFF);
1006 ReferencedDomainNameA.Buffer = lpReferencedDomainName;
1007
1008 RtlUnicodeStringToAnsiString(&ReferencedDomainNameA, &ReferencedDomainNameW, FALSE);
1009 ReferencedDomainNameA.Buffer[ReferencedDomainNameA.Length] = '\0';
1010 }
1011 }
1012
1013 /*
1014 * free previously allocated buffers
1015 */
1016
1017 if(SystemNameW.Buffer != NULL)
1018 {
1019 RtlFreeUnicodeString(&SystemNameW);
1020 }
1021 if(NameW.Buffer != NULL)
1022 {
1023 LocalFree(NameW.Buffer);
1024 }
1025 if(ReferencedDomainNameW.Buffer != NULL)
1026 {
1027 LocalFree(ReferencedDomainNameW.Buffer);
1028 }
1029
1030 return Ret;
1031 }
1032
1033
1034 /******************************************************************************
1035 * LookupAccountSidW [ADVAPI32.@]
1036 *
1037 * @implemented
1038 */
1039 BOOL WINAPI
1040 LookupAccountSidW(LPCWSTR pSystemName,
1041 PSID pSid,
1042 LPWSTR pAccountName,
1043 LPDWORD pdwAccountName,
1044 LPWSTR pDomainName,
1045 LPDWORD pdwDomainName,
1046 PSID_NAME_USE peUse)
1047 {
1048 LSA_UNICODE_STRING SystemName;
1049 LSA_OBJECT_ATTRIBUTES ObjectAttributes = {0};
1050 LSA_HANDLE PolicyHandle = NULL;
1051 NTSTATUS Status;
1052 PLSA_REFERENCED_DOMAIN_LIST ReferencedDomain = NULL;
1053 PLSA_TRANSLATED_NAME TranslatedName = NULL;
1054 BOOL ret;
1055 DWORD dwAccountName, dwDomainName;
1056
1057 RtlInitUnicodeString ( &SystemName, pSystemName );
1058 Status = LsaOpenPolicy ( &SystemName, &ObjectAttributes, POLICY_LOOKUP_NAMES, &PolicyHandle );
1059 if ( !NT_SUCCESS(Status) )
1060 {
1061 SetLastError ( LsaNtStatusToWinError(Status) );
1062 return FALSE;
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 } else
1090 {
1091 /* Lengths are sufficient, copy the data */
1092 if(dwAccountName)
1093 RtlCopyMemory(pAccountName, TranslatedName->Name.Buffer, dwAccountName * sizeof(WCHAR));
1094 pAccountName[dwAccountName] = L'\0';
1095
1096 if(dwDomainName)
1097 RtlCopyMemory(pDomainName, ReferencedDomain->Domains[0].Name.Buffer, dwDomainName * sizeof(WCHAR));
1098 pDomainName[dwDomainName] = L'\0';
1099
1100 *pdwAccountName = dwAccountName;
1101 *pdwDomainName = dwDomainName;
1102
1103 if (peUse)
1104 *peUse = TranslatedName->Use;
1105 }
1106
1107 if ( !ret )
1108 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1109 }
1110
1111 if ( ReferencedDomain )
1112 LsaFreeMemory ( ReferencedDomain );
1113 if ( TranslatedName )
1114 LsaFreeMemory ( TranslatedName );
1115
1116 return ret;
1117 }
1118
1119
1120
1121 /******************************************************************************
1122 * LookupAccountNameA [ADVAPI32.@]
1123 *
1124 * @implemented
1125 */
1126 BOOL
1127 WINAPI
1128 LookupAccountNameA(LPCSTR SystemName,
1129 LPCSTR AccountName,
1130 PSID Sid,
1131 LPDWORD SidLength,
1132 LPSTR ReferencedDomainName,
1133 LPDWORD hReferencedDomainNameLength,
1134 PSID_NAME_USE SidNameUse)
1135 {
1136 BOOL ret;
1137 UNICODE_STRING lpSystemW;
1138 UNICODE_STRING lpAccountW;
1139 LPWSTR lpReferencedDomainNameW = NULL;
1140
1141 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, SystemName);
1142 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, AccountName);
1143
1144 if (ReferencedDomainName)
1145 lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(),
1146 0,
1147 *hReferencedDomainNameLength * sizeof(WCHAR));
1148
1149 ret = LookupAccountNameW(lpSystemW.Buffer,
1150 lpAccountW.Buffer,
1151 Sid,
1152 SidLength,
1153 lpReferencedDomainNameW,
1154 hReferencedDomainNameLength,
1155 SidNameUse);
1156
1157 if (ret && lpReferencedDomainNameW)
1158 {
1159 WideCharToMultiByte(CP_ACP,
1160 0,
1161 lpReferencedDomainNameW,
1162 *hReferencedDomainNameLength + 1,
1163 ReferencedDomainName,
1164 *hReferencedDomainNameLength + 1,
1165 NULL,
1166 NULL);
1167 }
1168
1169 RtlFreeUnicodeString(&lpSystemW);
1170 RtlFreeUnicodeString(&lpAccountW);
1171 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
1172
1173 return ret;
1174 }
1175
1176
1177 /******************************************************************************
1178 * LookupAccountNameW [ADVAPI32.@]
1179 *
1180 * @unimplemented
1181 */
1182 BOOL
1183 WINAPI
1184 LookupAccountNameW(LPCWSTR lpSystemName,
1185 LPCWSTR lpAccountName,
1186 PSID Sid,
1187 LPDWORD cbSid,
1188 LPWSTR ReferencedDomainName,
1189 LPDWORD cchReferencedDomainName,
1190 PSID_NAME_USE peUse)
1191 {
1192 /* Default implementation: Always return a default SID */
1193 SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
1194 BOOL ret;
1195 PSID pSid;
1196 static const WCHAR dm[] = {'D','O','M','A','I','N',0};
1197 unsigned int i;
1198
1199 TRACE("%s %s %p %p %p %p %p - stub\n", lpSystemName, lpAccountName,
1200 Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
1201
1202 if (!ADVAPI_IsLocalComputer(lpSystemName))
1203 {
1204 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1205 return FALSE;
1206 }
1207
1208 for (i = 0; i < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); i++)
1209 {
1210 if (!wcscmp(lpAccountName, ACCOUNT_SIDS[i].account))
1211 {
1212 if (*cchReferencedDomainName)
1213 *ReferencedDomainName = '\0';
1214 *cchReferencedDomainName = 0;
1215 *peUse = SidTypeWellKnownGroup;
1216 return CreateWellKnownSid(ACCOUNT_SIDS[i].type, NULL, Sid, cbSid);
1217 }
1218 }
1219
1220 ret = AllocateAndInitializeSid(&identifierAuthority,
1221 2,
1222 SECURITY_BUILTIN_DOMAIN_RID,
1223 DOMAIN_ALIAS_RID_ADMINS,
1224 0, 0, 0, 0, 0, 0,
1225 &pSid);
1226
1227 if (!ret)
1228 return FALSE;
1229
1230 if (!RtlValidSid(pSid))
1231 {
1232 FreeSid(pSid);
1233 return FALSE;
1234 }
1235
1236 if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
1237 CopySid(*cbSid, Sid, pSid);
1238
1239 if (*cbSid < GetLengthSid(pSid))
1240 {
1241 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1242 ret = FALSE;
1243 }
1244
1245 *cbSid = GetLengthSid(pSid);
1246
1247 if (ReferencedDomainName != NULL && (*cchReferencedDomainName > wcslen(dm)))
1248 wcscpy(ReferencedDomainName, dm);
1249
1250 if ((*cchReferencedDomainName <= wcslen(dm)) || (!ret))
1251 {
1252 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1253 ret = FALSE;
1254 *cchReferencedDomainName = wcslen(dm) + 1;
1255 }
1256 else
1257 {
1258 *cchReferencedDomainName = wcslen(dm);
1259 }
1260
1261 FreeSid(pSid);
1262
1263 return ret;
1264 }
1265
1266
1267 /**********************************************************************
1268 * LookupPrivilegeValueA EXPORTED
1269 *
1270 * @implemented
1271 */
1272 BOOL
1273 WINAPI
1274 LookupPrivilegeValueA(LPCSTR lpSystemName,
1275 LPCSTR lpName,
1276 PLUID lpLuid)
1277 {
1278 UNICODE_STRING SystemName;
1279 UNICODE_STRING Name;
1280 BOOL Result;
1281
1282 /* Remote system? */
1283 if (lpSystemName != NULL)
1284 {
1285 RtlCreateUnicodeStringFromAsciiz(&SystemName,
1286 (LPSTR)lpSystemName);
1287 }
1288 else
1289 SystemName.Buffer = NULL;
1290
1291 /* Check the privilege name is not NULL */
1292 if (lpName == NULL)
1293 {
1294 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1295 return FALSE;
1296 }
1297
1298 RtlCreateUnicodeStringFromAsciiz(&Name,
1299 (LPSTR)lpName);
1300
1301 Result = LookupPrivilegeValueW(SystemName.Buffer,
1302 Name.Buffer,
1303 lpLuid);
1304
1305 RtlFreeUnicodeString(&Name);
1306
1307 /* Remote system? */
1308 if (SystemName.Buffer != NULL)
1309 {
1310 RtlFreeUnicodeString(&SystemName);
1311 }
1312
1313 return Result;
1314 }
1315
1316
1317 /**********************************************************************
1318 * LookupPrivilegeValueW
1319 *
1320 * @implemented
1321 */
1322 BOOL
1323 WINAPI
1324 LookupPrivilegeValueW(LPCWSTR lpSystemName,
1325 LPCWSTR lpPrivilegeName,
1326 PLUID lpLuid)
1327 {
1328 OBJECT_ATTRIBUTES ObjectAttributes = {0};
1329 UNICODE_STRING SystemName;
1330 UNICODE_STRING PrivilegeName;
1331 LSA_HANDLE PolicyHandle = NULL;
1332 NTSTATUS Status;
1333
1334 TRACE("%S,%S,%p\n", lpSystemName, lpPrivilegeName, lpLuid);
1335
1336 RtlInitUnicodeString(&SystemName,
1337 lpSystemName);
1338
1339 Status = LsaOpenPolicy(lpSystemName ? &SystemName : NULL,
1340 &ObjectAttributes,
1341 POLICY_LOOKUP_NAMES,
1342 &PolicyHandle);
1343 if (!NT_SUCCESS(Status))
1344 {
1345 SetLastError(LsaNtStatusToWinError(Status));
1346 return FALSE;
1347 }
1348
1349 RtlInitUnicodeString(&PrivilegeName,
1350 lpPrivilegeName);
1351
1352 Status = LsaLookupPrivilegeValue(PolicyHandle,
1353 &PrivilegeName,
1354 lpLuid);
1355
1356 LsaClose(PolicyHandle);
1357
1358 if (!NT_SUCCESS(Status))
1359 {
1360 SetLastError(LsaNtStatusToWinError(Status));
1361 return FALSE;
1362 }
1363
1364 return TRUE;
1365 }
1366
1367
1368 /**********************************************************************
1369 * LookupPrivilegeDisplayNameA EXPORTED
1370 *
1371 * @unimplemented
1372 */
1373 BOOL
1374 WINAPI
1375 LookupPrivilegeDisplayNameA(LPCSTR lpSystemName,
1376 LPCSTR lpName,
1377 LPSTR lpDisplayName,
1378 LPDWORD cbDisplayName,
1379 LPDWORD lpLanguageId)
1380 {
1381 FIXME("%s() not implemented!\n", __FUNCTION__);
1382 SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
1383 return FALSE;
1384 }
1385
1386
1387 /**********************************************************************
1388 * LookupPrivilegeDisplayNameW EXPORTED
1389 *
1390 * @unimplemented
1391 */
1392 BOOL
1393 WINAPI
1394 LookupPrivilegeDisplayNameW(LPCWSTR lpSystemName,
1395 LPCWSTR lpName,
1396 LPWSTR lpDisplayName,
1397 LPDWORD cbDisplayName,
1398 LPDWORD lpLanguageId)
1399 {
1400 FIXME("%s() not implemented!\n", __FUNCTION__);
1401 SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
1402 return FALSE;
1403 }
1404
1405
1406 /**********************************************************************
1407 * LookupPrivilegeNameA EXPORTED
1408 *
1409 * @implemented
1410 */
1411 BOOL
1412 WINAPI
1413 LookupPrivilegeNameA(LPCSTR lpSystemName,
1414 PLUID lpLuid,
1415 LPSTR lpName,
1416 LPDWORD cchName)
1417 {
1418 UNICODE_STRING lpSystemNameW;
1419 BOOL ret;
1420 DWORD wLen = 0;
1421
1422 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1423
1424 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1425 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1426 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1427 {
1428 LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1429
1430 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1431 &wLen);
1432 if (ret)
1433 {
1434 /* Windows crashes if cchName is NULL, so will I */
1435 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1436 *cchName, NULL, NULL);
1437
1438 if (len == 0)
1439 {
1440 /* WideCharToMultiByte failed */
1441 ret = FALSE;
1442 }
1443 else if (len > *cchName)
1444 {
1445 *cchName = len;
1446 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1447 ret = FALSE;
1448 }
1449 else
1450 {
1451 /* WideCharToMultiByte succeeded, output length needs to be
1452 * length not including NULL terminator
1453 */
1454 *cchName = len - 1;
1455 }
1456 }
1457 HeapFree(GetProcessHeap(), 0, lpNameW);
1458 }
1459 RtlFreeUnicodeString(&lpSystemNameW);
1460 return ret;
1461 }
1462
1463
1464 /**********************************************************************
1465 * LookupPrivilegeNameW EXPORTED
1466 *
1467 * @implemented
1468 */
1469 BOOL
1470 WINAPI
1471 LookupPrivilegeNameW(LPCWSTR lpSystemName,
1472 PLUID lpLuid,
1473 LPWSTR lpName,
1474 LPDWORD cchName)
1475 {
1476 OBJECT_ATTRIBUTES ObjectAttributes = {0};
1477 UNICODE_STRING SystemName;
1478 PUNICODE_STRING PrivilegeName = NULL;
1479 LSA_HANDLE PolicyHandle = NULL;
1480 NTSTATUS Status;
1481
1482 TRACE("%S,%p,%p,%p\n", lpSystemName, lpLuid, lpName, cchName);
1483
1484 RtlInitUnicodeString(&SystemName,
1485 lpSystemName);
1486
1487 Status = LsaOpenPolicy(lpSystemName ? &SystemName : NULL,
1488 &ObjectAttributes,
1489 POLICY_LOOKUP_NAMES,
1490 &PolicyHandle);
1491 if (!NT_SUCCESS(Status))
1492 {
1493 SetLastError(LsaNtStatusToWinError(Status));
1494 return FALSE;
1495 }
1496
1497 Status = LsaLookupPrivilegeName(PolicyHandle,
1498 lpLuid,
1499 &PrivilegeName);
1500 if (NT_SUCCESS(Status))
1501 {
1502 if (PrivilegeName->Length + sizeof(WCHAR) > (*cchName) * sizeof(WCHAR))
1503 {
1504 Status = STATUS_BUFFER_TOO_SMALL;
1505
1506 (*cchName) = (PrivilegeName->Length + sizeof(WCHAR)) / sizeof(WCHAR);
1507 }
1508 else
1509 {
1510 RtlMoveMemory(lpName,
1511 PrivilegeName->Buffer,
1512 PrivilegeName->Length);
1513 lpName[PrivilegeName->Length / sizeof(WCHAR)] = 0;
1514
1515 (*cchName) = PrivilegeName->Length / sizeof(WCHAR);
1516 }
1517
1518 LsaFreeMemory(PrivilegeName->Buffer);
1519 LsaFreeMemory(PrivilegeName);
1520 }
1521
1522 LsaClose(PolicyHandle);
1523
1524 if (!NT_SUCCESS(Status))
1525 {
1526 SetLastError(LsaNtStatusToWinError(Status));
1527 return FALSE;
1528 }
1529
1530 return TRUE;
1531 }
1532
1533
1534 static DWORD
1535 pGetSecurityInfoCheck(SECURITY_INFORMATION SecurityInfo,
1536 PSID *ppsidOwner,
1537 PSID *ppsidGroup,
1538 PACL *ppDacl,
1539 PACL *ppSacl,
1540 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
1541 {
1542 if ((SecurityInfo & (OWNER_SECURITY_INFORMATION |
1543 GROUP_SECURITY_INFORMATION |
1544 DACL_SECURITY_INFORMATION |
1545 SACL_SECURITY_INFORMATION)) &&
1546 ppSecurityDescriptor == NULL)
1547 {
1548 /* if one of the SIDs or ACLs are present, the security descriptor
1549 most not be NULL */
1550 return ERROR_INVALID_PARAMETER;
1551 }
1552 else
1553 {
1554 /* reset the pointers unless they're ignored */
1555 if ((SecurityInfo & OWNER_SECURITY_INFORMATION) &&
1556 ppsidOwner != NULL)
1557 {
1558 *ppsidOwner = NULL;
1559 }
1560 if ((SecurityInfo & GROUP_SECURITY_INFORMATION) &&
1561 ppsidGroup != NULL)
1562 {
1563 *ppsidGroup = NULL;
1564 }
1565 if ((SecurityInfo & DACL_SECURITY_INFORMATION) &&
1566 ppDacl != NULL)
1567 {
1568 *ppDacl = NULL;
1569 }
1570 if ((SecurityInfo & SACL_SECURITY_INFORMATION) &&
1571 ppSacl != NULL)
1572 {
1573 *ppSacl = NULL;
1574 }
1575
1576 if (SecurityInfo & (OWNER_SECURITY_INFORMATION |
1577 GROUP_SECURITY_INFORMATION |
1578 DACL_SECURITY_INFORMATION |
1579 SACL_SECURITY_INFORMATION))
1580 {
1581 *ppSecurityDescriptor = NULL;
1582 }
1583
1584 return ERROR_SUCCESS;
1585 }
1586 }
1587
1588
1589 static DWORD
1590 pSetSecurityInfoCheck(PSECURITY_DESCRIPTOR pSecurityDescriptor,
1591 SECURITY_INFORMATION SecurityInfo,
1592 PSID psidOwner,
1593 PSID psidGroup,
1594 PACL pDacl,
1595 PACL pSacl)
1596 {
1597 /* initialize a security descriptor on the stack */
1598 if (!InitializeSecurityDescriptor(pSecurityDescriptor,
1599 SECURITY_DESCRIPTOR_REVISION))
1600 {
1601 return GetLastError();
1602 }
1603
1604 if (SecurityInfo & OWNER_SECURITY_INFORMATION)
1605 {
1606 if (RtlValidSid(psidOwner))
1607 {
1608 if (!SetSecurityDescriptorOwner(pSecurityDescriptor,
1609 psidOwner,
1610 FALSE))
1611 {
1612 return GetLastError();
1613 }
1614 }
1615 else
1616 {
1617 return ERROR_INVALID_PARAMETER;
1618 }
1619 }
1620
1621 if (SecurityInfo & GROUP_SECURITY_INFORMATION)
1622 {
1623 if (RtlValidSid(psidGroup))
1624 {
1625 if (!SetSecurityDescriptorGroup(pSecurityDescriptor,
1626 psidGroup,
1627 FALSE))
1628 {
1629 return GetLastError();
1630 }
1631 }
1632 else
1633 {
1634 return ERROR_INVALID_PARAMETER;
1635 }
1636 }
1637
1638 if (SecurityInfo & DACL_SECURITY_INFORMATION)
1639 {
1640 if (pDacl != NULL)
1641 {
1642 if (SetSecurityDescriptorDacl(pSecurityDescriptor,
1643 TRUE,
1644 pDacl,
1645 FALSE))
1646 {
1647 /* check if the DACL needs to be protected from being
1648 modified by inheritable ACEs */
1649 if (SecurityInfo & PROTECTED_DACL_SECURITY_INFORMATION)
1650 {
1651 goto ProtectDacl;
1652 }
1653 }
1654 else
1655 {
1656 return GetLastError();
1657 }
1658 }
1659 else
1660 {
1661 ProtectDacl:
1662 /* protect the DACL from being modified by inheritable ACEs */
1663 if (!SetSecurityDescriptorControl(pSecurityDescriptor,
1664 SE_DACL_PROTECTED,
1665 SE_DACL_PROTECTED))
1666 {
1667 return GetLastError();
1668 }
1669 }
1670 }
1671
1672 if (SecurityInfo & SACL_SECURITY_INFORMATION)
1673 {
1674 if (pSacl != NULL)
1675 {
1676 if (SetSecurityDescriptorSacl(pSecurityDescriptor,
1677 TRUE,
1678 pSacl,
1679 FALSE))
1680 {
1681 /* check if the SACL needs to be protected from being
1682 modified by inheritable ACEs */
1683 if (SecurityInfo & PROTECTED_SACL_SECURITY_INFORMATION)
1684 {
1685 goto ProtectSacl;
1686 }
1687 }
1688 else
1689 {
1690 return GetLastError();
1691 }
1692 }
1693 else
1694 {
1695 ProtectSacl:
1696 /* protect the SACL from being modified by inheritable ACEs */
1697 if (!SetSecurityDescriptorControl(pSecurityDescriptor,
1698 SE_SACL_PROTECTED,
1699 SE_SACL_PROTECTED))
1700 {
1701 return GetLastError();
1702 }
1703 }
1704 }
1705
1706 return ERROR_SUCCESS;
1707 }
1708
1709
1710 /**********************************************************************
1711 * GetNamedSecurityInfoW EXPORTED
1712 *
1713 * @implemented
1714 */
1715 DWORD
1716 WINAPI
1717 GetNamedSecurityInfoW(LPWSTR pObjectName,
1718 SE_OBJECT_TYPE ObjectType,
1719 SECURITY_INFORMATION SecurityInfo,
1720 PSID *ppsidOwner,
1721 PSID *ppsidGroup,
1722 PACL *ppDacl,
1723 PACL *ppSacl,
1724 PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
1725 {
1726 DWORD ErrorCode;
1727
1728 if (pObjectName != NULL)
1729 {
1730 ErrorCode = CheckNtMartaPresent();
1731 if (ErrorCode == ERROR_SUCCESS)
1732 {
1733 ErrorCode = pGetSecurityInfoCheck(SecurityInfo,
1734 ppsidOwner,
1735 ppsidGroup,
1736 ppDacl,
1737 ppSacl,
1738 ppSecurityDescriptor);
1739
1740 if (ErrorCode == ERROR_SUCCESS)
1741 {
1742 /* call the MARTA provider */
1743 ErrorCode = AccRewriteGetNamedRights(pObjectName,
1744 ObjectType,
1745 SecurityInfo,
1746 ppsidOwner,
1747 ppsidGroup,
1748 ppDacl,
1749 ppSacl,
1750 ppSecurityDescriptor);
1751 }
1752 }
1753 }
1754 else
1755 ErrorCode = ERROR_INVALID_PARAMETER;
1756
1757 return ErrorCode;
1758 }
1759
1760
1761 /**********************************************************************
1762 * GetNamedSecurityInfoA EXPORTED
1763 *
1764 * @implemented
1765 */
1766 DWORD
1767 WINAPI
1768 GetNamedSecurityInfoA(LPSTR pObjectName,
1769 SE_OBJECT_TYPE ObjectType,
1770 SECURITY_INFORMATION SecurityInfo,
1771 PSID *ppsidOwner,
1772 PSID *ppsidGroup,
1773 PACL *ppDacl,
1774 PACL *ppSacl,
1775 PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
1776 {
1777 DWORD len;
1778 LPWSTR wstr = NULL;
1779 DWORD r;
1780
1781 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
1782 ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
1783
1784 if( pObjectName )
1785 {
1786 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
1787 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
1788 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
1789 }
1790
1791 r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
1792 ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
1793
1794 HeapFree( GetProcessHeap(), 0, wstr );
1795
1796 return r;
1797 }
1798
1799
1800 /**********************************************************************
1801 * SetNamedSecurityInfoW EXPORTED
1802 *
1803 * @implemented
1804 */
1805 DWORD
1806 WINAPI
1807 SetNamedSecurityInfoW(LPWSTR pObjectName,
1808 SE_OBJECT_TYPE ObjectType,
1809 SECURITY_INFORMATION SecurityInfo,
1810 PSID psidOwner,
1811 PSID psidGroup,
1812 PACL pDacl,
1813 PACL pSacl)
1814 {
1815 DWORD ErrorCode;
1816
1817 if (pObjectName != NULL)
1818 {
1819 ErrorCode = CheckNtMartaPresent();
1820 if (ErrorCode == ERROR_SUCCESS)
1821 {
1822 SECURITY_DESCRIPTOR SecurityDescriptor;
1823
1824 ErrorCode = pSetSecurityInfoCheck(&SecurityDescriptor,
1825 SecurityInfo,
1826 psidOwner,
1827 psidGroup,
1828 pDacl,
1829 pSacl);
1830
1831 if (ErrorCode == ERROR_SUCCESS)
1832 {
1833 /* call the MARTA provider */
1834 ErrorCode = AccRewriteSetNamedRights(pObjectName,
1835 ObjectType,
1836 SecurityInfo,
1837 &SecurityDescriptor);
1838 }
1839 }
1840 }
1841 else
1842 ErrorCode = ERROR_INVALID_PARAMETER;
1843
1844 return ErrorCode;
1845 }
1846
1847
1848 /**********************************************************************
1849 * SetNamedSecurityInfoA EXPORTED
1850 *
1851 * @implemented
1852 */
1853 DWORD
1854 WINAPI
1855 SetNamedSecurityInfoA(LPSTR pObjectName,
1856 SE_OBJECT_TYPE ObjectType,
1857 SECURITY_INFORMATION SecurityInfo,
1858 PSID psidOwner,
1859 PSID psidGroup,
1860 PACL pDacl,
1861 PACL pSacl)
1862 {
1863 UNICODE_STRING ObjectName;
1864 NTSTATUS Status;
1865 DWORD Ret;
1866
1867 Status = RtlCreateUnicodeStringFromAsciiz(&ObjectName,
1868 pObjectName);
1869 if (!NT_SUCCESS(Status))
1870 {
1871 return RtlNtStatusToDosError(Status);
1872 }
1873
1874 Ret = SetNamedSecurityInfoW(ObjectName.Buffer,
1875 ObjectType,
1876 SecurityInfo,
1877 psidOwner,
1878 psidGroup,
1879 pDacl,
1880 pSacl);
1881
1882 RtlFreeUnicodeString(&ObjectName);
1883
1884 return Ret;
1885 }
1886
1887
1888 /**********************************************************************
1889 * GetSecurityInfo EXPORTED
1890 *
1891 * @implemented
1892 */
1893 DWORD
1894 WINAPI
1895 GetSecurityInfo(HANDLE handle,
1896 SE_OBJECT_TYPE ObjectType,
1897 SECURITY_INFORMATION SecurityInfo,
1898 PSID *ppsidOwner,
1899 PSID *ppsidGroup,
1900 PACL *ppDacl,
1901 PACL *ppSacl,
1902 PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
1903 {
1904 DWORD ErrorCode;
1905
1906 if (handle != NULL)
1907 {
1908 ErrorCode = CheckNtMartaPresent();
1909 if (ErrorCode == ERROR_SUCCESS)
1910 {
1911 ErrorCode = pGetSecurityInfoCheck(SecurityInfo,
1912 ppsidOwner,
1913 ppsidGroup,
1914 ppDacl,
1915 ppSacl,
1916 ppSecurityDescriptor);
1917
1918 if (ErrorCode == ERROR_SUCCESS)
1919 {
1920 /* call the MARTA provider */
1921 ErrorCode = AccRewriteGetHandleRights(handle,
1922 ObjectType,
1923 SecurityInfo,
1924 ppsidOwner,
1925 ppsidGroup,
1926 ppDacl,
1927 ppSacl,
1928 ppSecurityDescriptor);
1929 }
1930 }
1931 }
1932 else
1933 ErrorCode = ERROR_INVALID_HANDLE;
1934
1935 return ErrorCode;
1936 }
1937
1938
1939 /**********************************************************************
1940 * SetSecurityInfo EXPORTED
1941 *
1942 * @implemented
1943 */
1944 DWORD
1945 WINAPI
1946 SetSecurityInfo(HANDLE handle,
1947 SE_OBJECT_TYPE ObjectType,
1948 SECURITY_INFORMATION SecurityInfo,
1949 PSID psidOwner,
1950 PSID psidGroup,
1951 PACL pDacl,
1952 PACL pSacl)
1953 {
1954 DWORD ErrorCode;
1955
1956 if (handle != NULL)
1957 {
1958 ErrorCode = CheckNtMartaPresent();
1959 if (ErrorCode == ERROR_SUCCESS)
1960 {
1961 SECURITY_DESCRIPTOR SecurityDescriptor;
1962
1963 ErrorCode = pSetSecurityInfoCheck(&SecurityDescriptor,
1964 SecurityInfo,
1965 psidOwner,
1966 psidGroup,
1967 pDacl,
1968 pSacl);
1969
1970 if (ErrorCode == ERROR_SUCCESS)
1971 {
1972 /* call the MARTA provider */
1973 ErrorCode = AccRewriteSetHandleRights(handle,
1974 ObjectType,
1975 SecurityInfo,
1976 &SecurityDescriptor);
1977 }
1978 }
1979 }
1980 else
1981 ErrorCode = ERROR_INVALID_HANDLE;
1982
1983 return ErrorCode;
1984 }
1985
1986
1987 /******************************************************************************
1988 * GetSecurityInfoExW EXPORTED
1989 */
1990 DWORD
1991 WINAPI
1992 GetSecurityInfoExA(HANDLE hObject,
1993 SE_OBJECT_TYPE ObjectType,
1994 SECURITY_INFORMATION SecurityInfo,
1995 LPCSTR lpProvider,
1996 LPCSTR lpProperty,
1997 PACTRL_ACCESSA *ppAccessList,
1998 PACTRL_AUDITA *ppAuditList,
1999 LPSTR *lppOwner,
2000 LPSTR *lppGroup)
2001 {
2002 FIXME("%s() not implemented!\n", __FUNCTION__);
2003 return ERROR_BAD_PROVIDER;
2004 }
2005
2006
2007 /******************************************************************************
2008 * GetSecurityInfoExW EXPORTED
2009 */
2010 DWORD
2011 WINAPI
2012 GetSecurityInfoExW(HANDLE hObject,
2013 SE_OBJECT_TYPE ObjectType,
2014 SECURITY_INFORMATION SecurityInfo,
2015 LPCWSTR lpProvider,
2016 LPCWSTR lpProperty,
2017 PACTRL_ACCESSW *ppAccessList,
2018 PACTRL_AUDITW *ppAuditList,
2019 LPWSTR *lppOwner,
2020 LPWSTR *lppGroup)
2021 {
2022 FIXME("%s() not implemented!\n", __FUNCTION__);
2023 return ERROR_BAD_PROVIDER;
2024 }
2025
2026
2027 /**********************************************************************
2028 * ImpersonateNamedPipeClient EXPORTED
2029 *
2030 * @implemented
2031 */
2032 BOOL
2033 WINAPI
2034 ImpersonateNamedPipeClient(HANDLE hNamedPipe)
2035 {
2036 IO_STATUS_BLOCK StatusBlock;
2037 NTSTATUS Status;
2038
2039 TRACE("ImpersonateNamedPipeClient() called\n");
2040
2041 Status = NtFsControlFile(hNamedPipe,
2042 NULL,
2043 NULL,
2044 NULL,
2045 &StatusBlock,
2046 FSCTL_PIPE_IMPERSONATE,
2047 NULL,
2048 0,
2049 NULL,
2050 0);
2051 if (!NT_SUCCESS(Status))
2052 {
2053 SetLastError(RtlNtStatusToDosError(Status));
2054 return FALSE;
2055 }
2056
2057 return TRUE;
2058 }
2059
2060
2061 /*
2062 * @implemented
2063 */
2064 BOOL
2065 WINAPI
2066 CreatePrivateObjectSecurity(PSECURITY_DESCRIPTOR ParentDescriptor,
2067 PSECURITY_DESCRIPTOR CreatorDescriptor,
2068 PSECURITY_DESCRIPTOR *NewDescriptor,
2069 BOOL IsDirectoryObject,
2070 HANDLE Token,
2071 PGENERIC_MAPPING GenericMapping)
2072 {
2073 NTSTATUS Status;
2074
2075 Status = RtlNewSecurityObject(ParentDescriptor,
2076 CreatorDescriptor,
2077 NewDescriptor,
2078 IsDirectoryObject,
2079 Token,
2080 GenericMapping);
2081 if (!NT_SUCCESS(Status))
2082 {
2083 SetLastError(RtlNtStatusToDosError(Status));
2084 return FALSE;
2085 }
2086
2087 return TRUE;
2088 }
2089
2090
2091 /*
2092 * @unimplemented
2093 */
2094 BOOL
2095 WINAPI
2096 CreatePrivateObjectSecurityEx(PSECURITY_DESCRIPTOR ParentDescriptor,
2097 PSECURITY_DESCRIPTOR CreatorDescriptor,
2098 PSECURITY_DESCRIPTOR* NewDescriptor,
2099 GUID* ObjectType,
2100 BOOL IsContainerObject,
2101 ULONG AutoInheritFlags,
2102 HANDLE Token,
2103 PGENERIC_MAPPING GenericMapping)
2104 {
2105 FIXME("%s() not implemented!\n", __FUNCTION__);
2106 return FALSE;
2107 }
2108
2109
2110 /*
2111 * @unimplemented
2112 */
2113 BOOL
2114 WINAPI
2115 CreatePrivateObjectSecurityWithMultipleInheritance(PSECURITY_DESCRIPTOR ParentDescriptor,
2116 PSECURITY_DESCRIPTOR CreatorDescriptor,
2117 PSECURITY_DESCRIPTOR* NewDescriptor,
2118 GUID** ObjectTypes,
2119 ULONG GuidCount,
2120 BOOL IsContainerObject,
2121 ULONG AutoInheritFlags,
2122 HANDLE Token,
2123 PGENERIC_MAPPING GenericMapping)
2124 {
2125 FIXME("%s() not implemented!\n", __FUNCTION__);
2126 return FALSE;
2127 }
2128
2129
2130 /*
2131 * @implemented
2132 */
2133 BOOL
2134 WINAPI
2135 DestroyPrivateObjectSecurity(PSECURITY_DESCRIPTOR *ObjectDescriptor)
2136 {
2137 NTSTATUS Status;
2138
2139 Status = RtlDeleteSecurityObject(ObjectDescriptor);
2140 if (!NT_SUCCESS(Status))
2141 {
2142 SetLastError(RtlNtStatusToDosError(Status));
2143 return FALSE;
2144 }
2145
2146 return TRUE;
2147 }
2148
2149
2150 /*
2151 * @implemented
2152 */
2153 BOOL
2154 WINAPI
2155 GetPrivateObjectSecurity(IN PSECURITY_DESCRIPTOR ObjectDescriptor,
2156 IN SECURITY_INFORMATION SecurityInformation,
2157 OUT PSECURITY_DESCRIPTOR ResultantDescriptor OPTIONAL,
2158 IN DWORD DescriptorLength,
2159 OUT PDWORD ReturnLength)
2160 {
2161 NTSTATUS Status;
2162
2163 /* Call RTL */
2164 Status = RtlQuerySecurityObject(ObjectDescriptor,
2165 SecurityInformation,
2166 ResultantDescriptor,
2167 DescriptorLength,
2168 ReturnLength);
2169 if (!NT_SUCCESS(Status))
2170 {
2171 /* Fail */
2172 SetLastError(RtlNtStatusToDosError(Status));
2173 return FALSE;
2174 }
2175
2176 /* Success */
2177 return TRUE;
2178 }
2179
2180
2181 /*
2182 * @implemented
2183 */
2184 BOOL
2185 WINAPI
2186 SetPrivateObjectSecurity(SECURITY_INFORMATION SecurityInformation,
2187 PSECURITY_DESCRIPTOR ModificationDescriptor,
2188 PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
2189 PGENERIC_MAPPING GenericMapping,
2190 HANDLE Token)
2191 {
2192 NTSTATUS Status;
2193
2194 Status = RtlSetSecurityObject(SecurityInformation,
2195 ModificationDescriptor,
2196 ObjectsSecurityDescriptor,
2197 GenericMapping,
2198 Token);
2199 if (!NT_SUCCESS(Status))
2200 {
2201 SetLastError(RtlNtStatusToDosError(Status));
2202 return FALSE;
2203 }
2204
2205 return TRUE;
2206 }
2207
2208
2209 /*
2210 * @implemented
2211 */
2212 DWORD
2213 WINAPI
2214 TreeResetNamedSecurityInfoW(LPWSTR pObjectName,
2215 SE_OBJECT_TYPE ObjectType,
2216 SECURITY_INFORMATION SecurityInfo,
2217 PSID pOwner,
2218 PSID pGroup,
2219 PACL pDacl,
2220 PACL pSacl,
2221 BOOL KeepExplicit,
2222 FN_PROGRESSW fnProgress,
2223 PROG_INVOKE_SETTING ProgressInvokeSetting,
2224 PVOID Args)
2225 {
2226 DWORD ErrorCode;
2227
2228 if (pObjectName != NULL)
2229 {
2230 ErrorCode = CheckNtMartaPresent();
2231 if (ErrorCode == ERROR_SUCCESS)
2232 {
2233 switch (ObjectType)
2234 {
2235 case SE_FILE_OBJECT:
2236 case SE_REGISTRY_KEY:
2237 {
2238 /* check the SecurityInfo flags for sanity (both, the protected
2239 and unprotected dacl/sacl flag must not be passed together) */
2240 if (((SecurityInfo & DACL_SECURITY_INFORMATION) &&
2241 (SecurityInfo & (PROTECTED_DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION)) ==
2242 (PROTECTED_DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION))
2243
2244 ||
2245
2246 ((SecurityInfo & SACL_SECURITY_INFORMATION) &&
2247 (SecurityInfo & (PROTECTED_SACL_SECURITY_INFORMATION | UNPROTECTED_SACL_SECURITY_INFORMATION)) ==
2248 (PROTECTED_SACL_SECURITY_INFORMATION | UNPROTECTED_SACL_SECURITY_INFORMATION)))
2249 {
2250 ErrorCode = ERROR_INVALID_PARAMETER;
2251 break;
2252 }
2253
2254 /* call the MARTA provider */
2255 ErrorCode = AccTreeResetNamedSecurityInfo(pObjectName,
2256 ObjectType,
2257 SecurityInfo,
2258 pOwner,
2259 pGroup,
2260 pDacl,
2261 pSacl,
2262 KeepExplicit,
2263 fnProgress,
2264 ProgressInvokeSetting,
2265 Args);
2266 break;
2267 }
2268
2269 default:
2270 /* object type not supported */
2271 ErrorCode = ERROR_INVALID_PARAMETER;
2272 break;
2273 }
2274 }
2275 }
2276 else
2277 ErrorCode = ERROR_INVALID_PARAMETER;
2278
2279 return ErrorCode;
2280 }
2281
2282 #ifdef HAS_FN_PROGRESSW
2283
2284 typedef struct _INERNAL_FNPROGRESSW_DATA
2285 {
2286 FN_PROGRESSA fnProgress;
2287 PVOID Args;
2288 } INERNAL_FNPROGRESSW_DATA, *PINERNAL_FNPROGRESSW_DATA;
2289
2290 static VOID WINAPI
2291 InternalfnProgressW(LPWSTR pObjectName,
2292 DWORD Status,
2293 PPROG_INVOKE_SETTING pInvokeSetting,
2294 PVOID Args,
2295 BOOL SecuritySet)
2296 {
2297 PINERNAL_FNPROGRESSW_DATA pifnProgressData = (PINERNAL_FNPROGRESSW_DATA)Args;
2298 INT ObjectNameSize;
2299 LPSTR pObjectNameA;
2300
2301 ObjectNameSize = WideCharToMultiByte(CP_ACP,
2302 0,
2303 pObjectName,
2304 -1,
2305 NULL,
2306 0,
2307 NULL,
2308 NULL);
2309
2310 if (ObjectNameSize > 0)
2311 {
2312 pObjectNameA = RtlAllocateHeap(RtlGetProcessHeap(),
2313 0,
2314 ObjectNameSize);
2315 if (pObjectNameA != NULL)
2316 {
2317 pObjectNameA[0] = '\0';
2318 WideCharToMultiByte(CP_ACP,
2319 0,
2320 pObjectName,
2321 -1,
2322 pObjectNameA,
2323 ObjectNameSize,
2324 NULL,
2325 NULL);
2326
2327 pifnProgressData->fnProgress((LPWSTR)pObjectNameA, /* FIXME: wrong cast!! */
2328 Status,
2329 pInvokeSetting,
2330 pifnProgressData->Args,
2331 SecuritySet);
2332
2333 RtlFreeHeap(RtlGetProcessHeap(),
2334 0,
2335 pObjectNameA);
2336 }
2337 }
2338 }
2339 #endif
2340
2341
2342 /*
2343 * @implemented
2344 */
2345 DWORD
2346 WINAPI
2347 TreeResetNamedSecurityInfoA(LPSTR pObjectName,
2348 SE_OBJECT_TYPE ObjectType,
2349 SECURITY_INFORMATION SecurityInfo,
2350 PSID pOwner,
2351 PSID pGroup,
2352 PACL pDacl,
2353 PACL pSacl,
2354 BOOL KeepExplicit,
2355 FN_PROGRESSA fnProgress,
2356 PROG_INVOKE_SETTING ProgressInvokeSetting,
2357 PVOID Args)
2358 {
2359 #ifndef HAS_FN_PROGRESSW
2360 /* That's all this function does, at least up to w2k3... Even MS was too
2361 lazy to implement it... */
2362 return ERROR_CALL_NOT_IMPLEMENTED;
2363 #else
2364 INERNAL_FNPROGRESSW_DATA ifnProgressData;
2365 UNICODE_STRING ObjectName;
2366 NTSTATUS Status;
2367 DWORD Ret;
2368
2369 Status = RtlCreateUnicodeStringFromAsciiz(&ObjectName,
2370 pObjectName);
2371 if (!NT_SUCCESS(Status))
2372 {
2373 return RtlNtStatusToDosError(Status);
2374 }
2375
2376 ifnProgressData.fnProgress = fnProgress;
2377 ifnProgressData.Args = Args;
2378
2379 Ret = TreeResetNamedSecurityInfoW(ObjectName.Buffer,
2380 ObjectType,
2381 SecurityInfo,
2382 pOwner,
2383 pGroup,
2384 pDacl,
2385 pSacl,
2386 KeepExplicit,
2387 (fnProgress != NULL ? InternalfnProgressW : NULL),
2388 ProgressInvokeSetting,
2389 &ifnProgressData);
2390
2391 RtlFreeUnicodeString(&ObjectName);
2392
2393 return Ret;
2394 #endif
2395 }
2396
2397 /******************************************************************************
2398 * SaferCreateLevel [ADVAPI32.@]
2399 */
2400 BOOL WINAPI SaferCreateLevel(DWORD ScopeId, DWORD LevelId, DWORD OpenFlags,
2401 SAFER_LEVEL_HANDLE* LevelHandle, LPVOID lpReserved)
2402 {
2403 FIXME("(%u, %x, %u, %p, %p) stub\n", ScopeId, LevelId, OpenFlags, LevelHandle, lpReserved);
2404 return FALSE;
2405 }
2406
2407 /******************************************************************************
2408 * SaferGetPolicyInformation [ADVAPI32.@]
2409 */
2410 BOOL WINAPI SaferGetPolicyInformation(DWORD scope, SAFER_POLICY_INFO_CLASS class, DWORD size,
2411 PVOID buffer, PDWORD required, LPVOID lpReserved)
2412 {
2413 FIXME("(%u %u %u %p %p %p) stub\n", scope, class, size, buffer, required, lpReserved);
2414 return FALSE;
2415 }
2416
2417 /******************************************************************************
2418 * QueryWindows31FilesMigration [ADVAPI32.@]
2419 *
2420 * PARAMS
2421 * x1 []
2422 */
2423 BOOL WINAPI
2424 QueryWindows31FilesMigration( DWORD x1 )
2425 {
2426 FIXME("(%d):stub\n",x1);
2427 return TRUE;
2428 }
2429
2430 /******************************************************************************
2431 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2432 *
2433 * PARAMS
2434 * x1 []
2435 * x2 []
2436 * x3 []
2437 * x4 []
2438 */
2439 BOOL WINAPI
2440 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2441 DWORD x4 )
2442 {
2443 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2444 return TRUE;
2445 }
2446
2447 /* EOF */