device_cloud_policy_manager_chromeos.cc revision 58537e28ecd584eab876aee8be7156509866d23a
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    EnterpriseInstallAttributes* install_attributes)
84    : CloudPolicyManager(
85          PolicyNamespaceKey(dm_protocol::kChromeDevicePolicyType,
86                             std::string()),
87          store.get()),
88      device_store_(store.Pass()),
89      install_attributes_(install_attributes),
90      device_management_service_(NULL),
91      local_state_(NULL) {}
92
93DeviceCloudPolicyManagerChromeOS::~DeviceCloudPolicyManagerChromeOS() {}
94
95void DeviceCloudPolicyManagerChromeOS::Connect(
96    PrefService* local_state,
97    DeviceManagementService* device_management_service,
98    scoped_ptr<CloudPolicyClient::StatusProvider> device_status_provider) {
99  CHECK(!device_management_service_);
100  CHECK(device_management_service);
101  CHECK(local_state);
102
103  local_state_ = local_state;
104  device_management_service_ = device_management_service;
105  device_status_provider_ = device_status_provider.Pass();
106
107  StartIfManaged();
108}
109
110void DeviceCloudPolicyManagerChromeOS::StartEnrollment(
111    const std::string& auth_token,
112    bool is_auto_enrollment,
113    const AllowedDeviceModes& allowed_device_modes,
114    const EnrollmentCallback& callback) {
115  CHECK(device_management_service_);
116  core()->Disconnect();
117
118  enrollment_handler_.reset(
119      new EnrollmentHandlerChromeOS(
120          device_store_.get(), install_attributes_, CreateClient(), auth_token,
121          install_attributes_->GetDeviceId(), is_auto_enrollment,
122          GetDeviceRequisition(), allowed_device_modes,
123          base::Bind(&DeviceCloudPolicyManagerChromeOS::EnrollmentCompleted,
124                     base::Unretained(this), callback)));
125  enrollment_handler_->StartEnrollment();
126}
127
128void DeviceCloudPolicyManagerChromeOS::CancelEnrollment() {
129  if (enrollment_handler_.get()) {
130    enrollment_handler_.reset();
131    StartIfManaged();
132  }
133}
134
135std::string DeviceCloudPolicyManagerChromeOS::GetDeviceRequisition() const {
136  std::string requisition;
137  const PrefService::Preference* pref = local_state_->FindPreference(
138      prefs::kDeviceEnrollmentRequisition);
139  if (pref->IsDefaultValue()) {
140    requisition =
141        GetMachineStatistic(chromeos::system::kOemDeviceRequisitionKey);
142  } else {
143    pref->GetValue()->GetAsString(&requisition);
144  }
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::system::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::system::kOemCanExitEnterpriseEnrollmentKey,
176                        true);
177}
178
179void DeviceCloudPolicyManagerChromeOS::Shutdown() {
180  CloudPolicyManager::Shutdown();
181  device_status_provider_.reset();
182}
183
184void DeviceCloudPolicyManagerChromeOS::OnStoreLoaded(CloudPolicyStore* store) {
185  CloudPolicyManager::OnStoreLoaded(store);
186
187  if (!enrollment_handler_.get())
188    StartIfManaged();
189}
190
191// static
192void DeviceCloudPolicyManagerChromeOS::RegisterPrefs(
193    PrefRegistrySimple* registry) {
194  registry->RegisterStringPref(prefs::kDeviceEnrollmentRequisition,
195                               std::string());
196  registry->RegisterBooleanPref(prefs::kDeviceEnrollmentAutoStart, false);
197  registry->RegisterBooleanPref(prefs::kDeviceEnrollmentCanExit, true);
198}
199
200// static
201std::string DeviceCloudPolicyManagerChromeOS::GetMachineID() {
202  std::string machine_id;
203  chromeos::system::StatisticsProvider* provider =
204      chromeos::system::StatisticsProvider::GetInstance();
205  for (size_t i = 0; i < arraysize(kMachineInfoSerialNumberKeys); i++) {
206    if (provider->GetMachineStatistic(kMachineInfoSerialNumberKeys[i],
207                                      &machine_id) &&
208        !machine_id.empty()) {
209      break;
210    }
211  }
212
213  if (machine_id.empty())
214    LOG(WARNING) << "Failed to get machine id.";
215
216  return machine_id;
217}
218
219// static
220std::string DeviceCloudPolicyManagerChromeOS::GetMachineModel() {
221  return GetMachineStatistic(kMachineInfoSystemHwqual);
222}
223
224std::string DeviceCloudPolicyManagerChromeOS::GetRobotAccountId() {
225  const enterprise_management::PolicyData* policy = device_store_->policy();
226  return policy ? policy->service_account_identity() : std::string();
227}
228
229scoped_ptr<CloudPolicyClient> DeviceCloudPolicyManagerChromeOS::CreateClient() {
230  return make_scoped_ptr(
231      new CloudPolicyClient(GetMachineID(), GetMachineModel(),
232                            USER_AFFILIATION_NONE,
233                            device_status_provider_.get(),
234                            device_management_service_));
235}
236
237void DeviceCloudPolicyManagerChromeOS::EnrollmentCompleted(
238    const EnrollmentCallback& callback,
239    EnrollmentStatus status) {
240  if (status.status() == EnrollmentStatus::STATUS_SUCCESS) {
241    core()->Connect(enrollment_handler_->ReleaseClient());
242    core()->StartRefreshScheduler();
243    core()->TrackRefreshDelayPref(local_state_,
244                                  prefs::kDevicePolicyRefreshRate);
245    attestation_policy_observer_.reset(
246        new chromeos::attestation::AttestationPolicyObserver(client()));
247  } else {
248    StartIfManaged();
249  }
250
251  enrollment_handler_.reset();
252  if (!callback.is_null())
253    callback.Run(status);
254}
255
256void DeviceCloudPolicyManagerChromeOS::StartIfManaged() {
257  if (device_management_service_ &&
258      local_state_ &&
259      store()->is_initialized() &&
260      store()->is_managed() &&
261      !service()) {
262    core()->Connect(CreateClient());
263    core()->StartRefreshScheduler();
264    core()->TrackRefreshDelayPref(local_state_,
265                                  prefs::kDevicePolicyRefreshRate);
266    attestation_policy_observer_.reset(
267        new chromeos::attestation::AttestationPolicyObserver(client()));
268  }
269}
270
271}  // namespace policy
272