device_cloud_policy_manager_chromeos.cc revision 868fa2fe829687343ffae624259930155e16dbd8
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    LOG(WARNING) << "Failed to get machine statistic " << key;
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    LOG(WARNING) << "Failed to get machine flag " << key;
75    return default_value;
76  }
77
78  return value;
79}
80
81}  // namespace
82
83DeviceCloudPolicyManagerChromeOS::DeviceCloudPolicyManagerChromeOS(
84    scoped_ptr<DeviceCloudPolicyStoreChromeOS> store,
85    EnterpriseInstallAttributes* install_attributes)
86    : CloudPolicyManager(
87          PolicyNamespaceKey(dm_protocol::kChromeDevicePolicyType,
88                             std::string()),
89          store.get()),
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 = GetMachineStatistic(chromeos::kOemDeviceRequisitionKey);
143  else
144    pref->GetValue()->GetAsString(&requisition);
145
146  return requisition;
147}
148
149void DeviceCloudPolicyManagerChromeOS::SetDeviceRequisition(
150    const std::string& requisition) {
151  if (local_state_) {
152    if (requisition.empty()) {
153      local_state_->ClearPref(prefs::kDeviceEnrollmentRequisition);
154      local_state_->ClearPref(prefs::kDeviceEnrollmentAutoStart);
155      local_state_->ClearPref(prefs::kDeviceEnrollmentCanExit);
156    } else {
157      local_state_->SetString(prefs::kDeviceEnrollmentRequisition, requisition);
158      local_state_->SetBoolean(prefs::kDeviceEnrollmentAutoStart, true);
159      local_state_->SetBoolean(prefs::kDeviceEnrollmentCanExit, false);
160    }
161  }
162}
163
164bool DeviceCloudPolicyManagerChromeOS::ShouldAutoStartEnrollment() const {
165  if (local_state_->HasPrefPath(prefs::kDeviceEnrollmentAutoStart))
166    return local_state_->GetBoolean(prefs::kDeviceEnrollmentAutoStart);
167
168  return GetMachineFlag(chromeos::kOemIsEnterpriseManagedKey, false);
169}
170
171bool DeviceCloudPolicyManagerChromeOS::CanExitEnrollment() const {
172  if (local_state_->HasPrefPath(prefs::kDeviceEnrollmentCanExit))
173    return local_state_->GetBoolean(prefs::kDeviceEnrollmentCanExit);
174
175  return GetMachineFlag(chromeos::kOemCanExitEnterpriseEnrollmentKey, true);
176}
177
178void DeviceCloudPolicyManagerChromeOS::Shutdown() {
179  CloudPolicyManager::Shutdown();
180  device_status_provider_.reset();
181}
182
183void DeviceCloudPolicyManagerChromeOS::OnStoreLoaded(CloudPolicyStore* store) {
184  CloudPolicyManager::OnStoreLoaded(store);
185
186  if (!enrollment_handler_.get())
187    StartIfManaged();
188}
189
190// static
191void DeviceCloudPolicyManagerChromeOS::RegisterPrefs(
192    PrefRegistrySimple* registry) {
193  registry->RegisterStringPref(prefs::kDeviceEnrollmentRequisition,
194                               std::string());
195  registry->RegisterBooleanPref(prefs::kDeviceEnrollmentAutoStart, false);
196  registry->RegisterBooleanPref(prefs::kDeviceEnrollmentCanExit, true);
197}
198
199// static
200std::string DeviceCloudPolicyManagerChromeOS::GetMachineID() {
201  std::string machine_id;
202  chromeos::system::StatisticsProvider* provider =
203      chromeos::system::StatisticsProvider::GetInstance();
204  for (size_t i = 0; i < arraysize(kMachineInfoSerialNumberKeys); i++) {
205    if (provider->GetMachineStatistic(kMachineInfoSerialNumberKeys[i],
206                                      &machine_id) &&
207        !machine_id.empty()) {
208      break;
209    }
210  }
211
212  if (machine_id.empty())
213    LOG(WARNING) << "Failed to get machine id.";
214
215  return machine_id;
216}
217
218// static
219std::string DeviceCloudPolicyManagerChromeOS::GetMachineModel() {
220  return GetMachineStatistic(kMachineInfoSystemHwqual);
221}
222
223scoped_ptr<CloudPolicyClient> DeviceCloudPolicyManagerChromeOS::CreateClient() {
224  return make_scoped_ptr(
225      new CloudPolicyClient(GetMachineID(), GetMachineModel(),
226                            USER_AFFILIATION_NONE,
227                            device_status_provider_.get(),
228                            device_management_service_));
229}
230
231void DeviceCloudPolicyManagerChromeOS::EnrollmentCompleted(
232    const EnrollmentCallback& callback,
233    EnrollmentStatus status) {
234  if (status.status() == EnrollmentStatus::STATUS_SUCCESS) {
235    core()->Connect(enrollment_handler_->ReleaseClient());
236    core()->StartRefreshScheduler();
237    core()->TrackRefreshDelayPref(local_state_,
238                                  prefs::kDevicePolicyRefreshRate);
239    attestation_policy_observer_.reset(
240        new chromeos::attestation::AttestationPolicyObserver(client()));
241  } else {
242    StartIfManaged();
243  }
244
245  enrollment_handler_.reset();
246  if (!callback.is_null())
247    callback.Run(status);
248}
249
250void DeviceCloudPolicyManagerChromeOS::StartIfManaged() {
251  if (device_management_service_ &&
252      local_state_ &&
253      store()->is_initialized() &&
254      store()->is_managed() &&
255      !service()) {
256    core()->Connect(CreateClient());
257    core()->StartRefreshScheduler();
258    core()->TrackRefreshDelayPref(local_state_,
259                                  prefs::kDevicePolicyRefreshRate);
260    attestation_policy_observer_.reset(
261        new chromeos::attestation::AttestationPolicyObserver(client()));
262  }
263}
264
265}  // namespace policy
266