Merge branch 'ntfs_rebase'
[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 {
3312 LPWSTR StringSidW;
3313 int Len;
3314
3315 if (!ConvertSidToStringSidW(Sid, &StringSidW))
3316 {
3317 return FALSE;
3318 }
3319
3320 Len = WideCharToMultiByte(CP_ACP, 0, StringSidW, -1, NULL, 0, NULL, NULL);
3321 if (Len <= 0)
3322 {
3323 LocalFree(StringSidW);
3324 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
3325 return FALSE;
3326 }
3327
3328 *StringSid = LocalAlloc(LMEM_FIXED, Len);
3329 if (NULL == *StringSid)
3330 {
3331 LocalFree(StringSidW);
3332 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
3333 return FALSE;
3334 }
3335
3336 if (!WideCharToMultiByte(CP_ACP, 0, StringSidW, -1, *StringSid, Len, NULL, NULL))
3337 {
3338 LocalFree(StringSid);
3339 LocalFree(StringSidW);
3340 return FALSE;
3341 }
3342
3343 LocalFree(StringSidW);
3344
3345 return TRUE;
3346 }
3347
3348 /*
3349 * @unimplemented
3350 */
3351 BOOL WINAPI
3352 CreateProcessWithLogonW(LPCWSTR lpUsername,
3353 LPCWSTR lpDomain,
3354 LPCWSTR lpPassword,
3355 DWORD dwLogonFlags,
3356 LPCWSTR lpApplicationName,
3357 LPWSTR lpCommandLine,
3358 DWORD dwCreationFlags,
3359 LPVOID lpEnvironment,
3360 LPCWSTR lpCurrentDirectory,
3361 LPSTARTUPINFOW lpStartupInfo,
3362 LPPROCESS_INFORMATION lpProcessInformation)
3363 {
3364 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername), debugstr_w(lpDomain),
3365 debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName),
3366 debugstr_w(lpCommandLine), dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory),
3367 lpStartupInfo, lpProcessInformation);
3368
3369 return FALSE;
3370 }
3371
3372 BOOL WINAPI CreateProcessWithTokenW(HANDLE token, DWORD logon_flags, LPCWSTR application_name, LPWSTR command_line,
3373 DWORD creation_flags, void *environment, LPCWSTR current_directory, STARTUPINFOW *startup_info,
3374 PROCESS_INFORMATION *process_information )
3375 {
3376 FIXME("%p 0x%08x %s %s 0x%08x %p %s %p %p - semi-stub\n", token,
3377 logon_flags, debugstr_w(application_name), debugstr_w(command_line),
3378 creation_flags, environment, debugstr_w(current_directory),
3379 startup_info, process_information);
3380
3381 /* FIXME: check if handles should be inherited */
3382 return CreateProcessW( application_name, command_line, NULL, NULL, FALSE, creation_flags, environment,
3383 current_directory, startup_info, process_information );
3384 }
3385
3386 /*
3387 * @implemented
3388 */
3389 BOOL WINAPI
3390 DuplicateTokenEx(IN HANDLE ExistingTokenHandle,
3391 IN DWORD dwDesiredAccess,
3392 IN LPSECURITY_ATTRIBUTES lpTokenAttributes OPTIONAL,
3393 IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
3394 IN TOKEN_TYPE TokenType,
3395 OUT PHANDLE DuplicateTokenHandle)
3396 {
3397 OBJECT_ATTRIBUTES ObjectAttributes;
3398 NTSTATUS Status;
3399 SECURITY_QUALITY_OF_SERVICE Sqos;
3400
3401 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
3402 ImpersonationLevel, TokenType, DuplicateTokenHandle);
3403
3404 Sqos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
3405 Sqos.ImpersonationLevel = ImpersonationLevel;
3406 Sqos.ContextTrackingMode = 0;
3407 Sqos.EffectiveOnly = FALSE;
3408
3409 if (lpTokenAttributes != NULL)
3410 {
3411 InitializeObjectAttributes(&ObjectAttributes,
3412 NULL,
3413 lpTokenAttributes->bInheritHandle ? OBJ_INHERIT : 0,
3414 NULL,
3415 lpTokenAttributes->lpSecurityDescriptor);
3416 }
3417 else
3418 {
3419 InitializeObjectAttributes(&ObjectAttributes,
3420 NULL,
3421 0,
3422 NULL,
3423 NULL);
3424 }
3425
3426 ObjectAttributes.SecurityQualityOfService = &Sqos;
3427
3428 Status = NtDuplicateToken(ExistingTokenHandle,
3429 dwDesiredAccess,
3430 &ObjectAttributes,
3431 FALSE,
3432 TokenType,
3433 DuplicateTokenHandle);
3434 if (!NT_SUCCESS(Status))
3435 {
3436 ERR("NtDuplicateToken failed: Status %08x\n", Status);
3437 SetLastError(RtlNtStatusToDosError(Status));
3438 return FALSE;
3439 }
3440
3441 TRACE("Returning token %p.\n", *DuplicateTokenHandle);
3442
3443 return TRUE;
3444 }
3445
3446 /*
3447 * @implemented
3448 */
3449 BOOL WINAPI
3450 DuplicateToken(IN HANDLE ExistingTokenHandle,
3451 IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
3452 OUT PHANDLE DuplicateTokenHandle)
3453 {
3454 return DuplicateTokenEx(ExistingTokenHandle,
3455 TOKEN_IMPERSONATE | TOKEN_QUERY,
3456 NULL,
3457 ImpersonationLevel,
3458 TokenImpersonation,
3459 DuplicateTokenHandle);
3460 }
3461
3462 /******************************************************************************
3463 * ComputeStringSidSize
3464 */
3465 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
3466 {
3467 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
3468 {
3469 int ctok = 0;
3470 while (*StringSid)
3471 {
3472 if (*StringSid == '-')
3473 ctok++;
3474 StringSid++;
3475 }
3476
3477 if (ctok >= 3)
3478 return GetSidLengthRequired(ctok - 2);
3479 }
3480 else /* String constant format - Only available in winxp and above */
3481 {
3482 unsigned int i;
3483
3484 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
3485 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
3486 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
3487
3488 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
3489 if (!strncmpW(WellKnownRids[i].wstr, StringSid, 2))
3490 {
3491 MAX_SID local;
3492 ADVAPI_GetComputerSid(&local);
3493 return GetSidLengthRequired(*GetSidSubAuthorityCount(&local) + 1);
3494 }
3495
3496 }
3497
3498 return GetSidLengthRequired(0);
3499 }
3500
3501 /******************************************************************************
3502 * ParseStringSidToSid
3503 */
3504 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
3505 {
3506 BOOL bret = FALSE;
3507 SID* pisid=pSid;
3508
3509 TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
3510 if (!StringSid)
3511 {
3512 SetLastError(ERROR_INVALID_PARAMETER);
3513 TRACE("StringSid is NULL, returning FALSE\n");
3514 return FALSE;
3515 }
3516
3517 while (*StringSid == ' ')
3518 StringSid++;
3519
3520 if (!*StringSid)
3521 goto lend; /* ERROR_INVALID_SID */
3522
3523 *cBytes = ComputeStringSidSize(StringSid);
3524 if (!pisid) /* Simply compute the size */
3525 {
3526 TRACE("only size requested, returning TRUE with %d\n", *cBytes);
3527 return TRUE;
3528 }
3529
3530 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
3531 {
3532 DWORD i = 0, identAuth;
3533 DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
3534
3535 StringSid += 2; /* Advance to Revision */
3536 pisid->Revision = atoiW(StringSid);
3537
3538 if (pisid->Revision != SDDL_REVISION)
3539 {
3540 TRACE("Revision %d is unknown\n", pisid->Revision);
3541 goto lend; /* ERROR_INVALID_SID */
3542 }
3543 if (csubauth == 0)
3544 {
3545 TRACE("SubAuthorityCount is 0\n");
3546 goto lend; /* ERROR_INVALID_SID */
3547 }
3548
3549 pisid->SubAuthorityCount = csubauth;
3550
3551 /* Advance to identifier authority */
3552 while (*StringSid && *StringSid != '-')
3553 StringSid++;
3554 if (*StringSid == '-')
3555 StringSid++;
3556
3557 /* MS' implementation can't handle values greater than 2^32 - 1, so
3558 * we don't either; assume most significant bytes are always 0
3559 */
3560 pisid->IdentifierAuthority.Value[0] = 0;
3561 pisid->IdentifierAuthority.Value[1] = 0;
3562 identAuth = atoiW(StringSid);
3563 pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
3564 pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
3565 pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
3566 pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
3567
3568 /* Advance to first sub authority */
3569 while (*StringSid && *StringSid != '-')
3570 StringSid++;
3571 if (*StringSid == '-')
3572 StringSid++;
3573
3574 while (*StringSid)
3575 {
3576 pisid->SubAuthority[i++] = atoiW(StringSid);
3577
3578 while (*StringSid && *StringSid != '-')
3579 StringSid++;
3580 if (*StringSid == '-')
3581 StringSid++;
3582 }
3583
3584 if (i != pisid->SubAuthorityCount)
3585 goto lend; /* ERROR_INVALID_SID */
3586
3587 bret = TRUE;
3588 }
3589 else /* String constant format - Only available in winxp and above */
3590 {
3591 unsigned int i;
3592 pisid->Revision = SDDL_REVISION;
3593
3594 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
3595 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
3596 {
3597 DWORD j;
3598 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
3599 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
3600 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
3601 pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
3602 bret = TRUE;
3603 }
3604
3605 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
3606 if (!strncmpW(WellKnownRids[i].wstr, StringSid, 2))
3607 {
3608 ADVAPI_GetComputerSid(pisid);
3609 pisid->SubAuthority[pisid->SubAuthorityCount] = WellKnownRids[i].Rid;
3610 pisid->SubAuthorityCount++;
3611 bret = TRUE;
3612 }
3613
3614 if (!bret)
3615 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
3616 }
3617
3618 lend:
3619 if (!bret)
3620 SetLastError(ERROR_INVALID_SID);
3621
3622 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
3623 return bret;
3624 }
3625
3626 /**********************************************************************
3627 * GetNamedSecurityInfoA EXPORTED
3628 *
3629 * @implemented
3630 */
3631 DWORD
3632 WINAPI
3633 GetNamedSecurityInfoA(LPSTR pObjectName,
3634 SE_OBJECT_TYPE ObjectType,
3635 SECURITY_INFORMATION SecurityInfo,
3636 PSID *ppsidOwner,
3637 PSID *ppsidGroup,
3638 PACL *ppDacl,
3639 PACL *ppSacl,
3640 PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
3641 {
3642 DWORD len;
3643 LPWSTR wstr = NULL;
3644 DWORD r;
3645
3646 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
3647 ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
3648
3649 if( pObjectName )
3650 {
3651 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
3652 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
3653 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
3654 }
3655
3656 r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
3657 ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
3658
3659 HeapFree( GetProcessHeap(), 0, wstr );
3660
3661 return r;
3662 }
3663
3664 /******************************************************************************
3665 * GetWindowsAccountDomainSid [ADVAPI32.@]
3666 */
3667 BOOL WINAPI GetWindowsAccountDomainSid( PSID sid, PSID domain_sid, DWORD *size )
3668 {
3669 SID_IDENTIFIER_AUTHORITY domain_ident = { SECURITY_NT_AUTHORITY };
3670 DWORD required_size;
3671 int i;
3672
3673 FIXME( "(%p %p %p): semi-stub\n", sid, domain_sid, size );
3674
3675 if (!sid || !IsValidSid( sid ))
3676 {
3677 SetLastError( ERROR_INVALID_SID );
3678 return FALSE;
3679 }
3680
3681 if (!size)
3682 {
3683 SetLastError( ERROR_INVALID_PARAMETER );
3684 return FALSE;
3685 }
3686
3687 if (*GetSidSubAuthorityCount( sid ) < 4)
3688 {
3689 SetLastError( ERROR_INVALID_SID );
3690 return FALSE;
3691 }
3692
3693 required_size = GetSidLengthRequired( 4 );
3694 if (*size < required_size || !domain_sid)
3695 {
3696 *size = required_size;
3697 SetLastError( domain_sid ? ERROR_INSUFFICIENT_BUFFER :
3698 ERROR_INVALID_PARAMETER );
3699 return FALSE;
3700 }
3701
3702 InitializeSid( domain_sid, &domain_ident, 4 );
3703 for (i = 0; i < 4; i++)
3704 *GetSidSubAuthority( domain_sid, i ) = *GetSidSubAuthority( sid, i );
3705
3706 *size = required_size;
3707 return TRUE;
3708 }
3709
3710 /*
3711 * @unimplemented
3712 */
3713 BOOL
3714 WINAPI
3715 EqualDomainSid(IN PSID pSid1,
3716 IN PSID pSid2,
3717 OUT BOOL* pfEqual)
3718 {
3719 UNIMPLEMENTED;
3720 return FALSE;
3721 }
3722
3723 /* EOF */