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