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