OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "sandbox/src/job.h" | |
6 | |
7 #include "base/win/windows_version.h" | |
8 #include "sandbox/src/restricted_token.h" | |
9 | |
10 namespace sandbox { | |
11 | |
12 Job::~Job() { | |
13 if (job_handle_) | |
14 ::CloseHandle(job_handle_); | |
15 }; | |
16 | |
17 DWORD Job::Init(JobLevel security_level, wchar_t *job_name, | |
18 DWORD ui_exceptions) { | |
19 if (job_handle_) | |
20 return ERROR_ALREADY_INITIALIZED; | |
21 | |
22 job_handle_ = ::CreateJobObject(NULL, // No security attribute | |
23 job_name); | |
24 if (!job_handle_) | |
25 return ::GetLastError(); | |
26 | |
27 JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = {0}; | |
28 JOBOBJECT_BASIC_UI_RESTRICTIONS jbur = {0}; | |
29 | |
30 // Set the settings for the different security levels. Note: The higher levels | |
31 // inherit from the lower levels. | |
32 switch (security_level) { | |
33 case JOB_LOCKDOWN: { | |
34 jeli.BasicLimitInformation.LimitFlags |= | |
35 JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION; | |
36 } | |
37 case JOB_RESTRICTED: { | |
38 jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_WRITECLIPBOARD; | |
39 jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_READCLIPBOARD; | |
40 jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_HANDLES; | |
41 jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_GLOBALATOMS; | |
42 } | |
43 case JOB_LIMITED_USER: { | |
44 jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_DISPLAYSETTINGS; | |
45 jeli.BasicLimitInformation.LimitFlags |= JOB_OBJECT_LIMIT_ACTIVE_PROCESS; | |
46 jeli.BasicLimitInformation.ActiveProcessLimit = 1; | |
47 } | |
48 case JOB_INTERACTIVE: { | |
49 jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS; | |
50 jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_DESKTOP; | |
51 jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_EXITWINDOWS; | |
52 } | |
53 case JOB_UNPROTECTED: { | |
54 // The JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE flag is not supported on | |
55 // Windows 2000. We need a mechanism on Windows 2000 to ensure | |
56 // that processes in the job are terminated when the job is closed | |
57 if (base::win::GetVersion() == base::win::VERSION_PRE_XP) | |
58 break; | |
59 | |
60 jeli.BasicLimitInformation.LimitFlags |= | |
61 JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; | |
62 break; | |
63 } | |
64 default: { | |
65 return ERROR_BAD_ARGUMENTS; | |
66 } | |
67 } | |
68 | |
69 if (FALSE == ::SetInformationJobObject(job_handle_, | |
70 JobObjectExtendedLimitInformation, | |
71 &jeli, | |
72 sizeof(jeli))) { | |
73 return ::GetLastError(); | |
74 } | |
75 | |
76 jbur.UIRestrictionsClass = jbur.UIRestrictionsClass & (~ui_exceptions); | |
77 if (FALSE == ::SetInformationJobObject(job_handle_, | |
78 JobObjectBasicUIRestrictions, | |
79 &jbur, | |
80 sizeof(jbur))) { | |
81 return ::GetLastError(); | |
82 } | |
83 | |
84 return ERROR_SUCCESS; | |
85 } | |
86 | |
87 DWORD Job::UserHandleGrantAccess(HANDLE handle) { | |
88 if (!job_handle_) | |
89 return ERROR_NO_DATA; | |
90 | |
91 if (!::UserHandleGrantAccess(handle, | |
92 job_handle_, | |
93 TRUE)) { // Access allowed. | |
94 return ::GetLastError(); | |
95 } | |
96 | |
97 return ERROR_SUCCESS; | |
98 } | |
99 | |
100 HANDLE Job::Detach() { | |
101 HANDLE handle_temp = job_handle_; | |
102 job_handle_ = NULL; | |
103 return handle_temp; | |
104 } | |
105 | |
106 DWORD Job::AssignProcessToJob(HANDLE process_handle) { | |
107 if (!job_handle_) | |
108 return ERROR_NO_DATA; | |
109 | |
110 if (FALSE == ::AssignProcessToJobObject(job_handle_, process_handle)) | |
111 return ::GetLastError(); | |
112 | |
113 return ERROR_SUCCESS; | |
114 } | |
115 | |
116 } // namespace sandbox | |
OLD | NEW |