widl: Add support for function parameter flags to SLTG typelib generator.
[wine.git] / dlls / wow64 / security.c
blob1a3d98fcceeaf84c8bdadbfce94871cce4e02466
1 /*
2 * WoW64 security functions
4 * Copyright 2021 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <stdarg.h>
23 #include "ntstatus.h"
24 #define WIN32_NO_STATUS
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winnt.h"
28 #include "winternl.h"
29 #include "wow64_private.h"
30 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(wow);
35 static TOKEN_GROUPS *token_groups_32to64( const TOKEN_GROUPS32 *groups32 )
37 TOKEN_GROUPS *groups;
38 ULONG i;
40 if (!groups32) return NULL;
41 groups = Wow64AllocateTemp( offsetof( TOKEN_GROUPS, Groups[groups32->GroupCount] ));
42 groups->GroupCount = groups32->GroupCount;
43 for (i = 0; i < groups->GroupCount; i++)
45 groups->Groups[i].Sid = ULongToPtr( groups32->Groups[i].Sid );
46 groups->Groups[i].Attributes = groups32->Groups[i].Attributes;
48 return groups;
52 /**********************************************************************
53 * wow64_NtAccessCheck
55 NTSTATUS WINAPI wow64_NtAccessCheck( UINT *args )
57 SECURITY_DESCRIPTOR *sd32 = get_ptr( &args );
58 HANDLE handle = get_handle( &args );
59 ACCESS_MASK access = get_ulong( &args );
60 GENERIC_MAPPING *mapping = get_ptr( &args );
61 PRIVILEGE_SET *privs = get_ptr( &args );
62 ULONG *retlen = get_ptr( &args );
63 ACCESS_MASK *access_granted = get_ptr( &args );
64 NTSTATUS *access_status = get_ptr( &args );
66 SECURITY_DESCRIPTOR sd;
68 return NtAccessCheck( secdesc_32to64( &sd, sd32 ), handle, access, mapping,
69 privs, retlen, access_granted, access_status );
73 /**********************************************************************
74 * wow64_NtAccessCheckAndAuditAlarm
76 NTSTATUS WINAPI wow64_NtAccessCheckAndAuditAlarm( UINT *args )
78 UNICODE_STRING32 *subsystem32 = get_ptr( &args );
79 HANDLE handle = get_handle( &args );
80 UNICODE_STRING32 *typename32 = get_ptr( &args );
81 UNICODE_STRING32 *objname32 = get_ptr( &args );
82 SECURITY_DESCRIPTOR *sd32 = get_ptr( &args );
83 ACCESS_MASK access = get_ulong( &args );
84 GENERIC_MAPPING *mapping = get_ptr( &args );
85 BOOLEAN creation = get_ulong( &args );
86 ACCESS_MASK *access_granted = get_ptr( &args );
87 BOOLEAN *access_status = get_ptr( &args );
88 BOOLEAN *onclose = get_ptr( &args );
90 UNICODE_STRING subsystem, typename, objname;
91 SECURITY_DESCRIPTOR sd;
93 return NtAccessCheckAndAuditAlarm( unicode_str_32to64( &subsystem, subsystem32 ), handle,
94 unicode_str_32to64( &typename, typename32 ),
95 unicode_str_32to64( &objname, objname32 ),
96 secdesc_32to64( &sd, sd32 ), access, mapping, creation,
97 access_granted, access_status, onclose );
101 /**********************************************************************
102 * wow64_NtAdjustGroupsToken
104 NTSTATUS WINAPI wow64_NtAdjustGroupsToken( UINT *args )
106 HANDLE handle = get_handle( &args );
107 BOOLEAN reset = get_ulong( &args );
108 TOKEN_GROUPS32 *groups = get_ptr( &args );
109 ULONG len = get_ulong( &args );
110 TOKEN_GROUPS32 *prev = get_ptr( &args );
111 ULONG *retlen = get_ptr( &args );
113 FIXME( "%p %d %p %lu %p %p\n", handle, reset, groups, len, prev, retlen );
114 return STATUS_NOT_IMPLEMENTED;
118 /**********************************************************************
119 * wow64_NtAdjustPrivilegesToken
121 NTSTATUS WINAPI wow64_NtAdjustPrivilegesToken( UINT *args )
123 HANDLE handle = get_handle( &args );
124 BOOLEAN disable = get_ulong( &args );
125 TOKEN_PRIVILEGES *privs = get_ptr( &args );
126 ULONG len = get_ulong( &args );
127 TOKEN_PRIVILEGES *prev = get_ptr( &args );
128 ULONG *retlen = get_ptr( &args );
130 return NtAdjustPrivilegesToken( handle, disable, privs, len, prev, retlen );
134 /**********************************************************************
135 * wow64_NtCreateLowBoxToken
137 NTSTATUS WINAPI wow64_NtCreateLowBoxToken( UINT *args )
139 ULONG *handle_ptr = get_ptr( &args );
140 HANDLE token = get_handle( &args );
141 ACCESS_MASK access = get_ulong( &args );
142 OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args );
143 SID *sid = get_ptr( &args );
144 ULONG count = get_ulong( &args );
145 SID_AND_ATTRIBUTES32 *capabilities32 = get_ptr( &args );
146 ULONG handle_count = get_ulong( &args );
147 ULONG *handles32 = get_ptr( &args );
149 FIXME( "%p %p %lx %p %p %lu %p %lu %p: stub\n",
150 handle_ptr, token, access, attr32, sid, count, capabilities32, handle_count, handles32 );
152 *handle_ptr = 0;
153 return STATUS_SUCCESS;
157 /**********************************************************************
158 * wow64_NtCreateToken
160 NTSTATUS WINAPI wow64_NtCreateToken( UINT *args )
162 ULONG *handle_ptr = get_ptr( &args );
163 ACCESS_MASK access = get_ulong( &args );
164 OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args );
165 TOKEN_TYPE type = get_ulong( &args );
166 LUID *luid = get_ptr( &args );
167 LARGE_INTEGER *expire = get_ptr( &args );
168 TOKEN_USER32 *user32 = get_ptr( &args );
169 TOKEN_GROUPS32 *groups32 = get_ptr( &args );
170 TOKEN_PRIVILEGES *privs = get_ptr( &args );
171 TOKEN_OWNER32 *owner32 = get_ptr( &args );
172 TOKEN_PRIMARY_GROUP32 *group32 = get_ptr( &args );
173 TOKEN_DEFAULT_DACL32 *dacl32 = get_ptr( &args );
174 TOKEN_SOURCE *source = get_ptr( &args );
176 struct object_attr64 attr;
177 TOKEN_USER user;
178 TOKEN_OWNER owner;
179 TOKEN_PRIMARY_GROUP group;
180 TOKEN_DEFAULT_DACL dacl;
181 HANDLE handle = 0;
182 NTSTATUS status;
184 status = NtCreateToken( &handle, access, objattr_32to64( &attr, attr32 ), type, luid, expire,
185 token_user_32to64( &user, user32 ), token_groups_32to64( groups32 ), privs,
186 token_owner_32to64( &owner, owner32 ), token_primary_group_32to64( &group, group32 ),
187 token_default_dacl_32to64( &dacl, dacl32 ), source );
188 put_handle( handle_ptr, handle );
189 return status;
193 /**********************************************************************
194 * wow64_NtDuplicateToken
196 NTSTATUS WINAPI wow64_NtDuplicateToken( UINT *args )
198 HANDLE token = get_handle( &args );
199 ACCESS_MASK access = get_ulong( &args );
200 OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args );
201 BOOLEAN effective_only = get_ulong( &args );
202 TOKEN_TYPE type = get_ulong( &args );
203 ULONG *handle_ptr = get_ptr( &args );
205 struct object_attr64 attr;
206 HANDLE handle = 0;
207 NTSTATUS status;
209 *handle_ptr = 0;
210 status = NtDuplicateToken( token, access, objattr_32to64( &attr, attr32 ), effective_only, type, &handle );
211 put_handle( handle_ptr, handle );
212 return status;
216 /**********************************************************************
217 * wow64_NtFilterToken
219 NTSTATUS WINAPI wow64_NtFilterToken( UINT *args )
221 HANDLE token = get_handle( &args );
222 ULONG flags = get_ulong( &args );
223 TOKEN_GROUPS32 *disable_sids32 = get_ptr( &args );
224 TOKEN_PRIVILEGES *privs = get_ptr( &args );
225 TOKEN_GROUPS32 *restrict_sids32 = get_ptr( &args );
226 ULONG *handle_ptr = get_ptr( &args );
228 HANDLE handle = 0;
229 NTSTATUS status;
231 *handle_ptr = 0;
232 status = NtFilterToken( token, flags, token_groups_32to64( disable_sids32 ), privs,
233 token_groups_32to64( restrict_sids32 ), &handle );
234 put_handle( handle_ptr, handle );
235 return status;
239 /**********************************************************************
240 * wow64_NtCompareTokens
242 NTSTATUS WINAPI wow64_NtCompareTokens( UINT *args )
244 HANDLE first = get_handle( &args );
245 HANDLE second = get_handle( &args );
246 BOOLEAN *equal = get_ptr( &args );
248 return NtCompareTokens( first, second, equal );
251 /**********************************************************************
252 * wow64_NtImpersonateAnonymousToken
254 NTSTATUS WINAPI wow64_NtImpersonateAnonymousToken( UINT *args )
256 HANDLE handle = get_handle( &args );
258 return NtImpersonateAnonymousToken( handle );
262 /**********************************************************************
263 * wow64_NtOpenProcessToken
265 NTSTATUS WINAPI wow64_NtOpenProcessToken( UINT *args )
267 HANDLE process = get_handle( &args );
268 ACCESS_MASK access = get_ulong( &args );
269 ULONG *handle_ptr = get_ptr( &args );
271 HANDLE handle = 0;
272 NTSTATUS status;
274 *handle_ptr = 0;
275 status = NtOpenProcessToken( process, access, &handle );
276 put_handle( handle_ptr, handle );
277 return status;
281 /**********************************************************************
282 * wow64_NtOpenProcessTokenEx
284 NTSTATUS WINAPI wow64_NtOpenProcessTokenEx( UINT *args )
286 HANDLE process = get_handle( &args );
287 ACCESS_MASK access = get_ulong( &args );
288 ULONG attributes = get_ulong( &args );
289 ULONG *handle_ptr = get_ptr( &args );
291 HANDLE handle = 0;
292 NTSTATUS status;
294 *handle_ptr = 0;
295 status = NtOpenProcessTokenEx( process, access, attributes, &handle );
296 put_handle( handle_ptr, handle );
297 return status;
301 /**********************************************************************
302 * wow64_NtOpenThreadToken
304 NTSTATUS WINAPI wow64_NtOpenThreadToken( UINT *args )
306 HANDLE thread = get_handle( &args );
307 ACCESS_MASK access = get_ulong( &args );
308 BOOLEAN self = get_ulong( &args );
309 ULONG *handle_ptr = get_ptr( &args );
311 HANDLE handle = 0;
312 NTSTATUS status;
314 *handle_ptr = 0;
315 status = NtOpenThreadToken( thread, access, self, &handle );
316 put_handle( handle_ptr, handle );
317 return status;
321 /**********************************************************************
322 * wow64_NtOpenThreadTokenEx
324 NTSTATUS WINAPI wow64_NtOpenThreadTokenEx( UINT *args )
326 HANDLE thread = get_handle( &args );
327 ACCESS_MASK access = get_ulong( &args );
328 BOOLEAN self = get_ulong( &args );
329 ULONG attributes = get_ulong( &args );
330 ULONG *handle_ptr = get_ptr( &args );
332 HANDLE handle = 0;
333 NTSTATUS status;
335 *handle_ptr = 0;
336 status = NtOpenThreadTokenEx( thread, access, self, attributes, &handle );
337 put_handle( handle_ptr, handle );
338 return status;
342 /**********************************************************************
343 * wow64_NtPrivilegeCheck
345 NTSTATUS WINAPI wow64_NtPrivilegeCheck( UINT *args )
347 HANDLE token = get_handle( &args );
348 PRIVILEGE_SET *privs = get_ptr( &args );
349 BOOLEAN *res = get_ptr( &args );
351 return NtPrivilegeCheck( token, privs, res );
355 /**********************************************************************
356 * wow64_NtQueryInformationToken
358 NTSTATUS WINAPI wow64_NtQueryInformationToken( UINT *args )
360 HANDLE handle = get_handle( &args );
361 TOKEN_INFORMATION_CLASS class = get_ulong( &args );
362 void *info = get_ptr( &args );
363 ULONG len = get_ulong( &args );
364 ULONG *retlen = get_ptr( &args );
366 NTSTATUS status;
367 ULONG ret_size, sid_len;
369 switch (class)
371 case TokenPrivileges: /* TOKEN_PRIVILEGES */
372 case TokenImpersonationLevel: /* SECURITY_IMPERSONATION_LEVEL */
373 case TokenStatistics: /* TOKEN_STATISTICS */
374 case TokenType: /* TOKEN_TYPE */
375 case TokenElevationType: /* TOKEN_ELEVATION_TYPE */
376 case TokenElevation: /* TOKEN_ELEVATION */
377 case TokenSessionId: /* ULONG */
378 case TokenVirtualizationEnabled: /* ULONG */
379 case TokenIsAppContainer: /* ULONG */
380 /* nothing to map */
381 return NtQueryInformationToken( handle, class, info, len, retlen );
383 case TokenUser: /* TOKEN_USER + SID */
384 case TokenIntegrityLevel: /* TOKEN_MANDATORY_LABEL + SID */
386 ULONG_PTR buffer[(sizeof(TOKEN_USER) + SECURITY_MAX_SID_SIZE) / sizeof(ULONG_PTR)];
387 TOKEN_USER *user = (TOKEN_USER *)buffer;
388 TOKEN_USER32 *user32 = info;
389 SID *sid;
391 status = NtQueryInformationToken( handle, class, &buffer, sizeof(buffer), &ret_size );
392 if (status) return status;
393 sid = user->User.Sid;
394 sid_len = offsetof( SID, SubAuthority[sid->SubAuthorityCount] );
395 if (len >= sizeof(*user32) + sid_len)
397 user32->User.Sid = PtrToUlong( user32 + 1 );
398 user32->User.Attributes = user->User.Attributes;
399 memcpy( user32 + 1, sid, sid_len );
401 else status = STATUS_BUFFER_TOO_SMALL;
402 if (retlen) *retlen = sizeof(*user32) + sid_len;
403 return status;
406 case TokenOwner: /* TOKEN_OWNER + SID */
407 case TokenPrimaryGroup: /* TOKEN_PRIMARY_GROUP + SID */
408 case TokenAppContainerSid: /* TOKEN_APPCONTAINER_INFORMATION + SID */
410 ULONG_PTR buffer[(sizeof(TOKEN_OWNER) + SECURITY_MAX_SID_SIZE) / sizeof(ULONG_PTR)];
411 TOKEN_OWNER *owner = (TOKEN_OWNER *)buffer;
412 TOKEN_OWNER32 *owner32 = info;
413 SID *sid;
415 status = NtQueryInformationToken( handle, class, &buffer, sizeof(buffer), &ret_size );
416 if (status) return status;
417 sid = owner->Owner;
418 sid_len = offsetof( SID, SubAuthority[sid->SubAuthorityCount] );
419 if (len >= sizeof(*owner32) + sid_len)
421 owner32->Owner = PtrToUlong( owner32 + 1 );
422 memcpy( owner32 + 1, sid, sid_len );
424 else status = STATUS_BUFFER_TOO_SMALL;
425 if (retlen) *retlen = sizeof(*owner32) + sid_len;
426 return status;
429 case TokenGroups: /* TOKEN_GROUPS */
430 case TokenLogonSid: /* TOKEN_GROUPS */
432 TOKEN_GROUPS32 *groups32 = info;
433 TOKEN_GROUPS *groups;
434 ULONG i, group_len, group32_len;
436 status = NtQueryInformationToken( handle, class, NULL, 0, &ret_size );
437 if (status != STATUS_BUFFER_TOO_SMALL) return status;
438 groups = Wow64AllocateTemp( ret_size );
439 status = NtQueryInformationToken( handle, class, groups, ret_size, &ret_size );
440 if (status) return status;
441 group_len = offsetof( TOKEN_GROUPS, Groups[groups->GroupCount] );
442 group32_len = offsetof( TOKEN_GROUPS32, Groups[groups->GroupCount] );
443 sid_len = ret_size - group_len;
444 ret_size = group32_len + sid_len;
445 if (len >= ret_size)
447 SID *sid = (SID *)((char *)groups + group_len);
448 SID *sid32 = (SID *)((char *)groups32 + group32_len);
450 memcpy( sid32, sid, sid_len );
451 groups32->GroupCount = groups->GroupCount;
452 for (i = 0; i < groups->GroupCount; i++)
454 groups32->Groups[i].Sid = PtrToUlong(sid32) + ((char *)groups->Groups[i].Sid - (char *)sid);
455 groups32->Groups[i].Attributes = groups->Groups[i].Attributes;
458 else status = STATUS_BUFFER_TOO_SMALL;
459 if (retlen) *retlen = ret_size;
460 return status;
463 case TokenDefaultDacl: /* TOKEN_DEFAULT_DACL + ACL */
465 ULONG size = len + sizeof(TOKEN_DEFAULT_DACL) - sizeof(TOKEN_DEFAULT_DACL32);
466 TOKEN_DEFAULT_DACL32 *dacl32 = info;
467 TOKEN_DEFAULT_DACL *dacl = Wow64AllocateTemp( size );
469 status = NtQueryInformationToken( handle, class, dacl, size, &ret_size );
470 if (!status)
472 dacl32->DefaultDacl = dacl->DefaultDacl ? PtrToUlong( dacl32 + 1 ) : 0;
473 memcpy( dacl32 + 1, dacl->DefaultDacl, ret_size - sizeof(*dacl) );
475 if (retlen) *retlen = ret_size + sizeof(*dacl32) - sizeof(*dacl);
476 return status;
479 case TokenLinkedToken: /* TOKEN_LINKED_TOKEN */
481 TOKEN_LINKED_TOKEN link;
483 status = NtQueryInformationToken( handle, class, &link, sizeof(link), &ret_size );
484 if (!status) *(ULONG *)info = HandleToLong( link.LinkedToken );
485 if (retlen) *retlen = sizeof(ULONG);
486 return status;
489 default:
490 FIXME( "unsupported class %u\n", class );
491 return STATUS_INVALID_INFO_CLASS;
496 /**********************************************************************
497 * wow64_NtQuerySecurityObject
499 NTSTATUS WINAPI wow64_NtQuerySecurityObject( UINT *args )
501 HANDLE handle = get_handle( &args );
502 SECURITY_INFORMATION info = get_ulong( &args );
503 SECURITY_DESCRIPTOR *sd = get_ptr( &args );
504 ULONG len = get_ulong( &args );
505 ULONG *retlen = get_ptr( &args );
507 /* returned descriptor is always SE_SELF_RELATIVE, no mapping needed */
508 return NtQuerySecurityObject( handle, info, sd, len, retlen );
512 /**********************************************************************
513 * wow64_NtSetInformationToken
515 NTSTATUS WINAPI wow64_NtSetInformationToken( UINT *args )
517 HANDLE handle = get_handle( &args );
518 TOKEN_INFORMATION_CLASS class = get_ulong( &args );
519 void *ptr = get_ptr( &args );
520 ULONG len = get_ulong( &args );
522 switch (class)
524 case TokenSessionId: /* ULONG */
525 return NtSetInformationToken( handle, class, ptr, len );
527 case TokenDefaultDacl: /* TOKEN_DEFAULT_DACL */
528 if (len >= sizeof(TOKEN_DEFAULT_DACL32))
530 TOKEN_DEFAULT_DACL32 *dacl32 = ptr;
531 TOKEN_DEFAULT_DACL dacl = { ULongToPtr( dacl32->DefaultDacl ) };
533 return NtSetInformationToken( handle, class, &dacl, sizeof(dacl) );
535 else return STATUS_INFO_LENGTH_MISMATCH;
537 default:
538 FIXME( "unsupported class %u\n", class );
539 return STATUS_NOT_IMPLEMENTED;
544 /**********************************************************************
545 * wow64_NtSetSecurityObject
547 NTSTATUS WINAPI wow64_NtSetSecurityObject( UINT *args )
549 HANDLE handle = get_handle( &args );
550 SECURITY_INFORMATION info = get_ulong( &args );
551 SECURITY_DESCRIPTOR *sd32 = get_ptr( &args );
553 SECURITY_DESCRIPTOR sd;
555 return NtSetSecurityObject( handle, info, secdesc_32to64( &sd, sd32 ));