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