device_cloud_policy_manager_chromeos.cc revision d0247b1b59f9c528cb6df88b4f2b9afaf80d181e
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
3// found in the LICENSE file.
4
5#include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h"
6
7#include "base/bind.h"
8#include "base/bind_helpers.h"
9#include "base/prefs/pref_registry_simple.h"
10#include "base/prefs/pref_service.h"
11#include "chrome/browser/chromeos/attestation/attestation_policy_observer.h"
12#include "chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos.h"
13#include "chrome/browser/chromeos/policy/enrollment_handler_chromeos.h"
14#include "chrome/browser/chromeos/policy/enterprise_install_attributes.h"
15#include "chrome/browser/chromeos/system/statistics_provider.h"
16#include "chrome/browser/policy/cloud/cloud_policy_constants.h"
17#include "chrome/browser/policy/cloud/cloud_policy_store.h"
18#include "chrome/browser/policy/cloud/device_management_service.h"
19#include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h"
20#include "chrome/common/pref_names.h"
21#include "chromeos/chromeos_constants.h"
22
23namespace em = enterprise_management;
24
25namespace policy {
26
27namespace {
28
29// MachineInfo key names.
30const char kMachineInfoSystemHwqual[] = "hardware_class";
31
32// These are the machine serial number keys that we check in order until we
33// find a non-empty serial number. The VPD spec says the serial number should be
34// in the "serial_number" key for v2+ VPDs. However, legacy devices used a
35// different keys to report their serial number, which we fall back to if
36// "serial_number" is not present.
37//
38// Product_S/N is still special-cased due to inconsistencies with serial
39// numbers on Lumpy devices: On these devices, serial_number is identical to
40// Product_S/N with an appended checksum. Unfortunately, the sticker on the
41// packaging doesn't include that checksum either (the sticker on the device
42// does though!). The former sticker is the source of the serial number used by
43// device management service, so we prefer Product_S/N over serial number to
44// match the server.
45//
46// TODO(mnissler): Move serial_number back to the top once the server side uses
47// the correct serial number.
48const char* kMachineInfoSerialNumberKeys[] = {
49  "Product_S/N",    // Lumpy/Alex devices
50  "serial_number",  // VPD v2+ devices
51  "Product_SN",     // Mario
52  "sn",             // old ZGB devices (more recent ones use serial_number)
53};
54
55// Fetches a machine statistic value from StatisticsProvider, returns an empty
56// string on failure.
57std::string GetMachineStatistic(const std::string& key) {
58  std::string value;
59  chromeos::system::StatisticsProvider* provider =
60      chromeos::system::StatisticsProvider::GetInstance();
61  if (!provider->GetMachineStatistic(key, &value))
62    return std::string();
63
64  return value;
65}
66
67// Gets a machine flag from StatisticsProvider, returns the given
68// |default_value| if not present.
69bool GetMachineFlag(const std::string& key, bool default_value) {
70  bool value = default_value;
71  chromeos::system::StatisticsProvider* provider =
72      chromeos::system::StatisticsProvider::GetInstance();
73  if (!provider->GetMachineFlag(key, &value))
74    return default_value;
75
76  return value;
77}
78
79}  // namespace
80
81DeviceCloudPolicyManagerChromeOS::DeviceCloudPolicyManagerChromeOS(
82    scoped_ptr<DeviceCloudPolicyStoreChromeOS> store,
83    const scoped_refptr<base::SequencedTaskRunner>& task_runner,
84    EnterpriseInstallAttributes* install_attributes)
85    : CloudPolicyManager(
86          PolicyNamespaceKey(dm_protocol::kChromeDevicePolicyType,
87                             std::string()),
88          store.get(),
89          task_runner),
90      device_store_(store.Pass()),
91      install_attributes_(install_attributes),
92      device_management_service_(NULL),
93      local_state_(NULL) {}
94
95DeviceCloudPolicyManagerChromeOS::~DeviceCloudPolicyManagerChromeOS() {}
96
97void DeviceCloudPolicyManagerChromeOS::Connect(
98    PrefService* local_state,
99    DeviceManagementService* device_management_service,
100    scoped_ptr<CloudPolicyClient::StatusProvider> device_status_provider) {
101  CHECK(!device_management_service_);
102  CHECK(device_management_service);
103  CHECK(local_state);
104
105  local_state_ = local_state;
106  device_management_service_ = device_management_service;
107  device_status_provider_ = device_status_provider.Pass();
108
109  StartIfManaged();
110}
111
112void DeviceCloudPolicyManagerChromeOS::StartEnrollment(
113    const std::string& auth_token,
114    bool is_auto_enrollment,
115    const AllowedDeviceModes& allowed_device_modes,
116    const EnrollmentCallback& callback) {
117  CHECK(device_management_service_);
118  core()->Disconnect();
119
120  enrollment_handler_.reset(
121      new EnrollmentHandlerChromeOS(
122          device_store_.get(), install_attributes_, CreateClient(), auth_token,
123          install_attributes_->GetDeviceId(), is_auto_enrollment,
124          GetDeviceRequisition(), allowed_device_modes,
125          base::Bind(&DeviceCloudPolicyManagerChromeOS::EnrollmentCompleted,
126                     base::Unretained(this), callback)));
127  enrollment_handler_->StartEnrollment();
128}
129
130void DeviceCloudPolicyManagerChromeOS::CancelEnrollment() {
131  if (enrollment_handler_.get()) {
132    enrollment_handler_.reset();
133    StartIfManaged();
134  }
135}
136
137std::string DeviceCloudPolicyManagerChromeOS::GetDeviceRequisition() const {
138  std::string requisition;
139  const PrefService::Preference* pref = local_state_->FindPreference(
140      prefs::kDeviceEnrollmentRequisition);
141  if (pref->IsDefaultValue()) {
142    requisition =
143        GetMachineStatistic(chromeos::system::kOemDeviceRequisitionKey);
144  } else {
145    pref->GetValue()->GetAsString(&requisition);
146  }
147
148  return requisition;
149}
150
151void DeviceCloudPolicyManagerChromeOS::SetDeviceRequisition(
152    const std::string& requisition) {
153  if (local_state_) {
154    if (requisition.empty()) {
155      local_state_->ClearPref(prefs::kDeviceEnrollmentRequisition);
156      local_state_->ClearPref(prefs::kDeviceEnrollmentAutoStart);
157      local_state_->ClearPref(prefs::kDeviceEnrollmentCanExit);
158    } else {
159      local_state_->SetString(prefs::kDeviceEnrollmentRequisition, requisition);
160      local_state_->SetBoolean(prefs::kDeviceEnrollmentAutoStart, true);
161      local_state_->SetBoolean(prefs::kDeviceEnrollmentCanExit, false);
162    }
163  }
164}
165
166bool DeviceCloudPolicyManagerChromeOS::ShouldAutoStartEnrollment() const {
167  if (local_state_->HasPrefPath(prefs::kDeviceEnrollmentAutoStart))
168    return local_state_->GetBoolean(prefs::kDeviceEnrollmentAutoStart);
169
170  return GetMachineFlag(chromeos::system::kOemIsEnterpriseManagedKey, false);
171}
172
173bool DeviceCloudPolicyManagerChromeOS::CanExitEnrollment() const {
174  if (local_state_->HasPrefPath(prefs::kDeviceEnrollmentCanExit))
175    return local_state_->GetBoolean(prefs::kDeviceEnrollmentCanExit);
176
177  return GetMachineFlag(chromeos::system::kOemCanExitEnterpriseEnrollmentKey,
178                        true);
179}
180
181void DeviceCloudPolicyManagerChromeOS::Shutdown() {
182  CloudPolicyManager::Shutdown();
183  device_status_provider_.reset();
184}
185
186void DeviceCloudPolicyManagerChromeOS::OnStoreLoaded(CloudPolicyStore* store) {
187  CloudPolicyManager::OnStoreLoaded(store);
188
189  if (!enrollment_handler_.get())
190    StartIfManaged();
191}
192
193// static
194void DeviceCloudPolicyManagerChromeOS::RegisterPrefs(
195    PrefRegistrySimple* registry) {
196  registry->RegisterStringPref(prefs::kDeviceEnrollmentRequisition,
197                               std::string());
198  registry->RegisterBooleanPref(prefs::kDeviceEnrollmentAutoStart, false);
199  registry->RegisterBooleanPref(prefs::kDeviceEnrollmentCanExit, true);
200}
201
202// static
203std::string DeviceCloudPolicyManagerChromeOS::GetMachineID() {
204  std::string machine_id;
205  chromeos::system::StatisticsProvider* provider =
206      chromeos::system::StatisticsProvider::GetInstance();
207  for (size_t i = 0; i < arraysize(kMachineInfoSerialNumberKeys); i++) {
208    if (provider->GetMachineStatistic(kMachineInfoSerialNumberKeys[i],
209                                      &machine_id) &&
210        !machine_id.empty()) {
211      break;
212    }
213  }
214
215  if (machine_id.empty())
216    LOG(WARNING) << "Failed to get machine id.";
217
218  return machine_id;
219}
220
221// static
222std::string DeviceCloudPolicyManagerChromeOS::GetMachineModel() {
223  return GetMachineStatistic(kMachineInfoSystemHwqual);
224}
225
226std::string DeviceCloudPolicyManagerChromeOS::GetRobotAccountId() {
227  const enterprise_management::PolicyData* policy = device_store_->policy();
228  return policy ? policy->service_account_identity() : std::string();
229}
230
231scoped_ptr<CloudPolicyClient> DeviceCloudPolicyManagerChromeOS::CreateClient() {
232  return make_scoped_ptr(
233      new CloudPolicyClient(GetMachineID(), GetMachineModel(),
234                            USER_AFFILIATION_NONE,
235                            device_status_provider_.get(),
236                            device_management_service_));
237}
238
239void DeviceCloudPolicyManagerChromeOS::EnrollmentCompleted(
240    const EnrollmentCallback& callback,
241    EnrollmentStatus status) {
242  if (status.status() == EnrollmentStatus::STATUS_SUCCESS) {
243    core()->Connect(enrollment_handler_->ReleaseClient());
244    core()->StartRefreshScheduler();
245    core()->TrackRefreshDelayPref(local_state_,
246                                  prefs::kDevicePolicyRefreshRate);
247    attestation_policy_observer_.reset(
248        new chromeos::attestation::AttestationPolicyObserver(client()));
249  } else {
250    StartIfManaged();
251  }
252
253  enrollment_handler_.reset();
254  if (!callback.is_null())
255    callback.Run(status);
256}
257
258void DeviceCloudPolicyManagerChromeOS::StartIfManaged() {
259  if (device_management_service_ &&
260      local_state_ &&
261      store()->is_initialized() &&
262      store()->is_managed() &&
263      !service()) {
264    core()->Connect(CreateClient());
265    core()->StartRefreshScheduler();
266    core()->TrackRefreshDelayPref(local_state_,
267                                  prefs::kDevicePolicyRefreshRate);
268    attestation_policy_observer_.reset(
269        new chromeos::attestation::AttestationPolicyObserver(client()));
270  }
271}
272
273}  // namespace policy
274