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