device_cloud_policy_initializer.cc revision 116680a4aac90f2aa7413d9095a592090648e557
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.
4
5#include "chrome/browser/chromeos/policy/device_cloud_policy_initializer.h"
6
7#include "base/bind.h"
8#include "base/bind_helpers.h"
9#include "base/logging.h"
10#include "base/prefs/pref_service.h"
11#include "base/sequenced_task_runner.h"
12#include "base/values.h"
13#include "chrome/browser/browser_process.h"
14#include "chrome/browser/chromeos/login/startup_utils.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_handler_chromeos.h"
19#include "chrome/browser/chromeos/policy/enterprise_install_attributes.h"
20#include "chrome/browser/chromeos/policy/server_backed_device_state.h"
21#include "chrome/common/chrome_content_client.h"
22#include "chrome/common/pref_names.h"
23#include "chromeos/system/statistics_provider.h"
24#include "components/policy/core/common/cloud/cloud_policy_constants.h"
25#include "components/policy/core/common/cloud/cloud_policy_core.h"
26#include "components/policy/core/common/cloud/system_policy_request_context.h"
27#include "net/url_request/url_request_context_getter.h"
28#include "policy/proto/device_management_backend.pb.h"
29
30namespace em = enterprise_management;
31
32namespace policy {
33
34namespace {
35
36// Gets a machine flag from StatisticsProvider, returning the given
37// |default_value| if not present.
38bool GetMachineFlag(const std::string& key, bool default_value) {
39  bool value = default_value;
40  chromeos::system::StatisticsProvider* provider =
41      chromeos::system::StatisticsProvider::GetInstance();
42  if (!provider->GetMachineFlag(key, &value))
43    return default_value;
44
45  return value;
46}
47
48}  // namespace
49
50DeviceCloudPolicyInitializer::DeviceCloudPolicyInitializer(
51    PrefService* local_state,
52    DeviceManagementService* enterprise_service,
53    DeviceManagementService* consumer_service,
54    const scoped_refptr<base::SequencedTaskRunner>& background_task_runner,
55    EnterpriseInstallAttributes* install_attributes,
56    ServerBackedStateKeysBroker* state_keys_broker,
57    DeviceCloudPolicyStoreChromeOS* device_store,
58    DeviceCloudPolicyManagerChromeOS* manager,
59    const base::Closure& on_connected_callback)
60    : local_state_(local_state),
61      enterprise_service_(enterprise_service),
62      consumer_service_(consumer_service),
63      background_task_runner_(background_task_runner),
64      install_attributes_(install_attributes),
65      state_keys_broker_(state_keys_broker),
66      device_store_(device_store),
67      manager_(manager),
68      on_connected_callback_(on_connected_callback) {
69  device_store_->AddObserver(this);
70  state_keys_update_subscription_ = state_keys_broker_->RegisterUpdateCallback(
71      base::Bind(&DeviceCloudPolicyInitializer::TryToCreateClient,
72                 base::Unretained(this)));
73
74  device_status_provider_.reset(
75      new DeviceStatusCollector(
76          local_state_,
77          chromeos::system::StatisticsProvider::GetInstance(),
78          NULL));
79
80  TryToCreateClient();
81}
82
83DeviceCloudPolicyInitializer::~DeviceCloudPolicyInitializer() {
84}
85
86void DeviceCloudPolicyInitializer::Shutdown() {
87  device_store_->RemoveObserver(this);
88  device_status_provider_.reset();
89  enrollment_handler_.reset();
90  state_keys_update_subscription_.reset();
91}
92
93void DeviceCloudPolicyInitializer::StartEnrollment(
94    DeviceManagementService* device_management_service,
95    const std::string& auth_token,
96    bool is_auto_enrollment,
97    const AllowedDeviceModes& allowed_device_modes,
98    const EnrollmentCallback& enrollment_callback) {
99  CHECK(!enrollment_handler_);
100
101  manager_->core()->Disconnect();
102  enrollment_handler_.reset(new EnrollmentHandlerChromeOS(
103      device_store_,
104      install_attributes_,
105      state_keys_broker_,
106      CreateClient(device_management_service),
107      background_task_runner_,
108      auth_token,
109      install_attributes_->GetDeviceId(),
110      is_auto_enrollment,
111      manager_->GetDeviceRequisition(),
112      allowed_device_modes,
113      base::Bind(&DeviceCloudPolicyInitializer::EnrollmentCompleted,
114                 base::Unretained(this),
115                 enrollment_callback)));
116  enrollment_handler_->StartEnrollment();
117}
118
119bool DeviceCloudPolicyInitializer::ShouldAutoStartEnrollment() const {
120  std::string restore_mode = GetRestoreMode();
121  if (restore_mode == kDeviceStateRestoreModeReEnrollmentRequested ||
122      restore_mode == kDeviceStateRestoreModeReEnrollmentEnforced) {
123    return true;
124  }
125
126  if (local_state_->HasPrefPath(prefs::kDeviceEnrollmentAutoStart))
127    return local_state_->GetBoolean(prefs::kDeviceEnrollmentAutoStart);
128
129  return GetMachineFlag(chromeos::system::kOemIsEnterpriseManagedKey, false);
130}
131
132bool DeviceCloudPolicyInitializer::ShouldRecoverEnrollment() const {
133  if (install_attributes_->IsEnterpriseDevice() &&
134      chromeos::StartupUtils::IsEnrollmentRecoveryRequired()) {
135    LOG(WARNING) << "Enrollment recovery required according to pref.";
136    if (!DeviceCloudPolicyManagerChromeOS::GetMachineID().empty())
137      return true;
138    LOG(WARNING) << "Postponing recovery because machine id is missing.";
139  }
140  return false;
141}
142
143std::string DeviceCloudPolicyInitializer::GetEnrollmentRecoveryDomain() const {
144  return install_attributes_->GetDomain();
145}
146
147bool DeviceCloudPolicyInitializer::CanExitEnrollment() const {
148  if (GetRestoreMode() == kDeviceStateRestoreModeReEnrollmentEnforced)
149    return false;
150
151  if (local_state_->HasPrefPath(prefs::kDeviceEnrollmentCanExit))
152    return local_state_->GetBoolean(prefs::kDeviceEnrollmentCanExit);
153
154  return GetMachineFlag(chromeos::system::kOemCanExitEnterpriseEnrollmentKey,
155                        true);
156}
157
158std::string
159DeviceCloudPolicyInitializer::GetForcedEnrollmentDomain() const {
160  const base::DictionaryValue* device_state_dict =
161      local_state_->GetDictionary(prefs::kServerBackedDeviceState);
162  std::string management_domain;
163  device_state_dict->GetString(kDeviceStateManagementDomain,
164                               &management_domain);
165  return management_domain;
166}
167
168void DeviceCloudPolicyInitializer::OnStoreLoaded(CloudPolicyStore* store) {
169  TryToCreateClient();
170}
171
172void DeviceCloudPolicyInitializer::OnStoreError(CloudPolicyStore* store) {
173  // Do nothing.
174}
175
176void DeviceCloudPolicyInitializer::EnrollmentCompleted(
177    const EnrollmentCallback& enrollment_callback,
178    EnrollmentStatus status) {
179  scoped_ptr<CloudPolicyClient> client = enrollment_handler_->ReleaseClient();
180  enrollment_handler_.reset();
181
182  if (status.status() == EnrollmentStatus::STATUS_SUCCESS) {
183    StartConnection(client.Pass());
184  } else {
185    // Some attempts to create a client may be blocked because the enrollment
186    // was in progress. We give it a try again.
187    TryToCreateClient();
188  }
189
190  if (!enrollment_callback.is_null())
191    enrollment_callback.Run(status);
192}
193
194scoped_ptr<CloudPolicyClient> DeviceCloudPolicyInitializer::CreateClient(
195    DeviceManagementService* device_management_service) {
196  scoped_refptr<net::URLRequestContextGetter> request_context =
197      new SystemPolicyRequestContext(
198          g_browser_process->system_request_context(), GetUserAgent());
199
200  return make_scoped_ptr(
201      new CloudPolicyClient(DeviceCloudPolicyManagerChromeOS::GetMachineID(),
202                            DeviceCloudPolicyManagerChromeOS::GetMachineModel(),
203                            kPolicyVerificationKeyHash,
204                            USER_AFFILIATION_NONE,
205                            device_status_provider_.get(),
206                            device_management_service,
207                            request_context));
208}
209
210void DeviceCloudPolicyInitializer::TryToCreateClient() {
211  if (device_store_->is_initialized() &&
212      device_store_->has_policy() &&
213      !device_store_->policy()->request_token().empty() &&
214      !state_keys_broker_->pending() &&
215      !enrollment_handler_) {
216    DeviceManagementService* service;
217    if (device_store_->policy()->management_mode() ==
218        em::PolicyData::CONSUMER_MANAGED) {
219      service = consumer_service_;
220    } else {
221      service = enterprise_service_;
222    }
223    StartConnection(CreateClient(service));
224  }
225}
226
227void DeviceCloudPolicyInitializer::StartConnection(
228    scoped_ptr<CloudPolicyClient> client) {
229  if (!manager_->core()->service())
230    manager_->StartConnection(client.Pass(), device_status_provider_.Pass());
231
232  if (!on_connected_callback_.is_null()) {
233    on_connected_callback_.Run();
234    on_connected_callback_.Reset();
235  }
236}
237
238std::string DeviceCloudPolicyInitializer::GetRestoreMode() const {
239  const base::DictionaryValue* device_state_dict =
240      local_state_->GetDictionary(prefs::kServerBackedDeviceState);
241  std::string restore_mode;
242  device_state_dict->GetString(kDeviceStateRestoreMode, &restore_mode);
243  return restore_mode;
244}
245
246}  // namespace policy
247