[ADVAPI32] Remove unused debug channels and comment out unused variables. Silences...
[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 return RtlIdentifierAuthoritySid(pSid);
763 }
764
765 /*
766 * @implemented
767 */
768 PDWORD
769 WINAPI
770 GetSidSubAuthority(PSID pSid,
771 DWORD nSubAuthority)
772 {
773 SetLastError(ERROR_SUCCESS);
774 return (PDWORD)RtlSubAuthoritySid(pSid, nSubAuthority);
775 }
776
777 /*
778 * @implemented
779 */
780 PUCHAR
781 WINAPI
782 GetSidSubAuthorityCount(PSID pSid)
783 {
784 SetLastError(ERROR_SUCCESS);
785 return RtlSubAuthorityCountSid(pSid);
786 }
787
788 /*
789 * @implemented
790 */
791 DWORD
792 WINAPI
793 GetLengthSid(PSID pSid)
794 {
795 return (DWORD)RtlLengthSid(pSid);
796 }
797
798 /*
799 * @implemented
800 */
801 BOOL
802 WINAPI
803 InitializeSecurityDescriptor(PSECURITY_DESCRIPTOR pSecurityDescriptor,
804 DWORD dwRevision)
805 {
806 NTSTATUS Status;
807
808 Status = RtlCreateSecurityDescriptor(pSecurityDescriptor,
809 dwRevision);
810 if (!NT_SUCCESS(Status))
811 {
812 SetLastError(RtlNtStatusToDosError(Status));
813 return FALSE;
814 }
815
816 return TRUE;
817 }
818
819 /*
820 * @implemented
821 */
822 BOOL
823 WINAPI
824 MakeAbsoluteSD(PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
825 PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
826 LPDWORD lpdwAbsoluteSecurityDescriptorSize,
827 PACL pDacl,
828 LPDWORD lpdwDaclSize,
829 PACL pSacl,
830 LPDWORD lpdwSaclSize,
831 PSID pOwner,
832 LPDWORD lpdwOwnerSize,
833 PSID pPrimaryGroup,
834 LPDWORD lpdwPrimaryGroupSize)
835 {
836 NTSTATUS Status;
837
838 Status = RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
839 pAbsoluteSecurityDescriptor,
840 lpdwAbsoluteSecurityDescriptorSize,
841 pDacl,
842 lpdwDaclSize,
843 pSacl,
844 lpdwSaclSize,
845 pOwner,
846 lpdwOwnerSize,
847 pPrimaryGroup,
848 lpdwPrimaryGroupSize);
849 if (!NT_SUCCESS(Status))
850 {
851 SetLastError(RtlNtStatusToDosError(Status));
852 return FALSE;
853 }
854
855 return TRUE;
856 }
857
858 /******************************************************************************
859 * GetKernelObjectSecurity [ADVAPI32.@]
860 */
861 BOOL WINAPI GetKernelObjectSecurity(
862 HANDLE Handle,
863 SECURITY_INFORMATION RequestedInformation,
864 PSECURITY_DESCRIPTOR pSecurityDescriptor,
865 DWORD nLength,
866 LPDWORD lpnLengthNeeded )
867 {
868 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation,
869 pSecurityDescriptor, nLength, lpnLengthNeeded);
870
871 return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
872 nLength, lpnLengthNeeded ));
873 }
874
875 /*
876 * @implemented
877 */
878 BOOL
879 WINAPI
880 InitializeAcl(PACL pAcl,
881 DWORD nAclLength,
882 DWORD dwAclRevision)
883 {
884 NTSTATUS Status;
885
886 Status = RtlCreateAcl(pAcl,
887 nAclLength,
888 dwAclRevision);
889 if (!NT_SUCCESS(Status))
890 {
891 SetLastError(RtlNtStatusToDosError(Status));
892 return FALSE;
893 }
894
895 return TRUE;
896 }
897
898 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
899 {
900 IO_STATUS_BLOCK io_block;
901
902 TRACE("(%p)\n", hNamedPipe);
903
904 return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
905 &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
906 }
907
908 /*
909 * @implemented
910 */
911 BOOL
912 WINAPI
913 AddAccessAllowedAce(PACL pAcl,
914 DWORD dwAceRevision,
915 DWORD AccessMask,
916 PSID pSid)
917 {
918 NTSTATUS Status;
919
920 Status = RtlAddAccessAllowedAce(pAcl,
921 dwAceRevision,
922 AccessMask,
923 pSid);
924 if (!NT_SUCCESS(Status))
925 {
926 SetLastError(RtlNtStatusToDosError(Status));
927 return FALSE;
928 }
929
930 return TRUE;
931 }
932
933 /*
934 * @implemented
935 */
936 BOOL WINAPI
937 AddAccessAllowedAceEx(PACL pAcl,
938 DWORD dwAceRevision,
939 DWORD AceFlags,
940 DWORD AccessMask,
941 PSID pSid)
942 {
943 NTSTATUS Status;
944
945 Status = RtlAddAccessAllowedAceEx(pAcl,
946 dwAceRevision,
947 AceFlags,
948 AccessMask,
949 pSid);
950 if (!NT_SUCCESS(Status))
951 {
952 SetLastError(RtlNtStatusToDosError(Status));
953 return FALSE;
954 }
955
956 return TRUE;
957 }
958
959 /*
960 * @implemented
961 */
962 BOOL
963 WINAPI
964 AddAccessDeniedAce(PACL pAcl,
965 DWORD dwAceRevision,
966 DWORD AccessMask,
967 PSID pSid)
968 {
969 NTSTATUS Status;
970
971 Status = RtlAddAccessDeniedAce(pAcl,
972 dwAceRevision,
973 AccessMask,
974 pSid);
975 if (!NT_SUCCESS(Status))
976 {
977 SetLastError(RtlNtStatusToDosError(Status));
978 return FALSE;
979 }
980
981 return TRUE;
982 }
983
984 /*
985 * @implemented
986 */
987 BOOL WINAPI
988 AddAccessDeniedAceEx(PACL pAcl,
989 DWORD dwAceRevision,
990 DWORD AceFlags,
991 DWORD AccessMask,
992 PSID pSid)
993 {
994 NTSTATUS Status;
995
996 Status = RtlAddAccessDeniedAceEx(pAcl,
997 dwAceRevision,
998 AceFlags,
999 AccessMask,
1000 pSid);
1001 if (!NT_SUCCESS(Status))
1002 {
1003 SetLastError(RtlNtStatusToDosError(Status));
1004 return FALSE;
1005 }
1006
1007 return TRUE;
1008 }
1009
1010 /*
1011 * @implemented
1012 */
1013 BOOL
1014 WINAPI
1015 AddAce(PACL pAcl,
1016 DWORD dwAceRevision,
1017 DWORD dwStartingAceIndex,
1018 LPVOID pAceList,
1019 DWORD nAceListLength)
1020 {
1021 NTSTATUS Status;
1022
1023 Status = RtlAddAce(pAcl,
1024 dwAceRevision,
1025 dwStartingAceIndex,
1026 pAceList,
1027 nAceListLength);
1028 if (!NT_SUCCESS(Status))
1029 {
1030 SetLastError(RtlNtStatusToDosError(Status));
1031 return FALSE;
1032 }
1033
1034 return TRUE;
1035 }
1036
1037 /******************************************************************************
1038 * DeleteAce [ADVAPI32.@]
1039 */
1040 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1041 {
1042 return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1043 }
1044
1045 /*
1046 * @implemented
1047 */
1048 BOOL
1049 WINAPI
1050 FindFirstFreeAce(PACL pAcl,
1051 LPVOID *pAce)
1052 {
1053 return RtlFirstFreeAce(pAcl,
1054 (PACE*)pAce);
1055 }
1056
1057 /******************************************************************************
1058 * GetAce [ADVAPI32.@]
1059 */
1060 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1061 {
1062 return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1063 }
1064
1065 /******************************************************************************
1066 * GetAclInformation [ADVAPI32.@]
1067 */
1068 BOOL WINAPI GetAclInformation(
1069 PACL pAcl,
1070 LPVOID pAclInformation,
1071 DWORD nAclInformationLength,
1072 ACL_INFORMATION_CLASS dwAclInformationClass)
1073 {
1074 return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1075 nAclInformationLength, dwAclInformationClass));
1076 }
1077
1078 /*
1079 * @implemented
1080 */
1081 BOOL
1082 WINAPI
1083 IsValidAcl(PACL pAcl)
1084 {
1085 return RtlValidAcl (pAcl);
1086 }
1087
1088 /*
1089 * @implemented
1090 */
1091 BOOL WINAPI
1092 AllocateLocallyUniqueId(PLUID Luid)
1093 {
1094 NTSTATUS Status;
1095
1096 Status = NtAllocateLocallyUniqueId (Luid);
1097 if (!NT_SUCCESS (Status))
1098 {
1099 SetLastError(RtlNtStatusToDosError(Status));
1100 return FALSE;
1101 }
1102
1103 return TRUE;
1104 }
1105
1106 /**********************************************************************
1107 * LookupPrivilegeDisplayNameA EXPORTED
1108 *
1109 * @unimplemented
1110 */
1111 BOOL
1112 WINAPI
1113 LookupPrivilegeDisplayNameA(LPCSTR lpSystemName,
1114 LPCSTR lpName,
1115 LPSTR lpDisplayName,
1116 LPDWORD cchDisplayName,
1117 LPDWORD lpLanguageId)
1118 {
1119 UNICODE_STRING lpSystemNameW;
1120 UNICODE_STRING lpNameW;
1121 BOOL ret;
1122 DWORD wLen = 0;
1123
1124 TRACE("%s %s %p %p %p\n", debugstr_a(lpSystemName), debugstr_a(lpName), lpName, cchDisplayName, lpLanguageId);
1125
1126 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1127 RtlCreateUnicodeStringFromAsciiz(&lpNameW, lpName);
1128 ret = LookupPrivilegeDisplayNameW(lpSystemNameW.Buffer, lpNameW.Buffer, NULL, &wLen, lpLanguageId);
1129 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1130 {
1131 LPWSTR lpDisplayNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1132
1133 ret = LookupPrivilegeDisplayNameW(lpSystemNameW.Buffer, lpNameW.Buffer, lpDisplayNameW,
1134 &wLen, lpLanguageId);
1135 if (ret)
1136 {
1137 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpDisplayNameW, -1, lpDisplayName,
1138 *cchDisplayName, NULL, NULL);
1139
1140 if (len == 0)
1141 {
1142 /* WideCharToMultiByte failed */
1143 ret = FALSE;
1144 }
1145 else if (len > *cchDisplayName)
1146 {
1147 *cchDisplayName = len;
1148 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1149 ret = FALSE;
1150 }
1151 else
1152 {
1153 /* WideCharToMultiByte succeeded, output length needs to be
1154 * length not including NULL terminator
1155 */
1156 *cchDisplayName = len - 1;
1157 }
1158 }
1159 HeapFree(GetProcessHeap(), 0, lpDisplayNameW);
1160 }
1161 RtlFreeUnicodeString(&lpSystemNameW);
1162 RtlFreeUnicodeString(&lpNameW);
1163 return ret;
1164 }
1165
1166 /**********************************************************************
1167 * LookupPrivilegeNameA EXPORTED
1168 *
1169 * @implemented
1170 */
1171 BOOL
1172 WINAPI
1173 LookupPrivilegeNameA(LPCSTR lpSystemName,
1174 PLUID lpLuid,
1175 LPSTR lpName,
1176 LPDWORD cchName)
1177 {
1178 UNICODE_STRING lpSystemNameW;
1179 BOOL ret;
1180 DWORD wLen = 0;
1181
1182 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1183
1184 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1185 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1186 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1187 {
1188 LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1189
1190 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1191 &wLen);
1192 if (ret)
1193 {
1194 /* Windows crashes if cchName is NULL, so will I */
1195 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1196 *cchName, NULL, NULL);
1197
1198 if (len == 0)
1199 {
1200 /* WideCharToMultiByte failed */
1201 ret = FALSE;
1202 }
1203 else if (len > *cchName)
1204 {
1205 *cchName = len;
1206 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1207 ret = FALSE;
1208 }
1209 else
1210 {
1211 /* WideCharToMultiByte succeeded, output length needs to be
1212 * length not including NULL terminator
1213 */
1214 *cchName = len - 1;
1215 }
1216 }
1217 HeapFree(GetProcessHeap(), 0, lpNameW);
1218 }
1219 RtlFreeUnicodeString(&lpSystemNameW);
1220 return ret;
1221 }
1222
1223 /******************************************************************************
1224 * GetFileSecurityA [ADVAPI32.@]
1225 *
1226 * Obtains Specified information about the security of a file or directory.
1227 *
1228 * PARAMS
1229 * lpFileName [I] Name of the file to get info for
1230 * RequestedInformation [I] SE_ flags from "winnt.h"
1231 * pSecurityDescriptor [O] Destination for security information
1232 * nLength [I] Length of pSecurityDescriptor
1233 * lpnLengthNeeded [O] Destination for length of returned security information
1234 *
1235 * RETURNS
1236 * Success: TRUE. pSecurityDescriptor contains the requested information.
1237 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
1238 *
1239 * NOTES
1240 * The information returned is constrained by the callers access rights and
1241 * privileges.
1242 *
1243 * @implemented
1244 */
1245 BOOL
1246 WINAPI
1247 GetFileSecurityA(LPCSTR lpFileName,
1248 SECURITY_INFORMATION RequestedInformation,
1249 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1250 DWORD nLength,
1251 LPDWORD lpnLengthNeeded)
1252 {
1253 UNICODE_STRING FileName;
1254 BOOL bResult;
1255
1256 if (!RtlCreateUnicodeStringFromAsciiz(&FileName, lpFileName))
1257 {
1258 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1259 return FALSE;
1260 }
1261
1262 bResult = GetFileSecurityW(FileName.Buffer,
1263 RequestedInformation,
1264 pSecurityDescriptor,
1265 nLength,
1266 lpnLengthNeeded);
1267
1268 RtlFreeUnicodeString(&FileName);
1269
1270 return bResult;
1271 }
1272
1273 /*
1274 * @implemented
1275 */
1276 BOOL
1277 WINAPI
1278 GetFileSecurityW(LPCWSTR lpFileName,
1279 SECURITY_INFORMATION RequestedInformation,
1280 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1281 DWORD nLength,
1282 LPDWORD lpnLengthNeeded)
1283 {
1284 OBJECT_ATTRIBUTES ObjectAttributes;
1285 IO_STATUS_BLOCK StatusBlock;
1286 UNICODE_STRING FileName;
1287 ULONG AccessMask = 0;
1288 HANDLE FileHandle;
1289 NTSTATUS Status;
1290
1291 TRACE("GetFileSecurityW() called\n");
1292
1293 QuerySecurityAccessMask(RequestedInformation, &AccessMask);
1294
1295 if (!RtlDosPathNameToNtPathName_U(lpFileName,
1296 &FileName,
1297 NULL,
1298 NULL))
1299 {
1300 ERR("Invalid path\n");
1301 SetLastError(ERROR_INVALID_NAME);
1302 return FALSE;
1303 }
1304
1305 InitializeObjectAttributes(&ObjectAttributes,
1306 &FileName,
1307 OBJ_CASE_INSENSITIVE,
1308 NULL,
1309 NULL);
1310
1311 Status = NtOpenFile(&FileHandle,
1312 AccessMask,
1313 &ObjectAttributes,
1314 &StatusBlock,
1315 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
1316 0);
1317
1318 RtlFreeHeap(RtlGetProcessHeap(),
1319 0,
1320 FileName.Buffer);
1321
1322 if (!NT_SUCCESS(Status))
1323 {
1324 ERR("NtOpenFile() failed (Status %lx)\n", Status);
1325 SetLastError(RtlNtStatusToDosError(Status));
1326 return FALSE;
1327 }
1328
1329 Status = NtQuerySecurityObject(FileHandle,
1330 RequestedInformation,
1331 pSecurityDescriptor,
1332 nLength,
1333 lpnLengthNeeded);
1334 NtClose(FileHandle);
1335 if (!NT_SUCCESS(Status))
1336 {
1337 ERR("NtQuerySecurityObject() failed (Status %lx)\n", Status);
1338 SetLastError(RtlNtStatusToDosError(Status));
1339 return FALSE;
1340 }
1341
1342 return TRUE;
1343 }
1344
1345 /******************************************************************************
1346 * SetFileSecurityA [ADVAPI32.@]
1347 * Sets the security of a file or directory
1348 *
1349 * @implemented
1350 */
1351 BOOL
1352 WINAPI
1353 SetFileSecurityA(LPCSTR lpFileName,
1354 SECURITY_INFORMATION SecurityInformation,
1355 PSECURITY_DESCRIPTOR pSecurityDescriptor)
1356 {
1357 UNICODE_STRING FileName;
1358 BOOL bResult;
1359
1360 if (!RtlCreateUnicodeStringFromAsciiz(&FileName, lpFileName))
1361 {
1362 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1363 return FALSE;
1364 }
1365
1366 bResult = SetFileSecurityW(FileName.Buffer,
1367 SecurityInformation,
1368 pSecurityDescriptor);
1369
1370 RtlFreeUnicodeString(&FileName);
1371
1372 return bResult;
1373 }
1374
1375 /******************************************************************************
1376 * SetFileSecurityW [ADVAPI32.@]
1377 * Sets the security of a file or directory
1378 *
1379 * @implemented
1380 */
1381 BOOL
1382 WINAPI
1383 SetFileSecurityW(LPCWSTR lpFileName,
1384 SECURITY_INFORMATION SecurityInformation,
1385 PSECURITY_DESCRIPTOR pSecurityDescriptor)
1386 {
1387 OBJECT_ATTRIBUTES ObjectAttributes;
1388 IO_STATUS_BLOCK StatusBlock;
1389 UNICODE_STRING FileName;
1390 ULONG AccessMask = 0;
1391 HANDLE FileHandle;
1392 NTSTATUS Status;
1393
1394 TRACE("SetFileSecurityW() called\n");
1395
1396 SetSecurityAccessMask(SecurityInformation, &AccessMask);
1397
1398 if (!RtlDosPathNameToNtPathName_U(lpFileName,
1399 &FileName,
1400 NULL,
1401 NULL))
1402 {
1403 ERR("Invalid path\n");
1404 SetLastError(ERROR_INVALID_NAME);
1405 return FALSE;
1406 }
1407
1408 InitializeObjectAttributes(&ObjectAttributes,
1409 &FileName,
1410 OBJ_CASE_INSENSITIVE,
1411 NULL,
1412 NULL);
1413
1414 Status = NtOpenFile(&FileHandle,
1415 AccessMask,
1416 &ObjectAttributes,
1417 &StatusBlock,
1418 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
1419 0);
1420
1421 RtlFreeHeap(RtlGetProcessHeap(),
1422 0,
1423 FileName.Buffer);
1424
1425 if (!NT_SUCCESS(Status))
1426 {
1427 ERR("NtOpenFile() failed (Status %lx)\n", Status);
1428 SetLastError(RtlNtStatusToDosError(Status));
1429 return FALSE;
1430 }
1431
1432 Status = NtSetSecurityObject(FileHandle,
1433 SecurityInformation,
1434 pSecurityDescriptor);
1435 NtClose(FileHandle);
1436
1437 if (!NT_SUCCESS(Status))
1438 {
1439 ERR("NtSetSecurityObject() failed (Status %lx)\n", Status);
1440 SetLastError(RtlNtStatusToDosError(Status));
1441 return FALSE;
1442 }
1443
1444 return TRUE;
1445 }
1446
1447 /******************************************************************************
1448 * QueryWindows31FilesMigration [ADVAPI32.@]
1449 *
1450 * PARAMS
1451 * x1 []
1452 */
1453 BOOL WINAPI
1454 QueryWindows31FilesMigration( DWORD x1 )
1455 {
1456 FIXME("(%d):stub\n",x1);
1457 return TRUE;
1458 }
1459
1460 /******************************************************************************
1461 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
1462 *
1463 * PARAMS
1464 * x1 []
1465 * x2 []
1466 * x3 []
1467 * x4 []
1468 */
1469 BOOL WINAPI
1470 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
1471 DWORD x4 )
1472 {
1473 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
1474 return TRUE;
1475 }
1476
1477 /*
1478 * @implemented
1479 */
1480 BOOL
1481 WINAPI
1482 RevertToSelf(VOID)
1483 {
1484 NTSTATUS Status;
1485 HANDLE Token = NULL;
1486
1487 Status = NtSetInformationThread(NtCurrentThread(),
1488 ThreadImpersonationToken,
1489 &Token,
1490 sizeof(HANDLE));
1491 if (!NT_SUCCESS(Status))
1492 {
1493 SetLastError(RtlNtStatusToDosError(Status));
1494 return FALSE;
1495 }
1496
1497 return TRUE;
1498 }
1499
1500 /*
1501 * @implemented
1502 */
1503 BOOL
1504 WINAPI
1505 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
1506 {
1507 NTSTATUS Status;
1508
1509 Status = RtlImpersonateSelf(ImpersonationLevel);
1510 if (!NT_SUCCESS(Status))
1511 {
1512 SetLastError(RtlNtStatusToDosError(Status));
1513 return FALSE;
1514 }
1515
1516 return TRUE;
1517 }
1518
1519 /*
1520 * @implemented
1521 */
1522 BOOL
1523 WINAPI
1524 AccessCheck(IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1525 IN HANDLE ClientToken,
1526 IN DWORD DesiredAccess,
1527 IN PGENERIC_MAPPING GenericMapping,
1528 OUT PPRIVILEGE_SET PrivilegeSet OPTIONAL,
1529 IN OUT LPDWORD PrivilegeSetLength,
1530 OUT LPDWORD GrantedAccess,
1531 OUT LPBOOL AccessStatus)
1532 {
1533 NTSTATUS Status;
1534 NTSTATUS NtAccessStatus;
1535
1536 /* Do the access check */
1537 Status = NtAccessCheck(pSecurityDescriptor,
1538 ClientToken,
1539 DesiredAccess,
1540 GenericMapping,
1541 PrivilegeSet,
1542 (PULONG)PrivilegeSetLength,
1543 (PACCESS_MASK)GrantedAccess,
1544 &NtAccessStatus);
1545
1546 /* See if the access check operation succeeded */
1547 if (!NT_SUCCESS(Status))
1548 {
1549 /* Check failed */
1550 SetLastError(RtlNtStatusToDosError(Status));
1551 return FALSE;
1552 }
1553
1554 /* Now check the access status */
1555 if (!NT_SUCCESS(NtAccessStatus))
1556 {
1557 /* Access denied */
1558 SetLastError(RtlNtStatusToDosError(NtAccessStatus));
1559 *AccessStatus = FALSE;
1560 }
1561 else
1562 {
1563 /* Access granted */
1564 *AccessStatus = TRUE;
1565 }
1566
1567 /* Check succeeded */
1568 return TRUE;
1569 }
1570
1571 /*
1572 * @unimplemented
1573 */
1574 BOOL WINAPI AccessCheckByType(
1575 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1576 PSID PrincipalSelfSid,
1577 HANDLE ClientToken,
1578 DWORD DesiredAccess,
1579 POBJECT_TYPE_LIST ObjectTypeList,
1580 DWORD ObjectTypeListLength,
1581 PGENERIC_MAPPING GenericMapping,
1582 PPRIVILEGE_SET PrivilegeSet,
1583 LPDWORD PrivilegeSetLength,
1584 LPDWORD GrantedAccess,
1585 LPBOOL AccessStatus)
1586 {
1587 FIXME("stub\n");
1588
1589 *AccessStatus = TRUE;
1590
1591 return !*AccessStatus;
1592 }
1593
1594 /*
1595 * @implemented
1596 */
1597 BOOL
1598 WINAPI
1599 SetKernelObjectSecurity(HANDLE Handle,
1600 SECURITY_INFORMATION SecurityInformation,
1601 PSECURITY_DESCRIPTOR SecurityDescriptor)
1602 {
1603 NTSTATUS Status;
1604
1605 Status = NtSetSecurityObject(Handle,
1606 SecurityInformation,
1607 SecurityDescriptor);
1608 if (!NT_SUCCESS(Status))
1609 {
1610 SetLastError(RtlNtStatusToDosError(Status));
1611 return FALSE;
1612 }
1613
1614 return TRUE;
1615 }
1616
1617 /*
1618 * @implemented
1619 */
1620 BOOL
1621 WINAPI
1622 AddAuditAccessAce(PACL pAcl,
1623 DWORD dwAceRevision,
1624 DWORD dwAccessMask,
1625 PSID pSid,
1626 BOOL bAuditSuccess,
1627 BOOL bAuditFailure)
1628 {
1629 NTSTATUS Status;
1630
1631 Status = RtlAddAuditAccessAce(pAcl,
1632 dwAceRevision,
1633 dwAccessMask,
1634 pSid,
1635 bAuditSuccess,
1636 bAuditFailure);
1637 if (!NT_SUCCESS(Status))
1638 {
1639 SetLastError(RtlNtStatusToDosError(Status));
1640 return FALSE;
1641 }
1642
1643 return TRUE;
1644 }
1645
1646 /*
1647 * @implemented
1648 */
1649 BOOL WINAPI
1650 AddAuditAccessAceEx(PACL pAcl,
1651 DWORD dwAceRevision,
1652 DWORD AceFlags,
1653 DWORD dwAccessMask,
1654 PSID pSid,
1655 BOOL bAuditSuccess,
1656 BOOL bAuditFailure)
1657 {
1658 NTSTATUS Status;
1659
1660 Status = RtlAddAuditAccessAceEx(pAcl,
1661 dwAceRevision,
1662 AceFlags,
1663 dwAccessMask,
1664 pSid,
1665 bAuditSuccess,
1666 bAuditFailure);
1667 if (!NT_SUCCESS(Status))
1668 {
1669 SetLastError(RtlNtStatusToDosError(Status));
1670 return FALSE;
1671 }
1672
1673 return TRUE;
1674 }
1675
1676 /******************************************************************************
1677 * LookupAccountNameA [ADVAPI32.@]
1678 *
1679 * @implemented
1680 */
1681 BOOL
1682 WINAPI
1683 LookupAccountNameA(LPCSTR SystemName,
1684 LPCSTR AccountName,
1685 PSID Sid,
1686 LPDWORD SidLength,
1687 LPSTR ReferencedDomainName,
1688 LPDWORD hReferencedDomainNameLength,
1689 PSID_NAME_USE SidNameUse)
1690 {
1691 BOOL ret;
1692 UNICODE_STRING lpSystemW;
1693 UNICODE_STRING lpAccountW;
1694 LPWSTR lpReferencedDomainNameW = NULL;
1695
1696 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, SystemName);
1697 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, AccountName);
1698
1699 if (ReferencedDomainName)
1700 lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(),
1701 0,
1702 *hReferencedDomainNameLength * sizeof(WCHAR));
1703
1704 ret = LookupAccountNameW(lpSystemW.Buffer,
1705 lpAccountW.Buffer,
1706 Sid,
1707 SidLength,
1708 lpReferencedDomainNameW,
1709 hReferencedDomainNameLength,
1710 SidNameUse);
1711
1712 if (ret && lpReferencedDomainNameW)
1713 {
1714 WideCharToMultiByte(CP_ACP,
1715 0,
1716 lpReferencedDomainNameW,
1717 *hReferencedDomainNameLength + 1,
1718 ReferencedDomainName,
1719 *hReferencedDomainNameLength + 1,
1720 NULL,
1721 NULL);
1722 }
1723
1724 RtlFreeUnicodeString(&lpSystemW);
1725 RtlFreeUnicodeString(&lpAccountW);
1726 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
1727
1728 return ret;
1729 }
1730
1731 /**********************************************************************
1732 * PrivilegeCheck EXPORTED
1733 *
1734 * @implemented
1735 */
1736 BOOL WINAPI
1737 PrivilegeCheck(HANDLE ClientToken,
1738 PPRIVILEGE_SET RequiredPrivileges,
1739 LPBOOL pfResult)
1740 {
1741 BOOLEAN Result;
1742 NTSTATUS Status;
1743
1744 Status = NtPrivilegeCheck(ClientToken,
1745 RequiredPrivileges,
1746 &Result);
1747 if (!NT_SUCCESS(Status))
1748 {
1749 SetLastError(RtlNtStatusToDosError(Status));
1750 return FALSE;
1751 }
1752
1753 *pfResult = (BOOL)Result;
1754
1755 return TRUE;
1756 }
1757
1758 /******************************************************************************
1759 * GetSecurityInfoExW EXPORTED
1760 */
1761 DWORD
1762 WINAPI
1763 GetSecurityInfoExA(HANDLE hObject,
1764 SE_OBJECT_TYPE ObjectType,
1765 SECURITY_INFORMATION SecurityInfo,
1766 LPCSTR lpProvider,
1767 LPCSTR lpProperty,
1768 PACTRL_ACCESSA *ppAccessList,
1769 PACTRL_AUDITA *ppAuditList,
1770 LPSTR *lppOwner,
1771 LPSTR *lppGroup)
1772 {
1773 FIXME("%s() not implemented!\n", __FUNCTION__);
1774 return ERROR_BAD_PROVIDER;
1775 }
1776
1777
1778 /******************************************************************************
1779 * GetSecurityInfoExW EXPORTED
1780 */
1781 DWORD
1782 WINAPI
1783 GetSecurityInfoExW(HANDLE hObject,
1784 SE_OBJECT_TYPE ObjectType,
1785 SECURITY_INFORMATION SecurityInfo,
1786 LPCWSTR lpProvider,
1787 LPCWSTR lpProperty,
1788 PACTRL_ACCESSW *ppAccessList,
1789 PACTRL_AUDITW *ppAuditList,
1790 LPWSTR *lppOwner,
1791 LPWSTR *lppGroup)
1792 {
1793 FIXME("%s() not implemented!\n", __FUNCTION__);
1794 return ERROR_BAD_PROVIDER;
1795 }
1796
1797 /******************************************************************************
1798 * BuildExplicitAccessWithNameA [ADVAPI32.@]
1799 */
1800 VOID WINAPI
1801 BuildExplicitAccessWithNameA(PEXPLICIT_ACCESSA pExplicitAccess,
1802 LPSTR pTrusteeName,
1803 DWORD AccessPermissions,
1804 ACCESS_MODE AccessMode,
1805 DWORD Inheritance)
1806 {
1807 pExplicitAccess->grfAccessPermissions = AccessPermissions;
1808 pExplicitAccess->grfAccessMode = AccessMode;
1809 pExplicitAccess->grfInheritance = Inheritance;
1810
1811 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
1812 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
1813 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
1814 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
1815 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
1816 }
1817
1818
1819 /******************************************************************************
1820 * BuildExplicitAccessWithNameW [ADVAPI32.@]
1821 */
1822 VOID WINAPI
1823 BuildExplicitAccessWithNameW(PEXPLICIT_ACCESSW pExplicitAccess,
1824 LPWSTR pTrusteeName,
1825 DWORD AccessPermissions,
1826 ACCESS_MODE AccessMode,
1827 DWORD Inheritance)
1828 {
1829 pExplicitAccess->grfAccessPermissions = AccessPermissions;
1830 pExplicitAccess->grfAccessMode = AccessMode;
1831 pExplicitAccess->grfInheritance = Inheritance;
1832
1833 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
1834 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
1835 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
1836 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
1837 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
1838 }
1839
1840 /******************************************************************************
1841 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
1842 */
1843 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
1844 SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
1845 LPSTR InheritedObjectTypeName, LPSTR Name )
1846 {
1847 DWORD ObjectsPresent = 0;
1848
1849 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
1850 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
1851
1852 /* Fill the OBJECTS_AND_NAME structure */
1853 pObjName->ObjectType = ObjectType;
1854 if (ObjectTypeName != NULL)
1855 {
1856 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
1857 }
1858
1859 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
1860 if (InheritedObjectTypeName != NULL)
1861 {
1862 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
1863 }
1864
1865 pObjName->ObjectsPresent = ObjectsPresent;
1866 pObjName->ptstrName = Name;
1867
1868 /* Fill the TRUSTEE structure */
1869 pTrustee->pMultipleTrustee = NULL;
1870 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
1871 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
1872 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
1873 pTrustee->ptstrName = (LPSTR)pObjName;
1874 }
1875
1876 /******************************************************************************
1877 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
1878 */
1879 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
1880 SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
1881 LPWSTR InheritedObjectTypeName, LPWSTR Name )
1882 {
1883 DWORD ObjectsPresent = 0;
1884
1885 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
1886 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
1887
1888 /* Fill the OBJECTS_AND_NAME structure */
1889 pObjName->ObjectType = ObjectType;
1890 if (ObjectTypeName != NULL)
1891 {
1892 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
1893 }
1894
1895 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
1896 if (InheritedObjectTypeName != NULL)
1897 {
1898 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
1899 }
1900
1901 pObjName->ObjectsPresent = ObjectsPresent;
1902 pObjName->ptstrName = Name;
1903
1904 /* Fill the TRUSTEE structure */
1905 pTrustee->pMultipleTrustee = NULL;
1906 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
1907 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
1908 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
1909 pTrustee->ptstrName = (LPWSTR)pObjName;
1910 }
1911
1912 /******************************************************************************
1913 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
1914 */
1915 VOID WINAPI
1916 BuildTrusteeWithObjectsAndSidA(PTRUSTEEA pTrustee,
1917 POBJECTS_AND_SID pObjSid,
1918 GUID *pObjectGuid,
1919 GUID *pInheritedObjectGuid,
1920 PSID pSid)
1921 {
1922 DWORD ObjectsPresent = 0;
1923
1924 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
1925
1926 /* Fill the OBJECTS_AND_SID structure */
1927 if (pObjectGuid != NULL)
1928 {
1929 pObjSid->ObjectTypeGuid = *pObjectGuid;
1930 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
1931 }
1932 else
1933 {
1934 ZeroMemory(&pObjSid->ObjectTypeGuid,
1935 sizeof(GUID));
1936 }
1937
1938 if (pInheritedObjectGuid != NULL)
1939 {
1940 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
1941 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
1942 }
1943 else
1944 {
1945 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
1946 sizeof(GUID));
1947 }
1948
1949 pObjSid->ObjectsPresent = ObjectsPresent;
1950 pObjSid->pSid = pSid;
1951
1952 /* Fill the TRUSTEE structure */
1953 pTrustee->pMultipleTrustee = NULL;
1954 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
1955 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
1956 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
1957 pTrustee->ptstrName = (LPSTR) pObjSid;
1958 }
1959
1960
1961 /******************************************************************************
1962 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
1963 */
1964 VOID WINAPI
1965 BuildTrusteeWithObjectsAndSidW(PTRUSTEEW pTrustee,
1966 POBJECTS_AND_SID pObjSid,
1967 GUID *pObjectGuid,
1968 GUID *pInheritedObjectGuid,
1969 PSID pSid)
1970 {
1971 DWORD ObjectsPresent = 0;
1972
1973 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
1974
1975 /* Fill the OBJECTS_AND_SID structure */
1976 if (pObjectGuid != NULL)
1977 {
1978 pObjSid->ObjectTypeGuid = *pObjectGuid;
1979 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
1980 }
1981 else
1982 {
1983 ZeroMemory(&pObjSid->ObjectTypeGuid,
1984 sizeof(GUID));
1985 }
1986
1987 if (pInheritedObjectGuid != NULL)
1988 {
1989 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
1990 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
1991 }
1992 else
1993 {
1994 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
1995 sizeof(GUID));
1996 }
1997
1998 pObjSid->ObjectsPresent = ObjectsPresent;
1999 pObjSid->pSid = pSid;
2000
2001 /* Fill the TRUSTEE structure */
2002 pTrustee->pMultipleTrustee = NULL;
2003 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2004 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
2005 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2006 pTrustee->ptstrName = (LPWSTR) pObjSid;
2007 }
2008
2009 /******************************************************************************
2010 * BuildTrusteeWithSidA [ADVAPI32.@]
2011 */
2012 VOID WINAPI
2013 BuildTrusteeWithSidA(PTRUSTEE_A pTrustee,
2014 PSID pSid)
2015 {
2016 TRACE("%p %p\n", pTrustee, pSid);
2017
2018 pTrustee->pMultipleTrustee = NULL;
2019 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2020 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
2021 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2022 pTrustee->ptstrName = (LPSTR) pSid;
2023 }
2024
2025
2026 /******************************************************************************
2027 * BuildTrusteeWithSidW [ADVAPI32.@]
2028 */
2029 VOID WINAPI
2030 BuildTrusteeWithSidW(PTRUSTEE_W pTrustee,
2031 PSID pSid)
2032 {
2033 TRACE("%p %p\n", pTrustee, pSid);
2034
2035 pTrustee->pMultipleTrustee = NULL;
2036 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2037 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
2038 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2039 pTrustee->ptstrName = (LPWSTR) pSid;
2040 }
2041
2042 /******************************************************************************
2043 * BuildTrusteeWithNameA [ADVAPI32.@]
2044 */
2045 VOID WINAPI
2046 BuildTrusteeWithNameA(PTRUSTEE_A pTrustee,
2047 LPSTR name)
2048 {
2049 TRACE("%p %s\n", pTrustee, name);
2050
2051 pTrustee->pMultipleTrustee = NULL;
2052 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2053 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
2054 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2055 pTrustee->ptstrName = name;
2056 }
2057
2058 /******************************************************************************
2059 * BuildTrusteeWithNameW [ADVAPI32.@]
2060 */
2061 VOID WINAPI
2062 BuildTrusteeWithNameW(PTRUSTEE_W pTrustee,
2063 LPWSTR name)
2064 {
2065 TRACE("%p %s\n", pTrustee, name);
2066
2067 pTrustee->pMultipleTrustee = NULL;
2068 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2069 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
2070 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2071 pTrustee->ptstrName = name;
2072 }
2073
2074 /******************************************************************************
2075 * GetTrusteeFormA [ADVAPI32.@]
2076 */
2077 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee)
2078 {
2079 TRACE("(%p)\n", pTrustee);
2080
2081 if (!pTrustee)
2082 return TRUSTEE_BAD_FORM;
2083
2084 return pTrustee->TrusteeForm;
2085 }
2086
2087 /******************************************************************************
2088 * GetTrusteeFormW [ADVAPI32.@]
2089 */
2090 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee)
2091 {
2092 TRACE("(%p)\n", pTrustee);
2093
2094 if (!pTrustee)
2095 return TRUSTEE_BAD_FORM;
2096
2097 return pTrustee->TrusteeForm;
2098 }
2099
2100 /******************************************************************************
2101 * GetTrusteeNameA [ADVAPI32.@]
2102 */
2103 LPSTR WINAPI
2104 GetTrusteeNameA(PTRUSTEE_A pTrustee)
2105 {
2106 return pTrustee->ptstrName;
2107 }
2108
2109
2110 /******************************************************************************
2111 * GetTrusteeNameW [ADVAPI32.@]
2112 */
2113 LPWSTR WINAPI
2114 GetTrusteeNameW(PTRUSTEE_W pTrustee)
2115 {
2116 return pTrustee->ptstrName;
2117 }
2118
2119 /******************************************************************************
2120 * GetTrusteeTypeA [ADVAPI32.@]
2121 */
2122 TRUSTEE_TYPE WINAPI
2123 GetTrusteeTypeA(PTRUSTEE_A pTrustee)
2124 {
2125 return pTrustee->TrusteeType;
2126 }
2127
2128 /******************************************************************************
2129 * GetTrusteeTypeW [ADVAPI32.@]
2130 */
2131 TRUSTEE_TYPE WINAPI
2132 GetTrusteeTypeW(PTRUSTEE_W pTrustee)
2133 {
2134 return pTrustee->TrusteeType;
2135 }
2136
2137 /*
2138 * @implemented
2139 */
2140 BOOL
2141 WINAPI
2142 SetAclInformation(PACL pAcl,
2143 LPVOID pAclInformation,
2144 DWORD nAclInformationLength,
2145 ACL_INFORMATION_CLASS dwAclInformationClass)
2146 {
2147 NTSTATUS Status;
2148
2149 Status = RtlSetInformationAcl(pAcl,
2150 pAclInformation,
2151 nAclInformationLength,
2152 dwAclInformationClass);
2153 if (!NT_SUCCESS(Status))
2154 {
2155 SetLastError(RtlNtStatusToDosError(Status));
2156 return FALSE;
2157 }
2158
2159 return TRUE;
2160 }
2161
2162 /**********************************************************************
2163 * SetNamedSecurityInfoA EXPORTED
2164 *
2165 * @implemented
2166 */
2167 DWORD
2168 WINAPI
2169 SetNamedSecurityInfoA(LPSTR pObjectName,
2170 SE_OBJECT_TYPE ObjectType,
2171 SECURITY_INFORMATION SecurityInfo,
2172 PSID psidOwner,
2173 PSID psidGroup,
2174 PACL pDacl,
2175 PACL pSacl)
2176 {
2177 UNICODE_STRING ObjectName;
2178 DWORD Ret;
2179
2180 if (!RtlCreateUnicodeStringFromAsciiz(&ObjectName, pObjectName))
2181 {
2182 return ERROR_NOT_ENOUGH_MEMORY;
2183 }
2184
2185 Ret = SetNamedSecurityInfoW(ObjectName.Buffer,
2186 ObjectType,
2187 SecurityInfo,
2188 psidOwner,
2189 psidGroup,
2190 pDacl,
2191 pSacl);
2192
2193 RtlFreeUnicodeString(&ObjectName);
2194
2195 return Ret;
2196 }
2197
2198 /*
2199 * @implemented
2200 */
2201 BOOL
2202 WINAPI
2203 AreAllAccessesGranted(DWORD GrantedAccess,
2204 DWORD DesiredAccess)
2205 {
2206 return (BOOL)RtlAreAllAccessesGranted(GrantedAccess,
2207 DesiredAccess);
2208 }
2209
2210 /*
2211 * @implemented
2212 */
2213 BOOL
2214 WINAPI
2215 AreAnyAccessesGranted(DWORD GrantedAccess,
2216 DWORD DesiredAccess)
2217 {
2218 return (BOOL)RtlAreAnyAccessesGranted(GrantedAccess,
2219 DesiredAccess);
2220 }
2221
2222 /******************************************************************************
2223 * ParseAclStringFlags
2224 */
2225 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
2226 {
2227 DWORD flags = 0;
2228 LPCWSTR szAcl = *StringAcl;
2229
2230 while (*szAcl != '(')
2231 {
2232 if (*szAcl == 'P')
2233 {
2234 flags |= SE_DACL_PROTECTED;
2235 }
2236 else if (*szAcl == 'A')
2237 {
2238 szAcl++;
2239 if (*szAcl == 'R')
2240 flags |= SE_DACL_AUTO_INHERIT_REQ;
2241 else if (*szAcl == 'I')
2242 flags |= SE_DACL_AUTO_INHERITED;
2243 }
2244 szAcl++;
2245 }
2246
2247 *StringAcl = szAcl;
2248 return flags;
2249 }
2250
2251 /******************************************************************************
2252 * ParseAceStringType
2253 */
2254 static const ACEFLAG AceType[] =
2255 {
2256 { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
2257 { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
2258 { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
2259 { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
2260 { SDDL_MANDATORY_LABEL,SYSTEM_MANDATORY_LABEL_ACE_TYPE },
2261 /*
2262 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
2263 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
2264 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
2265 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
2266 */
2267 { NULL, 0 },
2268 };
2269
2270 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
2271 {
2272 UINT len = 0;
2273 LPCWSTR szAcl = *StringAcl;
2274 const ACEFLAG *lpaf = AceType;
2275
2276 while (*szAcl == ' ')
2277 szAcl++;
2278
2279 while (lpaf->wstr &&
2280 (len = strlenW(lpaf->wstr)) &&
2281 strncmpW(lpaf->wstr, szAcl, len))
2282 lpaf++;
2283
2284 if (!lpaf->wstr)
2285 return 0;
2286
2287 *StringAcl = szAcl + len;
2288 return lpaf->value;
2289 }
2290
2291
2292 /******************************************************************************
2293 * ParseAceStringFlags
2294 */
2295 static const ACEFLAG AceFlags[] =
2296 {
2297 { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
2298 { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
2299 { SDDL_INHERITED, INHERITED_ACE },
2300 { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
2301 { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
2302 { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
2303 { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
2304 { NULL, 0 },
2305 };
2306
2307 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
2308 {
2309 UINT len = 0;
2310 BYTE flags = 0;
2311 LPCWSTR szAcl = *StringAcl;
2312
2313 while (*szAcl == ' ')
2314 szAcl++;
2315
2316 while (*szAcl != ';')
2317 {
2318 const ACEFLAG *lpaf = AceFlags;
2319
2320 while (lpaf->wstr &&
2321 (len = strlenW(lpaf->wstr)) &&
2322 strncmpW(lpaf->wstr, szAcl, len))
2323 lpaf++;
2324
2325 if (!lpaf->wstr)
2326 return 0;
2327
2328 flags |= lpaf->value;
2329 szAcl += len;
2330 }
2331
2332 *StringAcl = szAcl;
2333 return flags;
2334 }
2335
2336
2337 /******************************************************************************
2338 * ParseAceStringRights
2339 */
2340 static const ACEFLAG AceRights[] =
2341 {
2342 { SDDL_GENERIC_ALL, GENERIC_ALL },
2343 { SDDL_GENERIC_READ, GENERIC_READ },
2344 { SDDL_GENERIC_WRITE, GENERIC_WRITE },
2345 { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
2346
2347 { SDDL_READ_CONTROL, READ_CONTROL },
2348 { SDDL_STANDARD_DELETE, DELETE },
2349 { SDDL_WRITE_DAC, WRITE_DAC },
2350 { SDDL_WRITE_OWNER, WRITE_OWNER },
2351
2352 { SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP},
2353 { SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP},
2354 { SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD},
2355 { SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD},
2356 { SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST},
2357 { SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF},
2358 { SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT},
2359 { SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE},
2360 { SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS},
2361
2362 { SDDL_FILE_ALL, FILE_ALL_ACCESS },
2363 { SDDL_FILE_READ, FILE_GENERIC_READ },
2364 { SDDL_FILE_WRITE, FILE_GENERIC_WRITE },
2365 { SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE },
2366
2367 { SDDL_KEY_ALL, KEY_ALL_ACCESS },
2368 { SDDL_KEY_READ, KEY_READ },
2369 { SDDL_KEY_WRITE, KEY_WRITE },
2370 { SDDL_KEY_EXECUTE, KEY_EXECUTE },
2371
2372 { SDDL_NO_READ_UP, SYSTEM_MANDATORY_LABEL_NO_READ_UP },
2373 { SDDL_NO_WRITE_UP, SYSTEM_MANDATORY_LABEL_NO_WRITE_UP },
2374 { SDDL_NO_EXECUTE_UP, SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP },
2375 { NULL, 0 },
2376 };
2377
2378 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
2379 {
2380 UINT len = 0;
2381 DWORD rights = 0;
2382 LPCWSTR szAcl = *StringAcl;
2383
2384 while (*szAcl == ' ')
2385 szAcl++;
2386
2387 if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
2388 {
2389 LPCWSTR p = szAcl;
2390
2391 while (*p && *p != ';')
2392 p++;
2393
2394 if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
2395 {
2396 rights = strtoulW(szAcl, NULL, 16);
2397 szAcl = p;
2398 }
2399 else
2400 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
2401 }
2402 else
2403 {
2404 while (*szAcl != ';')
2405 {
2406 const ACEFLAG *lpaf = AceRights;
2407
2408 while (lpaf->wstr &&
2409 (len = strlenW(lpaf->wstr)) &&
2410 strncmpW(lpaf->wstr, szAcl, len))
2411 {
2412 lpaf++;
2413 }
2414
2415 if (!lpaf->wstr)
2416 return 0;
2417
2418 rights |= lpaf->value;
2419 szAcl += len;
2420 }
2421 }
2422
2423 *StringAcl = szAcl;
2424 return rights;
2425 }
2426
2427
2428 /******************************************************************************
2429 * ParseStringAclToAcl
2430 *
2431 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
2432 */
2433 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
2434 PACL pAcl, LPDWORD cBytes)
2435 {
2436 DWORD val;
2437 DWORD sidlen;
2438 DWORD length = sizeof(ACL);
2439 DWORD acesize = 0;
2440 DWORD acecount = 0;
2441 PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
2442 DWORD error = ERROR_INVALID_ACL;
2443
2444 TRACE("%s\n", debugstr_w(StringAcl));
2445
2446 if (!StringAcl)
2447 return FALSE;
2448
2449 if (pAcl) /* pAce is only useful if we're setting values */
2450 pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
2451
2452 /* Parse ACL flags */
2453 *lpdwFlags = ParseAclStringFlags(&StringAcl);
2454
2455 /* Parse ACE */
2456 while (*StringAcl == '(')
2457 {
2458 StringAcl++;
2459
2460 /* Parse ACE type */
2461 val = ParseAceStringType(&StringAcl);
2462 if (pAce)
2463 pAce->Header.AceType = (BYTE) val;
2464 if (*StringAcl != ';')
2465 {
2466 error = RPC_S_INVALID_STRING_UUID;
2467 goto lerr;
2468 }
2469 StringAcl++;
2470
2471 /* Parse ACE flags */
2472 val = ParseAceStringFlags(&StringAcl);
2473 if (pAce)
2474 pAce->Header.AceFlags = (BYTE) val;
2475 if (*StringAcl != ';')
2476 goto lerr;
2477 StringAcl++;
2478
2479 /* Parse ACE rights */
2480 val = ParseAceStringRights(&StringAcl);
2481 if (pAce)
2482 pAce->Mask = val;
2483 if (*StringAcl != ';')
2484 goto lerr;
2485 StringAcl++;
2486
2487 /* Parse ACE object guid */
2488 while (*StringAcl == ' ')
2489 StringAcl++;
2490 if (*StringAcl != ';')
2491 {
2492 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
2493 goto lerr;
2494 }
2495 StringAcl++;
2496
2497 /* Parse ACE inherit object guid */
2498 while (*StringAcl == ' ')
2499 StringAcl++;
2500 if (*StringAcl != ';')
2501 {
2502 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
2503 goto lerr;
2504 }
2505 StringAcl++;
2506
2507 /* Parse ACE account sid */
2508 if (ParseStringSidToSid(StringAcl, pAce ? &pAce->SidStart : NULL, &sidlen))
2509 {
2510 while (*StringAcl && *StringAcl != ')')
2511 StringAcl++;
2512 }
2513
2514 if (*StringAcl != ')')
2515 goto lerr;
2516 StringAcl++;
2517
2518 acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
2519 length += acesize;
2520 if (pAce)
2521 {
2522 pAce->Header.AceSize = acesize;
2523 pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
2524 }
2525 acecount++;
2526 }
2527
2528 *cBytes = length;
2529
2530 if (length > 0xffff)
2531 {
2532 ERR("ACL too large\n");
2533 goto lerr;
2534 }
2535
2536 if (pAcl)
2537 {
2538 pAcl->AclRevision = ACL_REVISION;
2539 pAcl->Sbz1 = 0;
2540 pAcl->AclSize = length;
2541 pAcl->AceCount = acecount++;
2542 pAcl->Sbz2 = 0;
2543 }
2544 return TRUE;
2545
2546 lerr:
2547 SetLastError(error);
2548 WARN("Invalid ACE string format\n");
2549 return FALSE;
2550 }
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);
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 {