ReactOS 0.4.15-dev-8428-g6910fa6
NtAccessCheckByType.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS API tests
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Tests for the NtAccessCheckByType API
5 * COPYRIGHT: Copyright 2023 George Bișoc <george.bisoc@reactos.org>
6 */
7
8#include "precomp.h"
9
11static GUID ObjectType = {0x12345678, 0x1234, 0x5678, {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}};
12static GUID ChildObjectType = {0x23456789, 0x2345, 0x6786, {0x2, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99}};
15
16static
19 _In_ BOOLEAN WantImpersonateLevel,
20 _In_ BOOLEAN WantImpersonateType)
21{
24 HANDLE DuplicatedToken;
27
30 &Token);
31 if (!NT_SUCCESS(Status))
32 {
33 trace("Failed to get current process token (Status 0x%08lx)\n", Status);
34 return NULL;
35 }
36
38 Sqos.ImpersonationLevel = WantImpersonateLevel ? SecurityImpersonation : SecurityAnonymous;
39 Sqos.ContextTrackingMode = 0;
40 Sqos.EffectiveOnly = FALSE;
41
43 NULL,
44 0,
45 NULL,
46 NULL);
47 ObjectAttributes.SecurityQualityOfService = &Sqos;
48
52 FALSE,
53 WantImpersonateType ? TokenImpersonation : TokenPrimary,
54 &DuplicatedToken);
55 if (!NT_SUCCESS(Status))
56 {
57 trace("Failed to duplicate token (Status 0x%08lx)\n", Status);
59 return NULL;
60 }
61
62 return DuplicatedToken;
63}
64
65static
66VOID
68{
72 PPRIVILEGE_SET PrivilegeSet = NULL;
73 ULONG PrivilegeSetLength;
76 OBJECT_TYPE_LIST ObjTypeList[2];
77
78 /* Everything is NULL */
80 NULL,
81 NULL,
82 0,
83 NULL,
84 0,
85 NULL,
86 NULL,
87 0,
88 NULL,
89 NULL);
91
92 /* Allocate a buffer for privileges set */
93 PrivilegeSetLength = FIELD_OFFSET(PRIVILEGE_SET, Privilege[16]);
94 PrivilegeSet = RtlAllocateHeap(RtlGetProcessHeap(), 0, PrivilegeSetLength);
95 if (PrivilegeSet == NULL)
96 {
97 skip("Failed to allocate PrivilegeSet, skipping tests\n");
98 goto Quit;
99 }
100
101 /* No token given */
103 NULL,
104 NULL,
106 NULL,
107 0,
108 &RegMapping,
109 PrivilegeSet,
110 &PrivilegeSetLength,
112 &AccessStatus);
114
115 /* Get a token now */
117 if (Token == NULL)
118 {
119 skip("Failed to get token, skipping tests\n");
120 goto Quit;
121 }
122
123 /* Token given but it's not an impersonation one */
125 NULL,
126 Token,
128 NULL,
129 0,
130 &RegMapping,
131 PrivilegeSet,
132 &PrivilegeSetLength,
134 &AccessStatus);
136
137 /* Get a token but this time with an invalid impersonation level */
138 NtClose(Token);
140 if (Token == NULL)
141 {
142 skip("Failed to get token, skipping tests\n");
143 goto Quit;
144 }
145
146 /* Token given but it doesn't have the right impersonation level */
148 NULL,
149 Token,
151 NULL,
152 0,
153 &RegMapping,
154 PrivilegeSet,
155 &PrivilegeSetLength,
157 &AccessStatus);
159
160 /* A generic access right is given */
162 NULL,
163 Token,
165 NULL,
166 0,
167 &RegMapping,
168 PrivilegeSet,
169 &PrivilegeSetLength,
171 &AccessStatus);
173
174 /* Close the token, get a valid one that we want */
175 NtClose(Token);
177 if (Token == NULL)
178 {
179 skip("Failed to get token, skipping tests\n");
180 goto Quit;
181 }
182
183 /* No security descriptor is given */
185 NULL,
186 Token,
188 NULL,
189 0,
190 &RegMapping,
191 PrivilegeSet,
192 &PrivilegeSetLength,
194 &AccessStatus);
196
197 /* The function expects a privilege set */
199 NULL,
200 Token,
202 NULL,
203 0,
204 &RegMapping,
205 NULL,
206 0,
208 &AccessStatus);
210
211 /* Create a security descriptor */
213 if (!NT_SUCCESS(Status))
214 {
215 skip("Failed to create a security descriptor, skipping tests\n");
216 goto Quit;
217 }
218
219 /* This descriptor will have no group, owner and DACL */
223
224 /* Give the invalid descriptor */
226 NULL,
227 Token,
229 NULL,
230 0,
231 &RegMapping,
232 PrivilegeSet,
233 &PrivilegeSetLength,
235 &AccessStatus);
237
238 /* Give a bogus principal SID */
240 (PSID)1,
241 Token,
243 NULL,
244 0,
245 &RegMapping,
246 PrivilegeSet,
247 &PrivilegeSetLength,
249 &AccessStatus);
250
251 /*
252 * On newer versions of Windows such as 10 the principal SID is validated
253 * after the security descriptor so it will always trigger an invalid
254 * descriptor case. On Windows Server 2003 the principal SID is captured
255 * before the security descriptor. ReactOS currently follows the Windows
256 * 10's behavior.
257 */
259 "STATUS_ACCESS_VIOLATION or STATUS_INVALID_SECURITY_DESCR expected, got 0x%lx\n", Status);
260
261 /* The first object element is not the root */
262 ObjTypeList[0].Level = ACCESS_PROPERTY_SET_GUID;
263 ObjTypeList[0].Sbz = 0;
264 ObjTypeList[0].ObjectType = &ObjectType;
265
266 /* Give a bogus list */
268 (PSID)1,
269 Token,
271 ObjTypeList,
272 RTL_NUMBER_OF(ObjTypeList),
273 &RegMapping,
274 PrivilegeSet,
275 &PrivilegeSetLength,
277 &AccessStatus);
279
280 /* This list has two roots */
281 ObjTypeList[0].Level = ACCESS_OBJECT_GUID;
282 ObjTypeList[0].Sbz = 0;
283 ObjTypeList[0].ObjectType = &ObjectType;
284
285 ObjTypeList[1].Level = ACCESS_OBJECT_GUID;
286 ObjTypeList[1].Sbz = 0;
287 ObjTypeList[1].ObjectType = &ChildObjectType;
288
289 /* Give a bogus list */
291 (PSID)1,
292 Token,
294 ObjTypeList,
295 RTL_NUMBER_OF(ObjTypeList),
296 &RegMapping,
297 PrivilegeSet,
298 &PrivilegeSetLength,
300 &AccessStatus);
302
303 /* This list has an object whose level is invalid */
304 ObjTypeList[0].Level = 0xa;
305 ObjTypeList[0].Sbz = 0;
306 ObjTypeList[0].ObjectType = &ObjectType;
307
308 /* Give a bogus list */
310 (PSID)1,
311 Token,
313 ObjTypeList,
314 RTL_NUMBER_OF(ObjTypeList),
315 &RegMapping,
316 PrivilegeSet,
317 &PrivilegeSetLength,
319 &AccessStatus);
321
322 /* This list doesn't have consistent object levels */
323 ObjTypeList[0].Level = ACCESS_OBJECT_GUID;
324 ObjTypeList[0].Sbz = 0;
325 ObjTypeList[0].ObjectType = &ObjectType;
326
327 ObjTypeList[1].Level = ACCESS_PROPERTY_GUID;
328 ObjTypeList[1].Sbz = 0;
329 ObjTypeList[1].ObjectType = &ChildObjectType;
330
331 /* Give a bogus list */
333 (PSID)1,
334 Token,
336 ObjTypeList,
337 RTL_NUMBER_OF(ObjTypeList),
338 &RegMapping,
339 PrivilegeSet,
340 &PrivilegeSetLength,
342 &AccessStatus);
344
345Quit:
346 if (Token)
347 {
348 NtClose(Token);
349 }
350
351 if (PrivilegeSet)
352 {
353 RtlFreeHeap(RtlGetProcessHeap(), 0, PrivilegeSet);
354 }
355}
356
357static
358VOID
360{
364 PPRIVILEGE_SET PrivilegeSet = NULL;
365 ULONG PrivilegeSetLength;
366 HANDLE Token = NULL;
368 OBJECT_TYPE_LIST ObjTypeList[2];
369 PSID AdminSid = NULL, UsersSid = NULL;
370
371 /* Allocate all the stuff we need */
372 PrivilegeSetLength = FIELD_OFFSET(PRIVILEGE_SET, Privilege[16]);
373 PrivilegeSet = RtlAllocateHeap(RtlGetProcessHeap(), 0, PrivilegeSetLength);
374 if (PrivilegeSet == NULL)
375 {
376 skip("Failed to allocate PrivilegeSet, skipping tests\n");
377 return;
378 }
379
381 2,
384 0,
385 0,
386 0,
387 0,
388 0,
389 0,
390 &AdminSid);
391 if (!NT_SUCCESS(Status))
392 {
393 skip("Failed to create Admins SID, skipping tests\n");
394 goto Quit;
395 }
396
398 2,
401 0,
402 0,
403 0,
404 0,
405 0,
406 0,
407 &UsersSid);
408 if (!NT_SUCCESS(Status))
409 {
410 skip("Failed to create User SID, skipping tests\n");
411 goto Quit;
412 }
413
415 if (Token == NULL)
416 {
417 skip("Failed to get token, skipping tests\n");
418 goto Quit;
419 }
420
422 if (!NT_SUCCESS(Status))
423 {
424 skip("Failed to create a security descriptor, skipping tests\n");
425 goto Quit;
426 }
427
428 /* Setup the descriptor with no DACL */
429 RtlSetGroupSecurityDescriptor(&Sd, UsersSid, FALSE);
432
433 /* Setup the object type list */
434 ObjTypeList[0].Level = ACCESS_OBJECT_GUID;
435 ObjTypeList[0].Sbz = 0;
436 ObjTypeList[0].ObjectType = &ObjectType;
437
438 ObjTypeList[1].Level = ACCESS_PROPERTY_SET_GUID;
439 ObjTypeList[1].Sbz = 0;
440 ObjTypeList[1].ObjectType = &ChildObjectType;
441
442 /*
443 * Evaluate the access -- a SD with no DACL is always a granted
444 * access as no ACL is enforced to protect the object.
445 */
447 NULL,
448 Token,
449 KEY_READ,
450 ObjTypeList,
451 RTL_NUMBER_OF(ObjTypeList),
452 &RegMapping,
453 PrivilegeSet,
454 &PrivilegeSetLength,
456 &AccessStatus);
458 ok(GrantedAccess == KEY_READ, "Expected KEY_READ as granted right but got 0x%08lx\n", GrantedAccess);
459 ok(AccessStatus == STATUS_SUCCESS, "Expected a success status but got 0x%08lx\n", AccessStatus);
460 ok(PrivilegeSet != NULL, "PrivilegeSet is NULL when it mustn't be!\n");
461 ok(PrivilegeSetLength != 0, "PrivilegeSetLength mustn't be 0!\n");
462
463 /* Evaluate access for MAXIMUM_ALLOWED as well */
465 NULL,
466 Token,
468 ObjTypeList,
469 RTL_NUMBER_OF(ObjTypeList),
470 &RegMapping,
471 PrivilegeSet,
472 &PrivilegeSetLength,
474 &AccessStatus);
476 ok(GrantedAccess == KEY_ALL_ACCESS, "Expected KEY_ALL_ACCESS as granted right but got 0x%08lx\n", GrantedAccess);
477 ok(AccessStatus == STATUS_SUCCESS, "Expected a success status but got 0x%08lx\n", AccessStatus);
478 ok(PrivilegeSet != NULL, "PrivilegeSet is NULL when it mustn't be!\n");
479 ok(PrivilegeSetLength != 0, "PrivilegeSetLength mustn't be 0!\n");
480
481 /*
482 * Evaluate access but with no object type list.
483 * NtAccessCheckByType will be treated as a normal NtAccessCheck.
484 */
486 NULL,
487 Token,
488 KEY_READ,
489 NULL,
490 0,
491 &RegMapping,
492 PrivilegeSet,
493 &PrivilegeSetLength,
495 &AccessStatus);
497 ok(GrantedAccess == KEY_READ, "Expected KEY_READ as granted right but got 0x%08lx\n", GrantedAccess);
498 ok(AccessStatus == STATUS_SUCCESS, "Expected a success status but got 0x%08lx\n", AccessStatus);
499 ok(PrivilegeSet != NULL, "PrivilegeSet is NULL when it mustn't be!\n");
500 ok(PrivilegeSetLength != 0, "PrivilegeSetLength mustn't be 0!\n");
501
502Quit:
503 if (Token)
504 {
505 NtClose(Token);
506 }
507
508 if (UsersSid)
509 {
510 RtlFreeSid(UsersSid);
511 }
512
513 if (AdminSid)
514 {
516 }
517
518 if (PrivilegeSet)
519 {
520 RtlFreeHeap(RtlGetProcessHeap(), 0, PrivilegeSet);
521 }
522}
523
524static
525VOID
527{
531 PPRIVILEGE_SET PrivilegeSet = NULL;
532 ULONG PrivilegeSetLength;
533 HANDLE Token = NULL;
534 PACL Dacl = NULL;
537 OBJECT_TYPE_LIST ObjTypeList[2];
538 PSID EveryoneSid = NULL, AdminSid = NULL, UsersSid = NULL;
539
540 /* Allocate all the stuff we need */
541 PrivilegeSetLength = FIELD_OFFSET(PRIVILEGE_SET, Privilege[16]);
542 PrivilegeSet = RtlAllocateHeap(RtlGetProcessHeap(), 0, PrivilegeSetLength);
543 if (PrivilegeSet == NULL)
544 {
545 skip("Failed to allocate PrivilegeSet, skipping tests\n");
546 return;
547 }
548
550 1,
552 0,
553 0,
554 0,
555 0,
556 0,
557 0,
558 0,
559 &EveryoneSid);
560 if (!NT_SUCCESS(Status))
561 {
562 skip("Failed to create Everyone SID, skipping tests\n");
563 goto Quit;
564 }
565
567 2,
570 0,
571 0,
572 0,
573 0,
574 0,
575 0,
576 &AdminSid);
577 if (!NT_SUCCESS(Status))
578 {
579 skip("Failed to create Admins SID, skipping tests\n");
580 goto Quit;
581 }
582
584 2,
587 0,
588 0,
589 0,
590 0,
591 0,
592 0,
593 &UsersSid);
594 if (!NT_SUCCESS(Status))
595 {
596 skip("Failed to create User SID, skipping tests\n");
597 goto Quit;
598 }
599
601 if (Token == NULL)
602 {
603 skip("Failed to get token, skipping tests\n");
604 goto Quit;
605 }
606
608 if (!NT_SUCCESS(Status))
609 {
610 skip("Failed to create a security descriptor, skipping tests\n");
611 goto Quit;
612 }
613
614 DaclSize = sizeof(ACL) +
615 sizeof(ACCESS_ALLOWED_OBJECT_ACE) + RtlLengthSid(EveryoneSid) +
617 Dacl = RtlAllocateHeap(RtlGetProcessHeap(),
619 DaclSize);
620 if (Dacl == NULL)
621 {
622 skip("Failed to allocate memory for DACL, skipping tests\n");
623 goto Quit;
624 }
625
626 /*
627 * Create an ordinary ACL with an old revision. Object types are supported
628 * starting with Revision 4, so adding ACEs to it will fail.
629 */
631 DaclSize,
633 if (!NT_SUCCESS(Status))
634 {
635 skip("Failed to create DACL, skipping tests\n");
636 goto Quit;
637 }
638
641 0,
642 KEY_READ,
643 &ObjectType,
644 NULL,
645 EveryoneSid);
647
648 /* Free the ACL and create a proper one with correct revision */
649 RtlFreeHeap(RtlGetProcessHeap(), 0, Dacl);
650 Dacl = RtlAllocateHeap(RtlGetProcessHeap(),
652 DaclSize);
653 if (Dacl == NULL)
654 {
655 skip("Failed to allocate memory for DACL, skipping tests\n");
656 goto Quit;
657 }
658
660 DaclSize,
662 if (!NT_SUCCESS(Status))
663 {
664 skip("Failed to create DACL, skipping tests\n");
665 goto Quit;
666 }
667
668 /* Setup ACEs -- READ for everyone and READ/WRITE for admins */
671 0,
672 KEY_READ,
673 &ObjectType,
674 NULL,
675 EveryoneSid);
676 if (!NT_SUCCESS(Status))
677 {
678 skip("Failed to add allowed object ACE for Everyone SID, skipping tests\n");
679 goto Quit;
680 }
681
684 0,
686 &ObjectType,
687 NULL,
688 AdminSid);
689 if (!NT_SUCCESS(Status))
690 {
691 skip("Failed to add allowed object ACE for Admins SID, skipping tests\n");
692 goto Quit;
693 }
694
695 /* Setup the descriptor */
696 RtlSetGroupSecurityDescriptor(&Sd, UsersSid, FALSE);
699
700 /* Setup the object type list */
701 ObjTypeList[0].Level = ACCESS_OBJECT_GUID;
702 ObjTypeList[0].Sbz = 0;
703 ObjTypeList[0].ObjectType = &ObjectType;
704
705 ObjTypeList[1].Level = ACCESS_PROPERTY_SET_GUID;
706 ObjTypeList[1].Sbz = 0;
707 ObjTypeList[1].ObjectType = &ChildObjectType;
708
709 /* Evaluate access -- KEY_READ has to be granted */
711 NULL,
712 Token,
713 KEY_READ,
714 ObjTypeList,
715 RTL_NUMBER_OF(ObjTypeList),
716 &RegMapping,
717 PrivilegeSet,
718 &PrivilegeSetLength,
720 &AccessStatus);
722 ok(GrantedAccess == KEY_READ, "Expected KEY_READ as granted right but got 0x%08lx\n", GrantedAccess);
723 ok(AccessStatus == STATUS_SUCCESS, "Expected a success status but got 0x%08lx\n", AccessStatus);
724 ok(PrivilegeSet != NULL, "PrivilegeSet is NULL when it mustn't be!\n");
725 ok(PrivilegeSetLength != 0, "PrivilegeSetLength mustn't be 0!\n");
726
727 /* Admins should be granted WRITE access */
729 NULL,
730 Token,
731 KEY_WRITE,
732 ObjTypeList,
733 RTL_NUMBER_OF(ObjTypeList),
734 &RegMapping,
735 PrivilegeSet,
736 &PrivilegeSetLength,
738 &AccessStatus);
740 ok(GrantedAccess == KEY_WRITE, "Expected KEY_WRITE as granted right but got 0x%08lx\n", GrantedAccess);
741 ok(AccessStatus == STATUS_SUCCESS, "Expected a success status but got 0x%08lx\n", AccessStatus);
742 ok(PrivilegeSet != NULL, "PrivilegeSet is NULL when it mustn't be!\n");
743 ok(PrivilegeSetLength != 0, "PrivilegeSetLength mustn't be 0!\n");
744
745Quit:
746 if (Dacl)
747 {
748 RtlFreeHeap(RtlGetProcessHeap(), 0, Dacl);
749 }
750
751 if (Token)
752 {
753 NtClose(Token);
754 }
755
756 if (UsersSid)
757 {
758 RtlFreeSid(UsersSid);
759 }
760
761 if (AdminSid)
762 {
764 }
765
766 if (EveryoneSid)
767 {
768 RtlFreeSid(EveryoneSid);
769 }
770
771 if (PrivilegeSet)
772 {
773 RtlFreeHeap(RtlGetProcessHeap(), 0, PrivilegeSet);
774 }
775}
776
777static
778VOID
780{
784 PPRIVILEGE_SET PrivilegeSet = NULL;
785 ULONG PrivilegeSetLength;
786 HANDLE Token = NULL;
787 PACL Dacl = NULL;
790 OBJECT_TYPE_LIST ObjTypeList[6];
791 PSID EveryoneSid = NULL, AdminSid = NULL, UsersSid = NULL;
792 GUID ChildObjectType2 = {0x34578901, 0x3456, 0x7896, {0x3, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0x00}};
793 GUID ChildObjectType3 = {0x45678901, 0x4567, 0x1122, {0x4, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x01}};
794 GUID ChildObjectType4 = {0x56788901, 0x1111, 0x2222, {0x5, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x02}};
795 GUID ChildObjectType5 = {0x67901234, 0x2222, 0x3333, {0x4, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x03}};
796
797 /* Allocate all the stuff we need */
798 PrivilegeSetLength = FIELD_OFFSET(PRIVILEGE_SET, Privilege[16]);
799 PrivilegeSet = RtlAllocateHeap(RtlGetProcessHeap(), 0, PrivilegeSetLength);
800 if (PrivilegeSet == NULL)
801 {
802 skip("Failed to allocate PrivilegeSet, skipping tests\n");
803 return;
804 }
805
807 1,
809 0,
810 0,
811 0,
812 0,
813 0,
814 0,
815 0,
816 &EveryoneSid);
817 if (!NT_SUCCESS(Status))
818 {
819 skip("Failed to create Everyone SID, skipping tests\n");
820 goto Quit;
821 }
822
824 2,
827 0,
828 0,
829 0,
830 0,
831 0,
832 0,
833 &AdminSid);
834 if (!NT_SUCCESS(Status))
835 {
836 skip("Failed to create Admins SID, skipping tests\n");
837 goto Quit;
838 }
839
841 2,
844 0,
845 0,
846 0,
847 0,
848 0,
849 0,
850 &UsersSid);
851 if (!NT_SUCCESS(Status))
852 {
853 skip("Failed to create User SID, skipping tests\n");
854 goto Quit;
855 }
856
858 if (Token == NULL)
859 {
860 skip("Failed to get token, skipping tests\n");
861 goto Quit;
862 }
863
865 if (!NT_SUCCESS(Status))
866 {
867 skip("Failed to create a security descriptor, skipping tests\n");
868 goto Quit;
869 }
870
871 DaclSize = sizeof(ACL) +
873 sizeof(ACCESS_ALLOWED_OBJECT_ACE) + RtlLengthSid(EveryoneSid) +
874 sizeof(ACCESS_ALLOWED_OBJECT_ACE) + RtlLengthSid(EveryoneSid) +
875 sizeof(ACCESS_ALLOWED_OBJECT_ACE) + RtlLengthSid(EveryoneSid) +
876 sizeof(ACCESS_ALLOWED_OBJECT_ACE) + RtlLengthSid(EveryoneSid) +
877 sizeof(ACCESS_ALLOWED_OBJECT_ACE) + RtlLengthSid(EveryoneSid);
878 Dacl = RtlAllocateHeap(RtlGetProcessHeap(),
880 DaclSize);
881 if (Dacl == NULL)
882 {
883 skip("Failed to allocate memory for DACL, skipping tests\n");
884 goto Quit;
885 }
886
888 DaclSize,
890 if (!NT_SUCCESS(Status))
891 {
892 skip("Failed to create DACL, skipping tests\n");
893 goto Quit;
894 }
895
896 /* Setup some rights for these objects, admins are granted everything */
899 0,
901 &ObjectType,
902 NULL,
903 AdminSid);
904 if (!NT_SUCCESS(Status))
905 {
906 skip("Failed to add allowed object ACE for Admins SID, skipping tests\n");
907 goto Quit;
908 }
909
912 0,
913 KEY_READ,
915 NULL,
916 EveryoneSid);
917 if (!NT_SUCCESS(Status))
918 {
919 skip("Failed to add allowed object ACE for Everyone SID, skipping tests\n");
920 goto Quit;
921 }
922
925 0,
926 KEY_WRITE,
927 &ChildObjectType2,
928 NULL,
929 EveryoneSid);
930 if (!NT_SUCCESS(Status))
931 {
932 skip("Failed to add allowed object ACE for Everyone SID, skipping tests\n");
933 goto Quit;
934 }
935
938 0,
940 &ChildObjectType3,
941 NULL,
942 EveryoneSid);
943 if (!NT_SUCCESS(Status))
944 {
945 skip("Failed to add allowed object ACE for Everyone SID, skipping tests\n");
946 goto Quit;
947 }
948
951 0,
953 &ChildObjectType4,
954 NULL,
955 EveryoneSid);
956 if (!NT_SUCCESS(Status))
957 {
958 skip("Failed to add allowed object ACE for Everyone SID, skipping tests\n");
959 goto Quit;
960 }
961
964 0,
966 &ChildObjectType5,
967 NULL,
968 EveryoneSid);
969 if (!NT_SUCCESS(Status))
970 {
971 skip("Failed to add allowed object ACE for Everyone SID, skipping tests\n");
972 goto Quit;
973 }
974
975 /* Setup the descriptor */
976 RtlSetGroupSecurityDescriptor(&Sd, UsersSid, FALSE);
979
980 /* Setup the object type list */
981 ObjTypeList[0].Level = ACCESS_OBJECT_GUID;
982 ObjTypeList[0].Sbz = 0;
983 ObjTypeList[0].ObjectType = &ObjectType;
984
985 ObjTypeList[1].Level = ACCESS_PROPERTY_SET_GUID;
986 ObjTypeList[1].Sbz = 0;
987 ObjTypeList[1].ObjectType = &ChildObjectType;
988
989 ObjTypeList[2].Level = ACCESS_PROPERTY_GUID;
990 ObjTypeList[2].Sbz = 0;
991 ObjTypeList[2].ObjectType = &ChildObjectType2;
992
993 ObjTypeList[3].Level = ACCESS_PROPERTY_GUID;
994 ObjTypeList[3].Sbz = 0;
995 ObjTypeList[3].ObjectType = &ChildObjectType3;
996
997 ObjTypeList[4].Level = ACCESS_PROPERTY_SET_GUID;
998 ObjTypeList[4].Sbz = 0;
999 ObjTypeList[4].ObjectType = &ChildObjectType4;
1000
1001 ObjTypeList[5].Level = ACCESS_PROPERTY_GUID;
1002 ObjTypeList[5].Sbz = 0;
1003 ObjTypeList[5].ObjectType = &ChildObjectType5;
1004
1005 /* Evaluate access for each object case */
1007 NULL,
1008 Token,
1010 ObjTypeList,
1011 RTL_NUMBER_OF(ObjTypeList),
1012 &RegMapping,
1013 PrivilegeSet,
1014 &PrivilegeSetLength,
1016 &AccessStatus);
1018 ok(GrantedAccess == KEY_ALL_ACCESS, "Expected KEY_ALL_ACCESS as granted right but got 0x%08lx\n", GrantedAccess);
1019 ok(AccessStatus == STATUS_SUCCESS, "Expected a success status but got 0x%08lx\n", AccessStatus);
1020
1022 NULL,
1023 Token,
1024 KEY_READ,
1025 ObjTypeList,
1026 RTL_NUMBER_OF(ObjTypeList),
1027 &RegMapping,
1028 PrivilegeSet,
1029 &PrivilegeSetLength,
1031 &AccessStatus);
1033 ok(GrantedAccess == KEY_READ, "Expected KEY_READ as granted right but got 0x%08lx\n", GrantedAccess);
1034 ok(AccessStatus == STATUS_SUCCESS, "Expected a success status but got 0x%08lx\n", AccessStatus);
1035
1037 NULL,
1038 Token,
1039 KEY_WRITE,
1040 ObjTypeList,
1041 RTL_NUMBER_OF(ObjTypeList),
1042 &RegMapping,
1043 PrivilegeSet,
1044 &PrivilegeSetLength,
1046 &AccessStatus);
1048 ok(GrantedAccess == KEY_WRITE, "Expected KEY_WRITE as granted right but got 0x%08lx\n", GrantedAccess);
1049 ok(AccessStatus == STATUS_SUCCESS, "Expected a success status but got 0x%08lx\n", AccessStatus);
1050
1052 NULL,
1053 Token,
1055 ObjTypeList,
1056 RTL_NUMBER_OF(ObjTypeList),
1057 &RegMapping,
1058 PrivilegeSet,
1059 &PrivilegeSetLength,
1061 &AccessStatus);
1063 ok(GrantedAccess == KEY_EXECUTE, "Expected KEY_EXECUTE as granted right but got 0x%08lx\n", GrantedAccess);
1064 ok(AccessStatus == STATUS_SUCCESS, "Expected a success status but got 0x%08lx\n", AccessStatus);
1065
1067 NULL,
1068 Token,
1070 ObjTypeList,
1071 RTL_NUMBER_OF(ObjTypeList),
1072 &RegMapping,
1073 PrivilegeSet,
1074 &PrivilegeSetLength,
1076 &AccessStatus);
1078 ok(GrantedAccess == KEY_SET_VALUE, "Expected KEY_SET_VALUE as granted right but got 0x%08lx\n", GrantedAccess);
1079 ok(AccessStatus == STATUS_SUCCESS, "Expected a success status but got 0x%08lx\n", AccessStatus);
1080
1082 NULL,
1083 Token,
1085 ObjTypeList,
1086 RTL_NUMBER_OF(ObjTypeList),
1087 &RegMapping,
1088 PrivilegeSet,
1089 &PrivilegeSetLength,
1091 &AccessStatus);
1093 ok(GrantedAccess == KEY_QUERY_VALUE, "Expected KEY_QUERY_VALUE as granted right but got 0x%08lx\n", GrantedAccess);
1094 ok(AccessStatus == STATUS_SUCCESS, "Expected a success status but got 0x%08lx\n", AccessStatus);
1095
1096Quit:
1097 if (Dacl)
1098 {
1099 RtlFreeHeap(RtlGetProcessHeap(), 0, Dacl);
1100 }
1101
1102 if (Token)
1103 {
1104 NtClose(Token);
1105 }
1106
1107 if (UsersSid)
1108 {
1109 RtlFreeSid(UsersSid);
1110 }
1111
1112 if (AdminSid)
1113 {
1115 }
1116
1117 if (EveryoneSid)
1118 {
1119 RtlFreeSid(EveryoneSid);
1120 }
1121
1122 if (PrivilegeSet)
1123 {
1124 RtlFreeHeap(RtlGetProcessHeap(), 0, PrivilegeSet);
1125 }
1126}
1127
1128static
1129VOID
1131{
1135 PPRIVILEGE_SET PrivilegeSet = NULL;
1136 ULONG PrivilegeSetLength;
1137 HANDLE Token = NULL;
1138 PACL Dacl = NULL;
1141 OBJECT_TYPE_LIST ObjTypeList[2];
1142 PSID EveryoneSid = NULL, AdminSid = NULL, UsersSid = NULL;
1143
1144 /* Allocate all the stuff we need */
1145 PrivilegeSetLength = FIELD_OFFSET(PRIVILEGE_SET, Privilege[16]);
1146 PrivilegeSet = RtlAllocateHeap(RtlGetProcessHeap(), 0, PrivilegeSetLength);
1147 if (PrivilegeSet == NULL)
1148 {
1149 skip("Failed to allocate PrivilegeSet, skipping tests\n");
1150 return;
1151 }
1152
1154 1,
1156 0,
1157 0,
1158 0,
1159 0,
1160 0,
1161 0,
1162 0,
1163 &EveryoneSid);
1164 if (!NT_SUCCESS(Status))
1165 {
1166 skip("Failed to create Everyone SID, skipping tests\n");
1167 goto Quit;
1168 }
1169
1171 2,
1174 0,
1175 0,
1176 0,
1177 0,
1178 0,
1179 0,
1180 &AdminSid);
1181 if (!NT_SUCCESS(Status))
1182 {
1183 skip("Failed to create Admins SID, skipping tests\n");
1184 goto Quit;
1185 }
1186
1188 2,
1191 0,
1192 0,
1193 0,
1194 0,
1195 0,
1196 0,
1197 &UsersSid);
1198 if (!NT_SUCCESS(Status))
1199 {
1200 skip("Failed to create User SID, skipping tests\n");
1201 goto Quit;
1202 }
1203
1205 if (Token == NULL)
1206 {
1207 skip("Failed to get token, skipping tests\n");
1208 goto Quit;
1209 }
1210
1212 if (!NT_SUCCESS(Status))
1213 {
1214 skip("Failed to create a security descriptor, skipping tests\n");
1215 goto Quit;
1216 }
1217
1218 DaclSize = sizeof(ACL) +
1220 sizeof(ACCESS_DENIED_OBJECT_ACE) + RtlLengthSid(EveryoneSid) +
1221 sizeof(ACCESS_ALLOWED_OBJECT_ACE) + RtlLengthSid(EveryoneSid);
1222 Dacl = RtlAllocateHeap(RtlGetProcessHeap(),
1224 DaclSize);
1225 if (Dacl == NULL)
1226 {
1227 skip("Failed to allocate memory for DACL, skipping tests\n");
1228 goto Quit;
1229 }
1230
1232 DaclSize,
1234 if (!NT_SUCCESS(Status))
1235 {
1236 skip("Failed to create DACL, skipping tests\n");
1237 goto Quit;
1238 }
1239
1240 /*
1241 * Admins can't query values from keys and everyone else is denied writing to
1242 * keys to child sub-object but can enumerate subkeys from the object itself.
1243 */
1246 0,
1248 &ObjectType,
1249 NULL,
1250 AdminSid);
1251 if (!NT_SUCCESS(Status))
1252 {
1253 skip("Failed to add deny object ACE for Admins SID, skipping tests\n");
1254 goto Quit;
1255 }
1256
1259 0,
1260 KEY_WRITE,
1262 NULL,
1263 EveryoneSid);
1264 if (!NT_SUCCESS(Status))
1265 {
1266 skip("Failed to add deny object ACE for Everyone SID, skipping tests\n");
1267 goto Quit;
1268 }
1269
1272 0,
1274 &ObjectType,
1275 NULL,
1276 EveryoneSid);
1277 if (!NT_SUCCESS(Status))
1278 {
1279 skip("Failed to add allowed object ACE for Everyone SID, skipping tests\n");
1280 goto Quit;
1281 }
1282
1283 /* Setup the descriptor */
1284 RtlSetGroupSecurityDescriptor(&Sd, UsersSid, FALSE);
1287
1288 /* Setup the object type list */
1289 ObjTypeList[0].Level = ACCESS_OBJECT_GUID;
1290 ObjTypeList[0].Sbz = 0;
1291 ObjTypeList[0].ObjectType = &ObjectType;
1292
1293 ObjTypeList[1].Level = ACCESS_PROPERTY_SET_GUID;
1294 ObjTypeList[1].Sbz = 0;
1295 ObjTypeList[1].ObjectType = &ChildObjectType;
1296
1297 /* Evaluate access -- they should be denied */
1299 NULL,
1300 Token,
1302 ObjTypeList,
1303 RTL_NUMBER_OF(ObjTypeList),
1304 &RegMapping,
1305 PrivilegeSet,
1306 &PrivilegeSetLength,
1308 &AccessStatus);
1310 ok(GrantedAccess == 0, "Expected no access rights but got 0x%08lx\n", GrantedAccess);
1311 ok(AccessStatus == STATUS_ACCESS_DENIED, "Expected access denied as status but got 0x%08lx\n", AccessStatus);
1312
1314 NULL,
1315 Token,
1316 KEY_WRITE,
1317 ObjTypeList,
1318 RTL_NUMBER_OF(ObjTypeList),
1319 &RegMapping,
1320 PrivilegeSet,
1321 &PrivilegeSetLength,
1323 &AccessStatus);
1325 ok(GrantedAccess == 0, "Expected no access rights but got 0x%08lx\n", GrantedAccess);
1326 ok(AccessStatus == STATUS_ACCESS_DENIED, "Expected access denied as status but got 0x%08lx\n", AccessStatus);
1327
1328 /* Everyone else should be granted only enumerate subkey access */
1330 NULL,
1331 Token,
1333 ObjTypeList,
1334 RTL_NUMBER_OF(ObjTypeList),
1335 &RegMapping,
1336 PrivilegeSet,
1337 &PrivilegeSetLength,
1339 &AccessStatus);
1341 ok(GrantedAccess == KEY_ENUMERATE_SUB_KEYS, "Expected KEY_ENUMERATE_SUB_KEYS as granted right but got 0x%08lx\n", GrantedAccess);
1342 ok(AccessStatus == STATUS_SUCCESS, "Expected a success status but got 0x%08lx\n", AccessStatus);
1343
1344Quit:
1345 if (Dacl)
1346 {
1347 RtlFreeHeap(RtlGetProcessHeap(), 0, Dacl);
1348 }
1349
1350 if (Token)
1351 {
1352 NtClose(Token);
1353 }
1354
1355 if (UsersSid)
1356 {
1357 RtlFreeSid(UsersSid);
1358 }
1359
1360 if (AdminSid)
1361 {
1363 }
1364
1365 if (EveryoneSid)
1366 {
1367 RtlFreeSid(EveryoneSid);
1368 }
1369
1370 if (PrivilegeSet)
1371 {
1372 RtlFreeHeap(RtlGetProcessHeap(), 0, PrivilegeSet);
1373 }
1374}
1375
1377{
1383}
static SID_IDENTIFIER_AUTHORITY WorldAuthority
static VOID AccessGrantedMultipleObjectsTests(VOID)
static VOID DenyAccessTests(VOID)
static HANDLE GetTokenProcess(_In_ BOOLEAN WantImpersonateLevel, _In_ BOOLEAN WantImpersonateType)
static SID_IDENTIFIER_AUTHORITY NtAuthority
static VOID AccessGrantedNoDaclTests(VOID)
static GENERIC_MAPPING RegMapping
static VOID AccessGrantedTests(VOID)
static VOID ParamsValidationTests(VOID)
static GUID ChildObjectType
static GUID ObjectType
unsigned char BOOLEAN
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
NTSTATUS NTAPI NtAccessCheckByType(_In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_opt_ PSID PrincipalSelfSid, _In_ HANDLE ClientToken, _In_ ACCESS_MASK DesiredAccess, _In_reads_opt_(ObjectTypeListLength) POBJECT_TYPE_LIST ObjectTypeList, _In_ ULONG ObjectTypeListLength, _In_ PGENERIC_MAPPING GenericMapping, _Out_writes_bytes_(*PrivilegeSetLength) PPRIVILEGE_SET PrivilegeSet, _Inout_ PULONG PrivilegeSetLength, _Out_ PACCESS_MASK GrantedAccess, _Out_ PNTSTATUS AccessStatus)
Determines whether security access can be granted to a client that requests such access on the object...
Definition: accesschk.c:2254
#define ok_hex(expression, result)
Definition: atltest.h:94
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define START_TEST(x)
Definition: atltest.h:75
LONG NTSTATUS
Definition: precomp.h:26
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:590
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:608
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
Status
Definition: gdiplustypes.h:25
NTSYSAPI NTSTATUS WINAPI RtlSetOwnerSecurityDescriptor(PSECURITY_DESCRIPTOR, PSID, BOOLEAN)
NTSYSAPI NTSTATUS WINAPI RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR, BOOLEAN, PACL, BOOLEAN)
@ SecurityImpersonation
Definition: lsa.idl:57
@ SecurityAnonymous
Definition: lsa.idl:55
struct _SECURITY_QUALITY_OF_SERVICE SECURITY_QUALITY_OF_SERVICE
@ TokenImpersonation
Definition: imports.h:274
@ TokenPrimary
Definition: imports.h:273
ObjectType
Definition: metafile.c:81
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
struct _ACCESS_ALLOWED_OBJECT_ACE ACCESS_ALLOWED_OBJECT_ACE
struct _ACL ACL
#define _In_
Definition: ms_sal.h:308
static PSID AdminSid
Definition: msgina.c:39
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL Dacl
Definition: rtlfuncs.h:1605
NTSYSAPI NTSTATUS NTAPI RtlCreateAcl(PACL Acl, ULONG AclSize, ULONG AclRevision)
NTSYSAPI ULONG NTAPI RtlLengthSid(IN PSID Sid)
Definition: sid.c:150
NTSYSAPI NTSTATUS NTAPI RtlAddAccessAllowedObjectAce(_Inout_ PACL pAcl, _In_ ULONG dwAceRevision, _In_ ULONG AceFlags, _In_ ACCESS_MASK AccessMask, _In_opt_ GUID *ObjectTypeGuid, _In_opt_ GUID *InheritedObjectTypeGuid, _In_ PSID pSid)
NTSYSAPI NTSTATUS NTAPI RtlCreateSecurityDescriptor(_Out_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ ULONG Revision)
NTSYSAPI PVOID NTAPI RtlFreeSid(_In_ _Post_invalid_ PSID Sid)
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG DaclSize
Definition: rtlfuncs.h:1606
NTSYSAPI NTSTATUS NTAPI RtlAddAccessDeniedObjectAce(_Inout_ PACL pAcl, _In_ ULONG dwAceRevision, _In_ ULONG AceFlags, _In_ ACCESS_MASK AccessMask, _In_opt_ GUID *ObjectTypeGuid, _In_opt_ GUID *InheritedObjectTypeGuid, _In_ PSID pSid)
ULONG ACCESS_MASK
Definition: nt_native.h:40
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define KEY_READ
Definition: nt_native.h:1023
#define NtCurrentProcess()
Definition: nt_native.h:1657
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define KEY_EXECUTE
Definition: nt_native.h:1037
#define KEY_ENUMERATE_SUB_KEYS
Definition: nt_native.h:1019
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
#define KEY_WRITE
Definition: nt_native.h:1031
#define GENERIC_WRITE
Definition: nt_native.h:90
#define MAXIMUM_ALLOWED
Definition: nt_native.h:83
#define KEY_SET_VALUE
Definition: nt_native.h:1017
NTSYSAPI NTSTATUS NTAPI RtlAllocateAndInitializeSid(IN PSID_IDENTIFIER_AUTHORITY IdentifierAuthority, IN UCHAR SubAuthorityCount, IN ULONG SubAuthority0, IN ULONG SubAuthority1, IN ULONG SubAuthority2, IN ULONG SubAuthority3, IN ULONG SubAuthority4, IN ULONG SubAuthority5, IN ULONG SubAuthority6, IN ULONG SubAuthority7, OUT PSID *Sid)
Definition: sid.c:290
NTSYSAPI NTSTATUS NTAPI RtlSetGroupSecurityDescriptor(IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor, IN PSID Group, IN BOOLEAN GroupDefaulted)
Definition: sd.c:410
NTSTATUS NTAPI NtOpenProcessToken(IN HANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess, OUT PHANDLE TokenHandle)
Definition: security.c:350
#define STATUS_INVALID_HANDLE
Definition: ntstatus.h:245
#define STATUS_NO_IMPERSONATION_TOKEN
Definition: ntstatus.h:328
#define STATUS_INVALID_SECURITY_DESCR
Definition: ntstatus.h:357
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
#define STATUS_GENERIC_NOT_MAPPED
Definition: ntstatus.h:466
#define STATUS_REVISION_MISMATCH
Definition: ntstatus.h:325
#define STATUS_BAD_IMPERSONATION_LEVEL
Definition: ntstatus.h:401
#define STATUS_SUCCESS
Definition: shellext.h:65
$USHORT Level
Definition: setypes.h:857
GUID * ObjectType
Definition: setypes.h:859
SECURITY_CONTEXT_TRACKING_MODE ContextTrackingMode
Definition: lsa.idl:66
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
Definition: lsa.idl:65
_Must_inspect_result_ __kernel_entry NTSTATUS NTAPI NtDuplicateToken(_In_ HANDLE ExistingTokenHandle, _In_ ACCESS_MASK DesiredAccess, _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, _In_ BOOLEAN EffectiveOnly, _In_ TOKEN_TYPE TokenType, _Out_ PHANDLE NewTokenHandle)
Duplicates a token.
Definition: tokenlif.c:1869
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
BOOL Privilege(LPTSTR pszPrivilege, BOOL bEnable)
Definition: user_lib.cpp:531
_In_ PSECURITY_SUBJECT_CONTEXT _In_ BOOLEAN _In_ ACCESS_MASK _In_ ACCESS_MASK _Outptr_opt_ PPRIVILEGE_SET _In_ PGENERIC_MAPPING _In_ KPROCESSOR_MODE _Out_ PACCESS_MASK _Out_ PNTSTATUS AccessStatus
Definition: sefuncs.h:21
_In_ PSECURITY_SUBJECT_CONTEXT _In_ BOOLEAN _In_ ACCESS_MASK _In_ ACCESS_MASK _Outptr_opt_ PPRIVILEGE_SET _In_ PGENERIC_MAPPING _In_ KPROCESSOR_MODE _Out_ PACCESS_MASK GrantedAccess
Definition: sefuncs.h:20
#define DOMAIN_ALIAS_RID_USERS
Definition: setypes.h:653
#define SECURITY_BUILTIN_DOMAIN_RID
Definition: setypes.h:581
#define TOKEN_DUPLICATE
Definition: setypes.h:926
#define SECURITY_WORLD_SID_AUTHORITY
Definition: setypes.h:527
#define SECURITY_WORLD_RID
Definition: setypes.h:541
#define ACL_REVISION4
Definition: setypes.h:45
#define TOKEN_QUERY
Definition: setypes.h:928
#define SECURITY_NT_AUTHORITY
Definition: setypes.h:554
#define SECURITY_DESCRIPTOR_REVISION
Definition: setypes.h:58
struct _ACCESS_DENIED_OBJECT_ACE ACCESS_DENIED_OBJECT_ACE
#define ACCESS_PROPERTY_SET_GUID
Definition: setypes.h:863
#define ACL_REVISION
Definition: setypes.h:39
#define DOMAIN_ALIAS_RID_ADMINS
Definition: setypes.h:652
#define ACCESS_OBJECT_GUID
Definition: setypes.h:862
#define ACCESS_PROPERTY_GUID
Definition: setypes.h:864