1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // This file contains unit tests for the RestrictedToken.
6
7 #define _ATL_NO_EXCEPTIONS
8 #include <atlbase.h>
9 #include <atlsecurity.h>
10 #include <vector>
11 #include "sandbox/win/src/restricted_token.h"
12 #include "sandbox/win/src/sid.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14
15 namespace sandbox {
16
17 // Tests the initializatioin with an invalid token handle.
TEST(RestrictedTokenTest,InvalidHandle)18 TEST(RestrictedTokenTest, InvalidHandle) {
19 RestrictedToken token;
20 ASSERT_EQ(ERROR_INVALID_HANDLE, token.Init(reinterpret_cast<HANDLE>(0x5555)));
21 }
22
23 // Tests the initialization with NULL as parameter.
TEST(RestrictedTokenTest,DefaultInit)24 TEST(RestrictedTokenTest, DefaultInit) {
25 // Get the current process token.
26 HANDLE token_handle = INVALID_HANDLE_VALUE;
27 ASSERT_TRUE(::OpenProcessToken(::GetCurrentProcess(), TOKEN_ALL_ACCESS,
28 &token_handle));
29
30 ASSERT_NE(INVALID_HANDLE_VALUE, token_handle);
31
32 ATL::CAccessToken access_token;
33 access_token.Attach(token_handle);
34
35 // Create the token using the current token.
36 RestrictedToken token_default;
37 ASSERT_EQ(ERROR_SUCCESS, token_default.Init(NULL));
38
39 // Get the handle to the restricted token.
40
41 HANDLE restricted_token_handle = NULL;
42 ASSERT_EQ(ERROR_SUCCESS,
43 token_default.GetRestrictedTokenHandle(&restricted_token_handle));
44
45 ATL::CAccessToken restricted_token;
46 restricted_token.Attach(restricted_token_handle);
47
48 ATL::CSid sid_user_restricted;
49 ATL::CSid sid_user_default;
50 ATL::CSid sid_owner_restricted;
51 ATL::CSid sid_owner_default;
52 ASSERT_TRUE(restricted_token.GetUser(&sid_user_restricted));
53 ASSERT_TRUE(access_token.GetUser(&sid_user_default));
54 ASSERT_TRUE(restricted_token.GetOwner(&sid_owner_restricted));
55 ASSERT_TRUE(access_token.GetOwner(&sid_owner_default));
56
57 // Check if both token have the same owner and user.
58 ASSERT_EQ(sid_user_restricted, sid_user_default);
59 ASSERT_EQ(sid_owner_restricted, sid_owner_default);
60 }
61
62 // Tests the initialization with a custom token as parameter.
TEST(RestrictedTokenTest,CustomInit)63 TEST(RestrictedTokenTest, CustomInit) {
64 // Get the current process token.
65 HANDLE token_handle = INVALID_HANDLE_VALUE;
66 ASSERT_TRUE(::OpenProcessToken(::GetCurrentProcess(), TOKEN_ALL_ACCESS,
67 &token_handle));
68
69 ASSERT_NE(INVALID_HANDLE_VALUE, token_handle);
70
71 ATL::CAccessToken access_token;
72 access_token.Attach(token_handle);
73
74 // Change the primary group.
75 access_token.SetPrimaryGroup(ATL::Sids::World());
76
77 // Create the token using the current token.
78 RestrictedToken token;
79 ASSERT_EQ(ERROR_SUCCESS, token.Init(access_token.GetHandle()));
80
81 // Get the handle to the restricted token.
82
83 HANDLE restricted_token_handle = NULL;
84 ASSERT_EQ(ERROR_SUCCESS,
85 token.GetRestrictedTokenHandle(&restricted_token_handle));
86
87 ATL::CAccessToken restricted_token;
88 restricted_token.Attach(restricted_token_handle);
89
90 ATL::CSid sid_restricted;
91 ATL::CSid sid_default;
92 ASSERT_TRUE(restricted_token.GetPrimaryGroup(&sid_restricted));
93 ASSERT_TRUE(access_token.GetPrimaryGroup(&sid_default));
94
95 // Check if both token have the same owner.
96 ASSERT_EQ(sid_restricted, sid_default);
97 }
98
99 // Verifies that the token created by the object are valid.
TEST(RestrictedTokenTest,ResultToken)100 TEST(RestrictedTokenTest, ResultToken) {
101 RestrictedToken token;
102 ASSERT_EQ(ERROR_SUCCESS, token.Init(NULL));
103
104 ASSERT_EQ(ERROR_SUCCESS,
105 token.AddRestrictingSid(ATL::Sids::World().GetPSID()));
106
107 HANDLE restricted_token;
108 ASSERT_EQ(ERROR_SUCCESS, token.GetRestrictedTokenHandle(&restricted_token));
109
110 ASSERT_TRUE(::IsTokenRestricted(restricted_token));
111
112 DWORD length = 0;
113 TOKEN_TYPE type;
114 ASSERT_TRUE(::GetTokenInformation(restricted_token,
115 ::TokenType,
116 &type,
117 sizeof(type),
118 &length));
119
120 ASSERT_EQ(type, TokenPrimary);
121
122 HANDLE impersonation_token;
123 ASSERT_EQ(ERROR_SUCCESS,
124 token.GetRestrictedTokenHandleForImpersonation(&impersonation_token));
125
126 ASSERT_TRUE(::IsTokenRestricted(impersonation_token));
127
128 ASSERT_TRUE(::GetTokenInformation(impersonation_token,
129 ::TokenType,
130 &type,
131 sizeof(type),
132 &length));
133
134 ASSERT_EQ(type, TokenImpersonation);
135
136 ::CloseHandle(impersonation_token);
137 ::CloseHandle(restricted_token);
138 }
139
140 // Verifies that the token created has "Restricted" in its default dacl.
TEST(RestrictedTokenTest,DefaultDacl)141 TEST(RestrictedTokenTest, DefaultDacl) {
142 RestrictedToken token;
143 ASSERT_EQ(ERROR_SUCCESS, token.Init(NULL));
144
145 ASSERT_EQ(ERROR_SUCCESS,
146 token.AddRestrictingSid(ATL::Sids::World().GetPSID()));
147
148 HANDLE handle;
149 ASSERT_EQ(ERROR_SUCCESS, token.GetRestrictedTokenHandle(&handle));
150
151 ATL::CAccessToken restricted_token;
152 restricted_token.Attach(handle);
153
154 ATL::CDacl dacl;
155 ASSERT_TRUE(restricted_token.GetDefaultDacl(&dacl));
156
157 bool restricted_found = false;
158
159 unsigned int ace_count = dacl.GetAceCount();
160 for (unsigned int i = 0; i < ace_count ; ++i) {
161 ATL::CSid sid;
162 ACCESS_MASK mask = 0;
163 dacl.GetAclEntry(i, &sid, &mask);
164 if (sid == ATL::Sids::RestrictedCode() && mask == GENERIC_ALL) {
165 restricted_found = true;
166 break;
167 }
168 }
169
170 ASSERT_TRUE(restricted_found);
171 }
172
173 // Tests the method "AddSidForDenyOnly".
TEST(RestrictedTokenTest,DenySid)174 TEST(RestrictedTokenTest, DenySid) {
175 RestrictedToken token;
176 HANDLE token_handle = NULL;
177
178 ASSERT_EQ(ERROR_SUCCESS, token.Init(NULL));
179 ASSERT_EQ(ERROR_SUCCESS, token.AddSidForDenyOnly(Sid(WinWorldSid)));
180 ASSERT_EQ(ERROR_SUCCESS, token.GetRestrictedTokenHandle(&token_handle));
181
182 ATL::CAccessToken restricted_token;
183 restricted_token.Attach(token_handle);
184
185 ATL::CTokenGroups groups;
186 ASSERT_TRUE(restricted_token.GetGroups(&groups));
187
188 ATL::CSid::CSidArray sids;
189 ATL::CAtlArray<DWORD> attributes;
190 groups.GetSidsAndAttributes(&sids, &attributes);
191
192 for (unsigned int i = 0; i < sids.GetCount(); i++) {
193 if (ATL::Sids::World() == sids[i]) {
194 ASSERT_EQ(SE_GROUP_USE_FOR_DENY_ONLY,
195 attributes[i] & SE_GROUP_USE_FOR_DENY_ONLY);
196 }
197 }
198 }
199
200 // Tests the method "AddAllSidsForDenyOnly".
TEST(RestrictedTokenTest,DenySids)201 TEST(RestrictedTokenTest, DenySids) {
202 RestrictedToken token;
203 HANDLE token_handle = NULL;
204
205 ASSERT_EQ(ERROR_SUCCESS, token.Init(NULL));
206 ASSERT_EQ(ERROR_SUCCESS, token.AddAllSidsForDenyOnly(NULL));
207 ASSERT_EQ(ERROR_SUCCESS, token.GetRestrictedTokenHandle(&token_handle));
208
209 ATL::CAccessToken restricted_token;
210 restricted_token.Attach(token_handle);
211
212 ATL::CTokenGroups groups;
213 ASSERT_TRUE(restricted_token.GetGroups(&groups));
214
215 ATL::CSid::CSidArray sids;
216 ATL::CAtlArray<DWORD> attributes;
217 groups.GetSidsAndAttributes(&sids, &attributes);
218
219 // Verify that all sids are really gone.
220 for (unsigned int i = 0; i < sids.GetCount(); i++) {
221 if ((attributes[i] & SE_GROUP_LOGON_ID) == 0 &&
222 (attributes[i] & SE_GROUP_INTEGRITY) == 0) {
223 ASSERT_EQ(SE_GROUP_USE_FOR_DENY_ONLY,
224 attributes[i] & SE_GROUP_USE_FOR_DENY_ONLY);
225 }
226 }
227 }
228
229 // Tests the method "AddAllSidsForDenyOnly" using an exception list.
TEST(RestrictedTokenTest,DenySidsException)230 TEST(RestrictedTokenTest, DenySidsException) {
231 RestrictedToken token;
232 HANDLE token_handle = NULL;
233
234 std::vector<Sid> sids_exception;
235 sids_exception.push_back(Sid(WinWorldSid));
236
237 ASSERT_EQ(ERROR_SUCCESS, token.Init(NULL));
238 ASSERT_EQ(ERROR_SUCCESS, token.AddAllSidsForDenyOnly(&sids_exception));
239 ASSERT_EQ(ERROR_SUCCESS, token.GetRestrictedTokenHandle(&token_handle));
240
241 ATL::CAccessToken restricted_token;
242 restricted_token.Attach(token_handle);
243
244 ATL::CTokenGroups groups;
245 ASSERT_TRUE(restricted_token.GetGroups(&groups));
246
247 ATL::CSid::CSidArray sids;
248 ATL::CAtlArray<DWORD> attributes;
249 groups.GetSidsAndAttributes(&sids, &attributes);
250
251 // Verify that all sids are really gone.
252 for (unsigned int i = 0; i < sids.GetCount(); i++) {
253 if ((attributes[i] & SE_GROUP_LOGON_ID) == 0 &&
254 (attributes[i] & SE_GROUP_INTEGRITY) == 0) {
255 if (ATL::Sids::World() == sids[i]) {
256 ASSERT_EQ(NULL, attributes[i] & SE_GROUP_USE_FOR_DENY_ONLY);
257 } else {
258 ASSERT_EQ(SE_GROUP_USE_FOR_DENY_ONLY,
259 attributes[i] & SE_GROUP_USE_FOR_DENY_ONLY);
260 }
261 }
262 }
263 }
264
265 // Tests test method AddOwnerSidForDenyOnly.
TEST(RestrictedTokenTest,DenyOwnerSid)266 TEST(RestrictedTokenTest, DenyOwnerSid) {
267 RestrictedToken token;
268 HANDLE token_handle = NULL;
269
270 ASSERT_EQ(ERROR_SUCCESS, token.Init(NULL));
271 ASSERT_EQ(ERROR_SUCCESS, token.AddUserSidForDenyOnly());
272 ASSERT_EQ(ERROR_SUCCESS, token.GetRestrictedTokenHandle(&token_handle));
273
274 ATL::CAccessToken restricted_token;
275 restricted_token.Attach(token_handle);
276
277 ATL::CTokenGroups groups;
278 ASSERT_TRUE(restricted_token.GetGroups(&groups));
279
280 ATL::CSid::CSidArray sids;
281 ATL::CAtlArray<DWORD> attributes;
282 groups.GetSidsAndAttributes(&sids, &attributes);
283
284 ATL::CSid user_sid;
285 ASSERT_TRUE(restricted_token.GetUser(&user_sid));
286
287 for (unsigned int i = 0; i < sids.GetCount(); ++i) {
288 if (user_sid == sids[i]) {
289 ASSERT_EQ(SE_GROUP_USE_FOR_DENY_ONLY,
290 attributes[i] & SE_GROUP_USE_FOR_DENY_ONLY);
291 }
292 }
293 }
294
295 // Tests test method AddOwnerSidForDenyOnly with a custom effective token.
TEST(RestrictedTokenTest,DenyOwnerSidCustom)296 TEST(RestrictedTokenTest, DenyOwnerSidCustom) {
297 // Get the current process token.
298 HANDLE token_handle = INVALID_HANDLE_VALUE;
299 ASSERT_TRUE(::OpenProcessToken(::GetCurrentProcess(), TOKEN_ALL_ACCESS,
300 &token_handle));
301
302 ASSERT_NE(INVALID_HANDLE_VALUE, token_handle);
303
304 ATL::CAccessToken access_token;
305 access_token.Attach(token_handle);
306
307 RestrictedToken token;
308 ASSERT_EQ(ERROR_SUCCESS, token.Init(access_token.GetHandle()));
309 ASSERT_EQ(ERROR_SUCCESS, token.AddUserSidForDenyOnly());
310 ASSERT_EQ(ERROR_SUCCESS, token.GetRestrictedTokenHandle(&token_handle));
311
312 ATL::CAccessToken restricted_token;
313 restricted_token.Attach(token_handle);
314
315 ATL::CTokenGroups groups;
316 ASSERT_TRUE(restricted_token.GetGroups(&groups));
317
318 ATL::CSid::CSidArray sids;
319 ATL::CAtlArray<DWORD> attributes;
320 groups.GetSidsAndAttributes(&sids, &attributes);
321
322 ATL::CSid user_sid;
323 ASSERT_TRUE(restricted_token.GetUser(&user_sid));
324
325 for (unsigned int i = 0; i < sids.GetCount(); ++i) {
326 if (user_sid == sids[i]) {
327 ASSERT_EQ(SE_GROUP_USE_FOR_DENY_ONLY,
328 attributes[i] & SE_GROUP_USE_FOR_DENY_ONLY);
329 }
330 }
331 }
332
333 // Tests the method DeleteAllPrivileges.
TEST(RestrictedTokenTest,DeleteAllPrivileges)334 TEST(RestrictedTokenTest, DeleteAllPrivileges) {
335 RestrictedToken token;
336 HANDLE token_handle = NULL;
337
338 ASSERT_EQ(ERROR_SUCCESS, token.Init(NULL));
339 ASSERT_EQ(ERROR_SUCCESS, token.DeleteAllPrivileges(NULL));
340 ASSERT_EQ(ERROR_SUCCESS, token.GetRestrictedTokenHandle(&token_handle));
341
342 ATL::CAccessToken restricted_token;
343 restricted_token.Attach(token_handle);
344
345 ATL::CTokenPrivileges privileges;
346 ASSERT_TRUE(restricted_token.GetPrivileges(&privileges));
347
348 ASSERT_EQ(0, privileges.GetCount());
349 }
350
351 // Tests the method DeleteAllPrivileges with an exception list.
TEST(RestrictedTokenTest,DeleteAllPrivilegesException)352 TEST(RestrictedTokenTest, DeleteAllPrivilegesException) {
353 RestrictedToken token;
354 HANDLE token_handle = NULL;
355
356 std::vector<base::string16> exceptions;
357 exceptions.push_back(SE_CHANGE_NOTIFY_NAME);
358
359 ASSERT_EQ(ERROR_SUCCESS, token.Init(NULL));
360 ASSERT_EQ(ERROR_SUCCESS, token.DeleteAllPrivileges(&exceptions));
361 ASSERT_EQ(ERROR_SUCCESS, token.GetRestrictedTokenHandle(&token_handle));
362
363 ATL::CAccessToken restricted_token;
364 restricted_token.Attach(token_handle);
365
366 ATL::CTokenPrivileges privileges;
367 ASSERT_TRUE(restricted_token.GetPrivileges(&privileges));
368
369 ATL::CTokenPrivileges::CNames privilege_names;
370 ATL::CTokenPrivileges::CAttributes privilege_name_attributes;
371 privileges.GetNamesAndAttributes(&privilege_names,
372 &privilege_name_attributes);
373
374 ASSERT_EQ(1, privileges.GetCount());
375
376 for (unsigned int i = 0; i < privileges.GetCount(); ++i) {
377 ASSERT_EQ(privilege_names[i], SE_CHANGE_NOTIFY_NAME);
378 }
379 }
380
381 // Tests the method DeletePrivilege.
TEST(RestrictedTokenTest,DeletePrivilege)382 TEST(RestrictedTokenTest, DeletePrivilege) {
383 RestrictedToken token;
384 HANDLE token_handle = NULL;
385
386 ASSERT_EQ(ERROR_SUCCESS, token.Init(NULL));
387 ASSERT_EQ(ERROR_SUCCESS, token.DeletePrivilege(SE_CHANGE_NOTIFY_NAME));
388 ASSERT_EQ(ERROR_SUCCESS, token.GetRestrictedTokenHandle(&token_handle));
389
390 ATL::CAccessToken restricted_token;
391 restricted_token.Attach(token_handle);
392
393 ATL::CTokenPrivileges privileges;
394 ASSERT_TRUE(restricted_token.GetPrivileges(&privileges));
395
396 ATL::CTokenPrivileges::CNames privilege_names;
397 ATL::CTokenPrivileges::CAttributes privilege_name_attributes;
398 privileges.GetNamesAndAttributes(&privilege_names,
399 &privilege_name_attributes);
400
401 for (unsigned int i = 0; i < privileges.GetCount(); ++i) {
402 ASSERT_NE(privilege_names[i], SE_CHANGE_NOTIFY_NAME);
403 }
404 }
405
406 // Checks if a sid is in the restricting list of the restricted token.
407 // Asserts if it's not the case. If count is a positive number, the number of
408 // elements in the restricting sids list has to be equal.
CheckRestrictingSid(const ATL::CAccessToken & restricted_token,ATL::CSid sid,int count)409 void CheckRestrictingSid(const ATL::CAccessToken &restricted_token,
410 ATL::CSid sid, int count) {
411 DWORD length = 8192;
412 BYTE *memory = new BYTE[length];
413 TOKEN_GROUPS *groups = reinterpret_cast<TOKEN_GROUPS*>(memory);
414 ASSERT_TRUE(::GetTokenInformation(restricted_token.GetHandle(),
415 TokenRestrictedSids,
416 groups,
417 length,
418 &length));
419
420 ATL::CTokenGroups atl_groups(*groups);
421 delete[] memory;
422
423 if (count >= 0)
424 ASSERT_EQ(count, atl_groups.GetCount());
425
426 ATL::CSid::CSidArray sids;
427 ATL::CAtlArray<DWORD> attributes;
428 atl_groups.GetSidsAndAttributes(&sids, &attributes);
429
430 bool present = false;
431 for (unsigned int i = 0; i < sids.GetCount(); ++i) {
432 if (sids[i] == sid) {
433 present = true;
434 break;
435 }
436 }
437
438 ASSERT_TRUE(present);
439 }
440
441 // Tests the method AddRestrictingSid.
TEST(RestrictedTokenTest,AddRestrictingSid)442 TEST(RestrictedTokenTest, AddRestrictingSid) {
443 RestrictedToken token;
444 HANDLE token_handle = NULL;
445
446 ASSERT_EQ(ERROR_SUCCESS, token.Init(NULL));
447 ASSERT_EQ(ERROR_SUCCESS,
448 token.AddRestrictingSid(ATL::Sids::World().GetPSID()));
449 ASSERT_EQ(ERROR_SUCCESS, token.GetRestrictedTokenHandle(&token_handle));
450
451 ATL::CAccessToken restricted_token;
452 restricted_token.Attach(token_handle);
453
454 CheckRestrictingSid(restricted_token, ATL::Sids::World(), 1);
455 }
456
457 // Tests the method AddRestrictingSidCurrentUser.
TEST(RestrictedTokenTest,AddRestrictingSidCurrentUser)458 TEST(RestrictedTokenTest, AddRestrictingSidCurrentUser) {
459 RestrictedToken token;
460 HANDLE token_handle = NULL;
461
462 ASSERT_EQ(ERROR_SUCCESS, token.Init(NULL));
463 ASSERT_EQ(ERROR_SUCCESS, token.AddRestrictingSidCurrentUser());
464 ASSERT_EQ(ERROR_SUCCESS, token.GetRestrictedTokenHandle(&token_handle));
465
466 ATL::CAccessToken restricted_token;
467 restricted_token.Attach(token_handle);
468 ATL::CSid user;
469 restricted_token.GetUser(&user);
470
471 CheckRestrictingSid(restricted_token, user, 1);
472 }
473
474 // Tests the method AddRestrictingSidCurrentUser with a custom effective token.
TEST(RestrictedTokenTest,AddRestrictingSidCurrentUserCustom)475 TEST(RestrictedTokenTest, AddRestrictingSidCurrentUserCustom) {
476 // Get the current process token.
477 HANDLE token_handle = INVALID_HANDLE_VALUE;
478 ASSERT_TRUE(::OpenProcessToken(::GetCurrentProcess(), TOKEN_ALL_ACCESS,
479 &token_handle));
480
481 ASSERT_NE(INVALID_HANDLE_VALUE, token_handle);
482
483 ATL::CAccessToken access_token;
484 access_token.Attach(token_handle);
485
486 RestrictedToken token;
487 ASSERT_EQ(ERROR_SUCCESS, token.Init(access_token.GetHandle()));
488 ASSERT_EQ(ERROR_SUCCESS, token.AddRestrictingSidCurrentUser());
489 ASSERT_EQ(ERROR_SUCCESS, token.GetRestrictedTokenHandle(&token_handle));
490
491 ATL::CAccessToken restricted_token;
492 restricted_token.Attach(token_handle);
493 ATL::CSid user;
494 restricted_token.GetUser(&user);
495
496 CheckRestrictingSid(restricted_token, user, 1);
497 }
498
499 // Tests the method AddRestrictingSidLogonSession.
TEST(RestrictedTokenTest,AddRestrictingSidLogonSession)500 TEST(RestrictedTokenTest, AddRestrictingSidLogonSession) {
501 RestrictedToken token;
502 HANDLE token_handle = NULL;
503
504 ASSERT_EQ(ERROR_SUCCESS, token.Init(NULL));
505 ASSERT_EQ(ERROR_SUCCESS, token.AddRestrictingSidLogonSession());
506 ASSERT_EQ(ERROR_SUCCESS, token.GetRestrictedTokenHandle(&token_handle));
507
508 ATL::CAccessToken restricted_token;
509 restricted_token.Attach(token_handle);
510 ATL::CSid session;
511 restricted_token.GetLogonSid(&session);
512
513 CheckRestrictingSid(restricted_token, session, 1);
514 }
515
516 // Tests adding a lot of restricting sids.
TEST(RestrictedTokenTest,AddMultipleRestrictingSids)517 TEST(RestrictedTokenTest, AddMultipleRestrictingSids) {
518 RestrictedToken token;
519 HANDLE token_handle = NULL;
520
521 ASSERT_EQ(ERROR_SUCCESS, token.Init(NULL));
522 ASSERT_EQ(ERROR_SUCCESS, token.AddRestrictingSidCurrentUser());
523 ASSERT_EQ(ERROR_SUCCESS, token.AddRestrictingSidLogonSession());
524 ASSERT_EQ(ERROR_SUCCESS,
525 token.AddRestrictingSid(ATL::Sids::World().GetPSID()));
526 ASSERT_EQ(ERROR_SUCCESS, token.GetRestrictedTokenHandle(&token_handle));
527
528 ATL::CAccessToken restricted_token;
529 restricted_token.Attach(token_handle);
530 ATL::CSid session;
531 restricted_token.GetLogonSid(&session);
532
533 DWORD length = 8192;
534 BYTE *memory = new BYTE[length];
535 TOKEN_GROUPS *groups = reinterpret_cast<TOKEN_GROUPS*>(memory);
536 ASSERT_TRUE(::GetTokenInformation(restricted_token.GetHandle(),
537 TokenRestrictedSids,
538 groups,
539 length,
540 &length));
541
542 ATL::CTokenGroups atl_groups(*groups);
543 delete[] memory;
544
545 ASSERT_EQ(3, atl_groups.GetCount());
546 }
547
548 // Tests the method "AddRestrictingSidAllSids".
TEST(RestrictedTokenTest,AddAllSidToRestrictingSids)549 TEST(RestrictedTokenTest, AddAllSidToRestrictingSids) {
550 RestrictedToken token;
551 HANDLE token_handle = NULL;
552
553 ASSERT_EQ(ERROR_SUCCESS, token.Init(NULL));
554 ASSERT_EQ(ERROR_SUCCESS, token.AddRestrictingSidAllSids());
555 ASSERT_EQ(ERROR_SUCCESS, token.GetRestrictedTokenHandle(&token_handle));
556
557 ATL::CAccessToken restricted_token;
558 restricted_token.Attach(token_handle);
559
560 ATL::CTokenGroups groups;
561 ASSERT_TRUE(restricted_token.GetGroups(&groups));
562
563 ATL::CSid::CSidArray sids;
564 ATL::CAtlArray<DWORD> attributes;
565 groups.GetSidsAndAttributes(&sids, &attributes);
566
567 // Verify that all group sids are in the restricting sid list.
568 for (unsigned int i = 0; i < sids.GetCount(); i++) {
569 if ((attributes[i] & SE_GROUP_INTEGRITY) == 0) {
570 CheckRestrictingSid(restricted_token, sids[i], -1);
571 }
572 }
573
574 // Verify that the user is in the restricting sid list.
575 ATL::CSid user;
576 restricted_token.GetUser(&user);
577 CheckRestrictingSid(restricted_token, user, -1);
578 }
579
580 // Checks the error code when the object is initialized twice.
TEST(RestrictedTokenTest,DoubleInit)581 TEST(RestrictedTokenTest, DoubleInit) {
582 RestrictedToken token;
583 ASSERT_EQ(ERROR_SUCCESS, token.Init(NULL));
584
585 ASSERT_EQ(ERROR_ALREADY_INITIALIZED, token.Init(NULL));
586 }
587
588 } // namespace sandbox
589