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 |