12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/policy/device_local_account_policy_provider.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h" 8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/values.h" 9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/chromeos/policy/device_local_account.h" 10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/chromeos/policy/device_local_account_external_data_manager.h" 11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chromeos/dbus/power_policy_controller.h" 12a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/cloud_policy_core.h" 13a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/cloud_policy_service.h" 146d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "components/policy/core/common/cloud/component_cloud_policy_service.h" 15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/policy/core/common/policy_bundle.h" 16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "components/policy/core/common/policy_map.h" 171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "components/policy/core/common/policy_namespace.h" 18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "policy/policy_constants.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace policy { 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DeviceLocalAccountPolicyProvider::DeviceLocalAccountPolicyProvider( 2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& user_id, 24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DeviceLocalAccountPolicyService* service, 25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<PolicyMap> chrome_policy_overrides) 2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) : user_id_(user_id), 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) service_(service), 28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) chrome_policy_overrides_(chrome_policy_overrides.Pass()), 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) store_initialized_(false), 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) waiting_for_policy_refresh_(false), 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_factory_(this) { 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) service_->AddObserver(this); 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateFromBroker(); 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DeviceLocalAccountPolicyProvider::~DeviceLocalAccountPolicyProvider() { 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) service_->RemoveObserver(this); 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// static 41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)scoped_ptr<DeviceLocalAccountPolicyProvider> 42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)DeviceLocalAccountPolicyProvider::Create( 43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& user_id, 44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DeviceLocalAccountPolicyService* device_local_account_policy_service) { 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DeviceLocalAccount::Type type; 46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!device_local_account_policy_service || 47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) !IsDeviceLocalAccountUser(user_id, &type)) { 48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return scoped_ptr<DeviceLocalAccountPolicyProvider>(); 49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<PolicyMap> chrome_policy_overrides; 52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (type == DeviceLocalAccount::TYPE_PUBLIC_SESSION) { 53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) chrome_policy_overrides.reset(new PolicyMap()); 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Exit the session when the lid is closed. The default behavior is to 56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // suspend while leaving the session running, which is not desirable for 57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // public sessions. 58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) chrome_policy_overrides->Set( 59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) key::kLidCloseAction, 60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) POLICY_LEVEL_MANDATORY, 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) POLICY_SCOPE_MACHINE, 62effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch new base::FundamentalValue( 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) chromeos::PowerPolicyController::ACTION_STOP_SESSION), 64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NULL); 65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Force the |ShelfAutoHideBehavior| policy to |Never|, ensuring that the 66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // ash shelf does not auto-hide. 67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) chrome_policy_overrides->Set( 68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) key::kShelfAutoHideBehavior, 69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) POLICY_LEVEL_MANDATORY, 70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) POLICY_SCOPE_MACHINE, 71effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch new base::StringValue("Never"), 72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NULL); 73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Force the |ShowLogoutButtonInTray| policy to |true|, ensuring that a big, 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // red logout button is shown in the ash system tray. 75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) chrome_policy_overrides->Set( 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) key::kShowLogoutButtonInTray, 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) POLICY_LEVEL_MANDATORY, 78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) POLICY_SCOPE_MACHINE, 79effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch new base::FundamentalValue(true), 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NULL); 81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Force the |FullscreenAllowed| policy to |false|, ensuring that the ash 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // shelf cannot be hidden by entering fullscreen mode. 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) chrome_policy_overrides->Set( 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) key::kFullscreenAllowed, 85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) POLICY_LEVEL_MANDATORY, 86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) POLICY_SCOPE_MACHINE, 87effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch new base::FundamentalValue(false), 88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NULL); 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<DeviceLocalAccountPolicyProvider> provider( 92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) new DeviceLocalAccountPolicyProvider(user_id, 93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) device_local_account_policy_service, 94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) chrome_policy_overrides.Pass())); 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return provider.Pass(); 96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool DeviceLocalAccountPolicyProvider::IsInitializationComplete( 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PolicyDomain domain) const { 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (domain == POLICY_DOMAIN_CHROME) 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return store_initialized_; 1026d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) if (ComponentCloudPolicyService::SupportsDomain(domain) && 1036d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) GetBroker() && GetBroker()->component_policy_service()) { 1046d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return GetBroker()->component_policy_service()->is_initialized(); 1056d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) } 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DeviceLocalAccountPolicyProvider::RefreshPolicies() { 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DeviceLocalAccountPolicyBroker* broker = GetBroker(); 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (broker && broker->core()->service()) { 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) waiting_for_policy_refresh_ = true; 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) broker->core()->service()->RefreshPolicy( 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&DeviceLocalAccountPolicyProvider::ReportPolicyRefresh, 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_factory_.GetWeakPtr())); 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateFromBroker(); 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DeviceLocalAccountPolicyProvider::OnPolicyUpdated( 12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& user_id) { 12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (user_id == user_id_) 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateFromBroker(); 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DeviceLocalAccountPolicyProvider::OnDeviceLocalAccountsChanged() { 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateFromBroker(); 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1316d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)DeviceLocalAccountPolicyBroker* DeviceLocalAccountPolicyProvider::GetBroker() 1326d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) const { 13390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return service_->GetBrokerForUser(user_id_); 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DeviceLocalAccountPolicyProvider::ReportPolicyRefresh(bool success) { 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) waiting_for_policy_refresh_ = false; 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateFromBroker(); 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DeviceLocalAccountPolicyProvider::UpdateFromBroker() { 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DeviceLocalAccountPolicyBroker* broker = GetBroker(); 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<PolicyBundle> bundle(new PolicyBundle()); 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (broker) { 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) store_initialized_ |= broker->core()->store()->is_initialized(); 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!waiting_for_policy_refresh_) { 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Copy policy from the broker. 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bundle->Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())) 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .CopyFrom(broker->core()->store()->policy_map()); 150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) external_data_manager_ = broker->external_data_manager(); 1516d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 1526d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) if (broker->component_policy_service()) 1536d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) bundle->MergeFrom(broker->component_policy_service()->policy()); 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Wait for the refresh to finish. 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Keep existing policy, but do send an update. 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) waiting_for_policy_refresh_ = false; 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_factory_.InvalidateWeakPtrs(); 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bundle->CopyFrom(policies()); 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Apply overrides. 166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (chrome_policy_overrides_) { 167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) PolicyMap& chrome_policy = 168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bundle->Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())); 169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (PolicyMap::const_iterator it(chrome_policy_overrides_->begin()); 170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) it != chrome_policy_overrides_->end(); 171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ++it) { 172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const PolicyMap::Entry& entry = it->second; 173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) chrome_policy.Set( 174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) it->first, entry.level, entry.scope, entry.value->DeepCopy(), NULL); 175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdatePolicy(bundle.Pass()); 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace policy 182