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