Add ICU message format support
[chromium-blink-merge.git] / sandbox / win / src / restricted_token_unittest.cc
blobfca1a079750df0e5048e1d47ee3050f01578c745
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.
5 // This file contains unit tests for the RestrictedToken.
7 #define _ATL_NO_EXCEPTIONS
8 #include <atlbase.h>
9 #include <atlsecurity.h>
10 #include <vector>
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"
17 namespace sandbox {
19 // Tests the initializatioin with an invalid token handle.
20 TEST(RestrictedTokenTest, InvalidHandle) {
21 RestrictedToken token;
22 ASSERT_EQ(ERROR_INVALID_HANDLE, token.Init(reinterpret_cast<HANDLE>(0x5555)));
25 // Tests the initialization with NULL as parameter.
26 TEST(RestrictedTokenTest, DefaultInit) {
27 // Get the current process token.
28 HANDLE token_handle = INVALID_HANDLE_VALUE;
29 ASSERT_TRUE(::OpenProcessToken(::GetCurrentProcess(), TOKEN_ALL_ACCESS,
30 &token_handle));
32 ASSERT_NE(INVALID_HANDLE_VALUE, token_handle);
34 ATL::CAccessToken access_token;
35 access_token.Attach(token_handle);
37 // Create the token using the current token.
38 RestrictedToken token_default;
39 ASSERT_EQ(ERROR_SUCCESS, token_default.Init(NULL));
41 // Get the handle to the restricted token.
43 base::win::ScopedHandle restricted_token_handle;
44 ASSERT_EQ(ERROR_SUCCESS,
45 token_default.GetRestrictedToken(&restricted_token_handle));
47 ATL::CAccessToken restricted_token;
48 restricted_token.Attach(restricted_token_handle.Take());
50 ATL::CSid sid_user_restricted;
51 ATL::CSid sid_user_default;
52 ATL::CSid sid_owner_restricted;
53 ATL::CSid sid_owner_default;
54 ASSERT_TRUE(restricted_token.GetUser(&sid_user_restricted));
55 ASSERT_TRUE(access_token.GetUser(&sid_user_default));
56 ASSERT_TRUE(restricted_token.GetOwner(&sid_owner_restricted));
57 ASSERT_TRUE(access_token.GetOwner(&sid_owner_default));
59 // Check if both token have the same owner and user.
60 ASSERT_EQ(sid_user_restricted, sid_user_default);
61 ASSERT_EQ(sid_owner_restricted, sid_owner_default);
64 // Tests the initialization with a custom token as parameter.
65 TEST(RestrictedTokenTest, CustomInit) {
66 // Get the current process token.
67 HANDLE token_handle = INVALID_HANDLE_VALUE;
68 ASSERT_TRUE(::OpenProcessToken(::GetCurrentProcess(), TOKEN_ALL_ACCESS,
69 &token_handle));
71 ASSERT_NE(INVALID_HANDLE_VALUE, token_handle);
73 ATL::CAccessToken access_token;
74 access_token.Attach(token_handle);
76 // Change the primary group.
77 access_token.SetPrimaryGroup(ATL::Sids::World());
79 // Create the token using the current token.
80 RestrictedToken token;
81 ASSERT_EQ(ERROR_SUCCESS, token.Init(access_token.GetHandle()));
83 // Get the handle to the restricted token.
85 base::win::ScopedHandle restricted_token_handle;
86 ASSERT_EQ(ERROR_SUCCESS,
87 token.GetRestrictedToken(&restricted_token_handle));
89 ATL::CAccessToken restricted_token;
90 restricted_token.Attach(restricted_token_handle.Take());
92 ATL::CSid sid_restricted;
93 ATL::CSid sid_default;
94 ASSERT_TRUE(restricted_token.GetPrimaryGroup(&sid_restricted));
95 ASSERT_TRUE(access_token.GetPrimaryGroup(&sid_default));
97 // Check if both token have the same owner.
98 ASSERT_EQ(sid_restricted, sid_default);
101 // Verifies that the token created by the object are valid.
102 TEST(RestrictedTokenTest, ResultToken) {
103 RestrictedToken token;
104 ASSERT_EQ(ERROR_SUCCESS, token.Init(NULL));
106 ASSERT_EQ(ERROR_SUCCESS,
107 token.AddRestrictingSid(ATL::Sids::World().GetPSID()));
109 base::win::ScopedHandle restricted_token;
110 ASSERT_EQ(ERROR_SUCCESS, token.GetRestrictedToken(&restricted_token));
112 ASSERT_TRUE(::IsTokenRestricted(restricted_token.Get()));
114 DWORD length = 0;
115 TOKEN_TYPE type;
116 ASSERT_TRUE(::GetTokenInformation(restricted_token.Get(),
117 ::TokenType,
118 &type,
119 sizeof(type),
120 &length));
122 ASSERT_EQ(type, TokenPrimary);
124 base::win::ScopedHandle impersonation_token;
125 ASSERT_EQ(ERROR_SUCCESS,
126 token.GetRestrictedTokenForImpersonation(&impersonation_token));
128 ASSERT_TRUE(::IsTokenRestricted(impersonation_token.Get()));
130 ASSERT_TRUE(::GetTokenInformation(impersonation_token.Get(),
131 ::TokenType,
132 &type,
133 sizeof(type),
134 &length));
136 ASSERT_EQ(type, TokenImpersonation);
139 // Verifies that the token created has "Restricted" in its default dacl.
140 TEST(RestrictedTokenTest, DefaultDacl) {
141 RestrictedToken token;
142 ASSERT_EQ(ERROR_SUCCESS, token.Init(NULL));
144 ASSERT_EQ(ERROR_SUCCESS,
145 token.AddRestrictingSid(ATL::Sids::World().GetPSID()));
147 base::win::ScopedHandle handle;
148 ASSERT_EQ(ERROR_SUCCESS, token.GetRestrictedToken(&handle));
150 ATL::CAccessToken restricted_token;
151 restricted_token.Attach(handle.Take());
153 ATL::CDacl dacl;
154 ASSERT_TRUE(restricted_token.GetDefaultDacl(&dacl));
156 bool restricted_found = false;
158 unsigned int ace_count = dacl.GetAceCount();
159 for (unsigned int i = 0; i < ace_count ; ++i) {
160 ATL::CSid sid;
161 ACCESS_MASK mask = 0;
162 dacl.GetAclEntry(i, &sid, &mask);
163 if (sid == ATL::Sids::RestrictedCode() && mask == GENERIC_ALL) {
164 restricted_found = true;
165 break;
169 ASSERT_TRUE(restricted_found);
172 // Tests the method "AddSidForDenyOnly".
173 TEST(RestrictedTokenTest, DenySid) {
174 RestrictedToken token;
175 base::win::ScopedHandle token_handle;
177 ASSERT_EQ(ERROR_SUCCESS, token.Init(NULL));
178 ASSERT_EQ(ERROR_SUCCESS, token.AddSidForDenyOnly(Sid(WinWorldSid)));
179 ASSERT_EQ(ERROR_SUCCESS, token.GetRestrictedToken(&token_handle));
181 ATL::CAccessToken restricted_token;
182 restricted_token.Attach(token_handle.Take());
184 ATL::CTokenGroups groups;
185 ASSERT_TRUE(restricted_token.GetGroups(&groups));
187 ATL::CSid::CSidArray sids;
188 ATL::CAtlArray<DWORD> attributes;
189 groups.GetSidsAndAttributes(&sids, &attributes);
191 for (unsigned int i = 0; i < sids.GetCount(); i++) {
192 if (ATL::Sids::World() == sids[i]) {
193 ASSERT_EQ(SE_GROUP_USE_FOR_DENY_ONLY,
194 attributes[i] & SE_GROUP_USE_FOR_DENY_ONLY);
199 // Tests the method "AddAllSidsForDenyOnly".
200 TEST(RestrictedTokenTest, DenySids) {
201 RestrictedToken token;
202 base::win::ScopedHandle token_handle;
204 ASSERT_EQ(ERROR_SUCCESS, token.Init(NULL));
205 ASSERT_EQ(ERROR_SUCCESS, token.AddAllSidsForDenyOnly(NULL));
206 ASSERT_EQ(ERROR_SUCCESS, token.GetRestrictedToken(&token_handle));
208 ATL::CAccessToken restricted_token;
209 restricted_token.Attach(token_handle.Take());
211 ATL::CTokenGroups groups;
212 ASSERT_TRUE(restricted_token.GetGroups(&groups));
214 ATL::CSid::CSidArray sids;
215 ATL::CAtlArray<DWORD> attributes;
216 groups.GetSidsAndAttributes(&sids, &attributes);
218 // Verify that all sids are really gone.
219 for (unsigned int i = 0; i < sids.GetCount(); i++) {
220 if ((attributes[i] & SE_GROUP_LOGON_ID) == 0 &&
221 (attributes[i] & SE_GROUP_INTEGRITY) == 0) {
222 ASSERT_EQ(SE_GROUP_USE_FOR_DENY_ONLY,
223 attributes[i] & SE_GROUP_USE_FOR_DENY_ONLY);
228 // Tests the method "AddAllSidsForDenyOnly" using an exception list.
229 TEST(RestrictedTokenTest, DenySidsException) {
230 RestrictedToken token;
231 base::win::ScopedHandle token_handle;
233 std::vector<Sid> sids_exception;
234 sids_exception.push_back(Sid(WinWorldSid));
236 ASSERT_EQ(ERROR_SUCCESS, token.Init(NULL));
237 ASSERT_EQ(ERROR_SUCCESS, token.AddAllSidsForDenyOnly(&sids_exception));
238 ASSERT_EQ(ERROR_SUCCESS, token.GetRestrictedToken(&token_handle));
240 ATL::CAccessToken restricted_token;
241 restricted_token.Attach(token_handle.Take());
243 ATL::CTokenGroups groups;
244 ASSERT_TRUE(restricted_token.GetGroups(&groups));
246 ATL::CSid::CSidArray sids;
247 ATL::CAtlArray<DWORD> attributes;
248 groups.GetSidsAndAttributes(&sids, &attributes);
250 // Verify that all sids are really gone.
251 for (unsigned int i = 0; i < sids.GetCount(); i++) {
252 if ((attributes[i] & SE_GROUP_LOGON_ID) == 0 &&
253 (attributes[i] & SE_GROUP_INTEGRITY) == 0) {
254 if (ATL::Sids::World() == sids[i]) {
255 ASSERT_EQ(NULL, attributes[i] & SE_GROUP_USE_FOR_DENY_ONLY);
256 } else {
257 ASSERT_EQ(SE_GROUP_USE_FOR_DENY_ONLY,
258 attributes[i] & SE_GROUP_USE_FOR_DENY_ONLY);
264 // Tests test method AddOwnerSidForDenyOnly.
265 TEST(RestrictedTokenTest, DenyOwnerSid) {
266 RestrictedToken token;
267 base::win::ScopedHandle token_handle;
269 ASSERT_EQ(ERROR_SUCCESS, token.Init(NULL));
270 ASSERT_EQ(ERROR_SUCCESS, token.AddUserSidForDenyOnly());
271 ASSERT_EQ(ERROR_SUCCESS, token.GetRestrictedToken(&token_handle));
273 ATL::CAccessToken restricted_token;
274 restricted_token.Attach(token_handle.Take());
276 ATL::CTokenGroups groups;
277 ASSERT_TRUE(restricted_token.GetGroups(&groups));
279 ATL::CSid::CSidArray sids;
280 ATL::CAtlArray<DWORD> attributes;
281 groups.GetSidsAndAttributes(&sids, &attributes);
283 ATL::CSid user_sid;
284 ASSERT_TRUE(restricted_token.GetUser(&user_sid));
286 for (unsigned int i = 0; i < sids.GetCount(); ++i) {
287 if (user_sid == sids[i]) {
288 ASSERT_EQ(SE_GROUP_USE_FOR_DENY_ONLY,
289 attributes[i] & SE_GROUP_USE_FOR_DENY_ONLY);
294 // Tests test method AddOwnerSidForDenyOnly with a custom effective token.
295 TEST(RestrictedTokenTest, DenyOwnerSidCustom) {
296 // Get the current process token.
297 HANDLE access_handle = INVALID_HANDLE_VALUE;
298 ASSERT_TRUE(::OpenProcessToken(::GetCurrentProcess(), TOKEN_ALL_ACCESS,
299 &access_handle));
301 ASSERT_NE(INVALID_HANDLE_VALUE, access_handle);
303 ATL::CAccessToken access_token;
304 access_token.Attach(access_handle);
306 RestrictedToken token;
307 base::win::ScopedHandle token_handle;
308 ASSERT_EQ(ERROR_SUCCESS, token.Init(access_token.GetHandle()));
309 ASSERT_EQ(ERROR_SUCCESS, token.AddUserSidForDenyOnly());
310 ASSERT_EQ(ERROR_SUCCESS, token.GetRestrictedToken(&token_handle));
312 ATL::CAccessToken restricted_token;
313 restricted_token.Attach(token_handle.Take());
315 ATL::CTokenGroups groups;
316 ASSERT_TRUE(restricted_token.GetGroups(&groups));
318 ATL::CSid::CSidArray sids;
319 ATL::CAtlArray<DWORD> attributes;
320 groups.GetSidsAndAttributes(&sids, &attributes);
322 ATL::CSid user_sid;
323 ASSERT_TRUE(restricted_token.GetUser(&user_sid));
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);
333 // Tests the method DeleteAllPrivileges.
334 TEST(RestrictedTokenTest, DeleteAllPrivileges) {
335 RestrictedToken token;
336 base::win::ScopedHandle token_handle;
338 ASSERT_EQ(ERROR_SUCCESS, token.Init(NULL));
339 ASSERT_EQ(ERROR_SUCCESS, token.DeleteAllPrivileges(NULL));
340 ASSERT_EQ(ERROR_SUCCESS, token.GetRestrictedToken(&token_handle));
342 ATL::CAccessToken restricted_token;
343 restricted_token.Attach(token_handle.Take());
345 ATL::CTokenPrivileges privileges;
346 ASSERT_TRUE(restricted_token.GetPrivileges(&privileges));
348 ASSERT_EQ(0, privileges.GetCount());
351 // Tests the method DeleteAllPrivileges with an exception list.
352 TEST(RestrictedTokenTest, DeleteAllPrivilegesException) {
353 RestrictedToken token;
354 base::win::ScopedHandle token_handle;
356 std::vector<base::string16> exceptions;
357 exceptions.push_back(SE_CHANGE_NOTIFY_NAME);
359 ASSERT_EQ(ERROR_SUCCESS, token.Init(NULL));
360 ASSERT_EQ(ERROR_SUCCESS, token.DeleteAllPrivileges(&exceptions));
361 ASSERT_EQ(ERROR_SUCCESS, token.GetRestrictedToken(&token_handle));
363 ATL::CAccessToken restricted_token;
364 restricted_token.Attach(token_handle.Take());
366 ATL::CTokenPrivileges privileges;
367 ASSERT_TRUE(restricted_token.GetPrivileges(&privileges));
369 ATL::CTokenPrivileges::CNames privilege_names;
370 ATL::CTokenPrivileges::CAttributes privilege_name_attributes;
371 privileges.GetNamesAndAttributes(&privilege_names,
372 &privilege_name_attributes);
374 ASSERT_EQ(1, privileges.GetCount());
376 for (unsigned int i = 0; i < privileges.GetCount(); ++i) {
377 ASSERT_EQ(privilege_names[i], SE_CHANGE_NOTIFY_NAME);
381 // Tests the method DeletePrivilege.
382 TEST(RestrictedTokenTest, DeletePrivilege) {
383 RestrictedToken token;
384 base::win::ScopedHandle token_handle;
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.GetRestrictedToken(&token_handle));
390 ATL::CAccessToken restricted_token;
391 restricted_token.Attach(token_handle.Take());
393 ATL::CTokenPrivileges privileges;
394 ASSERT_TRUE(restricted_token.GetPrivileges(&privileges));
396 ATL::CTokenPrivileges::CNames privilege_names;
397 ATL::CTokenPrivileges::CAttributes privilege_name_attributes;
398 privileges.GetNamesAndAttributes(&privilege_names,
399 &privilege_name_attributes);
401 for (unsigned int i = 0; i < privileges.GetCount(); ++i) {
402 ASSERT_NE(privilege_names[i], SE_CHANGE_NOTIFY_NAME);
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));
420 ATL::CTokenGroups atl_groups(*groups);
421 delete[] memory;
423 if (count >= 0)
424 ASSERT_EQ(count, atl_groups.GetCount());
426 ATL::CSid::CSidArray sids;
427 ATL::CAtlArray<DWORD> attributes;
428 atl_groups.GetSidsAndAttributes(&sids, &attributes);
430 bool present = false;
431 for (unsigned int i = 0; i < sids.GetCount(); ++i) {
432 if (sids[i] == sid) {
433 present = true;
434 break;
438 ASSERT_TRUE(present);
441 // Tests the method AddRestrictingSid.
442 TEST(RestrictedTokenTest, AddRestrictingSid) {
443 RestrictedToken token;
444 base::win::ScopedHandle token_handle;
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.GetRestrictedToken(&token_handle));
451 ATL::CAccessToken restricted_token;
452 restricted_token.Attach(token_handle.Take());
454 CheckRestrictingSid(restricted_token, ATL::Sids::World(), 1);
457 // Tests the method AddRestrictingSidCurrentUser.
458 TEST(RestrictedTokenTest, AddRestrictingSidCurrentUser) {
459 RestrictedToken token;
460 base::win::ScopedHandle token_handle;
462 ASSERT_EQ(ERROR_SUCCESS, token.Init(NULL));
463 ASSERT_EQ(ERROR_SUCCESS, token.AddRestrictingSidCurrentUser());
464 ASSERT_EQ(ERROR_SUCCESS, token.GetRestrictedToken(&token_handle));
466 ATL::CAccessToken restricted_token;
467 restricted_token.Attach(token_handle.Take());
468 ATL::CSid user;
469 restricted_token.GetUser(&user);
471 CheckRestrictingSid(restricted_token, user, 1);
474 // Tests the method AddRestrictingSidCurrentUser with a custom effective token.
475 TEST(RestrictedTokenTest, AddRestrictingSidCurrentUserCustom) {
476 // Get the current process token.
477 HANDLE access_handle = INVALID_HANDLE_VALUE;
478 ASSERT_TRUE(::OpenProcessToken(::GetCurrentProcess(), TOKEN_ALL_ACCESS,
479 &access_handle));
481 ASSERT_NE(INVALID_HANDLE_VALUE, access_handle);
483 ATL::CAccessToken access_token;
484 access_token.Attach(access_handle);
486 RestrictedToken token;
487 base::win::ScopedHandle token_handle;
488 ASSERT_EQ(ERROR_SUCCESS, token.Init(access_token.GetHandle()));
489 ASSERT_EQ(ERROR_SUCCESS, token.AddRestrictingSidCurrentUser());
490 ASSERT_EQ(ERROR_SUCCESS, token.GetRestrictedToken(&token_handle));
492 ATL::CAccessToken restricted_token;
493 restricted_token.Attach(token_handle.Take());
494 ATL::CSid user;
495 restricted_token.GetUser(&user);
497 CheckRestrictingSid(restricted_token, user, 1);
500 // Tests the method AddRestrictingSidLogonSession.
501 TEST(RestrictedTokenTest, AddRestrictingSidLogonSession) {
502 RestrictedToken token;
503 base::win::ScopedHandle token_handle;
505 ASSERT_EQ(ERROR_SUCCESS, token.Init(NULL));
506 ASSERT_EQ(ERROR_SUCCESS, token.AddRestrictingSidLogonSession());
507 ASSERT_EQ(ERROR_SUCCESS, token.GetRestrictedToken(&token_handle));
509 ATL::CAccessToken restricted_token;
510 restricted_token.Attach(token_handle.Take());
511 ATL::CSid session;
512 restricted_token.GetLogonSid(&session);
514 CheckRestrictingSid(restricted_token, session, 1);
517 // Tests adding a lot of restricting sids.
518 TEST(RestrictedTokenTest, AddMultipleRestrictingSids) {
519 RestrictedToken token;
520 base::win::ScopedHandle token_handle;
522 ASSERT_EQ(ERROR_SUCCESS, token.Init(NULL));
523 ASSERT_EQ(ERROR_SUCCESS, token.AddRestrictingSidCurrentUser());
524 ASSERT_EQ(ERROR_SUCCESS, token.AddRestrictingSidLogonSession());
525 ASSERT_EQ(ERROR_SUCCESS,
526 token.AddRestrictingSid(ATL::Sids::World().GetPSID()));
527 ASSERT_EQ(ERROR_SUCCESS, token.GetRestrictedToken(&token_handle));
529 ATL::CAccessToken restricted_token;
530 restricted_token.Attach(token_handle.Take());
531 ATL::CSid session;
532 restricted_token.GetLogonSid(&session);
534 DWORD length = 8192;
535 BYTE *memory = new BYTE[length];
536 TOKEN_GROUPS *groups = reinterpret_cast<TOKEN_GROUPS*>(memory);
537 ASSERT_TRUE(::GetTokenInformation(restricted_token.GetHandle(),
538 TokenRestrictedSids,
539 groups,
540 length,
541 &length));
543 ATL::CTokenGroups atl_groups(*groups);
544 delete[] memory;
546 ASSERT_EQ(3, atl_groups.GetCount());
549 // Tests the method "AddRestrictingSidAllSids".
550 TEST(RestrictedTokenTest, AddAllSidToRestrictingSids) {
551 RestrictedToken token;
552 base::win::ScopedHandle token_handle;
554 ASSERT_EQ(ERROR_SUCCESS, token.Init(NULL));
555 ASSERT_EQ(ERROR_SUCCESS, token.AddRestrictingSidAllSids());
556 ASSERT_EQ(ERROR_SUCCESS, token.GetRestrictedToken(&token_handle));
558 ATL::CAccessToken restricted_token;
559 restricted_token.Attach(token_handle.Take());
561 ATL::CTokenGroups groups;
562 ASSERT_TRUE(restricted_token.GetGroups(&groups));
564 ATL::CSid::CSidArray sids;
565 ATL::CAtlArray<DWORD> attributes;
566 groups.GetSidsAndAttributes(&sids, &attributes);
568 // Verify that all group sids are in the restricting sid list.
569 for (unsigned int i = 0; i < sids.GetCount(); i++) {
570 if ((attributes[i] & SE_GROUP_INTEGRITY) == 0) {
571 CheckRestrictingSid(restricted_token, sids[i], -1);
575 // Verify that the user is in the restricting sid list.
576 ATL::CSid user;
577 restricted_token.GetUser(&user);
578 CheckRestrictingSid(restricted_token, user, -1);
581 // Checks the error code when the object is initialized twice.
582 TEST(RestrictedTokenTest, DoubleInit) {
583 RestrictedToken token;
584 ASSERT_EQ(ERROR_SUCCESS, token.Init(NULL));
586 ASSERT_EQ(ERROR_ALREADY_INITIALIZED, token.Init(NULL));
589 } // namespace sandbox