1 // Copyright 2014 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.
5 #include "chrome/browser/chromeos/policy/device_cloud_policy_initializer.h"
8 #include "base/bind_helpers.h"
9 #include "base/callback.h"
10 #include "base/logging.h"
11 #include "base/prefs/pref_service.h"
12 #include "base/sequenced_task_runner.h"
13 #include "base/values.h"
14 #include "chrome/browser/browser_process.h"
15 #include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h"
16 #include "chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos.h"
17 #include "chrome/browser/chromeos/policy/device_status_collector.h"
18 #include "chrome/browser/chromeos/policy/enrollment_config.h"
19 #include "chrome/browser/chromeos/policy/enrollment_handler_chromeos.h"
20 #include "chrome/browser/chromeos/policy/enrollment_status_chromeos.h"
21 #include "chrome/browser/chromeos/policy/enterprise_install_attributes.h"
22 #include "chrome/browser/chromeos/policy/server_backed_device_state.h"
23 #include "chrome/common/chrome_content_client.h"
24 #include "chrome/common/pref_names.h"
25 #include "chromeos/system/statistics_provider.h"
26 #include "components/policy/core/common/cloud/cloud_policy_core.h"
27 #include "components/policy/core/common/cloud/device_management_service.h"
28 #include "components/policy/core/common/cloud/system_policy_request_context.h"
29 #include "net/url_request/url_request_context_getter.h"
35 // Gets a machine flag from StatisticsProvider, returning the given
36 // |default_value| if not present.
37 bool GetMachineFlag(const std::string
& key
, bool default_value
) {
38 bool value
= default_value
;
39 chromeos::system::StatisticsProvider
* provider
=
40 chromeos::system::StatisticsProvider::GetInstance();
41 if (!provider
->GetMachineFlag(key
, &value
))
49 DeviceCloudPolicyInitializer::DeviceCloudPolicyInitializer(
50 PrefService
* local_state
,
51 DeviceManagementService
* enterprise_service
,
52 DeviceManagementService
* consumer_service
,
53 const scoped_refptr
<base::SequencedTaskRunner
>& background_task_runner
,
54 EnterpriseInstallAttributes
* install_attributes
,
55 ServerBackedStateKeysBroker
* state_keys_broker
,
56 DeviceCloudPolicyStoreChromeOS
* device_store
,
57 DeviceCloudPolicyManagerChromeOS
* manager
)
58 : local_state_(local_state
),
59 enterprise_service_(enterprise_service
),
60 consumer_service_(consumer_service
),
61 background_task_runner_(background_task_runner
),
62 install_attributes_(install_attributes
),
63 state_keys_broker_(state_keys_broker
),
64 device_store_(device_store
),
66 is_initialized_(false) {
69 DeviceCloudPolicyInitializer::~DeviceCloudPolicyInitializer() {
70 DCHECK(!is_initialized_
);
73 void DeviceCloudPolicyInitializer::Init() {
74 DCHECK(!is_initialized_
);
76 is_initialized_
= true;
77 device_store_
->AddObserver(this);
78 state_keys_update_subscription_
= state_keys_broker_
->RegisterUpdateCallback(
79 base::Bind(&DeviceCloudPolicyInitializer::TryToCreateClient
,
80 base::Unretained(this)));
85 void DeviceCloudPolicyInitializer::Shutdown() {
86 DCHECK(is_initialized_
);
88 device_store_
->RemoveObserver(this);
89 enrollment_handler_
.reset();
90 state_keys_update_subscription_
.reset();
91 is_initialized_
= false;
94 void DeviceCloudPolicyInitializer::StartEnrollment(
95 ManagementMode management_mode
,
96 DeviceManagementService
* device_management_service
,
97 chromeos::OwnerSettingsServiceChromeOS
* owner_settings_service
,
98 const EnrollmentConfig
& enrollment_config
,
99 const std::string
& auth_token
,
100 const AllowedDeviceModes
& allowed_device_modes
,
101 const EnrollmentCallback
& enrollment_callback
) {
102 DCHECK(is_initialized_
);
103 DCHECK(!enrollment_handler_
);
105 manager_
->core()->Disconnect();
106 enrollment_handler_
.reset(new EnrollmentHandlerChromeOS(
107 device_store_
, install_attributes_
, state_keys_broker_
,
108 owner_settings_service
,
109 CreateClient(device_management_service
), background_task_runner_
,
110 enrollment_config
, auth_token
, install_attributes_
->GetDeviceId(),
111 manager_
->GetDeviceRequisition(), allowed_device_modes
, management_mode
,
112 base::Bind(&DeviceCloudPolicyInitializer::EnrollmentCompleted
,
113 base::Unretained(this), enrollment_callback
)));
114 enrollment_handler_
->StartEnrollment();
117 EnrollmentConfig
DeviceCloudPolicyInitializer::GetPrescribedEnrollmentConfig()
119 EnrollmentConfig config
;
121 const bool oobe_complete
= local_state_
->GetBoolean(prefs::kOobeComplete
);
122 if (oobe_complete
&& install_attributes_
->IsEnterpriseDevice()) {
123 // Regardless what mode is applicable, the enrollment domain is fixed.
124 config
.management_domain
= install_attributes_
->GetDomain();
126 // Enrollment has completed previously and installation-time attributes
127 // are in place. Enrollment recovery is required when the server
128 // registration gets lost.
129 if (local_state_
->GetBoolean(prefs::kEnrollmentRecoveryRequired
)) {
130 LOG(WARNING
) << "Enrollment recovery required according to pref.";
131 if (DeviceCloudPolicyManagerChromeOS::GetMachineID().empty())
132 LOG(WARNING
) << "Postponing recovery because machine id is missing.";
134 config
.mode
= EnrollmentConfig::MODE_RECOVERY
;
139 // OOBE is still running, or it is complete but the device hasn't been
140 // enrolled yet. In either case, enrollment should take place if there's a
141 // signal present that indicates the device should enroll.
143 // Gather enrollment signals from various sources.
144 const base::DictionaryValue
* device_state
=
145 local_state_
->GetDictionary(prefs::kServerBackedDeviceState
);
146 std::string device_state_restore_mode
;
147 std::string device_state_management_domain
;
149 device_state
->GetString(kDeviceStateRestoreMode
,
150 &device_state_restore_mode
);
151 device_state
->GetString(kDeviceStateManagementDomain
,
152 &device_state_management_domain
);
155 const bool pref_enrollment_auto_start_present
=
156 local_state_
->HasPrefPath(prefs::kDeviceEnrollmentAutoStart
);
157 const bool pref_enrollment_auto_start
=
158 local_state_
->GetBoolean(prefs::kDeviceEnrollmentAutoStart
);
160 const bool pref_enrollment_can_exit_present
=
161 local_state_
->HasPrefPath(prefs::kDeviceEnrollmentCanExit
);
162 const bool pref_enrollment_can_exit
=
163 local_state_
->GetBoolean(prefs::kDeviceEnrollmentCanExit
);
165 const bool oem_is_managed
=
166 GetMachineFlag(chromeos::system::kOemIsEnterpriseManagedKey
, false);
167 const bool oem_can_exit_enrollment
= GetMachineFlag(
168 chromeos::system::kOemCanExitEnterpriseEnrollmentKey
, true);
170 // Decide enrollment mode. Give precedence to forced variants.
171 if (device_state_restore_mode
==
172 kDeviceStateRestoreModeReEnrollmentEnforced
) {
173 config
.mode
= EnrollmentConfig::MODE_SERVER_FORCED
;
174 config
.management_domain
= device_state_management_domain
;
175 } else if (pref_enrollment_auto_start_present
&&
176 pref_enrollment_auto_start
&&
177 pref_enrollment_can_exit_present
&&
178 !pref_enrollment_can_exit
) {
179 config
.mode
= EnrollmentConfig::MODE_LOCAL_FORCED
;
180 } else if (oem_is_managed
&& !oem_can_exit_enrollment
) {
181 config
.mode
= EnrollmentConfig::MODE_LOCAL_FORCED
;
182 } else if (oobe_complete
) {
183 // If OOBE is complete, don't return advertised modes as there's currently
184 // no way to make sure advertised enrollment only gets shown once.
185 config
.mode
= EnrollmentConfig::MODE_NONE
;
186 } else if (device_state_restore_mode
==
187 kDeviceStateRestoreModeReEnrollmentRequested
) {
188 config
.mode
= EnrollmentConfig::MODE_SERVER_ADVERTISED
;
189 config
.management_domain
= device_state_management_domain
;
190 } else if (pref_enrollment_auto_start_present
&& pref_enrollment_auto_start
) {
191 config
.mode
= EnrollmentConfig::MODE_LOCAL_ADVERTISED
;
192 } else if (oem_is_managed
) {
193 config
.mode
= EnrollmentConfig::MODE_LOCAL_ADVERTISED
;
199 void DeviceCloudPolicyInitializer::OnStoreLoaded(CloudPolicyStore
* store
) {
203 void DeviceCloudPolicyInitializer::OnStoreError(CloudPolicyStore
* store
) {
207 void DeviceCloudPolicyInitializer::EnrollmentCompleted(
208 const EnrollmentCallback
& enrollment_callback
,
209 EnrollmentStatus status
) {
210 scoped_ptr
<CloudPolicyClient
> client
= enrollment_handler_
->ReleaseClient();
211 enrollment_handler_
.reset();
213 if (status
.status() == EnrollmentStatus::STATUS_SUCCESS
) {
214 StartConnection(client
.Pass());
216 // Some attempts to create a client may be blocked because the enrollment
217 // was in progress. We give it a try again.
221 if (!enrollment_callback
.is_null())
222 enrollment_callback
.Run(status
);
225 scoped_ptr
<CloudPolicyClient
> DeviceCloudPolicyInitializer::CreateClient(
226 DeviceManagementService
* device_management_service
) {
227 scoped_refptr
<net::URLRequestContextGetter
> request_context
=
228 new SystemPolicyRequestContext(
229 g_browser_process
->system_request_context(), GetUserAgent());
231 return make_scoped_ptr(
232 new CloudPolicyClient(DeviceCloudPolicyManagerChromeOS::GetMachineID(),
233 DeviceCloudPolicyManagerChromeOS::GetMachineModel(),
234 kPolicyVerificationKeyHash
,
235 device_management_service
,
239 void DeviceCloudPolicyInitializer::TryToCreateClient() {
240 if (!device_store_
->is_initialized() ||
241 !device_store_
->has_policy() ||
242 state_keys_broker_
->pending() ||
243 enrollment_handler_
) {
247 DeviceManagementService
* service
= nullptr;
248 if (GetManagementMode(*device_store_
->policy()) ==
249 MANAGEMENT_MODE_CONSUMER_MANAGED
) {
250 service
= consumer_service_
;
251 } else if (GetManagementMode(*device_store_
->policy()) ==
252 MANAGEMENT_MODE_ENTERPRISE_MANAGED
) {
253 service
= enterprise_service_
;
257 StartConnection(CreateClient(service
));
260 void DeviceCloudPolicyInitializer::StartConnection(
261 scoped_ptr
<CloudPolicyClient
> client
) {
262 if (!manager_
->core()->service())
263 manager_
->StartConnection(client
.Pass(), install_attributes_
);
266 } // namespace policy