Chromium Code Reviews| 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 <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/memory/scoped_ptr.h" | |
| 10 #include "sandbox/win/src/acl.h" | 11 #include "sandbox/win/src/acl.h" |
| 11 #include "sandbox/win/src/win_utils.h" | 12 #include "sandbox/win/src/win_utils.h" |
| 12 | 13 |
| 14 namespace { | |
| 15 | |
| 16 // Calls GetTokenInformation with the desired |info_class| and returns a buffer | |
| 17 // with the result. | |
| 18 scoped_ptr<BYTE[]> GetTokenInfo(const base::win::ScopedHandle& token, | |
| 19 _TOKEN_INFORMATION_CLASS info_class, | |
|
rvargas (doing something else)
2015/07/21 20:52:53
will remove the underscore.
| |
| 20 DWORD* error) { | |
| 21 // Get the required buffer size. | |
| 22 DWORD size = 0; | |
| 23 ::GetTokenInformation(token.Get(), info_class, NULL, 0, &size); | |
| 24 if (!size) { | |
| 25 *error = ::GetLastError(); | |
| 26 return nullptr; | |
| 27 } | |
| 28 | |
| 29 scoped_ptr<BYTE[]> buffer(new BYTE[size]); | |
| 30 if (!::GetTokenInformation(token.Get(), info_class, buffer.get(), size, | |
| 31 &size)) { | |
| 32 *error = ::GetLastError(); | |
| 33 return nullptr; | |
| 34 } | |
| 35 | |
| 36 *error = ERROR_SUCCESS; | |
| 37 return buffer.Pass(); | |
| 38 } | |
| 39 | |
| 40 } // namespace | |
| 41 | |
| 13 namespace sandbox { | 42 namespace sandbox { |
| 14 | 43 |
| 15 RestrictedToken::RestrictedToken() | 44 RestrictedToken::RestrictedToken() |
| 16 : effective_token_(NULL), | 45 : integrity_level_(INTEGRITY_LEVEL_LAST), |
| 17 integrity_level_(INTEGRITY_LEVEL_LAST), | |
| 18 init_(false) { | 46 init_(false) { |
| 19 } | 47 } |
| 20 | 48 |
| 21 RestrictedToken::~RestrictedToken() { | 49 RestrictedToken::~RestrictedToken() { |
| 22 if (effective_token_) | |
| 23 CloseHandle(effective_token_); | |
| 24 } | 50 } |
| 25 | 51 |
| 26 unsigned RestrictedToken::Init(const HANDLE effective_token) { | 52 unsigned RestrictedToken::Init(const HANDLE effective_token) { |
| 27 if (init_) | 53 if (init_) |
| 28 return ERROR_ALREADY_INITIALIZED; | 54 return ERROR_ALREADY_INITIALIZED; |
| 29 | 55 |
| 56 HANDLE temp_token; | |
| 30 if (effective_token) { | 57 if (effective_token) { |
| 31 // We duplicate the handle to be able to use it even if the original handle | 58 // We duplicate the handle to be able to use it even if the original handle |
| 32 // is closed. | 59 // is closed. |
| 33 HANDLE effective_token_dup; | 60 if (!::DuplicateHandle(::GetCurrentProcess(), effective_token, |
| 34 if (::DuplicateHandle(::GetCurrentProcess(), | 61 ::GetCurrentProcess(), &temp_token, |
| 35 effective_token, | 62 0, FALSE, DUPLICATE_SAME_ACCESS)) { |
| 36 ::GetCurrentProcess(), | |
| 37 &effective_token_dup, | |
| 38 0, | |
| 39 FALSE, | |
| 40 DUPLICATE_SAME_ACCESS)) { | |
| 41 effective_token_ = effective_token_dup; | |
| 42 } else { | |
| 43 return ::GetLastError(); | 63 return ::GetLastError(); |
| 44 } | 64 } |
| 45 } else { | 65 } else { |
| 46 if (!::OpenProcessToken(::GetCurrentProcess(), | 66 if (!::OpenProcessToken(::GetCurrentProcess(), TOKEN_ALL_ACCESS, |
| 47 TOKEN_ALL_ACCESS, | 67 &temp_token)) { |
| 48 &effective_token_)) | |
| 49 return ::GetLastError(); | 68 return ::GetLastError(); |
| 69 } | |
| 50 } | 70 } |
| 71 effective_token_.Set(temp_token); | |
| 51 | 72 |
| 52 init_ = true; | 73 init_ = true; |
| 53 return ERROR_SUCCESS; | 74 return ERROR_SUCCESS; |
| 54 } | 75 } |
| 55 | 76 |
| 56 unsigned RestrictedToken::GetRestrictedToken( | 77 unsigned RestrictedToken::GetRestrictedToken( |
| 57 base::win::ScopedHandle* token) const { | 78 base::win::ScopedHandle* token) const { |
| 58 DCHECK(init_); | 79 DCHECK(init_); |
| 59 if (!init_) | 80 if (!init_) |
| 60 return ERROR_NO_TOKEN; | 81 return ERROR_NO_TOKEN; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 95 } | 116 } |
| 96 } | 117 } |
| 97 | 118 |
| 98 BOOL result = TRUE; | 119 BOOL result = TRUE; |
| 99 HANDLE new_token_handle = NULL; | 120 HANDLE new_token_handle = NULL; |
| 100 // The SANDBOX_INERT flag did nothing in XP and it was just a way to tell | 121 // The SANDBOX_INERT flag did nothing in XP and it was just a way to tell |
| 101 // if a token has ben restricted given the limiations of IsTokenRestricted() | 122 // if a token has ben restricted given the limiations of IsTokenRestricted() |
| 102 // but it appears that in Windows 7 it hints the AppLocker subsystem to | 123 // but it appears that in Windows 7 it hints the AppLocker subsystem to |
| 103 // leave us alone. | 124 // leave us alone. |
| 104 if (deny_size || restrict_size || privileges_size) { | 125 if (deny_size || restrict_size || privileges_size) { |
| 105 result = ::CreateRestrictedToken(effective_token_, | 126 result = ::CreateRestrictedToken(effective_token_.Get(), |
| 106 SANDBOX_INERT, | 127 SANDBOX_INERT, |
| 107 static_cast<DWORD>(deny_size), | 128 static_cast<DWORD>(deny_size), |
| 108 deny_only_array, | 129 deny_only_array, |
| 109 static_cast<DWORD>(privileges_size), | 130 static_cast<DWORD>(privileges_size), |
| 110 privileges_to_disable_array, | 131 privileges_to_disable_array, |
| 111 static_cast<DWORD>(restrict_size), | 132 static_cast<DWORD>(restrict_size), |
| 112 sids_to_restrict_array, | 133 sids_to_restrict_array, |
| 113 &new_token_handle); | 134 &new_token_handle); |
| 114 } else { | 135 } else { |
| 115 // Duplicate the token even if it's not modified at this point | 136 // Duplicate the token even if it's not modified at this point |
| 116 // because any subsequent changes to this token would also affect the | 137 // because any subsequent changes to this token would also affect the |
| 117 // current process. | 138 // current process. |
| 118 result = ::DuplicateTokenEx(effective_token_, TOKEN_ALL_ACCESS, NULL, | 139 result = ::DuplicateTokenEx(effective_token_.Get(), TOKEN_ALL_ACCESS, NULL, |
| 119 SecurityIdentification, TokenPrimary, | 140 SecurityIdentification, TokenPrimary, |
| 120 &new_token_handle); | 141 &new_token_handle); |
| 121 } | 142 } |
| 122 | 143 |
| 123 if (deny_only_array) | 144 if (deny_only_array) |
| 124 delete[] deny_only_array; | 145 delete[] deny_only_array; |
| 125 | 146 |
| 126 if (sids_to_restrict_array) | 147 if (sids_to_restrict_array) |
| 127 delete[] sids_to_restrict_array; | 148 delete[] sids_to_restrict_array; |
| 128 | 149 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 186 | 207 |
| 187 token->Set(token_handle); | 208 token->Set(token_handle); |
| 188 return ERROR_SUCCESS; | 209 return ERROR_SUCCESS; |
| 189 } | 210 } |
| 190 | 211 |
| 191 unsigned RestrictedToken::AddAllSidsForDenyOnly(std::vector<Sid> *exceptions) { | 212 unsigned RestrictedToken::AddAllSidsForDenyOnly(std::vector<Sid> *exceptions) { |
| 192 DCHECK(init_); | 213 DCHECK(init_); |
| 193 if (!init_) | 214 if (!init_) |
| 194 return ERROR_NO_TOKEN; | 215 return ERROR_NO_TOKEN; |
| 195 | 216 |
| 196 TOKEN_GROUPS *token_groups = NULL; | 217 DWORD error; |
| 197 DWORD size = 0; | 218 scoped_ptr<BYTE[]> buffer = |
| 219 GetTokenInfo(effective_token_, TokenGroups, &error); | |
| 198 | 220 |
| 199 BOOL result = ::GetTokenInformation(effective_token_, | 221 if (!buffer) |
| 200 TokenGroups, | 222 return error; |
| 201 NULL, // No buffer. | |
| 202 0, // Size is 0. | |
| 203 &size); | |
| 204 if (!size) | |
| 205 return ::GetLastError(); | |
| 206 | 223 |
| 207 token_groups = reinterpret_cast<TOKEN_GROUPS*>(new BYTE[size]); | 224 TOKEN_GROUPS* token_groups = reinterpret_cast<TOKEN_GROUPS*>(buffer.get()); |
| 208 result = ::GetTokenInformation(effective_token_, | |
| 209 TokenGroups, | |
| 210 token_groups, | |
| 211 size, | |
| 212 &size); | |
| 213 if (!result) { | |
| 214 delete[] reinterpret_cast<BYTE*>(token_groups); | |
| 215 return ::GetLastError(); | |
| 216 } | |
| 217 | 225 |
| 218 // Build the list of the deny only group SIDs | 226 // Build the list of the deny only group SIDs |
| 219 for (unsigned int i = 0; i < token_groups->GroupCount ; ++i) { | 227 for (unsigned int i = 0; i < token_groups->GroupCount ; ++i) { |
| 220 if ((token_groups->Groups[i].Attributes & SE_GROUP_INTEGRITY) == 0 && | 228 if ((token_groups->Groups[i].Attributes & SE_GROUP_INTEGRITY) == 0 && |
| 221 (token_groups->Groups[i].Attributes & SE_GROUP_LOGON_ID) == 0) { | 229 (token_groups->Groups[i].Attributes & SE_GROUP_LOGON_ID) == 0) { |
| 222 bool should_ignore = false; | 230 bool should_ignore = false; |
| 223 if (exceptions) { | 231 if (exceptions) { |
| 224 for (unsigned int j = 0; j < exceptions->size(); ++j) { | 232 for (unsigned int j = 0; j < exceptions->size(); ++j) { |
| 225 if (::EqualSid(const_cast<SID*>((*exceptions)[j].GetPSID()), | 233 if (::EqualSid(const_cast<SID*>((*exceptions)[j].GetPSID()), |
| 226 token_groups->Groups[i].Sid)) { | 234 token_groups->Groups[i].Sid)) { |
| 227 should_ignore = true; | 235 should_ignore = true; |
| 228 break; | 236 break; |
| 229 } | 237 } |
| 230 } | 238 } |
| 231 } | 239 } |
| 232 if (!should_ignore) { | 240 if (!should_ignore) { |
| 233 sids_for_deny_only_.push_back( | 241 sids_for_deny_only_.push_back( |
| 234 reinterpret_cast<SID*>(token_groups->Groups[i].Sid)); | 242 reinterpret_cast<SID*>(token_groups->Groups[i].Sid)); |
| 235 } | 243 } |
| 236 } | 244 } |
| 237 } | 245 } |
| 238 | 246 |
| 239 delete[] reinterpret_cast<BYTE*>(token_groups); | |
| 240 | |
| 241 return ERROR_SUCCESS; | 247 return ERROR_SUCCESS; |
| 242 } | 248 } |
| 243 | 249 |
| 244 unsigned RestrictedToken::AddSidForDenyOnly(const Sid &sid) { | 250 unsigned RestrictedToken::AddSidForDenyOnly(const Sid &sid) { |
| 245 DCHECK(init_); | 251 DCHECK(init_); |
| 246 if (!init_) | 252 if (!init_) |
| 247 return ERROR_NO_TOKEN; | 253 return ERROR_NO_TOKEN; |
| 248 | 254 |
| 249 sids_for_deny_only_.push_back(sid); | 255 sids_for_deny_only_.push_back(sid); |
| 250 return ERROR_SUCCESS; | 256 return ERROR_SUCCESS; |
| 251 } | 257 } |
| 252 | 258 |
| 253 unsigned RestrictedToken::AddUserSidForDenyOnly() { | 259 unsigned RestrictedToken::AddUserSidForDenyOnly() { |
| 254 DCHECK(init_); | 260 DCHECK(init_); |
| 255 if (!init_) | 261 if (!init_) |
| 256 return ERROR_NO_TOKEN; | 262 return ERROR_NO_TOKEN; |
| 257 | 263 |
| 258 DWORD size = sizeof(TOKEN_USER) + SECURITY_MAX_SID_SIZE; | 264 DWORD size = sizeof(TOKEN_USER) + SECURITY_MAX_SID_SIZE; |
| 259 TOKEN_USER* token_user = reinterpret_cast<TOKEN_USER*>(new BYTE[size]); | 265 scoped_ptr<BYTE[]> buffer(new BYTE[size]); |
| 266 TOKEN_USER* token_user = reinterpret_cast<TOKEN_USER*>(buffer.get()); | |
| 260 | 267 |
| 261 BOOL result = ::GetTokenInformation(effective_token_, | 268 BOOL result = ::GetTokenInformation(effective_token_.Get(), TokenUser, |
| 262 TokenUser, | 269 token_user, size, &size); |
| 263 token_user, | |
| 264 size, | |
| 265 &size); | |
| 266 | 270 |
| 267 if (!result) { | 271 if (!result) |
| 268 delete[] reinterpret_cast<BYTE*>(token_user); | |
| 269 return ::GetLastError(); | 272 return ::GetLastError(); |
| 270 } | |
| 271 | 273 |
| 272 Sid user = reinterpret_cast<SID*>(token_user->User.Sid); | 274 Sid user = reinterpret_cast<SID*>(token_user->User.Sid); |
| 273 sids_for_deny_only_.push_back(user); | 275 sids_for_deny_only_.push_back(user); |
| 274 | 276 |
| 275 delete[] reinterpret_cast<BYTE*>(token_user); | |
| 276 | |
| 277 return ERROR_SUCCESS; | 277 return ERROR_SUCCESS; |
| 278 } | 278 } |
| 279 | 279 |
| 280 unsigned RestrictedToken::DeleteAllPrivileges( | 280 unsigned RestrictedToken::DeleteAllPrivileges( |
| 281 const std::vector<base::string16> *exceptions) { | 281 const std::vector<base::string16> *exceptions) { |
| 282 DCHECK(init_); | 282 DCHECK(init_); |
| 283 if (!init_) | 283 if (!init_) |
| 284 return ERROR_NO_TOKEN; | 284 return ERROR_NO_TOKEN; |
| 285 | 285 |
| 286 // Get the list of privileges in the token | 286 DWORD error; |
| 287 TOKEN_PRIVILEGES *token_privileges = NULL; | 287 scoped_ptr<BYTE[]> buffer = |
| 288 DWORD size = 0; | 288 GetTokenInfo(effective_token_, TokenPrivileges, &error); |
| 289 | 289 |
| 290 BOOL result = ::GetTokenInformation(effective_token_, | 290 if (!buffer) |
| 291 TokenPrivileges, | 291 return error; |
| 292 NULL, // No buffer. | |
| 293 0, // Size is 0. | |
| 294 &size); | |
| 295 if (!size) | |
| 296 return ::GetLastError(); | |
| 297 | 292 |
| 298 token_privileges = reinterpret_cast<TOKEN_PRIVILEGES*>(new BYTE[size]); | 293 TOKEN_PRIVILEGES* token_privileges = |
| 299 result = ::GetTokenInformation(effective_token_, | 294 reinterpret_cast<TOKEN_PRIVILEGES*>(buffer.get()); |
| 300 TokenPrivileges, | |
| 301 token_privileges, | |
| 302 size, | |
| 303 &size); | |
| 304 if (!result) { | |
| 305 delete[] reinterpret_cast<BYTE *>(token_privileges); | |
| 306 return ::GetLastError(); | |
| 307 } | |
| 308 | |
| 309 | 295 |
| 310 // Build the list of privileges to disable | 296 // Build the list of privileges to disable |
| 311 for (unsigned int i = 0; i < token_privileges->PrivilegeCount; ++i) { | 297 for (unsigned int i = 0; i < token_privileges->PrivilegeCount; ++i) { |
| 312 bool should_ignore = false; | 298 bool should_ignore = false; |
| 313 if (exceptions) { | 299 if (exceptions) { |
| 314 for (unsigned int j = 0; j < exceptions->size(); ++j) { | 300 for (unsigned int j = 0; j < exceptions->size(); ++j) { |
| 315 LUID luid = {0}; | 301 LUID luid = {0}; |
| 316 ::LookupPrivilegeValue(NULL, (*exceptions)[j].c_str(), &luid); | 302 ::LookupPrivilegeValue(NULL, (*exceptions)[j].c_str(), &luid); |
| 317 if (token_privileges->Privileges[i].Luid.HighPart == luid.HighPart && | 303 if (token_privileges->Privileges[i].Luid.HighPart == luid.HighPart && |
| 318 token_privileges->Privileges[i].Luid.LowPart == luid.LowPart) { | 304 token_privileges->Privileges[i].Luid.LowPart == luid.LowPart) { |
| 319 should_ignore = true; | 305 should_ignore = true; |
| 320 break; | 306 break; |
| 321 } | 307 } |
| 322 } | 308 } |
| 323 } | 309 } |
| 324 if (!should_ignore) { | 310 if (!should_ignore) { |
| 325 privileges_to_disable_.push_back(token_privileges->Privileges[i].Luid); | 311 privileges_to_disable_.push_back(token_privileges->Privileges[i].Luid); |
| 326 } | 312 } |
| 327 } | 313 } |
| 328 | 314 |
| 329 delete[] reinterpret_cast<BYTE *>(token_privileges); | |
| 330 | |
| 331 return ERROR_SUCCESS; | 315 return ERROR_SUCCESS; |
| 332 } | 316 } |
| 333 | 317 |
| 334 unsigned RestrictedToken::DeletePrivilege(const wchar_t *privilege) { | 318 unsigned RestrictedToken::DeletePrivilege(const wchar_t *privilege) { |
| 335 DCHECK(init_); | 319 DCHECK(init_); |
| 336 if (!init_) | 320 if (!init_) |
| 337 return ERROR_NO_TOKEN; | 321 return ERROR_NO_TOKEN; |
| 338 | 322 |
| 339 LUID luid = {0}; | 323 LUID luid = {0}; |
| 340 if (LookupPrivilegeValue(NULL, privilege, &luid)) | 324 if (LookupPrivilegeValue(NULL, privilege, &luid)) |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 352 | 336 |
| 353 sids_to_restrict_.push_back(sid); // No attributes | 337 sids_to_restrict_.push_back(sid); // No attributes |
| 354 return ERROR_SUCCESS; | 338 return ERROR_SUCCESS; |
| 355 } | 339 } |
| 356 | 340 |
| 357 unsigned RestrictedToken::AddRestrictingSidLogonSession() { | 341 unsigned RestrictedToken::AddRestrictingSidLogonSession() { |
| 358 DCHECK(init_); | 342 DCHECK(init_); |
| 359 if (!init_) | 343 if (!init_) |
| 360 return ERROR_NO_TOKEN; | 344 return ERROR_NO_TOKEN; |
| 361 | 345 |
| 362 TOKEN_GROUPS *token_groups = NULL; | 346 DWORD error; |
| 363 DWORD size = 0; | 347 scoped_ptr<BYTE[]> buffer = |
| 348 GetTokenInfo(effective_token_, TokenGroups, &error); | |
| 364 | 349 |
| 365 BOOL result = ::GetTokenInformation(effective_token_, | 350 if (!buffer) |
| 366 TokenGroups, | 351 return error; |
| 367 NULL, // No buffer. | |
| 368 0, // Size is 0. | |
| 369 &size); | |
| 370 if (!size) | |
| 371 return ::GetLastError(); | |
| 372 | 352 |
| 373 token_groups = reinterpret_cast<TOKEN_GROUPS*>(new BYTE[size]); | 353 TOKEN_GROUPS* token_groups = reinterpret_cast<TOKEN_GROUPS*>(buffer.get()); |
| 374 result = ::GetTokenInformation(effective_token_, | |
| 375 TokenGroups, | |
| 376 token_groups, | |
| 377 size, | |
| 378 &size); | |
| 379 if (!result) { | |
| 380 delete[] reinterpret_cast<BYTE*>(token_groups); | |
| 381 return ::GetLastError(); | |
| 382 } | |
| 383 | 354 |
| 384 SID *logon_sid = NULL; | 355 SID *logon_sid = NULL; |
| 385 for (unsigned int i = 0; i < token_groups->GroupCount ; ++i) { | 356 for (unsigned int i = 0; i < token_groups->GroupCount ; ++i) { |
| 386 if ((token_groups->Groups[i].Attributes & SE_GROUP_LOGON_ID) != 0) { | 357 if ((token_groups->Groups[i].Attributes & SE_GROUP_LOGON_ID) != 0) { |
| 387 logon_sid = static_cast<SID*>(token_groups->Groups[i].Sid); | 358 logon_sid = static_cast<SID*>(token_groups->Groups[i].Sid); |
| 388 break; | 359 break; |
| 389 } | 360 } |
| 390 } | 361 } |
| 391 | 362 |
| 392 if (logon_sid) | 363 if (logon_sid) |
| 393 sids_to_restrict_.push_back(logon_sid); | 364 sids_to_restrict_.push_back(logon_sid); |
| 394 | 365 |
| 395 delete[] reinterpret_cast<BYTE*>(token_groups); | |
| 396 | |
| 397 return ERROR_SUCCESS; | 366 return ERROR_SUCCESS; |
| 398 } | 367 } |
| 399 | 368 |
| 400 unsigned RestrictedToken::AddRestrictingSidCurrentUser() { | 369 unsigned RestrictedToken::AddRestrictingSidCurrentUser() { |
| 401 DCHECK(init_); | 370 DCHECK(init_); |
| 402 if (!init_) | 371 if (!init_) |
| 403 return ERROR_NO_TOKEN; | 372 return ERROR_NO_TOKEN; |
| 404 | 373 |
| 405 DWORD size = sizeof(TOKEN_USER) + SECURITY_MAX_SID_SIZE; | 374 DWORD size = sizeof(TOKEN_USER) + SECURITY_MAX_SID_SIZE; |
| 406 TOKEN_USER* token_user = reinterpret_cast<TOKEN_USER*>(new BYTE[size]); | 375 scoped_ptr<BYTE[]> buffer(new BYTE[size]); |
| 376 TOKEN_USER* token_user = reinterpret_cast<TOKEN_USER*>(buffer.get()); | |
| 407 | 377 |
| 408 BOOL result = ::GetTokenInformation(effective_token_, | 378 BOOL result = ::GetTokenInformation(effective_token_.Get(), TokenUser, |
| 409 TokenUser, | 379 token_user, size, &size); |
| 410 token_user, | |
| 411 size, | |
| 412 &size); | |
| 413 | 380 |
| 414 if (!result) { | 381 if (!result) |
| 415 delete[] reinterpret_cast<BYTE*>(token_user); | |
| 416 return ::GetLastError(); | 382 return ::GetLastError(); |
| 417 } | |
| 418 | 383 |
| 419 Sid user = reinterpret_cast<SID*>(token_user->User.Sid); | 384 Sid user = reinterpret_cast<SID*>(token_user->User.Sid); |
| 420 sids_to_restrict_.push_back(user); | 385 sids_to_restrict_.push_back(user); |
| 421 | 386 |
| 422 delete[] reinterpret_cast<BYTE*>(token_user); | |
| 423 | |
| 424 return ERROR_SUCCESS; | 387 return ERROR_SUCCESS; |
| 425 } | 388 } |
| 426 | 389 |
| 427 unsigned RestrictedToken::AddRestrictingSidAllSids() { | 390 unsigned RestrictedToken::AddRestrictingSidAllSids() { |
| 428 DCHECK(init_); | 391 DCHECK(init_); |
| 429 if (!init_) | 392 if (!init_) |
| 430 return ERROR_NO_TOKEN; | 393 return ERROR_NO_TOKEN; |
| 431 | 394 |
| 432 // Add the current user to the list. | 395 // Add the current user to the list. |
| 433 unsigned error = AddRestrictingSidCurrentUser(); | 396 DWORD error = AddRestrictingSidCurrentUser(); |
| 434 if (ERROR_SUCCESS != error) | 397 if (ERROR_SUCCESS != error) |
| 435 return error; | 398 return error; |
| 436 | 399 |
| 437 TOKEN_GROUPS *token_groups = NULL; | 400 scoped_ptr<BYTE[]> buffer = |
| 438 DWORD size = 0; | 401 GetTokenInfo(effective_token_, TokenGroups, &error); |
| 439 | 402 |
| 440 // Get the buffer size required. | 403 if (!buffer) |
| 441 BOOL result = ::GetTokenInformation(effective_token_, TokenGroups, NULL, 0, | 404 return error; |
| 442 &size); | |
| 443 if (!size) | |
| 444 return ::GetLastError(); | |
| 445 | 405 |
| 446 token_groups = reinterpret_cast<TOKEN_GROUPS*>(new BYTE[size]); | 406 TOKEN_GROUPS* token_groups = reinterpret_cast<TOKEN_GROUPS*>(buffer.get()); |
| 447 result = ::GetTokenInformation(effective_token_, | |
| 448 TokenGroups, | |
| 449 token_groups, | |
| 450 size, | |
| 451 &size); | |
| 452 if (!result) { | |
| 453 delete[] reinterpret_cast<BYTE*>(token_groups); | |
| 454 return ::GetLastError(); | |
| 455 } | |
| 456 | 407 |
| 457 // Build the list of restricting sids from all groups. | 408 // Build the list of restricting sids from all groups. |
| 458 for (unsigned int i = 0; i < token_groups->GroupCount ; ++i) { | 409 for (unsigned int i = 0; i < token_groups->GroupCount ; ++i) { |
| 459 if ((token_groups->Groups[i].Attributes & SE_GROUP_INTEGRITY) == 0) | 410 if ((token_groups->Groups[i].Attributes & SE_GROUP_INTEGRITY) == 0) |
| 460 AddRestrictingSid(reinterpret_cast<SID*>(token_groups->Groups[i].Sid)); | 411 AddRestrictingSid(reinterpret_cast<SID*>(token_groups->Groups[i].Sid)); |
| 461 } | 412 } |
| 462 | 413 |
| 463 delete[] reinterpret_cast<BYTE*>(token_groups); | |
| 464 | |
| 465 return ERROR_SUCCESS; | 414 return ERROR_SUCCESS; |
| 466 } | 415 } |
| 467 | 416 |
| 468 unsigned RestrictedToken::SetIntegrityLevel(IntegrityLevel integrity_level) { | 417 unsigned RestrictedToken::SetIntegrityLevel(IntegrityLevel integrity_level) { |
| 469 integrity_level_ = integrity_level; | 418 integrity_level_ = integrity_level; |
| 470 return ERROR_SUCCESS; | 419 return ERROR_SUCCESS; |
| 471 } | 420 } |
| 472 | 421 |
| 473 } // namespace sandbox | 422 } // namespace sandbox |
| OLD | NEW |