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