1 /*
2  * PROJECT:         ReactOS API tests
3  * LICENSE:         LGPLv2.1+ - See COPYING.LIB in the top level directory
4  * PURPOSE:         Test for RtlDeleteAce
5  * PROGRAMMERS:     Thomas Faber <thomas.faber@reactos.org>
6  */
7 
8 #include "precomp.h"
9 
10 static
11 PACL
MakeAcl(_In_ ULONG AceCount,...)12 MakeAcl(
13     _In_ ULONG AceCount,
14     ...)
15 {
16     PACL Acl;
17     PACE_HEADER AceHeader;
18     ULONG AclSize;
19     ULONG AceSizes[10];
20     ULONG i;
21     va_list Args;
22 
23     ASSERT(AceCount <= RTL_NUMBER_OF(AceSizes));
24     AclSize = sizeof(ACL);
25     va_start(Args, AceCount);
26     for (i = 0; i < AceCount; i++)
27     {
28         AceSizes[i] = va_arg(Args, int);
29         AclSize += AceSizes[i];
30     }
31     va_end(Args);
32 
33     Acl = AllocateGuarded(AclSize);
34     if (!Acl)
35     {
36         skip("Failed to allocate %lu bytes\n", AclSize);
37         return NULL;
38     }
39 
40     Acl->AclRevision = ACL_REVISION;
41     Acl->Sbz1 = 0;
42     Acl->AclSize = AclSize;
43     Acl->AceCount = AceCount;
44     Acl->Sbz2 = 0;
45 
46     AceHeader = (PACE_HEADER)(Acl + 1);
47     for (i = 0; i < AceCount; i++)
48     {
49         AceHeader->AceType = 0;
50         AceHeader->AceFlags = 0;
51         AceHeader->AceSize = AceSizes[i];
52         AceHeader = (PACE_HEADER)((PCHAR)AceHeader + AceHeader->AceSize);
53     }
54 
55     return Acl;
56 }
57 
START_TEST(RtlDeleteAce)58 START_TEST(RtlDeleteAce)
59 {
60     PACL Acl;
61     PACCESS_ALLOWED_ACE Ace;
62     ULONG AceSize;
63     PISID Sid;
64     NTSTATUS Status;
65     int i;
66 
67     Acl = MakeAcl(0);
68     if (Acl)
69     {
70         ok(RtlValidAcl(Acl), "Acl is invalid\n");
71 
72         /* There is no first ACE -- should stay untouched */
73         Status = RtlDeleteAce(Acl, 0);
74         ok(Status == STATUS_INVALID_PARAMETER, "Status = %lx\n", Status);
75         ok(Acl->AclSize == sizeof(ACL), "AclSize = %u\n", Acl->AclSize);
76         ok(Acl->AceCount == 0, "AceCount = %u\n", Acl->AceCount);
77 
78         /* Index -1 -- should stay untouched */
79         Status = RtlDeleteAce(Acl, 0xFFFFFFFF);
80         ok(Status == STATUS_INVALID_PARAMETER, "Status = %lx\n", Status);
81         FreeGuarded(Acl);
82     }
83 
84     AceSize = FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + FIELD_OFFSET(SID, SubAuthority);
85     Acl = MakeAcl(1, (int)AceSize);
86     if (Acl)
87     {
88         Ace = (PACCESS_ALLOWED_ACE)(Acl + 1);
89         Ace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
90         Sid = (PISID)&Ace->SidStart;
91         Sid->Revision = SID_REVISION;
92         Sid->SubAuthorityCount = 0;
93         RtlZeroMemory(&Sid->IdentifierAuthority, sizeof(Sid->IdentifierAuthority));
94 
95         ok(RtlValidAcl(Acl), "Acl is invalid\n");
96 
97         /* Out of bounds delete -- should stay untouched */
98         Status = RtlDeleteAce(Acl, 1);
99         ok(Status == STATUS_INVALID_PARAMETER, "Status = %lx\n", Status);
100         ok(Acl->AclSize == sizeof(ACL) + AceSize, "AclSize = %u\n", Acl->AclSize);
101         ok(Acl->AceCount == 1, "AceCount = %u\n", Acl->AceCount);
102         ok(Ace->Header.AceSize == AceSize, "AceSize = %u\n", Ace->Header.AceSize);
103 
104         /* Index -1 -- should stay untouched */
105         Status = RtlDeleteAce(Acl, 0xFFFFFFFF);
106         ok(Status == STATUS_INVALID_PARAMETER, "Status = %lx\n", Status);
107         ok(Acl->AclSize == sizeof(ACL) + AceSize, "AclSize = %u\n", Acl->AclSize);
108         ok(Acl->AceCount == 1, "AceCount = %u\n", Acl->AceCount);
109         ok(Ace->Header.AceSize == AceSize, "AceSize = %u\n", Ace->Header.AceSize);
110 
111         /* Delete the first (and only) ACE */
112         Status = RtlDeleteAce(Acl, 0);
113         ok(Status == STATUS_SUCCESS, "Status = %lx\n", Status);
114         ok(Acl->AclSize == sizeof(ACL) + AceSize, "AclSize = %u\n", Acl->AclSize);
115         ok(Acl->AceCount == 0, "AceCount = %u\n", Acl->AceCount);
116         ok(Ace->Header.AceSize == 0, "AceSize = %u\n", Ace->Header.AceSize);
117         FreeGuarded(Acl);
118     }
119 
120     AceSize = FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + FIELD_OFFSET(SID, SubAuthority[1]);
121     Acl = MakeAcl(4, (int)AceSize, (int)AceSize + 4, (int)AceSize + 8, (int)AceSize + 12);
122     if (Acl)
123     {
124         Ace = (PACCESS_ALLOWED_ACE)(Acl + 1);
125         for (i = 0; i < 4; i++)
126         {
127             Ace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
128             Sid = (PISID)&Ace->SidStart;
129             Sid->Revision = SID_REVISION;
130             Sid->SubAuthorityCount = 0;
131             RtlZeroMemory(&Sid->IdentifierAuthority, sizeof(Sid->IdentifierAuthority));
132             Ace = (PACCESS_ALLOWED_ACE)((PCHAR)Ace + Ace->Header.AceSize);
133         }
134 
135         ok(RtlValidAcl(Acl), "Acl is invalid\n");
136 
137         /* Out of bounds delete -- should stay untouched */
138         Status = RtlDeleteAce(Acl, 4);
139         ok(Status == STATUS_INVALID_PARAMETER, "Status = %lx\n", Status);
140         ok(Acl->AclSize == sizeof(ACL) + 4 * AceSize + 24, "AclSize = %u\n", Acl->AclSize);
141         ok(Acl->AceCount == 4, "AceCount = %u\n", Acl->AceCount);
142         Ace = (PACCESS_ALLOWED_ACE)(Acl + 1);
143         ok(Ace->Header.AceSize == AceSize, "AceSize = %u\n", Ace->Header.AceSize);
144         Ace = (PACCESS_ALLOWED_ACE)((PCHAR)Ace + Ace->Header.AceSize);
145         ok(Ace->Header.AceSize == AceSize + 4, "AceSize = %u\n", Ace->Header.AceSize);
146         Ace = (PACCESS_ALLOWED_ACE)((PCHAR)Ace + Ace->Header.AceSize);
147         ok(Ace->Header.AceSize == AceSize + 8, "AceSize = %u\n", Ace->Header.AceSize);
148         Ace = (PACCESS_ALLOWED_ACE)((PCHAR)Ace + Ace->Header.AceSize);
149         ok(Ace->Header.AceSize == AceSize + 12, "AceSize = %u\n", Ace->Header.AceSize);
150 
151         /* Index -1 -- should stay untouched */
152         Status = RtlDeleteAce(Acl, 0xFFFFFFFF);
153         ok(Status == STATUS_INVALID_PARAMETER, "Status = %lx\n", Status);
154         ok(Acl->AclSize == sizeof(ACL) + 4 * AceSize + 24, "AclSize = %u\n", Acl->AclSize);
155         ok(Acl->AceCount == 4, "AceCount = %u\n", Acl->AceCount);
156         Ace = (PACCESS_ALLOWED_ACE)(Acl + 1);
157         ok(Ace->Header.AceSize == AceSize, "AceSize = %u\n", Ace->Header.AceSize);
158         Ace = (PACCESS_ALLOWED_ACE)((PCHAR)Ace + Ace->Header.AceSize);
159         ok(Ace->Header.AceSize == AceSize + 4, "AceSize = %u\n", Ace->Header.AceSize);
160         Ace = (PACCESS_ALLOWED_ACE)((PCHAR)Ace + Ace->Header.AceSize);
161         ok(Ace->Header.AceSize == AceSize + 8, "AceSize = %u\n", Ace->Header.AceSize);
162         Ace = (PACCESS_ALLOWED_ACE)((PCHAR)Ace + Ace->Header.AceSize);
163         ok(Ace->Header.AceSize == AceSize + 12, "AceSize = %u\n", Ace->Header.AceSize);
164 
165         /* Delete the last ACE */
166         Status = RtlDeleteAce(Acl, 3);
167         ok(Status == STATUS_SUCCESS, "Status = %lx\n", Status);
168         ok(Acl->AclSize == sizeof(ACL) + 4 * AceSize + 24, "AclSize = %u\n", Acl->AclSize);
169         ok(Acl->AceCount == 3, "AceCount = %u\n", Acl->AceCount);
170         Ace = (PACCESS_ALLOWED_ACE)(Acl + 1);
171         ok(Ace->Header.AceSize == AceSize, "AceSize = %u\n", Ace->Header.AceSize);
172         Ace = (PACCESS_ALLOWED_ACE)((PCHAR)Ace + Ace->Header.AceSize);
173         ok(Ace->Header.AceSize == AceSize + 4, "AceSize = %u\n", Ace->Header.AceSize);
174         Ace = (PACCESS_ALLOWED_ACE)((PCHAR)Ace + Ace->Header.AceSize);
175         ok(Ace->Header.AceSize == AceSize + 8, "AceSize = %u\n", Ace->Header.AceSize);
176         Ace = (PACCESS_ALLOWED_ACE)((PCHAR)Ace + Ace->Header.AceSize);
177         ok(Ace->Header.AceSize == 0, "AceSize = %u\n", Ace->Header.AceSize);
178 
179         /* Delete the second ACE */
180         Status = RtlDeleteAce(Acl, 1);
181         ok(Status == STATUS_SUCCESS, "Status = %lx\n", Status);
182         ok(Acl->AclSize == sizeof(ACL) + 4 * AceSize + 24, "AclSize = %u\n", Acl->AclSize);
183         ok(Acl->AceCount == 2, "AceCount = %u\n", Acl->AceCount);
184         Ace = (PACCESS_ALLOWED_ACE)(Acl + 1);
185         ok(Ace->Header.AceSize == AceSize, "AceSize = %u\n", Ace->Header.AceSize);
186         Ace = (PACCESS_ALLOWED_ACE)((PCHAR)Ace + Ace->Header.AceSize);
187         ok(Ace->Header.AceSize == AceSize + 8, "AceSize = %u\n", Ace->Header.AceSize);
188         Ace = (PACCESS_ALLOWED_ACE)((PCHAR)Ace + Ace->Header.AceSize);
189         ok(Ace->Header.AceSize == 0, "AceSize = %u\n", Ace->Header.AceSize);
190 
191         /* Delete the first ACE */
192         Status = RtlDeleteAce(Acl, 0);
193         ok(Status == STATUS_SUCCESS, "Status = %lx\n", Status);
194         ok(Acl->AclSize == sizeof(ACL) + 4 * AceSize + 24, "AclSize = %u\n", Acl->AclSize);
195         ok(Acl->AceCount == 1, "AceCount = %u\n", Acl->AceCount);
196         Ace = (PACCESS_ALLOWED_ACE)(Acl + 1);
197         ok(Ace->Header.AceSize == AceSize + 8, "AceSize = %u\n", Ace->Header.AceSize);
198         Ace = (PACCESS_ALLOWED_ACE)((PCHAR)Ace + Ace->Header.AceSize);
199         ok(Ace->Header.AceSize == 0, "AceSize = %u\n", Ace->Header.AceSize);
200 
201         /* Delete the remaining ACE */
202         Status = RtlDeleteAce(Acl, 0);
203         ok(Status == STATUS_SUCCESS, "Status = %lx\n", Status);
204         ok(Acl->AclSize == sizeof(ACL) + 4 * AceSize + 24, "AclSize = %u\n", Acl->AclSize);
205         ok(Acl->AceCount == 0, "AceCount = %u\n", Acl->AceCount);
206         Ace = (PACCESS_ALLOWED_ACE)(Acl + 1);
207         ok(Ace->Header.AceSize == 0, "AceSize = %u\n", Ace->Header.AceSize);
208 
209         FreeGuarded(Acl);
210     }
211 }
212