Implement LookupPrivilegeNameW based on Wine code.
[reactos.git] / reactos / dll / win32 / advapi32 / sec / misc.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/advapi32/sec/misc.c
5 * PURPOSE: Miscellaneous security functions (some ported from Wine)
6 */
7
8 #include <advapi32.h>
9 #include "wine/unicode.h"
10 #include "wine/debug.h"
11
12 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
13
14 /* Needed for LookupAccountNameW implementation from Wine */
15
16 typedef struct _AccountSid
17 {
18 WELL_KNOWN_SID_TYPE type;
19 LPCWSTR account;
20 LPCWSTR domain;
21 SID_NAME_USE name_use;
22 } AccountSid;
23
24 static const WCHAR Account_Operators[] = { 'A','c','c','o','u','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
25 static const WCHAR Administrator[] = {'A','d','m','i','n','i','s','t','r','a','t','o','r',0 };
26 static const WCHAR Administrators[] = { 'A','d','m','i','n','i','s','t','r','a','t','o','r','s',0 };
27 static const WCHAR ANONYMOUS_LOGON[] = { 'A','N','O','N','Y','M','O','U','S',' ','L','O','G','O','N',0 };
28 static const WCHAR Authenticated_Users[] = { 'A','u','t','h','e','n','t','i','c','a','t','e','d',' ','U','s','e','r','s',0 };
29 static const WCHAR Backup_Operators[] = { 'B','a','c','k','u','p',' ','O','p','e','r','a','t','o','r','s',0 };
30 static const WCHAR BATCH[] = { 'B','A','T','C','H',0 };
31 static const WCHAR Blank[] = { 0 };
32 static const WCHAR BUILTIN[] = { 'B','U','I','L','T','I','N',0 };
33 static const WCHAR Cert_Publishers[] = { 'C','e','r','t',' ','P','u','b','l','i','s','h','e','r','s',0 };
34 static const WCHAR CREATOR_GROUP[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',0 };
35 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 };
36 static const WCHAR CREATOR_OWNER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',0 };
37 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 };
38 static const WCHAR DIALUP[] = { 'D','I','A','L','U','P',0 };
39 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 };
40 static const WCHAR DOMAIN[] = {'D','O','M','A','I','N',0};
41 static const WCHAR Domain_Admins[] = { 'D','o','m','a','i','n',' ','A','d','m','i','n','s',0 };
42 static const WCHAR Domain_Computers[] = { 'D','o','m','a','i','n',' ','C','o','m','p','u','t','e','r','s',0 };
43 static const WCHAR Domain_Controllers[] = { 'D','o','m','a','i','n',' ','C','o','n','t','r','o','l','l','e','r','s',0 };
44 static const WCHAR Domain_Guests[] = { 'D','o','m','a','i','n',' ','G','u','e','s','t','s',0 };
45 static const WCHAR Domain_Users[] = { 'D','o','m','a','i','n',' ','U','s','e','r','s',0 };
46 static const WCHAR Enterprise_Admins[] = { 'E','n','t','e','r','p','r','i','s','e',' ','A','d','m','i','n','s',0 };
47 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 };
48 static const WCHAR Everyone[] = { 'E','v','e','r','y','o','n','e',0 };
49 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 };
50 static const WCHAR Guest[] = { 'G','u','e','s','t',0 };
51 static const WCHAR Guests[] = { 'G','u','e','s','t','s',0 };
52 static const WCHAR INTERACTIVE[] = { 'I','N','T','E','R','A','C','T','I','V','E',0 };
53 static const WCHAR LOCAL[] = { 'L','O','C','A','L',0 };
54 static const WCHAR LOCAL_SERVICE[] = { 'L','O','C','A','L',' ','S','E','R','V','I','C','E',0 };
55 static const WCHAR NETWORK[] = { 'N','E','T','W','O','R','K',0 };
56 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 };
57 static const WCHAR NETWORK_SERVICE[] = { 'N','E','T','W','O','R','K',' ','S','E','R','V','I','C','E',0 };
58 static const WCHAR NT_AUTHORITY[] = { 'N','T',' ','A','U','T','H','O','R','I','T','Y',0 };
59 static const WCHAR NT_Pseudo_Domain[] = { 'N','T',' ','P','s','e','u','d','o',' ','D','o','m','a','i','n',0 };
60 static const WCHAR NTML_Authentication[] = { 'N','T','M','L',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
61 static const WCHAR NULL_SID[] = { 'N','U','L','L',' ','S','I','D',0 };
62 static const WCHAR Other_Organization[] = { 'O','t','h','e','r',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
63 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 };
64 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 };
65 static const WCHAR Power_Users[] = { 'P','o','w','e','r',' ','U','s','e','r','s',0 };
66 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 };
67 static const WCHAR Print_Operators[] = { 'P','r','i','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
68 static const WCHAR PROXY[] = { 'P','R','O','X','Y',0 };
69 static const WCHAR RAS_and_IAS_Servers[] = { 'R','A','S',' ','a','n','d',' ','I','A','S',' ','S','e','r','v','e','r','s',0 };
70 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 };
71 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 };
72 static const WCHAR Replicators[] = { 'R','e','p','l','i','c','a','t','o','r','s',0 };
73 static const WCHAR RESTRICTED[] = { 'R','E','S','T','R','I','C','T','E','D',0 };
74 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 };
75 static const WCHAR Schema_Admins[] = { 'S','c','h','e','m','a',' ','A','d','m','i','n','s',0 };
76 static const WCHAR SELF[] = { 'S','E','L','F',0 };
77 static const WCHAR Server_Operators[] = { 'S','e','r','v','e','r',' ','O','p','e','r','a','t','o','r','s',0 };
78 static const WCHAR SERVICE[] = { 'S','E','R','V','I','C','E',0 };
79 static const WCHAR SYSTEM[] = { 'S','Y','S','T','E','M',0 };
80 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 };
81 static const WCHAR This_Organization[] = { 'T','h','i','s',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
82 static const WCHAR Users[] = { 'U','s','e','r','s',0 };
83
84 static const AccountSid ACCOUNT_SIDS[] = {
85 { WinNullSid, NULL_SID, Blank, SidTypeWellKnownGroup },
86 { WinWorldSid, Everyone, Blank, SidTypeWellKnownGroup },
87 { WinLocalSid, LOCAL, Blank, SidTypeWellKnownGroup },
88 { WinCreatorOwnerSid, CREATOR_OWNER, Blank, SidTypeWellKnownGroup },
89 { WinCreatorGroupSid, CREATOR_GROUP, Blank, SidTypeWellKnownGroup },
90 { WinCreatorOwnerServerSid, CREATOR_OWNER_SERVER, Blank, SidTypeWellKnownGroup },
91 { WinCreatorGroupServerSid, CREATOR_GROUP_SERVER, Blank, SidTypeWellKnownGroup },
92 { WinNtAuthoritySid, NT_Pseudo_Domain, NT_Pseudo_Domain, SidTypeDomain },
93 { WinDialupSid, DIALUP, NT_AUTHORITY, SidTypeWellKnownGroup },
94 { WinNetworkSid, NETWORK, NT_AUTHORITY, SidTypeWellKnownGroup },
95 { WinBatchSid, BATCH, NT_AUTHORITY, SidTypeWellKnownGroup },
96 { WinInteractiveSid, INTERACTIVE, NT_AUTHORITY, SidTypeWellKnownGroup },
97 { WinServiceSid, SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
98 { WinAnonymousSid, ANONYMOUS_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
99 { WinProxySid, PROXY, NT_AUTHORITY, SidTypeWellKnownGroup },
100 { WinEnterpriseControllersSid, ENTERPRISE_DOMAIN_CONTROLLERS, NT_AUTHORITY, SidTypeWellKnownGroup },
101 { WinSelfSid, SELF, NT_AUTHORITY, SidTypeWellKnownGroup },
102 { WinAuthenticatedUserSid, Authenticated_Users, NT_AUTHORITY, SidTypeWellKnownGroup },
103 { WinRestrictedCodeSid, RESTRICTED, NT_AUTHORITY, SidTypeWellKnownGroup },
104 { WinTerminalServerSid, TERMINAL_SERVER_USER, NT_AUTHORITY, SidTypeWellKnownGroup },
105 { WinRemoteLogonIdSid, REMOTE_INTERACTIVE_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
106 { WinLocalSystemSid, SYSTEM, NT_AUTHORITY, SidTypeWellKnownGroup },
107 { WinLocalServiceSid, LOCAL_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
108 { WinNetworkServiceSid, NETWORK_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
109 { WinBuiltinDomainSid, BUILTIN, BUILTIN, SidTypeDomain },
110 { WinBuiltinAdministratorsSid, Administrators, BUILTIN, SidTypeAlias },
111 { WinBuiltinUsersSid, Users, BUILTIN, SidTypeAlias },
112 { WinBuiltinGuestsSid, Guests, BUILTIN, SidTypeAlias },
113 { WinBuiltinPowerUsersSid, Power_Users, BUILTIN, SidTypeAlias },
114 { WinBuiltinAccountOperatorsSid, Account_Operators, BUILTIN, SidTypeAlias },
115 { WinBuiltinSystemOperatorsSid, Server_Operators, BUILTIN, SidTypeAlias },
116 { WinBuiltinPrintOperatorsSid, Print_Operators, BUILTIN, SidTypeAlias },
117 { WinBuiltinBackupOperatorsSid, Backup_Operators, BUILTIN, SidTypeAlias },
118 { WinBuiltinReplicatorSid, Replicators, BUILTIN, SidTypeAlias },
119 { WinBuiltinPreWindows2000CompatibleAccessSid, Pre_Windows_2000_Compatible_Access, BUILTIN, SidTypeAlias },
120 { WinBuiltinRemoteDesktopUsersSid, Remote_Desktop_Users, BUILTIN, SidTypeAlias },
121 { WinBuiltinNetworkConfigurationOperatorsSid, Network_Configuration_Operators, BUILTIN, SidTypeAlias },
122 { WinNTLMAuthenticationSid, NTML_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
123 { WinDigestAuthenticationSid, Digest_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
124 { WinSChannelAuthenticationSid, SChannel_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
125 { WinThisOrganizationSid, This_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
126 { WinOtherOrganizationSid, Other_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
127 { WinBuiltinPerfMonitoringUsersSid, Performance_Monitor_Users, BUILTIN, SidTypeAlias },
128 { WinBuiltinPerfLoggingUsersSid, Performance_Log_Users, BUILTIN, SidTypeAlias },
129 };
130
131 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
132 { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
133 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
134 { '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 };
135 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
136 { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
137 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
138 { '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 };
139 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
140 { '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 };
141 static const WCHAR SE_TCB_NAME_W[] =
142 { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
143 static const WCHAR SE_SECURITY_NAME_W[] =
144 { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
145 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
146 { '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 };
147 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
148 { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
149 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
150 { '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 };
151 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
152 { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
153 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
154 { '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 };
155 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
156 { '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 };
157 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
158 { '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 };
159 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
160 { '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 };
161 static const WCHAR SE_BACKUP_NAME_W[] =
162 { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
163 static const WCHAR SE_RESTORE_NAME_W[] =
164 { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
165 static const WCHAR SE_SHUTDOWN_NAME_W[] =
166 { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
167 static const WCHAR SE_DEBUG_NAME_W[] =
168 { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
169 static const WCHAR SE_AUDIT_NAME_W[] =
170 { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
171 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
172 { '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 };
173 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
174 { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
175 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
176 { '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 };
177 static const WCHAR SE_UNDOCK_NAME_W[] =
178 { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
179 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
180 { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
181 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
182 { '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 };
183 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
184 { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
185 static const WCHAR SE_IMPERSONATE_NAME_W[] =
186 { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
187 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
188 { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
189
190 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
191 {
192 NULL,
193 NULL,
194 SE_CREATE_TOKEN_NAME_W,
195 SE_ASSIGNPRIMARYTOKEN_NAME_W,
196 SE_LOCK_MEMORY_NAME_W,
197 SE_INCREASE_QUOTA_NAME_W,
198 SE_MACHINE_ACCOUNT_NAME_W,
199 SE_TCB_NAME_W,
200 SE_SECURITY_NAME_W,
201 SE_TAKE_OWNERSHIP_NAME_W,
202 SE_LOAD_DRIVER_NAME_W,
203 SE_SYSTEM_PROFILE_NAME_W,
204 SE_SYSTEMTIME_NAME_W,
205 SE_PROF_SINGLE_PROCESS_NAME_W,
206 SE_INC_BASE_PRIORITY_NAME_W,
207 SE_CREATE_PAGEFILE_NAME_W,
208 SE_CREATE_PERMANENT_NAME_W,
209 SE_BACKUP_NAME_W,
210 SE_RESTORE_NAME_W,
211 SE_SHUTDOWN_NAME_W,
212 SE_DEBUG_NAME_W,
213 SE_AUDIT_NAME_W,
214 SE_SYSTEM_ENVIRONMENT_NAME_W,
215 SE_CHANGE_NOTIFY_NAME_W,
216 SE_REMOTE_SHUTDOWN_NAME_W,
217 SE_UNDOCK_NAME_W,
218 SE_SYNC_AGENT_NAME_W,
219 SE_ENABLE_DELEGATION_NAME_W,
220 SE_MANAGE_VOLUME_NAME_W,
221 SE_IMPERSONATE_NAME_W,
222 SE_CREATE_GLOBAL_NAME_W,
223 };
224
225
226 /* Interface to ntmarta.dll ***************************************************/
227
228 NTMARTA NtMartaStatic = { 0 };
229 static PNTMARTA NtMarta = NULL;
230
231 #define FindNtMartaProc(Name) \
232 NtMartaStatic.Name = (PVOID)GetProcAddress(NtMartaStatic.hDllInstance, \
233 "Acc" # Name ); \
234 if (NtMartaStatic.Name == NULL) \
235 { \
236 return GetLastError(); \
237 }
238
239
240 static DWORD
241 LoadAndInitializeNtMarta(VOID)
242 {
243 /* this code may be executed simultaneously by multiple threads in case they're
244 trying to initialize the interface at the same time, but that's no problem
245 because the pointers returned by GetProcAddress will be the same. However,
246 only one of the threads will change the NtMarta pointer to the NtMartaStatic
247 structure, the others threads will detect that there were other threads
248 initializing the structure faster and will release the reference to the
249 DLL */
250
251 NtMartaStatic.hDllInstance = LoadLibraryW(L"ntmarta.dll");
252 if (NtMartaStatic.hDllInstance == NULL)
253 {
254 return GetLastError();
255 }
256
257 #if 0
258 FindNtMartaProc(LookupAccountTrustee);
259 FindNtMartaProc(LookupAccountName);
260 FindNtMartaProc(LookupAccountSid);
261 FindNtMartaProc(SetEntriesInAList);
262 FindNtMartaProc(ConvertAccessToSecurityDescriptor);
263 FindNtMartaProc(ConvertSDToAccess);
264 FindNtMartaProc(ConvertAclToAccess);
265 FindNtMartaProc(GetAccessForTrustee);
266 FindNtMartaProc(GetExplicitEntries);
267 #endif
268 FindNtMartaProc(RewriteGetNamedRights);
269 FindNtMartaProc(RewriteSetNamedRights);
270 FindNtMartaProc(RewriteGetHandleRights);
271 FindNtMartaProc(RewriteSetHandleRights);
272 FindNtMartaProc(RewriteSetEntriesInAcl);
273 FindNtMartaProc(RewriteGetExplicitEntriesFromAcl);
274 FindNtMartaProc(TreeResetNamedSecurityInfo);
275 FindNtMartaProc(GetInheritanceSource);
276 FindNtMartaProc(FreeIndexArray);
277
278 return ERROR_SUCCESS;
279 }
280
281
282 DWORD
283 CheckNtMartaPresent(VOID)
284 {
285 DWORD ErrorCode;
286
287 if (InterlockedCompareExchangePointer(&NtMarta,
288 NULL,
289 NULL) == NULL)
290 {
291 /* we're the first one trying to use ntmarta, initialize it and change
292 the pointer after initialization */
293 ErrorCode = LoadAndInitializeNtMarta();
294
295 if (ErrorCode == ERROR_SUCCESS)
296 {
297 /* try change the NtMarta pointer */
298 if (InterlockedCompareExchangePointer(&NtMarta,
299 &NtMartaStatic,
300 NULL) != NULL)
301 {
302 /* another thread initialized ntmarta in the meanwhile, release
303 the reference of the dll loaded. */
304 FreeLibrary(NtMartaStatic.hDllInstance);
305 }
306 }
307 #if DBG
308 else
309 {
310 ERR("Failed to initialize ntmarta.dll! Error: 0x%x", ErrorCode);
311 }
312 #endif
313 }
314 else
315 {
316 /* ntmarta was already initialized */
317 ErrorCode = ERROR_SUCCESS;
318 }
319
320 return ErrorCode;
321 }
322
323
324 VOID
325 UnloadNtMarta(VOID)
326 {
327 if (InterlockedExchangePointer(&NtMarta,
328 NULL) != NULL)
329 {
330 FreeLibrary(NtMartaStatic.hDllInstance);
331 }
332 }
333
334
335 /******************************************************************************/
336
337 /*
338 * @implemented
339 */
340 BOOL
341 STDCALL
342 AreAllAccessesGranted(DWORD GrantedAccess,
343 DWORD DesiredAccess)
344 {
345 return (BOOL)RtlAreAllAccessesGranted(GrantedAccess,
346 DesiredAccess);
347 }
348
349
350 /*
351 * @implemented
352 */
353 BOOL
354 STDCALL
355 AreAnyAccessesGranted(DWORD GrantedAccess,
356 DWORD DesiredAccess)
357 {
358 return (BOOL)RtlAreAnyAccessesGranted(GrantedAccess,
359 DesiredAccess);
360 }
361
362
363 /************************************************************
364 * ADVAPI_IsLocalComputer
365 *
366 * Checks whether the server name indicates local machine.
367 */
368 BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName)
369 {
370 DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
371 BOOL Result;
372 LPWSTR buf;
373
374 if (!ServerName || !ServerName[0])
375 return TRUE;
376
377 buf = HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR));
378 Result = GetComputerNameW(buf, &dwSize);
379 if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
380 ServerName += 2;
381 Result = Result && !lstrcmpW(ServerName, buf);
382 HeapFree(GetProcessHeap(), 0, buf);
383
384 return Result;
385 }
386
387
388 /******************************************************************************
389 * GetFileSecurityA [ADVAPI32.@]
390 *
391 * Obtains Specified information about the security of a file or directory.
392 *
393 * PARAMS
394 * lpFileName [I] Name of the file to get info for
395 * RequestedInformation [I] SE_ flags from "winnt.h"
396 * pSecurityDescriptor [O] Destination for security information
397 * nLength [I] Length of pSecurityDescriptor
398 * lpnLengthNeeded [O] Destination for length of returned security information
399 *
400 * RETURNS
401 * Success: TRUE. pSecurityDescriptor contains the requested information.
402 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
403 *
404 * NOTES
405 * The information returned is constrained by the callers access rights and
406 * privileges.
407 *
408 * @implemented
409 */
410 BOOL
411 WINAPI
412 GetFileSecurityA(LPCSTR lpFileName,
413 SECURITY_INFORMATION RequestedInformation,
414 PSECURITY_DESCRIPTOR pSecurityDescriptor,
415 DWORD nLength,
416 LPDWORD lpnLengthNeeded)
417 {
418 UNICODE_STRING FileName;
419 NTSTATUS Status;
420 BOOL bResult;
421
422 Status = RtlCreateUnicodeStringFromAsciiz(&FileName,
423 (LPSTR)lpFileName);
424 if (!NT_SUCCESS(Status))
425 {
426 SetLastError(RtlNtStatusToDosError(Status));
427 return FALSE;
428 }
429
430 bResult = GetFileSecurityW(FileName.Buffer,
431 RequestedInformation,
432 pSecurityDescriptor,
433 nLength,
434 lpnLengthNeeded);
435
436 RtlFreeUnicodeString(&FileName);
437
438 return bResult;
439 }
440
441
442 /*
443 * @implemented
444 */
445 BOOL
446 WINAPI
447 GetFileSecurityW(LPCWSTR lpFileName,
448 SECURITY_INFORMATION RequestedInformation,
449 PSECURITY_DESCRIPTOR pSecurityDescriptor,
450 DWORD nLength,
451 LPDWORD lpnLengthNeeded)
452 {
453 OBJECT_ATTRIBUTES ObjectAttributes;
454 IO_STATUS_BLOCK StatusBlock;
455 UNICODE_STRING FileName;
456 ULONG AccessMask = 0;
457 HANDLE FileHandle;
458 NTSTATUS Status;
459
460 TRACE("GetFileSecurityW() called\n");
461
462 QuerySecurityAccessMask(RequestedInformation, &AccessMask);
463
464 if (!RtlDosPathNameToNtPathName_U(lpFileName,
465 &FileName,
466 NULL,
467 NULL))
468 {
469 ERR("Invalid path\n");
470 SetLastError(ERROR_INVALID_NAME);
471 return FALSE;
472 }
473
474 InitializeObjectAttributes(&ObjectAttributes,
475 &FileName,
476 OBJ_CASE_INSENSITIVE,
477 NULL,
478 NULL);
479
480 Status = NtOpenFile(&FileHandle,
481 AccessMask,
482 &ObjectAttributes,
483 &StatusBlock,
484 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
485 0);
486
487 RtlFreeHeap(RtlGetProcessHeap(),
488 0,
489 FileName.Buffer);
490
491 if (!NT_SUCCESS(Status))
492 {
493 ERR("NtOpenFile() failed (Status %lx)\n", Status);
494 SetLastError(RtlNtStatusToDosError(Status));
495 return FALSE;
496 }
497
498 Status = NtQuerySecurityObject(FileHandle,
499 RequestedInformation,
500 pSecurityDescriptor,
501 nLength,
502 lpnLengthNeeded);
503 NtClose(FileHandle);
504 if (!NT_SUCCESS(Status))
505 {
506 ERR("NtQuerySecurityObject() failed (Status %lx)\n", Status);
507 SetLastError(RtlNtStatusToDosError(Status));
508 return FALSE;
509 }
510
511 return TRUE;
512 }
513
514
515 /*
516 * @implemented
517 */
518 BOOL
519 STDCALL
520 GetKernelObjectSecurity(HANDLE Handle,
521 SECURITY_INFORMATION RequestedInformation,
522 PSECURITY_DESCRIPTOR pSecurityDescriptor,
523 DWORD nLength,
524 LPDWORD lpnLengthNeeded)
525 {
526 NTSTATUS Status;
527
528 Status = NtQuerySecurityObject(Handle,
529 RequestedInformation,
530 pSecurityDescriptor,
531 nLength,
532 lpnLengthNeeded);
533 if (!NT_SUCCESS(Status))
534 {
535 SetLastError(RtlNtStatusToDosError(Status));
536 return FALSE;
537 }
538
539 return TRUE;
540 }
541
542
543 /******************************************************************************
544 * SetFileSecurityA [ADVAPI32.@]
545 * Sets the security of a file or directory
546 *
547 * @implemented
548 */
549 BOOL
550 STDCALL
551 SetFileSecurityA(LPCSTR lpFileName,
552 SECURITY_INFORMATION SecurityInformation,
553 PSECURITY_DESCRIPTOR pSecurityDescriptor)
554 {
555 UNICODE_STRING FileName;
556 NTSTATUS Status;
557 BOOL bResult;
558
559 Status = RtlCreateUnicodeStringFromAsciiz(&FileName,
560 (LPSTR)lpFileName);
561 if (!NT_SUCCESS(Status))
562 {
563 SetLastError(RtlNtStatusToDosError(Status));
564 return FALSE;
565 }
566
567 bResult = SetFileSecurityW(FileName.Buffer,
568 SecurityInformation,
569 pSecurityDescriptor);
570
571 RtlFreeUnicodeString(&FileName);
572
573 return bResult;
574 }
575
576
577 /******************************************************************************
578 * SetFileSecurityW [ADVAPI32.@]
579 * Sets the security of a file or directory
580 *
581 * @implemented
582 */
583 BOOL
584 STDCALL
585 SetFileSecurityW(LPCWSTR lpFileName,
586 SECURITY_INFORMATION SecurityInformation,
587 PSECURITY_DESCRIPTOR pSecurityDescriptor)
588 {
589 OBJECT_ATTRIBUTES ObjectAttributes;
590 IO_STATUS_BLOCK StatusBlock;
591 UNICODE_STRING FileName;
592 ULONG AccessMask = 0;
593 HANDLE FileHandle;
594 NTSTATUS Status;
595
596 TRACE("SetFileSecurityW() called\n");
597
598 SetSecurityAccessMask(SecurityInformation, &AccessMask);
599
600 if (!RtlDosPathNameToNtPathName_U(lpFileName,
601 &FileName,
602 NULL,
603 NULL))
604 {
605 ERR("Invalid path\n");
606 SetLastError(ERROR_INVALID_NAME);
607 return FALSE;
608 }
609
610 InitializeObjectAttributes(&ObjectAttributes,
611 &FileName,
612 OBJ_CASE_INSENSITIVE,
613 NULL,
614 NULL);
615
616 Status = NtOpenFile(&FileHandle,
617 AccessMask,
618 &ObjectAttributes,
619 &StatusBlock,
620 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
621 0);
622
623 RtlFreeHeap(RtlGetProcessHeap(),
624 0,
625 FileName.Buffer);
626
627 if (!NT_SUCCESS(Status))
628 {
629 ERR("NtOpenFile() failed (Status %lx)\n", Status);
630 SetLastError(RtlNtStatusToDosError(Status));
631 return FALSE;
632 }
633
634 Status = NtSetSecurityObject(FileHandle,
635 SecurityInformation,
636 pSecurityDescriptor);
637 NtClose(FileHandle);
638
639 if (!NT_SUCCESS(Status))
640 {
641 ERR("NtSetSecurityObject() failed (Status %lx)\n", Status);
642 SetLastError(RtlNtStatusToDosError(Status));
643 return FALSE;
644 }
645
646 return TRUE;
647 }
648
649
650 /*
651 * @implemented
652 */
653 BOOL
654 STDCALL
655 SetKernelObjectSecurity(HANDLE Handle,
656 SECURITY_INFORMATION SecurityInformation,
657 PSECURITY_DESCRIPTOR SecurityDescriptor)
658 {
659 NTSTATUS Status;
660
661 Status = NtSetSecurityObject(Handle,
662 SecurityInformation,
663 SecurityDescriptor);
664 if (!NT_SUCCESS(Status))
665 {
666 SetLastError(RtlNtStatusToDosError(Status));
667 return FALSE;
668 }
669
670 return TRUE;
671 }
672
673
674 /*
675 * @implemented
676 */
677 BOOL
678 WINAPI
679 ImpersonateAnonymousToken(IN HANDLE ThreadHandle)
680 {
681 NTSTATUS Status;
682
683 Status = NtImpersonateAnonymousToken(ThreadHandle);
684 if (!NT_SUCCESS(Status))
685 {
686 SetLastError(RtlNtStatusToDosError(Status));
687 return FALSE;
688 }
689
690 return TRUE;
691 }
692
693
694 /*
695 * @implemented
696 */
697 BOOL
698 STDCALL
699 ImpersonateLoggedOnUser(HANDLE hToken)
700 {
701 SECURITY_QUALITY_OF_SERVICE Qos;
702 OBJECT_ATTRIBUTES ObjectAttributes;
703 HANDLE NewToken;
704 TOKEN_TYPE Type;
705 ULONG ReturnLength;
706 BOOL Duplicated;
707 NTSTATUS Status;
708
709 /* Get the token type */
710 Status = NtQueryInformationToken(hToken,
711 TokenType,
712 &Type,
713 sizeof(TOKEN_TYPE),
714 &ReturnLength);
715 if (!NT_SUCCESS(Status))
716 {
717 SetLastError(RtlNtStatusToDosError(Status));
718 return FALSE;
719 }
720
721 if (Type == TokenPrimary)
722 {
723 /* Create a duplicate impersonation token */
724 Qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
725 Qos.ImpersonationLevel = SecurityImpersonation;
726 Qos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
727 Qos.EffectiveOnly = FALSE;
728
729 ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
730 ObjectAttributes.RootDirectory = NULL;
731 ObjectAttributes.ObjectName = NULL;
732 ObjectAttributes.Attributes = 0;
733 ObjectAttributes.SecurityDescriptor = NULL;
734 ObjectAttributes.SecurityQualityOfService = &Qos;
735
736 Status = NtDuplicateToken(hToken,
737 TOKEN_IMPERSONATE | TOKEN_QUERY,
738 &ObjectAttributes,
739 FALSE,
740 TokenImpersonation,
741 &NewToken);
742 if (!NT_SUCCESS(Status))
743 {
744 SetLastError(RtlNtStatusToDosError(Status));
745 return FALSE;
746 }
747
748 Duplicated = TRUE;
749 }
750 else
751 {
752 /* User the original impersonation token */
753 NewToken = hToken;
754 Duplicated = FALSE;
755 }
756
757 /* Impersonate the the current thread */
758 Status = NtSetInformationThread(NtCurrentThread(),
759 ThreadImpersonationToken,
760 &NewToken,
761 sizeof(HANDLE));
762
763 if (Duplicated == TRUE)
764 {
765 NtClose(NewToken);
766 }
767
768 if (!NT_SUCCESS(Status))
769 {
770 SetLastError(RtlNtStatusToDosError(Status));
771 return FALSE;
772 }
773
774 return TRUE;
775 }
776
777
778 /*
779 * @implemented
780 */
781 BOOL
782 STDCALL
783 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
784 {
785 NTSTATUS Status;
786
787 Status = RtlImpersonateSelf(ImpersonationLevel);
788 if (!NT_SUCCESS(Status))
789 {
790 SetLastError(RtlNtStatusToDosError(Status));
791 return FALSE;
792 }
793
794 return TRUE;
795 }
796
797
798 /*
799 * @implemented
800 */
801 BOOL
802 STDCALL
803 RevertToSelf(VOID)
804 {
805 NTSTATUS Status;
806 HANDLE Token = NULL;
807
808 Status = NtSetInformationThread(NtCurrentThread(),
809 ThreadImpersonationToken,
810 &Token,
811 sizeof(HANDLE));
812 if (!NT_SUCCESS(Status))
813 {
814 SetLastError(RtlNtStatusToDosError(Status));
815 return FALSE;
816 }
817
818 return TRUE;
819 }
820
821
822 /******************************************************************************
823 * GetUserNameA [ADVAPI32.@]
824 *
825 * Get the current user name.
826 *
827 * PARAMS
828 * lpszName [O] Destination for the user name.
829 * lpSize [I/O] Size of lpszName.
830 *
831 *
832 * @implemented
833 */
834 BOOL
835 WINAPI
836 GetUserNameA(LPSTR lpszName,
837 LPDWORD lpSize)
838 {
839 UNICODE_STRING NameW;
840 ANSI_STRING NameA;
841 BOOL Ret;
842
843 /* apparently Win doesn't check whether lpSize is valid at all! */
844
845 NameW.MaximumLength = (*lpSize) * sizeof(WCHAR);
846 NameW.Buffer = LocalAlloc(LMEM_FIXED, NameW.MaximumLength);
847 if(NameW.Buffer == NULL)
848 {
849 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
850 return FALSE;
851 }
852
853 NameA.Length = 0;
854 NameA.MaximumLength = ((*lpSize) < 0xFFFF ? (USHORT)(*lpSize) : 0xFFFF);
855 NameA.Buffer = lpszName;
856
857 Ret = GetUserNameW(NameW.Buffer,
858 lpSize);
859 if(Ret)
860 {
861 NameW.Length = (*lpSize - 1) * sizeof(WCHAR);
862 RtlUnicodeStringToAnsiString(&NameA, &NameW, FALSE);
863
864 *lpSize = NameA.Length + 1;
865 }
866
867 LocalFree(NameW.Buffer);
868
869 return Ret;
870 }
871
872
873 /******************************************************************************
874 * GetUserNameW [ADVAPI32.@]
875 *
876 * See GetUserNameA.
877 *
878 * @implemented
879 */
880 BOOL
881 WINAPI
882 GetUserNameW(LPWSTR lpszName,
883 LPDWORD lpSize )
884 {
885 HANDLE hToken = INVALID_HANDLE_VALUE;
886 DWORD tu_len = 0;
887 char* tu_buf = NULL;
888 TOKEN_USER* token_user = NULL;
889 DWORD an_len = 0;
890 SID_NAME_USE snu = SidTypeUser;
891 WCHAR* domain_name = NULL;
892 DWORD dn_len = 0;
893
894 if ( !OpenThreadToken ( GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken ) )
895 {
896 DWORD dwLastError = GetLastError();
897 if ( dwLastError != ERROR_NO_TOKEN
898 && dwLastError != ERROR_NO_IMPERSONATION_TOKEN )
899 {
900 /* don't call SetLastError(),
901 as OpenThreadToken() ought to have set one */
902 return FALSE;
903 }
904 if ( !OpenProcessToken ( GetCurrentProcess(), TOKEN_QUERY, &hToken ) )
905 {
906 /* don't call SetLastError(),
907 as OpenProcessToken() ought to have set one */
908 return FALSE;
909 }
910 }
911 tu_buf = LocalAlloc ( LMEM_FIXED, 36 );
912 if ( !tu_buf )
913 {
914 SetLastError ( ERROR_NOT_ENOUGH_MEMORY );
915 CloseHandle ( hToken );
916 return FALSE;
917 }
918 if ( !GetTokenInformation ( hToken, TokenUser, tu_buf, 36, &tu_len ) || tu_len > 36 )
919 {
920 LocalFree ( tu_buf );
921 tu_buf = LocalAlloc ( LMEM_FIXED, tu_len );
922 if ( !tu_buf )
923 {
924 SetLastError ( ERROR_NOT_ENOUGH_MEMORY );
925 CloseHandle ( hToken );
926 return FALSE;
927 }
928 if ( !GetTokenInformation ( hToken, TokenUser, tu_buf, tu_len, &tu_len ) )
929 {
930 /* don't call SetLastError(),
931 as GetTokenInformation() ought to have set one */
932 LocalFree ( tu_buf );
933 CloseHandle ( hToken );
934 return FALSE;
935 }
936 }
937 CloseHandle ( hToken );
938 token_user = (TOKEN_USER*)tu_buf;
939
940 an_len = *lpSize;
941 dn_len = 32;
942 domain_name = LocalAlloc ( LMEM_FIXED, dn_len * sizeof(WCHAR) );
943 if ( !domain_name )
944 {
945 LocalFree ( tu_buf );
946 SetLastError ( ERROR_NOT_ENOUGH_MEMORY );
947 return FALSE;
948 }
949 if ( !LookupAccountSidW ( NULL, token_user->User.Sid, lpszName, &an_len, domain_name, &dn_len, &snu )
950 || dn_len > 32 )
951 {
952 if ( dn_len > 32 )
953 {
954 LocalFree ( domain_name );
955 domain_name = LocalAlloc ( LMEM_FIXED, dn_len * sizeof(WCHAR) );
956 if ( !domain_name )
957 {
958 LocalFree ( tu_buf );
959 SetLastError ( ERROR_NOT_ENOUGH_MEMORY );
960 return FALSE;
961 }
962 }
963 an_len = *lpSize;
964 if ( !LookupAccountSidW ( NULL, token_user->User.Sid, lpszName, &an_len, domain_name, &dn_len, &snu ) )
965 {
966 /* don't call SetLastError(),
967 as LookupAccountSid() ought to have set one */
968 LocalFree ( domain_name );
969 LocalFree ( tu_buf );
970 *lpSize = an_len;
971 return FALSE;
972 }
973 }
974
975 LocalFree ( domain_name );
976 LocalFree ( tu_buf );
977 *lpSize = an_len + 1;
978 return TRUE;
979 }
980
981
982 /******************************************************************************
983 * LookupAccountSidA [ADVAPI32.@]
984 *
985 * @implemented
986 */
987 BOOL
988 STDCALL
989 LookupAccountSidA(LPCSTR lpSystemName,
990 PSID lpSid,
991 LPSTR lpName,
992 LPDWORD cchName,
993 LPSTR lpReferencedDomainName,
994 LPDWORD cchReferencedDomainName,
995 PSID_NAME_USE peUse)
996 {
997 UNICODE_STRING NameW, ReferencedDomainNameW, SystemNameW;
998 DWORD szName, szReferencedDomainName;
999 BOOL Ret;
1000
1001 /*
1002 * save the buffer sizes the caller passed to us, as they may get modified and
1003 * we require the original values when converting back to ansi
1004 */
1005 szName = *cchName;
1006 szReferencedDomainName = *cchReferencedDomainName;
1007
1008 /*
1009 * allocate buffers for the unicode strings to receive
1010 */
1011
1012 if(szName > 0)
1013 {
1014 NameW.Length = 0;
1015 NameW.MaximumLength = szName * sizeof(WCHAR);
1016 NameW.Buffer = (PWSTR)LocalAlloc(LMEM_FIXED, NameW.MaximumLength);
1017 if(NameW.Buffer == NULL)
1018 {
1019 SetLastError(ERROR_OUTOFMEMORY);
1020 return FALSE;
1021 }
1022 }
1023 else
1024 NameW.Buffer = NULL;
1025
1026 if(szReferencedDomainName > 0)
1027 {
1028 ReferencedDomainNameW.Length = 0;
1029 ReferencedDomainNameW.MaximumLength = szReferencedDomainName * sizeof(WCHAR);
1030 ReferencedDomainNameW.Buffer = (PWSTR)LocalAlloc(LMEM_FIXED, ReferencedDomainNameW.MaximumLength);
1031 if(ReferencedDomainNameW.Buffer == NULL)
1032 {
1033 if(szName > 0)
1034 {
1035 LocalFree(NameW.Buffer);
1036 }
1037 SetLastError(ERROR_OUTOFMEMORY);
1038 return FALSE;
1039 }
1040 }
1041 else
1042 ReferencedDomainNameW.Buffer = NULL;
1043
1044 /*
1045 * convert the system name to unicode - if present
1046 */
1047
1048 if(lpSystemName != NULL)
1049 {
1050 ANSI_STRING SystemNameA;
1051
1052 RtlInitAnsiString(&SystemNameA, lpSystemName);
1053 RtlAnsiStringToUnicodeString(&SystemNameW, &SystemNameA, TRUE);
1054 }
1055 else
1056 SystemNameW.Buffer = NULL;
1057
1058 /*
1059 * it's time to call the unicode version
1060 */
1061
1062 Ret = LookupAccountSidW(SystemNameW.Buffer,
1063 lpSid,
1064 NameW.Buffer,
1065 cchName,
1066 ReferencedDomainNameW.Buffer,
1067 cchReferencedDomainName,
1068 peUse);
1069 if(Ret)
1070 {
1071 /*
1072 * convert unicode strings back to ansi, don't forget that we can't convert
1073 * more than 0xFFFF (USHORT) characters! Also don't forget to explicitly
1074 * terminate the converted string, the Rtl functions don't do that!
1075 */
1076 if(lpName != NULL)
1077 {
1078 ANSI_STRING NameA;
1079
1080 NameA.Length = 0;
1081 NameA.MaximumLength = ((szName <= 0xFFFF) ? (USHORT)szName : 0xFFFF);
1082 NameA.Buffer = lpName;
1083
1084 RtlUnicodeStringToAnsiString(&NameA, &NameW, FALSE);
1085 NameA.Buffer[NameA.Length] = '\0';
1086 }
1087
1088 if(lpReferencedDomainName != NULL)
1089 {
1090 ANSI_STRING ReferencedDomainNameA;
1091
1092 ReferencedDomainNameA.Length = 0;
1093 ReferencedDomainNameA.MaximumLength = ((szReferencedDomainName <= 0xFFFF) ?
1094 (USHORT)szReferencedDomainName : 0xFFFF);
1095 ReferencedDomainNameA.Buffer = lpReferencedDomainName;
1096
1097 RtlUnicodeStringToAnsiString(&ReferencedDomainNameA, &ReferencedDomainNameW, FALSE);
1098 ReferencedDomainNameA.Buffer[ReferencedDomainNameA.Length] = '\0';
1099 }
1100 }
1101
1102 /*
1103 * free previously allocated buffers
1104 */
1105
1106 if(SystemNameW.Buffer != NULL)
1107 {
1108 RtlFreeUnicodeString(&SystemNameW);
1109 }
1110 if(NameW.Buffer != NULL)
1111 {
1112 LocalFree(NameW.Buffer);
1113 }
1114 if(ReferencedDomainNameW.Buffer != NULL)
1115 {
1116 LocalFree(ReferencedDomainNameW.Buffer);
1117 }
1118
1119 return Ret;
1120 }
1121
1122
1123 /******************************************************************************
1124 * LookupAccountSidW [ADVAPI32.@]
1125 *
1126 * @implemented
1127 */
1128 BOOL WINAPI
1129 LookupAccountSidW(LPCWSTR pSystemName,
1130 PSID pSid,
1131 LPWSTR pAccountName,
1132 LPDWORD pdwAccountName,
1133 LPWSTR pDomainName,
1134 LPDWORD pdwDomainName,
1135 PSID_NAME_USE peUse)
1136 {
1137 LSA_UNICODE_STRING SystemName;
1138 LSA_OBJECT_ATTRIBUTES ObjectAttributes = {0};
1139 LSA_HANDLE PolicyHandle = NULL;
1140 NTSTATUS Status;
1141 PLSA_REFERENCED_DOMAIN_LIST ReferencedDomain = NULL;
1142 PLSA_TRANSLATED_NAME TranslatedName = NULL;
1143 BOOL ret;
1144
1145 RtlInitUnicodeString ( &SystemName, pSystemName );
1146 Status = LsaOpenPolicy ( &SystemName, &ObjectAttributes, POLICY_LOOKUP_NAMES, &PolicyHandle );
1147 if ( !NT_SUCCESS(Status) )
1148 {
1149 SetLastError ( LsaNtStatusToWinError(Status) );
1150 return FALSE;
1151 }
1152 Status = LsaLookupSids ( PolicyHandle, 1, &pSid, &ReferencedDomain, &TranslatedName );
1153
1154 LsaClose ( PolicyHandle );
1155
1156 if ( !NT_SUCCESS(Status) || Status == STATUS_SOME_NOT_MAPPED )
1157 {
1158 SetLastError ( LsaNtStatusToWinError(Status) );
1159 ret = FALSE;
1160 }
1161 else
1162 {
1163 ret = TRUE;
1164 if ( TranslatedName )
1165 {
1166 DWORD dwSrcLen = TranslatedName->Name.Length / sizeof(WCHAR);
1167 if ( *pdwAccountName <= dwSrcLen )
1168 {
1169 *pdwAccountName = dwSrcLen + 1;
1170 ret = FALSE;
1171 }
1172 else
1173 {
1174 *pdwAccountName = dwSrcLen;
1175 if (pAccountName)
1176 {
1177 RtlCopyMemory ( pAccountName, TranslatedName->Name.Buffer, TranslatedName->Name.Length );
1178 pAccountName[TranslatedName->Name.Length / sizeof(WCHAR)] = L'\0';
1179 }
1180 }
1181 if ( peUse )
1182 *peUse = TranslatedName->Use;
1183 }
1184
1185 if ( ReferencedDomain )
1186 {
1187 if ( ReferencedDomain->Entries > 0 )
1188 {
1189 DWORD dwSrcLen = ReferencedDomain->Domains[0].Name.Length / sizeof(WCHAR);
1190 if ( *pdwDomainName <= dwSrcLen )
1191 {
1192 *pdwDomainName = dwSrcLen + 1;
1193 ret = FALSE;
1194 }
1195 else
1196 {
1197 *pdwDomainName = dwSrcLen;
1198 RtlCopyMemory ( pDomainName, ReferencedDomain->Domains[0].Name.Buffer, ReferencedDomain->Domains[0].Name.Length );
1199 pDomainName[ReferencedDomain->Domains[0].Name.Length / sizeof(WCHAR)] = L'\0';
1200 }
1201 }
1202 }
1203
1204 if ( !ret )
1205 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1206 }
1207
1208 if ( ReferencedDomain )
1209 LsaFreeMemory ( ReferencedDomain );
1210 if ( TranslatedName )
1211 LsaFreeMemory ( TranslatedName );
1212
1213 return ret;
1214 }
1215
1216
1217
1218 /******************************************************************************
1219 * LookupAccountNameA [ADVAPI32.@]
1220 *
1221 * @implemented
1222 */
1223 BOOL
1224 STDCALL
1225 LookupAccountNameA(LPCSTR SystemName,
1226 LPCSTR AccountName,
1227 PSID Sid,
1228 LPDWORD SidLength,
1229 LPSTR ReferencedDomainName,
1230 LPDWORD hReferencedDomainNameLength,
1231 PSID_NAME_USE SidNameUse)
1232 {
1233 BOOL ret;
1234 UNICODE_STRING lpSystemW;
1235 UNICODE_STRING lpAccountW;
1236 LPWSTR lpReferencedDomainNameW = NULL;
1237
1238 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, SystemName);
1239 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, AccountName);
1240
1241 if (ReferencedDomainName)
1242 lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(),
1243 0,
1244 *hReferencedDomainNameLength * sizeof(WCHAR));
1245
1246 ret = LookupAccountNameW(lpSystemW.Buffer,
1247 lpAccountW.Buffer,
1248 Sid,
1249 SidLength,
1250 lpReferencedDomainNameW,
1251 hReferencedDomainNameLength,
1252 SidNameUse);
1253
1254 if (ret && lpReferencedDomainNameW)
1255 {
1256 WideCharToMultiByte(CP_ACP,
1257 0,
1258 lpReferencedDomainNameW,
1259 *hReferencedDomainNameLength,
1260 ReferencedDomainName,
1261 *hReferencedDomainNameLength,
1262 NULL,
1263 NULL);
1264 }
1265
1266 RtlFreeUnicodeString(&lpSystemW);
1267 RtlFreeUnicodeString(&lpAccountW);
1268 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
1269
1270 return ret;
1271 }
1272
1273
1274 /******************************************************************************
1275 * LookupAccountNameW [ADVAPI32.@]
1276 *
1277 * @unimplemented
1278 */
1279 BOOL
1280 WINAPI
1281 LookupAccountNameW(LPCWSTR lpSystemName,
1282 LPCWSTR lpAccountName,
1283 PSID Sid,
1284 LPDWORD cbSid,
1285 LPWSTR ReferencedDomainName,
1286 LPDWORD cchReferencedDomainName,
1287 PSID_NAME_USE peUse)
1288 {
1289 /* Default implementation: Always return a default SID */
1290 SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
1291 BOOL ret;
1292 PSID pSid;
1293 static const WCHAR dm[] = {'D','O','M','A','I','N',0};
1294 unsigned int i;
1295
1296 TRACE("%s %s %p %p %p %p %p - stub\n", lpSystemName, lpAccountName,
1297 Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
1298
1299 for (i = 0; i < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); i++)
1300 {
1301 if (!wcscmp(lpAccountName, ACCOUNT_SIDS[i].account))
1302 {
1303 if (*cchReferencedDomainName)
1304 *ReferencedDomainName = '\0';
1305 *cchReferencedDomainName = 0;
1306 *peUse = SidTypeWellKnownGroup;
1307 return CreateWellKnownSid(ACCOUNT_SIDS[i].type, NULL, Sid, cbSid);
1308 }
1309 }
1310
1311 ret = AllocateAndInitializeSid(&identifierAuthority,
1312 2,
1313 SECURITY_BUILTIN_DOMAIN_RID,
1314 DOMAIN_ALIAS_RID_ADMINS,
1315 0, 0, 0, 0, 0, 0,
1316 &pSid);
1317
1318 if (!ret)
1319 return FALSE;
1320
1321 if (!RtlValidSid(pSid))
1322 {
1323 FreeSid(pSid);
1324 return FALSE;
1325 }
1326
1327 if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
1328 CopySid(*cbSid, Sid, pSid);
1329
1330 if (*cbSid < GetLengthSid(pSid))
1331 {
1332 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1333 ret = FALSE;
1334 }
1335
1336 *cbSid = GetLengthSid(pSid);
1337
1338 if (ReferencedDomainName != NULL && (*cchReferencedDomainName > wcslen(dm)))
1339 wcscpy(ReferencedDomainName, dm);
1340
1341 if (*cchReferencedDomainName <= wcslen(dm))
1342 {
1343 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1344 ret = FALSE;
1345 }
1346
1347 *cchReferencedDomainName = wcslen(dm)+1;
1348
1349 FreeSid(pSid);
1350
1351 return ret;
1352 }
1353
1354
1355 /**********************************************************************
1356 * LookupPrivilegeValueA EXPORTED
1357 *
1358 * @implemented
1359 */
1360 BOOL
1361 STDCALL
1362 LookupPrivilegeValueA(LPCSTR lpSystemName,
1363 LPCSTR lpName,
1364 PLUID lpLuid)
1365 {
1366 UNICODE_STRING SystemName;
1367 UNICODE_STRING Name;
1368 BOOL Result;
1369
1370 /* Remote system? */
1371 if (lpSystemName != NULL)
1372 {
1373 RtlCreateUnicodeStringFromAsciiz(&SystemName,
1374 (LPSTR)lpSystemName);
1375 }
1376 else
1377 SystemName.Buffer = NULL;
1378
1379 /* Check the privilege name is not NULL */
1380 if (lpName == NULL)
1381 {
1382 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1383 return FALSE;
1384 }
1385
1386 RtlCreateUnicodeStringFromAsciiz(&Name,
1387 (LPSTR)lpName);
1388
1389 Result = LookupPrivilegeValueW(SystemName.Buffer,
1390 Name.Buffer,
1391 lpLuid);
1392
1393 RtlFreeUnicodeString(&Name);
1394
1395 /* Remote system? */
1396 if (SystemName.Buffer != NULL)
1397 {
1398 RtlFreeUnicodeString(&SystemName);
1399 }
1400
1401 return Result;
1402 }
1403
1404
1405 /**********************************************************************
1406 * LookupPrivilegeValueW EXPORTED
1407 *
1408 * @unimplemented
1409 */
1410 BOOL
1411 STDCALL
1412 LookupPrivilegeValueW(LPCWSTR SystemName,
1413 LPCWSTR PrivName,
1414 PLUID Luid)
1415 {
1416 static const WCHAR * const DefaultPrivNames[] =
1417 {
1418 L"SeCreateTokenPrivilege",
1419 L"SeAssignPrimaryTokenPrivilege",
1420 L"SeLockMemoryPrivilege",
1421 L"SeIncreaseQuotaPrivilege",
1422 L"SeUnsolicitedInputPrivilege",
1423 L"SeMachineAccountPrivilege",
1424 L"SeTcbPrivilege",
1425 L"SeSecurityPrivilege",
1426 L"SeTakeOwnershipPrivilege",
1427 L"SeLoadDriverPrivilege",
1428 L"SeSystemProfilePrivilege",
1429 L"SeSystemtimePrivilege",
1430 L"SeProfileSingleProcessPrivilege",
1431 L"SeIncreaseBasePriorityPrivilege",
1432 L"SeCreatePagefilePrivilege",
1433 L"SeCreatePermanentPrivilege",
1434 L"SeBackupPrivilege",
1435 L"SeRestorePrivilege",
1436 L"SeShutdownPrivilege",
1437 L"SeDebugPrivilege",
1438 L"SeAuditPrivilege",
1439 L"SeSystemEnvironmentPrivilege",
1440 L"SeChangeNotifyPrivilege",
1441 L"SeRemoteShutdownPrivilege",
1442 L"SeUndockPrivilege",
1443 L"SeSyncAgentPrivilege",
1444 L"SeEnableDelegationPrivilege",
1445 L"SeManageVolumePrivilege",
1446 L"SeImpersonatePrivilege",
1447 L"SeCreateGlobalPrivilege"
1448 };
1449 unsigned Priv;
1450
1451 if (NULL != SystemName && L'\0' != *SystemName)
1452 {
1453 FIXME("LookupPrivilegeValueW: not implemented for remote system\n");
1454 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1455 return FALSE;
1456 }
1457
1458 for (Priv = 0; Priv < sizeof(DefaultPrivNames) / sizeof(DefaultPrivNames[0]); Priv++)
1459 {
1460 if (0 == wcsicmp(PrivName, DefaultPrivNames[Priv]))
1461 {
1462 Luid->LowPart = Priv + 1;
1463 Luid->HighPart = 0;
1464 return TRUE;
1465 }
1466 }
1467
1468 WARN("LookupPrivilegeValueW: no such privilege %S\n", PrivName);
1469 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1470 return FALSE;
1471 }
1472
1473
1474 /**********************************************************************
1475 * LookupPrivilegeDisplayNameA EXPORTED
1476 *
1477 * @unimplemented
1478 */
1479 BOOL
1480 STDCALL
1481 LookupPrivilegeDisplayNameA(LPCSTR lpSystemName,
1482 LPCSTR lpName,
1483 LPSTR lpDisplayName,
1484 LPDWORD cbDisplayName,
1485 LPDWORD lpLanguageId)
1486 {
1487 FIXME("%s() not implemented!\n", __FUNCTION__);
1488 SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
1489 return FALSE;
1490 }
1491
1492
1493 /**********************************************************************
1494 * LookupPrivilegeDisplayNameW EXPORTED
1495 *
1496 * @unimplemented
1497 */
1498 BOOL
1499 STDCALL
1500 LookupPrivilegeDisplayNameW(LPCWSTR lpSystemName,
1501 LPCWSTR lpName,
1502 LPWSTR lpDisplayName,
1503 LPDWORD cbDisplayName,
1504 LPDWORD lpLanguageId)
1505 {
1506 FIXME("%s() not implemented!\n", __FUNCTION__);
1507 SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
1508 return FALSE;
1509 }
1510
1511
1512 /**********************************************************************
1513 * LookupPrivilegeNameA EXPORTED
1514 *
1515 * @implemented
1516 */
1517 BOOL
1518 STDCALL
1519 LookupPrivilegeNameA(LPCSTR lpSystemName,
1520 PLUID lpLuid,
1521 LPSTR lpName,
1522 LPDWORD cchName)
1523 {
1524 UNICODE_STRING lpSystemNameW;
1525 BOOL ret;
1526 DWORD wLen = 0;
1527
1528 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1529
1530 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1531 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1532 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1533 {
1534 LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1535
1536 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1537 &wLen);
1538 if (ret)
1539 {
1540 /* Windows crashes if cchName is NULL, so will I */
1541 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1542 *cchName, NULL, NULL);
1543
1544 if (len == 0)
1545 {
1546 /* WideCharToMultiByte failed */
1547 ret = FALSE;
1548 }
1549 else if (len > *cchName)
1550 {
1551 *cchName = len;
1552 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1553 ret = FALSE;
1554 }
1555 else
1556 {
1557 /* WideCharToMultiByte succeeded, output length needs to be
1558 * length not including NULL terminator
1559 */
1560 *cchName = len - 1;
1561 }
1562 }
1563 HeapFree(GetProcessHeap(), 0, lpNameW);
1564 }
1565 RtlFreeUnicodeString(&lpSystemNameW);
1566 return ret;
1567 }
1568
1569
1570 /**********************************************************************
1571 * LookupPrivilegeNameW EXPORTED
1572 *
1573 * @implemented
1574 */
1575 BOOL
1576 STDCALL
1577 LookupPrivilegeNameW(LPCWSTR lpSystemName,
1578 PLUID lpLuid,
1579 LPWSTR lpName,
1580 LPDWORD cchName)
1581 {
1582 size_t privNameLen;
1583
1584 TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
1585
1586 if (!ADVAPI_IsLocalComputer(lpSystemName))
1587 {
1588 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1589 return FALSE;
1590 }
1591 if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1592 lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
1593 {
1594 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1595 return FALSE;
1596 }
1597 privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
1598 /* Windows crashes if cchName is NULL, so will I */
1599 if (*cchName <= privNameLen)
1600 {
1601 *cchName = privNameLen + 1;
1602 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1603 return FALSE;
1604 }
1605 else
1606 {
1607 strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
1608 *cchName = privNameLen;
1609 return TRUE;
1610 }
1611 }
1612
1613
1614 static DWORD
1615 pGetSecurityInfoCheck(SECURITY_INFORMATION SecurityInfo,
1616 PSID *ppsidOwner,
1617 PSID *ppsidGroup,
1618 PACL *ppDacl,
1619 PACL *ppSacl,
1620 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
1621 {
1622 if ((SecurityInfo & (OWNER_SECURITY_INFORMATION |
1623 GROUP_SECURITY_INFORMATION |
1624 DACL_SECURITY_INFORMATION |
1625 SACL_SECURITY_INFORMATION)) &&
1626 ppSecurityDescriptor == NULL)
1627 {
1628 /* if one of the SIDs or ACLs are present, the security descriptor
1629 most not be NULL */
1630 return ERROR_INVALID_PARAMETER;
1631 }
1632 else
1633 {
1634 /* reset the pointers unless they're ignored */
1635 if ((SecurityInfo & OWNER_SECURITY_INFORMATION) &&
1636 ppsidOwner != NULL)
1637 {
1638 *ppsidOwner = NULL;
1639 }
1640 if ((SecurityInfo & GROUP_SECURITY_INFORMATION) &&
1641 ppsidGroup != NULL)
1642 {
1643 *ppsidGroup = NULL;
1644 }
1645 if ((SecurityInfo & DACL_SECURITY_INFORMATION) &&
1646 ppDacl != NULL)
1647 {
1648 *ppDacl = NULL;
1649 }
1650 if ((SecurityInfo & SACL_SECURITY_INFORMATION) &&
1651 ppSacl != NULL)
1652 {
1653 *ppSacl = NULL;
1654 }
1655
1656 if (SecurityInfo & (OWNER_SECURITY_INFORMATION |
1657 GROUP_SECURITY_INFORMATION |
1658 DACL_SECURITY_INFORMATION |
1659 SACL_SECURITY_INFORMATION))
1660 {
1661 *ppSecurityDescriptor = NULL;
1662 }
1663
1664 return ERROR_SUCCESS;
1665 }
1666 }
1667
1668
1669 static DWORD
1670 pSetSecurityInfoCheck(PSECURITY_DESCRIPTOR pSecurityDescriptor,
1671 SECURITY_INFORMATION SecurityInfo,
1672 PSID psidOwner,
1673 PSID psidGroup,
1674 PACL pDacl,
1675 PACL pSacl)
1676 {
1677 /* initialize a security descriptor on the stack */
1678 if (!InitializeSecurityDescriptor(pSecurityDescriptor,
1679 SECURITY_DESCRIPTOR_REVISION))
1680 {
1681 return GetLastError();
1682 }
1683
1684 if (SecurityInfo & OWNER_SECURITY_INFORMATION)
1685 {
1686 if (RtlValidSid(psidOwner))
1687 {
1688 if (!SetSecurityDescriptorOwner(pSecurityDescriptor,
1689 psidOwner,
1690 FALSE))
1691 {
1692 return GetLastError();
1693 }
1694 }
1695 else
1696 {
1697 return ERROR_INVALID_PARAMETER;
1698 }
1699 }
1700
1701 if (SecurityInfo & GROUP_SECURITY_INFORMATION)
1702 {
1703 if (RtlValidSid(psidGroup))
1704 {
1705 if (!SetSecurityDescriptorGroup(pSecurityDescriptor,
1706 psidGroup,
1707 FALSE))
1708 {
1709 return GetLastError();
1710 }
1711 }
1712 else
1713 {
1714 return ERROR_INVALID_PARAMETER;
1715 }
1716 }
1717
1718 if (SecurityInfo & DACL_SECURITY_INFORMATION)
1719 {
1720 if (pDacl != NULL)
1721 {
1722 if (SetSecurityDescriptorDacl(pSecurityDescriptor,
1723 TRUE,
1724 pDacl,
1725 FALSE))
1726 {
1727 /* check if the DACL needs to be protected from being
1728 modified by inheritable ACEs */
1729 if (SecurityInfo & PROTECTED_DACL_SECURITY_INFORMATION)
1730 {
1731 goto ProtectDacl;
1732 }
1733 }
1734 else
1735 {
1736 return GetLastError();
1737 }
1738 }
1739 else
1740 {
1741 ProtectDacl:
1742 /* protect the DACL from being modified by inheritable ACEs */
1743 if (!SetSecurityDescriptorControl(pSecurityDescriptor,
1744 SE_DACL_PROTECTED,
1745 SE_DACL_PROTECTED))
1746 {
1747 return GetLastError();
1748 }
1749 }
1750 }
1751
1752 if (SecurityInfo & SACL_SECURITY_INFORMATION)
1753 {
1754 if (pSacl != NULL)
1755 {
1756 if (SetSecurityDescriptorSacl(pSecurityDescriptor,
1757 TRUE,
1758 pSacl,
1759 FALSE))
1760 {
1761 /* check if the SACL needs to be protected from being
1762 modified by inheritable ACEs */
1763 if (SecurityInfo & PROTECTED_SACL_SECURITY_INFORMATION)
1764 {
1765 goto ProtectSacl;
1766 }
1767 }
1768 else
1769 {
1770 return GetLastError();
1771 }
1772 }
1773 else
1774 {
1775 ProtectSacl:
1776 /* protect the SACL from being modified by inheritable ACEs */
1777 if (!SetSecurityDescriptorControl(pSecurityDescriptor,
1778 SE_SACL_PROTECTED,
1779 SE_SACL_PROTECTED))
1780 {
1781 return GetLastError();
1782 }
1783 }
1784 }
1785
1786 return ERROR_SUCCESS;
1787 }
1788
1789
1790 /**********************************************************************
1791 * GetNamedSecurityInfoW EXPORTED
1792 *
1793 * @implemented
1794 */
1795 DWORD
1796 STDCALL
1797 GetNamedSecurityInfoW(LPWSTR pObjectName,
1798 SE_OBJECT_TYPE ObjectType,
1799 SECURITY_INFORMATION SecurityInfo,
1800 PSID *ppsidOwner,
1801 PSID *ppsidGroup,
1802 PACL *ppDacl,
1803 PACL *ppSacl,
1804 PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
1805 {
1806 DWORD ErrorCode;
1807
1808 if (pObjectName != NULL)
1809 {
1810 ErrorCode = CheckNtMartaPresent();
1811 if (ErrorCode == ERROR_SUCCESS)
1812 {
1813 ErrorCode = pGetSecurityInfoCheck(SecurityInfo,
1814 ppsidOwner,
1815 ppsidGroup,
1816 ppDacl,
1817 ppSacl,
1818 ppSecurityDescriptor);
1819
1820 if (ErrorCode == ERROR_SUCCESS)
1821 {
1822 /* call the MARTA provider */
1823 ErrorCode = AccRewriteGetNamedRights(pObjectName,
1824 ObjectType,
1825 SecurityInfo,
1826 ppsidOwner,
1827 ppsidGroup,
1828 ppDacl,
1829 ppSacl,
1830 ppSecurityDescriptor);
1831 }
1832 }
1833 }
1834 else
1835 ErrorCode = ERROR_INVALID_PARAMETER;
1836
1837 return ErrorCode;
1838 }
1839
1840
1841 /**********************************************************************
1842 * GetNamedSecurityInfoA EXPORTED
1843 *
1844 * @implemented
1845 */
1846 DWORD
1847 STDCALL
1848 GetNamedSecurityInfoA(LPSTR pObjectName,
1849 SE_OBJECT_TYPE ObjectType,
1850 SECURITY_INFORMATION SecurityInfo,
1851 PSID *ppsidOwner,
1852 PSID *ppsidGroup,
1853 PACL *ppDacl,
1854 PACL *ppSacl,
1855 PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
1856 {
1857 UNICODE_STRING ObjectName;
1858 NTSTATUS Status;
1859 DWORD Ret;
1860
1861 Status = RtlCreateUnicodeStringFromAsciiz(&ObjectName,
1862 pObjectName);
1863 if (!NT_SUCCESS(Status))
1864 {
1865 return RtlNtStatusToDosError(Status);
1866 }
1867
1868 Ret = GetNamedSecurityInfoW(ObjectName.Buffer,
1869 ObjectType,
1870 SecurityInfo,
1871 ppsidOwner,
1872 ppsidGroup,
1873 ppDacl,
1874 ppSacl,
1875 ppSecurityDescriptor);
1876
1877 RtlFreeUnicodeString(&ObjectName);
1878
1879 return Ret;
1880 }
1881
1882
1883 /**********************************************************************
1884 * SetNamedSecurityInfoW EXPORTED
1885 *
1886 * @implemented
1887 */
1888 DWORD
1889 STDCALL
1890 SetNamedSecurityInfoW(LPWSTR pObjectName,
1891 SE_OBJECT_TYPE ObjectType,
1892 SECURITY_INFORMATION SecurityInfo,
1893 PSID psidOwner,
1894 PSID psidGroup,
1895 PACL pDacl,
1896 PACL pSacl)
1897 {
1898 DWORD ErrorCode;
1899
1900 if (pObjectName != NULL)
1901 {
1902 ErrorCode = CheckNtMartaPresent();
1903 if (ErrorCode == ERROR_SUCCESS)
1904 {
1905 SECURITY_DESCRIPTOR SecurityDescriptor;
1906
1907 ErrorCode = pSetSecurityInfoCheck(&SecurityDescriptor,
1908 SecurityInfo,
1909 psidOwner,
1910 psidGroup,
1911 pDacl,
1912 pSacl);
1913
1914 if (ErrorCode == ERROR_SUCCESS)
1915 {
1916 /* call the MARTA provider */
1917 ErrorCode = AccRewriteSetNamedRights(pObjectName,
1918 ObjectType,
1919 SecurityInfo,
1920 &SecurityDescriptor);
1921 }
1922 }
1923 }
1924 else
1925 ErrorCode = ERROR_INVALID_PARAMETER;
1926
1927 return ErrorCode;
1928 }
1929
1930
1931 /**********************************************************************
1932 * SetNamedSecurityInfoA EXPORTED
1933 *
1934 * @implemented
1935 */
1936 DWORD
1937 STDCALL
1938 SetNamedSecurityInfoA(LPSTR pObjectName,
1939 SE_OBJECT_TYPE ObjectType,
1940 SECURITY_INFORMATION SecurityInfo,
1941 PSID psidOwner,
1942 PSID psidGroup,
1943 PACL pDacl,
1944 PACL pSacl)
1945 {
1946 UNICODE_STRING ObjectName;
1947 NTSTATUS Status;
1948 DWORD Ret;
1949
1950 Status = RtlCreateUnicodeStringFromAsciiz(&ObjectName,
1951 pObjectName);
1952 if (!NT_SUCCESS(Status))
1953 {
1954 return RtlNtStatusToDosError(Status);
1955 }
1956
1957 Ret = SetNamedSecurityInfoW(ObjectName.Buffer,
1958 ObjectType,
1959 SecurityInfo,
1960 psidOwner,
1961 psidGroup,
1962 pDacl,
1963 pSacl);
1964
1965 RtlFreeUnicodeString(&ObjectName);
1966
1967 return Ret;
1968 }
1969
1970
1971 /**********************************************************************
1972 * GetSecurityInfo EXPORTED
1973 *
1974 * @implemented
1975 */
1976 DWORD
1977 STDCALL
1978 GetSecurityInfo(HANDLE handle,
1979 SE_OBJECT_TYPE ObjectType,
1980 SECURITY_INFORMATION SecurityInfo,
1981 PSID *ppsidOwner,
1982 PSID *ppsidGroup,
1983 PACL *ppDacl,
1984 PACL *ppSacl,
1985 PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
1986 {
1987 DWORD ErrorCode;
1988
1989 if (handle != NULL)
1990 {
1991 ErrorCode = CheckNtMartaPresent();
1992 if (ErrorCode == ERROR_SUCCESS)
1993 {
1994 ErrorCode = pGetSecurityInfoCheck(SecurityInfo,
1995 ppsidOwner,
1996 ppsidGroup,
1997 ppDacl,
1998 ppSacl,
1999 ppSecurityDescriptor);
2000
2001 if (ErrorCode == ERROR_SUCCESS)
2002 {
2003 /* call the MARTA provider */
2004 ErrorCode = AccRewriteGetHandleRights(handle,
2005 ObjectType,
2006 SecurityInfo,
2007 ppsidOwner,
2008 ppsidGroup,
2009 ppDacl,
2010 ppSacl,
2011 ppSecurityDescriptor);
2012 }
2013 }
2014 }
2015 else
2016 ErrorCode = ERROR_INVALID_HANDLE;
2017
2018 return ErrorCode;
2019 }
2020
2021
2022 /**********************************************************************
2023 * SetSecurityInfo EXPORTED
2024 *
2025 * @implemented
2026 */
2027 DWORD
2028 WINAPI
2029 SetSecurityInfo(HANDLE handle,
2030 SE_OBJECT_TYPE ObjectType,
2031 SECURITY_INFORMATION SecurityInfo,
2032 PSID psidOwner,
2033 PSID psidGroup,
2034 PACL pDacl,
2035 PACL pSacl)
2036 {
2037 DWORD ErrorCode;
2038
2039 if (handle != NULL)
2040 {
2041 ErrorCode = CheckNtMartaPresent();
2042 if (ErrorCode == ERROR_SUCCESS)
2043 {
2044 SECURITY_DESCRIPTOR SecurityDescriptor;
2045
2046 ErrorCode = pSetSecurityInfoCheck(&SecurityDescriptor,
2047 SecurityInfo,
2048 psidOwner,
2049 psidGroup,
2050 pDacl,
2051 pSacl);
2052
2053 if (ErrorCode == ERROR_SUCCESS)
2054 {
2055 /* call the MARTA provider */
2056 ErrorCode = AccRewriteSetHandleRights(handle,
2057 ObjectType,
2058 SecurityInfo,
2059 &SecurityDescriptor);
2060 }
2061 }
2062 }
2063 else
2064 ErrorCode = ERROR_INVALID_HANDLE;
2065
2066 return ErrorCode;
2067 }
2068
2069
2070 /******************************************************************************
2071 * GetSecurityInfoExW EXPORTED
2072 */
2073 DWORD
2074 WINAPI
2075 GetSecurityInfoExA(HANDLE hObject,
2076 SE_OBJECT_TYPE ObjectType,
2077 SECURITY_INFORMATION SecurityInfo,
2078 LPCSTR lpProvider,
2079 LPCSTR lpProperty,
2080 PACTRL_ACCESSA *ppAccessList,
2081 PACTRL_AUDITA *ppAuditList,
2082 LPSTR *lppOwner,
2083 LPSTR *lppGroup)
2084 {
2085 FIXME("%s() not implemented!\n", __FUNCTION__);
2086 return ERROR_BAD_PROVIDER;
2087 }
2088
2089
2090 /******************************************************************************
2091 * GetSecurityInfoExW EXPORTED
2092 */
2093 DWORD
2094 WINAPI
2095 GetSecurityInfoExW(HANDLE hObject,
2096 SE_OBJECT_TYPE ObjectType,
2097 SECURITY_INFORMATION SecurityInfo,
2098 LPCWSTR lpProvider,
2099 LPCWSTR lpProperty,
2100 PACTRL_ACCESSW *ppAccessList,
2101 PACTRL_AUDITW *ppAuditList,
2102 LPWSTR *lppOwner,
2103 LPWSTR *lppGroup)
2104 {
2105 FIXME("%s() not implemented!\n", __FUNCTION__);
2106 return ERROR_BAD_PROVIDER;
2107 }
2108
2109
2110 /**********************************************************************
2111 * ImpersonateNamedPipeClient EXPORTED
2112 *
2113 * @implemented
2114 */
2115 BOOL
2116 STDCALL
2117 ImpersonateNamedPipeClient(HANDLE hNamedPipe)
2118 {
2119 IO_STATUS_BLOCK StatusBlock;
2120 NTSTATUS Status;
2121
2122 TRACE("ImpersonateNamedPipeClient() called\n");
2123
2124 Status = NtFsControlFile(hNamedPipe,
2125 NULL,
2126 NULL,
2127 NULL,
2128 &StatusBlock,
2129 FSCTL_PIPE_IMPERSONATE,
2130 NULL,
2131 0,
2132 NULL,
2133 0);
2134 if (!NT_SUCCESS(Status))
2135 {
2136 SetLastError(RtlNtStatusToDosError(Status));
2137 return FALSE;
2138 }
2139
2140 return TRUE;
2141 }
2142
2143
2144 /*
2145 * @implemented
2146 */
2147 BOOL
2148 STDCALL
2149 CreatePrivateObjectSecurity(PSECURITY_DESCRIPTOR ParentDescriptor,
2150 PSECURITY_DESCRIPTOR CreatorDescriptor,
2151 PSECURITY_DESCRIPTOR *NewDescriptor,
2152 BOOL IsDirectoryObject,
2153 HANDLE Token,
2154 PGENERIC_MAPPING GenericMapping)
2155 {
2156 NTSTATUS Status;
2157
2158 Status = RtlNewSecurityObject(ParentDescriptor,
2159 CreatorDescriptor,
2160 NewDescriptor,
2161 IsDirectoryObject,
2162 Token,
2163 GenericMapping);
2164 if (!NT_SUCCESS(Status))
2165 {
2166 SetLastError(RtlNtStatusToDosError(Status));
2167 return FALSE;
2168 }
2169
2170 return TRUE;
2171 }
2172
2173
2174 /*
2175 * @unimplemented
2176 */
2177 BOOL
2178 STDCALL
2179 CreatePrivateObjectSecurityEx(PSECURITY_DESCRIPTOR ParentDescriptor,
2180 PSECURITY_DESCRIPTOR CreatorDescriptor,
2181 PSECURITY_DESCRIPTOR* NewDescriptor,
2182 GUID* ObjectType,
2183 BOOL IsContainerObject,
2184 ULONG AutoInheritFlags,
2185 HANDLE Token,
2186 PGENERIC_MAPPING GenericMapping)
2187 {
2188 FIXME("%s() not implemented!\n", __FUNCTION__);
2189 return FALSE;
2190 }
2191
2192
2193 /*
2194 * @unimplemented
2195 */
2196 BOOL
2197 STDCALL
2198 CreatePrivateObjectSecurityWithMultipleInheritance(PSECURITY_DESCRIPTOR ParentDescriptor,
2199 PSECURITY_DESCRIPTOR CreatorDescriptor,
2200 PSECURITY_DESCRIPTOR* NewDescriptor,
2201 GUID** ObjectTypes,
2202 ULONG GuidCount,
2203 BOOL IsContainerObject,
2204 ULONG AutoInheritFlags,
2205 HANDLE Token,
2206 PGENERIC_MAPPING GenericMapping)
2207 {
2208 FIXME("%s() not implemented!\n", __FUNCTION__);
2209 return FALSE;
2210 }
2211
2212
2213 /*
2214 * @implemented
2215 */
2216 BOOL
2217 STDCALL
2218 DestroyPrivateObjectSecurity(PSECURITY_DESCRIPTOR *ObjectDescriptor)
2219 {
2220 NTSTATUS Status;
2221
2222 Status = RtlDeleteSecurityObject(ObjectDescriptor);
2223 if (!NT_SUCCESS(Status))
2224 {
2225 SetLastError(RtlNtStatusToDosError(Status));
2226 return FALSE;
2227 }
2228
2229 return TRUE;
2230 }
2231
2232
2233 /*
2234 * @implemented
2235 */
2236 BOOL
2237 STDCALL
2238 GetPrivateObjectSecurity(PSECURITY_DESCRIPTOR ObjectDescriptor,
2239 SECURITY_INFORMATION SecurityInformation,
2240 PSECURITY_DESCRIPTOR ResultantDescriptor,
2241 DWORD DescriptorLength,
2242 PDWORD ReturnLength)
2243 {
2244 NTSTATUS Status;
2245
2246 Status = RtlQuerySecurityObject(ObjectDescriptor,
2247 SecurityInformation,
2248 ResultantDescriptor,
2249 DescriptorLength,
2250 ReturnLength);
2251 if (!NT_SUCCESS(Status))
2252 {
2253 SetLastError(RtlNtStatusToDosError(Status));
2254 return FALSE;
2255 }
2256
2257 return TRUE;
2258 }
2259
2260
2261 /*
2262 * @implemented
2263 */
2264 BOOL
2265 STDCALL
2266 SetPrivateObjectSecurity(SECURITY_INFORMATION SecurityInformation,
2267 PSECURITY_DESCRIPTOR ModificationDescriptor,
2268 PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
2269 PGENERIC_MAPPING GenericMapping,
2270 HANDLE Token)
2271 {
2272 NTSTATUS Status;
2273
2274 Status = RtlSetSecurityObject(SecurityInformation,
2275 ModificationDescriptor,
2276 ObjectsSecurityDescriptor,
2277 GenericMapping,
2278 Token);
2279 if (!NT_SUCCESS(Status))
2280 {
2281 SetLastError(RtlNtStatusToDosError(Status));
2282 return FALSE;
2283 }
2284
2285 return TRUE;
2286 }
2287
2288
2289 /*
2290 * @implemented
2291 */
2292 DWORD
2293 STDCALL
2294 TreeResetNamedSecurityInfoW(LPWSTR pObjectName,
2295 SE_OBJECT_TYPE ObjectType,
2296 SECURITY_INFORMATION SecurityInfo,
2297 PSID pOwner,
2298 PSID pGroup,
2299 PACL pDacl,
2300 PACL pSacl,
2301 BOOL KeepExplicit,
2302 FN_PROGRESSW fnProgress,
2303 PROG_INVOKE_SETTING ProgressInvokeSetting,
2304 PVOID Args)
2305 {
2306 DWORD ErrorCode;
2307
2308 if (pObjectName != NULL)
2309 {
2310 ErrorCode = CheckNtMartaPresent();
2311 if (ErrorCode == ERROR_SUCCESS)
2312 {
2313 switch (ObjectType)
2314 {
2315 case SE_FILE_OBJECT:
2316 case SE_REGISTRY_KEY:
2317 {
2318 /* check the SecurityInfo flags for sanity (both, the protected
2319 and unprotected dacl/sacl flag must not be passed together) */
2320 if (((SecurityInfo & DACL_SECURITY_INFORMATION) &&
2321 (SecurityInfo & (PROTECTED_DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION)) ==
2322 (PROTECTED_DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION))
2323
2324 ||
2325
2326 ((SecurityInfo & SACL_SECURITY_INFORMATION) &&
2327 (SecurityInfo & (PROTECTED_SACL_SECURITY_INFORMATION | UNPROTECTED_SACL_SECURITY_INFORMATION)) ==
2328 (PROTECTED_SACL_SECURITY_INFORMATION | UNPROTECTED_SACL_SECURITY_INFORMATION)))
2329 {
2330 ErrorCode = ERROR_INVALID_PARAMETER;
2331 break;
2332 }
2333
2334 /* call the MARTA provider */
2335 ErrorCode = AccTreeResetNamedSecurityInfo(pObjectName,
2336 ObjectType,
2337 SecurityInfo,
2338 pOwner,
2339 pGroup,
2340 pDacl,
2341 pSacl,
2342 KeepExplicit,
2343 fnProgress,
2344 ProgressInvokeSetting,
2345 Args);
2346 break;
2347 }
2348
2349 default:
2350 /* object type not supported */
2351 ErrorCode = ERROR_INVALID_PARAMETER;
2352 break;
2353 }
2354 }
2355 }
2356 else
2357 ErrorCode = ERROR_INVALID_PARAMETER;
2358
2359 return ErrorCode;
2360 }
2361
2362 #ifdef HAS_FN_PROGRESSW
2363
2364 typedef struct _INERNAL_FNPROGRESSW_DATA
2365 {
2366 FN_PROGRESSA fnProgress;
2367 PVOID Args;
2368 } INERNAL_FNPROGRESSW_DATA, *PINERNAL_FNPROGRESSW_DATA;
2369
2370 static VOID STDCALL
2371 InternalfnProgressW(LPWSTR pObjectName,
2372 DWORD Status,
2373 PPROG_INVOKE_SETTING pInvokeSetting,
2374 PVOID Args,
2375 BOOL SecuritySet)
2376 {
2377 PINERNAL_FNPROGRESSW_DATA pifnProgressData = (PINERNAL_FNPROGRESSW_DATA)Args;
2378 INT ObjectNameSize;
2379 LPSTR pObjectNameA;
2380
2381 ObjectNameSize = WideCharToMultiByte(CP_ACP,
2382 0,
2383 pObjectName,
2384 -1,
2385 NULL,
2386 0,
2387 NULL,
2388 NULL);
2389
2390 if (ObjectNameSize > 0)
2391 {
2392 pObjectNameA = RtlAllocateHeap(RtlGetProcessHeap(),
2393 0,
2394 ObjectNameSize);
2395 if (pObjectNameA != NULL)
2396 {
2397 pObjectNameA[0] = '\0';
2398 WideCharToMultiByte(CP_ACP,
2399 0,
2400 pObjectName,
2401 -1,
2402 pObjectNameA,
2403 ObjectNameSize,
2404 NULL,
2405 NULL);
2406
2407 pifnProgressData->fnProgress((LPWSTR)pObjectNameA, /* FIXME: wrong cast!! */
2408 Status,
2409 pInvokeSetting,
2410 pifnProgressData->Args,
2411 SecuritySet);
2412
2413 RtlFreeHeap(RtlGetProcessHeap(),
2414 0,
2415 pObjectNameA);
2416 }
2417 }
2418 }
2419 #endif
2420
2421
2422 /*
2423 * @implemented
2424 */
2425 DWORD
2426 STDCALL
2427 TreeResetNamedSecurityInfoA(LPSTR pObjectName,
2428 SE_OBJECT_TYPE ObjectType,
2429 SECURITY_INFORMATION SecurityInfo,
2430 PSID pOwner,
2431 PSID pGroup,
2432 PACL pDacl,
2433 PACL pSacl,
2434 BOOL KeepExplicit,
2435 FN_PROGRESSA fnProgress,
2436 PROG_INVOKE_SETTING ProgressInvokeSetting,
2437 PVOID Args)
2438 {
2439 #ifndef HAS_FN_PROGRESSW
2440 /* That's all this function does, at least up to w2k3... Even MS was too
2441 lazy to implement it... */
2442 return ERROR_CALL_NOT_IMPLEMENTED;
2443 #else
2444 INERNAL_FNPROGRESSW_DATA ifnProgressData;
2445 UNICODE_STRING ObjectName;
2446 NTSTATUS Status;
2447 DWORD Ret;
2448
2449 Status = RtlCreateUnicodeStringFromAsciiz(&ObjectName,
2450 pObjectName);
2451 if (!NT_SUCCESS(Status))
2452 {
2453 return RtlNtStatusToDosError(Status);
2454 }
2455
2456 ifnProgressData.fnProgress = fnProgress;
2457 ifnProgressData.Args = Args;
2458
2459 Ret = TreeResetNamedSecurityInfoW(ObjectName.Buffer,
2460 ObjectType,
2461 SecurityInfo,
2462 pOwner,
2463 pGroup,
2464 pDacl,
2465 pSacl,
2466 KeepExplicit,
2467 (fnProgress != NULL ? InternalfnProgressW : NULL),
2468 ProgressInvokeSetting,
2469 &ifnProgressData);
2470
2471 RtlFreeUnicodeString(&ObjectName);
2472
2473 return Ret;
2474 #endif
2475 }
2476
2477 /* EOF */