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