| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "sandbox/win/src/restricted_token.h" | 5 #include "sandbox/win/src/restricted_token.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <memory> |
| 9 #include <vector> | 10 #include <vector> |
| 10 | 11 |
| 11 #include "base/logging.h" | 12 #include "base/logging.h" |
| 12 #include "base/memory/scoped_ptr.h" | |
| 13 #include "sandbox/win/src/acl.h" | 13 #include "sandbox/win/src/acl.h" |
| 14 #include "sandbox/win/src/win_utils.h" | 14 #include "sandbox/win/src/win_utils.h" |
| 15 | 15 |
| 16 namespace { | 16 namespace { |
| 17 | 17 |
| 18 // Calls GetTokenInformation with the desired |info_class| and returns a buffer | 18 // Calls GetTokenInformation with the desired |info_class| and returns a buffer |
| 19 // with the result. | 19 // with the result. |
| 20 scoped_ptr<BYTE[]> GetTokenInfo(const base::win::ScopedHandle& token, | 20 std::unique_ptr<BYTE[]> GetTokenInfo(const base::win::ScopedHandle& token, |
| 21 TOKEN_INFORMATION_CLASS info_class, | 21 TOKEN_INFORMATION_CLASS info_class, |
| 22 DWORD* error) { | 22 DWORD* error) { |
| 23 // Get the required buffer size. | 23 // Get the required buffer size. |
| 24 DWORD size = 0; | 24 DWORD size = 0; |
| 25 ::GetTokenInformation(token.Get(), info_class, NULL, 0, &size); | 25 ::GetTokenInformation(token.Get(), info_class, NULL, 0, &size); |
| 26 if (!size) { | 26 if (!size) { |
| 27 *error = ::GetLastError(); | 27 *error = ::GetLastError(); |
| 28 return nullptr; | 28 return nullptr; |
| 29 } | 29 } |
| 30 | 30 |
| 31 scoped_ptr<BYTE[]> buffer(new BYTE[size]); | 31 std::unique_ptr<BYTE[]> buffer(new BYTE[size]); |
| 32 if (!::GetTokenInformation(token.Get(), info_class, buffer.get(), size, | 32 if (!::GetTokenInformation(token.Get(), info_class, buffer.get(), size, |
| 33 &size)) { | 33 &size)) { |
| 34 *error = ::GetLastError(); | 34 *error = ::GetLastError(); |
| 35 return nullptr; | 35 return nullptr; |
| 36 } | 36 } |
| 37 | 37 |
| 38 *error = ERROR_SUCCESS; | 38 *error = ERROR_SUCCESS; |
| 39 return buffer; | 39 return buffer; |
| 40 } | 40 } |
| 41 | 41 |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 220 token->Set(token_handle); | 220 token->Set(token_handle); |
| 221 return ERROR_SUCCESS; | 221 return ERROR_SUCCESS; |
| 222 } | 222 } |
| 223 | 223 |
| 224 DWORD RestrictedToken::AddAllSidsForDenyOnly(std::vector<Sid> *exceptions) { | 224 DWORD RestrictedToken::AddAllSidsForDenyOnly(std::vector<Sid> *exceptions) { |
| 225 DCHECK(init_); | 225 DCHECK(init_); |
| 226 if (!init_) | 226 if (!init_) |
| 227 return ERROR_NO_TOKEN; | 227 return ERROR_NO_TOKEN; |
| 228 | 228 |
| 229 DWORD error; | 229 DWORD error; |
| 230 scoped_ptr<BYTE[]> buffer = | 230 std::unique_ptr<BYTE[]> buffer = |
| 231 GetTokenInfo(effective_token_, TokenGroups, &error); | 231 GetTokenInfo(effective_token_, TokenGroups, &error); |
| 232 | 232 |
| 233 if (!buffer) | 233 if (!buffer) |
| 234 return error; | 234 return error; |
| 235 | 235 |
| 236 TOKEN_GROUPS* token_groups = reinterpret_cast<TOKEN_GROUPS*>(buffer.get()); | 236 TOKEN_GROUPS* token_groups = reinterpret_cast<TOKEN_GROUPS*>(buffer.get()); |
| 237 | 237 |
| 238 // Build the list of the deny only group SIDs | 238 // Build the list of the deny only group SIDs |
| 239 for (unsigned int i = 0; i < token_groups->GroupCount ; ++i) { | 239 for (unsigned int i = 0; i < token_groups->GroupCount ; ++i) { |
| 240 if ((token_groups->Groups[i].Attributes & SE_GROUP_INTEGRITY) == 0 && | 240 if ((token_groups->Groups[i].Attributes & SE_GROUP_INTEGRITY) == 0 && |
| (...skipping 26 matching lines...) Expand all Loading... |
| 267 sids_for_deny_only_.push_back(sid); | 267 sids_for_deny_only_.push_back(sid); |
| 268 return ERROR_SUCCESS; | 268 return ERROR_SUCCESS; |
| 269 } | 269 } |
| 270 | 270 |
| 271 DWORD RestrictedToken::AddUserSidForDenyOnly() { | 271 DWORD RestrictedToken::AddUserSidForDenyOnly() { |
| 272 DCHECK(init_); | 272 DCHECK(init_); |
| 273 if (!init_) | 273 if (!init_) |
| 274 return ERROR_NO_TOKEN; | 274 return ERROR_NO_TOKEN; |
| 275 | 275 |
| 276 DWORD size = sizeof(TOKEN_USER) + SECURITY_MAX_SID_SIZE; | 276 DWORD size = sizeof(TOKEN_USER) + SECURITY_MAX_SID_SIZE; |
| 277 scoped_ptr<BYTE[]> buffer(new BYTE[size]); | 277 std::unique_ptr<BYTE[]> buffer(new BYTE[size]); |
| 278 TOKEN_USER* token_user = reinterpret_cast<TOKEN_USER*>(buffer.get()); | 278 TOKEN_USER* token_user = reinterpret_cast<TOKEN_USER*>(buffer.get()); |
| 279 | 279 |
| 280 BOOL result = ::GetTokenInformation(effective_token_.Get(), TokenUser, | 280 BOOL result = ::GetTokenInformation(effective_token_.Get(), TokenUser, |
| 281 token_user, size, &size); | 281 token_user, size, &size); |
| 282 | 282 |
| 283 if (!result) | 283 if (!result) |
| 284 return ::GetLastError(); | 284 return ::GetLastError(); |
| 285 | 285 |
| 286 Sid user = reinterpret_cast<SID*>(token_user->User.Sid); | 286 Sid user = reinterpret_cast<SID*>(token_user->User.Sid); |
| 287 sids_for_deny_only_.push_back(user); | 287 sids_for_deny_only_.push_back(user); |
| 288 | 288 |
| 289 return ERROR_SUCCESS; | 289 return ERROR_SUCCESS; |
| 290 } | 290 } |
| 291 | 291 |
| 292 DWORD RestrictedToken::DeleteAllPrivileges( | 292 DWORD RestrictedToken::DeleteAllPrivileges( |
| 293 const std::vector<base::string16> *exceptions) { | 293 const std::vector<base::string16> *exceptions) { |
| 294 DCHECK(init_); | 294 DCHECK(init_); |
| 295 if (!init_) | 295 if (!init_) |
| 296 return ERROR_NO_TOKEN; | 296 return ERROR_NO_TOKEN; |
| 297 | 297 |
| 298 DWORD error; | 298 DWORD error; |
| 299 scoped_ptr<BYTE[]> buffer = | 299 std::unique_ptr<BYTE[]> buffer = |
| 300 GetTokenInfo(effective_token_, TokenPrivileges, &error); | 300 GetTokenInfo(effective_token_, TokenPrivileges, &error); |
| 301 | 301 |
| 302 if (!buffer) | 302 if (!buffer) |
| 303 return error; | 303 return error; |
| 304 | 304 |
| 305 TOKEN_PRIVILEGES* token_privileges = | 305 TOKEN_PRIVILEGES* token_privileges = |
| 306 reinterpret_cast<TOKEN_PRIVILEGES*>(buffer.get()); | 306 reinterpret_cast<TOKEN_PRIVILEGES*>(buffer.get()); |
| 307 | 307 |
| 308 // Build the list of privileges to disable | 308 // Build the list of privileges to disable |
| 309 for (unsigned int i = 0; i < token_privileges->PrivilegeCount; ++i) { | 309 for (unsigned int i = 0; i < token_privileges->PrivilegeCount; ++i) { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 349 sids_to_restrict_.push_back(sid); // No attributes | 349 sids_to_restrict_.push_back(sid); // No attributes |
| 350 return ERROR_SUCCESS; | 350 return ERROR_SUCCESS; |
| 351 } | 351 } |
| 352 | 352 |
| 353 DWORD RestrictedToken::AddRestrictingSidLogonSession() { | 353 DWORD RestrictedToken::AddRestrictingSidLogonSession() { |
| 354 DCHECK(init_); | 354 DCHECK(init_); |
| 355 if (!init_) | 355 if (!init_) |
| 356 return ERROR_NO_TOKEN; | 356 return ERROR_NO_TOKEN; |
| 357 | 357 |
| 358 DWORD error; | 358 DWORD error; |
| 359 scoped_ptr<BYTE[]> buffer = | 359 std::unique_ptr<BYTE[]> buffer = |
| 360 GetTokenInfo(effective_token_, TokenGroups, &error); | 360 GetTokenInfo(effective_token_, TokenGroups, &error); |
| 361 | 361 |
| 362 if (!buffer) | 362 if (!buffer) |
| 363 return error; | 363 return error; |
| 364 | 364 |
| 365 TOKEN_GROUPS* token_groups = reinterpret_cast<TOKEN_GROUPS*>(buffer.get()); | 365 TOKEN_GROUPS* token_groups = reinterpret_cast<TOKEN_GROUPS*>(buffer.get()); |
| 366 | 366 |
| 367 SID *logon_sid = NULL; | 367 SID *logon_sid = NULL; |
| 368 for (unsigned int i = 0; i < token_groups->GroupCount ; ++i) { | 368 for (unsigned int i = 0; i < token_groups->GroupCount ; ++i) { |
| 369 if ((token_groups->Groups[i].Attributes & SE_GROUP_LOGON_ID) != 0) { | 369 if ((token_groups->Groups[i].Attributes & SE_GROUP_LOGON_ID) != 0) { |
| 370 logon_sid = static_cast<SID*>(token_groups->Groups[i].Sid); | 370 logon_sid = static_cast<SID*>(token_groups->Groups[i].Sid); |
| 371 break; | 371 break; |
| 372 } | 372 } |
| 373 } | 373 } |
| 374 | 374 |
| 375 if (logon_sid) | 375 if (logon_sid) |
| 376 sids_to_restrict_.push_back(logon_sid); | 376 sids_to_restrict_.push_back(logon_sid); |
| 377 | 377 |
| 378 return ERROR_SUCCESS; | 378 return ERROR_SUCCESS; |
| 379 } | 379 } |
| 380 | 380 |
| 381 DWORD RestrictedToken::AddRestrictingSidCurrentUser() { | 381 DWORD RestrictedToken::AddRestrictingSidCurrentUser() { |
| 382 DCHECK(init_); | 382 DCHECK(init_); |
| 383 if (!init_) | 383 if (!init_) |
| 384 return ERROR_NO_TOKEN; | 384 return ERROR_NO_TOKEN; |
| 385 | 385 |
| 386 DWORD size = sizeof(TOKEN_USER) + SECURITY_MAX_SID_SIZE; | 386 DWORD size = sizeof(TOKEN_USER) + SECURITY_MAX_SID_SIZE; |
| 387 scoped_ptr<BYTE[]> buffer(new BYTE[size]); | 387 std::unique_ptr<BYTE[]> buffer(new BYTE[size]); |
| 388 TOKEN_USER* token_user = reinterpret_cast<TOKEN_USER*>(buffer.get()); | 388 TOKEN_USER* token_user = reinterpret_cast<TOKEN_USER*>(buffer.get()); |
| 389 | 389 |
| 390 BOOL result = ::GetTokenInformation(effective_token_.Get(), TokenUser, | 390 BOOL result = ::GetTokenInformation(effective_token_.Get(), TokenUser, |
| 391 token_user, size, &size); | 391 token_user, size, &size); |
| 392 | 392 |
| 393 if (!result) | 393 if (!result) |
| 394 return ::GetLastError(); | 394 return ::GetLastError(); |
| 395 | 395 |
| 396 Sid user = reinterpret_cast<SID*>(token_user->User.Sid); | 396 Sid user = reinterpret_cast<SID*>(token_user->User.Sid); |
| 397 sids_to_restrict_.push_back(user); | 397 sids_to_restrict_.push_back(user); |
| 398 | 398 |
| 399 return ERROR_SUCCESS; | 399 return ERROR_SUCCESS; |
| 400 } | 400 } |
| 401 | 401 |
| 402 DWORD RestrictedToken::AddRestrictingSidAllSids() { | 402 DWORD RestrictedToken::AddRestrictingSidAllSids() { |
| 403 DCHECK(init_); | 403 DCHECK(init_); |
| 404 if (!init_) | 404 if (!init_) |
| 405 return ERROR_NO_TOKEN; | 405 return ERROR_NO_TOKEN; |
| 406 | 406 |
| 407 // Add the current user to the list. | 407 // Add the current user to the list. |
| 408 DWORD error = AddRestrictingSidCurrentUser(); | 408 DWORD error = AddRestrictingSidCurrentUser(); |
| 409 if (ERROR_SUCCESS != error) | 409 if (ERROR_SUCCESS != error) |
| 410 return error; | 410 return error; |
| 411 | 411 |
| 412 scoped_ptr<BYTE[]> buffer = | 412 std::unique_ptr<BYTE[]> buffer = |
| 413 GetTokenInfo(effective_token_, TokenGroups, &error); | 413 GetTokenInfo(effective_token_, TokenGroups, &error); |
| 414 | 414 |
| 415 if (!buffer) | 415 if (!buffer) |
| 416 return error; | 416 return error; |
| 417 | 417 |
| 418 TOKEN_GROUPS* token_groups = reinterpret_cast<TOKEN_GROUPS*>(buffer.get()); | 418 TOKEN_GROUPS* token_groups = reinterpret_cast<TOKEN_GROUPS*>(buffer.get()); |
| 419 | 419 |
| 420 // Build the list of restricting sids from all groups. | 420 // Build the list of restricting sids from all groups. |
| 421 for (unsigned int i = 0; i < token_groups->GroupCount ; ++i) { | 421 for (unsigned int i = 0; i < token_groups->GroupCount ; ++i) { |
| 422 if ((token_groups->Groups[i].Attributes & SE_GROUP_INTEGRITY) == 0) | 422 if ((token_groups->Groups[i].Attributes & SE_GROUP_INTEGRITY) == 0) |
| 423 AddRestrictingSid(reinterpret_cast<SID*>(token_groups->Groups[i].Sid)); | 423 AddRestrictingSid(reinterpret_cast<SID*>(token_groups->Groups[i].Sid)); |
| 424 } | 424 } |
| 425 | 425 |
| 426 return ERROR_SUCCESS; | 426 return ERROR_SUCCESS; |
| 427 } | 427 } |
| 428 | 428 |
| 429 DWORD RestrictedToken::SetIntegrityLevel(IntegrityLevel integrity_level) { | 429 DWORD RestrictedToken::SetIntegrityLevel(IntegrityLevel integrity_level) { |
| 430 integrity_level_ = integrity_level; | 430 integrity_level_ = integrity_level; |
| 431 return ERROR_SUCCESS; | 431 return ERROR_SUCCESS; |
| 432 } | 432 } |
| 433 | 433 |
| 434 void RestrictedToken::SetLockdownDefaultDacl() { | 434 void RestrictedToken::SetLockdownDefaultDacl() { |
| 435 lockdown_default_dacl_ = true; | 435 lockdown_default_dacl_ = true; |
| 436 } | 436 } |
| 437 | 437 |
| 438 } // namespace sandbox | 438 } // namespace sandbox |
| OLD | NEW |