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