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