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