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