Switch global error menu icon to vectorized MD asset
[chromium-blink-merge.git] / chrome / browser / chromeos / policy / device_cloud_policy_store_chromeos.cc
blob71841dab247475ff14ce8dac4868cbb01c1cad7e
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.
5 #include "chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos.h"
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "base/metrics/histogram.h"
10 #include "base/sequenced_task_runner.h"
11 #include "chrome/browser/chromeos/login/startup_utils.h"
12 #include "chrome/browser/chromeos/policy/device_policy_decoder_chromeos.h"
13 #include "chrome/browser/chromeos/policy/enterprise_install_attributes.h"
14 #include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h"
15 #include "components/ownership/owner_key_util.h"
16 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
17 #include "policy/proto/device_management_backend.pb.h"
19 namespace em = enterprise_management;
21 namespace policy {
23 DeviceCloudPolicyStoreChromeOS::DeviceCloudPolicyStoreChromeOS(
24 chromeos::DeviceSettingsService* device_settings_service,
25 EnterpriseInstallAttributes* install_attributes,
26 scoped_refptr<base::SequencedTaskRunner> background_task_runner)
27 : device_settings_service_(device_settings_service),
28 install_attributes_(install_attributes),
29 background_task_runner_(background_task_runner),
30 enrollment_validation_done_(false),
31 weak_factory_(this) {
32 device_settings_service_->AddObserver(this);
35 DeviceCloudPolicyStoreChromeOS::~DeviceCloudPolicyStoreChromeOS() {
36 device_settings_service_->RemoveObserver(this);
39 void DeviceCloudPolicyStoreChromeOS::Store(
40 const em::PolicyFetchResponse& policy) {
41 // Cancel all pending requests.
42 weak_factory_.InvalidateWeakPtrs();
44 scoped_refptr<ownership::PublicKey> public_key(
45 device_settings_service_->GetPublicKey());
46 if (!install_attributes_->IsEnterpriseDevice() ||
47 !device_settings_service_->policy_data() || !public_key.get() ||
48 !public_key->is_loaded()) {
49 status_ = STATUS_BAD_STATE;
50 NotifyStoreError();
51 return;
54 scoped_ptr<DeviceCloudPolicyValidator> validator(CreateValidator(policy));
55 validator->ValidateSignature(public_key->as_string(),
56 GetPolicyVerificationKey(),
57 install_attributes_->GetDomain(),
58 true);
59 validator->ValidateAgainstCurrentPolicy(
60 device_settings_service_->policy_data(),
61 CloudPolicyValidatorBase::TIMESTAMP_REQUIRED,
62 CloudPolicyValidatorBase::DM_TOKEN_REQUIRED);
63 validator.release()->StartValidation(
64 base::Bind(&DeviceCloudPolicyStoreChromeOS::OnPolicyToStoreValidated,
65 weak_factory_.GetWeakPtr()));
68 void DeviceCloudPolicyStoreChromeOS::Load() {
69 device_settings_service_->Load();
72 void DeviceCloudPolicyStoreChromeOS::InstallInitialPolicy(
73 const em::PolicyFetchResponse& policy) {
74 // Cancel all pending requests.
75 weak_factory_.InvalidateWeakPtrs();
77 if (!install_attributes_->IsEnterpriseDevice()) {
78 status_ = STATUS_BAD_STATE;
79 NotifyStoreError();
80 return;
83 scoped_ptr<DeviceCloudPolicyValidator> validator(CreateValidator(policy));
84 validator->ValidateInitialKey(GetPolicyVerificationKey(),
85 install_attributes_->GetDomain());
86 validator.release()->StartValidation(
87 base::Bind(&DeviceCloudPolicyStoreChromeOS::OnPolicyToStoreValidated,
88 weak_factory_.GetWeakPtr()));
91 void DeviceCloudPolicyStoreChromeOS::OwnershipStatusChanged() {
92 // Nothing to do.
95 void DeviceCloudPolicyStoreChromeOS::DeviceSettingsUpdated() {
96 if (!weak_factory_.HasWeakPtrs())
97 UpdateFromService();
100 void DeviceCloudPolicyStoreChromeOS::OnDeviceSettingsServiceShutdown() {
101 device_settings_service_ = nullptr;
104 scoped_ptr<DeviceCloudPolicyValidator>
105 DeviceCloudPolicyStoreChromeOS::CreateValidator(
106 const em::PolicyFetchResponse& policy) {
107 scoped_ptr<DeviceCloudPolicyValidator> validator(
108 DeviceCloudPolicyValidator::Create(
109 scoped_ptr<em::PolicyFetchResponse>(
110 new em::PolicyFetchResponse(policy)),
111 background_task_runner_));
112 validator->ValidateDomain(install_attributes_->GetDomain());
113 validator->ValidatePolicyType(dm_protocol::kChromeDevicePolicyType);
114 validator->ValidatePayload();
115 return validator.Pass();
118 void DeviceCloudPolicyStoreChromeOS::OnPolicyToStoreValidated(
119 DeviceCloudPolicyValidator* validator) {
120 if (!validator->success()) {
121 status_ = STATUS_VALIDATION_ERROR;
122 validation_status_ = validator->status();
123 NotifyStoreError();
124 return;
127 device_settings_service_->Store(
128 validator->policy().Pass(),
129 base::Bind(&DeviceCloudPolicyStoreChromeOS::OnPolicyStored,
130 weak_factory_.GetWeakPtr()));
133 void DeviceCloudPolicyStoreChromeOS::OnPolicyStored() {
134 UpdateFromService();
137 void DeviceCloudPolicyStoreChromeOS::UpdateFromService() {
138 const em::PolicyData* policy_data = device_settings_service_->policy_data();
139 const chromeos::DeviceSettingsService::Status status =
140 device_settings_service_->status();
142 const bool is_enterprise_managed = install_attributes_->IsEnterpriseDevice();
143 bool is_or_was_consumer_managed = false;
144 if (policy_data) {
145 const ManagementMode management_mode = GetManagementMode(*policy_data);
146 if (management_mode == MANAGEMENT_MODE_CONSUMER_MANAGED ||
147 (management_mode == MANAGEMENT_MODE_LOCAL_OWNER &&
148 policy() &&
149 GetManagementMode(*policy()) == MANAGEMENT_MODE_CONSUMER_MANAGED)) {
150 // The device is consumer-managed, or was consumer-managed and is now
151 // unmanaged.
152 is_or_was_consumer_managed = true;
156 if (!is_enterprise_managed && !is_or_was_consumer_managed) {
157 status_ = STATUS_BAD_STATE;
158 NotifyStoreError();
159 return;
162 // For enterprise devices, once per session, validate internal consistency of
163 // enrollment state (DM token must be present on enrolled devices) and in case
164 // of failure set flag to indicate that recovery is required.
165 if (is_enterprise_managed) {
166 switch (status) {
167 case chromeos::DeviceSettingsService::STORE_SUCCESS:
168 case chromeos::DeviceSettingsService::STORE_KEY_UNAVAILABLE:
169 case chromeos::DeviceSettingsService::STORE_NO_POLICY:
170 case chromeos::DeviceSettingsService::STORE_INVALID_POLICY:
171 case chromeos::DeviceSettingsService::STORE_VALIDATION_ERROR: {
172 if (!enrollment_validation_done_) {
173 enrollment_validation_done_ = true;
174 const bool has_dm_token =
175 status == chromeos::DeviceSettingsService::STORE_SUCCESS &&
176 policy_data &&
177 policy_data->has_request_token();
179 // At the time LoginDisplayHostImpl decides whether enrollment flow is
180 // to be started, policy hasn't been read yet. To work around this,
181 // once the need for recovery is detected upon policy load, a flag is
182 // stored in prefs which is accessed by LoginDisplayHostImpl early
183 // during (next) boot.
184 if (!has_dm_token) {
185 LOG(ERROR) << "Device policy read on enrolled device yields "
186 << "no DM token! Status: " << status << ".";
187 chromeos::StartupUtils::MarkEnrollmentRecoveryRequired();
189 UMA_HISTOGRAM_BOOLEAN("Enterprise.EnrolledPolicyHasDMToken",
190 has_dm_token);
192 break;
194 case chromeos::DeviceSettingsService::STORE_POLICY_ERROR:
195 case chromeos::DeviceSettingsService::STORE_OPERATION_FAILED:
196 case chromeos::DeviceSettingsService::STORE_TEMP_VALIDATION_ERROR:
197 // Do nothing for write errors or transient read errors.
198 break;
202 switch (status) {
203 case chromeos::DeviceSettingsService::STORE_SUCCESS: {
204 status_ = STATUS_OK;
205 policy_.reset(new em::PolicyData());
206 if (policy_data)
207 policy_->MergeFrom(*policy_data);
209 PolicyMap new_policy_map;
210 if (is_enterprise_managed && is_managed()) {
211 DecodeDevicePolicy(*device_settings_service_->device_settings(),
212 &new_policy_map);
214 policy_map_.Swap(&new_policy_map);
216 NotifyStoreLoaded();
217 return;
219 case chromeos::DeviceSettingsService::STORE_KEY_UNAVAILABLE:
220 status_ = STATUS_BAD_STATE;
221 break;
222 case chromeos::DeviceSettingsService::STORE_POLICY_ERROR:
223 case chromeos::DeviceSettingsService::STORE_OPERATION_FAILED:
224 status_ = STATUS_STORE_ERROR;
225 break;
226 case chromeos::DeviceSettingsService::STORE_NO_POLICY:
227 case chromeos::DeviceSettingsService::STORE_INVALID_POLICY:
228 case chromeos::DeviceSettingsService::STORE_VALIDATION_ERROR:
229 case chromeos::DeviceSettingsService::STORE_TEMP_VALIDATION_ERROR:
230 status_ = STATUS_LOAD_ERROR;
231 break;
234 NotifyStoreError();
237 } // namespace policy