[ADVAPI32/LSASRV]
[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 OBJECT_ATTRIBUTES ObjectAttributes = {0};
1423 UNICODE_STRING SystemName;
1424 UNICODE_STRING PrivilegeName;
1425 LSA_HANDLE PolicyHandle = NULL;
1426 NTSTATUS Status;
1427
1428 TRACE("%S,%S,%p\n", lpSystemName, lpPrivilegeName, lpLuid);
1429
1430 RtlInitUnicodeString(&SystemName,
1431 lpSystemName);
1432
1433 Status = LsaOpenPolicy(lpSystemName ? &SystemName : NULL,
1434 &ObjectAttributes,
1435 POLICY_LOOKUP_NAMES,
1436 &PolicyHandle);
1437 if (!NT_SUCCESS(Status))
1438 {
1439 SetLastError(LsaNtStatusToWinError(Status));
1440 return FALSE;
1441 }
1442
1443 RtlInitUnicodeString(&PrivilegeName,
1444 lpPrivilegeName);
1445
1446 Status = LsaLookupPrivilegeValue(PolicyHandle,
1447 &PrivilegeName,
1448 lpLuid);
1449
1450 LsaClose(PolicyHandle);
1451
1452 if (!NT_SUCCESS(Status))
1453 {
1454 SetLastError(LsaNtStatusToWinError(Status));
1455 return FALSE;
1456 }
1457
1458 return TRUE;
1459 }
1460
1461
1462 /**********************************************************************
1463 * LookupPrivilegeDisplayNameA EXPORTED
1464 *
1465 * @unimplemented
1466 */
1467 BOOL
1468 WINAPI
1469 LookupPrivilegeDisplayNameA(LPCSTR lpSystemName,
1470 LPCSTR lpName,
1471 LPSTR lpDisplayName,
1472 LPDWORD cbDisplayName,
1473 LPDWORD lpLanguageId)
1474 {
1475 FIXME("%s() not implemented!\n", __FUNCTION__);
1476 SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
1477 return FALSE;
1478 }
1479
1480
1481 /**********************************************************************
1482 * LookupPrivilegeDisplayNameW EXPORTED
1483 *
1484 * @unimplemented
1485 */
1486 BOOL
1487 WINAPI
1488 LookupPrivilegeDisplayNameW(LPCWSTR lpSystemName,
1489 LPCWSTR lpName,
1490 LPWSTR lpDisplayName,
1491 LPDWORD cbDisplayName,
1492 LPDWORD lpLanguageId)
1493 {
1494 FIXME("%s() not implemented!\n", __FUNCTION__);
1495 SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
1496 return FALSE;
1497 }
1498
1499
1500 /**********************************************************************
1501 * LookupPrivilegeNameA EXPORTED
1502 *
1503 * @implemented
1504 */
1505 BOOL
1506 WINAPI
1507 LookupPrivilegeNameA(LPCSTR lpSystemName,
1508 PLUID lpLuid,
1509 LPSTR lpName,
1510 LPDWORD cchName)
1511 {
1512 UNICODE_STRING lpSystemNameW;
1513 BOOL ret;
1514 DWORD wLen = 0;
1515
1516 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1517
1518 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1519 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1520 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1521 {
1522 LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1523
1524 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1525 &wLen);
1526 if (ret)
1527 {
1528 /* Windows crashes if cchName is NULL, so will I */
1529 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1530 *cchName, NULL, NULL);
1531
1532 if (len == 0)
1533 {
1534 /* WideCharToMultiByte failed */
1535 ret = FALSE;
1536 }
1537 else if (len > *cchName)
1538 {
1539 *cchName = len;
1540 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1541 ret = FALSE;
1542 }
1543 else
1544 {
1545 /* WideCharToMultiByte succeeded, output length needs to be
1546 * length not including NULL terminator
1547 */
1548 *cchName = len - 1;
1549 }
1550 }
1551 HeapFree(GetProcessHeap(), 0, lpNameW);
1552 }
1553 RtlFreeUnicodeString(&lpSystemNameW);
1554 return ret;
1555 }
1556
1557
1558 /**********************************************************************
1559 * LookupPrivilegeNameW EXPORTED
1560 *
1561 * @implemented
1562 */
1563 BOOL
1564 WINAPI
1565 LookupPrivilegeNameW(LPCWSTR lpSystemName,
1566 PLUID lpLuid,
1567 LPWSTR lpName,
1568 LPDWORD cchName)
1569 {
1570 OBJECT_ATTRIBUTES ObjectAttributes = {0};
1571 UNICODE_STRING SystemName;
1572 PUNICODE_STRING PrivilegeName = NULL;
1573 LSA_HANDLE PolicyHandle = NULL;
1574 NTSTATUS Status;
1575
1576 TRACE("%S,%p,%p,%p\n", lpSystemName, lpLuid, lpName, cchName);
1577
1578 RtlInitUnicodeString(&SystemName,
1579 lpSystemName);
1580
1581 Status = LsaOpenPolicy(lpSystemName ? &SystemName : NULL,
1582 &ObjectAttributes,
1583 POLICY_LOOKUP_NAMES,
1584 &PolicyHandle);
1585 if (!NT_SUCCESS(Status))
1586 {
1587 SetLastError(LsaNtStatusToWinError(Status));
1588 return FALSE;
1589 }
1590
1591 Status = LsaLookupPrivilegeName(PolicyHandle,
1592 lpLuid,
1593 &PrivilegeName);
1594 if (NT_SUCCESS(Status))
1595 {
1596 if (PrivilegeName->Length + sizeof(WCHAR) > (*cchName) * sizeof(WCHAR))
1597 {
1598 Status = STATUS_BUFFER_TOO_SMALL;
1599
1600 (*cchName) = (PrivilegeName->Length + sizeof(WCHAR)) / sizeof(WCHAR);
1601 }
1602 else
1603 {
1604 RtlMoveMemory(lpName,
1605 PrivilegeName->Buffer,
1606 PrivilegeName->Length);
1607 lpName[PrivilegeName->Length / sizeof(WCHAR)] = 0;
1608
1609 (*cchName) = PrivilegeName->Length / sizeof(WCHAR);
1610 }
1611
1612 LsaFreeMemory(PrivilegeName->Buffer);
1613 LsaFreeMemory(PrivilegeName);
1614 }
1615
1616 LsaClose(PolicyHandle);
1617
1618 if (!NT_SUCCESS(Status))
1619 {
1620 SetLastError(LsaNtStatusToWinError(Status));
1621 return FALSE;
1622 }
1623
1624 return TRUE;
1625 }
1626
1627
1628 static DWORD
1629 pGetSecurityInfoCheck(SECURITY_INFORMATION SecurityInfo,
1630 PSID *ppsidOwner,
1631 PSID *ppsidGroup,
1632 PACL *ppDacl,
1633 PACL *ppSacl,
1634 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
1635 {
1636 if ((SecurityInfo & (OWNER_SECURITY_INFORMATION |
1637 GROUP_SECURITY_INFORMATION |
1638 DACL_SECURITY_INFORMATION |
1639 SACL_SECURITY_INFORMATION)) &&
1640 ppSecurityDescriptor == NULL)
1641 {
1642 /* if one of the SIDs or ACLs are present, the security descriptor
1643 most not be NULL */
1644 return ERROR_INVALID_PARAMETER;
1645 }
1646 else
1647 {
1648 /* reset the pointers unless they're ignored */
1649 if ((SecurityInfo & OWNER_SECURITY_INFORMATION) &&
1650 ppsidOwner != NULL)
1651 {
1652 *ppsidOwner = NULL;
1653 }
1654 if ((SecurityInfo & GROUP_SECURITY_INFORMATION) &&
1655 ppsidGroup != NULL)
1656 {
1657 *ppsidGroup = NULL;
1658 }
1659 if ((SecurityInfo & DACL_SECURITY_INFORMATION) &&
1660 ppDacl != NULL)
1661 {
1662 *ppDacl = NULL;
1663 }
1664 if ((SecurityInfo & SACL_SECURITY_INFORMATION) &&
1665 ppSacl != NULL)
1666 {
1667 *ppSacl = NULL;
1668 }
1669
1670 if (SecurityInfo & (OWNER_SECURITY_INFORMATION |
1671 GROUP_SECURITY_INFORMATION |
1672 DACL_SECURITY_INFORMATION |
1673 SACL_SECURITY_INFORMATION))
1674 {
1675 *ppSecurityDescriptor = NULL;
1676 }
1677
1678 return ERROR_SUCCESS;
1679 }
1680 }
1681
1682
1683 static DWORD
1684 pSetSecurityInfoCheck(PSECURITY_DESCRIPTOR pSecurityDescriptor,
1685 SECURITY_INFORMATION SecurityInfo,
1686 PSID psidOwner,
1687 PSID psidGroup,
1688 PACL pDacl,
1689 PACL pSacl)
1690 {
1691 /* initialize a security descriptor on the stack */
1692 if (!InitializeSecurityDescriptor(pSecurityDescriptor,
1693 SECURITY_DESCRIPTOR_REVISION))
1694 {
1695 return GetLastError();
1696 }
1697
1698 if (SecurityInfo & OWNER_SECURITY_INFORMATION)
1699 {
1700 if (RtlValidSid(psidOwner))
1701 {
1702 if (!SetSecurityDescriptorOwner(pSecurityDescriptor,
1703 psidOwner,
1704 FALSE))
1705 {
1706 return GetLastError();
1707 }
1708 }
1709 else
1710 {
1711 return ERROR_INVALID_PARAMETER;
1712 }
1713 }
1714
1715 if (SecurityInfo & GROUP_SECURITY_INFORMATION)
1716 {
1717 if (RtlValidSid(psidGroup))
1718 {
1719 if (!SetSecurityDescriptorGroup(pSecurityDescriptor,
1720 psidGroup,
1721 FALSE))
1722 {
1723 return GetLastError();
1724 }
1725 }
1726 else
1727 {
1728 return ERROR_INVALID_PARAMETER;
1729 }
1730 }
1731
1732 if (SecurityInfo & DACL_SECURITY_INFORMATION)
1733 {
1734 if (pDacl != NULL)
1735 {
1736 if (SetSecurityDescriptorDacl(pSecurityDescriptor,
1737 TRUE,
1738 pDacl,
1739 FALSE))
1740 {
1741 /* check if the DACL needs to be protected from being
1742 modified by inheritable ACEs */
1743 if (SecurityInfo & PROTECTED_DACL_SECURITY_INFORMATION)
1744 {
1745 goto ProtectDacl;
1746 }
1747 }
1748 else
1749 {
1750 return GetLastError();
1751 }
1752 }
1753 else
1754 {
1755 ProtectDacl:
1756 /* protect the DACL from being modified by inheritable ACEs */
1757 if (!SetSecurityDescriptorControl(pSecurityDescriptor,
1758 SE_DACL_PROTECTED,
1759 SE_DACL_PROTECTED))
1760 {
1761 return GetLastError();
1762 }
1763 }
1764 }
1765
1766 if (SecurityInfo & SACL_SECURITY_INFORMATION)
1767 {
1768 if (pSacl != NULL)
1769 {
1770 if (SetSecurityDescriptorSacl(pSecurityDescriptor,
1771 TRUE,
1772 pSacl,
1773 FALSE))
1774 {
1775 /* check if the SACL needs to be protected from being
1776 modified by inheritable ACEs */
1777 if (SecurityInfo & PROTECTED_SACL_SECURITY_INFORMATION)
1778 {
1779 goto ProtectSacl;
1780 }
1781 }
1782 else
1783 {
1784 return GetLastError();
1785 }
1786 }
1787 else
1788 {
1789 ProtectSacl:
1790 /* protect the SACL from being modified by inheritable ACEs */
1791 if (!SetSecurityDescriptorControl(pSecurityDescriptor,
1792 SE_SACL_PROTECTED,
1793 SE_SACL_PROTECTED))
1794 {
1795 return GetLastError();
1796 }
1797 }
1798 }
1799
1800 return ERROR_SUCCESS;
1801 }
1802
1803
1804 /**********************************************************************
1805 * GetNamedSecurityInfoW EXPORTED
1806 *
1807 * @implemented
1808 */
1809 DWORD
1810 WINAPI
1811 GetNamedSecurityInfoW(LPWSTR pObjectName,
1812 SE_OBJECT_TYPE ObjectType,
1813 SECURITY_INFORMATION SecurityInfo,
1814 PSID *ppsidOwner,
1815 PSID *ppsidGroup,
1816 PACL *ppDacl,
1817 PACL *ppSacl,
1818 PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
1819 {
1820 DWORD ErrorCode;
1821
1822 if (pObjectName != NULL)
1823 {
1824 ErrorCode = CheckNtMartaPresent();
1825 if (ErrorCode == ERROR_SUCCESS)
1826 {
1827 ErrorCode = pGetSecurityInfoCheck(SecurityInfo,
1828 ppsidOwner,
1829 ppsidGroup,
1830 ppDacl,
1831 ppSacl,
1832 ppSecurityDescriptor);
1833
1834 if (ErrorCode == ERROR_SUCCESS)
1835 {
1836 /* call the MARTA provider */
1837 ErrorCode = AccRewriteGetNamedRights(pObjectName,
1838 ObjectType,
1839 SecurityInfo,
1840 ppsidOwner,
1841 ppsidGroup,
1842 ppDacl,
1843 ppSacl,
1844 ppSecurityDescriptor);
1845 }
1846 }
1847 }
1848 else
1849 ErrorCode = ERROR_INVALID_PARAMETER;
1850
1851 return ErrorCode;
1852 }
1853
1854
1855 /**********************************************************************
1856 * GetNamedSecurityInfoA EXPORTED
1857 *
1858 * @implemented
1859 */
1860 DWORD
1861 WINAPI
1862 GetNamedSecurityInfoA(LPSTR pObjectName,
1863 SE_OBJECT_TYPE ObjectType,
1864 SECURITY_INFORMATION SecurityInfo,
1865 PSID *ppsidOwner,
1866 PSID *ppsidGroup,
1867 PACL *ppDacl,
1868 PACL *ppSacl,
1869 PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
1870 {
1871 DWORD len;
1872 LPWSTR wstr = NULL;
1873 DWORD r;
1874
1875 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
1876 ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
1877
1878 if( pObjectName )
1879 {
1880 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
1881 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
1882 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
1883 }
1884
1885 r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
1886 ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
1887
1888 HeapFree( GetProcessHeap(), 0, wstr );
1889
1890 return r;
1891 }
1892
1893
1894 /**********************************************************************
1895 * SetNamedSecurityInfoW EXPORTED
1896 *
1897 * @implemented
1898 */
1899 DWORD
1900 WINAPI
1901 SetNamedSecurityInfoW(LPWSTR pObjectName,
1902 SE_OBJECT_TYPE ObjectType,
1903 SECURITY_INFORMATION SecurityInfo,
1904 PSID psidOwner,
1905 PSID psidGroup,
1906 PACL pDacl,
1907 PACL pSacl)
1908 {
1909 DWORD ErrorCode;
1910
1911 if (pObjectName != NULL)
1912 {
1913 ErrorCode = CheckNtMartaPresent();
1914 if (ErrorCode == ERROR_SUCCESS)
1915 {
1916 SECURITY_DESCRIPTOR SecurityDescriptor;
1917
1918 ErrorCode = pSetSecurityInfoCheck(&SecurityDescriptor,
1919 SecurityInfo,
1920 psidOwner,
1921 psidGroup,
1922 pDacl,
1923 pSacl);
1924
1925 if (ErrorCode == ERROR_SUCCESS)
1926 {
1927 /* call the MARTA provider */
1928 ErrorCode = AccRewriteSetNamedRights(pObjectName,
1929 ObjectType,
1930 SecurityInfo,
1931 &SecurityDescriptor);
1932 }
1933 }
1934 }
1935 else
1936 ErrorCode = ERROR_INVALID_PARAMETER;
1937
1938 return ErrorCode;
1939 }
1940
1941
1942 /**********************************************************************
1943 * SetNamedSecurityInfoA EXPORTED
1944 *
1945 * @implemented
1946 */
1947 DWORD
1948 WINAPI
1949 SetNamedSecurityInfoA(LPSTR pObjectName,
1950 SE_OBJECT_TYPE ObjectType,
1951 SECURITY_INFORMATION SecurityInfo,
1952 PSID psidOwner,
1953 PSID psidGroup,
1954 PACL pDacl,
1955 PACL pSacl)
1956 {
1957 UNICODE_STRING ObjectName;
1958 NTSTATUS Status;
1959 DWORD Ret;
1960
1961 Status = RtlCreateUnicodeStringFromAsciiz(&ObjectName,
1962 pObjectName);
1963 if (!NT_SUCCESS(Status))
1964 {
1965 return RtlNtStatusToDosError(Status);
1966 }
1967
1968 Ret = SetNamedSecurityInfoW(ObjectName.Buffer,
1969 ObjectType,
1970 SecurityInfo,
1971 psidOwner,
1972 psidGroup,
1973 pDacl,
1974 pSacl);
1975
1976 RtlFreeUnicodeString(&ObjectName);
1977
1978 return Ret;
1979 }
1980
1981
1982 /**********************************************************************
1983 * GetSecurityInfo EXPORTED
1984 *
1985 * @implemented
1986 */
1987 DWORD
1988 WINAPI
1989 GetSecurityInfo(HANDLE handle,
1990 SE_OBJECT_TYPE ObjectType,
1991 SECURITY_INFORMATION SecurityInfo,
1992 PSID *ppsidOwner,
1993 PSID *ppsidGroup,
1994 PACL *ppDacl,
1995 PACL *ppSacl,
1996 PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
1997 {
1998 DWORD ErrorCode;
1999
2000 if (handle != NULL)
2001 {
2002 ErrorCode = CheckNtMartaPresent();
2003 if (ErrorCode == ERROR_SUCCESS)
2004 {
2005 ErrorCode = pGetSecurityInfoCheck(SecurityInfo,
2006 ppsidOwner,
2007 ppsidGroup,
2008 ppDacl,
2009 ppSacl,
2010 ppSecurityDescriptor);
2011
2012 if (ErrorCode == ERROR_SUCCESS)
2013 {
2014 /* call the MARTA provider */
2015 ErrorCode = AccRewriteGetHandleRights(handle,
2016 ObjectType,
2017 SecurityInfo,
2018 ppsidOwner,
2019 ppsidGroup,
2020 ppDacl,
2021 ppSacl,
2022 ppSecurityDescriptor);
2023 }
2024 }
2025 }
2026 else
2027 ErrorCode = ERROR_INVALID_HANDLE;
2028
2029 return ErrorCode;
2030 }
2031
2032
2033 /**********************************************************************
2034 * SetSecurityInfo EXPORTED
2035 *
2036 * @implemented
2037 */
2038 DWORD
2039 WINAPI
2040 SetSecurityInfo(HANDLE handle,
2041 SE_OBJECT_TYPE ObjectType,
2042 SECURITY_INFORMATION SecurityInfo,
2043 PSID psidOwner,
2044 PSID psidGroup,
2045 PACL pDacl,
2046 PACL pSacl)
2047 {
2048 DWORD ErrorCode;
2049
2050 if (handle != NULL)
2051 {
2052 ErrorCode = CheckNtMartaPresent();
2053 if (ErrorCode == ERROR_SUCCESS)
2054 {
2055 SECURITY_DESCRIPTOR SecurityDescriptor;
2056
2057 ErrorCode = pSetSecurityInfoCheck(&SecurityDescriptor,
2058 SecurityInfo,
2059 psidOwner,
2060 psidGroup,
2061 pDacl,
2062 pSacl);
2063
2064 if (ErrorCode == ERROR_SUCCESS)
2065 {
2066 /* call the MARTA provider */
2067 ErrorCode = AccRewriteSetHandleRights(handle,
2068 ObjectType,
2069 SecurityInfo,
2070 &SecurityDescriptor);
2071 }
2072 }
2073 }
2074 else
2075 ErrorCode = ERROR_INVALID_HANDLE;
2076
2077 return ErrorCode;
2078 }
2079
2080
2081 /******************************************************************************
2082 * GetSecurityInfoExW EXPORTED
2083 */
2084 DWORD
2085 WINAPI
2086 GetSecurityInfoExA(HANDLE hObject,
2087 SE_OBJECT_TYPE ObjectType,
2088 SECURITY_INFORMATION SecurityInfo,
2089 LPCSTR lpProvider,
2090 LPCSTR lpProperty,
2091 PACTRL_ACCESSA *ppAccessList,
2092 PACTRL_AUDITA *ppAuditList,
2093 LPSTR *lppOwner,
2094 LPSTR *lppGroup)
2095 {
2096 FIXME("%s() not implemented!\n", __FUNCTION__);
2097 return ERROR_BAD_PROVIDER;
2098 }
2099
2100
2101 /******************************************************************************
2102 * GetSecurityInfoExW EXPORTED
2103 */
2104 DWORD
2105 WINAPI
2106 GetSecurityInfoExW(HANDLE hObject,
2107 SE_OBJECT_TYPE ObjectType,
2108 SECURITY_INFORMATION SecurityInfo,
2109 LPCWSTR lpProvider,
2110 LPCWSTR lpProperty,
2111 PACTRL_ACCESSW *ppAccessList,
2112 PACTRL_AUDITW *ppAuditList,
2113 LPWSTR *lppOwner,
2114 LPWSTR *lppGroup)
2115 {
2116 FIXME("%s() not implemented!\n", __FUNCTION__);
2117 return ERROR_BAD_PROVIDER;
2118 }
2119
2120
2121 /**********************************************************************
2122 * ImpersonateNamedPipeClient EXPORTED
2123 *
2124 * @implemented
2125 */
2126 BOOL
2127 WINAPI
2128 ImpersonateNamedPipeClient(HANDLE hNamedPipe)
2129 {
2130 IO_STATUS_BLOCK StatusBlock;
2131 NTSTATUS Status;
2132
2133 TRACE("ImpersonateNamedPipeClient() called\n");
2134
2135 Status = NtFsControlFile(hNamedPipe,
2136 NULL,
2137 NULL,
2138 NULL,
2139 &StatusBlock,
2140 FSCTL_PIPE_IMPERSONATE,
2141 NULL,
2142 0,
2143 NULL,
2144 0);
2145 if (!NT_SUCCESS(Status))
2146 {
2147 SetLastError(RtlNtStatusToDosError(Status));
2148 return FALSE;
2149 }
2150
2151 return TRUE;
2152 }
2153
2154
2155 /*
2156 * @implemented
2157 */
2158 BOOL
2159 WINAPI
2160 CreatePrivateObjectSecurity(PSECURITY_DESCRIPTOR ParentDescriptor,
2161 PSECURITY_DESCRIPTOR CreatorDescriptor,
2162 PSECURITY_DESCRIPTOR *NewDescriptor,
2163 BOOL IsDirectoryObject,
2164 HANDLE Token,
2165 PGENERIC_MAPPING GenericMapping)
2166 {
2167 NTSTATUS Status;
2168
2169 Status = RtlNewSecurityObject(ParentDescriptor,
2170 CreatorDescriptor,
2171 NewDescriptor,
2172 IsDirectoryObject,
2173 Token,
2174 GenericMapping);
2175 if (!NT_SUCCESS(Status))
2176 {
2177 SetLastError(RtlNtStatusToDosError(Status));
2178 return FALSE;
2179 }
2180
2181 return TRUE;
2182 }
2183
2184
2185 /*
2186 * @unimplemented
2187 */
2188 BOOL
2189 WINAPI
2190 CreatePrivateObjectSecurityEx(PSECURITY_DESCRIPTOR ParentDescriptor,
2191 PSECURITY_DESCRIPTOR CreatorDescriptor,
2192 PSECURITY_DESCRIPTOR* NewDescriptor,
2193 GUID* ObjectType,
2194 BOOL IsContainerObject,
2195 ULONG AutoInheritFlags,
2196 HANDLE Token,
2197 PGENERIC_MAPPING GenericMapping)
2198 {
2199 FIXME("%s() not implemented!\n", __FUNCTION__);
2200 return FALSE;
2201 }
2202
2203
2204 /*
2205 * @unimplemented
2206 */
2207 BOOL
2208 WINAPI
2209 CreatePrivateObjectSecurityWithMultipleInheritance(PSECURITY_DESCRIPTOR ParentDescriptor,
2210 PSECURITY_DESCRIPTOR CreatorDescriptor,
2211 PSECURITY_DESCRIPTOR* NewDescriptor,
2212 GUID** ObjectTypes,
2213 ULONG GuidCount,
2214 BOOL IsContainerObject,
2215 ULONG AutoInheritFlags,
2216 HANDLE Token,
2217 PGENERIC_MAPPING GenericMapping)
2218 {
2219 FIXME("%s() not implemented!\n", __FUNCTION__);
2220 return FALSE;
2221 }
2222
2223
2224 /*
2225 * @implemented
2226 */
2227 BOOL
2228 WINAPI
2229 DestroyPrivateObjectSecurity(PSECURITY_DESCRIPTOR *ObjectDescriptor)
2230 {
2231 NTSTATUS Status;
2232
2233 Status = RtlDeleteSecurityObject(ObjectDescriptor);
2234 if (!NT_SUCCESS(Status))
2235 {
2236 SetLastError(RtlNtStatusToDosError(Status));
2237 return FALSE;
2238 }
2239
2240 return TRUE;
2241 }
2242
2243
2244 /*
2245 * @implemented
2246 */
2247 BOOL
2248 WINAPI
2249 GetPrivateObjectSecurity(IN PSECURITY_DESCRIPTOR ObjectDescriptor,
2250 IN SECURITY_INFORMATION SecurityInformation,
2251 OUT PSECURITY_DESCRIPTOR ResultantDescriptor OPTIONAL,
2252 IN DWORD DescriptorLength,
2253 OUT PDWORD ReturnLength)
2254 {
2255 NTSTATUS Status;
2256
2257 /* Call RTL */
2258 Status = RtlQuerySecurityObject(ObjectDescriptor,
2259 SecurityInformation,
2260 ResultantDescriptor,
2261 DescriptorLength,
2262 ReturnLength);
2263 if (!NT_SUCCESS(Status))
2264 {
2265 /* Fail */
2266 SetLastError(RtlNtStatusToDosError(Status));
2267 return FALSE;
2268 }
2269
2270 /* Success */
2271 return TRUE;
2272 }
2273
2274
2275 /*
2276 * @implemented
2277 */
2278 BOOL
2279 WINAPI
2280 SetPrivateObjectSecurity(SECURITY_INFORMATION SecurityInformation,
2281 PSECURITY_DESCRIPTOR ModificationDescriptor,
2282 PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
2283 PGENERIC_MAPPING GenericMapping,
2284 HANDLE Token)
2285 {
2286 NTSTATUS Status;
2287
2288 Status = RtlSetSecurityObject(SecurityInformation,
2289 ModificationDescriptor,
2290 ObjectsSecurityDescriptor,
2291 GenericMapping,
2292 Token);
2293 if (!NT_SUCCESS(Status))
2294 {
2295 SetLastError(RtlNtStatusToDosError(Status));
2296 return FALSE;
2297 }
2298
2299 return TRUE;
2300 }
2301
2302
2303 /*
2304 * @implemented
2305 */
2306 DWORD
2307 WINAPI
2308 TreeResetNamedSecurityInfoW(LPWSTR pObjectName,
2309 SE_OBJECT_TYPE ObjectType,
2310 SECURITY_INFORMATION SecurityInfo,
2311 PSID pOwner,
2312 PSID pGroup,
2313 PACL pDacl,
2314 PACL pSacl,
2315 BOOL KeepExplicit,
2316 FN_PROGRESSW fnProgress,
2317 PROG_INVOKE_SETTING ProgressInvokeSetting,
2318 PVOID Args)
2319 {
2320 DWORD ErrorCode;
2321
2322 if (pObjectName != NULL)
2323 {
2324 ErrorCode = CheckNtMartaPresent();
2325 if (ErrorCode == ERROR_SUCCESS)
2326 {
2327 switch (ObjectType)
2328 {
2329 case SE_FILE_OBJECT:
2330 case SE_REGISTRY_KEY:
2331 {
2332 /* check the SecurityInfo flags for sanity (both, the protected
2333 and unprotected dacl/sacl flag must not be passed together) */
2334 if (((SecurityInfo & DACL_SECURITY_INFORMATION) &&
2335 (SecurityInfo & (PROTECTED_DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION)) ==
2336 (PROTECTED_DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION))
2337
2338 ||
2339
2340 ((SecurityInfo & SACL_SECURITY_INFORMATION) &&
2341 (SecurityInfo & (PROTECTED_SACL_SECURITY_INFORMATION | UNPROTECTED_SACL_SECURITY_INFORMATION)) ==
2342 (PROTECTED_SACL_SECURITY_INFORMATION | UNPROTECTED_SACL_SECURITY_INFORMATION)))
2343 {
2344 ErrorCode = ERROR_INVALID_PARAMETER;
2345 break;
2346 }
2347
2348 /* call the MARTA provider */
2349 ErrorCode = AccTreeResetNamedSecurityInfo(pObjectName,
2350 ObjectType,
2351 SecurityInfo,
2352 pOwner,
2353 pGroup,
2354 pDacl,
2355 pSacl,
2356 KeepExplicit,
2357 fnProgress,
2358 ProgressInvokeSetting,
2359 Args);
2360 break;
2361 }
2362
2363 default:
2364 /* object type not supported */
2365 ErrorCode = ERROR_INVALID_PARAMETER;
2366 break;
2367 }
2368 }
2369 }
2370 else
2371 ErrorCode = ERROR_INVALID_PARAMETER;
2372
2373 return ErrorCode;
2374 }
2375
2376 #ifdef HAS_FN_PROGRESSW
2377
2378 typedef struct _INERNAL_FNPROGRESSW_DATA
2379 {
2380 FN_PROGRESSA fnProgress;
2381 PVOID Args;
2382 } INERNAL_FNPROGRESSW_DATA, *PINERNAL_FNPROGRESSW_DATA;
2383
2384 static VOID WINAPI
2385 InternalfnProgressW(LPWSTR pObjectName,
2386 DWORD Status,
2387 PPROG_INVOKE_SETTING pInvokeSetting,
2388 PVOID Args,
2389 BOOL SecuritySet)
2390 {
2391 PINERNAL_FNPROGRESSW_DATA pifnProgressData = (PINERNAL_FNPROGRESSW_DATA)Args;
2392 INT ObjectNameSize;
2393 LPSTR pObjectNameA;
2394
2395 ObjectNameSize = WideCharToMultiByte(CP_ACP,
2396 0,
2397 pObjectName,
2398 -1,
2399 NULL,
2400 0,
2401 NULL,
2402 NULL);
2403
2404 if (ObjectNameSize > 0)
2405 {
2406 pObjectNameA = RtlAllocateHeap(RtlGetProcessHeap(),
2407 0,
2408 ObjectNameSize);
2409 if (pObjectNameA != NULL)
2410 {
2411 pObjectNameA[0] = '\0';
2412 WideCharToMultiByte(CP_ACP,
2413 0,
2414 pObjectName,
2415 -1,
2416 pObjectNameA,
2417 ObjectNameSize,
2418 NULL,
2419 NULL);
2420
2421 pifnProgressData->fnProgress((LPWSTR)pObjectNameA, /* FIXME: wrong cast!! */
2422 Status,
2423 pInvokeSetting,
2424 pifnProgressData->Args,
2425 SecuritySet);
2426
2427 RtlFreeHeap(RtlGetProcessHeap(),
2428 0,
2429 pObjectNameA);
2430 }
2431 }
2432 }
2433 #endif
2434
2435
2436 /*
2437 * @implemented
2438 */
2439 DWORD
2440 WINAPI
2441 TreeResetNamedSecurityInfoA(LPSTR pObjectName,
2442 SE_OBJECT_TYPE ObjectType,
2443 SECURITY_INFORMATION SecurityInfo,
2444 PSID pOwner,
2445 PSID pGroup,
2446 PACL pDacl,
2447 PACL pSacl,
2448 BOOL KeepExplicit,
2449 FN_PROGRESSA fnProgress,
2450 PROG_INVOKE_SETTING ProgressInvokeSetting,
2451 PVOID Args)
2452 {
2453 #ifndef HAS_FN_PROGRESSW
2454 /* That's all this function does, at least up to w2k3... Even MS was too
2455 lazy to implement it... */
2456 return ERROR_CALL_NOT_IMPLEMENTED;
2457 #else
2458 INERNAL_FNPROGRESSW_DATA ifnProgressData;
2459 UNICODE_STRING ObjectName;
2460 NTSTATUS Status;
2461 DWORD Ret;
2462
2463 Status = RtlCreateUnicodeStringFromAsciiz(&ObjectName,
2464 pObjectName);
2465 if (!NT_SUCCESS(Status))
2466 {
2467 return RtlNtStatusToDosError(Status);
2468 }
2469
2470 ifnProgressData.fnProgress = fnProgress;
2471 ifnProgressData.Args = Args;
2472
2473 Ret = TreeResetNamedSecurityInfoW(ObjectName.Buffer,
2474 ObjectType,
2475 SecurityInfo,
2476 pOwner,
2477 pGroup,
2478 pDacl,
2479 pSacl,
2480 KeepExplicit,
2481 (fnProgress != NULL ? InternalfnProgressW : NULL),
2482 ProgressInvokeSetting,
2483 &ifnProgressData);
2484
2485 RtlFreeUnicodeString(&ObjectName);
2486
2487 return Ret;
2488 #endif
2489 }
2490
2491 /******************************************************************************
2492 * SaferCreateLevel [ADVAPI32.@]
2493 */
2494 BOOL WINAPI SaferCreateLevel(DWORD ScopeId, DWORD LevelId, DWORD OpenFlags,
2495 SAFER_LEVEL_HANDLE* LevelHandle, LPVOID lpReserved)
2496 {
2497 FIXME("(%u, %x, %u, %p, %p) stub\n", ScopeId, LevelId, OpenFlags, LevelHandle, lpReserved);
2498 return FALSE;
2499 }
2500
2501 /******************************************************************************
2502 * SaferGetPolicyInformation [ADVAPI32.@]
2503 */
2504 BOOL WINAPI SaferGetPolicyInformation(DWORD scope, SAFER_POLICY_INFO_CLASS class, DWORD size,
2505 PVOID buffer, PDWORD required, LPVOID lpReserved)
2506 {
2507 FIXME("(%u %u %u %p %p %p) stub\n", scope, class, size, buffer, required, lpReserved);
2508 return FALSE;
2509 }
2510
2511 /******************************************************************************
2512 * QueryWindows31FilesMigration [ADVAPI32.@]
2513 *
2514 * PARAMS
2515 * x1 []
2516 */
2517 BOOL WINAPI
2518 QueryWindows31FilesMigration( DWORD x1 )
2519 {
2520 FIXME("(%d):stub\n",x1);
2521 return TRUE;
2522 }
2523
2524 /******************************************************************************
2525 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2526 *
2527 * PARAMS
2528 * x1 []
2529 * x2 []
2530 * x3 []
2531 * x4 []
2532 */
2533 BOOL WINAPI
2534 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2535 DWORD x4 )
2536 {
2537 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2538 return TRUE;
2539 }
2540
2541 /* EOF */