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 31 namespace em = enterprise_management; 32 33 namespace policy { 34 35 namespace { 36 37 // Gets a machine flag from StatisticsProvider, returning the given 38 // |default_value| if not present. 39 bool 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 51 DeviceCloudPolicyInitializer::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 75 DeviceCloudPolicyInitializer::~DeviceCloudPolicyInitializer() { 76 DCHECK(!is_initialized_); 77 } 78 79 void 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 97 void 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 107 void 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 137 bool 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 150 bool 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 161 std::string DeviceCloudPolicyInitializer::GetEnrollmentRecoveryDomain() const { 162 return install_attributes_->GetDomain(); 163 } 164 165 bool 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 176 std::string 177 DeviceCloudPolicyInitializer::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 186 void DeviceCloudPolicyInitializer::OnStoreLoaded(CloudPolicyStore* store) { 187 TryToCreateClient(); 188 } 189 190 void DeviceCloudPolicyInitializer::OnStoreError(CloudPolicyStore* store) { 191 // Do nothing. 192 } 193 194 void 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 212 scoped_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 228 void 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 245 void 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 256 std::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