Home | History | Annotate | Download | only in policy
      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_local_account_policy_store.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/callback.h"
      9 #include "base/values.h"
     10 #include "chrome/browser/policy/cloud/device_management_service.h"
     11 #include "chrome/browser/policy/external_data_fetcher.h"
     12 #include "chrome/browser/policy/policy_types.h"
     13 #include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h"
     14 #include "chromeos/dbus/power_policy_controller.h"
     15 #include "chromeos/dbus/session_manager_client.h"
     16 #include "policy/policy_constants.h"
     17 #include "policy/proto/cloud_policy.pb.h"
     18 
     19 namespace em = enterprise_management;
     20 
     21 namespace policy {
     22 
     23 DeviceLocalAccountPolicyStore::DeviceLocalAccountPolicyStore(
     24     const std::string& account_id,
     25     chromeos::SessionManagerClient* session_manager_client,
     26     chromeos::DeviceSettingsService* device_settings_service)
     27     : account_id_(account_id),
     28       session_manager_client_(session_manager_client),
     29       device_settings_service_(device_settings_service),
     30       weak_factory_(this) {}
     31 
     32 DeviceLocalAccountPolicyStore::~DeviceLocalAccountPolicyStore() {}
     33 
     34 void DeviceLocalAccountPolicyStore::Load() {
     35   weak_factory_.InvalidateWeakPtrs();
     36   session_manager_client_->RetrieveDeviceLocalAccountPolicy(
     37       account_id_,
     38       base::Bind(&DeviceLocalAccountPolicyStore::ValidateLoadedPolicyBlob,
     39                  weak_factory_.GetWeakPtr()));
     40 }
     41 
     42 void DeviceLocalAccountPolicyStore::Store(
     43     const em::PolicyFetchResponse& policy) {
     44   weak_factory_.InvalidateWeakPtrs();
     45   CheckKeyAndValidate(
     46       make_scoped_ptr(new em::PolicyFetchResponse(policy)),
     47       base::Bind(&DeviceLocalAccountPolicyStore::StoreValidatedPolicy,
     48                  weak_factory_.GetWeakPtr()));
     49 }
     50 
     51 void DeviceLocalAccountPolicyStore::ValidateLoadedPolicyBlob(
     52     const std::string& policy_blob) {
     53   if (policy_blob.empty()) {
     54     status_ = CloudPolicyStore::STATUS_LOAD_ERROR;
     55     NotifyStoreError();
     56   } else {
     57     scoped_ptr<em::PolicyFetchResponse> policy(new em::PolicyFetchResponse());
     58     if (policy->ParseFromString(policy_blob)) {
     59       CheckKeyAndValidate(
     60           policy.Pass(),
     61           base::Bind(&DeviceLocalAccountPolicyStore::UpdatePolicy,
     62                      weak_factory_.GetWeakPtr()));
     63     } else {
     64       status_ = CloudPolicyStore::STATUS_PARSE_ERROR;
     65       NotifyStoreError();
     66     }
     67   }
     68 }
     69 
     70 void DeviceLocalAccountPolicyStore::UpdatePolicy(
     71     UserCloudPolicyValidator* validator) {
     72   validation_status_ = validator->status();
     73   if (!validator->success()) {
     74     status_ = STATUS_VALIDATION_ERROR;
     75     NotifyStoreError();
     76     return;
     77   }
     78 
     79   InstallPolicy(validator->policy_data().Pass(), validator->payload().Pass());
     80   // Exit the session when the lid is closed. The default behavior is to
     81   // suspend while leaving the session running, which is not desirable for
     82   // public sessions.
     83   policy_map_.Set(key::kLidCloseAction,
     84                   POLICY_LEVEL_MANDATORY,
     85                   POLICY_SCOPE_USER,
     86                   base::Value::CreateIntegerValue(
     87                       chromeos::PowerPolicyController::ACTION_STOP_SESSION),
     88                   NULL);
     89 
     90   // Force the |ShelfAutoHideBehavior| policy to |Never|, ensuring that the ash
     91   // shelf does not auto-hide.
     92   policy_map_.Set(key::kShelfAutoHideBehavior,
     93                   POLICY_LEVEL_MANDATORY,
     94                   POLICY_SCOPE_USER,
     95                   Value::CreateStringValue("Never"),
     96                   NULL);
     97   // Force the |ShowLogoutButtonInTray| policy to |true|, ensuring that a big,
     98   // red logout button is shown in the ash system tray.
     99   policy_map_.Set(key::kShowLogoutButtonInTray,
    100                   POLICY_LEVEL_MANDATORY,
    101                   POLICY_SCOPE_USER,
    102                   Value::CreateBooleanValue(true),
    103                   NULL);
    104   // Restrict device-local accounts to hosted apps for now (i.e. no extensions,
    105   // packaged apps etc.) for security/privacy reasons (i.e. we'd like to
    106   // prevent the admin from stealing private information from random people).
    107   scoped_ptr<base::ListValue> allowed_extension_types(new base::ListValue());
    108   allowed_extension_types->AppendString("hosted_app");
    109   policy_map_.Set(key::kExtensionAllowedTypes,
    110                   POLICY_LEVEL_MANDATORY,
    111                   POLICY_SCOPE_USER,
    112                   allowed_extension_types.release(),
    113                   NULL);
    114 
    115   status_ = STATUS_OK;
    116   NotifyStoreLoaded();
    117 }
    118 
    119 void DeviceLocalAccountPolicyStore::StoreValidatedPolicy(
    120     UserCloudPolicyValidator* validator) {
    121   if (!validator->success()) {
    122     status_ = CloudPolicyStore::STATUS_VALIDATION_ERROR;
    123     validation_status_ = validator->status();
    124     NotifyStoreError();
    125     return;
    126   }
    127 
    128   std::string policy_blob;
    129   if (!validator->policy()->SerializeToString(&policy_blob)) {
    130     status_ = CloudPolicyStore::STATUS_SERIALIZE_ERROR;
    131     NotifyStoreError();
    132     return;
    133   }
    134 
    135   session_manager_client_->StoreDeviceLocalAccountPolicy(
    136       account_id_,
    137       policy_blob,
    138       base::Bind(&DeviceLocalAccountPolicyStore::HandleStoreResult,
    139                  weak_factory_.GetWeakPtr()));
    140 }
    141 
    142 void DeviceLocalAccountPolicyStore::HandleStoreResult(bool success) {
    143   if (!success) {
    144     status_ = CloudPolicyStore::STATUS_STORE_ERROR;
    145     NotifyStoreError();
    146   } else {
    147     Load();
    148   }
    149 }
    150 
    151 void DeviceLocalAccountPolicyStore::CheckKeyAndValidate(
    152     scoped_ptr<em::PolicyFetchResponse> policy,
    153     const UserCloudPolicyValidator::CompletionCallback& callback) {
    154   device_settings_service_->GetOwnershipStatusAsync(
    155       base::Bind(&DeviceLocalAccountPolicyStore::Validate,
    156                  weak_factory_.GetWeakPtr(),
    157                  base::Passed(&policy),
    158                  callback));
    159 }
    160 
    161 void DeviceLocalAccountPolicyStore::Validate(
    162     scoped_ptr<em::PolicyFetchResponse> policy_response,
    163     const UserCloudPolicyValidator::CompletionCallback& callback,
    164     chromeos::DeviceSettingsService::OwnershipStatus ownership_status,
    165     bool is_owner) {
    166   DCHECK_NE(chromeos::DeviceSettingsService::OWNERSHIP_UNKNOWN,
    167             ownership_status);
    168   scoped_refptr<chromeos::OwnerKey> key =
    169       device_settings_service_->GetOwnerKey();
    170   if (!key.get() || !key->public_key()) {
    171     status_ = CloudPolicyStore::STATUS_BAD_STATE;
    172     NotifyStoreLoaded();
    173     return;
    174   }
    175 
    176   scoped_ptr<UserCloudPolicyValidator> validator(
    177       UserCloudPolicyValidator::Create(policy_response.Pass()));
    178   validator->ValidateUsername(account_id_);
    179   validator->ValidatePolicyType(dm_protocol::kChromePublicAccountPolicyType);
    180   validator->ValidateAgainstCurrentPolicy(
    181       policy(),
    182       CloudPolicyValidatorBase::TIMESTAMP_REQUIRED,
    183       CloudPolicyValidatorBase::DM_TOKEN_REQUIRED);
    184   validator->ValidatePayload();
    185   validator->ValidateSignature(*key->public_key(), false);
    186   validator.release()->StartValidation(callback);
    187 }
    188 
    189 }  // namespace policy
    190