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