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. 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. 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. 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. 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. 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". 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". 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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". 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. 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