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