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