15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/logging.h"
9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/metrics/histogram.h"
108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/sequenced_task_runner.h"
11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/chromeos/login/startup_utils.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/policy/device_policy_decoder_chromeos.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/policy/enterprise_install_attributes.h"
14a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h"
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/ownership/owner_key_util.h"
16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "policy/proto/device_management_backend.pb.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace em = enterprise_management;
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace policy {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DeviceCloudPolicyStoreChromeOS::DeviceCloudPolicyStoreChromeOS(
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    chromeos::DeviceSettingsService* device_settings_service,
248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    EnterpriseInstallAttributes* install_attributes,
258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    scoped_refptr<base::SequencedTaskRunner> background_task_runner)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : device_settings_service_(device_settings_service),
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      install_attributes_(install_attributes),
288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      background_task_runner_(background_task_runner),
295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      enrollment_validation_done_(false),
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      weak_factory_(this) {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  device_settings_service_->AddObserver(this);
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DeviceCloudPolicyStoreChromeOS::~DeviceCloudPolicyStoreChromeOS() {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  device_settings_service_->RemoveObserver(this);
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeviceCloudPolicyStoreChromeOS::Store(
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const em::PolicyFetchResponse& policy) {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Cancel all pending requests.
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  weak_factory_.InvalidateWeakPtrs();
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<ownership::PublicKey> public_key(
44f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      device_settings_service_->GetPublicKey());
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!install_attributes_->IsEnterpriseDevice() ||
46f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      !device_settings_service_->policy_data() || !public_key.get() ||
47f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      !public_key->is_loaded()) {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    status_ = STATUS_BAD_STATE;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotifyStoreError();
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DeviceCloudPolicyValidator> validator(CreateValidator(policy));
54f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  validator->ValidateSignature(public_key->as_string(),
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               GetPolicyVerificationKey(),
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               install_attributes_->GetDomain(),
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               true);
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  validator->ValidateAgainstCurrentPolicy(
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      device_settings_service_->policy_data(),
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CloudPolicyValidatorBase::TIMESTAMP_REQUIRED,
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CloudPolicyValidatorBase::DM_TOKEN_REQUIRED);
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  validator.release()->StartValidation(
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&DeviceCloudPolicyStoreChromeOS::OnPolicyToStoreValidated,
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 weak_factory_.GetWeakPtr()));
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeviceCloudPolicyStoreChromeOS::Load() {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  device_settings_service_->Load();
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeviceCloudPolicyStoreChromeOS::InstallInitialPolicy(
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const em::PolicyFetchResponse& policy) {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Cancel all pending requests.
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  weak_factory_.InvalidateWeakPtrs();
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!install_attributes_->IsEnterpriseDevice() &&
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      device_settings_service_->status() !=
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          chromeos::DeviceSettingsService::STORE_NO_POLICY) {
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    status_ = STATUS_BAD_STATE;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotifyStoreError();
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DeviceCloudPolicyValidator> validator(CreateValidator(policy));
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  validator->ValidateInitialKey(GetPolicyVerificationKey(),
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                install_attributes_->GetDomain());
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  validator.release()->StartValidation(
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&DeviceCloudPolicyStoreChromeOS::OnPolicyToStoreValidated,
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 weak_factory_.GetWeakPtr()));
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeviceCloudPolicyStoreChromeOS::OwnershipStatusChanged() {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Nothing to do.
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeviceCloudPolicyStoreChromeOS::DeviceSettingsUpdated() {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!weak_factory_.HasWeakPtrs())
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UpdateFromService();
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_ptr<DeviceCloudPolicyValidator>
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DeviceCloudPolicyStoreChromeOS::CreateValidator(
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        const em::PolicyFetchResponse& policy) {
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DeviceCloudPolicyValidator> validator(
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DeviceCloudPolicyValidator::Create(
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          scoped_ptr<em::PolicyFetchResponse>(
1078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)              new em::PolicyFetchResponse(policy)),
1088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          background_task_runner_));
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  validator->ValidateDomain(install_attributes_->GetDomain());
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  validator->ValidatePolicyType(dm_protocol::kChromeDevicePolicyType);
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  validator->ValidatePayload();
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return validator.Pass();
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeviceCloudPolicyStoreChromeOS::OnPolicyToStoreValidated(
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DeviceCloudPolicyValidator* validator) {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!validator->success()) {
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    status_ = STATUS_VALIDATION_ERROR;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    validation_status_ = validator->status();
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotifyStoreError();
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  device_settings_service_->Store(
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      validator->policy().Pass(),
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&DeviceCloudPolicyStoreChromeOS::OnPolicyStored,
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 weak_factory_.GetWeakPtr()));
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeviceCloudPolicyStoreChromeOS::OnPolicyStored() {
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateFromService();
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeviceCloudPolicyStoreChromeOS::UpdateFromService() {
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!install_attributes_->IsEnterpriseDevice()) {
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    status_ = STATUS_BAD_STATE;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotifyStoreError();
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Once per session, validate internal consistency of enrollment state (DM
1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // token must be present on enrolled devices) and in case of failure set flag
1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // to indicate that recovery is required.
144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const chromeos::DeviceSettingsService::Status status =
145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      device_settings_service_->status();
1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  switch (status) {
1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case chromeos::DeviceSettingsService::STORE_SUCCESS:
1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case chromeos::DeviceSettingsService::STORE_KEY_UNAVAILABLE:
1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case chromeos::DeviceSettingsService::STORE_NO_POLICY:
1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case chromeos::DeviceSettingsService::STORE_INVALID_POLICY:
1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case chromeos::DeviceSettingsService::STORE_VALIDATION_ERROR: {
1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      if (!enrollment_validation_done_) {
1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        enrollment_validation_done_ = true;
1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        const bool has_dm_token =
1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            status == chromeos::DeviceSettingsService::STORE_SUCCESS &&
1565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            device_settings_service_->policy_data() &&
1575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            device_settings_service_->policy_data()->has_request_token();
1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        // At the time LoginDisplayHostImpl decides whether enrollment flow is
1605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        // to be started, policy hasn't been read yet.  To work around this,
1615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        // once the need for recovery is detected upon policy load, a flag is
1625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        // stored in prefs which is accessed by LoginDisplayHostImpl early
1635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        // during (next) boot.
1645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if (!has_dm_token) {
1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          LOG(ERROR) << "Device policy read on enrolled device yields "
1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                     << "no DM token! Status: " << status << ".";
1675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          chromeos::StartupUtils::MarkEnrollmentRecoveryRequired();
1685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        }
1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        UMA_HISTOGRAM_BOOLEAN("Enterprise.EnrolledPolicyHasDMToken",
1705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              has_dm_token);
1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      }
1725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      break;
173116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
1745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case chromeos::DeviceSettingsService::STORE_POLICY_ERROR:
1755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case chromeos::DeviceSettingsService::STORE_OPERATION_FAILED:
1765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case chromeos::DeviceSettingsService::STORE_TEMP_VALIDATION_ERROR:
1775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      // Do nothing for write errors or transient read errors.
1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      break;
179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  switch (status) {
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case chromeos::DeviceSettingsService::STORE_SUCCESS: {
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      status_ = STATUS_OK;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      policy_.reset(new em::PolicyData());
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (device_settings_service_->policy_data())
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        policy_->MergeFrom(*device_settings_service_->policy_data());
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PolicyMap new_policy_map;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (is_managed()) {
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DecodeDevicePolicy(*device_settings_service_->device_settings(),
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           &new_policy_map, install_attributes_);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      policy_map_.Swap(&new_policy_map);
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NotifyStoreLoaded();
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case chromeos::DeviceSettingsService::STORE_KEY_UNAVAILABLE:
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      status_ = STATUS_BAD_STATE;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case chromeos::DeviceSettingsService::STORE_POLICY_ERROR:
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case chromeos::DeviceSettingsService::STORE_OPERATION_FAILED:
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      status_ = STATUS_STORE_ERROR;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case chromeos::DeviceSettingsService::STORE_NO_POLICY:
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case chromeos::DeviceSettingsService::STORE_INVALID_POLICY:
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case chromeos::DeviceSettingsService::STORE_VALIDATION_ERROR:
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case chromeos::DeviceSettingsService::STORE_TEMP_VALIDATION_ERROR:
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      status_ = STATUS_LOAD_ERROR;
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NotifyStoreError();
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace policy
217