Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: sandbox/win/src/restricted_token.cc

Issue 1246103003: Sandbox: store RestrictedToken::effective_token_ on a ScopedHandle. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « sandbox/win/src/restricted_token.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « sandbox/win/src/restricted_token.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698