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