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