device_local_account_policy_store.cc revision 8bcbed890bc3ce4d7a057a8f32cab53fa534672e
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
19namespace em = enterprise_management;
20
21namespace policy {
22
23DeviceLocalAccountPolicyStore::DeviceLocalAccountPolicyStore(
24    const std::string& account_id,
25    chromeos::SessionManagerClient* session_manager_client,
26    chromeos::DeviceSettingsService* device_settings_service,
27    scoped_refptr<base::SequencedTaskRunner> background_task_runner)
28    : UserCloudPolicyStoreBase(background_task_runner),
29      account_id_(account_id),
30      session_manager_client_(session_manager_client),
31      device_settings_service_(device_settings_service),
32      weak_factory_(this) {}
33
34DeviceLocalAccountPolicyStore::~DeviceLocalAccountPolicyStore() {}
35
36void DeviceLocalAccountPolicyStore::Load() {
37  weak_factory_.InvalidateWeakPtrs();
38  session_manager_client_->RetrieveDeviceLocalAccountPolicy(
39      account_id_,
40      base::Bind(&DeviceLocalAccountPolicyStore::ValidateLoadedPolicyBlob,
41                 weak_factory_.GetWeakPtr()));
42}
43
44void DeviceLocalAccountPolicyStore::Store(
45    const em::PolicyFetchResponse& policy) {
46  weak_factory_.InvalidateWeakPtrs();
47  CheckKeyAndValidate(
48      make_scoped_ptr(new em::PolicyFetchResponse(policy)),
49      base::Bind(&DeviceLocalAccountPolicyStore::StoreValidatedPolicy,
50                 weak_factory_.GetWeakPtr()));
51}
52
53void DeviceLocalAccountPolicyStore::ValidateLoadedPolicyBlob(
54    const std::string& policy_blob) {
55  if (policy_blob.empty()) {
56    status_ = CloudPolicyStore::STATUS_LOAD_ERROR;
57    NotifyStoreError();
58  } else {
59    scoped_ptr<em::PolicyFetchResponse> policy(new em::PolicyFetchResponse());
60    if (policy->ParseFromString(policy_blob)) {
61      CheckKeyAndValidate(
62          policy.Pass(),
63          base::Bind(&DeviceLocalAccountPolicyStore::UpdatePolicy,
64                     weak_factory_.GetWeakPtr()));
65    } else {
66      status_ = CloudPolicyStore::STATUS_PARSE_ERROR;
67      NotifyStoreError();
68    }
69  }
70}
71
72void DeviceLocalAccountPolicyStore::UpdatePolicy(
73    UserCloudPolicyValidator* validator) {
74  validation_status_ = validator->status();
75  if (!validator->success()) {
76    status_ = STATUS_VALIDATION_ERROR;
77    NotifyStoreError();
78    return;
79  }
80
81  InstallPolicy(validator->policy_data().Pass(), validator->payload().Pass());
82  // Exit the session when the lid is closed. The default behavior is to
83  // suspend while leaving the session running, which is not desirable for
84  // public sessions.
85  policy_map_.Set(key::kLidCloseAction,
86                  POLICY_LEVEL_MANDATORY,
87                  POLICY_SCOPE_USER,
88                  base::Value::CreateIntegerValue(
89                      chromeos::PowerPolicyController::ACTION_STOP_SESSION),
90                  NULL);
91  // Force the |ShelfAutoHideBehavior| policy to |Never|, ensuring that the ash
92  // shelf does not auto-hide.
93  policy_map_.Set(key::kShelfAutoHideBehavior,
94                  POLICY_LEVEL_MANDATORY,
95                  POLICY_SCOPE_USER,
96                  Value::CreateStringValue("Never"),
97                  NULL);
98  // Force the |ShowLogoutButtonInTray| policy to |true|, ensuring that a big,
99  // red logout button is shown in the ash system tray.
100  policy_map_.Set(key::kShowLogoutButtonInTray,
101                  POLICY_LEVEL_MANDATORY,
102                  POLICY_SCOPE_USER,
103                  Value::CreateBooleanValue(true),
104                  NULL);
105  // Force the |FullscreenAllowed| policy to |false|, ensuring that the ash
106  // shelf cannot be hidden by entering fullscreen mode.
107  policy_map_.Set(key::kFullscreenAllowed,
108                  POLICY_LEVEL_MANDATORY,
109                  POLICY_SCOPE_USER,
110                  Value::CreateBooleanValue(false),
111                  NULL);
112
113  status_ = STATUS_OK;
114  NotifyStoreLoaded();
115}
116
117void DeviceLocalAccountPolicyStore::StoreValidatedPolicy(
118    UserCloudPolicyValidator* validator) {
119  if (!validator->success()) {
120    status_ = CloudPolicyStore::STATUS_VALIDATION_ERROR;
121    validation_status_ = validator->status();
122    NotifyStoreError();
123    return;
124  }
125
126  std::string policy_blob;
127  if (!validator->policy()->SerializeToString(&policy_blob)) {
128    status_ = CloudPolicyStore::STATUS_SERIALIZE_ERROR;
129    NotifyStoreError();
130    return;
131  }
132
133  session_manager_client_->StoreDeviceLocalAccountPolicy(
134      account_id_,
135      policy_blob,
136      base::Bind(&DeviceLocalAccountPolicyStore::HandleStoreResult,
137                 weak_factory_.GetWeakPtr()));
138}
139
140void DeviceLocalAccountPolicyStore::HandleStoreResult(bool success) {
141  if (!success) {
142    status_ = CloudPolicyStore::STATUS_STORE_ERROR;
143    NotifyStoreError();
144  } else {
145    Load();
146  }
147}
148
149void DeviceLocalAccountPolicyStore::CheckKeyAndValidate(
150    scoped_ptr<em::PolicyFetchResponse> policy,
151    const UserCloudPolicyValidator::CompletionCallback& callback) {
152  device_settings_service_->GetOwnershipStatusAsync(
153      base::Bind(&DeviceLocalAccountPolicyStore::Validate,
154                 weak_factory_.GetWeakPtr(),
155                 base::Passed(&policy),
156                 callback));
157}
158
159void DeviceLocalAccountPolicyStore::Validate(
160    scoped_ptr<em::PolicyFetchResponse> policy_response,
161    const UserCloudPolicyValidator::CompletionCallback& callback,
162    chromeos::DeviceSettingsService::OwnershipStatus ownership_status) {
163  DCHECK_NE(chromeos::DeviceSettingsService::OWNERSHIP_UNKNOWN,
164            ownership_status);
165  scoped_refptr<chromeos::OwnerKey> key =
166      device_settings_service_->GetOwnerKey();
167  if (!key.get() || !key->public_key()) {
168    status_ = CloudPolicyStore::STATUS_BAD_STATE;
169    NotifyStoreLoaded();
170    return;
171  }
172
173  scoped_ptr<UserCloudPolicyValidator> validator(
174      UserCloudPolicyValidator::Create(policy_response.Pass(),
175                                       background_task_runner()));
176  validator->ValidateUsername(account_id_);
177  validator->ValidatePolicyType(dm_protocol::kChromePublicAccountPolicyType);
178  validator->ValidateAgainstCurrentPolicy(
179      policy(),
180      CloudPolicyValidatorBase::TIMESTAMP_REQUIRED,
181      CloudPolicyValidatorBase::DM_TOKEN_REQUIRED);
182  validator->ValidatePayload();
183  validator->ValidateSignature(*key->public_key(), false);
184  validator.release()->StartValidation(callback);
185}
186
187}  // namespace policy
188