[ADVAPI32] Fix crash when running advapi32:security with DPH.
[reactos.git] / dll / win32 / advapi32 / wine / security.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 * Copyright 2006 Hervé Poussineau
8 *
9 * PROJECT: ReactOS system libraries
10 * FILE: dll/win32/advapi32/wine/security.c
11 */
12
13 #include <advapi32.h>
14
15 #include <sddl.h>
16
17 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
18
19 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes);
20
21 typedef struct _ACEFLAG
22 {
23 LPCWSTR wstr;
24 DWORD value;
25 } ACEFLAG, *LPACEFLAG;
26
27 typedef struct _MAX_SID
28 {
29 /* same fields as struct _SID */
30 BYTE Revision;
31 BYTE SubAuthorityCount;
32 SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
33 DWORD SubAuthority[SID_MAX_SUB_AUTHORITIES];
34 } MAX_SID;
35
36 typedef struct WELLKNOWNSID
37 {
38 WCHAR wstr[2];
39 WELL_KNOWN_SID_TYPE Type;
40 MAX_SID Sid;
41 } WELLKNOWNSID;
42
43 static const WELLKNOWNSID WellKnownSids[] =
44 {
45 { {0,0}, WinNullSid, { SID_REVISION, 1, { SECURITY_NULL_SID_AUTHORITY }, { SECURITY_NULL_RID } } },
46 { {'W','D'}, WinWorldSid, { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY }, { SECURITY_WORLD_RID } } },
47 { {0,0}, WinLocalSid, { SID_REVISION, 1, { SECURITY_LOCAL_SID_AUTHORITY }, { SECURITY_LOCAL_RID } } },
48 { {'C','O'}, WinCreatorOwnerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_RID } } },
49 { {'C','G'}, WinCreatorGroupSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_RID } } },
50 { {0,0}, WinCreatorOwnerServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_SERVER_RID } } },
51 { {0,0}, WinCreatorGroupServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_SERVER_RID } } },
52 { {0,0}, WinNtAuthoritySid, { SID_REVISION, 0, { SECURITY_NT_AUTHORITY }, { SECURITY_NULL_RID } } },
53 { {0,0}, WinDialupSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_DIALUP_RID } } },
54 { {'N','U'}, WinNetworkSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_RID } } },
55 { {0,0}, WinBatchSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BATCH_RID } } },
56 { {'I','U'}, WinInteractiveSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_INTERACTIVE_RID } } },
57 { {'S','U'}, WinServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_SERVICE_RID } } },
58 { {'A','N'}, WinAnonymousSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ANONYMOUS_LOGON_RID } } },
59 { {0,0}, WinProxySid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PROXY_RID } } },
60 { {'E','D'}, WinEnterpriseControllersSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ENTERPRISE_CONTROLLERS_RID } } },
61 { {'P','S'}, WinSelfSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PRINCIPAL_SELF_RID } } },
62 { {'A','U'}, WinAuthenticatedUserSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_AUTHENTICATED_USER_RID } } },
63 { {'R','C'}, WinRestrictedCodeSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_RESTRICTED_CODE_RID } } },
64 { {0,0}, WinTerminalServerSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_TERMINAL_SERVER_RID } } },
65 { {0,0}, WinRemoteLogonIdSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_REMOTE_LOGON_RID } } },
66 { {'S','Y'}, WinLocalSystemSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SYSTEM_RID } } },
67 { {'L','S'}, WinLocalServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SERVICE_RID } } },
68 { {'N','S'}, WinNetworkServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_SERVICE_RID } } },
69 { {0,0}, WinBuiltinDomainSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID } } },
70 { {'B','A'}, WinBuiltinAdministratorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS } } },
71 { {'B','U'}, WinBuiltinUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS } } },
72 { {'B','G'}, WinBuiltinGuestsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_GUESTS } } },
73 { {'P','U'}, WinBuiltinPowerUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS } } },
74 { {'A','O'}, WinBuiltinAccountOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ACCOUNT_OPS } } },
75 { {'S','O'}, WinBuiltinSystemOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_SYSTEM_OPS } } },
76 { {'P','O'}, WinBuiltinPrintOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PRINT_OPS } } },
77 { {'B','O'}, WinBuiltinBackupOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_BACKUP_OPS } } },
78 { {'R','E'}, WinBuiltinReplicatorSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REPLICATOR } } },
79 { {'R','U'}, WinBuiltinPreWindows2000CompatibleAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PREW2KCOMPACCESS } } },
80 { {'R','D'}, WinBuiltinRemoteDesktopUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS } } },
81 { {'N','O'}, WinBuiltinNetworkConfigurationOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS } } },
82 { {0,0}, WinNTLMAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_NTLM_RID } } },
83 { {0,0}, WinDigestAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_DIGEST_RID } } },
84 { {0,0}, WinSChannelAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_SCHANNEL_RID } } },
85 { {0,0}, WinThisOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_THIS_ORGANIZATION_RID } } },
86 { {0,0}, WinOtherOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_OTHER_ORGANIZATION_RID } } },
87 { {0,0}, WinBuiltinIncomingForestTrustBuildersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS } } },
88 { {0,0}, WinBuiltinPerfMonitoringUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_MONITORING_USERS } } },
89 { {0,0}, WinBuiltinPerfLoggingUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_LOGGING_USERS } } },
90 { {0,0}, WinBuiltinAuthorizationAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS } } },
91 { {0,0}, WinBuiltinTerminalServerLicenseServersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS } } },
92 { {0,0}, WinBuiltinDCOMUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_DCOM_USERS } } },
93 { {'L','W'}, WinLowLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_LOW_RID} } },
94 { {'M','E'}, WinMediumLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_MEDIUM_RID } } },
95 { {'H','I'}, WinHighLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_HIGH_RID } } },
96 { {'S','I'}, WinSystemLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_SYSTEM_RID } } },
97 };
98
99 /* these SIDs must be constructed as relative to some domain - only the RID is well-known */
100 typedef struct WELLKNOWNRID
101 {
102 WCHAR wstr[2];
103 WELL_KNOWN_SID_TYPE Type;
104 DWORD Rid;
105 } WELLKNOWNRID;
106
107 static const WELLKNOWNRID WellKnownRids[] = {
108 { {'L','A'}, WinAccountAdministratorSid, DOMAIN_USER_RID_ADMIN },
109 { {'L','G'}, WinAccountGuestSid, DOMAIN_USER_RID_GUEST },
110 { {0,0}, WinAccountKrbtgtSid, DOMAIN_USER_RID_KRBTGT },
111 { {'D','A'}, WinAccountDomainAdminsSid, DOMAIN_GROUP_RID_ADMINS },
112 { {'D','U'}, WinAccountDomainUsersSid, DOMAIN_GROUP_RID_USERS },
113 { {'D','G'}, WinAccountDomainGuestsSid, DOMAIN_GROUP_RID_GUESTS },
114 { {'D','C'}, WinAccountComputersSid, DOMAIN_GROUP_RID_COMPUTERS },
115 { {'D','D'}, WinAccountControllersSid, DOMAIN_GROUP_RID_CONTROLLERS },
116 { {'C','A'}, WinAccountCertAdminsSid, DOMAIN_GROUP_RID_CERT_ADMINS },
117 { {'S','A'}, WinAccountSchemaAdminsSid, DOMAIN_GROUP_RID_SCHEMA_ADMINS },
118 { {'E','A'}, WinAccountEnterpriseAdminsSid, DOMAIN_GROUP_RID_ENTERPRISE_ADMINS },
119 { {'P','A'}, WinAccountPolicyAdminsSid, DOMAIN_GROUP_RID_POLICY_ADMINS },
120 { {'R','S'}, WinAccountRasAndIasServersSid, DOMAIN_ALIAS_RID_RAS_SERVERS },
121 };
122
123 #ifndef __REACTOS__
124 static const SID sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } };
125 #endif
126
127 static const WCHAR SDDL_NO_READ_UP[] = {'N','R',0};
128 static const WCHAR SDDL_NO_WRITE_UP[] = {'N','W',0};
129 static const WCHAR SDDL_NO_EXECUTE_UP[] = {'N','X',0};
130
131 /*
132 * ACE types
133 */
134 static const WCHAR SDDL_ACCESS_ALLOWED[] = {'A',0};
135 static const WCHAR SDDL_ACCESS_DENIED[] = {'D',0};
136 #ifndef __REACTOS__
137 static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED[] = {'O','A',0};
138 static const WCHAR SDDL_OBJECT_ACCESS_DENIED[] = {'O','D',0};
139 #endif
140 static const WCHAR SDDL_AUDIT[] = {'A','U',0};
141 static const WCHAR SDDL_ALARM[] = {'A','L',0};
142 static const WCHAR SDDL_MANDATORY_LABEL[] = {'M','L',0};
143 #ifndef __REACTOS__
144 static const WCHAR SDDL_OBJECT_AUDIT[] = {'O','U',0};
145 static const WCHAR SDDL_OBJECT_ALARM[] = {'O','L',0};
146 #endif
147
148 /*
149 * SDDL ADS Rights
150 */
151 #define ADS_RIGHT_DS_CREATE_CHILD 0x0001
152 #define ADS_RIGHT_DS_DELETE_CHILD 0x0002
153 #define ADS_RIGHT_ACTRL_DS_LIST 0x0004
154 #define ADS_RIGHT_DS_SELF 0x0008
155 #define ADS_RIGHT_DS_READ_PROP 0x0010
156 #define ADS_RIGHT_DS_WRITE_PROP 0x0020
157 #define ADS_RIGHT_DS_DELETE_TREE 0x0040
158 #define ADS_RIGHT_DS_LIST_OBJECT 0x0080
159 #define ADS_RIGHT_DS_CONTROL_ACCESS 0x0100
160
161 /*
162 * ACE flags
163 */
164 static const WCHAR SDDL_CONTAINER_INHERIT[] = {'C','I',0};
165 static const WCHAR SDDL_OBJECT_INHERIT[] = {'O','I',0};
166 static const WCHAR SDDL_NO_PROPAGATE[] = {'N','P',0};
167 static const WCHAR SDDL_INHERIT_ONLY[] = {'I','O',0};
168 static const WCHAR SDDL_INHERITED[] = {'I','D',0};
169 static const WCHAR SDDL_AUDIT_SUCCESS[] = {'S','A',0};
170 static const WCHAR SDDL_AUDIT_FAILURE[] = {'F','A',0};
171
172 static const char * debugstr_sid(PSID sid)
173 {
174 int auth = 0;
175 SID * psid = (SID *)sid;
176
177 if (psid == NULL)
178 return "(null)";
179
180 auth = psid->IdentifierAuthority.Value[5] +
181 (psid->IdentifierAuthority.Value[4] << 8) +
182 (psid->IdentifierAuthority.Value[3] << 16) +
183 (psid->IdentifierAuthority.Value[2] << 24);
184
185 switch (psid->SubAuthorityCount) {
186 case 0:
187 return wine_dbg_sprintf("S-%d-%d", psid->Revision, auth);
188 case 1:
189 return wine_dbg_sprintf("S-%d-%d-%lu", psid->Revision, auth,
190 psid->SubAuthority[0]);
191 case 2:
192 return wine_dbg_sprintf("S-%d-%d-%lu-%lu", psid->Revision, auth,
193 psid->SubAuthority[0], psid->SubAuthority[1]);
194 case 3:
195 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu", psid->Revision, auth,
196 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2]);
197 case 4:
198 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu", psid->Revision, auth,
199 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
200 psid->SubAuthority[3]);
201 case 5:
202 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu", psid->Revision, auth,
203 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
204 psid->SubAuthority[3], psid->SubAuthority[4]);
205 case 6:
206 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu-%lu", psid->Revision, auth,
207 psid->SubAuthority[3], psid->SubAuthority[1], psid->SubAuthority[2],
208 psid->SubAuthority[0], psid->SubAuthority[4], psid->SubAuthority[5]);
209 case 7:
210 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu-%lu-%lu", psid->Revision, auth,
211 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
212 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
213 psid->SubAuthority[6]);
214 case 8:
215 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu-%lu-%lu-%lu", psid->Revision, auth,
216 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
217 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
218 psid->SubAuthority[6], psid->SubAuthority[7]);
219 }
220 return "(too-big)";
221 }
222
223 /* set last error code from NT status and get the proper boolean return value */
224 /* used for functions that are a simple wrapper around the corresponding ntdll API */
225 static __inline BOOL set_ntstatus( NTSTATUS status )
226 {
227 if (!NT_SUCCESS(status)) SetLastError( RtlNtStatusToDosError( status ));
228 return NT_SUCCESS(status);
229 }
230
231 static LPWSTR SERV_dup( LPCSTR str )
232 {
233 UINT len;
234 LPWSTR wstr;
235
236 if( !str )
237 return NULL;
238 len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );
239 wstr = heap_alloc( len*sizeof (WCHAR) );
240 MultiByteToWideChar( CP_ACP, 0, str, -1, wstr, len );
241 return wstr;
242 }
243
244 /************************************************************
245 * ADVAPI_IsLocalComputer
246 *
247 * Checks whether the server name indicates local machine.
248 */
249 BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName)
250 {
251 DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
252 BOOL Result;
253 LPWSTR buf;
254
255 if (!ServerName || !ServerName[0])
256 return TRUE;
257
258 buf = heap_alloc(dwSize * sizeof(WCHAR));
259 Result = GetComputerNameW(buf, &dwSize);
260 if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
261 ServerName += 2;
262 Result = Result && !lstrcmpW(ServerName, buf);
263 heap_free(buf);
264
265 return Result;
266 }
267
268 /************************************************************
269 * ADVAPI_GetComputerSid
270 */
271 BOOL ADVAPI_GetComputerSid(PSID sid)
272 {
273 static const struct /* same fields as struct SID */
274 {
275 BYTE Revision;
276 BYTE SubAuthorityCount;
277 SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
278 DWORD SubAuthority[4];
279 } computer_sid =
280 { SID_REVISION, 4, { SECURITY_NT_AUTHORITY }, { SECURITY_NT_NON_UNIQUE, 0, 0, 0 } };
281
282 memcpy( sid, &computer_sid, sizeof(computer_sid) );
283 return TRUE;
284 }
285
286 /* Exported functions */
287
288 /*
289 * @implemented
290 */
291 BOOL WINAPI
292 OpenProcessToken(HANDLE ProcessHandle,
293 DWORD DesiredAccess,
294 PHANDLE TokenHandle)
295 {
296 NTSTATUS Status;
297
298 TRACE("%p, %x, %p.\n", ProcessHandle, DesiredAccess, TokenHandle);
299
300 Status = NtOpenProcessToken(ProcessHandle,
301 DesiredAccess,
302 TokenHandle);
303 if (!NT_SUCCESS(Status))
304 {
305 ERR("NtOpenProcessToken failed! Status %08x.\n", Status);
306 SetLastError(RtlNtStatusToDosError(Status));
307 return FALSE;
308 }
309
310 TRACE("Returning token %p.\n", *TokenHandle);
311
312 return TRUE;
313 }
314
315 /******************************************************************************
316 * OpenThreadToken [ADVAPI32.@]
317 *
318 * Opens the access token associated with a thread handle.
319 *
320 * PARAMS
321 * ThreadHandle [I] Handle to process
322 * DesiredAccess [I] Desired access to the thread
323 * OpenAsSelf [I] ???
324 * TokenHandle [O] Destination for the token handle
325 *
326 * RETURNS
327 * Success: TRUE. TokenHandle contains the access token.
328 * Failure: FALSE.
329 *
330 * NOTES
331 * See NtOpenThreadToken.
332 */
333 BOOL WINAPI
334 OpenThreadToken( HANDLE ThreadHandle, DWORD DesiredAccess,
335 BOOL OpenAsSelf, HANDLE *TokenHandle)
336 {
337 return set_ntstatus( NtOpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle));
338 }
339
340 /*
341 * @implemented
342 */
343 BOOL WINAPI
344 AdjustTokenGroups(HANDLE TokenHandle,
345 BOOL ResetToDefault,
346 PTOKEN_GROUPS NewState,
347 DWORD BufferLength,
348 PTOKEN_GROUPS PreviousState,
349 PDWORD ReturnLength)
350 {
351 NTSTATUS Status;
352
353 Status = NtAdjustGroupsToken(TokenHandle,
354 ResetToDefault,
355 NewState,
356 BufferLength,
357 PreviousState,
358 (PULONG)ReturnLength);
359 if (!NT_SUCCESS(Status))
360 {
361 SetLastError(RtlNtStatusToDosError(Status));
362 return FALSE;
363 }
364
365 return TRUE;
366 }
367
368 /*
369 * @implemented
370 */
371 BOOL WINAPI
372 AdjustTokenPrivileges(HANDLE TokenHandle,
373 BOOL DisableAllPrivileges,
374 PTOKEN_PRIVILEGES NewState,
375 DWORD BufferLength,
376 PTOKEN_PRIVILEGES PreviousState,
377 PDWORD ReturnLength)
378 {
379 NTSTATUS Status;
380
381 Status = NtAdjustPrivilegesToken(TokenHandle,
382 DisableAllPrivileges,
383 NewState,
384 BufferLength,
385 PreviousState,
386 (PULONG)ReturnLength);
387 if (STATUS_NOT_ALL_ASSIGNED == Status)
388 {
389 SetLastError(ERROR_NOT_ALL_ASSIGNED);
390 return TRUE;
391 }
392
393 if (!NT_SUCCESS(Status))
394 {
395 SetLastError(RtlNtStatusToDosError(Status));
396 return FALSE;
397 }
398
399 /* AdjustTokenPrivileges is documented to do this */
400 SetLastError(ERROR_SUCCESS);
401
402 return TRUE;
403 }
404
405 /*
406 * @implemented
407 */
408 BOOL WINAPI
409 GetTokenInformation(HANDLE TokenHandle,
410 TOKEN_INFORMATION_CLASS TokenInformationClass,
411 LPVOID TokenInformation,
412 DWORD TokenInformationLength,
413 PDWORD ReturnLength)
414 {
415 NTSTATUS Status;
416
417 Status = NtQueryInformationToken(TokenHandle,
418 TokenInformationClass,
419 TokenInformation,
420 TokenInformationLength,
421 (PULONG)ReturnLength);
422 if (!NT_SUCCESS(Status))
423 {
424 SetLastError(RtlNtStatusToDosError(Status));
425 return FALSE;
426 }
427
428 return TRUE;
429 }
430
431 /*
432 * @implemented
433 */
434 BOOL WINAPI
435 SetTokenInformation(HANDLE TokenHandle,
436 TOKEN_INFORMATION_CLASS TokenInformationClass,
437 LPVOID TokenInformation,
438 DWORD TokenInformationLength)
439 {
440 NTSTATUS Status;
441
442 Status = NtSetInformationToken(TokenHandle,
443 TokenInformationClass,
444 TokenInformation,
445 TokenInformationLength);
446 if (!NT_SUCCESS(Status))
447 {
448 SetLastError(RtlNtStatusToDosError(Status));
449 return FALSE;
450 }
451
452 return TRUE;
453 }
454
455 /*
456 * @implemented
457 */
458 BOOL WINAPI
459 SetThreadToken(IN PHANDLE ThreadHandle OPTIONAL,
460 IN HANDLE TokenHandle)
461 {
462 NTSTATUS Status;
463 HANDLE hThread;
464
465 hThread = (ThreadHandle != NULL) ? *ThreadHandle : NtCurrentThread();
466
467 Status = NtSetInformationThread(hThread,
468 ThreadImpersonationToken,
469 &TokenHandle,
470 sizeof(HANDLE));
471 if (!NT_SUCCESS(Status))
472 {
473 SetLastError(RtlNtStatusToDosError(Status));
474 return FALSE;
475 }
476
477 return TRUE;
478 }
479
480 /*************************************************************************
481 * CreateRestrictedToken [ADVAPI32.@]
482 *
483 * Create a new more restricted token from an existing token.
484 *
485 * PARAMS
486 * baseToken [I] Token to base the new restricted token on
487 * flags [I] Options
488 * nDisableSids [I] Length of disableSids array
489 * disableSids [I] Array of SIDs to disable in the new token
490 * nDeletePrivs [I] Length of deletePrivs array
491 * deletePrivs [I] Array of privileges to delete in the new token
492 * nRestrictSids [I] Length of restrictSids array
493 * restrictSids [I] Array of SIDs to restrict in the new token
494 * newToken [O] Address where the new token is stored
495 *
496 * RETURNS
497 * Success: TRUE
498 * Failure: FALSE
499 */
500 BOOL WINAPI CreateRestrictedToken(
501 HANDLE baseToken,
502 DWORD flags,
503 DWORD nDisableSids,
504 PSID_AND_ATTRIBUTES disableSids,
505 DWORD nDeletePrivs,
506 PLUID_AND_ATTRIBUTES deletePrivs,
507 DWORD nRestrictSids,
508 PSID_AND_ATTRIBUTES restrictSids,
509 PHANDLE newToken)
510 {
511 TOKEN_TYPE type;
512 SECURITY_IMPERSONATION_LEVEL level = SecurityAnonymous;
513 DWORD size;
514
515 FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n",
516 baseToken, flags, nDisableSids, disableSids,
517 nDeletePrivs, deletePrivs,
518 nRestrictSids, restrictSids,
519 newToken);
520
521 size = sizeof(type);
522 if (!GetTokenInformation( baseToken, TokenType, &type, size, &size )) return FALSE;
523 if (type == TokenImpersonation)
524 {
525 size = sizeof(level);
526 if (!GetTokenInformation( baseToken, TokenImpersonationLevel, &level, size, &size ))
527 return FALSE;
528 }
529 return DuplicateTokenEx( baseToken, MAXIMUM_ALLOWED, NULL, level, type, newToken );
530 }
531
532 /******************************************************************************
533 * AllocateAndInitializeSid [ADVAPI32.@]
534 *
535 * PARAMS
536 * pIdentifierAuthority []
537 * nSubAuthorityCount []
538 * nSubAuthority0 []
539 * nSubAuthority1 []
540 * nSubAuthority2 []
541 * nSubAuthority3 []
542 * nSubAuthority4 []
543 * nSubAuthority5 []
544 * nSubAuthority6 []
545 * nSubAuthority7 []
546 * pSid []
547 */
548 BOOL WINAPI
549 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
550 BYTE nSubAuthorityCount,
551 DWORD nSubAuthority0, DWORD nSubAuthority1,
552 DWORD nSubAuthority2, DWORD nSubAuthority3,
553 DWORD nSubAuthority4, DWORD nSubAuthority5,
554 DWORD nSubAuthority6, DWORD nSubAuthority7,
555 PSID *pSid )
556 {
557 return set_ntstatus( RtlAllocateAndInitializeSid(
558 pIdentifierAuthority, nSubAuthorityCount,
559 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
560 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
561 pSid ));
562 }
563
564 /*
565 * @implemented
566 *
567 * RETURNS
568 * Docs says this function does NOT return a value
569 * even thou it's defined to return a PVOID...
570 */
571 PVOID
572 WINAPI
573 FreeSid(PSID pSid)
574 {
575 return RtlFreeSid(pSid);
576 }
577
578 /******************************************************************************
579 * CopySid [ADVAPI32.@]
580 *
581 * PARAMS
582 * nDestinationSidLength []
583 * pDestinationSid []
584 * pSourceSid []
585 */
586 BOOL WINAPI
587 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
588 {
589 return set_ntstatus(RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid));
590 }
591
592 /*
593 * @unimplemented
594 */
595 BOOL
596 WINAPI
597 CreateWellKnownSid(IN WELL_KNOWN_SID_TYPE WellKnownSidType,
598 IN PSID DomainSid OPTIONAL,
599 OUT PSID pSid,
600 IN OUT DWORD* cbSid)
601 {
602 unsigned int i;
603 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
604
605 if (cbSid == NULL || (DomainSid && !IsValidSid(DomainSid)))
606 {
607 SetLastError(ERROR_INVALID_PARAMETER);
608 return FALSE;
609 }
610
611 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
612 if (WellKnownSids[i].Type == WellKnownSidType) {
613 DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
614
615 if (*cbSid < length)
616 {
617 *cbSid = length;
618 SetLastError(ERROR_INSUFFICIENT_BUFFER);
619 return FALSE;
620 }
621 if (!pSid)
622 {
623 SetLastError(ERROR_INVALID_PARAMETER);
624 return FALSE;
625 }
626 CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
627 *cbSid = length;
628 return TRUE;
629 }
630 }
631
632 if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES)
633 {
634 SetLastError(ERROR_INVALID_PARAMETER);
635 return FALSE;
636 }
637
638 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
639 if (WellKnownRids[i].Type == WellKnownSidType) {
640 UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid);
641 DWORD domain_sid_length = GetSidLengthRequired(domain_subauth);
642 DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1);
643
644 if (*cbSid < output_sid_length)
645 {
646 *cbSid = output_sid_length;
647 SetLastError(ERROR_INSUFFICIENT_BUFFER);
648 return FALSE;
649 }
650 if (!pSid)
651 {
652 SetLastError(ERROR_INVALID_PARAMETER);
653 return FALSE;
654 }
655 CopyMemory(pSid, DomainSid, domain_sid_length);
656 (*GetSidSubAuthorityCount(pSid))++;
657 (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid;
658 *cbSid = output_sid_length;
659 return TRUE;
660 }
661
662 SetLastError(ERROR_INVALID_PARAMETER);
663 return FALSE;
664 }
665
666 /*
667 * @unimplemented
668 */
669 BOOL
670 WINAPI
671 IsWellKnownSid(IN PSID pSid,
672 IN WELL_KNOWN_SID_TYPE WellKnownSidType)
673 {
674 unsigned int i;
675 TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
676
677 for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
678 {
679 if (WellKnownSids[i].Type == WellKnownSidType)
680 {
681 if (EqualSid(pSid, (PSID)(&WellKnownSids[i].Sid.Revision)))
682 return TRUE;
683 }
684 }
685
686 return FALSE;
687 }
688
689 /*
690 * @implemented
691 */
692 BOOL
693 WINAPI
694 IsValidSid(PSID pSid)
695 {
696 return (BOOL)RtlValidSid(pSid);
697 }
698
699 /*
700 * @implemented
701 */
702 BOOL
703 WINAPI
704 EqualSid(PSID pSid1,
705 PSID pSid2)
706 {
707 SetLastError(ERROR_SUCCESS);
708 return RtlEqualSid (pSid1, pSid2);
709 }
710
711 /*
712 * @implemented
713 */
714 BOOL
715 WINAPI
716 EqualPrefixSid(PSID pSid1,
717 PSID pSid2)
718 {
719 return RtlEqualPrefixSid (pSid1, pSid2);
720 }
721
722 /*
723 * @implemented
724 */
725 DWORD
726 WINAPI
727 GetSidLengthRequired(UCHAR nSubAuthorityCount)
728 {
729 return (DWORD)RtlLengthRequiredSid(nSubAuthorityCount);
730 }
731
732 /*
733 * @implemented
734 */
735 BOOL
736 WINAPI
737 InitializeSid(PSID Sid,
738 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
739 BYTE nSubAuthorityCount)
740 {
741 NTSTATUS Status;
742
743 Status = RtlInitializeSid(Sid,
744 pIdentifierAuthority,
745 nSubAuthorityCount);
746 if (!NT_SUCCESS(Status))
747 {
748 SetLastError(RtlNtStatusToDosError(Status));
749 return FALSE;
750 }
751
752 return TRUE;
753 }
754
755 /*
756 * @implemented
757 */
758 PSID_IDENTIFIER_AUTHORITY
759 WINAPI
760 GetSidIdentifierAuthority(PSID pSid)
761 {
762 SetLastError(ERROR_SUCCESS);
763 return RtlIdentifierAuthoritySid(pSid);
764 }
765
766 /*
767 * @implemented
768 */
769 PDWORD
770 WINAPI
771 GetSidSubAuthority(PSID pSid,
772 DWORD nSubAuthority)
773 {
774 SetLastError(ERROR_SUCCESS);
775 return (PDWORD)RtlSubAuthoritySid(pSid, nSubAuthority);
776 }
777
778 /*
779 * @implemented
780 */
781 PUCHAR
782 WINAPI
783 GetSidSubAuthorityCount(PSID pSid)
784 {
785 SetLastError(ERROR_SUCCESS);
786 return RtlSubAuthorityCountSid(pSid);
787 }
788
789 /*
790 * @implemented
791 */
792 DWORD
793 WINAPI
794 GetLengthSid(PSID pSid)
795 {
796 return (DWORD)RtlLengthSid(pSid);
797 }
798
799 /*
800 * @implemented
801 */
802 BOOL
803 WINAPI
804 InitializeSecurityDescriptor(PSECURITY_DESCRIPTOR pSecurityDescriptor,
805 DWORD dwRevision)
806 {
807 NTSTATUS Status;
808
809 Status = RtlCreateSecurityDescriptor(pSecurityDescriptor,
810 dwRevision);
811 if (!NT_SUCCESS(Status))
812 {
813 SetLastError(RtlNtStatusToDosError(Status));
814 return FALSE;
815 }
816
817 return TRUE;
818 }
819
820 /*
821 * @implemented
822 */
823 BOOL
824 WINAPI
825 MakeAbsoluteSD(PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
826 PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
827 LPDWORD lpdwAbsoluteSecurityDescriptorSize,
828 PACL pDacl,
829 LPDWORD lpdwDaclSize,
830 PACL pSacl,
831 LPDWORD lpdwSaclSize,
832 PSID pOwner,
833 LPDWORD lpdwOwnerSize,
834 PSID pPrimaryGroup,
835 LPDWORD lpdwPrimaryGroupSize)
836 {
837 NTSTATUS Status;
838
839 Status = RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
840 pAbsoluteSecurityDescriptor,
841 lpdwAbsoluteSecurityDescriptorSize,
842 pDacl,
843 lpdwDaclSize,
844 pSacl,
845 lpdwSaclSize,
846 pOwner,
847 lpdwOwnerSize,
848 pPrimaryGroup,
849 lpdwPrimaryGroupSize);
850 if (!NT_SUCCESS(Status))
851 {
852 SetLastError(RtlNtStatusToDosError(Status));
853 return FALSE;
854 }
855
856 return TRUE;
857 }
858
859 /******************************************************************************
860 * GetKernelObjectSecurity [ADVAPI32.@]
861 */
862 BOOL WINAPI GetKernelObjectSecurity(
863 HANDLE Handle,
864 SECURITY_INFORMATION RequestedInformation,
865 PSECURITY_DESCRIPTOR pSecurityDescriptor,
866 DWORD nLength,
867 LPDWORD lpnLengthNeeded )
868 {
869 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation,
870 pSecurityDescriptor, nLength, lpnLengthNeeded);
871
872 return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
873 nLength, lpnLengthNeeded ));
874 }
875
876 /*
877 * @implemented
878 */
879 BOOL
880 WINAPI
881 InitializeAcl(PACL pAcl,
882 DWORD nAclLength,
883 DWORD dwAclRevision)
884 {
885 NTSTATUS Status;
886
887 Status = RtlCreateAcl(pAcl,
888 nAclLength,
889 dwAclRevision);
890 if (!NT_SUCCESS(Status))
891 {
892 SetLastError(RtlNtStatusToDosError(Status));
893 return FALSE;
894 }
895
896 return TRUE;
897 }
898
899 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
900 {
901 IO_STATUS_BLOCK io_block;
902
903 TRACE("(%p)\n", hNamedPipe);
904
905 return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
906 &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
907 }
908
909 /*
910 * @implemented
911 */
912 BOOL
913 WINAPI
914 AddAccessAllowedAce(PACL pAcl,
915 DWORD dwAceRevision,
916 DWORD AccessMask,
917 PSID pSid)
918 {
919 NTSTATUS Status;
920
921 Status = RtlAddAccessAllowedAce(pAcl,
922 dwAceRevision,
923 AccessMask,
924 pSid);
925 if (!NT_SUCCESS(Status))
926 {
927 SetLastError(RtlNtStatusToDosError(Status));
928 return FALSE;
929 }
930
931 return TRUE;
932 }
933
934 /*
935 * @implemented
936 */
937 BOOL WINAPI
938 AddAccessAllowedAceEx(PACL pAcl,
939 DWORD dwAceRevision,
940 DWORD AceFlags,
941 DWORD AccessMask,
942 PSID pSid)
943 {
944 NTSTATUS Status;
945
946 Status = RtlAddAccessAllowedAceEx(pAcl,
947 dwAceRevision,
948 AceFlags,
949 AccessMask,
950 pSid);
951 if (!NT_SUCCESS(Status))
952 {
953 SetLastError(RtlNtStatusToDosError(Status));
954 return FALSE;
955 }
956
957 return TRUE;
958 }
959
960 /*
961 * @implemented
962 */
963 BOOL
964 WINAPI
965 AddAccessDeniedAce(PACL pAcl,
966 DWORD dwAceRevision,
967 DWORD AccessMask,
968 PSID pSid)
969 {
970 NTSTATUS Status;
971
972 Status = RtlAddAccessDeniedAce(pAcl,
973 dwAceRevision,
974 AccessMask,
975 pSid);
976 if (!NT_SUCCESS(Status))
977 {
978 SetLastError(RtlNtStatusToDosError(Status));
979 return FALSE;
980 }
981
982 return TRUE;
983 }
984
985 /*
986 * @implemented
987 */
988 BOOL WINAPI
989 AddAccessDeniedAceEx(PACL pAcl,
990 DWORD dwAceRevision,
991 DWORD AceFlags,
992 DWORD AccessMask,
993 PSID pSid)
994 {
995 NTSTATUS Status;
996
997 Status = RtlAddAccessDeniedAceEx(pAcl,
998 dwAceRevision,
999 AceFlags,
1000 AccessMask,
1001 pSid);
1002 if (!NT_SUCCESS(Status))
1003 {
1004 SetLastError(RtlNtStatusToDosError(Status));
1005 return FALSE;
1006 }
1007
1008 return TRUE;
1009 }
1010
1011 /*
1012 * @implemented
1013 */
1014 BOOL
1015 WINAPI
1016 AddAce(PACL pAcl,
1017 DWORD dwAceRevision,
1018 DWORD dwStartingAceIndex,
1019 LPVOID pAceList,
1020 DWORD nAceListLength)
1021 {
1022 NTSTATUS Status;
1023
1024 Status = RtlAddAce(pAcl,
1025 dwAceRevision,
1026 dwStartingAceIndex,
1027 pAceList,
1028 nAceListLength);
1029 if (!NT_SUCCESS(Status))
1030 {
1031 SetLastError(RtlNtStatusToDosError(Status));
1032 return FALSE;
1033 }
1034
1035 return TRUE;
1036 }
1037
1038 /******************************************************************************
1039 * DeleteAce [ADVAPI32.@]
1040 */
1041 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1042 {
1043 return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1044 }
1045
1046 /*
1047 * @implemented
1048 */
1049 BOOL
1050 WINAPI
1051 FindFirstFreeAce(PACL pAcl,
1052 LPVOID *pAce)
1053 {
1054 return RtlFirstFreeAce(pAcl,
1055 (PACE*)pAce);
1056 }
1057
1058 /******************************************************************************
1059 * GetAce [ADVAPI32.@]
1060 */
1061 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1062 {
1063 return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1064 }
1065
1066 /******************************************************************************
1067 * GetAclInformation [ADVAPI32.@]
1068 */
1069 BOOL WINAPI GetAclInformation(
1070 PACL pAcl,
1071 LPVOID pAclInformation,
1072 DWORD nAclInformationLength,
1073 ACL_INFORMATION_CLASS dwAclInformationClass)
1074 {
1075 return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1076 nAclInformationLength, dwAclInformationClass));
1077 }
1078
1079 /*
1080 * @implemented
1081 */
1082 BOOL
1083 WINAPI
1084 IsValidAcl(PACL pAcl)
1085 {
1086 return RtlValidAcl (pAcl);
1087 }
1088
1089 /*
1090 * @implemented
1091 */
1092 BOOL WINAPI
1093 AllocateLocallyUniqueId(PLUID Luid)
1094 {
1095 NTSTATUS Status;
1096
1097 Status = NtAllocateLocallyUniqueId (Luid);
1098 if (!NT_SUCCESS (Status))
1099 {
1100 SetLastError(RtlNtStatusToDosError(Status));
1101 return FALSE;
1102 }
1103
1104 return TRUE;
1105 }
1106
1107 /**********************************************************************
1108 * LookupPrivilegeDisplayNameA EXPORTED
1109 *
1110 * @unimplemented
1111 */
1112 BOOL
1113 WINAPI
1114 LookupPrivilegeDisplayNameA(LPCSTR lpSystemName,
1115 LPCSTR lpName,
1116 LPSTR lpDisplayName,
1117 LPDWORD cchDisplayName,
1118 LPDWORD lpLanguageId)
1119 {
1120 UNICODE_STRING lpSystemNameW;
1121 UNICODE_STRING lpNameW;
1122 BOOL ret;
1123 DWORD wLen = 0;
1124
1125 TRACE("%s %s %p %p %p\n", debugstr_a(lpSystemName), debugstr_a(lpName), lpName, cchDisplayName, lpLanguageId);
1126
1127 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1128 RtlCreateUnicodeStringFromAsciiz(&lpNameW, lpName);
1129 ret = LookupPrivilegeDisplayNameW(lpSystemNameW.Buffer, lpNameW.Buffer, NULL, &wLen, lpLanguageId);
1130 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1131 {
1132 LPWSTR lpDisplayNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1133
1134 ret = LookupPrivilegeDisplayNameW(lpSystemNameW.Buffer, lpNameW.Buffer, lpDisplayNameW,
1135 &wLen, lpLanguageId);
1136 if (ret)
1137 {
1138 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpDisplayNameW, -1, lpDisplayName,
1139 *cchDisplayName, NULL, NULL);
1140
1141 if (len == 0)
1142 {
1143 /* WideCharToMultiByte failed */
1144 ret = FALSE;
1145 }
1146 else if (len > *cchDisplayName)
1147 {
1148 *cchDisplayName = len;
1149 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1150 ret = FALSE;
1151 }
1152 else
1153 {
1154 /* WideCharToMultiByte succeeded, output length needs to be
1155 * length not including NULL terminator
1156 */
1157 *cchDisplayName = len - 1;
1158 }
1159 }
1160 HeapFree(GetProcessHeap(), 0, lpDisplayNameW);
1161 }
1162 RtlFreeUnicodeString(&lpSystemNameW);
1163 RtlFreeUnicodeString(&lpNameW);
1164 return ret;
1165 }
1166
1167 /**********************************************************************
1168 * LookupPrivilegeNameA EXPORTED
1169 *
1170 * @implemented
1171 */
1172 BOOL
1173 WINAPI
1174 LookupPrivilegeNameA(LPCSTR lpSystemName,
1175 PLUID lpLuid,
1176 LPSTR lpName,
1177 LPDWORD cchName)
1178 {
1179 UNICODE_STRING lpSystemNameW;
1180 BOOL ret;
1181 DWORD wLen = 0;
1182
1183 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1184
1185 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1186 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1187 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1188 {
1189 LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1190
1191 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1192 &wLen);
1193 if (ret)
1194 {
1195 /* Windows crashes if cchName is NULL, so will I */
1196 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1197 *cchName, NULL, NULL);
1198
1199 if (len == 0)
1200 {
1201 /* WideCharToMultiByte failed */
1202 ret = FALSE;
1203 }
1204 else if (len > *cchName)
1205 {
1206 *cchName = len;
1207 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1208 ret = FALSE;
1209 }
1210 else
1211 {
1212 /* WideCharToMultiByte succeeded, output length needs to be
1213 * length not including NULL terminator
1214 */
1215 *cchName = len - 1;
1216 }
1217 }
1218 HeapFree(GetProcessHeap(), 0, lpNameW);
1219 }
1220 RtlFreeUnicodeString(&lpSystemNameW);
1221 return ret;
1222 }
1223
1224 /******************************************************************************
1225 * GetFileSecurityA [ADVAPI32.@]
1226 *
1227 * Obtains Specified information about the security of a file or directory.
1228 *
1229 * PARAMS
1230 * lpFileName [I] Name of the file to get info for
1231 * RequestedInformation [I] SE_ flags from "winnt.h"
1232 * pSecurityDescriptor [O] Destination for security information
1233 * nLength [I] Length of pSecurityDescriptor
1234 * lpnLengthNeeded [O] Destination for length of returned security information
1235 *
1236 * RETURNS
1237 * Success: TRUE. pSecurityDescriptor contains the requested information.
1238 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
1239 *
1240 * NOTES
1241 * The information returned is constrained by the callers access rights and
1242 * privileges.
1243 *
1244 * @implemented
1245 */
1246 BOOL
1247 WINAPI
1248 GetFileSecurityA(LPCSTR lpFileName,
1249 SECURITY_INFORMATION RequestedInformation,
1250 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1251 DWORD nLength,
1252 LPDWORD lpnLengthNeeded)
1253 {
1254 UNICODE_STRING FileName;
1255 BOOL bResult;
1256
1257 if (!RtlCreateUnicodeStringFromAsciiz(&FileName, lpFileName))
1258 {
1259 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1260 return FALSE;
1261 }
1262
1263 bResult = GetFileSecurityW(FileName.Buffer,
1264 RequestedInformation,
1265 pSecurityDescriptor,
1266 nLength,
1267 lpnLengthNeeded);
1268
1269 RtlFreeUnicodeString(&FileName);
1270
1271 return bResult;
1272 }
1273
1274 /*
1275 * @implemented
1276 */
1277 BOOL
1278 WINAPI
1279 GetFileSecurityW(LPCWSTR lpFileName,
1280 SECURITY_INFORMATION RequestedInformation,
1281 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1282 DWORD nLength,
1283 LPDWORD lpnLengthNeeded)
1284 {
1285 OBJECT_ATTRIBUTES ObjectAttributes;
1286 IO_STATUS_BLOCK StatusBlock;
1287 UNICODE_STRING FileName;
1288 ULONG AccessMask = 0;
1289 HANDLE FileHandle;
1290 NTSTATUS Status;
1291
1292 TRACE("GetFileSecurityW() called\n");
1293
1294 QuerySecurityAccessMask(RequestedInformation, &AccessMask);
1295
1296 if (!RtlDosPathNameToNtPathName_U(lpFileName,
1297 &FileName,
1298 NULL,
1299 NULL))
1300 {
1301 ERR("Invalid path\n");
1302 SetLastError(ERROR_INVALID_NAME);
1303 return FALSE;
1304 }
1305
1306 InitializeObjectAttributes(&ObjectAttributes,
1307 &FileName,
1308 OBJ_CASE_INSENSITIVE,
1309 NULL,
1310 NULL);
1311
1312 Status = NtOpenFile(&FileHandle,
1313 AccessMask,
1314 &ObjectAttributes,
1315 &StatusBlock,
1316 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
1317 0);
1318
1319 RtlFreeHeap(RtlGetProcessHeap(),
1320 0,
1321 FileName.Buffer);
1322
1323 if (!NT_SUCCESS(Status))
1324 {
1325 ERR("NtOpenFile() failed (Status %lx)\n", Status);
1326 SetLastError(RtlNtStatusToDosError(Status));
1327 return FALSE;
1328 }
1329
1330 Status = NtQuerySecurityObject(FileHandle,
1331 RequestedInformation,
1332 pSecurityDescriptor,
1333 nLength,
1334 lpnLengthNeeded);
1335 NtClose(FileHandle);
1336 if (!NT_SUCCESS(Status))
1337 {
1338 ERR("NtQuerySecurityObject() failed (Status %lx)\n", Status);
1339 SetLastError(RtlNtStatusToDosError(Status));
1340 return FALSE;
1341 }
1342
1343 return TRUE;
1344 }
1345
1346 /******************************************************************************
1347 * SetFileSecurityA [ADVAPI32.@]
1348 * Sets the security of a file or directory
1349 *
1350 * @implemented
1351 */
1352 BOOL
1353 WINAPI
1354 SetFileSecurityA(LPCSTR lpFileName,
1355 SECURITY_INFORMATION SecurityInformation,
1356 PSECURITY_DESCRIPTOR pSecurityDescriptor)
1357 {
1358 UNICODE_STRING FileName;
1359 BOOL bResult;
1360
1361 if (!RtlCreateUnicodeStringFromAsciiz(&FileName, lpFileName))
1362 {
1363 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1364 return FALSE;
1365 }
1366
1367 bResult = SetFileSecurityW(FileName.Buffer,
1368 SecurityInformation,
1369 pSecurityDescriptor);
1370
1371 RtlFreeUnicodeString(&FileName);
1372
1373 return bResult;
1374 }
1375
1376 /******************************************************************************
1377 * SetFileSecurityW [ADVAPI32.@]
1378 * Sets the security of a file or directory
1379 *
1380 * @implemented
1381 */
1382 BOOL
1383 WINAPI
1384 SetFileSecurityW(LPCWSTR lpFileName,
1385 SECURITY_INFORMATION SecurityInformation,
1386 PSECURITY_DESCRIPTOR pSecurityDescriptor)
1387 {
1388 OBJECT_ATTRIBUTES ObjectAttributes;
1389 IO_STATUS_BLOCK StatusBlock;
1390 UNICODE_STRING FileName;
1391 ULONG AccessMask = 0;
1392 HANDLE FileHandle;
1393 NTSTATUS Status;
1394
1395 TRACE("SetFileSecurityW() called\n");
1396
1397 SetSecurityAccessMask(SecurityInformation, &AccessMask);
1398
1399 if (!RtlDosPathNameToNtPathName_U(lpFileName,
1400 &FileName,
1401 NULL,
1402 NULL))
1403 {
1404 ERR("Invalid path\n");
1405 SetLastError(ERROR_INVALID_NAME);
1406 return FALSE;
1407 }
1408
1409 InitializeObjectAttributes(&ObjectAttributes,
1410 &FileName,
1411 OBJ_CASE_INSENSITIVE,
1412 NULL,
1413 NULL);
1414
1415 Status = NtOpenFile(&FileHandle,
1416 AccessMask,
1417 &ObjectAttributes,
1418 &StatusBlock,
1419 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
1420 0);
1421
1422 RtlFreeHeap(RtlGetProcessHeap(),
1423 0,
1424 FileName.Buffer);
1425
1426 if (!NT_SUCCESS(Status))
1427 {
1428 ERR("NtOpenFile() failed (Status %lx)\n", Status);
1429 SetLastError(RtlNtStatusToDosError(Status));
1430 return FALSE;
1431 }
1432
1433 Status = NtSetSecurityObject(FileHandle,
1434 SecurityInformation,
1435 pSecurityDescriptor);
1436 NtClose(FileHandle);
1437
1438 if (!NT_SUCCESS(Status))
1439 {
1440 ERR("NtSetSecurityObject() failed (Status %lx)\n", Status);
1441 SetLastError(RtlNtStatusToDosError(Status));
1442 return FALSE;
1443 }
1444
1445 return TRUE;
1446 }
1447
1448 /******************************************************************************
1449 * QueryWindows31FilesMigration [ADVAPI32.@]
1450 *
1451 * PARAMS
1452 * x1 []
1453 */
1454 BOOL WINAPI
1455 QueryWindows31FilesMigration( DWORD x1 )
1456 {
1457 FIXME("(%d):stub\n",x1);
1458 return TRUE;
1459 }
1460
1461 /******************************************************************************
1462 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
1463 *
1464 * PARAMS
1465 * x1 []
1466 * x2 []
1467 * x3 []
1468 * x4 []
1469 */
1470 BOOL WINAPI
1471 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
1472 DWORD x4 )
1473 {
1474 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
1475 return TRUE;
1476 }
1477
1478 /*
1479 * @implemented
1480 */
1481 BOOL
1482 WINAPI
1483 RevertToSelf(VOID)
1484 {
1485 NTSTATUS Status;
1486 HANDLE Token = NULL;
1487
1488 Status = NtSetInformationThread(NtCurrentThread(),
1489 ThreadImpersonationToken,
1490 &Token,
1491 sizeof(HANDLE));
1492 if (!NT_SUCCESS(Status))
1493 {
1494 SetLastError(RtlNtStatusToDosError(Status));
1495 return FALSE;
1496 }
1497
1498 return TRUE;
1499 }
1500
1501 /*
1502 * @implemented
1503 */
1504 BOOL
1505 WINAPI
1506 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
1507 {
1508 NTSTATUS Status;
1509
1510 Status = RtlImpersonateSelf(ImpersonationLevel);
1511 if (!NT_SUCCESS(Status))
1512 {
1513 SetLastError(RtlNtStatusToDosError(Status));
1514 return FALSE;
1515 }
1516
1517 return TRUE;
1518 }
1519
1520 /*
1521 * @implemented
1522 */
1523 BOOL
1524 WINAPI
1525 AccessCheck(IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1526 IN HANDLE ClientToken,
1527 IN DWORD DesiredAccess,
1528 IN PGENERIC_MAPPING GenericMapping,
1529 OUT PPRIVILEGE_SET PrivilegeSet OPTIONAL,
1530 IN OUT LPDWORD PrivilegeSetLength,
1531 OUT LPDWORD GrantedAccess,
1532 OUT LPBOOL AccessStatus)
1533 {
1534 NTSTATUS Status;
1535 NTSTATUS NtAccessStatus;
1536
1537 /* Do the access check */
1538 Status = NtAccessCheck(pSecurityDescriptor,
1539 ClientToken,
1540 DesiredAccess,
1541 GenericMapping,
1542 PrivilegeSet,
1543 (PULONG)PrivilegeSetLength,
1544 (PACCESS_MASK)GrantedAccess,
1545 &NtAccessStatus);
1546
1547 /* See if the access check operation succeeded */
1548 if (!NT_SUCCESS(Status))
1549 {
1550 /* Check failed */
1551 SetLastError(RtlNtStatusToDosError(Status));
1552 return FALSE;
1553 }
1554
1555 /* Now check the access status */
1556 if (!NT_SUCCESS(NtAccessStatus))
1557 {
1558 /* Access denied */
1559 SetLastError(RtlNtStatusToDosError(NtAccessStatus));
1560 *AccessStatus = FALSE;
1561 }
1562 else
1563 {
1564 /* Access granted */
1565 *AccessStatus = TRUE;
1566 }
1567
1568 /* Check succeeded */
1569 return TRUE;
1570 }
1571
1572 /*
1573 * @unimplemented
1574 */
1575 BOOL WINAPI AccessCheckByType(
1576 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1577 PSID PrincipalSelfSid,
1578 HANDLE ClientToken,
1579 DWORD DesiredAccess,
1580 POBJECT_TYPE_LIST ObjectTypeList,
1581 DWORD ObjectTypeListLength,
1582 PGENERIC_MAPPING GenericMapping,
1583 PPRIVILEGE_SET PrivilegeSet,
1584 LPDWORD PrivilegeSetLength,
1585 LPDWORD GrantedAccess,
1586 LPBOOL AccessStatus)
1587 {
1588 FIXME("stub\n");
1589
1590 *AccessStatus = TRUE;
1591
1592 return !*AccessStatus;
1593 }
1594
1595 /*
1596 * @implemented
1597 */
1598 BOOL
1599 WINAPI
1600 SetKernelObjectSecurity(HANDLE Handle,
1601 SECURITY_INFORMATION SecurityInformation,
1602 PSECURITY_DESCRIPTOR SecurityDescriptor)
1603 {
1604 NTSTATUS Status;
1605
1606 Status = NtSetSecurityObject(Handle,
1607 SecurityInformation,
1608 SecurityDescriptor);
1609 if (!NT_SUCCESS(Status))
1610 {
1611 SetLastError(RtlNtStatusToDosError(Status));
1612 return FALSE;
1613 }
1614
1615 return TRUE;
1616 }
1617
1618 /*
1619 * @implemented
1620 */
1621 BOOL
1622 WINAPI
1623 AddAuditAccessAce(PACL pAcl,
1624 DWORD dwAceRevision,
1625 DWORD dwAccessMask,
1626 PSID pSid,
1627 BOOL bAuditSuccess,
1628 BOOL bAuditFailure)
1629 {
1630 NTSTATUS Status;
1631
1632 Status = RtlAddAuditAccessAce(pAcl,
1633 dwAceRevision,
1634 dwAccessMask,
1635 pSid,
1636 bAuditSuccess,
1637 bAuditFailure);
1638 if (!NT_SUCCESS(Status))
1639 {
1640 SetLastError(RtlNtStatusToDosError(Status));
1641 return FALSE;
1642 }
1643
1644 return TRUE;
1645 }
1646
1647 /*
1648 * @implemented
1649 */
1650 BOOL WINAPI
1651 AddAuditAccessAceEx(PACL pAcl,
1652 DWORD dwAceRevision,
1653 DWORD AceFlags,
1654 DWORD dwAccessMask,
1655 PSID pSid,
1656 BOOL bAuditSuccess,
1657 BOOL bAuditFailure)
1658 {
1659 NTSTATUS Status;
1660
1661 Status = RtlAddAuditAccessAceEx(pAcl,
1662 dwAceRevision,
1663 AceFlags,
1664 dwAccessMask,
1665 pSid,
1666 bAuditSuccess,
1667 bAuditFailure);
1668 if (!NT_SUCCESS(Status))
1669 {
1670 SetLastError(RtlNtStatusToDosError(Status));
1671 return FALSE;
1672 }
1673
1674 return TRUE;
1675 }
1676
1677 /******************************************************************************
1678 * LookupAccountNameA [ADVAPI32.@]
1679 *
1680 * @implemented
1681 */
1682 BOOL
1683 WINAPI
1684 LookupAccountNameA(LPCSTR SystemName,
1685 LPCSTR AccountName,
1686 PSID Sid,
1687 LPDWORD SidLength,
1688 LPSTR ReferencedDomainName,
1689 LPDWORD hReferencedDomainNameLength,
1690 PSID_NAME_USE SidNameUse)
1691 {
1692 BOOL ret;
1693 UNICODE_STRING lpSystemW;
1694 UNICODE_STRING lpAccountW;
1695 LPWSTR lpReferencedDomainNameW = NULL;
1696
1697 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, SystemName);
1698 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, AccountName);
1699
1700 if (ReferencedDomainName)
1701 lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(),
1702 0,
1703 *hReferencedDomainNameLength * sizeof(WCHAR));
1704
1705 ret = LookupAccountNameW(lpSystemW.Buffer,
1706 lpAccountW.Buffer,
1707 Sid,
1708 SidLength,
1709 lpReferencedDomainNameW,
1710 hReferencedDomainNameLength,
1711 SidNameUse);
1712
1713 if (ret && lpReferencedDomainNameW)
1714 {
1715 WideCharToMultiByte(CP_ACP,
1716 0,
1717 lpReferencedDomainNameW,
1718 *hReferencedDomainNameLength + 1,
1719 ReferencedDomainName,
1720 *hReferencedDomainNameLength + 1,
1721 NULL,
1722 NULL);
1723 }
1724
1725 RtlFreeUnicodeString(&lpSystemW);
1726 RtlFreeUnicodeString(&lpAccountW);
1727 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
1728
1729 return ret;
1730 }
1731
1732 /**********************************************************************
1733 * PrivilegeCheck EXPORTED
1734 *
1735 * @implemented
1736 */
1737 BOOL WINAPI
1738 PrivilegeCheck(HANDLE ClientToken,
1739 PPRIVILEGE_SET RequiredPrivileges,
1740 LPBOOL pfResult)
1741 {
1742 BOOLEAN Result;
1743 NTSTATUS Status;
1744
1745 Status = NtPrivilegeCheck(ClientToken,
1746 RequiredPrivileges,
1747 &Result);
1748 if (!NT_SUCCESS(Status))
1749 {
1750 SetLastError(RtlNtStatusToDosError(Status));
1751 return FALSE;
1752 }
1753
1754 *pfResult = (BOOL)Result;
1755
1756 return TRUE;
1757 }
1758
1759 /******************************************************************************
1760 * GetSecurityInfoExW EXPORTED
1761 */
1762 DWORD
1763 WINAPI
1764 GetSecurityInfoExA(HANDLE hObject,
1765 SE_OBJECT_TYPE ObjectType,
1766 SECURITY_INFORMATION SecurityInfo,
1767 LPCSTR lpProvider,
1768 LPCSTR lpProperty,
1769 PACTRL_ACCESSA *ppAccessList,
1770 PACTRL_AUDITA *ppAuditList,
1771 LPSTR *lppOwner,
1772 LPSTR *lppGroup)
1773 {
1774 FIXME("%s() not implemented!\n", __FUNCTION__);
1775 return ERROR_BAD_PROVIDER;
1776 }
1777
1778
1779 /******************************************************************************
1780 * GetSecurityInfoExW EXPORTED
1781 */
1782 DWORD
1783 WINAPI
1784 GetSecurityInfoExW(HANDLE hObject,
1785 SE_OBJECT_TYPE ObjectType,
1786 SECURITY_INFORMATION SecurityInfo,
1787 LPCWSTR lpProvider,
1788 LPCWSTR lpProperty,
1789 PACTRL_ACCESSW *ppAccessList,
1790 PACTRL_AUDITW *ppAuditList,
1791 LPWSTR *lppOwner,
1792 LPWSTR *lppGroup)
1793 {
1794 FIXME("%s() not implemented!\n", __FUNCTION__);
1795 return ERROR_BAD_PROVIDER;
1796 }
1797
1798 /******************************************************************************
1799 * BuildExplicitAccessWithNameA [ADVAPI32.@]
1800 */
1801 VOID WINAPI
1802 BuildExplicitAccessWithNameA(PEXPLICIT_ACCESSA pExplicitAccess,
1803 LPSTR pTrusteeName,
1804 DWORD AccessPermissions,
1805 ACCESS_MODE AccessMode,
1806 DWORD Inheritance)
1807 {
1808 pExplicitAccess->grfAccessPermissions = AccessPermissions;
1809 pExplicitAccess->grfAccessMode = AccessMode;
1810 pExplicitAccess->grfInheritance = Inheritance;
1811
1812 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
1813 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
1814 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
1815 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
1816 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
1817 }
1818
1819
1820 /******************************************************************************
1821 * BuildExplicitAccessWithNameW [ADVAPI32.@]
1822 */
1823 VOID WINAPI
1824 BuildExplicitAccessWithNameW(PEXPLICIT_ACCESSW pExplicitAccess,
1825 LPWSTR pTrusteeName,
1826 DWORD AccessPermissions,
1827 ACCESS_MODE AccessMode,
1828 DWORD Inheritance)
1829 {
1830 pExplicitAccess->grfAccessPermissions = AccessPermissions;
1831 pExplicitAccess->grfAccessMode = AccessMode;
1832 pExplicitAccess->grfInheritance = Inheritance;
1833
1834 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
1835 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
1836 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
1837 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
1838 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
1839 }
1840
1841 /******************************************************************************
1842 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
1843 */
1844 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
1845 SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
1846 LPSTR InheritedObjectTypeName, LPSTR Name )
1847 {
1848 DWORD ObjectsPresent = 0;
1849
1850 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
1851 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
1852
1853 /* Fill the OBJECTS_AND_NAME structure */
1854 pObjName->ObjectType = ObjectType;
1855 if (ObjectTypeName != NULL)
1856 {
1857 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
1858 }
1859
1860 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
1861 if (InheritedObjectTypeName != NULL)
1862 {
1863 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
1864 }
1865
1866 pObjName->ObjectsPresent = ObjectsPresent;
1867 pObjName->ptstrName = Name;
1868
1869 /* Fill the TRUSTEE structure */
1870 pTrustee->pMultipleTrustee = NULL;
1871 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
1872 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
1873 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
1874 pTrustee->ptstrName = (LPSTR)pObjName;
1875 }
1876
1877 /******************************************************************************
1878 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
1879 */
1880 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
1881 SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
1882 LPWSTR InheritedObjectTypeName, LPWSTR Name )
1883 {
1884 DWORD ObjectsPresent = 0;
1885
1886 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
1887 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
1888
1889 /* Fill the OBJECTS_AND_NAME structure */
1890 pObjName->ObjectType = ObjectType;
1891 if (ObjectTypeName != NULL)
1892 {
1893 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
1894 }
1895
1896 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
1897 if (InheritedObjectTypeName != NULL)
1898 {
1899 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
1900 }
1901
1902 pObjName->ObjectsPresent = ObjectsPresent;
1903 pObjName->ptstrName = Name;
1904
1905 /* Fill the TRUSTEE structure */
1906 pTrustee->pMultipleTrustee = NULL;
1907 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
1908 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
1909 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
1910 pTrustee->ptstrName = (LPWSTR)pObjName;
1911 }
1912
1913 /******************************************************************************
1914 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
1915 */
1916 VOID WINAPI
1917 BuildTrusteeWithObjectsAndSidA(PTRUSTEEA pTrustee,
1918 POBJECTS_AND_SID pObjSid,
1919 GUID *pObjectGuid,
1920 GUID *pInheritedObjectGuid,
1921 PSID pSid)
1922 {
1923 DWORD ObjectsPresent = 0;
1924
1925 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
1926
1927 /* Fill the OBJECTS_AND_SID structure */
1928 if (pObjectGuid != NULL)
1929 {
1930 pObjSid->ObjectTypeGuid = *pObjectGuid;
1931 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
1932 }
1933 else
1934 {
1935 ZeroMemory(&pObjSid->ObjectTypeGuid,
1936 sizeof(GUID));
1937 }
1938
1939 if (pInheritedObjectGuid != NULL)
1940 {
1941 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
1942 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
1943 }
1944 else
1945 {
1946 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
1947 sizeof(GUID));
1948 }
1949
1950 pObjSid->ObjectsPresent = ObjectsPresent;
1951 pObjSid->pSid = pSid;
1952
1953 /* Fill the TRUSTEE structure */
1954 pTrustee->pMultipleTrustee = NULL;
1955 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
1956 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
1957 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
1958 pTrustee->ptstrName = (LPSTR) pObjSid;
1959 }
1960
1961
1962 /******************************************************************************
1963 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
1964 */
1965 VOID WINAPI
1966 BuildTrusteeWithObjectsAndSidW(PTRUSTEEW pTrustee,
1967 POBJECTS_AND_SID pObjSid,
1968 GUID *pObjectGuid,
1969 GUID *pInheritedObjectGuid,
1970 PSID pSid)
1971 {
1972 DWORD ObjectsPresent = 0;
1973
1974 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
1975
1976 /* Fill the OBJECTS_AND_SID structure */
1977 if (pObjectGuid != NULL)
1978 {
1979 pObjSid->ObjectTypeGuid = *pObjectGuid;
1980 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
1981 }
1982 else
1983 {
1984 ZeroMemory(&pObjSid->ObjectTypeGuid,
1985 sizeof(GUID));
1986 }
1987
1988 if (pInheritedObjectGuid != NULL)
1989 {
1990 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
1991 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
1992 }
1993 else
1994 {
1995 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
1996 sizeof(GUID));
1997 }
1998
1999 pObjSid->ObjectsPresent = ObjectsPresent;
2000 pObjSid->pSid = pSid;
2001
2002 /* Fill the TRUSTEE structure */
2003 pTrustee->pMultipleTrustee = NULL;
2004 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2005 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
2006 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2007 pTrustee->ptstrName = (LPWSTR) pObjSid;
2008 }
2009
2010 /******************************************************************************
2011 * BuildTrusteeWithSidA [ADVAPI32.@]
2012 */
2013 VOID WINAPI
2014 BuildTrusteeWithSidA(PTRUSTEE_A pTrustee,
2015 PSID pSid)
2016 {
2017 TRACE("%p %p\n", pTrustee, pSid);
2018
2019 pTrustee->pMultipleTrustee = NULL;
2020 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2021 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
2022 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2023 pTrustee->ptstrName = (LPSTR) pSid;
2024 }
2025
2026
2027 /******************************************************************************
2028 * BuildTrusteeWithSidW [ADVAPI32.@]
2029 */
2030 VOID WINAPI
2031 BuildTrusteeWithSidW(PTRUSTEE_W pTrustee,
2032 PSID pSid)
2033 {
2034 TRACE("%p %p\n", pTrustee, pSid);
2035
2036 pTrustee->pMultipleTrustee = NULL;
2037 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2038 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
2039 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2040 pTrustee->ptstrName = (LPWSTR) pSid;
2041 }
2042
2043 /******************************************************************************
2044 * BuildTrusteeWithNameA [ADVAPI32.@]
2045 */
2046 VOID WINAPI
2047 BuildTrusteeWithNameA(PTRUSTEE_A pTrustee,
2048 LPSTR name)
2049 {
2050 TRACE("%p %s\n", pTrustee, name);
2051
2052 pTrustee->pMultipleTrustee = NULL;
2053 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2054 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
2055 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2056 pTrustee->ptstrName = name;
2057 }
2058
2059 /******************************************************************************
2060 * BuildTrusteeWithNameW [ADVAPI32.@]
2061 */
2062 VOID WINAPI
2063 BuildTrusteeWithNameW(PTRUSTEE_W pTrustee,
2064 LPWSTR name)
2065 {
2066 TRACE("%p %s\n", pTrustee, name);
2067
2068 pTrustee->pMultipleTrustee = NULL;
2069 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2070 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
2071 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2072 pTrustee->ptstrName = name;
2073 }
2074
2075 /******************************************************************************
2076 * GetTrusteeFormA [ADVAPI32.@]
2077 */
2078 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee)
2079 {
2080 TRACE("(%p)\n", pTrustee);
2081
2082 if (!pTrustee)
2083 return TRUSTEE_BAD_FORM;
2084
2085 return pTrustee->TrusteeForm;
2086 }
2087
2088 /******************************************************************************
2089 * GetTrusteeFormW [ADVAPI32.@]
2090 */
2091 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee)
2092 {
2093 TRACE("(%p)\n", pTrustee);
2094
2095 if (!pTrustee)
2096 return TRUSTEE_BAD_FORM;
2097
2098 return pTrustee->TrusteeForm;
2099 }
2100
2101 /******************************************************************************
2102 * GetTrusteeNameA [ADVAPI32.@]
2103 */
2104 LPSTR WINAPI
2105 GetTrusteeNameA(PTRUSTEE_A pTrustee)
2106 {
2107 return pTrustee->ptstrName;
2108 }
2109
2110
2111 /******************************************************************************
2112 * GetTrusteeNameW [ADVAPI32.@]
2113 */
2114 LPWSTR WINAPI
2115 GetTrusteeNameW(PTRUSTEE_W pTrustee)
2116 {
2117 return pTrustee->ptstrName;
2118 }
2119
2120 /******************************************************************************
2121 * GetTrusteeTypeA [ADVAPI32.@]
2122 */
2123 TRUSTEE_TYPE WINAPI
2124 GetTrusteeTypeA(PTRUSTEE_A pTrustee)
2125 {
2126 return pTrustee->TrusteeType;
2127 }
2128
2129 /******************************************************************************
2130 * GetTrusteeTypeW [ADVAPI32.@]
2131 */
2132 TRUSTEE_TYPE WINAPI
2133 GetTrusteeTypeW(PTRUSTEE_W pTrustee)
2134 {
2135 return pTrustee->TrusteeType;
2136 }
2137
2138 /*
2139 * @implemented
2140 */
2141 BOOL
2142 WINAPI
2143 SetAclInformation(PACL pAcl,
2144 LPVOID pAclInformation,
2145 DWORD nAclInformationLength,
2146 ACL_INFORMATION_CLASS dwAclInformationClass)
2147 {
2148 NTSTATUS Status;
2149
2150 Status = RtlSetInformationAcl(pAcl,
2151 pAclInformation,
2152 nAclInformationLength,
2153 dwAclInformationClass);
2154 if (!NT_SUCCESS(Status))
2155 {
2156 SetLastError(RtlNtStatusToDosError(Status));
2157 return FALSE;
2158 }
2159
2160 return TRUE;
2161 }
2162
2163 /**********************************************************************
2164 * SetNamedSecurityInfoA EXPORTED
2165 *
2166 * @implemented
2167 */
2168 DWORD
2169 WINAPI
2170 SetNamedSecurityInfoA(LPSTR pObjectName,
2171 SE_OBJECT_TYPE ObjectType,
2172 SECURITY_INFORMATION SecurityInfo,
2173 PSID psidOwner,
2174 PSID psidGroup,
2175 PACL pDacl,
2176 PACL pSacl)
2177 {
2178 UNICODE_STRING ObjectName;
2179 DWORD Ret;
2180
2181 if (!RtlCreateUnicodeStringFromAsciiz(&ObjectName, pObjectName))
2182 {
2183 return ERROR_NOT_ENOUGH_MEMORY;
2184 }
2185
2186 Ret = SetNamedSecurityInfoW(ObjectName.Buffer,
2187 ObjectType,
2188 SecurityInfo,
2189 psidOwner,
2190 psidGroup,
2191 pDacl,
2192 pSacl);
2193
2194 RtlFreeUnicodeString(&ObjectName);
2195
2196 return Ret;
2197 }
2198
2199 /*
2200 * @implemented
2201 */
2202 BOOL
2203 WINAPI
2204 AreAllAccessesGranted(DWORD GrantedAccess,
2205 DWORD DesiredAccess)
2206 {
2207 return (BOOL)RtlAreAllAccessesGranted(GrantedAccess,
2208 DesiredAccess);
2209 }
2210
2211 /*
2212 * @implemented
2213 */
2214 BOOL
2215 WINAPI
2216 AreAnyAccessesGranted(DWORD GrantedAccess,
2217 DWORD DesiredAccess)
2218 {
2219 return (BOOL)RtlAreAnyAccessesGranted(GrantedAccess,
2220 DesiredAccess);
2221 }
2222
2223 /******************************************************************************
2224 * ParseAclStringFlags
2225 */
2226 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
2227 {
2228 DWORD flags = 0;
2229 LPCWSTR szAcl = *StringAcl;
2230
2231 while (*szAcl && *szAcl != '(')
2232 {
2233 if (*szAcl == 'P')
2234 {
2235 flags |= SE_DACL_PROTECTED;
2236 }
2237 else if (*szAcl == 'A')
2238 {
2239 szAcl++;
2240 if (*szAcl == 'R')
2241 flags |= SE_DACL_AUTO_INHERIT_REQ;
2242 else if (*szAcl == 'I')
2243 flags |= SE_DACL_AUTO_INHERITED;
2244 }
2245 szAcl++;
2246 }
2247
2248 *StringAcl = szAcl;
2249 return flags;
2250 }
2251
2252 /******************************************************************************
2253 * ParseAceStringType
2254 */
2255 static const ACEFLAG AceType[] =
2256 {
2257 { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
2258 { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
2259 { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
2260 { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
2261 { SDDL_MANDATORY_LABEL,SYSTEM_MANDATORY_LABEL_ACE_TYPE },
2262 /*
2263 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
2264 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
2265 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
2266 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
2267 */
2268 { NULL, 0 },
2269 };
2270
2271 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
2272 {
2273 UINT len = 0;
2274 LPCWSTR szAcl = *StringAcl;
2275 const ACEFLAG *lpaf = AceType;
2276
2277 while (*szAcl == ' ')
2278 szAcl++;
2279
2280 while (lpaf->wstr &&
2281 (len = strlenW(lpaf->wstr)) &&
2282 strncmpW(lpaf->wstr, szAcl, len))
2283 lpaf++;
2284
2285 if (!lpaf->wstr)
2286 return 0;
2287
2288 *StringAcl = szAcl + len;
2289 return lpaf->value;
2290 }
2291
2292
2293 /******************************************************************************
2294 * ParseAceStringFlags
2295 */
2296 static const ACEFLAG AceFlags[] =
2297 {
2298 { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
2299 { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
2300 { SDDL_INHERITED, INHERITED_ACE },
2301 { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
2302 { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
2303 { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
2304 { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
2305 { NULL, 0 },
2306 };
2307
2308 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
2309 {
2310 UINT len = 0;
2311 BYTE flags = 0;
2312 LPCWSTR szAcl = *StringAcl;
2313
2314 while (*szAcl == ' ')
2315 szAcl++;
2316
2317 while (*szAcl != ';')
2318 {
2319 const ACEFLAG *lpaf = AceFlags;
2320
2321 while (lpaf->wstr &&
2322 (len = strlenW(lpaf->wstr)) &&
2323 strncmpW(lpaf->wstr, szAcl, len))
2324 lpaf++;
2325
2326 if (!lpaf->wstr)
2327 return 0;
2328
2329 flags |= lpaf->value;
2330 szAcl += len;
2331 }
2332
2333 *StringAcl = szAcl;
2334 return flags;
2335 }
2336
2337
2338 /******************************************************************************
2339 * ParseAceStringRights
2340 */
2341 static const ACEFLAG AceRights[] =
2342 {
2343 { SDDL_GENERIC_ALL, GENERIC_ALL },
2344 { SDDL_GENERIC_READ, GENERIC_READ },
2345 { SDDL_GENERIC_WRITE, GENERIC_WRITE },
2346 { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
2347
2348 { SDDL_READ_CONTROL, READ_CONTROL },
2349 { SDDL_STANDARD_DELETE, DELETE },
2350 { SDDL_WRITE_DAC, WRITE_DAC },
2351 { SDDL_WRITE_OWNER, WRITE_OWNER },
2352
2353 { SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP},
2354 { SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP},
2355 { SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD},
2356 { SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD},
2357 { SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST},
2358 { SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF},
2359 { SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT},
2360 { SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE},
2361 { SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS},
2362
2363 { SDDL_FILE_ALL, FILE_ALL_ACCESS },
2364 { SDDL_FILE_READ, FILE_GENERIC_READ },
2365 { SDDL_FILE_WRITE, FILE_GENERIC_WRITE },
2366 { SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE },
2367
2368 { SDDL_KEY_ALL, KEY_ALL_ACCESS },
2369 { SDDL_KEY_READ, KEY_READ },
2370 { SDDL_KEY_WRITE, KEY_WRITE },
2371 { SDDL_KEY_EXECUTE, KEY_EXECUTE },
2372
2373 { SDDL_NO_READ_UP, SYSTEM_MANDATORY_LABEL_NO_READ_UP },
2374 { SDDL_NO_WRITE_UP, SYSTEM_MANDATORY_LABEL_NO_WRITE_UP },
2375 { SDDL_NO_EXECUTE_UP, SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP },
2376 { NULL, 0 },
2377 };
2378
2379 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
2380 {
2381 UINT len = 0;
2382 DWORD rights = 0;
2383 LPCWSTR szAcl = *StringAcl;
2384
2385 while (*szAcl == ' ')
2386 szAcl++;
2387
2388 if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
2389 {
2390 LPCWSTR p = szAcl;
2391
2392 while (*p && *p != ';')
2393 p++;
2394
2395 if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
2396 {
2397 rights = strtoulW(szAcl, NULL, 16);
2398 szAcl = p;
2399 }
2400 else
2401 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
2402 }
2403 else
2404 {
2405 while (*szAcl != ';')
2406 {
2407 const ACEFLAG *lpaf = AceRights;
2408
2409 while (lpaf->wstr &&
2410 (len = strlenW(lpaf->wstr)) &&
2411 strncmpW(lpaf->wstr, szAcl, len))
2412 {
2413 lpaf++;
2414 }
2415
2416 if (!lpaf->wstr)
2417 return 0;
2418
2419 rights |= lpaf->value;
2420 szAcl += len;
2421 }
2422 }
2423
2424 *StringAcl = szAcl;
2425 return rights;
2426 }
2427
2428
2429 /******************************************************************************
2430 * ParseStringAclToAcl
2431 *
2432 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
2433 */
2434 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
2435 PACL pAcl, LPDWORD cBytes)
2436 {
2437 DWORD val;
2438 DWORD sidlen;
2439 DWORD length = sizeof(ACL);
2440 DWORD acesize = 0;
2441 DWORD acecount = 0;
2442 PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
2443 DWORD error = ERROR_INVALID_ACL;
2444
2445 TRACE("%s\n", debugstr_w(StringAcl));
2446
2447 if (!StringAcl)
2448 return FALSE;
2449
2450 if (pAcl) /* pAce is only useful if we're setting values */
2451 pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
2452
2453 /* Parse ACL flags */
2454 *lpdwFlags = ParseAclStringFlags(&StringAcl);
2455
2456 /* Parse ACE */
2457 while (*StringAcl == '(')
2458 {
2459 StringAcl++;
2460
2461 /* Parse ACE type */
2462 val = ParseAceStringType(&StringAcl);
2463 if (pAce)
2464 pAce->Header.AceType = (BYTE) val;
2465 if (*StringAcl != ';')
2466 {
2467 error = RPC_S_INVALID_STRING_UUID;
2468 goto lerr;
2469 }
2470 StringAcl++;
2471
2472 /* Parse ACE flags */
2473 val = ParseAceStringFlags(&StringAcl);
2474 if (pAce)
2475 pAce->Header.AceFlags = (BYTE) val;
2476 if (*StringAcl != ';')
2477 goto lerr;
2478 StringAcl++;
2479
2480 /* Parse ACE rights */
2481 val = ParseAceStringRights(&StringAcl);
2482 if (pAce)
2483 pAce->Mask = val;
2484 if (*StringAcl != ';')
2485 goto lerr;
2486 StringAcl++;
2487
2488 /* Parse ACE object guid */
2489 while (*StringAcl == ' ')
2490 StringAcl++;
2491 if (*StringAcl != ';')
2492 {
2493 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
2494 goto lerr;
2495 }
2496 StringAcl++;
2497
2498 /* Parse ACE inherit object guid */
2499 while (*StringAcl == ' ')
2500 StringAcl++;
2501 if (*StringAcl != ';')
2502 {
2503 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
2504 goto lerr;
2505 }
2506 StringAcl++;
2507
2508 /* Parse ACE account sid */
2509 if (ParseStringSidToSid(StringAcl, pAce ? &pAce->SidStart : NULL, &sidlen))
2510 {
2511 while (*StringAcl && *StringAcl != ')')
2512 StringAcl++;
2513 }
2514
2515 if (*StringAcl != ')')
2516 goto lerr;
2517 StringAcl++;
2518
2519 acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
2520 length += acesize;
2521 if (pAce)
2522 {
2523 pAce->Header.AceSize = acesize;
2524 pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
2525 }
2526 acecount++;
2527 }
2528
2529 *cBytes = length;
2530
2531 if (length > 0xffff)
2532 {
2533 ERR("ACL too large\n");
2534 goto lerr;
2535 }
2536
2537 if (pAcl)
2538 {
2539 pAcl->AclRevision = ACL_REVISION;
2540 pAcl->Sbz1 = 0;
2541 pAcl->AclSize = length;
2542 pAcl->AceCount = acecount;
2543 pAcl->Sbz2 = 0;
2544 }
2545 return TRUE;
2546
2547 lerr:
2548 SetLastError(error);
2549 WARN("Invalid ACE string format\n");
2550 return FALSE;
2551 }
2552
2553 /******************************************************************************
2554 * ParseStringSecurityDescriptorToSecurityDescriptor
2555 */
2556 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
2557 LPCWSTR StringSecurityDescriptor,
2558 SECURITY_DESCRIPTOR_RELATIVE* SecurityDescriptor,
2559 LPDWORD cBytes)
2560 {
2561 BOOL bret = FALSE;
2562 WCHAR toktype;
2563 WCHAR *tok;
2564 LPCWSTR lptoken;
2565 LPBYTE lpNext = NULL;
2566 DWORD len;
2567
2568 *cBytes = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
2569
2570 tok = heap_alloc( (lstrlenW(StringSecurityDescriptor) + 1) * sizeof(WCHAR));
2571
2572 if (SecurityDescriptor)
2573 lpNext = (LPBYTE)(SecurityDescriptor + 1);
2574
2575 while (*StringSecurityDescriptor == ' ')
2576 StringSecurityDescriptor++;
2577
2578 while (*StringSecurityDescriptor)
2579 {
2580 toktype = *StringSecurityDescriptor;
2581
2582 /* Expect char identifier followed by ':' */
2583 StringSecurityDescriptor++;
2584 if (*StringSecurityDescriptor != ':')
2585 {
2586 SetLastError(ERROR_INVALID_PARAMETER);
2587 goto lend;
2588 }
2589 StringSecurityDescriptor++;
2590
2591 /* Extract token */
2592 lptoken = StringSecurityDescriptor;
2593 while (*lptoken && *lptoken != ':')
2594 lptoken++;
2595
2596 if (*lptoken)
2597 lptoken--;
2598
2599 len = lptoken - StringSecurityDescriptor;
2600 memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
2601 tok[len] = 0;
2602
2603 switch (toktype)
2604 {
2605 case 'O':
2606 {
2607 DWORD bytes;
2608
2609 if (!ParseStringSidToSid(tok, lpNext, &bytes))
2610 goto lend;
2611
2612 if (SecurityDescriptor)
2613 {
2614 SecurityDescriptor->Owner = lpNext - (LPBYTE)SecurityDescriptor;
2615 lpNext += bytes; /* Advance to next token */
2616 }
2617
2618 *cBytes += bytes;
2619
2620 break;
2621 }
2622
2623 case 'G':
2624 {
2625 DWORD bytes;
2626
2627 if (!ParseStringSidToSid(tok, lpNext, &bytes))
2628 goto lend;
2629
2630 if (SecurityDescriptor)
2631 {
2632 SecurityDescriptor->Group = lpNext - (LPBYTE)SecurityDescriptor;
2633 lpNext += bytes; /* Advance to next token */
2634 }
2635
2636 *cBytes += bytes;
2637
2638 break;
2639 }
2640
2641 case 'D':
2642 {
2643 DWORD flags;
2644 DWORD bytes;
2645
2646 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
2647 goto lend;
2648
2649 if (SecurityDescriptor)
2650 {
2651 SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
2652 SecurityDescriptor->Dacl = lpNext - (LPBYTE)SecurityDescriptor;
2653 lpNext += bytes; /* Advance to next token */
2654 }
2655
2656 *cBytes += bytes;
2657
2658 break;
2659 }
2660
2661 case 'S':
2662 {
2663 DWORD flags;
2664 DWORD bytes;
2665
2666 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
2667 goto lend;
2668
2669 if (SecurityDescriptor)
2670 {
2671 SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
2672 SecurityDescriptor->Sacl = lpNext - (LPBYTE)SecurityDescriptor;
2673 lpNext += bytes; /* Advance to next token */
2674 }
2675
2676 *cBytes += bytes;
2677
2678 break;
2679 }
2680
2681 default:
2682 FIXME("Unknown token\n");
2683 SetLastError(ERROR_INVALID_PARAMETER);
2684 goto lend;
2685 }
2686
2687 StringSecurityDescriptor = lptoken;
2688 }
2689
2690 bret = TRUE;
2691
2692 lend:
2693 heap_free(tok);
2694 return bret;
2695 }
2696
2697 /* Winehq cvs 20050916 */
2698 /******************************************************************************
2699 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
2700 * @implemented
2701 */
2702 BOOL
2703 WINAPI
2704 ConvertStringSecurityDescriptorToSecurityDescriptorA(LPCSTR StringSecurityDescriptor,
2705 DWORD StringSDRevision,
2706 PSECURITY_DESCRIPTOR* SecurityDescriptor,
2707 PULONG SecurityDescriptorSize)
2708 {
2709 UINT len;
2710 BOOL ret = FALSE;
2711 LPWSTR StringSecurityDescriptorW;
2712
2713 len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
2714 StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2715
2716 if (StringSecurityDescriptorW)
2717 {
2718 MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
2719
2720 ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
2721 StringSDRevision, SecurityDescriptor,
2722 SecurityDescriptorSize);
2723 HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
2724 }
2725
2726 return ret;
2727 }
2728
2729 /******************************************************************************
2730 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
2731 * @implemented
2732 */
2733 BOOL WINAPI
2734 ConvertStringSecurityDescriptorToSecurityDescriptorW(LPCWSTR StringSecurityDescriptor,
2735 DWORD StringSDRevision,
2736 PSECURITY_DESCRIPTOR* SecurityDescriptor,
2737 PULONG SecurityDescriptorSize)
2738 {
2739 DWORD cBytes;
2740 SECURITY_DESCRIPTOR* psd;
2741 BOOL bret = FALSE;
2742
2743 TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
2744
2745 if (GetVersion() & 0x80000000)
2746 {
2747 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2748 goto lend;
2749 }
2750 else if (!StringSecurityDescriptor || !SecurityDescriptor)
2751 {
2752 SetLastError(ERROR_INVALID_PARAMETER);
2753 goto lend;
2754 }
2755 else if (StringSDRevision != SID_REVISION)
2756 {
2757 SetLastError(ERROR_UNKNOWN_REVISION);
2758 goto lend;
2759 }
2760
2761 /* Compute security descriptor length */
2762 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
2763 NULL, &cBytes))
2764 goto lend;
2765
2766 psd = *SecurityDescriptor = LocalAlloc(GMEM_ZEROINIT, cBytes);
2767 if (!psd) goto lend;
2768
2769 psd->Revision = SID_REVISION;
2770 psd->Control |= SE_SELF_RELATIVE;
2771
2772 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
2773 (SECURITY_DESCRIPTOR_RELATIVE *)psd, &cBytes))
2774 {
2775 LocalFree(psd);
2776 goto lend;
2777 }
2778
2779 if (SecurityDescriptorSize)
2780 *SecurityDescriptorSize = cBytes;
2781
2782 bret = TRUE;
2783
2784 lend:
2785 TRACE(" ret=%d\n", bret);
2786 return bret;
2787 }
2788
2789 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
2790 {
2791 if (cch == -1)
2792 cch = strlenW(string);
2793
2794 if (plen)
2795 *plen += cch;
2796
2797 if (pwptr)
2798 {
2799 memcpy(*pwptr, string, sizeof(WCHAR)*cch);
2800 *pwptr += cch;
2801 }
2802 }
2803
2804 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
2805 {
2806 DWORD i;
2807 WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
2808 WCHAR subauthfmt[] = { '-','%','u',0 };
2809 WCHAR buf[26];
2810 SID *pisid = psid;
2811
2812 if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
2813 {
2814 SetLastError(ERROR_INVALID_SID);
2815 return FALSE;
2816 }
2817
2818 if (pisid->IdentifierAuthority.Value[0] ||
2819 pisid->IdentifierAuthority.Value[1])
2820 {
2821 FIXME("not matching MS' bugs\n");
2822 SetLastError(ERROR_INVALID_SID);
2823 return FALSE;
2824 }
2825
2826 sprintfW( buf, fmt, pisid->Revision,
2827 MAKELONG(
2828 MAKEWORD( pisid->IdentifierAuthority.Value[5],
2829 pisid->IdentifierAuthority.Value[4] ),
2830 MAKEWORD( pisid->IdentifierAuthority.Value[3],
2831 pisid->IdentifierAuthority.Value[2] )
2832 ) );
2833 DumpString(buf, -1, pwptr, plen);
2834
2835 for( i=0; i<pisid->SubAuthorityCount; i++ )
2836 {
2837 sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
2838 DumpString(buf, -1, pwptr, plen);
2839 }
2840 return TRUE;
2841 }
2842
2843 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
2844 {
2845 size_t i;
2846 for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
2847 {
2848 if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
2849 {
2850 DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
2851 return TRUE;
2852 }
2853 }
2854
2855 return DumpSidNumeric(psid, pwptr, plen);
2856 }
2857
2858 static const LPCWSTR AceRightBitNames[32] = {
2859 SDDL_CREATE_CHILD, /* 0 */
2860 SDDL_DELETE_CHILD,
2861 SDDL_LIST_CHILDREN,
2862 SDDL_SELF_WRITE,
2863 SDDL_READ_PROPERTY, /* 4 */
2864 SDDL_WRITE_PROPERTY,
2865 SDDL_DELETE_TREE,
2866 SDDL_LIST_OBJECT,
2867 SDDL_CONTROL_ACCESS, /* 8 */
2868 NULL,
2869 NULL,
2870 NULL,
2871 NULL, /* 12 */
2872 NULL,
2873 NULL,
2874 NULL,
2875 SDDL_STANDARD_DELETE, /* 16 */
2876 SDDL_READ_CONTROL,
2877 SDDL_WRITE_DAC,
2878 SDDL_WRITE_OWNER,
2879 NULL, /* 20 */
2880 NULL,
2881 NULL,
2882 NULL,
2883 NULL, /* 24 */
2884 NULL,
2885 NULL,
2886 NULL,
2887 SDDL_GENERIC_ALL, /* 28 */
2888 SDDL_GENERIC_EXECUTE,
2889 SDDL_GENERIC_WRITE,
2890 SDDL_GENERIC_READ
2891 };
2892
2893 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
2894 {
2895 static const WCHAR fmtW[] = {'0','x','%','x',0};
2896 WCHAR buf[15];
2897 size_t i;
2898
2899 if (mask == 0)
2900 return;
2901
2902 /* first check if the right have name */
2903 for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++)
2904 {
2905 if (AceRights[i].wstr == NULL)
2906 break;
2907 if (mask == AceRights[i].value)
2908 {
2909 DumpString(AceRights[i].wstr, -1, pwptr, plen);
2910 return;
2911 }
2912 }
2913
2914 /* then check if it can be built from bit names */
2915 for (i = 0; i < 32; i++)
2916 {
2917 if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
2918 {
2919 /* can't be built from bit names */
2920 sprintfW(buf, fmtW, mask);
2921 DumpString(buf, -1, pwptr, plen);
2922 return;
2923 }
2924 }
2925
2926 /* build from bit names */
2927 for (i = 0; i < 32; i++)
2928 if (mask & (1 << i))
2929 DumpString(AceRightBitNames[i], -1, pwptr, plen);
2930 }
2931
2932 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
2933 {
2934 ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
2935 static const WCHAR openbr = '(';
2936 static const WCHAR closebr = ')';
2937 static const WCHAR semicolon = ';';
2938
2939 if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
2940 {
2941 SetLastError(ERROR_INVALID_ACL);
2942 return FALSE;
2943 }
2944
2945 piace = pace;
2946 DumpString(&openbr, 1, pwptr, plen);
2947 switch (piace->Header.AceType)
2948 {
2949 case ACCESS_ALLOWED_ACE_TYPE:
2950 DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
2951 break;
2952 case ACCESS_DENIED_ACE_TYPE:
2953 DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
2954 break;
2955 case SYSTEM_AUDIT_ACE_TYPE:
2956 DumpString(SDDL_AUDIT, -1, pwptr, plen);
2957 break;
2958 case SYSTEM_ALARM_ACE_TYPE:
2959 DumpString(SDDL_ALARM, -1, pwptr, plen);
2960 break;
2961 }
2962 DumpString(&semicolon, 1, pwptr, plen);
2963
2964 if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
2965 DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
2966 if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
2967 DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
2968 if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
2969 DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
2970 if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
2971 DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
2972 if (piace->Header.AceFlags & INHERITED_ACE)
2973 DumpString(SDDL_INHERITED, -1, pwptr, plen);
2974 if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
2975 DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
2976 if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
2977 DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
2978 DumpString(&semicolon, 1, pwptr, plen);
2979 DumpRights(piace->Mask, pwptr, plen);
2980 DumpString(&semicolon, 1, pwptr, plen);
2981 /* objects not supported */
2982 DumpString(&semicolon, 1, pwptr, plen);
2983 /* objects not supported */
2984 DumpString(&semicolon, 1, pwptr, plen);
2985 if (!DumpSid((PSID)&piace->SidStart, pwptr, plen))
2986 return FALSE;
2987 DumpString(&closebr, 1, pwptr, plen);
2988 return TRUE;
2989 }
2990
2991 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
2992 {
2993 WORD count;
2994 int i;
2995
2996 if (protected)
2997 DumpString(SDDL_PROTECTED, -1, pwptr, plen);
2998 if (autoInheritReq)
2999 DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
3000 if (autoInherited)
3001 DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
3002
3003 if (pacl == NULL)
3004 return TRUE;
3005
3006 if (!IsValidAcl(pacl))
3007 return FALSE;
3008
3009 count = pacl->AceCount;
3010 for (i = 0; i < count; i++)
3011 {
3012 LPVOID ace;
3013 if (!GetAce(pacl, i, &ace))
3014 return FALSE;
3015 if (!DumpAce(ace, pwptr, plen))
3016 return FALSE;
3017 }
3018
3019 return TRUE;
3020 }
3021
3022 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
3023 {
3024 static const WCHAR prefix[] = {'O',':',0};
3025 BOOL bDefaulted;
3026 PSID psid;
3027
3028 if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
3029 return FALSE;
3030
3031 if (psid == NULL)
3032 return TRUE;
3033
3034 DumpString(prefix, -1, pwptr, plen);
3035 if (!DumpSid(psid, pwptr, plen))
3036 return FALSE;
3037 return TRUE;
3038 }
3039
3040 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
3041 {
3042 static const WCHAR prefix[] = {'G',':',0};
3043 BOOL bDefaulted;
3044 PSID psid;
3045
3046 if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
3047 return FALSE;
3048
3049 if (psid == NULL)
3050 return TRUE;
3051
3052 DumpString(prefix, -1, pwptr, plen);
3053 if (!DumpSid(psid, pwptr, plen))
3054 return FALSE;
3055 return TRUE;
3056 }
3057
3058 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
3059 {
3060 static const WCHAR dacl[] = {'D',':',0};
3061 SECURITY_DESCRIPTOR_CONTROL control;
3062 BOOL present, defaulted;
3063 DWORD revision;
3064 PACL pacl;
3065
3066 if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
3067 return FALSE;
3068
3069 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
3070 return FALSE;
3071
3072 if (!present)
3073 return TRUE;
3074
3075 DumpString(dacl, 2, pwptr, plen);
3076 if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
3077 return FALSE;
3078 return TRUE;
3079 }
3080
3081 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
3082 {
3083 static const WCHAR sacl[] = {'S',':',0};
3084 SECURITY_DESCRIPTOR_CONTROL control;
3085 BOOL present, defaulted;
3086 DWORD revision;
3087 PACL pacl;
3088
3089 if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
3090 return FALSE;
3091
3092 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
3093 return FALSE;
3094
3095 if (!present)
3096 return TRUE;
3097
3098 DumpString(sacl, 2, pwptr, plen);
3099 if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
3100 return FALSE;
3101 return TRUE;
3102 }
3103
3104 /******************************************************************************
3105 * ConvertSecurityDescriptorToStringSecurityDescriptorW [ADVAPI32.@]
3106 */
3107 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, PULONG OutputLen)
3108 {
3109 ULONG len;
3110 WCHAR *wptr, *wstr;
3111
3112 if (SDRevision != SDDL_REVISION_1)
3113 {
3114 ERR("Program requested unknown SDDL revision %d\n", SDRevision);
3115 SetLastError(ERROR_UNKNOWN_REVISION);
3116 return FALSE;
3117 }
3118
3119 len = 0;
3120 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
3121 if (!DumpOwner(SecurityDescriptor, NULL, &len))
3122 return FALSE;
3123 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
3124 if (!DumpGroup(SecurityDescriptor, NULL, &len))
3125 return FALSE;
3126 if (RequestedInformation & DACL_SECURITY_INFORMATION)
3127 if (!DumpDacl(SecurityDescriptor, NULL, &len))
3128 return FALSE;
3129 if (RequestedInformation & SACL_SECURITY_INFORMATION)
3130 if (!DumpSacl(SecurityDescriptor, NULL, &len))
3131 return FALSE;
3132
3133 wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
3134 #ifdef __REACTOS__
3135 if (wstr == NULL)
3136 return FALSE;
3137 #endif
3138
3139 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
3140 if (!DumpOwner(SecurityDescriptor, &wptr, NULL)) {
3141 LocalFree (wstr);
3142 return FALSE;
3143 }
3144 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
3145 if (!DumpGroup(SecurityDescriptor, &wptr, NULL)) {
3146 LocalFree (wstr);
3147 return FALSE;
3148 }
3149 if (RequestedInformation & DACL_SECURITY_INFORMATION)
3150 if (!DumpDacl(SecurityDescriptor, &wptr, NULL)) {
3151 LocalFree (wstr);
3152 return FALSE;
3153 }
3154 if (RequestedInformation & SACL_SECURITY_INFORMATION)
3155 if (!DumpSacl(SecurityDescriptor, &wptr, NULL)) {
3156 LocalFree (wstr);
3157 return FALSE;
3158 }
3159 *wptr = 0;
3160
3161 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
3162 *OutputString = wstr;
3163 if (OutputLen)
3164 *OutputLen = strlenW(*OutputString)+1;
3165 return TRUE;
3166 }
3167
3168 /******************************************************************************
3169 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
3170 */
3171 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, PULONG OutputLen)
3172 {
3173 LPWSTR wstr;
3174 ULONG len;
3175 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
3176 {
3177 int lenA;
3178
3179 lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
3180 *OutputString = heap_alloc(lenA);
3181 #ifdef __REACTOS__
3182 if (*OutputString == NULL)
3183 {
3184 LocalFree(wstr);
3185 *OutputLen = 0;
3186 return FALSE;
3187 }
3188 #endif
3189 WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
3190 LocalFree(wstr);
3191
3192 if (OutputLen != NULL)
3193 *OutputLen = lenA;
3194 return TRUE;
3195 }
3196 else
3197 {
3198 *OutputString = NULL;
3199 if (OutputLen)
3200 *OutputLen = 0;
3201 return FALSE;
3202 }
3203 }
3204
3205 /******************************************************************************
3206 * ConvertStringSidToSidW [ADVAPI32.@]
3207 */
3208 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
3209 {
3210 BOOL bret = FALSE;
3211 DWORD cBytes;
3212
3213 TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
3214 if (GetVersion() & 0x80000000)
3215 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3216 else if (!StringSid || !Sid)
3217 SetLastError(ERROR_INVALID_PARAMETER);
3218 else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
3219 {
3220 PSID pSid = *Sid = LocalAlloc(0, cBytes);
3221
3222 bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
3223 if (!bret)
3224 LocalFree(*Sid);
3225 }
3226 return bret;
3227 }
3228
3229 /******************************************************************************
3230 * ConvertStringSidToSidA [ADVAPI32.@]
3231 */
3232 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
3233 {
3234 BOOL bret = FALSE;
3235
3236 TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
3237 if (GetVersion() & 0x80000000)
3238 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3239 else if (!StringSid || !Sid)
3240 SetLastError(ERROR_INVALID_PARAMETER);
3241 else
3242 {
3243 WCHAR *wStringSid = SERV_dup(StringSid);
3244 bret = ConvertStringSidToSidW(wStringSid, Sid);
3245 heap_free(wStringSid);
3246 }
3247 return bret;
3248 }
3249
3250 /*
3251 * @implemented
3252 */
3253 BOOL
3254 WINAPI
3255 ConvertSidToStringSidW(PSID Sid,
3256 LPWSTR *StringSid)
3257 {
3258 NTSTATUS Status;
3259 UNICODE_STRING UnicodeString;
3260 WCHAR FixedBuffer[64];
3261
3262 if (!RtlValidSid(Sid))
3263 {
3264 SetLastError(ERROR_INVALID_SID);
3265 return FALSE;
3266 }
3267
3268 UnicodeString.Length = 0;
3269 UnicodeString.MaximumLength = sizeof(FixedBuffer);
3270 UnicodeString.Buffer = FixedBuffer;
3271 Status = RtlConvertSidToUnicodeString(&UnicodeString, Sid, FALSE);
3272 if (STATUS_BUFFER_TOO_SMALL == Status)
3273 {
3274 Status = RtlConvertSidToUnicodeString(&UnicodeString, Sid, TRUE);
3275 }
3276
3277 if (!NT_SUCCESS(Status))
3278 {
3279 SetLastError(RtlNtStatusToDosError(Status));
3280 return FALSE;
3281 }
3282
3283 *StringSid = LocalAlloc(LMEM_FIXED, UnicodeString.Length + sizeof(WCHAR));
3284 if (NULL == *StringSid)
3285 {
3286 if (UnicodeString.Buffer != FixedBuffer)
3287 {
3288 RtlFreeUnicodeString(&UnicodeString);
3289 }
3290 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
3291 return FALSE;
3292 }
3293
3294 MoveMemory(*StringSid, UnicodeString.Buffer, UnicodeString.Length);
3295 ZeroMemory((PCHAR) *StringSid + UnicodeString.Length, sizeof(WCHAR));
3296 if (UnicodeString.Buffer != FixedBuffer)
3297 {
3298 RtlFreeUnicodeString(&UnicodeString);
3299 }
3300
3301 return TRUE;
3302 }
3303
3304 /*
3305 * @implemented
3306 */
3307 BOOL
3308 WINAPI
3309 ConvertSidToStringSidA(PSID Sid,
3310 LPSTR *StringSid)
3311 {
3312 LPWSTR StringSidW;
3313 int Len;
3314
3315 if (!ConvertSidToStringSidW(Sid, &StringSidW))
3316 {
3317 return FALSE;
3318 }
3319
3320 Len = WideCharToMultiByte(CP_ACP, 0, StringSidW, -1, NULL, 0, NULL, NULL);
3321 if (Len <= 0)
3322 {
3323 LocalFree(StringSidW);
3324 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
3325 return FALSE;
3326 }
3327
3328 *StringSid = LocalAlloc(LMEM_FIXED, Len);
3329 if (NULL == *StringSid)
3330 {
3331 LocalFree(StringSidW);
3332 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
3333 return FALSE;
3334 }
3335
3336 if (!WideCharToMultiByte(CP_ACP, 0, StringSidW, -1, *StringSid, Len, NULL, NULL))
3337 {
3338 LocalFree(StringSid);
3339 LocalFree(StringSidW);
3340 return FALSE;
3341 }
3342
3343 LocalFree(StringSidW);
3344
3345 return TRUE;
3346 }
3347
3348 /*
3349 * @unimplemented
3350 */
3351 BOOL WINAPI
3352 CreateProcessWithLogonW(LPCWSTR lpUsername,
3353 LPCWSTR lpDomain,
3354 LPCWSTR lpPassword,
3355 DWORD dwLogonFlags,
3356 LPCWSTR lpApplicationName,
3357 LPWSTR lpCommandLine,
3358 DWORD dwCreationFlags,
3359 LPVOID lpEnvironment,
3360 LPCWSTR lpCurrentDirectory,
3361 LPSTARTUPINFOW lpStartupInfo,
3362 LPPROCESS_INFORMATION lpProcessInformation)
3363 {
3364 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername), debugstr_w(lpDomain),
3365 debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName),
3366 debugstr_w(lpCommandLine), dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory),
3367 lpStartupInfo, lpProcessInformation);
3368
3369 return FALSE;
3370 }
3371
3372 BOOL WINAPI CreateProcessWithTokenW(HANDLE token, DWORD logon_flags, LPCWSTR application_name, LPWSTR command_line,
3373 DWORD creation_flags, void *environment, LPCWSTR current_directory, STARTUPINFOW *startup_info,
3374 PROCESS_INFORMATION *process_information )
3375 {
3376 FIXME("%p 0x%08x %s %s 0x%08x %p %s %p %p - semi-stub\n", token,
3377 logon_flags, debugstr_w(application_name), debugstr_w(command_line),
3378 creation_flags, environment, debugstr_w(current_directory),
3379 startup_info, process_information);
3380
3381 /* FIXME: check if handles should be inherited */
3382 return CreateProcessW( application_name, command_line, NULL, NULL, FALSE, creation_flags, environment,
3383 current_directory, startup_info, process_information );
3384 }
3385
3386 /*
3387 * @implemented
3388 */
3389 BOOL WINAPI
3390 DuplicateTokenEx(IN HANDLE ExistingTokenHandle,
3391 IN DWORD dwDesiredAccess,
3392 IN LPSECURITY_ATTRIBUTES lpTokenAttributes OPTIONAL,
3393 IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
3394 IN TOKEN_TYPE TokenType,
3395 OUT PHANDLE DuplicateTokenHandle)
3396 {
3397 OBJECT_ATTRIBUTES ObjectAttributes;
3398 NTSTATUS Status;
3399 SECURITY_QUALITY_OF_SERVICE Sqos;
3400
3401 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
3402 ImpersonationLevel, TokenType, DuplicateTokenHandle);
3403
3404 Sqos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
3405 Sqos.ImpersonationLevel = ImpersonationLevel;
3406 Sqos.ContextTrackingMode = 0;
3407 Sqos.EffectiveOnly = FALSE;
3408
3409 if (lpTokenAttributes != NULL)
3410 {
3411 InitializeObjectAttributes(&ObjectAttributes,
3412 NULL,
3413 lpTokenAttributes->bInheritHandle ? OBJ_INHERIT : 0,
3414 NULL,
3415 lpTokenAttributes->lpSecurityDescriptor);
3416 }
3417 else
3418 {
3419 InitializeObjectAttributes(&ObjectAttributes,
3420 NULL,
3421 0,
3422 NULL,
3423 NULL);
3424 }
3425
3426 ObjectAttributes.SecurityQualityOfService = &Sqos;
3427
3428 Status = NtDuplicateToken(ExistingTokenHandle,
3429 dwDesiredAccess,
3430 &ObjectAttributes,
3431 FALSE,
3432 TokenType,
3433 DuplicateTokenHandle);
3434 if (!NT_SUCCESS(Status))
3435 {
3436 ERR("NtDuplicateToken failed: Status %08x\n", Status);
3437 SetLastError(RtlNtStatusToDosError(Status));
3438 return FALSE;
3439 }
3440
3441 TRACE("Returning token %p.\n", *DuplicateTokenHandle);
3442
3443 return TRUE;
3444 }
3445
3446 /*
3447 * @implemented
3448 */
3449 BOOL WINAPI
3450 DuplicateToken(IN HANDLE ExistingTokenHandle,
3451 IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
3452 OUT PHANDLE DuplicateTokenHandle)
3453 {
3454 return DuplicateTokenEx(ExistingTokenHandle,
3455 TOKEN_IMPERSONATE | TOKEN_QUERY,
3456 NULL,
3457 ImpersonationLevel,
3458 TokenImpersonation,
3459 DuplicateTokenHandle);
3460 }
3461
3462 /******************************************************************************
3463 * ComputeStringSidSize
3464 */
3465 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
3466 {
3467 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
3468 {
3469 int ctok = 0;
3470 while (*StringSid)
3471 {
3472 if (*StringSid == '-')
3473 ctok++;
3474 StringSid++;
3475 }
3476
3477 if (ctok >= 3)
3478 return GetSidLengthRequired(ctok - 2);
3479 }
3480 else /* String constant format - Only available in winxp and above */
3481 {
3482 unsigned int i;
3483
3484 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
3485 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
3486 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
3487
3488 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
3489 if (!strncmpW(WellKnownRids[i].wstr, StringSid, 2))
3490 {
3491 MAX_SID local;
3492 ADVAPI_GetComputerSid(&local);
3493 return GetSidLengthRequired(*GetSidSubAuthorityCount(&local) + 1);
3494 }
3495
3496 }
3497
3498 return GetSidLengthRequired(0);
3499 }
3500
3501 /******************************************************************************
3502 * ParseStringSidToSid
3503 */
3504 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
3505 {
3506 BOOL bret = FALSE;
3507 SID* pisid=pSid;
3508
3509 TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
3510 if (!StringSid)
3511 {
3512 SetLastError(ERROR_INVALID_PARAMETER);
3513 TRACE("StringSid is NULL, returning FALSE\n");
3514 return FALSE;
3515 }
3516
3517 while (*StringSid == ' ')
3518 StringSid++;
3519
3520 if (!*StringSid)
3521 goto lend; /* ERROR_INVALID_SID */
3522
3523 *cBytes = ComputeStringSidSize(StringSid);
3524 if (!pisid) /* Simply compute the size */
3525 {
3526 TRACE("only size requested, returning TRUE with %d\n", *cBytes);
3527 return TRUE;
3528 }
3529
3530 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
3531 {
3532 DWORD i = 0, identAuth;
3533 DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
3534
3535 StringSid += 2; /* Advance to Revision */
3536 pisid->Revision = atoiW(StringSid);
3537
3538 if (pisid->Revision != SDDL_REVISION)
3539 {
3540 TRACE("Revision %d is unknown\n", pisid->Revision);
3541 goto lend; /* ERROR_INVALID_SID */
3542 }
3543 if (csubauth == 0)
3544 {
3545 TRACE("SubAuthorityCount is 0\n");
3546 goto lend; /* ERROR_INVALID_SID */
3547 }
3548
3549 pisid->SubAuthorityCount = csubauth;
3550
3551 /* Advance to identifier authority */
3552 while (*StringSid && *StringSid != '-')
3553 StringSid++;
3554 if (*StringSid == '-')
3555 StringSid++;
3556
3557 /* MS' implementation can't handle values greater than 2^32 - 1, so
3558 * we don't either; assume most significant bytes are always 0
3559 */
3560 pisid->IdentifierAuthority.Value[0] = 0;
3561 pisid->IdentifierAuthority.Value[1] = 0;
3562 identAuth = atoiW(StringSid);
3563 pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
3564 pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
3565 pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
3566 pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
3567
3568 /* Advance to first sub authority */
3569 while (*StringSid && *StringSid != '-')
3570 StringSid++;
3571 if (*StringSid == '-')
3572 StringSid++;
3573
3574 while (*StringSid)
3575 {
3576 pisid->SubAuthority[i++] = atoiW(StringSid);
3577
3578 while (*StringSid && *StringSid != '-')
3579 StringSid++;
3580 if (*StringSid == '-')
3581 StringSid++;
3582 }
3583
3584 if (i != pisid->SubAuthorityCount)
3585 goto lend; /* ERROR_INVALID_SID */
3586
3587 bret = TRUE;
3588 }
3589 else /* String constant format - Only available in winxp and above */
3590 {
3591 unsigned int i;
3592 pisid->Revision = SDDL_REVISION;
3593
3594 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
3595 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
3596 {
3597 DWORD j;
3598 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
3599 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
3600 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
3601 pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
3602 bret = TRUE;
3603 }
3604
3605 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
3606 if (!strncmpW(WellKnownRids[i].wstr, StringSid, 2))
3607 {
3608 ADVAPI_GetComputerSid(pisid);
3609 pisid->SubAuthority[pisid->SubAuthorityCount] = WellKnownRids[i].Rid;
3610 pisid->SubAuthorityCount++;
3611 bret = TRUE;
3612 }
3613
3614 if (!bret)
3615 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
3616 }
3617
3618 lend:
3619 if (!bret)
3620 SetLastError(ERROR_INVALID_SID);
3621
3622 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
3623 return bret;
3624 }
3625
3626 /**********************************************************************
3627 * GetNamedSecurityInfoA EXPORTED
3628 *
3629 * @implemented
3630 */
3631 DWORD
3632 WINAPI
3633 GetNamedSecurityInfoA(LPSTR pObjectName,
3634 SE_OBJECT_TYPE ObjectType,
3635 SECURITY_INFORMATION SecurityInfo,
3636 PSID *ppsidOwner,
3637 PSID *ppsidGroup,
3638 PACL *ppDacl,
3639 PACL *ppSacl,
3640 PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
3641 {
3642 DWORD len;
3643 LPWSTR wstr = NULL;
3644 DWORD r;
3645
3646 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
3647 ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
3648
3649 if( pObjectName )
3650 {
3651 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
3652 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
3653 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
3654 }
3655
3656 r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
3657 ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
3658
3659 HeapFree( GetProcessHeap(), 0, wstr );
3660
3661 return r;
3662 }
3663
3664 /******************************************************************************
3665 * GetWindowsAccountDomainSid [ADVAPI32.@]
3666 */
3667 BOOL WINAPI GetWindowsAccountDomainSid( PSID sid, PSID domain_sid, DWORD *size )
3668 {
3669 SID_IDENTIFIER_AUTHORITY domain_ident = { SECURITY_NT_AUTHORITY };
3670 DWORD required_size;
3671 int i;
3672
3673 FIXME( "(%p %p %p): semi-stub\n", sid, domain_sid, size );
3674
3675 if (!sid || !IsValidSid( sid ))
3676 {
3677 SetLastError( ERROR_INVALID_SID );
3678 return FALSE;
3679 }
3680
3681 if (!size)
3682 {
3683 SetLastError( ERROR_INVALID_PARAMETER );
3684 return FALSE;
3685 }
3686
3687 if (*GetSidSubAuthorityCount( sid ) < 4)
3688 {
3689 SetLastError( ERROR_INVALID_SID );
3690 return FALSE;
3691 }
3692
3693 required_size = GetSidLengthRequired( 4 );
3694 if (*size < required_size || !domain_sid)
3695 {
3696 *size = required_size;
3697 SetLastError( domain_sid ? ERROR_INSUFFICIENT_BUFFER :
3698 ERROR_INVALID_PARAMETER );
3699 return FALSE;
3700 }
3701
3702 InitializeSid( domain_sid, &domain_ident, 4 );
3703 for (i = 0; i < 4; i++)
3704 *GetSidSubAuthority( domain_sid, i ) = *GetSidSubAuthority( sid, i );
3705
3706 *size = required_size;
3707 return TRUE;
3708 }
3709
3710 /*
3711 * @unimplemented
3712 */
3713 BOOL
3714 WINAPI
3715 EqualDomainSid(IN PSID pSid1,
3716 IN PSID pSid2,
3717 OUT BOOL* pfEqual)
3718 {
3719 UNIMPLEMENTED;
3720 return FALSE;
3721 }
3722
3723 /* EOF */