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