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