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 |