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