677e274734eb08fe839931c49b29de5c4978729a
[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 static const ACEFLAG AceRights[] =
230 {
231 { SDDL_GENERIC_ALL, GENERIC_ALL },
232 { SDDL_GENERIC_READ, GENERIC_READ },
233 { SDDL_GENERIC_WRITE, GENERIC_WRITE },
234 { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
235
236 { SDDL_READ_CONTROL, READ_CONTROL },
237 { SDDL_STANDARD_DELETE, DELETE },
238 { SDDL_WRITE_DAC, WRITE_DAC },
239 { SDDL_WRITE_OWNER, WRITE_OWNER },
240
241 { SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP},
242 { SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP},
243 { SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD},
244 { SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD},
245 { SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST},
246 { SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF},
247 { SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT},
248 { SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE},
249 { SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS},
250
251 { SDDL_FILE_ALL, FILE_ALL_ACCESS },
252 { SDDL_FILE_READ, FILE_GENERIC_READ },
253 { SDDL_FILE_WRITE, FILE_GENERIC_WRITE },
254 { SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE },
255
256 { SDDL_KEY_ALL, KEY_ALL_ACCESS },
257 { SDDL_KEY_READ, KEY_READ },
258 { SDDL_KEY_WRITE, KEY_WRITE },
259 { SDDL_KEY_EXECUTE, KEY_EXECUTE },
260 { NULL, 0 },
261 };
262
263 /* set last error code from NT status and get the proper boolean return value */
264 /* used for functions that are a simple wrapper around the corresponding ntdll API */
265 static __inline BOOL set_ntstatus( NTSTATUS status )
266 {
267 if (!NT_SUCCESS(status)) SetLastError( RtlNtStatusToDosError( status ));
268 return NT_SUCCESS(status);
269 }
270
271 static const RECORD SidTable[] =
272 {
273 { SDDL_ACCOUNT_OPERATORS, WinBuiltinAccountOperatorsSid },
274 { SDDL_ALIAS_PREW2KCOMPACC, WinBuiltinPreWindows2000CompatibleAccessSid },
275 { SDDL_ANONYMOUS, WinAnonymousSid },
276 { SDDL_AUTHENTICATED_USERS, WinAuthenticatedUserSid },
277 { SDDL_BUILTIN_ADMINISTRATORS, WinBuiltinAdministratorsSid },
278 { SDDL_BUILTIN_GUESTS, WinBuiltinGuestsSid },
279 { SDDL_BACKUP_OPERATORS, WinBuiltinBackupOperatorsSid },
280 { SDDL_BUILTIN_USERS, WinBuiltinUsersSid },
281 { SDDL_CERT_SERV_ADMINISTRATORS, WinAccountCertAdminsSid /* FIXME: DOMAIN_GROUP_RID_CERT_ADMINS */ },
282 { SDDL_CREATOR_GROUP, WinCreatorGroupSid },
283 { SDDL_CREATOR_OWNER, WinCreatorOwnerSid },
284 { SDDL_DOMAIN_ADMINISTRATORS, WinAccountDomainAdminsSid /* FIXME: DOMAIN_GROUP_RID_ADMINS */ },
285 { SDDL_DOMAIN_COMPUTERS, WinAccountComputersSid /* FIXME: DOMAIN_GROUP_RID_COMPUTERS */ },
286 { SDDL_DOMAIN_DOMAIN_CONTROLLERS, WinAccountControllersSid /* FIXME: DOMAIN_GROUP_RID_CONTROLLERS */ },
287 { SDDL_DOMAIN_GUESTS, WinAccountDomainGuestsSid /* FIXME: DOMAIN_GROUP_RID_GUESTS */ },
288 { SDDL_DOMAIN_USERS, WinAccountDomainUsersSid /* FIXME: DOMAIN_GROUP_RID_USERS */ },
289 { SDDL_ENTERPRISE_ADMINS, WinAccountEnterpriseAdminsSid /* FIXME: DOMAIN_GROUP_RID_ENTERPRISE_ADMINS */ },
290 { SDDL_ENTERPRISE_DOMAIN_CONTROLLERS, WinEnterpriseControllersSid },
291 { SDDL_EVERYONE, WinWorldSid },
292 { SDDL_GROUP_POLICY_ADMINS, WinAccountPolicyAdminsSid /* FIXME: DOMAIN_GROUP_RID_POLICY_ADMINS */ },
293 { SDDL_INTERACTIVE, WinInteractiveSid },
294 { SDDL_LOCAL_ADMIN, WinAccountAdministratorSid /* FIXME: DOMAIN_USER_RID_ADMIN */ },
295 { SDDL_LOCAL_GUEST, WinAccountGuestSid /* FIXME: DOMAIN_USER_RID_GUEST */ },
296 { SDDL_LOCAL_SERVICE, WinLocalServiceSid },
297 { SDDL_LOCAL_SYSTEM, WinLocalSystemSid },
298 { SDDL_NETWORK, WinNetworkSid },
299 { SDDL_NETWORK_CONFIGURATION_OPS, WinBuiltinNetworkConfigurationOperatorsSid },
300 { SDDL_NETWORK_SERVICE, WinNetworkServiceSid },
301 { SDDL_PRINTER_OPERATORS, WinBuiltinPrintOperatorsSid },
302 { SDDL_PERSONAL_SELF, WinSelfSid },
303 { SDDL_POWER_USERS, WinBuiltinPowerUsersSid },
304 { SDDL_RAS_SERVERS, WinAccountRasAndIasServersSid /* FIXME: DOMAIN_ALIAS_RID_RAS_SERVERS */ },
305 { SDDL_REMOTE_DESKTOP, WinBuiltinRemoteDesktopUsersSid },
306 { SDDL_REPLICATOR, WinBuiltinReplicatorSid },
307 { SDDL_RESTRICTED_CODE, WinRestrictedCodeSid },
308 { SDDL_SCHEMA_ADMINISTRATORS, WinAccountSchemaAdminsSid /* FIXME: DOMAIN_GROUP_RID_SCHEMA_ADMINS */ },
309 { SDDL_SERVER_OPERATORS, WinBuiltinSystemOperatorsSid },
310 { SDDL_SERVICE, WinServiceSid },
311 { NULL, 0 },
312 };
313
314 /************************************************************
315 * ADVAPI_IsLocalComputer
316 *
317 * Checks whether the server name indicates local machine.
318 */
319 BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName)
320 {
321 DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
322 BOOL Result;
323 LPWSTR buf;
324
325 if (!ServerName || !ServerName[0])
326 return TRUE;
327
328 buf = heap_alloc(dwSize * sizeof(WCHAR));
329 Result = GetComputerNameW(buf, &dwSize);
330 if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
331 ServerName += 2;
332 Result = Result && !lstrcmpW(ServerName, buf);
333 heap_free(buf);
334
335 return Result;
336 }
337
338 /* Exported functions */
339
340 /*
341 * @implemented
342 */
343 BOOL WINAPI
344 OpenProcessToken(HANDLE ProcessHandle,
345 DWORD DesiredAccess,
346 PHANDLE TokenHandle)
347 {
348 NTSTATUS Status;
349
350 TRACE("%p, %x, %p.\n", ProcessHandle, DesiredAccess, TokenHandle);
351
352 Status = NtOpenProcessToken(ProcessHandle,
353 DesiredAccess,
354 TokenHandle);
355 if (!NT_SUCCESS(Status))
356 {
357 ERR("NtOpenProcessToken failed! Status %08x.\n", Status);
358 SetLastError(RtlNtStatusToDosError(Status));
359 return FALSE;
360 }
361
362 TRACE("Returning token %p.\n", *TokenHandle);
363
364 return TRUE;
365 }
366
367 /******************************************************************************
368 * OpenThreadToken [ADVAPI32.@]
369 *
370 * Opens the access token associated with a thread handle.
371 *
372 * PARAMS
373 * ThreadHandle [I] Handle to process
374 * DesiredAccess [I] Desired access to the thread
375 * OpenAsSelf [I] ???
376 * TokenHandle [O] Destination for the token handle
377 *
378 * RETURNS
379 * Success: TRUE. TokenHandle contains the access token.
380 * Failure: FALSE.
381 *
382 * NOTES
383 * See NtOpenThreadToken.
384 */
385 BOOL WINAPI
386 OpenThreadToken( HANDLE ThreadHandle, DWORD DesiredAccess,
387 BOOL OpenAsSelf, HANDLE *TokenHandle)
388 {
389 return set_ntstatus( NtOpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle));
390 }
391
392 /*
393 * @implemented
394 */
395 BOOL WINAPI
396 AdjustTokenGroups(HANDLE TokenHandle,
397 BOOL ResetToDefault,
398 PTOKEN_GROUPS NewState,
399 DWORD BufferLength,
400 PTOKEN_GROUPS PreviousState,
401 PDWORD ReturnLength)
402 {
403 NTSTATUS Status;
404
405 Status = NtAdjustGroupsToken(TokenHandle,
406 ResetToDefault,
407 NewState,
408 BufferLength,
409 PreviousState,
410 (PULONG)ReturnLength);
411 if (!NT_SUCCESS(Status))
412 {
413 SetLastError(RtlNtStatusToDosError(Status));
414 return FALSE;
415 }
416
417 return TRUE;
418 }
419
420 /*
421 * @implemented
422 */
423 BOOL WINAPI
424 AdjustTokenPrivileges(HANDLE TokenHandle,
425 BOOL DisableAllPrivileges,
426 PTOKEN_PRIVILEGES NewState,
427 DWORD BufferLength,
428 PTOKEN_PRIVILEGES PreviousState,
429 PDWORD ReturnLength)
430 {
431 NTSTATUS Status;
432
433 Status = NtAdjustPrivilegesToken(TokenHandle,
434 DisableAllPrivileges,
435 NewState,
436 BufferLength,
437 PreviousState,
438 (PULONG)ReturnLength);
439 if (STATUS_NOT_ALL_ASSIGNED == Status)
440 {
441 SetLastError(ERROR_NOT_ALL_ASSIGNED);
442 return TRUE;
443 }
444
445 if (!NT_SUCCESS(Status))
446 {
447 SetLastError(RtlNtStatusToDosError(Status));
448 return FALSE;
449 }
450
451 /* AdjustTokenPrivileges is documented to do this */
452 SetLastError(ERROR_SUCCESS);
453
454 return TRUE;
455 }
456
457 /*
458 * @implemented
459 */
460 BOOL WINAPI
461 GetTokenInformation(HANDLE TokenHandle,
462 TOKEN_INFORMATION_CLASS TokenInformationClass,
463 LPVOID TokenInformation,
464 DWORD TokenInformationLength,
465 PDWORD ReturnLength)
466 {
467 NTSTATUS Status;
468
469 Status = NtQueryInformationToken(TokenHandle,
470 TokenInformationClass,
471 TokenInformation,
472 TokenInformationLength,
473 (PULONG)ReturnLength);
474 if (!NT_SUCCESS(Status))
475 {
476 SetLastError(RtlNtStatusToDosError(Status));
477 return FALSE;
478 }
479
480 return TRUE;
481 }
482
483 /*
484 * @implemented
485 */
486 BOOL WINAPI
487 SetTokenInformation(HANDLE TokenHandle,
488 TOKEN_INFORMATION_CLASS TokenInformationClass,
489 LPVOID TokenInformation,
490 DWORD TokenInformationLength)
491 {
492 NTSTATUS Status;
493
494 Status = NtSetInformationToken(TokenHandle,
495 TokenInformationClass,
496 TokenInformation,
497 TokenInformationLength);
498 if (!NT_SUCCESS(Status))
499 {
500 SetLastError(RtlNtStatusToDosError(Status));
501 return FALSE;
502 }
503
504 return TRUE;
505 }
506
507 /*
508 * @implemented
509 */
510 BOOL WINAPI
511 SetThreadToken(IN PHANDLE ThreadHandle OPTIONAL,
512 IN HANDLE TokenHandle)
513 {
514 NTSTATUS Status;
515 HANDLE hThread;
516
517 hThread = (ThreadHandle != NULL) ? *ThreadHandle : NtCurrentThread();
518
519 Status = NtSetInformationThread(hThread,
520 ThreadImpersonationToken,
521 &TokenHandle,
522 sizeof(HANDLE));
523 if (!NT_SUCCESS(Status))
524 {
525 SetLastError(RtlNtStatusToDosError(Status));
526 return FALSE;
527 }
528
529 return TRUE;
530 }
531
532 /*************************************************************************
533 * CreateRestrictedToken [ADVAPI32.@]
534 *
535 * Create a new more restricted token from an existing token.
536 *
537 * PARAMS
538 * baseToken [I] Token to base the new restricted token on
539 * flags [I] Options
540 * nDisableSids [I] Length of disableSids array
541 * disableSids [I] Array of SIDs to disable in the new token
542 * nDeletePrivs [I] Length of deletePrivs array
543 * deletePrivs [I] Array of privileges to delete in the new token
544 * nRestrictSids [I] Length of restrictSids array
545 * restrictSids [I] Array of SIDs to restrict in the new token
546 * newToken [O] Address where the new token is stored
547 *
548 * RETURNS
549 * Success: TRUE
550 * Failure: FALSE
551 */
552 BOOL WINAPI CreateRestrictedToken(
553 HANDLE baseToken,
554 DWORD flags,
555 DWORD nDisableSids,
556 PSID_AND_ATTRIBUTES disableSids,
557 DWORD nDeletePrivs,
558 PLUID_AND_ATTRIBUTES deletePrivs,
559 DWORD nRestrictSids,
560 PSID_AND_ATTRIBUTES restrictSids,
561 PHANDLE newToken)
562 {
563 TOKEN_TYPE type;
564 SECURITY_IMPERSONATION_LEVEL level = TokenImpersonationLevel;
565 DWORD size;
566
567 FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n",
568 baseToken, flags, nDisableSids, disableSids,
569 nDeletePrivs, deletePrivs,
570 nRestrictSids, restrictSids,
571 newToken);
572
573 size = sizeof(type);
574 if (!GetTokenInformation( baseToken, TokenType, &type, size, &size )) return FALSE;
575 if (type == TokenImpersonation)
576 {
577 size = sizeof(level);
578 if (!GetTokenInformation( baseToken, TokenImpersonationLevel, &level, size, &size ))
579 return FALSE;
580 }
581 return DuplicateTokenEx( baseToken, MAXIMUM_ALLOWED, NULL, level, type, newToken );
582 }
583
584 /******************************************************************************
585 * AllocateAndInitializeSid [ADVAPI32.@]
586 *
587 * PARAMS
588 * pIdentifierAuthority []
589 * nSubAuthorityCount []
590 * nSubAuthority0 []
591 * nSubAuthority1 []
592 * nSubAuthority2 []
593 * nSubAuthority3 []
594 * nSubAuthority4 []
595 * nSubAuthority5 []
596 * nSubAuthority6 []
597 * nSubAuthority7 []
598 * pSid []
599 */
600 BOOL WINAPI
601 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
602 BYTE nSubAuthorityCount,
603 DWORD nSubAuthority0, DWORD nSubAuthority1,
604 DWORD nSubAuthority2, DWORD nSubAuthority3,
605 DWORD nSubAuthority4, DWORD nSubAuthority5,
606 DWORD nSubAuthority6, DWORD nSubAuthority7,
607 PSID *pSid )
608 {
609 return set_ntstatus( RtlAllocateAndInitializeSid(
610 pIdentifierAuthority, nSubAuthorityCount,
611 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
612 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
613 pSid ));
614 }
615
616 /*
617 * @implemented
618 *
619 * RETURNS
620 * Docs says this function does NOT return a value
621 * even thou it's defined to return a PVOID...
622 */
623 PVOID
624 WINAPI
625 FreeSid(PSID pSid)
626 {
627 return RtlFreeSid(pSid);
628 }
629
630 /******************************************************************************
631 * CopySid [ADVAPI32.@]
632 *
633 * PARAMS
634 * nDestinationSidLength []
635 * pDestinationSid []
636 * pSourceSid []
637 */
638 BOOL WINAPI
639 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
640 {
641 return set_ntstatus(RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid));
642 }
643
644 /*
645 * @unimplemented
646 */
647 BOOL
648 WINAPI
649 CreateWellKnownSid(IN WELL_KNOWN_SID_TYPE WellKnownSidType,
650 IN PSID DomainSid OPTIONAL,
651 OUT PSID pSid,
652 IN OUT DWORD* cbSid)
653 {
654 unsigned int i;
655 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
656
657 if (cbSid == NULL || (DomainSid && !IsValidSid(DomainSid)))
658 {
659 SetLastError(ERROR_INVALID_PARAMETER);
660 return FALSE;
661 }
662
663 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
664 if (WellKnownSids[i].Type == WellKnownSidType) {
665 DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
666
667 if (*cbSid < length)
668 {
669 *cbSid = length;
670 SetLastError(ERROR_INSUFFICIENT_BUFFER);
671 return FALSE;
672 }
673 if (!pSid)
674 {
675 SetLastError(ERROR_INVALID_PARAMETER);
676 return FALSE;
677 }
678 CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
679 *cbSid = length;
680 return TRUE;
681 }
682 }
683
684 if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES)
685 {
686 SetLastError(ERROR_INVALID_PARAMETER);
687 return FALSE;
688 }
689
690 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
691 if (WellKnownRids[i].Type == WellKnownSidType) {
692 UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid);
693 DWORD domain_sid_length = GetSidLengthRequired(domain_subauth);
694 DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1);
695
696 if (*cbSid < output_sid_length)
697 {
698 *cbSid = output_sid_length;
699 SetLastError(ERROR_INSUFFICIENT_BUFFER);
700 return FALSE;
701 }
702 if (!pSid)
703 {
704 SetLastError(ERROR_INVALID_PARAMETER);
705 return FALSE;
706 }
707 CopyMemory(pSid, DomainSid, domain_sid_length);
708 (*GetSidSubAuthorityCount(pSid))++;
709 (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid;
710 *cbSid = output_sid_length;
711 return TRUE;
712 }
713
714 SetLastError(ERROR_INVALID_PARAMETER);
715 return FALSE;
716 }
717
718 /*
719 * @unimplemented
720 */
721 BOOL
722 WINAPI
723 IsWellKnownSid(IN PSID pSid,
724 IN WELL_KNOWN_SID_TYPE WellKnownSidType)
725 {
726 unsigned int i;
727 TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
728
729 for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
730 {
731 if (WellKnownSids[i].Type == WellKnownSidType)
732 {
733 if (EqualSid(pSid, (PSID)(&WellKnownSids[i].Sid.Revision)))
734 return TRUE;
735 }
736 }
737
738 return FALSE;
739 }
740
741 /*
742 * @implemented
743 */
744 BOOL
745 WINAPI
746 IsValidSid(PSID pSid)
747 {
748 return (BOOL)RtlValidSid(pSid);
749 }
750
751 /*
752 * @implemented
753 */
754 BOOL
755 WINAPI
756 EqualSid(PSID pSid1,
757 PSID pSid2)
758 {
759 SetLastError(ERROR_SUCCESS);
760 return RtlEqualSid (pSid1, pSid2);
761 }
762
763 /*
764 * @implemented
765 */
766 BOOL
767 WINAPI
768 EqualPrefixSid(PSID pSid1,
769 PSID pSid2)
770 {
771 return RtlEqualPrefixSid (pSid1, pSid2);
772 }
773
774 /*
775 * @implemented
776 */
777 DWORD
778 WINAPI
779 GetSidLengthRequired(UCHAR nSubAuthorityCount)
780 {
781 return (DWORD)RtlLengthRequiredSid(nSubAuthorityCount);
782 }
783
784 /*
785 * @implemented
786 */
787 BOOL
788 WINAPI
789 InitializeSid(PSID Sid,
790 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
791 BYTE nSubAuthorityCount)
792 {
793 NTSTATUS Status;
794
795 Status = RtlInitializeSid(Sid,
796 pIdentifierAuthority,
797 nSubAuthorityCount);
798 if (!NT_SUCCESS(Status))
799 {
800 SetLastError(RtlNtStatusToDosError(Status));
801 return FALSE;
802 }
803
804 return TRUE;
805 }
806
807 /*
808 * @implemented
809 */
810 PSID_IDENTIFIER_AUTHORITY
811 WINAPI
812 GetSidIdentifierAuthority(PSID pSid)
813 {
814 return RtlIdentifierAuthoritySid(pSid);
815 }
816
817 /*
818 * @implemented
819 */
820 PDWORD
821 WINAPI
822 GetSidSubAuthority(PSID pSid,
823 DWORD nSubAuthority)
824 {
825 SetLastError(ERROR_SUCCESS);
826 return (PDWORD)RtlSubAuthoritySid(pSid, nSubAuthority);
827 }
828
829 /*
830 * @implemented
831 */
832 PUCHAR
833 WINAPI
834 GetSidSubAuthorityCount(PSID pSid)
835 {
836 SetLastError(ERROR_SUCCESS);
837 return RtlSubAuthorityCountSid(pSid);
838 }
839
840 /*
841 * @implemented
842 */
843 DWORD
844 WINAPI
845 GetLengthSid(PSID pSid)
846 {
847 return (DWORD)RtlLengthSid(pSid);
848 }
849
850 /*
851 * @implemented
852 */
853 BOOL
854 WINAPI
855 InitializeSecurityDescriptor(PSECURITY_DESCRIPTOR pSecurityDescriptor,
856 DWORD dwRevision)
857 {
858 NTSTATUS Status;
859
860 Status = RtlCreateSecurityDescriptor(pSecurityDescriptor,
861 dwRevision);
862 if (!NT_SUCCESS(Status))
863 {
864 SetLastError(RtlNtStatusToDosError(Status));
865 return FALSE;
866 }
867
868 return TRUE;
869 }
870
871 /*
872 * @implemented
873 */
874 BOOL
875 WINAPI
876 MakeAbsoluteSD(PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
877 PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
878 LPDWORD lpdwAbsoluteSecurityDescriptorSize,
879 PACL pDacl,
880 LPDWORD lpdwDaclSize,
881 PACL pSacl,
882 LPDWORD lpdwSaclSize,
883 PSID pOwner,
884 LPDWORD lpdwOwnerSize,
885 PSID pPrimaryGroup,
886 LPDWORD lpdwPrimaryGroupSize)
887 {
888 NTSTATUS Status;
889
890 Status = RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
891 pAbsoluteSecurityDescriptor,
892 lpdwAbsoluteSecurityDescriptorSize,
893 pDacl,
894 lpdwDaclSize,
895 pSacl,
896 lpdwSaclSize,
897 pOwner,
898 lpdwOwnerSize,
899 pPrimaryGroup,
900 lpdwPrimaryGroupSize);
901 if (!NT_SUCCESS(Status))
902 {
903 SetLastError(RtlNtStatusToDosError(Status));
904 return FALSE;
905 }
906
907 return TRUE;
908 }
909
910 /******************************************************************************
911 * GetKernelObjectSecurity [ADVAPI32.@]
912 */
913 BOOL WINAPI GetKernelObjectSecurity(
914 HANDLE Handle,
915 SECURITY_INFORMATION RequestedInformation,
916 PSECURITY_DESCRIPTOR pSecurityDescriptor,
917 DWORD nLength,
918 LPDWORD lpnLengthNeeded )
919 {
920 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation,
921 pSecurityDescriptor, nLength, lpnLengthNeeded);
922
923 return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
924 nLength, lpnLengthNeeded ));
925 }
926
927 /*
928 * @implemented
929 */
930 BOOL
931 WINAPI
932 InitializeAcl(PACL pAcl,
933 DWORD nAclLength,
934 DWORD dwAclRevision)
935 {
936 NTSTATUS Status;
937
938 Status = RtlCreateAcl(pAcl,
939 nAclLength,
940 dwAclRevision);
941 if (!NT_SUCCESS(Status))
942 {
943 SetLastError(RtlNtStatusToDosError(Status));
944 return FALSE;
945 }
946
947 return TRUE;
948 }
949
950 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
951 {
952 IO_STATUS_BLOCK io_block;
953
954 TRACE("(%p)\n", hNamedPipe);
955
956 return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
957 &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
958 }
959
960 /*
961 * @implemented
962 */
963 BOOL
964 WINAPI
965 AddAccessAllowedAce(PACL pAcl,
966 DWORD dwAceRevision,
967 DWORD AccessMask,
968 PSID pSid)
969 {
970 NTSTATUS Status;
971
972 Status = RtlAddAccessAllowedAce(pAcl,
973 dwAceRevision,
974 AccessMask,
975 pSid);
976 if (!NT_SUCCESS(Status))
977 {
978 SetLastError(RtlNtStatusToDosError(Status));
979 return FALSE;
980 }
981
982 return TRUE;
983 }
984
985 /*
986 * @implemented
987 */
988 BOOL WINAPI
989 AddAccessAllowedAceEx(PACL pAcl,
990 DWORD dwAceRevision,
991 DWORD AceFlags,
992 DWORD AccessMask,
993 PSID pSid)
994 {
995 NTSTATUS Status;
996
997 Status = RtlAddAccessAllowedAceEx(pAcl,
998 dwAceRevision,
999 AceFlags,
1000 AccessMask,
1001 pSid);
1002 if (!NT_SUCCESS(Status))
1003 {
1004 SetLastError(RtlNtStatusToDosError(Status));
1005 return FALSE;
1006 }
1007
1008 return TRUE;
1009 }
1010
1011 /*
1012 * @implemented
1013 */
1014 BOOL
1015 WINAPI
1016 AddAccessDeniedAce(PACL pAcl,
1017 DWORD dwAceRevision,
1018 DWORD AccessMask,
1019 PSID pSid)
1020 {
1021 NTSTATUS Status;
1022
1023 Status = RtlAddAccessDeniedAce(pAcl,
1024 dwAceRevision,
1025 AccessMask,
1026 pSid);
1027 if (!NT_SUCCESS(Status))
1028 {
1029 SetLastError(RtlNtStatusToDosError(Status));
1030 return FALSE;
1031 }
1032
1033 return TRUE;
1034 }
1035
1036 /*
1037 * @implemented
1038 */
1039 BOOL WINAPI
1040 AddAccessDeniedAceEx(PACL pAcl,
1041 DWORD dwAceRevision,
1042 DWORD AceFlags,
1043 DWORD AccessMask,
1044 PSID pSid)
1045 {
1046 NTSTATUS Status;
1047
1048 Status = RtlAddAccessDeniedAceEx(pAcl,
1049 dwAceRevision,
1050 AceFlags,
1051 AccessMask,
1052 pSid);
1053 if (!NT_SUCCESS(Status))
1054 {
1055 SetLastError(RtlNtStatusToDosError(Status));
1056 return FALSE;
1057 }
1058
1059 return TRUE;
1060 }
1061
1062 /*
1063 * @implemented
1064 */
1065 BOOL
1066 WINAPI
1067 AddAce(PACL pAcl,
1068 DWORD dwAceRevision,
1069 DWORD dwStartingAceIndex,
1070 LPVOID pAceList,
1071 DWORD nAceListLength)
1072 {
1073 NTSTATUS Status;
1074
1075 Status = RtlAddAce(pAcl,
1076 dwAceRevision,
1077 dwStartingAceIndex,
1078 pAceList,
1079 nAceListLength);
1080 if (!NT_SUCCESS(Status))
1081 {
1082 SetLastError(RtlNtStatusToDosError(Status));
1083 return FALSE;
1084 }
1085
1086 return TRUE;
1087 }
1088
1089 /*
1090 * @implemented
1091 */
1092 BOOL
1093 WINAPI
1094 DeleteAce(PACL pAcl,
1095 DWORD dwAceIndex)
1096 {
1097 NTSTATUS Status;
1098
1099 Status = RtlDeleteAce(pAcl,
1100 dwAceIndex);
1101 if (!NT_SUCCESS(Status))
1102 {
1103 SetLastError(RtlNtStatusToDosError(Status));
1104 return FALSE;
1105 }
1106
1107 return TRUE;
1108 }
1109
1110 /*
1111 * @implemented
1112 */
1113 BOOL
1114 WINAPI
1115 FindFirstFreeAce(PACL pAcl,
1116 LPVOID *pAce)
1117 {
1118 return RtlFirstFreeAce(pAcl,
1119 (PACE*)pAce);
1120 }
1121
1122
1123 /*
1124 * @implemented
1125 */
1126 BOOL
1127 WINAPI
1128 GetAce(PACL pAcl,
1129 DWORD dwAceIndex,
1130 LPVOID *pAce)
1131 {
1132 NTSTATUS Status;
1133
1134 Status = RtlGetAce(pAcl,
1135 dwAceIndex,
1136 pAce);
1137 if (!NT_SUCCESS(Status))
1138 {
1139 SetLastError(RtlNtStatusToDosError(Status));
1140 return FALSE;
1141 }
1142
1143 return TRUE;
1144 }
1145
1146 /*
1147 * @implemented
1148 */
1149 BOOL
1150 WINAPI
1151 GetAclInformation(PACL pAcl,
1152 LPVOID pAclInformation,
1153 DWORD nAclInformationLength,
1154 ACL_INFORMATION_CLASS dwAclInformationClass)
1155 {
1156 NTSTATUS Status;
1157
1158 Status = RtlQueryInformationAcl(pAcl,
1159 pAclInformation,
1160 nAclInformationLength,
1161 dwAclInformationClass);
1162 if (!NT_SUCCESS(Status))
1163 {
1164 SetLastError(RtlNtStatusToDosError(Status));
1165 return FALSE;
1166 }
1167
1168 return TRUE;
1169 }
1170
1171 /*
1172 * @implemented
1173 */
1174 BOOL
1175 WINAPI
1176 IsValidAcl(PACL pAcl)
1177 {
1178 return RtlValidAcl (pAcl);
1179 }
1180
1181 /*
1182 * @implemented
1183 */
1184 BOOL WINAPI
1185 AllocateLocallyUniqueId(PLUID Luid)
1186 {
1187 NTSTATUS Status;
1188
1189 Status = NtAllocateLocallyUniqueId (Luid);
1190 if (!NT_SUCCESS (Status))
1191 {
1192 SetLastError(RtlNtStatusToDosError(Status));
1193 return FALSE;
1194 }
1195
1196 return TRUE;
1197 }
1198
1199 /**********************************************************************
1200 * LookupPrivilegeDisplayNameA EXPORTED
1201 *
1202 * @unimplemented
1203 */
1204 BOOL
1205 WINAPI
1206 LookupPrivilegeDisplayNameA(LPCSTR lpSystemName,
1207 LPCSTR lpName,
1208 LPSTR lpDisplayName,
1209 LPDWORD cbDisplayName,
1210 LPDWORD lpLanguageId)
1211 {
1212 FIXME("%s() not implemented!\n", __FUNCTION__);
1213 SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
1214 return FALSE;
1215 }
1216
1217
1218 /**********************************************************************
1219 * LookupPrivilegeDisplayNameW EXPORTED
1220 *
1221 * @unimplemented
1222 */
1223 BOOL
1224 WINAPI
1225 LookupPrivilegeDisplayNameW(LPCWSTR lpSystemName,
1226 LPCWSTR lpName,
1227 LPWSTR lpDisplayName,
1228 LPDWORD cbDisplayName,
1229 LPDWORD lpLanguageId)
1230 {
1231 FIXME("%s() not implemented!\n", __FUNCTION__);
1232 SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
1233 return FALSE;
1234 }
1235
1236 /**********************************************************************
1237 * LookupPrivilegeNameA EXPORTED
1238 *
1239 * @implemented
1240 */
1241 BOOL
1242 WINAPI
1243 LookupPrivilegeNameA(LPCSTR lpSystemName,
1244 PLUID lpLuid,
1245 LPSTR lpName,
1246 LPDWORD cchName)
1247 {
1248 UNICODE_STRING lpSystemNameW;
1249 BOOL ret;
1250 DWORD wLen = 0;
1251
1252 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1253
1254 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1255 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1256 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1257 {
1258 LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1259
1260 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1261 &wLen);
1262 if (ret)
1263 {
1264 /* Windows crashes if cchName is NULL, so will I */
1265 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1266 *cchName, NULL, NULL);
1267
1268 if (len == 0)
1269 {
1270 /* WideCharToMultiByte failed */
1271 ret = FALSE;
1272 }
1273 else if (len > *cchName)
1274 {
1275 *cchName = len;
1276 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1277 ret = FALSE;
1278 }
1279 else
1280 {
1281 /* WideCharToMultiByte succeeded, output length needs to be
1282 * length not including NULL terminator
1283 */
1284 *cchName = len - 1;
1285 }
1286 }
1287 HeapFree(GetProcessHeap(), 0, lpNameW);
1288 }
1289 RtlFreeUnicodeString(&lpSystemNameW);
1290 return ret;
1291 }
1292
1293 /******************************************************************************
1294 * GetFileSecurityA [ADVAPI32.@]
1295 *
1296 * Obtains Specified information about the security of a file or directory.
1297 *
1298 * PARAMS
1299 * lpFileName [I] Name of the file to get info for
1300 * RequestedInformation [I] SE_ flags from "winnt.h"
1301 * pSecurityDescriptor [O] Destination for security information
1302 * nLength [I] Length of pSecurityDescriptor
1303 * lpnLengthNeeded [O] Destination for length of returned security information
1304 *
1305 * RETURNS
1306 * Success: TRUE. pSecurityDescriptor contains the requested information.
1307 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
1308 *
1309 * NOTES
1310 * The information returned is constrained by the callers access rights and
1311 * privileges.
1312 *
1313 * @implemented
1314 */
1315 BOOL
1316 WINAPI
1317 GetFileSecurityA(LPCSTR lpFileName,
1318 SECURITY_INFORMATION RequestedInformation,
1319 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1320 DWORD nLength,
1321 LPDWORD lpnLengthNeeded)
1322 {
1323 UNICODE_STRING FileName;
1324 BOOL bResult;
1325
1326 if (!RtlCreateUnicodeStringFromAsciiz(&FileName, lpFileName))
1327 {
1328 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1329 return FALSE;
1330 }
1331
1332 bResult = GetFileSecurityW(FileName.Buffer,
1333 RequestedInformation,
1334 pSecurityDescriptor,
1335 nLength,
1336 lpnLengthNeeded);
1337
1338 RtlFreeUnicodeString(&FileName);
1339
1340 return bResult;
1341 }
1342
1343 /*
1344 * @implemented
1345 */
1346 BOOL
1347 WINAPI
1348 GetFileSecurityW(LPCWSTR lpFileName,
1349 SECURITY_INFORMATION RequestedInformation,
1350 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1351 DWORD nLength,
1352 LPDWORD lpnLengthNeeded)
1353 {
1354 OBJECT_ATTRIBUTES ObjectAttributes;
1355 IO_STATUS_BLOCK StatusBlock;
1356 UNICODE_STRING FileName;
1357 ULONG AccessMask = 0;
1358 HANDLE FileHandle;
1359 NTSTATUS Status;
1360
1361 TRACE("GetFileSecurityW() called\n");
1362
1363 QuerySecurityAccessMask(RequestedInformation, &AccessMask);
1364
1365 if (!RtlDosPathNameToNtPathName_U(lpFileName,
1366 &FileName,
1367 NULL,
1368 NULL))
1369 {
1370 ERR("Invalid path\n");
1371 SetLastError(ERROR_INVALID_NAME);
1372 return FALSE;
1373 }
1374
1375 InitializeObjectAttributes(&ObjectAttributes,
1376 &FileName,
1377 OBJ_CASE_INSENSITIVE,
1378 NULL,
1379 NULL);
1380
1381 Status = NtOpenFile(&FileHandle,
1382 AccessMask,
1383 &ObjectAttributes,
1384 &StatusBlock,
1385 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
1386 0);
1387
1388 RtlFreeHeap(RtlGetProcessHeap(),
1389 0,
1390 FileName.Buffer);
1391
1392 if (!NT_SUCCESS(Status))
1393 {
1394 ERR("NtOpenFile() failed (Status %lx)\n", Status);
1395 SetLastError(RtlNtStatusToDosError(Status));
1396 return FALSE;
1397 }
1398
1399 Status = NtQuerySecurityObject(FileHandle,
1400 RequestedInformation,
1401 pSecurityDescriptor,
1402 nLength,
1403 lpnLengthNeeded);
1404 NtClose(FileHandle);
1405 if (!NT_SUCCESS(Status))
1406 {
1407 ERR("NtQuerySecurityObject() failed (Status %lx)\n", Status);
1408 SetLastError(RtlNtStatusToDosError(Status));
1409 return FALSE;
1410 }
1411
1412 return TRUE;
1413 }
1414
1415 /******************************************************************************
1416 * SetFileSecurityA [ADVAPI32.@]
1417 * Sets the security of a file or directory
1418 *
1419 * @implemented
1420 */
1421 BOOL
1422 WINAPI
1423 SetFileSecurityA(LPCSTR lpFileName,
1424 SECURITY_INFORMATION SecurityInformation,
1425 PSECURITY_DESCRIPTOR pSecurityDescriptor)
1426 {
1427 UNICODE_STRING FileName;
1428 BOOL bResult;
1429
1430 if (!RtlCreateUnicodeStringFromAsciiz(&FileName, lpFileName))
1431 {
1432 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1433 return FALSE;
1434 }
1435
1436 bResult = SetFileSecurityW(FileName.Buffer,
1437 SecurityInformation,
1438 pSecurityDescriptor);
1439
1440 RtlFreeUnicodeString(&FileName);
1441
1442 return bResult;
1443 }
1444
1445 /******************************************************************************
1446 * SetFileSecurityW [ADVAPI32.@]
1447 * Sets the security of a file or directory
1448 *
1449 * @implemented
1450 */
1451 BOOL
1452 WINAPI
1453 SetFileSecurityW(LPCWSTR lpFileName,
1454 SECURITY_INFORMATION SecurityInformation,
1455 PSECURITY_DESCRIPTOR pSecurityDescriptor)
1456 {
1457 OBJECT_ATTRIBUTES ObjectAttributes;
1458 IO_STATUS_BLOCK StatusBlock;
1459 UNICODE_STRING FileName;
1460 ULONG AccessMask = 0;
1461 HANDLE FileHandle;
1462 NTSTATUS Status;
1463
1464 TRACE("SetFileSecurityW() called\n");
1465
1466 SetSecurityAccessMask(SecurityInformation, &AccessMask);
1467
1468 if (!RtlDosPathNameToNtPathName_U(lpFileName,
1469 &FileName,
1470 NULL,
1471 NULL))
1472 {
1473 ERR("Invalid path\n");
1474 SetLastError(ERROR_INVALID_NAME);
1475 return FALSE;
1476 }
1477
1478 InitializeObjectAttributes(&ObjectAttributes,
1479 &FileName,
1480 OBJ_CASE_INSENSITIVE,
1481 NULL,
1482 NULL);
1483
1484 Status = NtOpenFile(&FileHandle,
1485 AccessMask,
1486 &ObjectAttributes,
1487 &StatusBlock,
1488 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
1489 0);
1490
1491 RtlFreeHeap(RtlGetProcessHeap(),
1492 0,
1493 FileName.Buffer);
1494
1495 if (!NT_SUCCESS(Status))
1496 {
1497 ERR("NtOpenFile() failed (Status %lx)\n", Status);
1498 SetLastError(RtlNtStatusToDosError(Status));
1499 return FALSE;
1500 }
1501
1502 Status = NtSetSecurityObject(FileHandle,
1503 SecurityInformation,
1504 pSecurityDescriptor);
1505 NtClose(FileHandle);
1506
1507 if (!NT_SUCCESS(Status))
1508 {
1509 ERR("NtSetSecurityObject() failed (Status %lx)\n", Status);
1510 SetLastError(RtlNtStatusToDosError(Status));
1511 return FALSE;
1512 }
1513
1514 return TRUE;
1515 }
1516
1517 /******************************************************************************
1518 * QueryWindows31FilesMigration [ADVAPI32.@]
1519 *
1520 * PARAMS
1521 * x1 []
1522 */
1523 BOOL WINAPI
1524 QueryWindows31FilesMigration( DWORD x1 )
1525 {
1526 FIXME("(%d):stub\n",x1);
1527 return TRUE;
1528 }
1529
1530 /******************************************************************************
1531 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
1532 *
1533 * PARAMS
1534 * x1 []
1535 * x2 []
1536 * x3 []
1537 * x4 []
1538 */
1539 BOOL WINAPI
1540 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
1541 DWORD x4 )
1542 {
1543 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
1544 return TRUE;
1545 }
1546
1547 /*
1548 * @implemented
1549 */
1550 BOOL
1551 WINAPI
1552 RevertToSelf(VOID)
1553 {
1554 NTSTATUS Status;
1555 HANDLE Token = NULL;
1556
1557 Status = NtSetInformationThread(NtCurrentThread(),
1558 ThreadImpersonationToken,
1559 &Token,
1560 sizeof(HANDLE));
1561 if (!NT_SUCCESS(Status))
1562 {
1563 SetLastError(RtlNtStatusToDosError(Status));
1564 return FALSE;
1565 }
1566
1567 return TRUE;
1568 }
1569
1570 /*
1571 * @implemented
1572 */
1573 BOOL
1574 WINAPI
1575 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
1576 {
1577 NTSTATUS Status;
1578
1579 Status = RtlImpersonateSelf(ImpersonationLevel);
1580 if (!NT_SUCCESS(Status))
1581 {
1582 SetLastError(RtlNtStatusToDosError(Status));
1583 return FALSE;
1584 }
1585
1586 return TRUE;
1587 }
1588
1589 /*
1590 * @implemented
1591 */
1592 BOOL
1593 WINAPI
1594 AccessCheck(IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1595 IN HANDLE ClientToken,
1596 IN DWORD DesiredAccess,
1597 IN PGENERIC_MAPPING GenericMapping,
1598 OUT PPRIVILEGE_SET PrivilegeSet OPTIONAL,
1599 IN OUT LPDWORD PrivilegeSetLength,
1600 OUT LPDWORD GrantedAccess,
1601 OUT LPBOOL AccessStatus)
1602 {
1603 NTSTATUS Status;
1604 NTSTATUS NtAccessStatus;
1605
1606 /* Do the access check */
1607 Status = NtAccessCheck(pSecurityDescriptor,
1608 ClientToken,
1609 DesiredAccess,
1610 GenericMapping,
1611 PrivilegeSet,
1612 (PULONG)PrivilegeSetLength,
1613 (PACCESS_MASK)GrantedAccess,
1614 &NtAccessStatus);
1615
1616 /* See if the access check operation succeeded */
1617 if (!NT_SUCCESS(Status))
1618 {
1619 /* Check failed */
1620 SetLastError(RtlNtStatusToDosError(Status));
1621 return FALSE;
1622 }
1623
1624 /* Now check the access status */
1625 if (!NT_SUCCESS(NtAccessStatus))
1626 {
1627 /* Access denied */
1628 SetLastError(RtlNtStatusToDosError(NtAccessStatus));
1629 *AccessStatus = FALSE;
1630 }
1631 else
1632 {
1633 /* Access granted */
1634 *AccessStatus = TRUE;
1635 }
1636
1637 /* Check succeeded */
1638 return TRUE;
1639 }
1640
1641 /*
1642 * @unimplemented
1643 */
1644 BOOL WINAPI AccessCheckByType(
1645 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1646 PSID PrincipalSelfSid,
1647 HANDLE ClientToken,
1648 DWORD DesiredAccess,
1649 POBJECT_TYPE_LIST ObjectTypeList,
1650 DWORD ObjectTypeListLength,
1651 PGENERIC_MAPPING GenericMapping,
1652 PPRIVILEGE_SET PrivilegeSet,
1653 LPDWORD PrivilegeSetLength,
1654 LPDWORD GrantedAccess,
1655 LPBOOL AccessStatus)
1656 {
1657 FIXME("stub\n");
1658
1659 *AccessStatus = TRUE;
1660
1661 return !*AccessStatus;
1662 }
1663
1664 /*
1665 * @implemented
1666 */
1667 BOOL
1668 WINAPI
1669 SetKernelObjectSecurity(HANDLE Handle,
1670 SECURITY_INFORMATION SecurityInformation,
1671 PSECURITY_DESCRIPTOR SecurityDescriptor)
1672 {
1673 NTSTATUS Status;
1674
1675 Status = NtSetSecurityObject(Handle,
1676 SecurityInformation,
1677 SecurityDescriptor);
1678 if (!NT_SUCCESS(Status))
1679 {
1680 SetLastError(RtlNtStatusToDosError(Status));
1681 return FALSE;
1682 }
1683
1684 return TRUE;
1685 }
1686
1687 /*
1688 * @implemented
1689 */
1690 BOOL
1691 WINAPI
1692 AddAuditAccessAce(PACL pAcl,
1693 DWORD dwAceRevision,
1694 DWORD dwAccessMask,
1695 PSID pSid,
1696 BOOL bAuditSuccess,
1697 BOOL bAuditFailure)
1698 {
1699 NTSTATUS Status;
1700
1701 Status = RtlAddAuditAccessAce(pAcl,
1702 dwAceRevision,
1703 dwAccessMask,
1704 pSid,
1705 bAuditSuccess,
1706 bAuditFailure);
1707 if (!NT_SUCCESS(Status))
1708 {
1709 SetLastError(RtlNtStatusToDosError(Status));
1710 return FALSE;
1711 }
1712
1713 return TRUE;
1714 }
1715
1716 /*
1717 * @implemented
1718 */
1719 BOOL WINAPI
1720 AddAuditAccessAceEx(PACL pAcl,
1721 DWORD dwAceRevision,
1722 DWORD AceFlags,
1723 DWORD dwAccessMask,
1724 PSID pSid,
1725 BOOL bAuditSuccess,
1726 BOOL bAuditFailure)
1727 {
1728 NTSTATUS Status;
1729
1730 Status = RtlAddAuditAccessAceEx(pAcl,
1731 dwAceRevision,
1732 AceFlags,
1733 dwAccessMask,
1734 pSid,
1735 bAuditSuccess,
1736 bAuditFailure);
1737 if (!NT_SUCCESS(Status))
1738 {
1739 SetLastError(RtlNtStatusToDosError(Status));
1740 return FALSE;
1741 }
1742
1743 return TRUE;
1744 }
1745
1746 /******************************************************************************
1747 * LookupAccountNameA [ADVAPI32.@]
1748 *
1749 * @implemented
1750 */
1751 BOOL
1752 WINAPI
1753 LookupAccountNameA(LPCSTR SystemName,
1754 LPCSTR AccountName,
1755 PSID Sid,
1756 LPDWORD SidLength,
1757 LPSTR ReferencedDomainName,
1758 LPDWORD hReferencedDomainNameLength,
1759 PSID_NAME_USE SidNameUse)
1760 {
1761 BOOL ret;
1762 UNICODE_STRING lpSystemW;
1763 UNICODE_STRING lpAccountW;
1764 LPWSTR lpReferencedDomainNameW = NULL;
1765
1766 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, SystemName);
1767 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, AccountName);
1768
1769 if (ReferencedDomainName)
1770 lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(),
1771 0,
1772 *hReferencedDomainNameLength * sizeof(WCHAR));
1773
1774 ret = LookupAccountNameW(lpSystemW.Buffer,
1775 lpAccountW.Buffer,
1776 Sid,
1777 SidLength,
1778 lpReferencedDomainNameW,
1779 hReferencedDomainNameLength,
1780 SidNameUse);
1781
1782 if (ret && lpReferencedDomainNameW)
1783 {
1784 WideCharToMultiByte(CP_ACP,
1785 0,
1786 lpReferencedDomainNameW,
1787 *hReferencedDomainNameLength + 1,
1788 ReferencedDomainName,
1789 *hReferencedDomainNameLength + 1,
1790 NULL,
1791 NULL);
1792 }
1793
1794 RtlFreeUnicodeString(&lpSystemW);
1795 RtlFreeUnicodeString(&lpAccountW);
1796 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
1797
1798 return ret;
1799 }
1800
1801 /**********************************************************************
1802 * PrivilegeCheck EXPORTED
1803 *
1804 * @implemented
1805 */
1806 BOOL WINAPI
1807 PrivilegeCheck(HANDLE ClientToken,
1808 PPRIVILEGE_SET RequiredPrivileges,
1809 LPBOOL pfResult)
1810 {
1811 BOOLEAN Result;
1812 NTSTATUS Status;
1813
1814 Status = NtPrivilegeCheck(ClientToken,
1815 RequiredPrivileges,
1816 &Result);
1817 if (!NT_SUCCESS(Status))
1818 {
1819 SetLastError(RtlNtStatusToDosError(Status));
1820 return FALSE;
1821 }
1822
1823 *pfResult = (BOOL)Result;
1824
1825 return TRUE;
1826 }
1827
1828 /******************************************************************************
1829 * GetSecurityInfoExW EXPORTED
1830 */
1831 DWORD
1832 WINAPI
1833 GetSecurityInfoExA(HANDLE hObject,
1834 SE_OBJECT_TYPE ObjectType,
1835 SECURITY_INFORMATION SecurityInfo,
1836 LPCSTR lpProvider,
1837 LPCSTR lpProperty,
1838 PACTRL_ACCESSA *ppAccessList,
1839 PACTRL_AUDITA *ppAuditList,
1840 LPSTR *lppOwner,
1841 LPSTR *lppGroup)
1842 {
1843 FIXME("%s() not implemented!\n", __FUNCTION__);
1844 return ERROR_BAD_PROVIDER;
1845 }
1846
1847
1848 /******************************************************************************
1849 * GetSecurityInfoExW EXPORTED
1850 */
1851 DWORD
1852 WINAPI
1853 GetSecurityInfoExW(HANDLE hObject,
1854 SE_OBJECT_TYPE ObjectType,
1855 SECURITY_INFORMATION SecurityInfo,
1856 LPCWSTR lpProvider,
1857 LPCWSTR lpProperty,
1858 PACTRL_ACCESSW *ppAccessList,
1859 PACTRL_AUDITW *ppAuditList,
1860 LPWSTR *lppOwner,
1861 LPWSTR *lppGroup)
1862 {
1863 FIXME("%s() not implemented!\n", __FUNCTION__);
1864 return ERROR_BAD_PROVIDER;
1865 }
1866
1867 /******************************************************************************
1868 * BuildExplicitAccessWithNameA [ADVAPI32.@]
1869 */
1870 VOID WINAPI
1871 BuildExplicitAccessWithNameA(PEXPLICIT_ACCESSA pExplicitAccess,
1872 LPSTR pTrusteeName,
1873 DWORD AccessPermissions,
1874 ACCESS_MODE AccessMode,
1875 DWORD Inheritance)
1876 {
1877 pExplicitAccess->grfAccessPermissions = AccessPermissions;
1878 pExplicitAccess->grfAccessMode = AccessMode;
1879 pExplicitAccess->grfInheritance = Inheritance;
1880
1881 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
1882 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
1883 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
1884 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
1885 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
1886 }
1887
1888
1889 /******************************************************************************
1890 * BuildExplicitAccessWithNameW [ADVAPI32.@]
1891 */
1892 VOID WINAPI
1893 BuildExplicitAccessWithNameW(PEXPLICIT_ACCESSW pExplicitAccess,
1894 LPWSTR pTrusteeName,
1895 DWORD AccessPermissions,
1896 ACCESS_MODE AccessMode,
1897 DWORD Inheritance)
1898 {
1899 pExplicitAccess->grfAccessPermissions = AccessPermissions;
1900 pExplicitAccess->grfAccessMode = AccessMode;
1901 pExplicitAccess->grfInheritance = Inheritance;
1902
1903 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
1904 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
1905 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
1906 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
1907 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
1908 }
1909
1910 /******************************************************************************
1911 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
1912 */
1913 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
1914 SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
1915 LPSTR InheritedObjectTypeName, LPSTR Name )
1916 {
1917 DWORD ObjectsPresent = 0;
1918
1919 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
1920 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
1921
1922 /* Fill the OBJECTS_AND_NAME structure */
1923 pObjName->ObjectType = ObjectType;
1924 if (ObjectTypeName != NULL)
1925 {
1926 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
1927 }
1928
1929 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
1930 if (InheritedObjectTypeName != NULL)
1931 {
1932 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
1933 }
1934
1935 pObjName->ObjectsPresent = ObjectsPresent;
1936 pObjName->ptstrName = Name;
1937
1938 /* Fill the TRUSTEE structure */
1939 pTrustee->pMultipleTrustee = NULL;
1940 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
1941 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
1942 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
1943 pTrustee->ptstrName = (LPSTR)pObjName;
1944 }
1945
1946 /******************************************************************************
1947 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
1948 */
1949 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
1950 SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
1951 LPWSTR InheritedObjectTypeName, LPWSTR Name )
1952 {
1953 DWORD ObjectsPresent = 0;
1954
1955 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
1956 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
1957
1958 /* Fill the OBJECTS_AND_NAME structure */
1959 pObjName->ObjectType = ObjectType;
1960 if (ObjectTypeName != NULL)
1961 {
1962 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
1963 }
1964
1965 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
1966 if (InheritedObjectTypeName != NULL)
1967 {
1968 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
1969 }
1970
1971 pObjName->ObjectsPresent = ObjectsPresent;
1972 pObjName->ptstrName = Name;
1973
1974 /* Fill the TRUSTEE structure */
1975 pTrustee->pMultipleTrustee = NULL;
1976 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
1977 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
1978 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
1979 pTrustee->ptstrName = (LPWSTR)pObjName;
1980 }
1981
1982 /******************************************************************************
1983 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
1984 */
1985 VOID WINAPI
1986 BuildTrusteeWithObjectsAndSidA(PTRUSTEEA pTrustee,
1987 POBJECTS_AND_SID pObjSid,
1988 GUID *pObjectGuid,
1989 GUID *pInheritedObjectGuid,
1990 PSID pSid)
1991 {
1992 DWORD ObjectsPresent = 0;
1993
1994 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
1995
1996 /* Fill the OBJECTS_AND_SID structure */
1997 if (pObjectGuid != NULL)
1998 {
1999 pObjSid->ObjectTypeGuid = *pObjectGuid;
2000 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2001 }
2002 else
2003 {
2004 ZeroMemory(&pObjSid->ObjectTypeGuid,
2005 sizeof(GUID));
2006 }
2007
2008 if (pInheritedObjectGuid != NULL)
2009 {
2010 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
2011 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2012 }
2013 else
2014 {
2015 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
2016 sizeof(GUID));
2017 }
2018
2019 pObjSid->ObjectsPresent = ObjectsPresent;
2020 pObjSid->pSid = pSid;
2021
2022 /* Fill the TRUSTEE structure */
2023 pTrustee->pMultipleTrustee = NULL;
2024 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2025 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
2026 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2027 pTrustee->ptstrName = (LPSTR) pObjSid;
2028 }
2029
2030
2031 /******************************************************************************
2032 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
2033 */
2034 VOID WINAPI
2035 BuildTrusteeWithObjectsAndSidW(PTRUSTEEW pTrustee,
2036 POBJECTS_AND_SID pObjSid,
2037 GUID *pObjectGuid,
2038 GUID *pInheritedObjectGuid,
2039 PSID pSid)
2040 {
2041 DWORD ObjectsPresent = 0;
2042
2043 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
2044
2045 /* Fill the OBJECTS_AND_SID structure */
2046 if (pObjectGuid != NULL)
2047 {
2048 pObjSid->ObjectTypeGuid = *pObjectGuid;
2049 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2050 }
2051 else
2052 {
2053 ZeroMemory(&pObjSid->ObjectTypeGuid,
2054 sizeof(GUID));
2055 }
2056
2057 if (pInheritedObjectGuid != NULL)
2058 {
2059 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
2060 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2061 }
2062 else
2063 {
2064 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
2065 sizeof(GUID));
2066 }
2067
2068 pObjSid->ObjectsPresent = ObjectsPresent;
2069 pObjSid->pSid = pSid;
2070
2071 /* Fill the TRUSTEE structure */
2072 pTrustee->pMultipleTrustee = NULL;
2073 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2074 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
2075 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2076 pTrustee->ptstrName = (LPWSTR) pObjSid;
2077 }
2078
2079 /******************************************************************************
2080 * BuildTrusteeWithSidA [ADVAPI32.@]
2081 */
2082 VOID WINAPI
2083 BuildTrusteeWithSidA(PTRUSTEE_A pTrustee,
2084 PSID pSid)
2085 {
2086 TRACE("%p %p\n", pTrustee, pSid);
2087
2088 pTrustee->pMultipleTrustee = NULL;
2089 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2090 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
2091 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2092 pTrustee->ptstrName = (LPSTR) pSid;
2093 }
2094
2095
2096 /******************************************************************************
2097 * BuildTrusteeWithSidW [ADVAPI32.@]
2098 */
2099 VOID WINAPI
2100 BuildTrusteeWithSidW(PTRUSTEE_W pTrustee,
2101 PSID pSid)
2102 {
2103 TRACE("%p %p\n", pTrustee, pSid);
2104
2105 pTrustee->pMultipleTrustee = NULL;
2106 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2107 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
2108 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2109 pTrustee->ptstrName = (LPWSTR) pSid;
2110 }
2111
2112 /******************************************************************************
2113 * BuildTrusteeWithNameA [ADVAPI32.@]
2114 */
2115 VOID WINAPI
2116 BuildTrusteeWithNameA(PTRUSTEE_A pTrustee,
2117 LPSTR name)
2118 {
2119 TRACE("%p %s\n", pTrustee, name);
2120
2121 pTrustee->pMultipleTrustee = NULL;
2122 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2123 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
2124 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2125 pTrustee->ptstrName = name;
2126 }
2127
2128 /******************************************************************************
2129 * BuildTrusteeWithNameW [ADVAPI32.@]
2130 */
2131 VOID WINAPI
2132 BuildTrusteeWithNameW(PTRUSTEE_W pTrustee,
2133 LPWSTR name)
2134 {
2135 TRACE("%p %s\n", pTrustee, name);
2136
2137 pTrustee->pMultipleTrustee = NULL;
2138 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2139 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
2140 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2141 pTrustee->ptstrName = name;
2142 }
2143
2144 /******************************************************************************
2145 * GetTrusteeFormW [ADVAPI32.@]
2146 */
2147 TRUSTEE_FORM WINAPI
2148 GetTrusteeFormA(PTRUSTEE_A pTrustee)
2149 {
2150 return pTrustee->TrusteeForm;
2151 }
2152
2153
2154 /******************************************************************************
2155 * GetTrusteeFormW [ADVAPI32.@]
2156 */
2157 TRUSTEE_FORM WINAPI
2158 GetTrusteeFormW(PTRUSTEE_W pTrustee)
2159 {
2160 return pTrustee->TrusteeForm;
2161 }
2162
2163 /******************************************************************************
2164 * GetTrusteeNameA [ADVAPI32.@]
2165 */
2166 LPSTR WINAPI
2167 GetTrusteeNameA(PTRUSTEE_A pTrustee)
2168 {
2169 return pTrustee->ptstrName;
2170 }
2171
2172
2173 /******************************************************************************
2174 * GetTrusteeNameW [ADVAPI32.@]
2175 */
2176 LPWSTR WINAPI
2177 GetTrusteeNameW(PTRUSTEE_W pTrustee)
2178 {
2179 return pTrustee->ptstrName;
2180 }
2181
2182 /******************************************************************************
2183 * GetTrusteeTypeA [ADVAPI32.@]
2184 */
2185 TRUSTEE_TYPE WINAPI
2186 GetTrusteeTypeA(PTRUSTEE_A pTrustee)
2187 {
2188 return pTrustee->TrusteeType;
2189 }
2190
2191 /******************************************************************************
2192 * GetTrusteeTypeW [ADVAPI32.@]
2193 */
2194 TRUSTEE_TYPE WINAPI
2195 GetTrusteeTypeW(PTRUSTEE_W pTrustee)
2196 {
2197 return pTrustee->TrusteeType;
2198 }
2199
2200 /*
2201 * @implemented
2202 */
2203 BOOL
2204 WINAPI
2205 SetAclInformation(PACL pAcl,
2206 LPVOID pAclInformation,
2207 DWORD nAclInformationLength,
2208 ACL_INFORMATION_CLASS dwAclInformationClass)
2209 {
2210 NTSTATUS Status;
2211
2212 Status = RtlSetInformationAcl(pAcl,
2213 pAclInformation,
2214 nAclInformationLength,
2215 dwAclInformationClass);
2216 if (!NT_SUCCESS(Status))
2217 {
2218 SetLastError(RtlNtStatusToDosError(Status));
2219 return FALSE;
2220 }
2221
2222 return TRUE;
2223 }
2224
2225 /**********************************************************************
2226 * SetNamedSecurityInfoA EXPORTED
2227 *
2228 * @implemented
2229 */
2230 DWORD
2231 WINAPI
2232 SetNamedSecurityInfoA(LPSTR pObjectName,
2233 SE_OBJECT_TYPE ObjectType,
2234 SECURITY_INFORMATION SecurityInfo,
2235 PSID psidOwner,
2236 PSID psidGroup,
2237 PACL pDacl,
2238 PACL pSacl)
2239 {
2240 UNICODE_STRING ObjectName;
2241 DWORD Ret;
2242
2243 if (!RtlCreateUnicodeStringFromAsciiz(&ObjectName, pObjectName))
2244 {
2245 return ERROR_NOT_ENOUGH_MEMORY;
2246 }
2247
2248 Ret = SetNamedSecurityInfoW(ObjectName.Buffer,
2249 ObjectType,
2250 SecurityInfo,
2251 psidOwner,
2252 psidGroup,
2253 pDacl,
2254 pSacl);
2255
2256 RtlFreeUnicodeString(&ObjectName);
2257
2258 return Ret;
2259 }
2260
2261 /*
2262 * @implemented
2263 */
2264 BOOL
2265 WINAPI
2266 AreAllAccessesGranted(DWORD GrantedAccess,
2267 DWORD DesiredAccess)
2268 {
2269 return (BOOL)RtlAreAllAccessesGranted(GrantedAccess,
2270 DesiredAccess);
2271 }
2272
2273 /*
2274 * @implemented
2275 */
2276 BOOL
2277 WINAPI
2278 AreAnyAccessesGranted(DWORD GrantedAccess,
2279 DWORD DesiredAccess)
2280 {
2281 return (BOOL)RtlAreAnyAccessesGranted(GrantedAccess,
2282 DesiredAccess);
2283 }
2284
2285 /******************************************************************************
2286 * ParseAclStringFlags
2287 */
2288 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
2289 {
2290 DWORD flags = 0;
2291 LPCWSTR szAcl = *StringAcl;
2292
2293 while (*szAcl != '(')
2294 {
2295 if (*szAcl == 'P')
2296 {
2297 flags |= SE_DACL_PROTECTED;
2298 }
2299 else if (*szAcl == 'A')
2300 {
2301 szAcl++;
2302 if (*szAcl == 'R')
2303 flags |= SE_DACL_AUTO_INHERIT_REQ;
2304 else if (*szAcl == 'I')
2305 flags |= SE_DACL_AUTO_INHERITED;
2306 }
2307 szAcl++;
2308 }
2309
2310 *StringAcl = szAcl;
2311 return flags;
2312 }
2313
2314 /******************************************************************************
2315 * ParseAceStringType
2316 */
2317 static const ACEFLAG AceType[] =
2318 {
2319 { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
2320 { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
2321 { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
2322 { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
2323 /*
2324 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
2325 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
2326 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
2327 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
2328 */
2329 { NULL, 0 },
2330 };
2331
2332 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
2333 {
2334 UINT len = 0;
2335 LPCWSTR szAcl = *StringAcl;
2336 const ACEFLAG *lpaf = AceType;
2337
2338 while (*szAcl == ' ')
2339 szAcl++;
2340
2341 while (lpaf->wstr &&
2342 (len = strlenW(lpaf->wstr)) &&
2343 strncmpW(lpaf->wstr, szAcl, len))
2344 lpaf++;
2345
2346 if (!lpaf->wstr)
2347 return 0;
2348
2349 *StringAcl = szAcl + len;
2350 return lpaf->value;
2351 }
2352
2353
2354 /******************************************************************************
2355 * ParseAceStringFlags
2356 */
2357 static const ACEFLAG AceFlags[] =
2358 {
2359 { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
2360 { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
2361 { SDDL_INHERITED, INHERITED_ACE },
2362 { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
2363 { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
2364 { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
2365 { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
2366 { NULL, 0 },
2367 };
2368
2369 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
2370 {
2371 UINT len = 0;
2372 BYTE flags = 0;
2373 LPCWSTR szAcl = *StringAcl;
2374
2375 while (*szAcl == ' ')
2376 szAcl++;
2377
2378 while (*szAcl != ';')
2379 {
2380 const ACEFLAG *lpaf = AceFlags;
2381
2382 while (lpaf->wstr &&
2383 (len = strlenW(lpaf->wstr)) &&
2384 strncmpW(lpaf->wstr, szAcl, len))
2385 lpaf++;
2386
2387 if (!lpaf->wstr)
2388 return 0;
2389
2390 flags |= lpaf->value;
2391 szAcl += len;
2392 }
2393
2394 *StringAcl = szAcl;
2395 return flags;
2396 }
2397
2398
2399 /******************************************************************************
2400 * ParseAceStringRights
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(SidTable) / sizeof(SidTable[0]) - 1; i++)
3249 {
3250 if (wcscmp(StringSid, Sid