xref: /reactos/dll/win32/advapi32/sec/misc.c (revision 03422451)
1c2c66affSColin Finck /*
2c2c66affSColin Finck  * COPYRIGHT:       See COPYING in the top level directory
3c2c66affSColin Finck  * WINE COPYRIGHT:
4c2c66affSColin Finck  * Copyright 1999, 2000 Juergen Schmied <juergen.schmied@debitel.net>
5c2c66affSColin Finck  * Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
6c2c66affSColin Finck  * Copyright 2006 Robert Reif
7c2c66affSColin Finck  *
8c2c66affSColin Finck  * PROJECT:         ReactOS system libraries
9c2c66affSColin Finck  * FILE:            dll/win32/advapi32/sec/misc.c
10c2c66affSColin Finck  * PURPOSE:         Miscellaneous security functions (some ported from Wine)
11c2c66affSColin Finck  */
12c2c66affSColin Finck 
13c2c66affSColin Finck #include <advapi32.h>
14c2c66affSColin Finck 
15c2c66affSColin Finck WINE_DEFAULT_DEBUG_CHANNEL(advapi);
16c2c66affSColin Finck 
17c2c66affSColin Finck /* Interface to ntmarta.dll ***************************************************/
18c2c66affSColin Finck 
19c2c66affSColin Finck NTMARTA NtMartaStatic = { 0 };
20c2c66affSColin Finck static PNTMARTA NtMarta = NULL;
21c2c66affSColin Finck 
22c2c66affSColin Finck #define FindNtMartaProc(Name)                                                  \
23c2c66affSColin Finck     NtMartaStatic.Name = (PVOID)GetProcAddress(NtMartaStatic.hDllInstance,     \
24c2c66affSColin Finck                                                "Acc" # Name );                 \
25c2c66affSColin Finck     if (NtMartaStatic.Name == NULL)                                            \
26c2c66affSColin Finck     {                                                                          \
27c2c66affSColin Finck         return GetLastError();                                                 \
28c2c66affSColin Finck     }
29c2c66affSColin Finck 
30c2c66affSColin Finck 
31c2c66affSColin Finck static DWORD
LoadAndInitializeNtMarta(VOID)32c2c66affSColin Finck LoadAndInitializeNtMarta(VOID)
33c2c66affSColin Finck {
34c2c66affSColin Finck     /* this code may be executed simultaneously by multiple threads in case they're
35c2c66affSColin Finck        trying to initialize the interface at the same time, but that's no problem
36c2c66affSColin Finck        because the pointers returned by GetProcAddress will be the same. However,
37c2c66affSColin Finck        only one of the threads will change the NtMarta pointer to the NtMartaStatic
38c2c66affSColin Finck        structure, the others threads will detect that there were other threads
39c2c66affSColin Finck        initializing the structure faster and will release the reference to the
40c2c66affSColin Finck        DLL */
41c2c66affSColin Finck 
42c2c66affSColin Finck     NtMartaStatic.hDllInstance = LoadLibraryW(L"ntmarta.dll");
43c2c66affSColin Finck     if (NtMartaStatic.hDllInstance == NULL)
44c2c66affSColin Finck     {
45c2c66affSColin Finck         return GetLastError();
46c2c66affSColin Finck     }
47c2c66affSColin Finck 
48c2c66affSColin Finck #if 0
49c2c66affSColin Finck     FindNtMartaProc(LookupAccountTrustee);
50c2c66affSColin Finck     FindNtMartaProc(LookupAccountName);
51c2c66affSColin Finck     FindNtMartaProc(LookupAccountSid);
52c2c66affSColin Finck     FindNtMartaProc(SetEntriesInAList);
53c2c66affSColin Finck     FindNtMartaProc(ConvertAccessToSecurityDescriptor);
54c2c66affSColin Finck     FindNtMartaProc(ConvertSDToAccess);
55c2c66affSColin Finck     FindNtMartaProc(ConvertAclToAccess);
56c2c66affSColin Finck     FindNtMartaProc(GetAccessForTrustee);
57c2c66affSColin Finck     FindNtMartaProc(GetExplicitEntries);
58c2c66affSColin Finck #endif
59c2c66affSColin Finck     FindNtMartaProc(RewriteGetNamedRights);
60c2c66affSColin Finck     FindNtMartaProc(RewriteSetNamedRights);
61c2c66affSColin Finck     FindNtMartaProc(RewriteGetHandleRights);
62c2c66affSColin Finck     FindNtMartaProc(RewriteSetHandleRights);
63c2c66affSColin Finck     FindNtMartaProc(RewriteSetEntriesInAcl);
64c2c66affSColin Finck     FindNtMartaProc(RewriteGetExplicitEntriesFromAcl);
65c2c66affSColin Finck     FindNtMartaProc(TreeResetNamedSecurityInfo);
66c2c66affSColin Finck     FindNtMartaProc(GetInheritanceSource);
67c2c66affSColin Finck     FindNtMartaProc(FreeIndexArray);
68c2c66affSColin Finck 
69c2c66affSColin Finck     return ERROR_SUCCESS;
70c2c66affSColin Finck }
71c2c66affSColin Finck 
72c2c66affSColin Finck 
73c2c66affSColin Finck DWORD
CheckNtMartaPresent(VOID)74c2c66affSColin Finck CheckNtMartaPresent(VOID)
75c2c66affSColin Finck {
76c2c66affSColin Finck     DWORD ErrorCode;
77c2c66affSColin Finck 
78c2c66affSColin Finck     if (InterlockedCompareExchangePointer((PVOID)&NtMarta,
79c2c66affSColin Finck                                           NULL,
80c2c66affSColin Finck                                           NULL) == NULL)
81c2c66affSColin Finck     {
82c2c66affSColin Finck         /* we're the first one trying to use ntmarta, initialize it and change
83c2c66affSColin Finck            the pointer after initialization */
84c2c66affSColin Finck         ErrorCode = LoadAndInitializeNtMarta();
85c2c66affSColin Finck 
86c2c66affSColin Finck         if (ErrorCode == ERROR_SUCCESS)
87c2c66affSColin Finck         {
88c2c66affSColin Finck             /* try change the NtMarta pointer */
89c2c66affSColin Finck             if (InterlockedCompareExchangePointer((PVOID)&NtMarta,
90c2c66affSColin Finck                                                   &NtMartaStatic,
91c2c66affSColin Finck                                                   NULL) != NULL)
92c2c66affSColin Finck             {
93c2c66affSColin Finck                 /* another thread initialized ntmarta in the meanwhile, release
94c2c66affSColin Finck                    the reference of the dll loaded. */
95c2c66affSColin Finck                 FreeLibrary(NtMartaStatic.hDllInstance);
96c2c66affSColin Finck             }
97c2c66affSColin Finck         }
98c2c66affSColin Finck #if DBG
99c2c66affSColin Finck         else
100c2c66affSColin Finck         {
101*03422451SSerge Gautherie             ERR("Failed to initialize ntmarta.dll! Error: 0x%x\n", ErrorCode);
102c2c66affSColin Finck         }
103c2c66affSColin Finck #endif
104c2c66affSColin Finck     }
105c2c66affSColin Finck     else
106c2c66affSColin Finck     {
107c2c66affSColin Finck         /* ntmarta was already initialized */
108c2c66affSColin Finck         ErrorCode = ERROR_SUCCESS;
109c2c66affSColin Finck     }
110c2c66affSColin Finck 
111c2c66affSColin Finck     return ErrorCode;
112c2c66affSColin Finck }
113c2c66affSColin Finck 
114c2c66affSColin Finck 
115c2c66affSColin Finck VOID
UnloadNtMarta(VOID)116c2c66affSColin Finck UnloadNtMarta(VOID)
117c2c66affSColin Finck {
118c2c66affSColin Finck     if (InterlockedExchangePointer((PVOID)&NtMarta,
119c2c66affSColin Finck                                    NULL) != NULL)
120c2c66affSColin Finck     {
121c2c66affSColin Finck         FreeLibrary(NtMartaStatic.hDllInstance);
122c2c66affSColin Finck     }
123c2c66affSColin Finck }
124c2c66affSColin Finck 
125c2c66affSColin Finck 
126c2c66affSColin Finck /******************************************************************************/
127c2c66affSColin Finck 
128c2c66affSColin Finck /*
129c2c66affSColin Finck  * @implemented
130c2c66affSColin Finck  */
131c2c66affSColin Finck BOOL
132c2c66affSColin Finck WINAPI
ImpersonateAnonymousToken(IN HANDLE ThreadHandle)133c2c66affSColin Finck ImpersonateAnonymousToken(IN HANDLE ThreadHandle)
134c2c66affSColin Finck {
135c2c66affSColin Finck     NTSTATUS Status;
136c2c66affSColin Finck 
137c2c66affSColin Finck     Status = NtImpersonateAnonymousToken(ThreadHandle);
138c2c66affSColin Finck     if (!NT_SUCCESS(Status))
139c2c66affSColin Finck     {
140c2c66affSColin Finck         SetLastError(RtlNtStatusToDosError(Status));
141c2c66affSColin Finck         return FALSE;
142c2c66affSColin Finck     }
143c2c66affSColin Finck 
144c2c66affSColin Finck     return TRUE;
145c2c66affSColin Finck }
146c2c66affSColin Finck 
147c2c66affSColin Finck /*
148c2c66affSColin Finck  * @implemented
149c2c66affSColin Finck  */
150c2c66affSColin Finck BOOL
151c2c66affSColin Finck WINAPI
ImpersonateLoggedOnUser(HANDLE hToken)152c2c66affSColin Finck ImpersonateLoggedOnUser(HANDLE hToken)
153c2c66affSColin Finck {
154c2c66affSColin Finck     SECURITY_QUALITY_OF_SERVICE Qos;
155c2c66affSColin Finck     OBJECT_ATTRIBUTES ObjectAttributes;
156c2c66affSColin Finck     HANDLE NewToken;
157c2c66affSColin Finck     TOKEN_TYPE Type;
158c2c66affSColin Finck     ULONG ReturnLength;
159c2c66affSColin Finck     BOOL Duplicated;
160c2c66affSColin Finck     NTSTATUS Status;
161c2c66affSColin Finck 
162c2c66affSColin Finck     /* Get the token type */
163c2c66affSColin Finck     Status = NtQueryInformationToken(hToken,
164c2c66affSColin Finck                                      TokenType,
165c2c66affSColin Finck                                      &Type,
166c2c66affSColin Finck                                      sizeof(TOKEN_TYPE),
167c2c66affSColin Finck                                      &ReturnLength);
168c2c66affSColin Finck     if (!NT_SUCCESS(Status))
169c2c66affSColin Finck     {
170c2c66affSColin Finck         SetLastError(RtlNtStatusToDosError(Status));
171c2c66affSColin Finck         return FALSE;
172c2c66affSColin Finck     }
173c2c66affSColin Finck 
174c2c66affSColin Finck     if (Type == TokenPrimary)
175c2c66affSColin Finck     {
176c2c66affSColin Finck         /* Create a duplicate impersonation token */
177c2c66affSColin Finck         Qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
178c2c66affSColin Finck         Qos.ImpersonationLevel = SecurityImpersonation;
179c2c66affSColin Finck         Qos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
180c2c66affSColin Finck         Qos.EffectiveOnly = FALSE;
181c2c66affSColin Finck 
182c2c66affSColin Finck         ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
183c2c66affSColin Finck         ObjectAttributes.RootDirectory = NULL;
184c2c66affSColin Finck         ObjectAttributes.ObjectName = NULL;
185c2c66affSColin Finck         ObjectAttributes.Attributes = 0;
186c2c66affSColin Finck         ObjectAttributes.SecurityDescriptor = NULL;
187c2c66affSColin Finck         ObjectAttributes.SecurityQualityOfService = &Qos;
188c2c66affSColin Finck 
189c2c66affSColin Finck         Status = NtDuplicateToken(hToken,
190c2c66affSColin Finck                                   TOKEN_IMPERSONATE | TOKEN_QUERY,
191c2c66affSColin Finck                                   &ObjectAttributes,
192c2c66affSColin Finck                                   FALSE,
193c2c66affSColin Finck                                   TokenImpersonation,
194c2c66affSColin Finck                                   &NewToken);
195c2c66affSColin Finck         if (!NT_SUCCESS(Status))
196c2c66affSColin Finck         {
197c2c66affSColin Finck             ERR("NtDuplicateToken failed: Status %08x\n", Status);
198c2c66affSColin Finck             SetLastError(RtlNtStatusToDosError(Status));
199c2c66affSColin Finck             return FALSE;
200c2c66affSColin Finck         }
201c2c66affSColin Finck 
202c2c66affSColin Finck         Duplicated = TRUE;
203c2c66affSColin Finck     }
204c2c66affSColin Finck     else
205c2c66affSColin Finck     {
206c2c66affSColin Finck         /* User the original impersonation token */
207c2c66affSColin Finck         NewToken = hToken;
208c2c66affSColin Finck         Duplicated = FALSE;
209c2c66affSColin Finck     }
210c2c66affSColin Finck 
211c2c66affSColin Finck     /* Impersonate the the current thread */
212c2c66affSColin Finck     Status = NtSetInformationThread(NtCurrentThread(),
213c2c66affSColin Finck                                     ThreadImpersonationToken,
214c2c66affSColin Finck                                     &NewToken,
215c2c66affSColin Finck                                     sizeof(HANDLE));
216c2c66affSColin Finck 
217c2c66affSColin Finck     if (Duplicated != FALSE)
218c2c66affSColin Finck     {
219c2c66affSColin Finck         NtClose(NewToken);
220c2c66affSColin Finck     }
221c2c66affSColin Finck 
222c2c66affSColin Finck     if (!NT_SUCCESS(Status))
223c2c66affSColin Finck     {
224c2c66affSColin Finck         ERR("NtSetInformationThread failed: Status %08x\n", Status);
225c2c66affSColin Finck         SetLastError(RtlNtStatusToDosError(Status));
226c2c66affSColin Finck         return FALSE;
227c2c66affSColin Finck     }
228c2c66affSColin Finck 
229c2c66affSColin Finck     return TRUE;
230c2c66affSColin Finck }
231c2c66affSColin Finck 
232c2c66affSColin Finck /******************************************************************************
233c2c66affSColin Finck  * GetUserNameA [ADVAPI32.@]
234c2c66affSColin Finck  *
235c2c66affSColin Finck  * Get the current user name.
236c2c66affSColin Finck  *
237c2c66affSColin Finck  * PARAMS
238c2c66affSColin Finck  *  lpszName [O]   Destination for the user name.
239c2c66affSColin Finck  *  lpSize   [I/O] Size of lpszName.
240c2c66affSColin Finck  *
241c2c66affSColin Finck  *
242c2c66affSColin Finck  * @implemented
243c2c66affSColin Finck  */
244c2c66affSColin Finck BOOL
245c2c66affSColin Finck WINAPI
GetUserNameA(LPSTR lpszName,LPDWORD lpSize)246c2c66affSColin Finck GetUserNameA(LPSTR lpszName,
247c2c66affSColin Finck              LPDWORD lpSize)
248c2c66affSColin Finck {
249c2c66affSColin Finck     UNICODE_STRING NameW;
250c2c66affSColin Finck     ANSI_STRING NameA;
251c2c66affSColin Finck     BOOL Ret;
252c2c66affSColin Finck 
253c2c66affSColin Finck     /* apparently Win doesn't check whether lpSize is valid at all! */
254c2c66affSColin Finck 
255c2c66affSColin Finck     NameW.MaximumLength = (*lpSize) * sizeof(WCHAR);
256c2c66affSColin Finck     NameW.Buffer = LocalAlloc(LMEM_FIXED, NameW.MaximumLength);
257c2c66affSColin Finck     if(NameW.Buffer == NULL)
258c2c66affSColin Finck     {
259c2c66affSColin Finck         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
260c2c66affSColin Finck         return FALSE;
261c2c66affSColin Finck     }
262c2c66affSColin Finck 
263c2c66affSColin Finck     NameA.Length = 0;
264c2c66affSColin Finck     NameA.MaximumLength = ((*lpSize) < 0xFFFF ? (USHORT)(*lpSize) : 0xFFFF);
265c2c66affSColin Finck     NameA.Buffer = lpszName;
266c2c66affSColin Finck 
267c2c66affSColin Finck     Ret = GetUserNameW(NameW.Buffer,
268c2c66affSColin Finck                        lpSize);
269c2c66affSColin Finck     if(Ret)
270c2c66affSColin Finck     {
271c2c66affSColin Finck         NameW.Length = (*lpSize - 1) * sizeof(WCHAR);
272c2c66affSColin Finck         RtlUnicodeStringToAnsiString(&NameA, &NameW, FALSE);
273c2c66affSColin Finck 
274c2c66affSColin Finck         *lpSize = NameA.Length + 1;
275c2c66affSColin Finck     }
276c2c66affSColin Finck 
277c2c66affSColin Finck     LocalFree(NameW.Buffer);
278c2c66affSColin Finck 
279c2c66affSColin Finck     return Ret;
280c2c66affSColin Finck }
281c2c66affSColin Finck 
282c2c66affSColin Finck /******************************************************************************
283c2c66affSColin Finck  * GetUserNameW [ADVAPI32.@]
284c2c66affSColin Finck  *
285c2c66affSColin Finck  * See GetUserNameA.
286c2c66affSColin Finck  *
287c2c66affSColin Finck  * @implemented
288c2c66affSColin Finck  */
289c2c66affSColin Finck BOOL
290c2c66affSColin Finck WINAPI
GetUserNameW(LPWSTR lpszName,LPDWORD lpSize)291c2c66affSColin Finck GetUserNameW(LPWSTR lpszName,
292c2c66affSColin Finck              LPDWORD lpSize)
293c2c66affSColin Finck {
294c2c66affSColin Finck     HANDLE hToken = INVALID_HANDLE_VALUE;
295c2c66affSColin Finck     DWORD tu_len = 0;
296c2c66affSColin Finck     char* tu_buf = NULL;
297c2c66affSColin Finck     TOKEN_USER* token_user = NULL;
298c2c66affSColin Finck     DWORD an_len = 0;
299c2c66affSColin Finck     SID_NAME_USE snu = SidTypeUser;
300c2c66affSColin Finck     WCHAR* domain_name = NULL;
301c2c66affSColin Finck     DWORD dn_len = 0;
302c2c66affSColin Finck 
303c2c66affSColin Finck     if (!OpenThreadToken (GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken))
304c2c66affSColin Finck     {
305c2c66affSColin Finck         DWORD dwLastError = GetLastError();
306c2c66affSColin Finck         if (dwLastError != ERROR_NO_TOKEN
307c2c66affSColin Finck             && dwLastError != ERROR_NO_IMPERSONATION_TOKEN)
308c2c66affSColin Finck         {
309c2c66affSColin Finck             /* don't call SetLastError(),
310c2c66affSColin Finck                as OpenThreadToken() ought to have set one */
311c2c66affSColin Finck             return FALSE;
312c2c66affSColin Finck         }
313c2c66affSColin Finck 
314c2c66affSColin Finck         if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
315c2c66affSColin Finck         {
316c2c66affSColin Finck             /* don't call SetLastError(),
317c2c66affSColin Finck                as OpenProcessToken() ought to have set one */
318c2c66affSColin Finck             return FALSE;
319c2c66affSColin Finck         }
320c2c66affSColin Finck     }
321c2c66affSColin Finck 
322c2c66affSColin Finck     tu_buf = LocalAlloc(LMEM_FIXED, 36);
323c2c66affSColin Finck     if (!tu_buf)
324c2c66affSColin Finck     {
325c2c66affSColin Finck         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
326c2c66affSColin Finck         CloseHandle(hToken);
327c2c66affSColin Finck         return FALSE;
328c2c66affSColin Finck     }
329c2c66affSColin Finck 
330c2c66affSColin Finck     if (!GetTokenInformation(hToken, TokenUser, tu_buf, 36, &tu_len) || tu_len > 36)
331c2c66affSColin Finck     {
332c2c66affSColin Finck         LocalFree(tu_buf);
333c2c66affSColin Finck         tu_buf = LocalAlloc(LMEM_FIXED, tu_len);
334c2c66affSColin Finck         if (!tu_buf)
335c2c66affSColin Finck         {
336c2c66affSColin Finck             SetLastError(ERROR_NOT_ENOUGH_MEMORY);
337c2c66affSColin Finck             CloseHandle(hToken);
338c2c66affSColin Finck             return FALSE;
339c2c66affSColin Finck         }
340c2c66affSColin Finck 
341c2c66affSColin Finck         if (!GetTokenInformation(hToken, TokenUser, tu_buf, tu_len, &tu_len))
342c2c66affSColin Finck         {
343c2c66affSColin Finck             /* don't call SetLastError(),
344c2c66affSColin Finck                as GetTokenInformation() ought to have set one */
345c2c66affSColin Finck             LocalFree(tu_buf);
346c2c66affSColin Finck             CloseHandle(hToken);
347c2c66affSColin Finck             return FALSE;
348c2c66affSColin Finck         }
349c2c66affSColin Finck     }
350c2c66affSColin Finck 
351c2c66affSColin Finck     CloseHandle(hToken);
352c2c66affSColin Finck     token_user = (TOKEN_USER*)tu_buf;
353c2c66affSColin Finck 
354c2c66affSColin Finck     an_len = *lpSize;
355c2c66affSColin Finck     dn_len = 32;
356c2c66affSColin Finck     domain_name = LocalAlloc(LMEM_FIXED, dn_len * sizeof(WCHAR));
357c2c66affSColin Finck     if (!domain_name)
358c2c66affSColin Finck     {
359c2c66affSColin Finck         LocalFree(tu_buf);
360c2c66affSColin Finck         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
361c2c66affSColin Finck         return FALSE;
362c2c66affSColin Finck     }
363c2c66affSColin Finck 
364c2c66affSColin Finck     if (!LookupAccountSidW(NULL, token_user->User.Sid, lpszName, &an_len, domain_name, &dn_len, &snu)
365c2c66affSColin Finck         || dn_len > 32)
366c2c66affSColin Finck     {
367c2c66affSColin Finck         if (dn_len > 32)
368c2c66affSColin Finck         {
369c2c66affSColin Finck             LocalFree(domain_name);
370c2c66affSColin Finck             domain_name = LocalAlloc(LMEM_FIXED, dn_len * sizeof(WCHAR));
371c2c66affSColin Finck             if (!domain_name)
372c2c66affSColin Finck             {
373c2c66affSColin Finck                 LocalFree(tu_buf);
374c2c66affSColin Finck                 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
375c2c66affSColin Finck                 return FALSE;
376c2c66affSColin Finck             }
377c2c66affSColin Finck         }
378c2c66affSColin Finck 
379c2c66affSColin Finck         an_len = *lpSize;
380c2c66affSColin Finck         if (!LookupAccountSidW(NULL, token_user->User.Sid, lpszName, &an_len, domain_name, &dn_len, &snu))
381c2c66affSColin Finck         {
382c2c66affSColin Finck             /* don't call SetLastError(),
383c2c66affSColin Finck                as LookupAccountSid() ought to have set one */
384c2c66affSColin Finck             LocalFree(domain_name);
385c2c66affSColin Finck             LocalFree(tu_buf);
386c2c66affSColin Finck             *lpSize = an_len;
387c2c66affSColin Finck             return FALSE;
388c2c66affSColin Finck         }
389c2c66affSColin Finck     }
390c2c66affSColin Finck 
391c2c66affSColin Finck     LocalFree(domain_name);
392c2c66affSColin Finck     LocalFree(tu_buf);
393c2c66affSColin Finck     *lpSize = an_len + 1;
394c2c66affSColin Finck     return TRUE;
395c2c66affSColin Finck }
396c2c66affSColin Finck 
397c2c66affSColin Finck 
398c2c66affSColin Finck /******************************************************************************
399c2c66affSColin Finck  * LookupAccountSidA [ADVAPI32.@]
400c2c66affSColin Finck  *
401c2c66affSColin Finck  * @implemented
402c2c66affSColin Finck  */
403c2c66affSColin Finck BOOL
404c2c66affSColin Finck WINAPI
LookupAccountSidA(LPCSTR lpSystemName,PSID lpSid,LPSTR lpName,LPDWORD cchName,LPSTR lpReferencedDomainName,LPDWORD cchReferencedDomainName,PSID_NAME_USE peUse)405c2c66affSColin Finck LookupAccountSidA(LPCSTR lpSystemName,
406c2c66affSColin Finck                   PSID lpSid,
407c2c66affSColin Finck                   LPSTR lpName,
408c2c66affSColin Finck                   LPDWORD cchName,
409c2c66affSColin Finck                   LPSTR lpReferencedDomainName,
410c2c66affSColin Finck                   LPDWORD cchReferencedDomainName,
411c2c66affSColin Finck                   PSID_NAME_USE peUse)
412c2c66affSColin Finck {
413c2c66affSColin Finck     UNICODE_STRING NameW, ReferencedDomainNameW, SystemNameW;
414c2c66affSColin Finck     LPWSTR NameBuffer = NULL;
415c2c66affSColin Finck     LPWSTR ReferencedDomainNameBuffer = NULL;
416c2c66affSColin Finck     DWORD dwName, dwReferencedDomainName;
417c2c66affSColin Finck     BOOL Ret;
418c2c66affSColin Finck 
419c2c66affSColin Finck     /*
420c2c66affSColin Finck      * save the buffer sizes the caller passed to us, as they may get modified and
421c2c66affSColin Finck      * we require the original values when converting back to ansi
422c2c66affSColin Finck      */
423c2c66affSColin Finck     dwName = *cchName;
424c2c66affSColin Finck     dwReferencedDomainName = *cchReferencedDomainName;
425c2c66affSColin Finck 
426c2c66affSColin Finck     /* allocate buffers for the unicode strings to receive */
427c2c66affSColin Finck     if (dwName > 0)
428c2c66affSColin Finck     {
429c2c66affSColin Finck         NameBuffer = LocalAlloc(LMEM_FIXED, dwName * sizeof(WCHAR));
430c2c66affSColin Finck         if (NameBuffer == NULL)
431c2c66affSColin Finck         {
432c2c66affSColin Finck             SetLastError(ERROR_OUTOFMEMORY);
433c2c66affSColin Finck             return FALSE;
434c2c66affSColin Finck         }
435c2c66affSColin Finck     }
436c2c66affSColin Finck     else
437c2c66affSColin Finck         NameBuffer = NULL;
438c2c66affSColin Finck 
439c2c66affSColin Finck     if (dwReferencedDomainName > 0)
440c2c66affSColin Finck     {
441c2c66affSColin Finck         ReferencedDomainNameBuffer = LocalAlloc(LMEM_FIXED, dwReferencedDomainName * sizeof(WCHAR));
442c2c66affSColin Finck         if (ReferencedDomainNameBuffer == NULL)
443c2c66affSColin Finck         {
444c2c66affSColin Finck             if (dwName > 0)
445c2c66affSColin Finck             {
446c2c66affSColin Finck                 LocalFree(NameBuffer);
447c2c66affSColin Finck             }
448c2c66affSColin Finck 
449c2c66affSColin Finck             SetLastError(ERROR_OUTOFMEMORY);
450c2c66affSColin Finck             return FALSE;
451c2c66affSColin Finck         }
452c2c66affSColin Finck     }
453c2c66affSColin Finck     else
454c2c66affSColin Finck         ReferencedDomainNameBuffer = NULL;
455c2c66affSColin Finck 
456c2c66affSColin Finck 
457c2c66affSColin Finck     /* convert the system name to unicode - if present */
458c2c66affSColin Finck     if (lpSystemName != NULL)
459c2c66affSColin Finck     {
460c2c66affSColin Finck         ANSI_STRING SystemNameA;
461c2c66affSColin Finck 
462c2c66affSColin Finck         RtlInitAnsiString(&SystemNameA, lpSystemName);
463c2c66affSColin Finck         RtlAnsiStringToUnicodeString(&SystemNameW, &SystemNameA, TRUE);
464c2c66affSColin Finck     }
465c2c66affSColin Finck     else
466c2c66affSColin Finck         SystemNameW.Buffer = NULL;
467c2c66affSColin Finck 
468c2c66affSColin Finck     /* it's time to call the unicode version */
469c2c66affSColin Finck     Ret = LookupAccountSidW(SystemNameW.Buffer,
470c2c66affSColin Finck                             lpSid,
471c2c66affSColin Finck                             NameBuffer,
472c2c66affSColin Finck                             cchName,
473c2c66affSColin Finck                             ReferencedDomainNameBuffer,
474c2c66affSColin Finck                             cchReferencedDomainName,
475c2c66affSColin Finck                             peUse);
476c2c66affSColin Finck     if (Ret)
477c2c66affSColin Finck     {
478c2c66affSColin Finck         /*
479c2c66affSColin Finck          * convert unicode strings back to ansi, don't forget that we can't convert
480c2c66affSColin Finck          * more than 0xFFFF (USHORT) characters! Also don't forget to explicitly
481c2c66affSColin Finck          * terminate the converted string, the Rtl functions don't do that!
482c2c66affSColin Finck          */
483c2c66affSColin Finck         if (lpName != NULL)
484c2c66affSColin Finck         {
485c2c66affSColin Finck             ANSI_STRING NameA;
486c2c66affSColin Finck 
487c2c66affSColin Finck             NameA.Length = 0;
488c2c66affSColin Finck             NameA.MaximumLength = ((dwName <= 0xFFFF) ? (USHORT)dwName : 0xFFFF);
489c2c66affSColin Finck             NameA.Buffer = lpName;
490c2c66affSColin Finck 
491c2c66affSColin Finck             RtlInitUnicodeString(&NameW, NameBuffer);
492c2c66affSColin Finck             RtlUnicodeStringToAnsiString(&NameA, &NameW, FALSE);
493c2c66affSColin Finck             NameA.Buffer[NameA.Length] = '\0';
494c2c66affSColin Finck         }
495c2c66affSColin Finck 
496c2c66affSColin Finck         if (lpReferencedDomainName != NULL)
497c2c66affSColin Finck         {
498c2c66affSColin Finck             ANSI_STRING ReferencedDomainNameA;
499c2c66affSColin Finck 
500c2c66affSColin Finck             ReferencedDomainNameA.Length = 0;
501c2c66affSColin Finck             ReferencedDomainNameA.MaximumLength = ((dwReferencedDomainName <= 0xFFFF) ?
502c2c66affSColin Finck                                                    (USHORT)dwReferencedDomainName : 0xFFFF);
503c2c66affSColin Finck             ReferencedDomainNameA.Buffer = lpReferencedDomainName;
504c2c66affSColin Finck 
505c2c66affSColin Finck             RtlInitUnicodeString(&ReferencedDomainNameW, ReferencedDomainNameBuffer);
506c2c66affSColin Finck             RtlUnicodeStringToAnsiString(&ReferencedDomainNameA, &ReferencedDomainNameW, FALSE);
507c2c66affSColin Finck             ReferencedDomainNameA.Buffer[ReferencedDomainNameA.Length] = '\0';
508c2c66affSColin Finck         }
509c2c66affSColin Finck     }
510c2c66affSColin Finck 
511c2c66affSColin Finck     /* free previously allocated buffers */
512c2c66affSColin Finck     if (SystemNameW.Buffer != NULL)
513c2c66affSColin Finck     {
514c2c66affSColin Finck         RtlFreeUnicodeString(&SystemNameW);
515c2c66affSColin Finck     }
516c2c66affSColin Finck 
517c2c66affSColin Finck     if (NameBuffer != NULL)
518c2c66affSColin Finck     {
519c2c66affSColin Finck         LocalFree(NameBuffer);
520c2c66affSColin Finck     }
521c2c66affSColin Finck 
522c2c66affSColin Finck     if (ReferencedDomainNameBuffer != NULL)
523c2c66affSColin Finck     {
524c2c66affSColin Finck         LocalFree(ReferencedDomainNameBuffer);
525c2c66affSColin Finck     }
526c2c66affSColin Finck 
527c2c66affSColin Finck     return Ret;
528c2c66affSColin Finck }
529c2c66affSColin Finck 
530c2c66affSColin Finck 
531c2c66affSColin Finck /******************************************************************************
532c2c66affSColin Finck  * LookupAccountSidW [ADVAPI32.@]
533c2c66affSColin Finck  *
534c2c66affSColin Finck  * @implemented
535c2c66affSColin Finck  */
536c2c66affSColin Finck BOOL WINAPI
LookupAccountSidW(LPCWSTR pSystemName,PSID pSid,LPWSTR pAccountName,LPDWORD pdwAccountName,LPWSTR pDomainName,LPDWORD pdwDomainName,PSID_NAME_USE peUse)537c2c66affSColin Finck LookupAccountSidW(LPCWSTR pSystemName,
538c2c66affSColin Finck                   PSID pSid,
539c2c66affSColin Finck                   LPWSTR pAccountName,
540c2c66affSColin Finck                   LPDWORD pdwAccountName,
541c2c66affSColin Finck                   LPWSTR pDomainName,
542c2c66affSColin Finck                   LPDWORD pdwDomainName,
543c2c66affSColin Finck                   PSID_NAME_USE peUse)
544c2c66affSColin Finck {
545c2c66affSColin Finck     LSA_UNICODE_STRING SystemName;
546c2c66affSColin Finck     LSA_OBJECT_ATTRIBUTES ObjectAttributes = {0};
547c2c66affSColin Finck     LSA_HANDLE PolicyHandle = NULL;
548c2c66affSColin Finck     NTSTATUS Status;
549c2c66affSColin Finck     PLSA_REFERENCED_DOMAIN_LIST ReferencedDomain = NULL;
550c2c66affSColin Finck     PLSA_TRANSLATED_NAME TranslatedName = NULL;
551c2c66affSColin Finck     BOOL ret;
552c2c66affSColin Finck     DWORD dwAccountName, dwDomainName;
553c2c66affSColin Finck 
554c2c66affSColin Finck     RtlInitUnicodeString(&SystemName, pSystemName);
555c2c66affSColin Finck     Status = LsaOpenPolicy(&SystemName, &ObjectAttributes, POLICY_LOOKUP_NAMES, &PolicyHandle);
556c2c66affSColin Finck     if (!NT_SUCCESS(Status))
557c2c66affSColin Finck     {
558c2c66affSColin Finck         SetLastError(LsaNtStatusToWinError(Status));
559c2c66affSColin Finck         return FALSE;
560c2c66affSColin Finck     }
561c2c66affSColin Finck 
562c2c66affSColin Finck     Status = LsaLookupSids(PolicyHandle, 1, &pSid, &ReferencedDomain, &TranslatedName);
563c2c66affSColin Finck 
564c2c66affSColin Finck     LsaClose(PolicyHandle);
565c2c66affSColin Finck 
566c2c66affSColin Finck     if (!NT_SUCCESS(Status) || Status == STATUS_SOME_NOT_MAPPED)
567c2c66affSColin Finck     {
568c2c66affSColin Finck         SetLastError(LsaNtStatusToWinError(Status));
569c2c66affSColin Finck         ret = FALSE;
570c2c66affSColin Finck     }
571c2c66affSColin Finck     else
572c2c66affSColin Finck     {
573c2c66affSColin Finck         ret = TRUE;
574c2c66affSColin Finck 
575c2c66affSColin Finck         dwAccountName = TranslatedName->Name.Length / sizeof(WCHAR);
576c2c66affSColin Finck         if (ReferencedDomain && ReferencedDomain->Entries > 0)
577c2c66affSColin Finck             dwDomainName = ReferencedDomain->Domains[0].Name.Length / sizeof(WCHAR);
578c2c66affSColin Finck         else
579c2c66affSColin Finck             dwDomainName = 0;
580c2c66affSColin Finck 
581c2c66affSColin Finck         if (*pdwAccountName <= dwAccountName || *pdwDomainName <= dwDomainName)
582c2c66affSColin Finck         {
583c2c66affSColin Finck             /* One or two buffers are insufficient, add up a char for NULL termination */
584c2c66affSColin Finck             *pdwAccountName = dwAccountName + 1;
585c2c66affSColin Finck             *pdwDomainName = dwDomainName + 1;
586c2c66affSColin Finck             ret = FALSE;
587c2c66affSColin Finck         }
588c2c66affSColin Finck         else
589c2c66affSColin Finck         {
590c2c66affSColin Finck             /* Lengths are sufficient, copy the data */
591c2c66affSColin Finck             if (dwAccountName)
592c2c66affSColin Finck                 RtlCopyMemory(pAccountName, TranslatedName->Name.Buffer, dwAccountName * sizeof(WCHAR));
593c2c66affSColin Finck             pAccountName[dwAccountName] = L'\0';
594c2c66affSColin Finck 
595c2c66affSColin Finck             if (dwDomainName)
596c2c66affSColin Finck                 RtlCopyMemory(pDomainName, ReferencedDomain->Domains[0].Name.Buffer, dwDomainName * sizeof(WCHAR));
597c2c66affSColin Finck             pDomainName[dwDomainName] = L'\0';
598c2c66affSColin Finck 
599c2c66affSColin Finck             *pdwAccountName = dwAccountName;
600c2c66affSColin Finck             *pdwDomainName = dwDomainName;
601c2c66affSColin Finck 
602c2c66affSColin Finck             if (peUse)
603c2c66affSColin Finck                 *peUse = TranslatedName->Use;
604c2c66affSColin Finck         }
605c2c66affSColin Finck 
606c2c66affSColin Finck         if (!ret)
607c2c66affSColin Finck             SetLastError(ERROR_INSUFFICIENT_BUFFER);
608c2c66affSColin Finck     }
609c2c66affSColin Finck 
610c2c66affSColin Finck     if (ReferencedDomain)
611c2c66affSColin Finck         LsaFreeMemory(ReferencedDomain);
612c2c66affSColin Finck 
613c2c66affSColin Finck     if (TranslatedName)
614c2c66affSColin Finck         LsaFreeMemory(TranslatedName);
615c2c66affSColin Finck 
616c2c66affSColin Finck     return ret;
617c2c66affSColin Finck }
618c2c66affSColin Finck 
619c2c66affSColin Finck /******************************************************************************
620c2c66affSColin Finck  * LookupAccountNameW [ADVAPI32.@]
621c2c66affSColin Finck  *
622c2c66affSColin Finck  * @implemented
623c2c66affSColin Finck  */
624c2c66affSColin Finck BOOL
625c2c66affSColin Finck WINAPI
LookupAccountNameW(LPCWSTR lpSystemName,LPCWSTR lpAccountName,PSID Sid,LPDWORD cbSid,LPWSTR ReferencedDomainName,LPDWORD cchReferencedDomainName,PSID_NAME_USE peUse)626c2c66affSColin Finck LookupAccountNameW(LPCWSTR lpSystemName,
627c2c66affSColin Finck                    LPCWSTR lpAccountName,
628c2c66affSColin Finck                    PSID Sid,
629c2c66affSColin Finck                    LPDWORD cbSid,
630c2c66affSColin Finck                    LPWSTR ReferencedDomainName,
631c2c66affSColin Finck                    LPDWORD cchReferencedDomainName,
632c2c66affSColin Finck                    PSID_NAME_USE peUse)
633c2c66affSColin Finck {
634c2c66affSColin Finck     OBJECT_ATTRIBUTES ObjectAttributes = {0};
635c2c66affSColin Finck     UNICODE_STRING SystemName;
636c2c66affSColin Finck     UNICODE_STRING AccountName;
637c2c66affSColin Finck     LSA_HANDLE PolicyHandle = NULL;
638c2c66affSColin Finck     PLSA_REFERENCED_DOMAIN_LIST ReferencedDomains = NULL;
639c2c66affSColin Finck     PLSA_TRANSLATED_SID TranslatedSid = NULL;
640c2c66affSColin Finck     PSID pDomainSid;
641c2c66affSColin Finck     DWORD dwDomainNameLength;
642c2c66affSColin Finck     DWORD dwSidLength;
643c2c66affSColin Finck     UCHAR nSubAuthorities;
644c2c66affSColin Finck     BOOL bResult;
645c2c66affSColin Finck     NTSTATUS Status;
646c2c66affSColin Finck 
647c2c66affSColin Finck     TRACE("%s %s %p %p %p %p %p\n", lpSystemName, lpAccountName,
648c2c66affSColin Finck           Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
649c2c66affSColin Finck 
650c2c66affSColin Finck     RtlInitUnicodeString(&SystemName,
651c2c66affSColin Finck                          lpSystemName);
652c2c66affSColin Finck 
653c2c66affSColin Finck     Status = LsaOpenPolicy(lpSystemName ? &SystemName : NULL,
654c2c66affSColin Finck                            &ObjectAttributes,
655c2c66affSColin Finck                            POLICY_LOOKUP_NAMES,
656c2c66affSColin Finck                            &PolicyHandle);
657c2c66affSColin Finck     if (!NT_SUCCESS(Status))
658c2c66affSColin Finck     {
659c2c66affSColin Finck         SetLastError(LsaNtStatusToWinError(Status));
660c2c66affSColin Finck         return FALSE;
661c2c66affSColin Finck     }
662c2c66affSColin Finck 
663c2c66affSColin Finck     RtlInitUnicodeString(&AccountName,
664c2c66affSColin Finck                          lpAccountName);
665c2c66affSColin Finck 
666c2c66affSColin Finck     Status = LsaLookupNames(PolicyHandle,
667c2c66affSColin Finck                             1,
668c2c66affSColin Finck                             &AccountName,
669c2c66affSColin Finck                             &ReferencedDomains,
670c2c66affSColin Finck                             &TranslatedSid);
671c2c66affSColin Finck 
672c2c66affSColin Finck     LsaClose(PolicyHandle);
673c2c66affSColin Finck 
674c2c66affSColin Finck     if (!NT_SUCCESS(Status) || Status == STATUS_SOME_NOT_MAPPED)
675c2c66affSColin Finck     {
676c2c66affSColin Finck         SetLastError(LsaNtStatusToWinError(Status));
677c2c66affSColin Finck         bResult = FALSE;
678c2c66affSColin Finck     }
679c2c66affSColin Finck     else
680c2c66affSColin Finck     {
681c2c66affSColin Finck         pDomainSid = ReferencedDomains->Domains[TranslatedSid->DomainIndex].Sid;
682c2c66affSColin Finck         nSubAuthorities = *GetSidSubAuthorityCount(pDomainSid);
683c2c66affSColin Finck         dwSidLength = GetSidLengthRequired(nSubAuthorities + 1);
684c2c66affSColin Finck 
685c2c66affSColin Finck         dwDomainNameLength = ReferencedDomains->Domains->Name.Length / sizeof(WCHAR);
686c2c66affSColin Finck 
687c2c66affSColin Finck         if (*cbSid < dwSidLength ||
688c2c66affSColin Finck             *cchReferencedDomainName < dwDomainNameLength + 1)
689c2c66affSColin Finck         {
690c2c66affSColin Finck             *cbSid = dwSidLength;
691c2c66affSColin Finck             *cchReferencedDomainName = dwDomainNameLength + 1;
692c2c66affSColin Finck 
693c2c66affSColin Finck             bResult = FALSE;
694c2c66affSColin Finck         }
695c2c66affSColin Finck         else
696c2c66affSColin Finck         {
697c2c66affSColin Finck             CopySid(*cbSid, Sid, pDomainSid);
698c2c66affSColin Finck             *GetSidSubAuthorityCount(Sid) = nSubAuthorities + 1;
699c2c66affSColin Finck             *GetSidSubAuthority(Sid, (DWORD)nSubAuthorities) = TranslatedSid->RelativeId;
700c2c66affSColin Finck 
701c2c66affSColin Finck             RtlCopyMemory(ReferencedDomainName, ReferencedDomains->Domains->Name.Buffer, dwDomainNameLength * sizeof(WCHAR));
702c2c66affSColin Finck             ReferencedDomainName[dwDomainNameLength] = L'\0';
703c2c66affSColin Finck 
704c2c66affSColin Finck             *cchReferencedDomainName = dwDomainNameLength;
705c2c66affSColin Finck 
706c2c66affSColin Finck             *peUse = TranslatedSid->Use;
707c2c66affSColin Finck 
708c2c66affSColin Finck             bResult = TRUE;
709c2c66affSColin Finck         }
710c2c66affSColin Finck 
711c2c66affSColin Finck         if (bResult == FALSE)
712c2c66affSColin Finck             SetLastError(ERROR_INSUFFICIENT_BUFFER);
713c2c66affSColin Finck     }
714c2c66affSColin Finck 
715c2c66affSColin Finck     if (ReferencedDomains != NULL)
716c2c66affSColin Finck         LsaFreeMemory(ReferencedDomains);
717c2c66affSColin Finck 
718c2c66affSColin Finck     if (TranslatedSid != NULL)
719c2c66affSColin Finck         LsaFreeMemory(TranslatedSid);
720c2c66affSColin Finck 
721c2c66affSColin Finck     return bResult;
722c2c66affSColin Finck }
723c2c66affSColin Finck 
724c2c66affSColin Finck 
725c2c66affSColin Finck /**********************************************************************
726c2c66affSColin Finck  * LookupPrivilegeValueA				EXPORTED
727c2c66affSColin Finck  *
728c2c66affSColin Finck  * @implemented
729c2c66affSColin Finck  */
730c2c66affSColin Finck BOOL
731c2c66affSColin Finck WINAPI
LookupPrivilegeValueA(LPCSTR lpSystemName,LPCSTR lpName,PLUID lpLuid)732c2c66affSColin Finck LookupPrivilegeValueA(LPCSTR lpSystemName,
733c2c66affSColin Finck                       LPCSTR lpName,
734c2c66affSColin Finck                       PLUID lpLuid)
735c2c66affSColin Finck {
736c2c66affSColin Finck     UNICODE_STRING SystemName;
737c2c66affSColin Finck     UNICODE_STRING Name;
738c2c66affSColin Finck     BOOL Result;
739c2c66affSColin Finck 
740c2c66affSColin Finck     /* Remote system? */
741c2c66affSColin Finck     if (lpSystemName != NULL)
742c2c66affSColin Finck     {
743c2c66affSColin Finck         RtlCreateUnicodeStringFromAsciiz(&SystemName,
744c2c66affSColin Finck                                          (LPSTR)lpSystemName);
745c2c66affSColin Finck     }
746c2c66affSColin Finck     else
747c2c66affSColin Finck         SystemName.Buffer = NULL;
748c2c66affSColin Finck 
749c2c66affSColin Finck     /* Check the privilege name is not NULL */
750c2c66affSColin Finck     if (lpName == NULL)
751c2c66affSColin Finck     {
752c2c66affSColin Finck         SetLastError(ERROR_NO_SUCH_PRIVILEGE);
753c2c66affSColin Finck         return FALSE;
754c2c66affSColin Finck     }
755c2c66affSColin Finck 
756c2c66affSColin Finck     RtlCreateUnicodeStringFromAsciiz(&Name,
757c2c66affSColin Finck                                      (LPSTR)lpName);
758c2c66affSColin Finck 
759c2c66affSColin Finck     Result = LookupPrivilegeValueW(SystemName.Buffer,
760c2c66affSColin Finck                                    Name.Buffer,
761c2c66affSColin Finck                                    lpLuid);
762c2c66affSColin Finck 
763c2c66affSColin Finck     RtlFreeUnicodeString(&Name);
764c2c66affSColin Finck 
765c2c66affSColin Finck     /* Remote system? */
766c2c66affSColin Finck     if (SystemName.Buffer != NULL)
767c2c66affSColin Finck     {
768c2c66affSColin Finck         RtlFreeUnicodeString(&SystemName);
769c2c66affSColin Finck     }
770c2c66affSColin Finck 
771c2c66affSColin Finck     return Result;
772c2c66affSColin Finck }
773c2c66affSColin Finck 
774c2c66affSColin Finck 
775c2c66affSColin Finck /**********************************************************************
776c2c66affSColin Finck  * LookupPrivilegeValueW
777c2c66affSColin Finck  *
778c2c66affSColin Finck  * @implemented
779c2c66affSColin Finck  */
780c2c66affSColin Finck BOOL
781c2c66affSColin Finck WINAPI
LookupPrivilegeValueW(LPCWSTR lpSystemName,LPCWSTR lpPrivilegeName,PLUID lpLuid)782c2c66affSColin Finck LookupPrivilegeValueW(LPCWSTR lpSystemName,
783c2c66affSColin Finck                       LPCWSTR lpPrivilegeName,
784c2c66affSColin Finck                       PLUID lpLuid)
785c2c66affSColin Finck {
786c2c66affSColin Finck     OBJECT_ATTRIBUTES ObjectAttributes = {0};
787c2c66affSColin Finck     UNICODE_STRING SystemName;
788c2c66affSColin Finck     UNICODE_STRING PrivilegeName;
789c2c66affSColin Finck     LSA_HANDLE PolicyHandle = NULL;
790c2c66affSColin Finck     NTSTATUS Status;
791c2c66affSColin Finck 
792c2c66affSColin Finck     TRACE("%S,%S,%p\n", lpSystemName, lpPrivilegeName, lpLuid);
793c2c66affSColin Finck 
794c2c66affSColin Finck     RtlInitUnicodeString(&SystemName,
795c2c66affSColin Finck                          lpSystemName);
796c2c66affSColin Finck 
797c2c66affSColin Finck     Status = LsaOpenPolicy(lpSystemName ? &SystemName : NULL,
798c2c66affSColin Finck                            &ObjectAttributes,
799c2c66affSColin Finck                            POLICY_LOOKUP_NAMES,
800c2c66affSColin Finck                            &PolicyHandle);
801c2c66affSColin Finck     if (!NT_SUCCESS(Status))
802c2c66affSColin Finck     {
803c2c66affSColin Finck         SetLastError(LsaNtStatusToWinError(Status));
804c2c66affSColin Finck         return FALSE;
805c2c66affSColin Finck     }
806c2c66affSColin Finck 
807c2c66affSColin Finck     RtlInitUnicodeString(&PrivilegeName,
808c2c66affSColin Finck                          lpPrivilegeName);
809c2c66affSColin Finck 
810c2c66affSColin Finck     Status = LsaLookupPrivilegeValue(PolicyHandle,
811c2c66affSColin Finck                                      &PrivilegeName,
812c2c66affSColin Finck                                      lpLuid);
813c2c66affSColin Finck 
814c2c66affSColin Finck     LsaClose(PolicyHandle);
815c2c66affSColin Finck 
816c2c66affSColin Finck     if (!NT_SUCCESS(Status))
817c2c66affSColin Finck     {
818c2c66affSColin Finck         SetLastError(LsaNtStatusToWinError(Status));
819c2c66affSColin Finck         return FALSE;
820c2c66affSColin Finck     }
821c2c66affSColin Finck 
822c2c66affSColin Finck     return TRUE;
823c2c66affSColin Finck }
824c2c66affSColin Finck 
825c2c66affSColin Finck /**********************************************************************
826c2c66affSColin Finck  * LookupPrivilegeNameW				EXPORTED
827c2c66affSColin Finck  *
828c2c66affSColin Finck  * @implemented
829c2c66affSColin Finck  */
830c2c66affSColin Finck BOOL
831c2c66affSColin Finck WINAPI
LookupPrivilegeNameW(LPCWSTR lpSystemName,PLUID lpLuid,LPWSTR lpName,LPDWORD cchName)832c2c66affSColin Finck LookupPrivilegeNameW(LPCWSTR lpSystemName,
833c2c66affSColin Finck                      PLUID lpLuid,
834c2c66affSColin Finck                      LPWSTR lpName,
835c2c66affSColin Finck                      LPDWORD cchName)
836c2c66affSColin Finck {
837c2c66affSColin Finck     OBJECT_ATTRIBUTES ObjectAttributes = {0};
838c2c66affSColin Finck     UNICODE_STRING SystemName;
839c2c66affSColin Finck     PUNICODE_STRING PrivilegeName = NULL;
840c2c66affSColin Finck     LSA_HANDLE PolicyHandle = NULL;
841c2c66affSColin Finck     NTSTATUS Status;
842c2c66affSColin Finck 
843c2c66affSColin Finck     TRACE("%S,%p,%p,%p\n", lpSystemName, lpLuid, lpName, cchName);
844c2c66affSColin Finck 
845c2c66affSColin Finck     RtlInitUnicodeString(&SystemName,
846c2c66affSColin Finck                          lpSystemName);
847c2c66affSColin Finck 
848c2c66affSColin Finck     Status = LsaOpenPolicy(lpSystemName ? &SystemName : NULL,
849c2c66affSColin Finck                            &ObjectAttributes,
850c2c66affSColin Finck                            POLICY_LOOKUP_NAMES,
851c2c66affSColin Finck                            &PolicyHandle);
852c2c66affSColin Finck     if (!NT_SUCCESS(Status))
853c2c66affSColin Finck     {
854c2c66affSColin Finck         SetLastError(LsaNtStatusToWinError(Status));
855c2c66affSColin Finck         return FALSE;
856c2c66affSColin Finck     }
857c2c66affSColin Finck 
858c2c66affSColin Finck     Status = LsaLookupPrivilegeName(PolicyHandle,
859c2c66affSColin Finck                                     lpLuid,
860c2c66affSColin Finck                                     &PrivilegeName);
861c2c66affSColin Finck     if (NT_SUCCESS(Status))
862c2c66affSColin Finck     {
863c2c66affSColin Finck         if (PrivilegeName->Length + sizeof(WCHAR) > *cchName * sizeof(WCHAR))
864c2c66affSColin Finck         {
865c2c66affSColin Finck             Status = STATUS_BUFFER_TOO_SMALL;
866c2c66affSColin Finck 
867c2c66affSColin Finck             *cchName = (PrivilegeName->Length + sizeof(WCHAR)) / sizeof(WCHAR);
868c2c66affSColin Finck         }
869c2c66affSColin Finck         else
870c2c66affSColin Finck         {
871c2c66affSColin Finck             RtlMoveMemory(lpName,
872c2c66affSColin Finck                           PrivilegeName->Buffer,
873c2c66affSColin Finck                           PrivilegeName->Length);
874c2c66affSColin Finck             lpName[PrivilegeName->Length / sizeof(WCHAR)] = 0;
875c2c66affSColin Finck 
876c2c66affSColin Finck             *cchName = PrivilegeName->Length / sizeof(WCHAR);
877c2c66affSColin Finck         }
878c2c66affSColin Finck 
879c2c66affSColin Finck         LsaFreeMemory(PrivilegeName->Buffer);
880c2c66affSColin Finck         LsaFreeMemory(PrivilegeName);
881c2c66affSColin Finck     }
882c2c66affSColin Finck 
883c2c66affSColin Finck     LsaClose(PolicyHandle);
884c2c66affSColin Finck 
885c2c66affSColin Finck     if (!NT_SUCCESS(Status))
886c2c66affSColin Finck     {
887c2c66affSColin Finck         SetLastError(LsaNtStatusToWinError(Status));
888c2c66affSColin Finck         return FALSE;
889c2c66affSColin Finck     }
890c2c66affSColin Finck 
891c2c66affSColin Finck     return TRUE;
892c2c66affSColin Finck }
893c2c66affSColin Finck 
894c2c66affSColin Finck /**********************************************************************
895c2c66affSColin Finck  * LookupPrivilegeDisplayNameW			EXPORTED
896c2c66affSColin Finck  *
897c2c66affSColin Finck  * @unimplemented
898c2c66affSColin Finck  */
899c2c66affSColin Finck BOOL
900c2c66affSColin Finck WINAPI
LookupPrivilegeDisplayNameW(LPCWSTR lpSystemName,LPCWSTR lpName,LPWSTR lpDisplayName,LPDWORD cchDisplayName,LPDWORD lpLanguageId)901c2c66affSColin Finck LookupPrivilegeDisplayNameW(LPCWSTR lpSystemName,
902c2c66affSColin Finck                             LPCWSTR lpName,
903c2c66affSColin Finck                             LPWSTR lpDisplayName,
904c2c66affSColin Finck                             LPDWORD cchDisplayName,
905c2c66affSColin Finck                             LPDWORD lpLanguageId)
906c2c66affSColin Finck {
907c2c66affSColin Finck     OBJECT_ATTRIBUTES ObjectAttributes = {0};
908c2c66affSColin Finck     UNICODE_STRING SystemName, Name;
909c2c66affSColin Finck     PUNICODE_STRING DisplayName;
910c2c66affSColin Finck     LSA_HANDLE PolicyHandle = NULL;
911c2c66affSColin Finck     USHORT LanguageId;
912c2c66affSColin Finck     NTSTATUS Status;
913c2c66affSColin Finck 
914c2c66affSColin Finck     TRACE("%S,%S,%p,%p,%p\n", lpSystemName, lpName, lpDisplayName, cchDisplayName, lpLanguageId);
915c2c66affSColin Finck 
916c2c66affSColin Finck     RtlInitUnicodeString(&SystemName, lpSystemName);
917c2c66affSColin Finck     RtlInitUnicodeString(&Name, lpName);
918c2c66affSColin Finck 
919c2c66affSColin Finck     Status = LsaOpenPolicy(lpSystemName ? &SystemName : NULL,
920c2c66affSColin Finck                            &ObjectAttributes,
921c2c66affSColin Finck                            POLICY_LOOKUP_NAMES,
922c2c66affSColin Finck                            &PolicyHandle);
923c2c66affSColin Finck     if (!NT_SUCCESS(Status))
924c2c66affSColin Finck     {
925c2c66affSColin Finck         SetLastError(LsaNtStatusToWinError(Status));
926c2c66affSColin Finck         return FALSE;
927c2c66affSColin Finck     }
928c2c66affSColin Finck 
929c2c66affSColin Finck     Status = LsaLookupPrivilegeDisplayName(PolicyHandle, &Name, &DisplayName, &LanguageId);
930c2c66affSColin Finck     if (NT_SUCCESS(Status))
931c2c66affSColin Finck     {
932c2c66affSColin Finck         *lpLanguageId = LanguageId;
933c2c66affSColin Finck         if (DisplayName->Length + sizeof(WCHAR) > *cchDisplayName * sizeof(WCHAR))
934c2c66affSColin Finck         {
935c2c66affSColin Finck             Status = STATUS_BUFFER_TOO_SMALL;
936c2c66affSColin Finck 
937c2c66affSColin Finck             *cchDisplayName = (DisplayName->Length + sizeof(WCHAR)) / sizeof(WCHAR);
938c2c66affSColin Finck         }
939c2c66affSColin Finck         else
940c2c66affSColin Finck         {
941c2c66affSColin Finck             RtlMoveMemory(lpDisplayName,
942c2c66affSColin Finck                           DisplayName->Buffer,
943c2c66affSColin Finck                           DisplayName->Length);
944c2c66affSColin Finck             lpDisplayName[DisplayName->Length / sizeof(WCHAR)] = 0;
945c2c66affSColin Finck 
946c2c66affSColin Finck             *cchDisplayName = DisplayName->Length / sizeof(WCHAR);
947c2c66affSColin Finck         }
948c2c66affSColin Finck 
949c2c66affSColin Finck         LsaFreeMemory(DisplayName->Buffer);
950c2c66affSColin Finck         LsaFreeMemory(DisplayName);
951c2c66affSColin Finck     }
952c2c66affSColin Finck 
953c2c66affSColin Finck     LsaClose(PolicyHandle);
954c2c66affSColin Finck 
955c2c66affSColin Finck     if (!NT_SUCCESS(Status))
956c2c66affSColin Finck     {
957c2c66affSColin Finck         SetLastError(LsaNtStatusToWinError(Status));
958c2c66affSColin Finck         return FALSE;
959c2c66affSColin Finck     }
960c2c66affSColin Finck 
961c2c66affSColin Finck     return TRUE;
962c2c66affSColin Finck }
963c2c66affSColin Finck 
964c2c66affSColin Finck static DWORD
pGetSecurityInfoCheck(SECURITY_INFORMATION SecurityInfo,PSID * ppsidOwner,PSID * ppsidGroup,PACL * ppDacl,PACL * ppSacl,PSECURITY_DESCRIPTOR * ppSecurityDescriptor)965c2c66affSColin Finck pGetSecurityInfoCheck(SECURITY_INFORMATION SecurityInfo,
966c2c66affSColin Finck                       PSID *ppsidOwner,
967c2c66affSColin Finck                       PSID *ppsidGroup,
968c2c66affSColin Finck                       PACL *ppDacl,
969c2c66affSColin Finck                       PACL *ppSacl,
970c2c66affSColin Finck                       PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
971c2c66affSColin Finck {
972c2c66affSColin Finck     if ((SecurityInfo & (OWNER_SECURITY_INFORMATION |
973c2c66affSColin Finck                          GROUP_SECURITY_INFORMATION |
974c2c66affSColin Finck                          DACL_SECURITY_INFORMATION |
975c2c66affSColin Finck                          SACL_SECURITY_INFORMATION)) &&
976c2c66affSColin Finck         ppSecurityDescriptor == NULL)
977c2c66affSColin Finck     {
978c2c66affSColin Finck         /* if one of the SIDs or ACLs are present, the security descriptor
979c2c66affSColin Finck            most not be NULL */
980c2c66affSColin Finck         return ERROR_INVALID_PARAMETER;
981c2c66affSColin Finck     }
982c2c66affSColin Finck     else
983c2c66affSColin Finck     {
984c2c66affSColin Finck         /* reset the pointers unless they're ignored */
985c2c66affSColin Finck         if ((SecurityInfo & OWNER_SECURITY_INFORMATION) &&
986c2c66affSColin Finck             ppsidOwner != NULL)
987c2c66affSColin Finck         {
988c2c66affSColin Finck             *ppsidOwner = NULL;
989c2c66affSColin Finck         }
990c2c66affSColin Finck         if ((SecurityInfo & GROUP_SECURITY_INFORMATION) &&
991c2c66affSColin Finck             ppsidGroup != NULL)
992c2c66affSColin Finck         {
993c2c66affSColin Finck             *ppsidGroup = NULL;
994c2c66affSColin Finck         }
995c2c66affSColin Finck         if ((SecurityInfo & DACL_SECURITY_INFORMATION) &&
996c2c66affSColin Finck             ppDacl != NULL)
997c2c66affSColin Finck         {
998c2c66affSColin Finck             *ppDacl = NULL;
999c2c66affSColin Finck         }
1000c2c66affSColin Finck         if ((SecurityInfo & SACL_SECURITY_INFORMATION) &&
1001c2c66affSColin Finck             ppSacl != NULL)
1002c2c66affSColin Finck         {
1003c2c66affSColin Finck             *ppSacl = NULL;
1004c2c66affSColin Finck         }
1005c2c66affSColin Finck 
1006c2c66affSColin Finck         if (SecurityInfo & (OWNER_SECURITY_INFORMATION |
1007c2c66affSColin Finck                             GROUP_SECURITY_INFORMATION |
1008c2c66affSColin Finck                             DACL_SECURITY_INFORMATION |
1009c2c66affSColin Finck                             SACL_SECURITY_INFORMATION))
1010c2c66affSColin Finck         {
1011c2c66affSColin Finck             *ppSecurityDescriptor = NULL;
1012c2c66affSColin Finck         }
1013c2c66affSColin Finck 
1014c2c66affSColin Finck         return ERROR_SUCCESS;
1015c2c66affSColin Finck     }
1016c2c66affSColin Finck }
1017c2c66affSColin Finck 
1018c2c66affSColin Finck 
1019c2c66affSColin Finck static DWORD
pSetSecurityInfoCheck(PSECURITY_DESCRIPTOR pSecurityDescriptor,SECURITY_INFORMATION SecurityInfo,PSID psidOwner,PSID psidGroup,PACL pDacl,PACL pSacl)1020c2c66affSColin Finck pSetSecurityInfoCheck(PSECURITY_DESCRIPTOR pSecurityDescriptor,
1021c2c66affSColin Finck                       SECURITY_INFORMATION SecurityInfo,
1022c2c66affSColin Finck                       PSID psidOwner,
1023c2c66affSColin Finck                       PSID psidGroup,
1024c2c66affSColin Finck                       PACL pDacl,
1025c2c66affSColin Finck                       PACL pSacl)
1026c2c66affSColin Finck {
1027c2c66affSColin Finck     /* initialize a security descriptor on the stack */
1028c2c66affSColin Finck     if (!InitializeSecurityDescriptor(pSecurityDescriptor,
1029c2c66affSColin Finck                                       SECURITY_DESCRIPTOR_REVISION))
1030c2c66affSColin Finck     {
1031c2c66affSColin Finck         return GetLastError();
1032c2c66affSColin Finck     }
1033c2c66affSColin Finck 
1034c2c66affSColin Finck     if (SecurityInfo & OWNER_SECURITY_INFORMATION)
1035c2c66affSColin Finck     {
1036c2c66affSColin Finck         if (RtlValidSid(psidOwner))
1037c2c66affSColin Finck         {
1038c2c66affSColin Finck             if (!SetSecurityDescriptorOwner(pSecurityDescriptor,
1039c2c66affSColin Finck                                             psidOwner,
1040c2c66affSColin Finck                                             FALSE))
1041c2c66affSColin Finck             {
1042c2c66affSColin Finck                 return GetLastError();
1043c2c66affSColin Finck             }
1044c2c66affSColin Finck         }
1045c2c66affSColin Finck         else
1046c2c66affSColin Finck         {
1047c2c66affSColin Finck             return ERROR_INVALID_PARAMETER;
1048c2c66affSColin Finck         }
1049c2c66affSColin Finck     }
1050c2c66affSColin Finck 
1051c2c66affSColin Finck     if (SecurityInfo & GROUP_SECURITY_INFORMATION)
1052c2c66affSColin Finck     {
1053c2c66affSColin Finck         if (RtlValidSid(psidGroup))
1054c2c66affSColin Finck         {
1055c2c66affSColin Finck             if (!SetSecurityDescriptorGroup(pSecurityDescriptor,
1056c2c66affSColin Finck                                             psidGroup,
1057c2c66affSColin Finck                                             FALSE))
1058c2c66affSColin Finck             {
1059c2c66affSColin Finck                 return GetLastError();
1060c2c66affSColin Finck             }
1061c2c66affSColin Finck         }
1062c2c66affSColin Finck         else
1063c2c66affSColin Finck         {
1064c2c66affSColin Finck             return ERROR_INVALID_PARAMETER;
1065c2c66affSColin Finck         }
1066c2c66affSColin Finck     }
1067c2c66affSColin Finck 
1068c2c66affSColin Finck     if (SecurityInfo & DACL_SECURITY_INFORMATION)
1069c2c66affSColin Finck     {
1070c2c66affSColin Finck         if (pDacl != NULL)
1071c2c66affSColin Finck         {
1072c2c66affSColin Finck             if (SetSecurityDescriptorDacl(pSecurityDescriptor,
1073c2c66affSColin Finck                                           TRUE,
1074c2c66affSColin Finck                                           pDacl,
1075c2c66affSColin Finck                                           FALSE))
1076c2c66affSColin Finck             {
1077c2c66affSColin Finck                 /* check if the DACL needs to be protected from being
1078c2c66affSColin Finck                    modified by inheritable ACEs */
1079c2c66affSColin Finck                 if (SecurityInfo & PROTECTED_DACL_SECURITY_INFORMATION)
1080c2c66affSColin Finck                 {
1081c2c66affSColin Finck                     goto ProtectDacl;
1082c2c66affSColin Finck                 }
1083c2c66affSColin Finck             }
1084c2c66affSColin Finck             else
1085c2c66affSColin Finck             {
1086c2c66affSColin Finck                 return GetLastError();
1087c2c66affSColin Finck             }
1088c2c66affSColin Finck         }
1089c2c66affSColin Finck         else
1090c2c66affSColin Finck         {
1091c2c66affSColin Finck ProtectDacl:
1092c2c66affSColin Finck             /* protect the DACL from being modified by inheritable ACEs */
1093c2c66affSColin Finck             if (!SetSecurityDescriptorControl(pSecurityDescriptor,
1094c2c66affSColin Finck                                               SE_DACL_PROTECTED,
1095c2c66affSColin Finck                                               SE_DACL_PROTECTED))
1096c2c66affSColin Finck             {
1097c2c66affSColin Finck                 return GetLastError();
1098c2c66affSColin Finck             }
1099c2c66affSColin Finck         }
1100c2c66affSColin Finck     }
1101c2c66affSColin Finck 
1102c2c66affSColin Finck     if (SecurityInfo & SACL_SECURITY_INFORMATION)
1103c2c66affSColin Finck     {
1104c2c66affSColin Finck         if (pSacl != NULL)
1105c2c66affSColin Finck         {
1106c2c66affSColin Finck             if (SetSecurityDescriptorSacl(pSecurityDescriptor,
1107c2c66affSColin Finck                                           TRUE,
1108c2c66affSColin Finck                                           pSacl,
1109c2c66affSColin Finck                                           FALSE))
1110c2c66affSColin Finck             {
1111c2c66affSColin Finck                 /* check if the SACL needs to be protected from being
1112c2c66affSColin Finck                    modified by inheritable ACEs */
1113c2c66affSColin Finck                 if (SecurityInfo & PROTECTED_SACL_SECURITY_INFORMATION)
1114c2c66affSColin Finck                 {
1115c2c66affSColin Finck                     goto ProtectSacl;
1116c2c66affSColin Finck                 }
1117c2c66affSColin Finck             }
1118c2c66affSColin Finck             else
1119c2c66affSColin Finck             {
1120c2c66affSColin Finck                 return GetLastError();
1121c2c66affSColin Finck             }
1122c2c66affSColin Finck         }
1123c2c66affSColin Finck         else
1124c2c66affSColin Finck         {
1125c2c66affSColin Finck ProtectSacl:
1126c2c66affSColin Finck             /* protect the SACL from being modified by inheritable ACEs */
1127c2c66affSColin Finck             if (!SetSecurityDescriptorControl(pSecurityDescriptor,
1128c2c66affSColin Finck                                               SE_SACL_PROTECTED,
1129c2c66affSColin Finck                                               SE_SACL_PROTECTED))
1130c2c66affSColin Finck             {
1131c2c66affSColin Finck                 return GetLastError();
1132c2c66affSColin Finck             }
1133c2c66affSColin Finck         }
1134c2c66affSColin Finck     }
1135c2c66affSColin Finck 
1136c2c66affSColin Finck     return ERROR_SUCCESS;
1137c2c66affSColin Finck }
1138c2c66affSColin Finck 
1139c2c66affSColin Finck 
1140c2c66affSColin Finck /**********************************************************************
1141c2c66affSColin Finck  * GetNamedSecurityInfoW			EXPORTED
1142c2c66affSColin Finck  *
1143c2c66affSColin Finck  * @implemented
1144c2c66affSColin Finck  */
1145c2c66affSColin Finck DWORD
1146c2c66affSColin Finck WINAPI
GetNamedSecurityInfoW(LPWSTR pObjectName,SE_OBJECT_TYPE ObjectType,SECURITY_INFORMATION SecurityInfo,PSID * ppsidOwner,PSID * ppsidGroup,PACL * ppDacl,PACL * ppSacl,PSECURITY_DESCRIPTOR * ppSecurityDescriptor)1147c2c66affSColin Finck GetNamedSecurityInfoW(LPWSTR pObjectName,
1148c2c66affSColin Finck                       SE_OBJECT_TYPE ObjectType,
1149c2c66affSColin Finck                       SECURITY_INFORMATION SecurityInfo,
1150c2c66affSColin Finck                       PSID *ppsidOwner,
1151c2c66affSColin Finck                       PSID *ppsidGroup,
1152c2c66affSColin Finck                       PACL *ppDacl,
1153c2c66affSColin Finck                       PACL *ppSacl,
1154c2c66affSColin Finck                       PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
1155c2c66affSColin Finck {
1156c2c66affSColin Finck     DWORD ErrorCode;
1157c2c66affSColin Finck 
1158c2c66affSColin Finck     if (pObjectName != NULL)
1159c2c66affSColin Finck     {
1160c2c66affSColin Finck         ErrorCode = CheckNtMartaPresent();
1161c2c66affSColin Finck         if (ErrorCode == ERROR_SUCCESS)
1162c2c66affSColin Finck         {
1163c2c66affSColin Finck             ErrorCode = pGetSecurityInfoCheck(SecurityInfo,
1164c2c66affSColin Finck                                               ppsidOwner,
1165c2c66affSColin Finck                                               ppsidGroup,
1166c2c66affSColin Finck                                               ppDacl,
1167c2c66affSColin Finck                                               ppSacl,
1168c2c66affSColin Finck                                               ppSecurityDescriptor);
1169c2c66affSColin Finck 
1170c2c66affSColin Finck             if (ErrorCode == ERROR_SUCCESS)
1171c2c66affSColin Finck             {
1172c2c66affSColin Finck                 /* call the MARTA provider */
1173c2c66affSColin Finck                 ErrorCode = AccRewriteGetNamedRights(pObjectName,
1174c2c66affSColin Finck                                                      ObjectType,
1175c2c66affSColin Finck                                                      SecurityInfo,
1176c2c66affSColin Finck                                                      ppsidOwner,
1177c2c66affSColin Finck                                                      ppsidGroup,
1178c2c66affSColin Finck                                                      ppDacl,
1179c2c66affSColin Finck                                                      ppSacl,
1180c2c66affSColin Finck                                                      ppSecurityDescriptor);
1181c2c66affSColin Finck             }
1182c2c66affSColin Finck         }
1183c2c66affSColin Finck     }
1184c2c66affSColin Finck     else
1185c2c66affSColin Finck         ErrorCode = ERROR_INVALID_PARAMETER;
1186c2c66affSColin Finck 
1187c2c66affSColin Finck     return ErrorCode;
1188c2c66affSColin Finck }
1189c2c66affSColin Finck 
1190c2c66affSColin Finck /**********************************************************************
1191c2c66affSColin Finck  * SetNamedSecurityInfoW			EXPORTED
1192c2c66affSColin Finck  *
1193c2c66affSColin Finck  * @implemented
1194c2c66affSColin Finck  */
1195c2c66affSColin Finck DWORD
1196c2c66affSColin Finck WINAPI
SetNamedSecurityInfoW(LPWSTR pObjectName,SE_OBJECT_TYPE ObjectType,SECURITY_INFORMATION SecurityInfo,PSID psidOwner,PSID psidGroup,PACL pDacl,PACL pSacl)1197c2c66affSColin Finck SetNamedSecurityInfoW(LPWSTR pObjectName,
1198c2c66affSColin Finck                       SE_OBJECT_TYPE ObjectType,
1199c2c66affSColin Finck                       SECURITY_INFORMATION SecurityInfo,
1200c2c66affSColin Finck                       PSID psidOwner,
1201c2c66affSColin Finck                       PSID psidGroup,
1202c2c66affSColin Finck                       PACL pDacl,
1203c2c66affSColin Finck                       PACL pSacl)
1204c2c66affSColin Finck {
1205c2c66affSColin Finck     DWORD ErrorCode;
1206c2c66affSColin Finck 
1207c2c66affSColin Finck     if (pObjectName != NULL)
1208c2c66affSColin Finck     {
1209c2c66affSColin Finck         ErrorCode = CheckNtMartaPresent();
1210c2c66affSColin Finck         if (ErrorCode == ERROR_SUCCESS)
1211c2c66affSColin Finck         {
1212c2c66affSColin Finck             SECURITY_DESCRIPTOR SecurityDescriptor;
1213c2c66affSColin Finck 
1214c2c66affSColin Finck             ErrorCode = pSetSecurityInfoCheck(&SecurityDescriptor,
1215c2c66affSColin Finck                                               SecurityInfo,
1216c2c66affSColin Finck                                               psidOwner,
1217c2c66affSColin Finck                                               psidGroup,
1218c2c66affSColin Finck                                               pDacl,
1219c2c66affSColin Finck                                               pSacl);
1220c2c66affSColin Finck 
1221c2c66affSColin Finck             if (ErrorCode == ERROR_SUCCESS)
1222c2c66affSColin Finck             {
1223c2c66affSColin Finck                 /* call the MARTA provider */
1224c2c66affSColin Finck                 ErrorCode = AccRewriteSetNamedRights(pObjectName,
1225c2c66affSColin Finck                                                      ObjectType,
1226c2c66affSColin Finck                                                      SecurityInfo,
1227c2c66affSColin Finck                                                      &SecurityDescriptor);
1228c2c66affSColin Finck             }
1229c2c66affSColin Finck         }
1230c2c66affSColin Finck     }
1231c2c66affSColin Finck     else
1232c2c66affSColin Finck         ErrorCode = ERROR_INVALID_PARAMETER;
1233c2c66affSColin Finck 
1234c2c66affSColin Finck     return ErrorCode;
1235c2c66affSColin Finck }
1236c2c66affSColin Finck 
1237c2c66affSColin Finck /**********************************************************************
1238c2c66affSColin Finck  * GetSecurityInfo				EXPORTED
1239c2c66affSColin Finck  *
1240c2c66affSColin Finck  * @implemented
1241c2c66affSColin Finck  */
1242c2c66affSColin Finck DWORD
1243c2c66affSColin Finck WINAPI
GetSecurityInfo(HANDLE handle,SE_OBJECT_TYPE ObjectType,SECURITY_INFORMATION SecurityInfo,PSID * ppsidOwner,PSID * ppsidGroup,PACL * ppDacl,PACL * ppSacl,PSECURITY_DESCRIPTOR * ppSecurityDescriptor)1244c2c66affSColin Finck GetSecurityInfo(HANDLE handle,
1245c2c66affSColin Finck                 SE_OBJECT_TYPE ObjectType,
1246c2c66affSColin Finck                 SECURITY_INFORMATION SecurityInfo,
1247c2c66affSColin Finck                 PSID *ppsidOwner,
1248c2c66affSColin Finck                 PSID *ppsidGroup,
1249c2c66affSColin Finck                 PACL *ppDacl,
1250c2c66affSColin Finck                 PACL *ppSacl,
1251c2c66affSColin Finck                 PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
1252c2c66affSColin Finck {
1253c2c66affSColin Finck     DWORD ErrorCode;
1254c2c66affSColin Finck 
1255c2c66affSColin Finck     if (handle != NULL)
1256c2c66affSColin Finck     {
1257c2c66affSColin Finck         ErrorCode = CheckNtMartaPresent();
1258c2c66affSColin Finck         if (ErrorCode == ERROR_SUCCESS)
1259c2c66affSColin Finck         {
1260c2c66affSColin Finck             ErrorCode = pGetSecurityInfoCheck(SecurityInfo,
1261c2c66affSColin Finck                                               ppsidOwner,
1262c2c66affSColin Finck                                               ppsidGroup,
1263c2c66affSColin Finck                                               ppDacl,
1264c2c66affSColin Finck                                               ppSacl,
1265c2c66affSColin Finck                                               ppSecurityDescriptor);
1266c2c66affSColin Finck 
1267c2c66affSColin Finck             if (ErrorCode == ERROR_SUCCESS)
1268c2c66affSColin Finck             {
1269c2c66affSColin Finck                 /* call the MARTA provider */
1270c2c66affSColin Finck                 ErrorCode = AccRewriteGetHandleRights(handle,
1271c2c66affSColin Finck                                                       ObjectType,
1272c2c66affSColin Finck                                                       SecurityInfo,
1273c2c66affSColin Finck                                                       ppsidOwner,
1274c2c66affSColin Finck                                                       ppsidGroup,
1275c2c66affSColin Finck                                                       ppDacl,
1276c2c66affSColin Finck                                                       ppSacl,
1277c2c66affSColin Finck                                                       ppSecurityDescriptor);
1278c2c66affSColin Finck             }
1279c2c66affSColin Finck         }
1280c2c66affSColin Finck     }
1281c2c66affSColin Finck     else
1282c2c66affSColin Finck         ErrorCode = ERROR_INVALID_HANDLE;
1283c2c66affSColin Finck 
1284c2c66affSColin Finck     return ErrorCode;
1285c2c66affSColin Finck }
1286c2c66affSColin Finck 
1287c2c66affSColin Finck 
1288c2c66affSColin Finck /**********************************************************************
1289c2c66affSColin Finck  * SetSecurityInfo				EXPORTED
1290c2c66affSColin Finck  *
1291c2c66affSColin Finck  * @implemented
1292c2c66affSColin Finck  */
1293c2c66affSColin Finck DWORD
1294c2c66affSColin Finck WINAPI
SetSecurityInfo(HANDLE handle,SE_OBJECT_TYPE ObjectType,SECURITY_INFORMATION SecurityInfo,PSID psidOwner,PSID psidGroup,PACL pDacl,PACL pSacl)1295c2c66affSColin Finck SetSecurityInfo(HANDLE handle,
1296c2c66affSColin Finck                 SE_OBJECT_TYPE ObjectType,
1297c2c66affSColin Finck                 SECURITY_INFORMATION SecurityInfo,
1298c2c66affSColin Finck                 PSID psidOwner,
1299c2c66affSColin Finck                 PSID psidGroup,
1300c2c66affSColin Finck                 PACL pDacl,
1301c2c66affSColin Finck                 PACL pSacl)
1302c2c66affSColin Finck {
1303c2c66affSColin Finck     DWORD ErrorCode;
1304c2c66affSColin Finck 
1305c2c66affSColin Finck     if (handle != NULL)
1306c2c66affSColin Finck     {
1307c2c66affSColin Finck         ErrorCode = CheckNtMartaPresent();
1308c2c66affSColin Finck         if (ErrorCode == ERROR_SUCCESS)
1309c2c66affSColin Finck         {
1310c2c66affSColin Finck             SECURITY_DESCRIPTOR SecurityDescriptor;
1311c2c66affSColin Finck 
1312c2c66affSColin Finck             ErrorCode = pSetSecurityInfoCheck(&SecurityDescriptor,
1313c2c66affSColin Finck                                               SecurityInfo,
1314c2c66affSColin Finck                                               psidOwner,
1315c2c66affSColin Finck                                               psidGroup,
1316c2c66affSColin Finck                                               pDacl,
1317c2c66affSColin Finck                                               pSacl);
1318c2c66affSColin Finck 
1319c2c66affSColin Finck             if (ErrorCode == ERROR_SUCCESS)
1320c2c66affSColin Finck             {
1321c2c66affSColin Finck                 /* call the MARTA provider */
1322c2c66affSColin Finck                 ErrorCode = AccRewriteSetHandleRights(handle,
1323c2c66affSColin Finck                                                       ObjectType,
1324c2c66affSColin Finck                                                       SecurityInfo,
1325c2c66affSColin Finck                                                       &SecurityDescriptor);
1326c2c66affSColin Finck             }
1327c2c66affSColin Finck         }
1328c2c66affSColin Finck     }
1329c2c66affSColin Finck     else
1330c2c66affSColin Finck         ErrorCode = ERROR_INVALID_HANDLE;
1331c2c66affSColin Finck 
1332c2c66affSColin Finck     return ErrorCode;
1333c2c66affSColin Finck }
1334c2c66affSColin Finck 
1335c2c66affSColin Finck /*
1336c2c66affSColin Finck  * @implemented
1337c2c66affSColin Finck  */
1338c2c66affSColin Finck BOOL
1339c2c66affSColin Finck WINAPI
CreatePrivateObjectSecurity(PSECURITY_DESCRIPTOR ParentDescriptor,PSECURITY_DESCRIPTOR CreatorDescriptor,PSECURITY_DESCRIPTOR * NewDescriptor,BOOL IsDirectoryObject,HANDLE Token,PGENERIC_MAPPING GenericMapping)1340c2c66affSColin Finck CreatePrivateObjectSecurity(PSECURITY_DESCRIPTOR ParentDescriptor,
1341c2c66affSColin Finck                             PSECURITY_DESCRIPTOR CreatorDescriptor,
1342c2c66affSColin Finck                             PSECURITY_DESCRIPTOR *NewDescriptor,
1343c2c66affSColin Finck                             BOOL IsDirectoryObject,
1344c2c66affSColin Finck                             HANDLE Token,
1345c2c66affSColin Finck                             PGENERIC_MAPPING GenericMapping)
1346c2c66affSColin Finck {
1347c2c66affSColin Finck     NTSTATUS Status;
1348c2c66affSColin Finck 
1349c2c66affSColin Finck     Status = RtlNewSecurityObject(ParentDescriptor,
1350c2c66affSColin Finck                                   CreatorDescriptor,
1351c2c66affSColin Finck                                   NewDescriptor,
1352c2c66affSColin Finck                                   IsDirectoryObject,
1353c2c66affSColin Finck                                   Token,
1354c2c66affSColin Finck                                   GenericMapping);
1355c2c66affSColin Finck     if (!NT_SUCCESS(Status))
1356c2c66affSColin Finck     {
1357c2c66affSColin Finck         SetLastError(RtlNtStatusToDosError(Status));
1358c2c66affSColin Finck         return FALSE;
1359c2c66affSColin Finck     }
1360c2c66affSColin Finck 
1361c2c66affSColin Finck     return TRUE;
1362c2c66affSColin Finck }
1363c2c66affSColin Finck 
1364c2c66affSColin Finck 
1365c2c66affSColin Finck /*
1366c2c66affSColin Finck  * @unimplemented
1367c2c66affSColin Finck  */
1368c2c66affSColin Finck BOOL
1369c2c66affSColin Finck WINAPI
CreatePrivateObjectSecurityEx(PSECURITY_DESCRIPTOR ParentDescriptor,PSECURITY_DESCRIPTOR CreatorDescriptor,PSECURITY_DESCRIPTOR * NewDescriptor,GUID * ObjectType,BOOL IsContainerObject,ULONG AutoInheritFlags,HANDLE Token,PGENERIC_MAPPING GenericMapping)1370c2c66affSColin Finck CreatePrivateObjectSecurityEx(PSECURITY_DESCRIPTOR ParentDescriptor,
1371c2c66affSColin Finck                               PSECURITY_DESCRIPTOR CreatorDescriptor,
1372c2c66affSColin Finck                               PSECURITY_DESCRIPTOR* NewDescriptor,
1373c2c66affSColin Finck                               GUID* ObjectType,
1374c2c66affSColin Finck                               BOOL IsContainerObject,
1375c2c66affSColin Finck                               ULONG AutoInheritFlags,
1376c2c66affSColin Finck                               HANDLE Token,
1377c2c66affSColin Finck                               PGENERIC_MAPPING GenericMapping)
1378c2c66affSColin Finck {
1379c2c66affSColin Finck     FIXME("%s() not implemented!\n", __FUNCTION__);
1380c2c66affSColin Finck     return FALSE;
1381c2c66affSColin Finck }
1382c2c66affSColin Finck 
1383c2c66affSColin Finck 
1384c2c66affSColin Finck /*
1385c2c66affSColin Finck  * @unimplemented
1386c2c66affSColin Finck  */
1387c2c66affSColin Finck BOOL
1388c2c66affSColin Finck WINAPI
CreatePrivateObjectSecurityWithMultipleInheritance(PSECURITY_DESCRIPTOR ParentDescriptor,PSECURITY_DESCRIPTOR CreatorDescriptor,PSECURITY_DESCRIPTOR * NewDescriptor,GUID ** ObjectTypes,ULONG GuidCount,BOOL IsContainerObject,ULONG AutoInheritFlags,HANDLE Token,PGENERIC_MAPPING GenericMapping)1389c2c66affSColin Finck CreatePrivateObjectSecurityWithMultipleInheritance(PSECURITY_DESCRIPTOR ParentDescriptor,
1390c2c66affSColin Finck                                                    PSECURITY_DESCRIPTOR CreatorDescriptor,
1391c2c66affSColin Finck                                                    PSECURITY_DESCRIPTOR* NewDescriptor,
1392c2c66affSColin Finck                                                    GUID** ObjectTypes,
1393c2c66affSColin Finck                                                    ULONG GuidCount,
1394c2c66affSColin Finck                                                    BOOL IsContainerObject,
1395c2c66affSColin Finck                                                    ULONG AutoInheritFlags,
1396c2c66affSColin Finck                                                    HANDLE Token,
1397c2c66affSColin Finck                                                    PGENERIC_MAPPING GenericMapping)
1398c2c66affSColin Finck {
1399c2c66affSColin Finck     FIXME("%s() semi-stub\n", __FUNCTION__);
1400c2c66affSColin Finck     return CreatePrivateObjectSecurity(ParentDescriptor, CreatorDescriptor, NewDescriptor, IsContainerObject, Token, GenericMapping);
1401c2c66affSColin Finck }
1402c2c66affSColin Finck 
1403c2c66affSColin Finck 
1404c2c66affSColin Finck /*
1405c2c66affSColin Finck  * @implemented
1406c2c66affSColin Finck  */
1407c2c66affSColin Finck BOOL
1408c2c66affSColin Finck WINAPI
DestroyPrivateObjectSecurity(PSECURITY_DESCRIPTOR * ObjectDescriptor)1409c2c66affSColin Finck DestroyPrivateObjectSecurity(PSECURITY_DESCRIPTOR *ObjectDescriptor)
1410c2c66affSColin Finck {
1411c2c66affSColin Finck     NTSTATUS Status;
1412c2c66affSColin Finck 
1413c2c66affSColin Finck     Status = RtlDeleteSecurityObject(ObjectDescriptor);
1414c2c66affSColin Finck     if (!NT_SUCCESS(Status))
1415c2c66affSColin Finck     {
1416c2c66affSColin Finck         SetLastError(RtlNtStatusToDosError(Status));
1417c2c66affSColin Finck         return FALSE;
1418c2c66affSColin Finck     }
1419c2c66affSColin Finck 
1420c2c66affSColin Finck     return TRUE;
1421c2c66affSColin Finck }
1422c2c66affSColin Finck 
1423c2c66affSColin Finck 
1424c2c66affSColin Finck /*
1425c2c66affSColin Finck  * @implemented
1426c2c66affSColin Finck  */
1427c2c66affSColin Finck BOOL
1428c2c66affSColin Finck WINAPI
GetPrivateObjectSecurity(IN PSECURITY_DESCRIPTOR ObjectDescriptor,IN SECURITY_INFORMATION SecurityInformation,OUT PSECURITY_DESCRIPTOR ResultantDescriptor OPTIONAL,IN DWORD DescriptorLength,OUT PDWORD ReturnLength)1429c2c66affSColin Finck GetPrivateObjectSecurity(IN PSECURITY_DESCRIPTOR ObjectDescriptor,
1430c2c66affSColin Finck                          IN SECURITY_INFORMATION SecurityInformation,
1431c2c66affSColin Finck                          OUT PSECURITY_DESCRIPTOR ResultantDescriptor OPTIONAL,
1432c2c66affSColin Finck                          IN DWORD DescriptorLength,
1433c2c66affSColin Finck                          OUT PDWORD ReturnLength)
1434c2c66affSColin Finck {
1435c2c66affSColin Finck     NTSTATUS Status;
1436c2c66affSColin Finck 
1437c2c66affSColin Finck     /* Call RTL */
1438c2c66affSColin Finck     Status = RtlQuerySecurityObject(ObjectDescriptor,
1439c2c66affSColin Finck                                     SecurityInformation,
1440c2c66affSColin Finck                                     ResultantDescriptor,
1441c2c66affSColin Finck                                     DescriptorLength,
1442c2c66affSColin Finck                                     ReturnLength);
1443c2c66affSColin Finck     if (!NT_SUCCESS(Status))
1444c2c66affSColin Finck     {
1445c2c66affSColin Finck         /* Fail */
1446c2c66affSColin Finck         SetLastError(RtlNtStatusToDosError(Status));
1447c2c66affSColin Finck         return FALSE;
1448c2c66affSColin Finck     }
1449c2c66affSColin Finck 
1450c2c66affSColin Finck     /* Success */
1451c2c66affSColin Finck     return TRUE;
1452c2c66affSColin Finck }
1453c2c66affSColin Finck 
1454c2c66affSColin Finck 
1455c2c66affSColin Finck /*
1456c2c66affSColin Finck  * @implemented
1457c2c66affSColin Finck  */
1458c2c66affSColin Finck BOOL
1459c2c66affSColin Finck WINAPI
SetPrivateObjectSecurity(SECURITY_INFORMATION SecurityInformation,PSECURITY_DESCRIPTOR ModificationDescriptor,PSECURITY_DESCRIPTOR * ObjectsSecurityDescriptor,PGENERIC_MAPPING GenericMapping,HANDLE Token)1460c2c66affSColin Finck SetPrivateObjectSecurity(SECURITY_INFORMATION SecurityInformation,
1461c2c66affSColin Finck                          PSECURITY_DESCRIPTOR ModificationDescriptor,
1462c2c66affSColin Finck                          PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
1463c2c66affSColin Finck                          PGENERIC_MAPPING GenericMapping,
1464c2c66affSColin Finck                          HANDLE Token)
1465c2c66affSColin Finck {
1466c2c66affSColin Finck     NTSTATUS Status;
1467c2c66affSColin Finck 
1468c2c66affSColin Finck     Status = RtlSetSecurityObject(SecurityInformation,
1469c2c66affSColin Finck                                   ModificationDescriptor,
1470c2c66affSColin Finck                                   ObjectsSecurityDescriptor,
1471c2c66affSColin Finck                                   GenericMapping,
1472c2c66affSColin Finck                                   Token);
1473c2c66affSColin Finck     if (!NT_SUCCESS(Status))
1474c2c66affSColin Finck     {
1475c2c66affSColin Finck         SetLastError(RtlNtStatusToDosError(Status));
1476c2c66affSColin Finck         return FALSE;
1477c2c66affSColin Finck     }
1478c2c66affSColin Finck 
1479c2c66affSColin Finck     return TRUE;
1480c2c66affSColin Finck }
1481c2c66affSColin Finck 
1482c2c66affSColin Finck 
1483c2c66affSColin Finck /*
1484c2c66affSColin Finck  * @implemented
1485c2c66affSColin Finck  */
1486c2c66affSColin Finck DWORD
1487c2c66affSColin Finck WINAPI
TreeResetNamedSecurityInfoW(LPWSTR pObjectName,SE_OBJECT_TYPE ObjectType,SECURITY_INFORMATION SecurityInfo,PSID pOwner,PSID pGroup,PACL pDacl,PACL pSacl,BOOL KeepExplicit,FN_PROGRESSW fnProgress,PROG_INVOKE_SETTING ProgressInvokeSetting,PVOID Args)1488c2c66affSColin Finck TreeResetNamedSecurityInfoW(LPWSTR pObjectName,
1489c2c66affSColin Finck                             SE_OBJECT_TYPE ObjectType,
1490c2c66affSColin Finck                             SECURITY_INFORMATION SecurityInfo,
1491c2c66affSColin Finck                             PSID pOwner,
1492c2c66affSColin Finck                             PSID pGroup,
1493c2c66affSColin Finck                             PACL pDacl,
1494c2c66affSColin Finck                             PACL pSacl,
1495c2c66affSColin Finck                             BOOL KeepExplicit,
1496c2c66affSColin Finck                             FN_PROGRESSW fnProgress,
1497c2c66affSColin Finck                             PROG_INVOKE_SETTING ProgressInvokeSetting,
1498c2c66affSColin Finck                             PVOID Args)
1499c2c66affSColin Finck {
1500c2c66affSColin Finck     DWORD ErrorCode;
1501c2c66affSColin Finck 
1502c2c66affSColin Finck     if (pObjectName != NULL)
1503c2c66affSColin Finck     {
1504c2c66affSColin Finck         ErrorCode = CheckNtMartaPresent();
1505c2c66affSColin Finck         if (ErrorCode == ERROR_SUCCESS)
1506c2c66affSColin Finck         {
1507c2c66affSColin Finck             switch (ObjectType)
1508c2c66affSColin Finck             {
1509c2c66affSColin Finck                 case SE_FILE_OBJECT:
1510c2c66affSColin Finck                 case SE_REGISTRY_KEY:
1511c2c66affSColin Finck                 {
1512c2c66affSColin Finck                     /* check the SecurityInfo flags for sanity (both, the protected
1513c2c66affSColin Finck                        and unprotected dacl/sacl flag must not be passed together) */
1514c2c66affSColin Finck                     if (((SecurityInfo & DACL_SECURITY_INFORMATION) &&
1515c2c66affSColin Finck                          (SecurityInfo & (PROTECTED_DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION)) ==
1516c2c66affSColin Finck                              (PROTECTED_DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION))
1517c2c66affSColin Finck 
1518c2c66affSColin Finck                         ||
1519c2c66affSColin Finck 
1520c2c66affSColin Finck                         ((SecurityInfo & SACL_SECURITY_INFORMATION) &&
1521c2c66affSColin Finck                          (SecurityInfo & (PROTECTED_SACL_SECURITY_INFORMATION | UNPROTECTED_SACL_SECURITY_INFORMATION)) ==
1522c2c66affSColin Finck                              (PROTECTED_SACL_SECURITY_INFORMATION | UNPROTECTED_SACL_SECURITY_INFORMATION)))
1523c2c66affSColin Finck                     {
1524c2c66affSColin Finck                         ErrorCode = ERROR_INVALID_PARAMETER;
1525c2c66affSColin Finck                         break;
1526c2c66affSColin Finck                     }
1527c2c66affSColin Finck 
1528c2c66affSColin Finck                     /* call the MARTA provider */
1529c2c66affSColin Finck                     ErrorCode = AccTreeResetNamedSecurityInfo(pObjectName,
1530c2c66affSColin Finck                                                               ObjectType,
1531c2c66affSColin Finck                                                               SecurityInfo,
1532c2c66affSColin Finck                                                               pOwner,
1533c2c66affSColin Finck                                                               pGroup,
1534c2c66affSColin Finck                                                               pDacl,
1535c2c66affSColin Finck                                                               pSacl,
1536c2c66affSColin Finck                                                               KeepExplicit,
1537c2c66affSColin Finck                                                               fnProgress,
1538c2c66affSColin Finck                                                               ProgressInvokeSetting,
1539c2c66affSColin Finck                                                               Args);
1540c2c66affSColin Finck                     break;
1541c2c66affSColin Finck                 }
1542c2c66affSColin Finck 
1543c2c66affSColin Finck                 default:
1544c2c66affSColin Finck                     /* object type not supported */
1545c2c66affSColin Finck                     ErrorCode = ERROR_INVALID_PARAMETER;
1546c2c66affSColin Finck                     break;
1547c2c66affSColin Finck             }
1548c2c66affSColin Finck         }
1549c2c66affSColin Finck     }
1550c2c66affSColin Finck     else
1551c2c66affSColin Finck         ErrorCode = ERROR_INVALID_PARAMETER;
1552c2c66affSColin Finck 
1553c2c66affSColin Finck     return ErrorCode;
1554c2c66affSColin Finck }
1555c2c66affSColin Finck 
1556c2c66affSColin Finck #ifdef HAS_FN_PROGRESSW
1557c2c66affSColin Finck 
1558c2c66affSColin Finck typedef struct _INTERNAL_FNPROGRESSW_DATA
1559c2c66affSColin Finck {
1560c2c66affSColin Finck     FN_PROGRESSA fnProgress;
1561c2c66affSColin Finck     PVOID Args;
1562c2c66affSColin Finck } INTERNAL_FNPROGRESSW_DATA, *PINTERNAL_FNPROGRESSW_DATA;
1563c2c66affSColin Finck 
1564c2c66affSColin Finck static VOID WINAPI
InternalfnProgressW(LPWSTR pObjectName,DWORD Status,PPROG_INVOKE_SETTING pInvokeSetting,PVOID Args,BOOL SecuritySet)1565c2c66affSColin Finck InternalfnProgressW(LPWSTR pObjectName,
1566c2c66affSColin Finck                     DWORD Status,
1567c2c66affSColin Finck                     PPROG_INVOKE_SETTING pInvokeSetting,
1568c2c66affSColin Finck                     PVOID Args,
1569c2c66affSColin Finck                     BOOL SecuritySet)
1570c2c66affSColin Finck {
1571c2c66affSColin Finck     PINTERNAL_FNPROGRESSW_DATA pifnProgressData = (PINTERNAL_FNPROGRESSW_DATA)Args;
1572c2c66affSColin Finck     INT ObjectNameSize;
1573c2c66affSColin Finck     LPSTR pObjectNameA;
1574c2c66affSColin Finck 
1575c2c66affSColin Finck     ObjectNameSize = WideCharToMultiByte(CP_ACP,
1576c2c66affSColin Finck                                          0,
1577c2c66affSColin Finck                                          pObjectName,
1578c2c66affSColin Finck                                          -1,
1579c2c66affSColin Finck                                          NULL,
1580c2c66affSColin Finck                                          0,
1581c2c66affSColin Finck                                          NULL,
1582c2c66affSColin Finck                                          NULL);
1583c2c66affSColin Finck 
1584c2c66affSColin Finck     if (ObjectNameSize > 0)
1585c2c66affSColin Finck     {
1586c2c66affSColin Finck         pObjectNameA = RtlAllocateHeap(RtlGetProcessHeap(),
1587c2c66affSColin Finck                                        0,
1588c2c66affSColin Finck                                        ObjectNameSize);
1589c2c66affSColin Finck         if (pObjectNameA != NULL)
1590c2c66affSColin Finck         {
1591c2c66affSColin Finck             pObjectNameA[0] = '\0';
1592c2c66affSColin Finck             WideCharToMultiByte(CP_ACP,
1593c2c66affSColin Finck                                 0,
1594c2c66affSColin Finck                                 pObjectName,
1595c2c66affSColin Finck                                 -1,
1596c2c66affSColin Finck                                 pObjectNameA,
1597c2c66affSColin Finck                                 ObjectNameSize,
1598c2c66affSColin Finck                                 NULL,
1599c2c66affSColin Finck                                 NULL);
1600c2c66affSColin Finck 
1601c2c66affSColin Finck             pifnProgressData->fnProgress((LPWSTR)pObjectNameA, /* FIXME: wrong cast!! */
1602c2c66affSColin Finck                                          Status,
1603c2c66affSColin Finck                                          pInvokeSetting,
1604c2c66affSColin Finck                                          pifnProgressData->Args,
1605c2c66affSColin Finck                                          SecuritySet);
1606c2c66affSColin Finck 
1607c2c66affSColin Finck             RtlFreeHeap(RtlGetProcessHeap(),
1608c2c66affSColin Finck                         0,
1609c2c66affSColin Finck                         pObjectNameA);
1610c2c66affSColin Finck         }
1611c2c66affSColin Finck     }
1612c2c66affSColin Finck }
1613c2c66affSColin Finck #endif
1614c2c66affSColin Finck 
1615c2c66affSColin Finck 
1616c2c66affSColin Finck /*
1617c2c66affSColin Finck  * @implemented
1618c2c66affSColin Finck  */
1619c2c66affSColin Finck DWORD
1620c2c66affSColin Finck WINAPI
TreeResetNamedSecurityInfoA(LPSTR pObjectName,SE_OBJECT_TYPE ObjectType,SECURITY_INFORMATION SecurityInfo,PSID pOwner,PSID pGroup,PACL pDacl,PACL pSacl,BOOL KeepExplicit,FN_PROGRESSA fnProgress,PROG_INVOKE_SETTING ProgressInvokeSetting,PVOID Args)1621c2c66affSColin Finck TreeResetNamedSecurityInfoA(LPSTR pObjectName,
1622c2c66affSColin Finck                             SE_OBJECT_TYPE ObjectType,
1623c2c66affSColin Finck                             SECURITY_INFORMATION SecurityInfo,
1624c2c66affSColin Finck                             PSID pOwner,
1625c2c66affSColin Finck                             PSID pGroup,
1626c2c66affSColin Finck                             PACL pDacl,
1627c2c66affSColin Finck                             PACL pSacl,
1628c2c66affSColin Finck                             BOOL KeepExplicit,
1629c2c66affSColin Finck                             FN_PROGRESSA fnProgress,
1630c2c66affSColin Finck                             PROG_INVOKE_SETTING ProgressInvokeSetting,
1631c2c66affSColin Finck                             PVOID Args)
1632c2c66affSColin Finck {
1633c2c66affSColin Finck #ifndef HAS_FN_PROGRESSW
1634c2c66affSColin Finck     /* That's all this function does, at least up to w2k3... Even MS was too
1635c2c66affSColin Finck        lazy to implement it... */
1636c2c66affSColin Finck     return ERROR_CALL_NOT_IMPLEMENTED;
1637c2c66affSColin Finck #else
1638c2c66affSColin Finck     INTERNAL_FNPROGRESSW_DATA ifnProgressData;
1639c2c66affSColin Finck     UNICODE_STRING ObjectName;
1640c2c66affSColin Finck     DWORD Ret;
1641c2c66affSColin Finck 
1642c2c66affSColin Finck     if (!RtlCreateUnicodeStringFromAsciiz(&ObjectName, pObjectName))
1643c2c66affSColin Finck     {
1644c2c66affSColin Finck         return ERROR_NOT_ENOUGH_MEMORY;
1645c2c66affSColin Finck     }
1646c2c66affSColin Finck 
1647c2c66affSColin Finck     ifnProgressData.fnProgress = fnProgress;
1648c2c66affSColin Finck     ifnProgressData.Args = Args;
1649c2c66affSColin Finck 
1650c2c66affSColin Finck     Ret = TreeResetNamedSecurityInfoW(ObjectName.Buffer,
1651c2c66affSColin Finck                                       ObjectType,
1652c2c66affSColin Finck                                       SecurityInfo,
1653c2c66affSColin Finck                                       pOwner,
1654c2c66affSColin Finck                                       pGroup,
1655c2c66affSColin Finck                                       pDacl,
1656c2c66affSColin Finck                                       pSacl,
1657c2c66affSColin Finck                                       KeepExplicit,
1658c2c66affSColin Finck                                       (fnProgress != NULL ? InternalfnProgressW : NULL),
1659c2c66affSColin Finck                                       ProgressInvokeSetting,
1660c2c66affSColin Finck                                       &ifnProgressData);
1661c2c66affSColin Finck 
1662c2c66affSColin Finck     RtlFreeUnicodeString(&ObjectName);
1663c2c66affSColin Finck 
1664c2c66affSColin Finck     return Ret;
1665c2c66affSColin Finck #endif
1666c2c66affSColin Finck }
1667c2c66affSColin Finck 
1668c2c66affSColin Finck /* EOF */
1669