18cbf760cc929301c06a769fed7a151361e44489
[reactos.git] / reactos / dll / win32 / advapi32 / sec / misc.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * WINE COPYRIGHT:
4 * Copyright 1999, 2000 Juergen Schmied <juergen.schmied@debitel.net>
5 * Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
6 * Copyright 2006 Robert Reif
7 *
8 * PROJECT: ReactOS system libraries
9 * FILE: dll/win32/advapi32/sec/misc.c
10 * PURPOSE: Miscellaneous security functions (some ported from Wine)
11 */
12
13 #include <advapi32.h>
14 #include "wine/unicode.h"
15 #include "wine/debug.h"
16
17 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
18
19 /* Needed for LookupAccountNameW implementation from Wine */
20
21 typedef struct _AccountSid
22 {
23 WELL_KNOWN_SID_TYPE type;
24 LPCWSTR account;
25 LPCWSTR domain;
26 SID_NAME_USE name_use;
27 } AccountSid;
28
29 static const WCHAR Account_Operators[] = { 'A','c','c','o','u','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
30 static const WCHAR Administrator[] = {'A','d','m','i','n','i','s','t','r','a','t','o','r',0 };
31 static const WCHAR Administrators[] = { 'A','d','m','i','n','i','s','t','r','a','t','o','r','s',0 };
32 static const WCHAR ANONYMOUS_LOGON[] = { 'A','N','O','N','Y','M','O','U','S',' ','L','O','G','O','N',0 };
33 static const WCHAR Authenticated_Users[] = { 'A','u','t','h','e','n','t','i','c','a','t','e','d',' ','U','s','e','r','s',0 };
34 static const WCHAR Backup_Operators[] = { 'B','a','c','k','u','p',' ','O','p','e','r','a','t','o','r','s',0 };
35 static const WCHAR BATCH[] = { 'B','A','T','C','H',0 };
36 static const WCHAR Blank[] = { 0 };
37 static const WCHAR BUILTIN[] = { 'B','U','I','L','T','I','N',0 };
38 static const WCHAR Cert_Publishers[] = { 'C','e','r','t',' ','P','u','b','l','i','s','h','e','r','s',0 };
39 static const WCHAR CREATOR_GROUP[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',0 };
40 static const WCHAR CREATOR_GROUP_SERVER[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',' ','S','E','R','V','E','R',0 };
41 static const WCHAR CREATOR_OWNER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',0 };
42 static const WCHAR CREATOR_OWNER_SERVER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',' ','S','E','R','V','E','R',0 };
43 static const WCHAR DIALUP[] = { 'D','I','A','L','U','P',0 };
44 static const WCHAR Digest_Authentication[] = { 'D','i','g','e','s','t',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
45 static const WCHAR DOMAIN[] = {'D','O','M','A','I','N',0};
46 static const WCHAR Domain_Admins[] = { 'D','o','m','a','i','n',' ','A','d','m','i','n','s',0 };
47 static const WCHAR Domain_Computers[] = { 'D','o','m','a','i','n',' ','C','o','m','p','u','t','e','r','s',0 };
48 static const WCHAR Domain_Controllers[] = { 'D','o','m','a','i','n',' ','C','o','n','t','r','o','l','l','e','r','s',0 };
49 static const WCHAR Domain_Guests[] = { 'D','o','m','a','i','n',' ','G','u','e','s','t','s',0 };
50 static const WCHAR Domain_Users[] = { 'D','o','m','a','i','n',' ','U','s','e','r','s',0 };
51 static const WCHAR Enterprise_Admins[] = { 'E','n','t','e','r','p','r','i','s','e',' ','A','d','m','i','n','s',0 };
52 static const WCHAR ENTERPRISE_DOMAIN_CONTROLLERS[] = { 'E','N','T','E','R','P','R','I','S','E',' ','D','O','M','A','I','N',' ','C','O','N','T','R','O','L','L','E','R','S',0 };
53 static const WCHAR Everyone[] = { 'E','v','e','r','y','o','n','e',0 };
54 static const WCHAR Group_Policy_Creator_Owners[] = { 'G','r','o','u','p',' ','P','o','l','i','c','y',' ','C','r','e','a','t','o','r',' ','O','w','n','e','r','s',0 };
55 static const WCHAR Guest[] = { 'G','u','e','s','t',0 };
56 static const WCHAR Guests[] = { 'G','u','e','s','t','s',0 };
57 static const WCHAR INTERACTIVE[] = { 'I','N','T','E','R','A','C','T','I','V','E',0 };
58 static const WCHAR LOCAL[] = { 'L','O','C','A','L',0 };
59 static const WCHAR LOCAL_SERVICE[] = { 'L','O','C','A','L',' ','S','E','R','V','I','C','E',0 };
60 static const WCHAR NETWORK[] = { 'N','E','T','W','O','R','K',0 };
61 static const WCHAR Network_Configuration_Operators[] = { 'N','e','t','w','o','r','k',' ','C','o','n','f','i','g','u','r','a','t','i','o','n',' ','O','p','e','r','a','t','o','r','s',0 };
62 static const WCHAR NETWORK_SERVICE[] = { 'N','E','T','W','O','R','K',' ','S','E','R','V','I','C','E',0 };
63 static const WCHAR NT_AUTHORITY[] = { 'N','T',' ','A','U','T','H','O','R','I','T','Y',0 };
64 static const WCHAR NT_Pseudo_Domain[] = { 'N','T',' ','P','s','e','u','d','o',' ','D','o','m','a','i','n',0 };
65 static const WCHAR NTML_Authentication[] = { 'N','T','M','L',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
66 static const WCHAR NULL_SID[] = { 'N','U','L','L',' ','S','I','D',0 };
67 static const WCHAR Other_Organization[] = { 'O','t','h','e','r',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
68 static const WCHAR Performance_Log_Users[] = { 'P','e','r','f','o','r','m','a','n','c','e',' ','L','o','g',' ','U','s','e','r','s',0 };
69 static const WCHAR Performance_Monitor_Users[] = { 'P','e','r','f','o','r','m','a','n','c','e',' ','M','o','n','i','t','o','r',' ','U','s','e','r','s',0 };
70 static const WCHAR Power_Users[] = { 'P','o','w','e','r',' ','U','s','e','r','s',0 };
71 static const WCHAR Pre_Windows_2000_Compatible_Access[] = { 'P','r','e','-','W','i','n','d','o','w','s',' ','2','0','0','0',' ','C','o','m','p','a','t','i','b','l','e',' ','A','c','c','e','s','s',0 };
72 static const WCHAR Print_Operators[] = { 'P','r','i','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
73 static const WCHAR PROXY[] = { 'P','R','O','X','Y',0 };
74 static const WCHAR RAS_and_IAS_Servers[] = { 'R','A','S',' ','a','n','d',' ','I','A','S',' ','S','e','r','v','e','r','s',0 };
75 static const WCHAR Remote_Desktop_Users[] = { 'R','e','m','o','t','e',' ','D','e','s','k','t','o','p',' ','U','s','e','r','s',0 };
76 static const WCHAR REMOTE_INTERACTIVE_LOGON[] = { 'R','E','M','O','T','E',' ','I','N','T','E','R','A','C','T','I','V','E',' ','L','O','G','O','N',0 };
77 static const WCHAR Replicators[] = { 'R','e','p','l','i','c','a','t','o','r','s',0 };
78 static const WCHAR RESTRICTED[] = { 'R','E','S','T','R','I','C','T','E','D',0 };
79 static const WCHAR SChannel_Authentication[] = { 'S','C','h','a','n','n','e','l',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
80 static const WCHAR Schema_Admins[] = { 'S','c','h','e','m','a',' ','A','d','m','i','n','s',0 };
81 static const WCHAR SELF[] = { 'S','E','L','F',0 };
82 static const WCHAR Server_Operators[] = { 'S','e','r','v','e','r',' ','O','p','e','r','a','t','o','r','s',0 };
83 static const WCHAR SERVICE[] = { 'S','E','R','V','I','C','E',0 };
84 static const WCHAR SYSTEM[] = { 'S','Y','S','T','E','M',0 };
85 static const WCHAR TERMINAL_SERVER_USER[] = { 'T','E','R','M','I','N','A','L',' ','S','E','R','V','E','R',' ','U','S','E','R',0 };
86 static const WCHAR This_Organization[] = { 'T','h','i','s',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
87 static const WCHAR Users[] = { 'U','s','e','r','s',0 };
88
89 static const AccountSid ACCOUNT_SIDS[] = {
90 { WinNullSid, NULL_SID, Blank, SidTypeWellKnownGroup },
91 { WinWorldSid, Everyone, Blank, SidTypeWellKnownGroup },
92 { WinLocalSid, LOCAL, Blank, SidTypeWellKnownGroup },
93 { WinCreatorOwnerSid, CREATOR_OWNER, Blank, SidTypeWellKnownGroup },
94 { WinCreatorGroupSid, CREATOR_GROUP, Blank, SidTypeWellKnownGroup },
95 { WinCreatorOwnerServerSid, CREATOR_OWNER_SERVER, Blank, SidTypeWellKnownGroup },
96 { WinCreatorGroupServerSid, CREATOR_GROUP_SERVER, Blank, SidTypeWellKnownGroup },
97 { WinNtAuthoritySid, NT_Pseudo_Domain, NT_Pseudo_Domain, SidTypeDomain },
98 { WinDialupSid, DIALUP, NT_AUTHORITY, SidTypeWellKnownGroup },
99 { WinNetworkSid, NETWORK, NT_AUTHORITY, SidTypeWellKnownGroup },
100 { WinBatchSid, BATCH, NT_AUTHORITY, SidTypeWellKnownGroup },
101 { WinInteractiveSid, INTERACTIVE, NT_AUTHORITY, SidTypeWellKnownGroup },
102 { WinServiceSid, SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
103 { WinAnonymousSid, ANONYMOUS_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
104 { WinProxySid, PROXY, NT_AUTHORITY, SidTypeWellKnownGroup },
105 { WinEnterpriseControllersSid, ENTERPRISE_DOMAIN_CONTROLLERS, NT_AUTHORITY, SidTypeWellKnownGroup },
106 { WinSelfSid, SELF, NT_AUTHORITY, SidTypeWellKnownGroup },
107 { WinAuthenticatedUserSid, Authenticated_Users, NT_AUTHORITY, SidTypeWellKnownGroup },
108 { WinRestrictedCodeSid, RESTRICTED, NT_AUTHORITY, SidTypeWellKnownGroup },
109 { WinTerminalServerSid, TERMINAL_SERVER_USER, NT_AUTHORITY, SidTypeWellKnownGroup },
110 { WinRemoteLogonIdSid, REMOTE_INTERACTIVE_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
111 { WinLocalSystemSid, SYSTEM, NT_AUTHORITY, SidTypeWellKnownGroup },
112 { WinLocalServiceSid, LOCAL_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
113 { WinNetworkServiceSid, NETWORK_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
114 { WinBuiltinDomainSid, BUILTIN, BUILTIN, SidTypeDomain },
115 { WinBuiltinAdministratorsSid, Administrators, BUILTIN, SidTypeAlias },
116 { WinBuiltinUsersSid, Users, BUILTIN, SidTypeAlias },
117 { WinBuiltinGuestsSid, Guests, BUILTIN, SidTypeAlias },
118 { WinBuiltinPowerUsersSid, Power_Users, BUILTIN, SidTypeAlias },
119 { WinBuiltinAccountOperatorsSid, Account_Operators, BUILTIN, SidTypeAlias },
120 { WinBuiltinSystemOperatorsSid, Server_Operators, BUILTIN, SidTypeAlias },
121 { WinBuiltinPrintOperatorsSid, Print_Operators, BUILTIN, SidTypeAlias },
122 { WinBuiltinBackupOperatorsSid, Backup_Operators, BUILTIN, SidTypeAlias },
123 { WinBuiltinReplicatorSid, Replicators, BUILTIN, SidTypeAlias },
124 { WinBuiltinPreWindows2000CompatibleAccessSid, Pre_Windows_2000_Compatible_Access, BUILTIN, SidTypeAlias },
125 { WinBuiltinRemoteDesktopUsersSid, Remote_Desktop_Users, BUILTIN, SidTypeAlias },
126 { WinBuiltinNetworkConfigurationOperatorsSid, Network_Configuration_Operators, BUILTIN, SidTypeAlias },
127 { WinNTLMAuthenticationSid, NTML_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
128 { WinDigestAuthenticationSid, Digest_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
129 { WinSChannelAuthenticationSid, SChannel_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
130 { WinThisOrganizationSid, This_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
131 { WinOtherOrganizationSid, Other_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
132 { WinBuiltinPerfMonitoringUsersSid, Performance_Monitor_Users, BUILTIN, SidTypeAlias },
133 { WinBuiltinPerfLoggingUsersSid, Performance_Log_Users, BUILTIN, SidTypeAlias },
134 };
135
136 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
137 { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
138 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
139 { 'S','e','A','s','s','i','g','n','P','r','i','m','a','r','y','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
140 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
141 { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
142 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
143 { 'S','e','I','n','c','r','e','a','s','e','Q','u','o','t','a','P','r','i','v','i','l','e','g','e',0 };
144 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
145 { 'S','e','M','a','c','h','i','n','e','A','c','c','o','u','n','t','P','r','i','v','i','l','e','g','e',0 };
146 static const WCHAR SE_TCB_NAME_W[] =
147 { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
148 static const WCHAR SE_SECURITY_NAME_W[] =
149 { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
150 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
151 { 'S','e','T','a','k','e','O','w','n','e','r','s','h','i','p','P','r','i','v','i','l','e','g','e',0 };
152 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
153 { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
154 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
155 { 'S','e','S','y','s','t','e','m','P','r','o','f','i','l','e','P','r','i','v','i','l','e','g','e',0 };
156 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
157 { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
158 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
159 { 'S','e','P','r','o','f','i','l','e','S','i','n','g','l','e','P','r','o','c','e','s','s','P','r','i','v','i','l','e','g','e',0 };
160 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
161 { 'S','e','I','n','c','r','e','a','s','e','B','a','s','e','P','r','i','o','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
162 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
163 { 'S','e','C','r','e','a','t','e','P','a','g','e','f','i','l','e','P','r','i','v','i','l','e','g','e',0 };
164 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
165 { 'S','e','C','r','e','a','t','e','P','e','r','m','a','n','e','n','t','P','r','i','v','i','l','e','g','e',0 };
166 static const WCHAR SE_BACKUP_NAME_W[] =
167 { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
168 static const WCHAR SE_RESTORE_NAME_W[] =
169 { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
170 static const WCHAR SE_SHUTDOWN_NAME_W[] =
171 { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
172 static const WCHAR SE_DEBUG_NAME_W[] =
173 { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
174 static const WCHAR SE_AUDIT_NAME_W[] =
175 { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
176 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
177 { 'S','e','S','y','s','t','e','m','E','n','v','i','r','o','n','m','e','n','t','P','r','i','v','i','l','e','g','e',0 };
178 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
179 { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
180 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
181 { 'S','e','R','e','m','o','t','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
182 static const WCHAR SE_UNDOCK_NAME_W[] =
183 { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
184 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
185 { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
186 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
187 { 'S','e','E','n','a','b','l','e','D','e','l','e','g','a','t','i','o','n','P','r','i','v','i','l','e','g','e',0 };
188 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
189 { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
190 static const WCHAR SE_IMPERSONATE_NAME_W[] =
191 { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
192 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
193 { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
194
195 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
196 {
197 NULL,
198 NULL,
199 SE_CREATE_TOKEN_NAME_W,
200 SE_ASSIGNPRIMARYTOKEN_NAME_W,
201 SE_LOCK_MEMORY_NAME_W,
202 SE_INCREASE_QUOTA_NAME_W,
203 SE_MACHINE_ACCOUNT_NAME_W,
204 SE_TCB_NAME_W,
205 SE_SECURITY_NAME_W,
206 SE_TAKE_OWNERSHIP_NAME_W,
207 SE_LOAD_DRIVER_NAME_W,
208 SE_SYSTEM_PROFILE_NAME_W,
209 SE_SYSTEMTIME_NAME_W,
210 SE_PROF_SINGLE_PROCESS_NAME_W,
211 SE_INC_BASE_PRIORITY_NAME_W,
212 SE_CREATE_PAGEFILE_NAME_W,
213 SE_CREATE_PERMANENT_NAME_W,
214 SE_BACKUP_NAME_W,
215 SE_RESTORE_NAME_W,
216 SE_SHUTDOWN_NAME_W,
217 SE_DEBUG_NAME_W,
218 SE_AUDIT_NAME_W,
219 SE_SYSTEM_ENVIRONMENT_NAME_W,
220 SE_CHANGE_NOTIFY_NAME_W,
221 SE_REMOTE_SHUTDOWN_NAME_W,
222 SE_UNDOCK_NAME_W,
223 SE_SYNC_AGENT_NAME_W,
224 SE_ENABLE_DELEGATION_NAME_W,
225 SE_MANAGE_VOLUME_NAME_W,
226 SE_IMPERSONATE_NAME_W,
227 SE_CREATE_GLOBAL_NAME_W,
228 };
229
230
231 /* Interface to ntmarta.dll ***************************************************/
232
233 NTMARTA NtMartaStatic = { 0 };
234 static PNTMARTA NtMarta = NULL;
235
236 #define FindNtMartaProc(Name) \
237 NtMartaStatic.Name = (PVOID)GetProcAddress(NtMartaStatic.hDllInstance, \
238 "Acc" # Name ); \
239 if (NtMartaStatic.Name == NULL) \
240 { \
241 return GetLastError(); \
242 }
243
244
245 static DWORD
246 LoadAndInitializeNtMarta(VOID)
247 {
248 /* this code may be executed simultaneously by multiple threads in case they're
249 trying to initialize the interface at the same time, but that's no problem
250 because the pointers returned by GetProcAddress will be the same. However,
251 only one of the threads will change the NtMarta pointer to the NtMartaStatic
252 structure, the others threads will detect that there were other threads
253 initializing the structure faster and will release the reference to the
254 DLL */
255
256 NtMartaStatic.hDllInstance = LoadLibraryW(L"ntmarta.dll");
257 if (NtMartaStatic.hDllInstance == NULL)
258 {
259 return GetLastError();
260 }
261
262 #if 0
263 FindNtMartaProc(LookupAccountTrustee);
264 FindNtMartaProc(LookupAccountName);
265 FindNtMartaProc(LookupAccountSid);
266 FindNtMartaProc(SetEntriesInAList);
267 FindNtMartaProc(ConvertAccessToSecurityDescriptor);
268 FindNtMartaProc(ConvertSDToAccess);
269 FindNtMartaProc(ConvertAclToAccess);
270 FindNtMartaProc(GetAccessForTrustee);
271 FindNtMartaProc(GetExplicitEntries);
272 #endif
273 FindNtMartaProc(RewriteGetNamedRights);
274 FindNtMartaProc(RewriteSetNamedRights);
275 FindNtMartaProc(RewriteGetHandleRights);
276 FindNtMartaProc(RewriteSetHandleRights);
277 FindNtMartaProc(RewriteSetEntriesInAcl);
278 FindNtMartaProc(RewriteGetExplicitEntriesFromAcl);
279 FindNtMartaProc(TreeResetNamedSecurityInfo);
280 FindNtMartaProc(GetInheritanceSource);
281 FindNtMartaProc(FreeIndexArray);
282
283 return ERROR_SUCCESS;
284 }
285
286
287 DWORD
288 CheckNtMartaPresent(VOID)
289 {
290 DWORD ErrorCode;
291
292 if (InterlockedCompareExchangePointer(&NtMarta,
293 NULL,
294 NULL) == NULL)
295 {
296 /* we're the first one trying to use ntmarta, initialize it and change
297 the pointer after initialization */
298 ErrorCode = LoadAndInitializeNtMarta();
299
300 if (ErrorCode == ERROR_SUCCESS)
301 {
302 /* try change the NtMarta pointer */
303 if (InterlockedCompareExchangePointer(&NtMarta,
304 &NtMartaStatic,
305 NULL) != NULL)
306 {
307 /* another thread initialized ntmarta in the meanwhile, release
308 the reference of the dll loaded. */
309 FreeLibrary(NtMartaStatic.hDllInstance);
310 }
311 }
312 #if DBG
313 else
314 {
315 ERR("Failed to initialize ntmarta.dll! Error: 0x%x", ErrorCode);
316 }
317 #endif
318 }
319 else
320 {
321 /* ntmarta was already initialized */
322 ErrorCode = ERROR_SUCCESS;
323 }
324
325 return ErrorCode;
326 }
327
328
329 VOID
330 UnloadNtMarta(VOID)
331 {
332 if (InterlockedExchangePointer(&NtMarta,
333 NULL) != NULL)
334 {
335 FreeLibrary(NtMartaStatic.hDllInstance);
336 }
337 }
338
339
340 /******************************************************************************/
341
342 /*
343 * @implemented
344 */
345 BOOL
346 STDCALL
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 STDCALL
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 STDCALL
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 STDCALL
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 STDCALL
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 STDCALL
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 STDCALL
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 STDCALL
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 STDCALL
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 STDCALL
994 LookupAccountSidA(LPCSTR lpSystemName,
995 PSID lpSid,
996 LPSTR lpName,
997 LPDWORD cchName,
998 LPSTR lpReferencedDomainName,
999 LPDWORD cchReferencedDomainName,
1000 PSID_NAME_USE peUse)
1001 {
1002 UNICODE_STRING NameW, ReferencedDomainNameW, SystemNameW;
1003 DWORD szName, szReferencedDomainName;
1004 BOOL Ret;
1005
1006 /*
1007 * save the buffer sizes the caller passed to us, as they may get modified and
1008 * we require the original values when converting back to ansi
1009 */
1010 szName = *cchName;
1011 szReferencedDomainName = *cchReferencedDomainName;
1012
1013 /*
1014 * allocate buffers for the unicode strings to receive
1015 */
1016
1017 if(szName > 0)
1018 {
1019 NameW.Length = 0;
1020 NameW.MaximumLength = szName * sizeof(WCHAR);
1021 NameW.Buffer = (PWSTR)LocalAlloc(LMEM_FIXED, NameW.MaximumLength);
1022 if(NameW.Buffer == NULL)
1023 {
1024 SetLastError(ERROR_OUTOFMEMORY);
1025 return FALSE;
1026 }
1027 }
1028 else
1029 NameW.Buffer = NULL;
1030
1031 if(szReferencedDomainName > 0)
1032 {
1033 ReferencedDomainNameW.Length = 0;
1034 ReferencedDomainNameW.MaximumLength = szReferencedDomainName * sizeof(WCHAR);
1035 ReferencedDomainNameW.Buffer = (PWSTR)LocalAlloc(LMEM_FIXED, ReferencedDomainNameW.MaximumLength);
1036 if(ReferencedDomainNameW.Buffer == NULL)
1037 {
1038 if(szName > 0)
1039 {
1040 LocalFree(NameW.Buffer);
1041 }
1042 SetLastError(ERROR_OUTOFMEMORY);
1043 return FALSE;
1044 }
1045 }
1046 else
1047 ReferencedDomainNameW.Buffer = NULL;
1048
1049 /*
1050 * convert the system name to unicode - if present
1051 */
1052
1053 if(lpSystemName != NULL)
1054 {
1055 ANSI_STRING SystemNameA;
1056
1057 RtlInitAnsiString(&SystemNameA, lpSystemName);
1058 RtlAnsiStringToUnicodeString(&SystemNameW, &SystemNameA, TRUE);
1059 }
1060 else
1061 SystemNameW.Buffer = NULL;
1062
1063 /*
1064 * it's time to call the unicode version
1065 */
1066
1067 Ret = LookupAccountSidW(SystemNameW.Buffer,
1068 lpSid,
1069 NameW.Buffer,
1070 cchName,
1071 ReferencedDomainNameW.Buffer,
1072 cchReferencedDomainName,
1073 peUse);
1074 if(Ret)
1075 {
1076 /*
1077 * convert unicode strings back to ansi, don't forget that we can't convert
1078 * more than 0xFFFF (USHORT) characters! Also don't forget to explicitly
1079 * terminate the converted string, the Rtl functions don't do that!
1080 */
1081 if(lpName != NULL)
1082 {
1083 ANSI_STRING NameA;
1084
1085 NameA.Length = 0;
1086 NameA.MaximumLength = ((szName <= 0xFFFF) ? (USHORT)szName : 0xFFFF);
1087 NameA.Buffer = lpName;
1088
1089 RtlUnicodeStringToAnsiString(&NameA, &NameW, FALSE);
1090 NameA.Buffer[NameA.Length] = '\0';
1091 }
1092
1093 if(lpReferencedDomainName != NULL)
1094 {
1095 ANSI_STRING ReferencedDomainNameA;
1096
1097 ReferencedDomainNameA.Length = 0;
1098 ReferencedDomainNameA.MaximumLength = ((szReferencedDomainName <= 0xFFFF) ?
1099 (USHORT)szReferencedDomainName : 0xFFFF);
1100 ReferencedDomainNameA.Buffer = lpReferencedDomainName;
1101
1102 RtlUnicodeStringToAnsiString(&ReferencedDomainNameA, &ReferencedDomainNameW, FALSE);
1103 ReferencedDomainNameA.Buffer[ReferencedDomainNameA.Length] = '\0';
1104 }
1105 }
1106
1107 /*
1108 * free previously allocated buffers
1109 */
1110
1111 if(SystemNameW.Buffer != NULL)
1112 {
1113 RtlFreeUnicodeString(&SystemNameW);
1114 }
1115 if(NameW.Buffer != NULL)
1116 {
1117 LocalFree(NameW.Buffer);
1118 }
1119 if(ReferencedDomainNameW.Buffer != NULL)
1120 {
1121 LocalFree(ReferencedDomainNameW.Buffer);
1122 }
1123
1124 return Ret;
1125 }
1126
1127
1128 /******************************************************************************
1129 * LookupAccountSidW [ADVAPI32.@]
1130 *
1131 * @implemented
1132 */
1133 BOOL WINAPI
1134 LookupAccountSidW(LPCWSTR pSystemName,
1135 PSID pSid,
1136 LPWSTR pAccountName,
1137 LPDWORD pdwAccountName,
1138 LPWSTR pDomainName,
1139 LPDWORD pdwDomainName,
1140 PSID_NAME_USE peUse)
1141 {
1142 LSA_UNICODE_STRING SystemName;
1143 LSA_OBJECT_ATTRIBUTES ObjectAttributes = {0};
1144 LSA_HANDLE PolicyHandle = NULL;
1145 NTSTATUS Status;
1146 PLSA_REFERENCED_DOMAIN_LIST ReferencedDomain = NULL;
1147 PLSA_TRANSLATED_NAME TranslatedName = NULL;
1148 BOOL ret;
1149
1150 RtlInitUnicodeString ( &SystemName, pSystemName );
1151 Status = LsaOpenPolicy ( &SystemName, &ObjectAttributes, POLICY_LOOKUP_NAMES, &PolicyHandle );
1152 if ( !NT_SUCCESS(Status) )
1153 {
1154 SetLastError ( LsaNtStatusToWinError(Status) );
1155 return FALSE;
1156 }
1157 Status = LsaLookupSids ( PolicyHandle, 1, &pSid, &ReferencedDomain, &TranslatedName );
1158
1159 LsaClose ( PolicyHandle );
1160
1161 if ( !NT_SUCCESS(Status) || Status == STATUS_SOME_NOT_MAPPED )
1162 {
1163 SetLastError ( LsaNtStatusToWinError(Status) );
1164 ret = FALSE;
1165 }
1166 else
1167 {
1168 ret = TRUE;
1169 if ( TranslatedName )
1170 {
1171 DWORD dwSrcLen = TranslatedName->Name.Length / sizeof(WCHAR);
1172 if ( *pdwAccountName <= dwSrcLen )
1173 {
1174 *pdwAccountName = dwSrcLen + 1;
1175 ret = FALSE;
1176 }
1177 else
1178 {
1179 *pdwAccountName = dwSrcLen;
1180 if (pAccountName)
1181 {
1182 RtlCopyMemory ( pAccountName, TranslatedName->Name.Buffer, TranslatedName->Name.Length );
1183 pAccountName[TranslatedName->Name.Length / sizeof(WCHAR)] = L'\0';
1184 }
1185 }
1186 if ( peUse )
1187 *peUse = TranslatedName->Use;
1188 }
1189
1190 if ( ReferencedDomain )
1191 {
1192 if ( ReferencedDomain->Entries > 0 )
1193 {
1194 DWORD dwSrcLen = ReferencedDomain->Domains[0].Name.Length / sizeof(WCHAR);
1195 if ( *pdwDomainName <= dwSrcLen )
1196 {
1197 *pdwDomainName = dwSrcLen + 1;
1198 ret = FALSE;
1199 }
1200 else
1201 {
1202 *pdwDomainName = dwSrcLen;
1203 RtlCopyMemory ( pDomainName, ReferencedDomain->Domains[0].Name.Buffer, ReferencedDomain->Domains[0].Name.Length );
1204 pDomainName[ReferencedDomain->Domains[0].Name.Length / sizeof(WCHAR)] = L'\0';
1205 }
1206 }
1207 }
1208
1209 if ( !ret )
1210 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1211 }
1212
1213 if ( ReferencedDomain )
1214 LsaFreeMemory ( ReferencedDomain );
1215 if ( TranslatedName )
1216 LsaFreeMemory ( TranslatedName );
1217
1218 return ret;
1219 }
1220
1221
1222
1223 /******************************************************************************
1224 * LookupAccountNameA [ADVAPI32.@]
1225 *
1226 * @implemented
1227 */
1228 BOOL
1229 STDCALL
1230 LookupAccountNameA(LPCSTR SystemName,
1231 LPCSTR AccountName,
1232 PSID Sid,
1233 LPDWORD SidLength,
1234 LPSTR ReferencedDomainName,
1235 LPDWORD hReferencedDomainNameLength,
1236 PSID_NAME_USE SidNameUse)
1237 {
1238 BOOL ret;
1239 UNICODE_STRING lpSystemW;
1240 UNICODE_STRING lpAccountW;
1241 LPWSTR lpReferencedDomainNameW = NULL;
1242
1243 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, SystemName);
1244 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, AccountName);
1245
1246 if (ReferencedDomainName)
1247 lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(),
1248 0,
1249 *hReferencedDomainNameLength * sizeof(WCHAR));
1250
1251 ret = LookupAccountNameW(lpSystemW.Buffer,
1252 lpAccountW.Buffer,
1253 Sid,
1254 SidLength,
1255 lpReferencedDomainNameW,
1256 hReferencedDomainNameLength,
1257 SidNameUse);
1258
1259 if (ret && lpReferencedDomainNameW)
1260 {
1261 WideCharToMultiByte(CP_ACP,
1262 0,
1263 lpReferencedDomainNameW,
1264 *hReferencedDomainNameLength,
1265 ReferencedDomainName,
1266 *hReferencedDomainNameLength,
1267 NULL,
1268 NULL);
1269 }
1270
1271 RtlFreeUnicodeString(&lpSystemW);
1272 RtlFreeUnicodeString(&lpAccountW);
1273 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
1274
1275 return ret;
1276 }
1277
1278
1279 /******************************************************************************
1280 * LookupAccountNameW [ADVAPI32.@]
1281 *
1282 * @unimplemented
1283 */
1284 BOOL
1285 WINAPI
1286 LookupAccountNameW(LPCWSTR lpSystemName,
1287 LPCWSTR lpAccountName,
1288 PSID Sid,
1289 LPDWORD cbSid,
1290 LPWSTR ReferencedDomainName,
1291 LPDWORD cchReferencedDomainName,
1292 PSID_NAME_USE peUse)
1293 {
1294 /* Default implementation: Always return a default SID */
1295 SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
1296 BOOL ret;
1297 PSID pSid;
1298 static const WCHAR dm[] = {'D','O','M','A','I','N',0};
1299 unsigned int i;
1300
1301 TRACE("%s %s %p %p %p %p %p - stub\n", lpSystemName, lpAccountName,
1302 Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
1303
1304 for (i = 0; i < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); i++)
1305 {
1306 if (!wcscmp(lpAccountName, ACCOUNT_SIDS[i].account))
1307 {
1308 if (*cchReferencedDomainName)
1309 *ReferencedDomainName = '\0';
1310 *cchReferencedDomainName = 0;
1311 *peUse = SidTypeWellKnownGroup;
1312 return CreateWellKnownSid(ACCOUNT_SIDS[i].type, NULL, Sid, cbSid);
1313 }
1314 }
1315
1316 ret = AllocateAndInitializeSid(&identifierAuthority,
1317 2,
1318 SECURITY_BUILTIN_DOMAIN_RID,
1319 DOMAIN_ALIAS_RID_ADMINS,
1320 0, 0, 0, 0, 0, 0,
1321 &pSid);
1322
1323 if (!ret)
1324 return FALSE;
1325
1326 if (!RtlValidSid(pSid))
1327 {
1328 FreeSid(pSid);
1329 return FALSE;
1330 }
1331
1332 if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
1333 CopySid(*cbSid, Sid, pSid);
1334
1335 if (*cbSid < GetLengthSid(pSid))
1336 {
1337 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1338 ret = FALSE;
1339 }
1340
1341 *cbSid = GetLengthSid(pSid);
1342
1343 if (ReferencedDomainName != NULL && (*cchReferencedDomainName > wcslen(dm)))
1344 wcscpy(ReferencedDomainName, dm);
1345
1346 if (*cchReferencedDomainName <= wcslen(dm))
1347 {
1348 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1349 ret = FALSE;
1350 }
1351
1352 *cchReferencedDomainName = wcslen(dm)+1;
1353
1354 FreeSid(pSid);
1355
1356 return ret;
1357 }
1358
1359
1360 /**********************************************************************
1361 * LookupPrivilegeValueA EXPORTED
1362 *
1363 * @implemented
1364 */
1365 BOOL
1366 STDCALL
1367 LookupPrivilegeValueA(LPCSTR lpSystemName,
1368 LPCSTR lpName,
1369 PLUID lpLuid)
1370 {
1371 UNICODE_STRING SystemName;
1372 UNICODE_STRING Name;
1373 BOOL Result;
1374
1375 /* Remote system? */
1376 if (lpSystemName != NULL)
1377 {
1378 RtlCreateUnicodeStringFromAsciiz(&SystemName,
1379 (LPSTR)lpSystemName);
1380 }
1381 else
1382 SystemName.Buffer = NULL;
1383
1384 /* Check the privilege name is not NULL */
1385 if (lpName == NULL)
1386 {
1387 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1388 return FALSE;
1389 }
1390
1391 RtlCreateUnicodeStringFromAsciiz(&Name,
1392 (LPSTR)lpName);
1393
1394 Result = LookupPrivilegeValueW(SystemName.Buffer,
1395 Name.Buffer,
1396 lpLuid);
1397
1398 RtlFreeUnicodeString(&Name);
1399
1400 /* Remote system? */
1401 if (SystemName.Buffer != NULL)
1402 {
1403 RtlFreeUnicodeString(&SystemName);
1404 }
1405
1406 return Result;
1407 }
1408
1409
1410 /**********************************************************************
1411 * LookupPrivilegeValueW EXPORTED
1412 *
1413 * @unimplemented
1414 */
1415 BOOL
1416 STDCALL
1417 LookupPrivilegeValueW(LPCWSTR SystemName,
1418 LPCWSTR PrivName,
1419 PLUID Luid)
1420 {
1421 static const WCHAR * const DefaultPrivNames[] =
1422 {
1423 L"SeCreateTokenPrivilege",
1424 L"SeAssignPrimaryTokenPrivilege",
1425 L"SeLockMemoryPrivilege",
1426 L"SeIncreaseQuotaPrivilege",
1427 L"SeUnsolicitedInputPrivilege",
1428 L"SeMachineAccountPrivilege",
1429 L"SeTcbPrivilege",
1430 L"SeSecurityPrivilege",
1431 L"SeTakeOwnershipPrivilege",
1432 L"SeLoadDriverPrivilege",
1433 L"SeSystemProfilePrivilege",
1434 L"SeSystemtimePrivilege",
1435 L"SeProfileSingleProcessPrivilege",
1436 L"SeIncreaseBasePriorityPrivilege",
1437 L"SeCreatePagefilePrivilege",
1438 L"SeCreatePermanentPrivilege",
1439 L"SeBackupPrivilege",
1440 L"SeRestorePrivilege",
1441 L"SeShutdownPrivilege",
1442 L"SeDebugPrivilege",
1443 L"SeAuditPrivilege",
1444 L"SeSystemEnvironmentPrivilege",
1445 L"SeChangeNotifyPrivilege",
1446 L"SeRemoteShutdownPrivilege",
1447 L"SeUndockPrivilege",
1448 L"SeSyncAgentPrivilege",
1449 L"SeEnableDelegationPrivilege",
1450 L"SeManageVolumePrivilege",
1451 L"SeImpersonatePrivilege",
1452 L"SeCreateGlobalPrivilege"
1453 };
1454 unsigned Priv;
1455
1456 if (NULL != SystemName && L'\0' != *SystemName)
1457 {
1458 FIXME("LookupPrivilegeValueW: not implemented for remote system\n");
1459 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1460 return FALSE;
1461 }
1462
1463 for (Priv = 0; Priv < sizeof(DefaultPrivNames) / sizeof(DefaultPrivNames[0]); Priv++)
1464 {
1465 if (0 == wcsicmp(PrivName, DefaultPrivNames[Priv]))
1466 {
1467 Luid->LowPart = Priv + 1;
1468 Luid->HighPart = 0;
1469 return TRUE;
1470 }
1471 }
1472
1473 WARN("LookupPrivilegeValueW: no such privilege %S\n", PrivName);
1474 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1475 return FALSE;
1476 }
1477
1478
1479 /**********************************************************************
1480 * LookupPrivilegeDisplayNameA EXPORTED
1481 *
1482 * @unimplemented
1483 */
1484 BOOL
1485 STDCALL
1486 LookupPrivilegeDisplayNameA(LPCSTR lpSystemName,
1487 LPCSTR lpName,
1488 LPSTR 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 * LookupPrivilegeDisplayNameW EXPORTED
1500 *
1501 * @unimplemented
1502 */
1503 BOOL
1504 STDCALL
1505 LookupPrivilegeDisplayNameW(LPCWSTR lpSystemName,
1506 LPCWSTR lpName,
1507 LPWSTR lpDisplayName,
1508 LPDWORD cbDisplayName,
1509 LPDWORD lpLanguageId)
1510 {
1511 FIXME("%s() not implemented!\n", __FUNCTION__);
1512 SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
1513 return FALSE;
1514 }
1515
1516
1517 /**********************************************************************
1518 * LookupPrivilegeNameA EXPORTED
1519 *
1520 * @implemented
1521 */
1522 BOOL
1523 STDCALL
1524 LookupPrivilegeNameA(LPCSTR lpSystemName,
1525 PLUID lpLuid,
1526 LPSTR lpName,
1527 LPDWORD cchName)
1528 {
1529 UNICODE_STRING lpSystemNameW;
1530 BOOL ret;
1531 DWORD wLen = 0;
1532
1533 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1534
1535 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1536 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1537 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1538 {
1539 LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1540
1541 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1542 &wLen);
1543 if (ret)
1544 {
1545 /* Windows crashes if cchName is NULL, so will I */
1546 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1547 *cchName, NULL, NULL);
1548
1549 if (len == 0)
1550 {
1551 /* WideCharToMultiByte failed */
1552 ret = FALSE;
1553 }
1554 else if (len > *cchName)
1555 {
1556 *cchName = len;
1557 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1558 ret = FALSE;
1559 }
1560 else
1561 {
1562 /* WideCharToMultiByte succeeded, output length needs to be
1563 * length not including NULL terminator
1564 */
1565 *cchName = len - 1;
1566 }
1567 }
1568 HeapFree(GetProcessHeap(), 0, lpNameW);
1569 }
1570 RtlFreeUnicodeString(&lpSystemNameW);
1571 return ret;
1572 }
1573
1574
1575 /**********************************************************************
1576 * LookupPrivilegeNameW EXPORTED
1577 *
1578 * @implemented
1579 */
1580 BOOL
1581 STDCALL
1582 LookupPrivilegeNameW(LPCWSTR lpSystemName,
1583 PLUID lpLuid,
1584 LPWSTR lpName,
1585 LPDWORD cchName)
1586 {
1587 size_t privNameLen;
1588
1589 TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
1590
1591 if (!ADVAPI_IsLocalComputer(lpSystemName))
1592 {
1593 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1594 return FALSE;
1595 }
1596 if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1597 lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
1598 {
1599 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1600 return FALSE;
1601 }
1602 privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
1603 /* Windows crashes if cchName is NULL, so will I */
1604 if (*cchName <= privNameLen)
1605 {
1606 *cchName = privNameLen + 1;
1607 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1608 return FALSE;
1609 }
1610 else
1611 {
1612 strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
1613 *cchName = privNameLen;
1614 return TRUE;
1615 }
1616 }
1617
1618
1619 static DWORD
1620 pGetSecurityInfoCheck(SECURITY_INFORMATION SecurityInfo,
1621 PSID *ppsidOwner,
1622 PSID *ppsidGroup,
1623 PACL *ppDacl,
1624 PACL *ppSacl,
1625 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
1626 {
1627 if ((SecurityInfo & (OWNER_SECURITY_INFORMATION |
1628 GROUP_SECURITY_INFORMATION |
1629 DACL_SECURITY_INFORMATION |
1630 SACL_SECURITY_INFORMATION)) &&
1631 ppSecurityDescriptor == NULL)
1632 {
1633 /* if one of the SIDs or ACLs are present, the security descriptor
1634 most not be NULL */
1635 return ERROR_INVALID_PARAMETER;
1636 }
1637 else
1638 {
1639 /* reset the pointers unless they're ignored */
1640 if ((SecurityInfo & OWNER_SECURITY_INFORMATION) &&
1641 ppsidOwner != NULL)
1642 {
1643 *ppsidOwner = NULL;
1644 }
1645 if ((SecurityInfo & GROUP_SECURITY_INFORMATION) &&
1646 ppsidGroup != NULL)
1647 {
1648 *ppsidGroup = NULL;
1649 }
1650 if ((SecurityInfo & DACL_SECURITY_INFORMATION) &&
1651 ppDacl != NULL)
1652 {
1653 *ppDacl = NULL;
1654 }
1655 if ((SecurityInfo & SACL_SECURITY_INFORMATION) &&
1656 ppSacl != NULL)
1657 {
1658 *ppSacl = NULL;
1659 }
1660
1661 if (SecurityInfo & (OWNER_SECURITY_INFORMATION |
1662 GROUP_SECURITY_INFORMATION |
1663 DACL_SECURITY_INFORMATION |
1664 SACL_SECURITY_INFORMATION))
1665 {
1666 *ppSecurityDescriptor = NULL;
1667 }
1668
1669 return ERROR_SUCCESS;
1670 }
1671 }
1672
1673
1674 static DWORD
1675 pSetSecurityInfoCheck(PSECURITY_DESCRIPTOR pSecurityDescriptor,
1676 SECURITY_INFORMATION SecurityInfo,
1677 PSID psidOwner,
1678 PSID psidGroup,
1679 PACL pDacl,
1680 PACL pSacl)
1681 {
1682 /* initialize a security descriptor on the stack */
1683 if (!InitializeSecurityDescriptor(pSecurityDescriptor,
1684 SECURITY_DESCRIPTOR_REVISION))
1685 {
1686 return GetLastError();
1687 }
1688
1689 if (SecurityInfo & OWNER_SECURITY_INFORMATION)
1690 {
1691 if (RtlValidSid(psidOwner))
1692 {
1693 if (!SetSecurityDescriptorOwner(pSecurityDescriptor,
1694 psidOwner,
1695 FALSE))
1696 {
1697 return GetLastError();
1698 }
1699 }
1700 else
1701 {
1702 return ERROR_INVALID_PARAMETER;
1703 }
1704 }
1705
1706 if (SecurityInfo & GROUP_SECURITY_INFORMATION)
1707 {
1708 if (RtlValidSid(psidGroup))
1709 {
1710 if (!SetSecurityDescriptorGroup(pSecurityDescriptor,
1711 psidGroup,
1712 FALSE))
1713 {
1714 return GetLastError();
1715 }
1716 }
1717 else
1718 {
1719 return ERROR_INVALID_PARAMETER;
1720 }
1721 }
1722
1723 if (SecurityInfo & DACL_SECURITY_INFORMATION)
1724 {
1725 if (pDacl != NULL)
1726 {
1727 if (SetSecurityDescriptorDacl(pSecurityDescriptor,
1728 TRUE,
1729 pDacl,
1730 FALSE))
1731 {
1732 /* check if the DACL needs to be protected from being
1733 modified by inheritable ACEs */
1734 if (SecurityInfo & PROTECTED_DACL_SECURITY_INFORMATION)
1735 {
1736 goto ProtectDacl;
1737 }
1738 }
1739 else
1740 {
1741 return GetLastError();
1742 }
1743 }
1744 else
1745 {
1746 ProtectDacl:
1747 /* protect the DACL from being modified by inheritable ACEs */
1748 if (!SetSecurityDescriptorControl(pSecurityDescriptor,
1749 SE_DACL_PROTECTED,
1750 SE_DACL_PROTECTED))
1751 {
1752 return GetLastError();
1753 }
1754 }
1755 }
1756
1757 if (SecurityInfo & SACL_SECURITY_INFORMATION)
1758 {
1759 if (pSacl != NULL)
1760 {
1761 if (SetSecurityDescriptorSacl(pSecurityDescriptor,
1762 TRUE,
1763 pSacl,
1764 FALSE))
1765 {
1766 /* check if the SACL needs to be protected from being
1767 modified by inheritable ACEs */
1768 if (SecurityInfo & PROTECTED_SACL_SECURITY_INFORMATION)
1769 {
1770 goto ProtectSacl;
1771 }
1772 }
1773 else
1774 {
1775 return GetLastError();
1776 }
1777 }
1778 else
1779 {
1780 ProtectSacl:
1781 /* protect the SACL from being modified by inheritable ACEs */
1782 if (!SetSecurityDescriptorControl(pSecurityDescriptor,
1783 SE_SACL_PROTECTED,
1784 SE_SACL_PROTECTED))
1785 {
1786 return GetLastError();
1787 }
1788 }
1789 }
1790
1791 return ERROR_SUCCESS;
1792 }
1793
1794
1795 /**********************************************************************
1796 * GetNamedSecurityInfoW EXPORTED
1797 *
1798 * @implemented
1799 */
1800 DWORD
1801 STDCALL
1802 GetNamedSecurityInfoW(LPWSTR pObjectName,
1803 SE_OBJECT_TYPE ObjectType,
1804 SECURITY_INFORMATION SecurityInfo,
1805 PSID *ppsidOwner,
1806 PSID *ppsidGroup,
1807 PACL *ppDacl,
1808 PACL *ppSacl,
1809 PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
1810 {
1811 DWORD ErrorCode;
1812
1813 if (pObjectName != NULL)
1814 {
1815 ErrorCode = CheckNtMartaPresent();
1816 if (ErrorCode == ERROR_SUCCESS)
1817 {
1818 ErrorCode = pGetSecurityInfoCheck(SecurityInfo,
1819 ppsidOwner,
1820 ppsidGroup,
1821 ppDacl,
1822 ppSacl,
1823 ppSecurityDescriptor);
1824
1825 if (ErrorCode == ERROR_SUCCESS)
1826 {
1827 /* call the MARTA provider */
1828 ErrorCode = AccRewriteGetNamedRights(pObjectName,
1829 ObjectType,
1830 SecurityInfo,
1831 ppsidOwner,
1832 ppsidGroup,
1833 ppDacl,
1834 ppSacl,
1835 ppSecurityDescriptor);
1836 }
1837 }
1838 }
1839 else
1840 ErrorCode = ERROR_INVALID_PARAMETER;
1841
1842 return ErrorCode;
1843 }
1844
1845
1846 /**********************************************************************
1847 * GetNamedSecurityInfoA EXPORTED
1848 *
1849 * @implemented
1850 */
1851 DWORD
1852 STDCALL
1853 GetNamedSecurityInfoA(LPSTR pObjectName,
1854 SE_OBJECT_TYPE ObjectType,
1855 SECURITY_INFORMATION SecurityInfo,
1856 PSID *ppsidOwner,
1857 PSID *ppsidGroup,
1858 PACL *ppDacl,
1859 PACL *ppSacl,
1860 PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
1861 {
1862 UNICODE_STRING ObjectName;
1863 NTSTATUS Status;
1864 DWORD Ret;
1865
1866 Status = RtlCreateUnicodeStringFromAsciiz(&ObjectName,
1867 pObjectName);
1868 if (!NT_SUCCESS(Status))
1869 {
1870 return RtlNtStatusToDosError(Status);
1871 }
1872
1873 Ret = GetNamedSecurityInfoW(ObjectName.Buffer,
1874 ObjectType,
1875 SecurityInfo,
1876 ppsidOwner,
1877 ppsidGroup,
1878 ppDacl,
1879 ppSacl,
1880 ppSecurityDescriptor);
1881
1882 RtlFreeUnicodeString(&ObjectName);
1883
1884 return Ret;
1885 }
1886
1887
1888 /**********************************************************************
1889 * SetNamedSecurityInfoW EXPORTED
1890 *
1891 * @implemented
1892 */
1893 DWORD
1894 STDCALL
1895 SetNamedSecurityInfoW(LPWSTR pObjectName,
1896 SE_OBJECT_TYPE ObjectType,
1897 SECURITY_INFORMATION SecurityInfo,
1898 PSID psidOwner,
1899 PSID psidGroup,
1900 PACL pDacl,
1901 PACL pSacl)
1902 {
1903 DWORD ErrorCode;
1904
1905 if (pObjectName != NULL)
1906 {
1907 ErrorCode = CheckNtMartaPresent();
1908 if (ErrorCode == ERROR_SUCCESS)
1909 {
1910 SECURITY_DESCRIPTOR SecurityDescriptor;
1911
1912 ErrorCode = pSetSecurityInfoCheck(&SecurityDescriptor,
1913 SecurityInfo,
1914 psidOwner,
1915 psidGroup,
1916 pDacl,
1917 pSacl);
1918
1919 if (ErrorCode == ERROR_SUCCESS)
1920 {
1921 /* call the MARTA provider */
1922 ErrorCode = AccRewriteSetNamedRights(pObjectName,
1923 ObjectType,
1924 SecurityInfo,
1925 &SecurityDescriptor);
1926 }
1927 }
1928 }
1929 else
1930 ErrorCode = ERROR_INVALID_PARAMETER;
1931
1932 return ErrorCode;
1933 }
1934
1935
1936 /**********************************************************************
1937 * SetNamedSecurityInfoA EXPORTED
1938 *
1939 * @implemented
1940 */
1941 DWORD
1942 STDCALL
1943 SetNamedSecurityInfoA(LPSTR pObjectName,
1944 SE_OBJECT_TYPE ObjectType,
1945 SECURITY_INFORMATION SecurityInfo,
1946 PSID psidOwner,
1947 PSID psidGroup,
1948 PACL pDacl,
1949 PACL pSacl)
1950 {
1951 UNICODE_STRING ObjectName;
1952 NTSTATUS Status;
1953 DWORD Ret;
1954
1955 Status = RtlCreateUnicodeStringFromAsciiz(&ObjectName,
1956 pObjectName);
1957 if (!NT_SUCCESS(Status))
1958 {
1959 return RtlNtStatusToDosError(Status);
1960 }
1961
1962 Ret = SetNamedSecurityInfoW(ObjectName.Buffer,
1963 ObjectType,
1964 SecurityInfo,
1965 psidOwner,
1966 psidGroup,
1967 pDacl,
1968 pSacl);
1969
1970 RtlFreeUnicodeString(&ObjectName);
1971
1972 return Ret;
1973 }
1974
1975
1976 /**********************************************************************
1977 * GetSecurityInfo EXPORTED
1978 *
1979 * @implemented
1980 */
1981 DWORD
1982 STDCALL
1983 GetSecurityInfo(HANDLE handle,
1984 SE_OBJECT_TYPE ObjectType,
1985 SECURITY_INFORMATION SecurityInfo,
1986 PSID *ppsidOwner,
1987 PSID *ppsidGroup,
1988 PACL *ppDacl,
1989 PACL *ppSacl,
1990 PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
1991 {
1992 DWORD ErrorCode;
1993
1994 if (handle != NULL)
1995 {
1996 ErrorCode = CheckNtMartaPresent();
1997 if (ErrorCode == ERROR_SUCCESS)
1998 {
1999 ErrorCode = pGetSecurityInfoCheck(SecurityInfo,
2000 ppsidOwner,
2001 ppsidGroup,
2002 ppDacl,
2003 ppSacl,
2004 ppSecurityDescriptor);
2005
2006 if (ErrorCode == ERROR_SUCCESS)
2007 {
2008 /* call the MARTA provider */
2009 ErrorCode = AccRewriteGetHandleRights(handle,
2010 ObjectType,
2011 SecurityInfo,
2012 ppsidOwner,
2013 ppsidGroup,
2014 ppDacl,
2015 ppSacl,
2016 ppSecurityDescriptor);
2017 }
2018 }
2019 }
2020 else
2021 ErrorCode = ERROR_INVALID_HANDLE;
2022
2023 return ErrorCode;
2024 }
2025
2026
2027 /**********************************************************************
2028 * SetSecurityInfo EXPORTED
2029 *
2030 * @implemented
2031 */
2032 DWORD
2033 WINAPI
2034 SetSecurityInfo(HANDLE handle,
2035 SE_OBJECT_TYPE ObjectType,
2036 SECURITY_INFORMATION SecurityInfo,
2037 PSID psidOwner,
2038 PSID psidGroup,
2039 PACL pDacl,
2040 PACL pSacl)
2041 {
2042 DWORD ErrorCode;
2043
2044 if (handle != NULL)
2045 {
2046 ErrorCode = CheckNtMartaPresent();
2047 if (ErrorCode == ERROR_SUCCESS)
2048 {
2049 SECURITY_DESCRIPTOR SecurityDescriptor;
2050
2051 ErrorCode = pSetSecurityInfoCheck(&SecurityDescriptor,
2052 SecurityInfo,
2053 psidOwner,
2054 psidGroup,
2055 pDacl,
2056 pSacl);
2057
2058 if (ErrorCode == ERROR_SUCCESS)
2059 {
2060 /* call the MARTA provider */
2061 ErrorCode = AccRewriteSetHandleRights(handle,
2062 ObjectType,
2063 SecurityInfo,
2064 &SecurityDescriptor);
2065 }
2066 }
2067 }
2068 else
2069 ErrorCode = ERROR_INVALID_HANDLE;
2070
2071 return ErrorCode;
2072 }
2073
2074
2075 /******************************************************************************
2076 * GetSecurityInfoExW EXPORTED
2077 */
2078 DWORD
2079 WINAPI
2080 GetSecurityInfoExA(HANDLE hObject,
2081 SE_OBJECT_TYPE ObjectType,
2082 SECURITY_INFORMATION SecurityInfo,
2083 LPCSTR lpProvider,
2084 LPCSTR lpProperty,
2085 PACTRL_ACCESSA *ppAccessList,
2086 PACTRL_AUDITA *ppAuditList,
2087 LPSTR *lppOwner,
2088 LPSTR *lppGroup)
2089 {
2090 FIXME("%s() not implemented!\n", __FUNCTION__);
2091 return ERROR_BAD_PROVIDER;
2092 }
2093
2094
2095 /******************************************************************************
2096 * GetSecurityInfoExW EXPORTED
2097 */
2098 DWORD
2099 WINAPI
2100 GetSecurityInfoExW(HANDLE hObject,
2101 SE_OBJECT_TYPE ObjectType,
2102 SECURITY_INFORMATION SecurityInfo,
2103 LPCWSTR lpProvider,
2104 LPCWSTR lpProperty,
2105 PACTRL_ACCESSW *ppAccessList,
2106 PACTRL_AUDITW *ppAuditList,
2107 LPWSTR *lppOwner,
2108 LPWSTR *lppGroup)
2109 {
2110 FIXME("%s() not implemented!\n", __FUNCTION__);
2111 return ERROR_BAD_PROVIDER;
2112 }
2113
2114
2115 /**********************************************************************
2116 * ImpersonateNamedPipeClient EXPORTED
2117 *
2118 * @implemented
2119 */
2120 BOOL
2121 STDCALL
2122 ImpersonateNamedPipeClient(HANDLE hNamedPipe)
2123 {
2124 IO_STATUS_BLOCK StatusBlock;
2125 NTSTATUS Status;
2126
2127 TRACE("ImpersonateNamedPipeClient() called\n");
2128
2129 Status = NtFsControlFile(hNamedPipe,
2130 NULL,
2131 NULL,
2132 NULL,
2133 &StatusBlock,
2134 FSCTL_PIPE_IMPERSONATE,
2135 NULL,
2136 0,
2137 NULL,
2138 0);
2139 if (!NT_SUCCESS(Status))
2140 {
2141 SetLastError(RtlNtStatusToDosError(Status));
2142 return FALSE;
2143 }
2144
2145 return TRUE;
2146 }
2147
2148
2149 /*
2150 * @implemented
2151 */
2152 BOOL
2153 STDCALL
2154 CreatePrivateObjectSecurity(PSECURITY_DESCRIPTOR ParentDescriptor,
2155 PSECURITY_DESCRIPTOR CreatorDescriptor,
2156 PSECURITY_DESCRIPTOR *NewDescriptor,
2157 BOOL IsDirectoryObject,
2158 HANDLE Token,
2159 PGENERIC_MAPPING GenericMapping)
2160 {
2161 NTSTATUS Status;
2162
2163 Status = RtlNewSecurityObject(ParentDescriptor,
2164 CreatorDescriptor,
2165 NewDescriptor,
2166 IsDirectoryObject,
2167 Token,
2168 GenericMapping);
2169 if (!NT_SUCCESS(Status))
2170 {
2171 SetLastError(RtlNtStatusToDosError(Status));
2172 return FALSE;
2173 }
2174
2175 return TRUE;
2176 }
2177
2178
2179 /*
2180 * @unimplemented
2181 */
2182 BOOL
2183 STDCALL
2184 CreatePrivateObjectSecurityEx(PSECURITY_DESCRIPTOR ParentDescriptor,
2185 PSECURITY_DESCRIPTOR CreatorDescriptor,
2186 PSECURITY_DESCRIPTOR* NewDescriptor,
2187 GUID* ObjectType,
2188 BOOL IsContainerObject,
2189 ULONG AutoInheritFlags,
2190 HANDLE Token,
2191 PGENERIC_MAPPING GenericMapping)
2192 {
2193 FIXME("%s() not implemented!\n", __FUNCTION__);
2194 return FALSE;
2195 }
2196
2197
2198 /*
2199 * @unimplemented
2200 */
2201 BOOL
2202 STDCALL
2203 CreatePrivateObjectSecurityWithMultipleInheritance(PSECURITY_DESCRIPTOR ParentDescriptor,
2204 PSECURITY_DESCRIPTOR CreatorDescriptor,
2205 PSECURITY_DESCRIPTOR* NewDescriptor,
2206 GUID** ObjectTypes,
2207 ULONG GuidCount,
2208 BOOL IsContainerObject,
2209 ULONG AutoInheritFlags,
2210 HANDLE Token,
2211 PGENERIC_MAPPING GenericMapping)
2212 {
2213 FIXME("%s() not implemented!\n", __FUNCTION__);
2214 return FALSE;
2215 }
2216
2217
2218 /*
2219 * @implemented
2220 */
2221 BOOL
2222 STDCALL
2223 DestroyPrivateObjectSecurity(PSECURITY_DESCRIPTOR *ObjectDescriptor)
2224 {
2225 NTSTATUS Status;
2226
2227 Status = RtlDeleteSecurityObject(ObjectDescriptor);
2228 if (!NT_SUCCESS(Status))
2229 {
2230 SetLastError(RtlNtStatusToDosError(Status));
2231 return FALSE;
2232 }
2233
2234 return TRUE;
2235 }
2236
2237
2238 /*
2239 * @implemented
2240 */
2241 BOOL
2242 STDCALL
2243 GetPrivateObjectSecurity(PSECURITY_DESCRIPTOR ObjectDescriptor,
2244 SECURITY_INFORMATION SecurityInformation,
2245 PSECURITY_DESCRIPTOR ResultantDescriptor,
2246 DWORD DescriptorLength,
2247 PDWORD ReturnLength)
2248 {
2249 NTSTATUS Status;
2250
2251 Status = RtlQuerySecurityObject(ObjectDescriptor,
2252 SecurityInformation,
2253 ResultantDescriptor,
2254 DescriptorLength,
2255 ReturnLength);
2256 if (!NT_SUCCESS(Status))
2257 {
2258 SetLastError(RtlNtStatusToDosError(Status));
2259 return FALSE;
2260 }
2261
2262 return TRUE;
2263 }
2264
2265
2266 /*
2267 * @implemented
2268 */
2269 BOOL
2270 STDCALL
2271 SetPrivateObjectSecurity(SECURITY_INFORMATION SecurityInformation,
2272 PSECURITY_DESCRIPTOR ModificationDescriptor,
2273 PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
2274 PGENERIC_MAPPING GenericMapping,
2275 HANDLE Token)
2276 {
2277 NTSTATUS Status;
2278
2279 Status = RtlSetSecurityObject(SecurityInformation,
2280 ModificationDescriptor,
2281 ObjectsSecurityDescriptor,
2282 GenericMapping,
2283 Token);
2284 if (!NT_SUCCESS(Status))
2285 {
2286 SetLastError(RtlNtStatusToDosError(Status));
2287 return FALSE;
2288 }
2289
2290 return TRUE;
2291 }
2292
2293
2294 /*
2295 * @implemented
2296 */
2297 DWORD
2298 STDCALL
2299 TreeResetNamedSecurityInfoW(LPWSTR pObjectName,
2300 SE_OBJECT_TYPE ObjectType,
2301 SECURITY_INFORMATION SecurityInfo,
2302 PSID pOwner,
2303 PSID pGroup,
2304 PACL pDacl,
2305 PACL pSacl,
2306 BOOL KeepExplicit,
2307 FN_PROGRESSW fnProgress,
2308 PROG_INVOKE_SETTING ProgressInvokeSetting,
2309 PVOID Args)
2310 {
2311 DWORD ErrorCode;
2312
2313 if (pObjectName != NULL)
2314 {
2315 ErrorCode = CheckNtMartaPresent();
2316 if (ErrorCode == ERROR_SUCCESS)
2317 {
2318 switch (ObjectType)
2319 {
2320 case SE_FILE_OBJECT:
2321 case SE_REGISTRY_KEY:
2322 {
2323 /* check the SecurityInfo flags for sanity (both, the protected
2324 and unprotected dacl/sacl flag must not be passed together) */
2325 if (((SecurityInfo & DACL_SECURITY_INFORMATION) &&
2326 (SecurityInfo & (PROTECTED_DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION)) ==
2327 (PROTECTED_DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION))
2328
2329 ||
2330
2331 ((SecurityInfo & SACL_SECURITY_INFORMATION) &&
2332 (SecurityInfo & (PROTECTED_SACL_SECURITY_INFORMATION | UNPROTECTED_SACL_SECURITY_INFORMATION)) ==
2333 (PROTECTED_SACL_SECURITY_INFORMATION | UNPROTECTED_SACL_SECURITY_INFORMATION)))
2334 {
2335 ErrorCode = ERROR_INVALID_PARAMETER;
2336 break;
2337 }
2338
2339 /* call the MARTA provider */
2340 ErrorCode = AccTreeResetNamedSecurityInfo(pObjectName,
2341 ObjectType,
2342 SecurityInfo,
2343 pOwner,
2344 pGroup,
2345 pDacl,
2346 pSacl,
2347 KeepExplicit,
2348 fnProgress,
2349 ProgressInvokeSetting,
2350 Args);
2351 break;
2352 }
2353
2354 default:
2355 /* object type not supported */
2356 ErrorCode = ERROR_INVALID_PARAMETER;
2357 break;
2358 }
2359 }
2360 }
2361 else
2362 ErrorCode = ERROR_INVALID_PARAMETER;
2363
2364 return ErrorCode;
2365 }
2366
2367 #ifdef HAS_FN_PROGRESSW
2368
2369 typedef struct _INERNAL_FNPROGRESSW_DATA
2370 {
2371 FN_PROGRESSA fnProgress;
2372 PVOID Args;
2373 } INERNAL_FNPROGRESSW_DATA, *PINERNAL_FNPROGRESSW_DATA;
2374
2375 static VOID STDCALL
2376 InternalfnProgressW(LPWSTR pObjectName,
2377 DWORD Status,
2378 PPROG_INVOKE_SETTING pInvokeSetting,
2379 PVOID Args,
2380 BOOL SecuritySet)
2381 {
2382 PINERNAL_FNPROGRESSW_DATA pifnProgressData = (PINERNAL_FNPROGRESSW_DATA)Args;
2383 INT ObjectNameSize;
2384 LPSTR pObjectNameA;
2385
2386 ObjectNameSize = WideCharToMultiByte(CP_ACP,
2387 0,
2388 pObjectName,
2389 -1,
2390 NULL,
2391 0,
2392 NULL,
2393 NULL);
2394
2395 if (ObjectNameSize > 0)
2396 {
2397 pObjectNameA = RtlAllocateHeap(RtlGetProcessHeap(),
2398 0,
2399 ObjectNameSize);
2400 if (pObjectNameA != NULL)
2401 {
2402 pObjectNameA[0] = '\0';
2403 WideCharToMultiByte(CP_ACP,
2404 0,
2405 pObjectName,
2406 -1,
2407 pObjectNameA,
2408 ObjectNameSize,
2409 NULL,
2410 NULL);
2411
2412 pifnProgressData->fnProgress((LPWSTR)pObjectNameA, /* FIXME: wrong cast!! */
2413 Status,
2414 pInvokeSetting,
2415 pifnProgressData->Args,
2416 SecuritySet);
2417
2418 RtlFreeHeap(RtlGetProcessHeap(),
2419 0,
2420 pObjectNameA);
2421 }
2422 }
2423 }
2424 #endif
2425
2426
2427 /*
2428 * @implemented
2429 */
2430 DWORD
2431 STDCALL
2432 TreeResetNamedSecurityInfoA(LPSTR pObjectName,
2433 SE_OBJECT_TYPE ObjectType,
2434 SECURITY_INFORMATION SecurityInfo,
2435 PSID pOwner,
2436 PSID pGroup,
2437 PACL pDacl,
2438 PACL pSacl,
2439 BOOL KeepExplicit,
2440 FN_PROGRESSA fnProgress,
2441 PROG_INVOKE_SETTING ProgressInvokeSetting,
2442 PVOID Args)
2443 {
2444 #ifndef HAS_FN_PROGRESSW
2445 /* That's all this function does, at least up to w2k3... Even MS was too
2446 lazy to implement it... */
2447 return ERROR_CALL_NOT_IMPLEMENTED;
2448 #else
2449 INERNAL_FNPROGRESSW_DATA ifnProgressData;
2450 UNICODE_STRING ObjectName;
2451 NTSTATUS Status;
2452 DWORD Ret;
2453
2454 Status = RtlCreateUnicodeStringFromAsciiz(&ObjectName,
2455 pObjectName);
2456 if (!NT_SUCCESS(Status))
2457 {
2458 return RtlNtStatusToDosError(Status);
2459 }
2460
2461 ifnProgressData.fnProgress = fnProgress;
2462 ifnProgressData.Args = Args;
2463
2464 Ret = TreeResetNamedSecurityInfoW(ObjectName.Buffer,
2465 ObjectType,
2466 SecurityInfo,
2467 pOwner,
2468 pGroup,
2469 pDacl,
2470 pSacl,
2471 KeepExplicit,
2472 (fnProgress != NULL ? InternalfnProgressW : NULL),
2473 ProgressInvokeSetting,
2474 &ifnProgressData);
2475
2476 RtlFreeUnicodeString(&ObjectName);
2477
2478 return Ret;
2479 #endif
2480 }
2481
2482 /* EOF */