1// Copyright 2014 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_initializer.h" 6 7#include "base/bind.h" 8#include "base/bind_helpers.h" 9#include "base/logging.h" 10#include "base/prefs/pref_service.h" 11#include "base/sequenced_task_runner.h" 12#include "base/values.h" 13#include "chrome/browser/browser_process.h" 14#include "chrome/browser/chromeos/login/startup_utils.h" 15#include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h" 16#include "chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos.h" 17#include "chrome/browser/chromeos/policy/device_status_collector.h" 18#include "chrome/browser/chromeos/policy/enrollment_handler_chromeos.h" 19#include "chrome/browser/chromeos/policy/enterprise_install_attributes.h" 20#include "chrome/browser/chromeos/policy/server_backed_device_state.h" 21#include "chrome/browser/chromeos/settings/device_settings_service.h" 22#include "chrome/common/chrome_content_client.h" 23#include "chrome/common/pref_names.h" 24#include "chromeos/system/statistics_provider.h" 25#include "components/policy/core/common/cloud/cloud_policy_constants.h" 26#include "components/policy/core/common/cloud/cloud_policy_core.h" 27#include "components/policy/core/common/cloud/device_management_service.h" 28#include "components/policy/core/common/cloud/system_policy_request_context.h" 29#include "net/url_request/url_request_context_getter.h" 30 31namespace em = enterprise_management; 32 33namespace policy { 34 35namespace { 36 37// Gets a machine flag from StatisticsProvider, returning the given 38// |default_value| if not present. 39bool GetMachineFlag(const std::string& key, bool default_value) { 40 bool value = default_value; 41 chromeos::system::StatisticsProvider* provider = 42 chromeos::system::StatisticsProvider::GetInstance(); 43 if (!provider->GetMachineFlag(key, &value)) 44 return default_value; 45 46 return value; 47} 48 49} // namespace 50 51DeviceCloudPolicyInitializer::DeviceCloudPolicyInitializer( 52 PrefService* local_state, 53 DeviceManagementService* enterprise_service, 54 DeviceManagementService* consumer_service, 55 const scoped_refptr<base::SequencedTaskRunner>& background_task_runner, 56 EnterpriseInstallAttributes* install_attributes, 57 ServerBackedStateKeysBroker* state_keys_broker, 58 DeviceCloudPolicyStoreChromeOS* device_store, 59 DeviceCloudPolicyManagerChromeOS* manager, 60 chromeos::DeviceSettingsService* device_settings_service, 61 const base::Closure& on_connected_callback) 62 : local_state_(local_state), 63 enterprise_service_(enterprise_service), 64 consumer_service_(consumer_service), 65 background_task_runner_(background_task_runner), 66 install_attributes_(install_attributes), 67 state_keys_broker_(state_keys_broker), 68 device_store_(device_store), 69 manager_(manager), 70 device_settings_service_(device_settings_service), 71 on_connected_callback_(on_connected_callback), 72 is_initialized_(false) { 73} 74 75DeviceCloudPolicyInitializer::~DeviceCloudPolicyInitializer() { 76 DCHECK(!is_initialized_); 77} 78 79void DeviceCloudPolicyInitializer::Init() { 80 DCHECK(!is_initialized_); 81 82 is_initialized_ = true; 83 device_store_->AddObserver(this); 84 state_keys_update_subscription_ = state_keys_broker_->RegisterUpdateCallback( 85 base::Bind(&DeviceCloudPolicyInitializer::TryToCreateClient, 86 base::Unretained(this))); 87 88 device_status_provider_.reset( 89 new DeviceStatusCollector( 90 local_state_, 91 chromeos::system::StatisticsProvider::GetInstance(), 92 NULL)); 93 94 TryToCreateClient(); 95} 96 97void DeviceCloudPolicyInitializer::Shutdown() { 98 DCHECK(is_initialized_); 99 100 device_store_->RemoveObserver(this); 101 device_status_provider_.reset(); 102 enrollment_handler_.reset(); 103 state_keys_update_subscription_.reset(); 104 is_initialized_ = false; 105} 106 107void DeviceCloudPolicyInitializer::StartEnrollment( 108 em::PolicyData::ManagementMode management_mode, 109 DeviceManagementService* device_management_service, 110 const std::string& auth_token, 111 bool is_auto_enrollment, 112 const AllowedDeviceModes& allowed_device_modes, 113 const EnrollmentCallback& enrollment_callback) { 114 DCHECK(is_initialized_); 115 DCHECK(!enrollment_handler_); 116 117 manager_->core()->Disconnect(); 118 enrollment_handler_.reset(new EnrollmentHandlerChromeOS( 119 device_store_, 120 install_attributes_, 121 state_keys_broker_, 122 device_settings_service_, 123 CreateClient(device_management_service), 124 background_task_runner_, 125 auth_token, 126 install_attributes_->GetDeviceId(), 127 is_auto_enrollment, 128 manager_->GetDeviceRequisition(), 129 allowed_device_modes, 130 management_mode, 131 base::Bind(&DeviceCloudPolicyInitializer::EnrollmentCompleted, 132 base::Unretained(this), 133 enrollment_callback))); 134 enrollment_handler_->StartEnrollment(); 135} 136 137bool DeviceCloudPolicyInitializer::ShouldAutoStartEnrollment() const { 138 std::string restore_mode = GetRestoreMode(); 139 if (restore_mode == kDeviceStateRestoreModeReEnrollmentRequested || 140 restore_mode == kDeviceStateRestoreModeReEnrollmentEnforced) { 141 return true; 142 } 143 144 if (local_state_->HasPrefPath(prefs::kDeviceEnrollmentAutoStart)) 145 return local_state_->GetBoolean(prefs::kDeviceEnrollmentAutoStart); 146 147 return GetMachineFlag(chromeos::system::kOemIsEnterpriseManagedKey, false); 148} 149 150bool DeviceCloudPolicyInitializer::ShouldRecoverEnrollment() const { 151 if (install_attributes_->IsEnterpriseDevice() && 152 chromeos::StartupUtils::IsEnrollmentRecoveryRequired()) { 153 LOG(WARNING) << "Enrollment recovery required according to pref."; 154 if (!DeviceCloudPolicyManagerChromeOS::GetMachineID().empty()) 155 return true; 156 LOG(WARNING) << "Postponing recovery because machine id is missing."; 157 } 158 return false; 159} 160 161std::string DeviceCloudPolicyInitializer::GetEnrollmentRecoveryDomain() const { 162 return install_attributes_->GetDomain(); 163} 164 165bool DeviceCloudPolicyInitializer::CanExitEnrollment() const { 166 if (GetRestoreMode() == kDeviceStateRestoreModeReEnrollmentEnforced) 167 return false; 168 169 if (local_state_->HasPrefPath(prefs::kDeviceEnrollmentCanExit)) 170 return local_state_->GetBoolean(prefs::kDeviceEnrollmentCanExit); 171 172 return GetMachineFlag(chromeos::system::kOemCanExitEnterpriseEnrollmentKey, 173 true); 174} 175 176std::string 177DeviceCloudPolicyInitializer::GetForcedEnrollmentDomain() const { 178 const base::DictionaryValue* device_state_dict = 179 local_state_->GetDictionary(prefs::kServerBackedDeviceState); 180 std::string management_domain; 181 device_state_dict->GetString(kDeviceStateManagementDomain, 182 &management_domain); 183 return management_domain; 184} 185 186void DeviceCloudPolicyInitializer::OnStoreLoaded(CloudPolicyStore* store) { 187 TryToCreateClient(); 188} 189 190void DeviceCloudPolicyInitializer::OnStoreError(CloudPolicyStore* store) { 191 // Do nothing. 192} 193 194void DeviceCloudPolicyInitializer::EnrollmentCompleted( 195 const EnrollmentCallback& enrollment_callback, 196 EnrollmentStatus status) { 197 scoped_ptr<CloudPolicyClient> client = enrollment_handler_->ReleaseClient(); 198 enrollment_handler_.reset(); 199 200 if (status.status() == EnrollmentStatus::STATUS_SUCCESS) { 201 StartConnection(client.Pass()); 202 } else { 203 // Some attempts to create a client may be blocked because the enrollment 204 // was in progress. We give it a try again. 205 TryToCreateClient(); 206 } 207 208 if (!enrollment_callback.is_null()) 209 enrollment_callback.Run(status); 210} 211 212scoped_ptr<CloudPolicyClient> DeviceCloudPolicyInitializer::CreateClient( 213 DeviceManagementService* device_management_service) { 214 scoped_refptr<net::URLRequestContextGetter> request_context = 215 new SystemPolicyRequestContext( 216 g_browser_process->system_request_context(), GetUserAgent()); 217 218 return make_scoped_ptr( 219 new CloudPolicyClient(DeviceCloudPolicyManagerChromeOS::GetMachineID(), 220 DeviceCloudPolicyManagerChromeOS::GetMachineModel(), 221 kPolicyVerificationKeyHash, 222 USER_AFFILIATION_NONE, 223 device_status_provider_.get(), 224 device_management_service, 225 request_context)); 226} 227 228void DeviceCloudPolicyInitializer::TryToCreateClient() { 229 if (device_store_->is_initialized() && 230 device_store_->has_policy() && 231 !device_store_->policy()->request_token().empty() && 232 !state_keys_broker_->pending() && 233 !enrollment_handler_) { 234 DeviceManagementService* service; 235 if (device_store_->policy()->management_mode() == 236 em::PolicyData::CONSUMER_MANAGED) { 237 service = consumer_service_; 238 } else { 239 service = enterprise_service_; 240 } 241 StartConnection(CreateClient(service)); 242 } 243} 244 245void DeviceCloudPolicyInitializer::StartConnection( 246 scoped_ptr<CloudPolicyClient> client) { 247 if (!manager_->core()->service()) 248 manager_->StartConnection(client.Pass(), device_status_provider_.Pass()); 249 250 if (!on_connected_callback_.is_null()) { 251 on_connected_callback_.Run(); 252 on_connected_callback_.Reset(); 253 } 254} 255 256std::string DeviceCloudPolicyInitializer::GetRestoreMode() const { 257 const base::DictionaryValue* device_state_dict = 258 local_state_->GetDictionary(prefs::kServerBackedDeviceState); 259 std::string restore_mode; 260 device_state_dict->GetString(kDeviceStateRestoreMode, &restore_mode); 261 return restore_mode; 262} 263 264} // namespace policy 265