1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file.
4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/policy/profile_policy_connector.h"
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <vector>
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/bind.h"
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/logging.h"
11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/values.h"
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/browser_process.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/policy/core/browser/browser_policy_connector.h"
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/policy/core/common/cloud/cloud_policy_core.h"
15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/cloud_policy_manager.h"
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/policy/core/common/cloud/cloud_policy_store.h"
17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/configuration_policy_provider.h"
18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/forwarding_policy_provider.h"
19a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/policy_service_impl.h"
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "google_apis/gaia/gaia_auth_util.h"
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_CHROMEOS)
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h"
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/policy/device_local_account_policy_provider.h"
26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/chromeos/policy/login_profile_policy_provider.h"
275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "components/user_manager/user.h"
286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "components/user_manager/user_manager.h"
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace policy {
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)namespace {
3446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
3546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)bool HasChromePolicy(ConfigurationPolicyProvider* provider,
3646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                     const char* name) {
3746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!provider)
3846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return false;
3946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  PolicyNamespace chrome_ns(POLICY_DOMAIN_CHROME, "");
4046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return provider->policies().Get(chrome_ns).Get(name) != NULL;
4146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
4246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
4346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}  // namespace
4446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ProfilePolicyConnector::ProfilePolicyConnector()
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_CHROMEOS)
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : is_primary_user_(false),
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      user_cloud_policy_manager_(NULL)
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#else
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : user_cloud_policy_manager_(NULL)
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      {}
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ProfilePolicyConnector::~ProfilePolicyConnector() {}
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
560f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void ProfilePolicyConnector::Init(
570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    bool force_immediate_load,
580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#if defined(OS_CHROMEOS)
595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const user_manager::User* user,
600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#endif
61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SchemaRegistry* schema_registry,
620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    CloudPolicyManager* user_cloud_policy_manager) {
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  user_cloud_policy_manager_ = user_cloud_policy_manager;
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // |providers| contains a list of the policy providers available for the
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // PolicyService of this connector, in decreasing order of priority.
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  //
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Note: all the providers appended to this vector must eventually become
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // initialized for every policy domain, otherwise some subsystems will never
70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // use the policies exposed by the PolicyService!
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // The default ConfigurationPolicyProvider::IsInitializationComplete()
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // result is true, so take care if a provider overrides that.
7346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  //
7446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Note: if you append a new provider then make sure IsPolicyFromCloudPolicy()
7546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // is also updated below.
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector<ConfigurationPolicyProvider*> providers;
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_CHROMEOS)
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  BrowserPolicyConnectorChromeOS* connector =
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      g_browser_process->platform_part()->browser_policy_connector_chromeos();
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#else
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  BrowserPolicyConnector* connector =
83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      g_browser_process->browser_policy_connector();
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (connector->GetPlatformProvider()) {
87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    forwarding_policy_provider_.reset(
88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        new ForwardingPolicyProvider(connector->GetPlatformProvider()));
89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    forwarding_policy_provider_->Init(schema_registry);
90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    providers.push_back(forwarding_policy_provider_.get());
91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_CHROMEOS)
94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (connector->GetDeviceCloudPolicyManager())
95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    providers.push_back(connector->GetDeviceCloudPolicyManager());
96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif
97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  if (user_cloud_policy_manager)
990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    providers.push_back(user_cloud_policy_manager);
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#if defined(OS_CHROMEOS)
1020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  if (!user) {
103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DCHECK(schema_registry);
1040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // This case occurs for the signin profile.
1050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    special_user_policy_provider_.reset(
1060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        new LoginProfilePolicyProvider(connector->GetPolicyService()));
107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  } else {
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // |user| should never be NULL except for the signin profile.
1096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    is_primary_user_ =
1106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        user == user_manager::UserManager::Get()->GetPrimaryUser();
111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    special_user_policy_provider_ = DeviceLocalAccountPolicyProvider::Create(
112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        user->email(),
113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        connector->GetDeviceLocalAccountPolicyService());
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (special_user_policy_provider_) {
116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    special_user_policy_provider_->Init(schema_registry);
117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    providers.push_back(special_user_policy_provider_.get());
118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  policy_service_.reset(new PolicyServiceImpl(providers));
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_CHROMEOS)
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (is_primary_user_) {
1250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    if (user_cloud_policy_manager)
1260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      connector->SetUserPolicyDelegate(user_cloud_policy_manager);
127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    else if (special_user_policy_provider_)
128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      connector->SetUserPolicyDelegate(special_user_policy_provider_.get());
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ProfilePolicyConnector::InitForTesting(scoped_ptr<PolicyService> service) {
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  policy_service_ = service.Pass();
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ProfilePolicyConnector::Shutdown() {
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_CHROMEOS)
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  BrowserPolicyConnectorChromeOS* connector =
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      g_browser_process->platform_part()->browser_policy_connector_chromeos();
141424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (is_primary_user_)
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    connector->SetUserPolicyDelegate(NULL);
143eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (special_user_policy_provider_)
144eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    special_user_policy_provider_->Shutdown();
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (forwarding_policy_provider_)
147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    forwarding_policy_provider_->Shutdown();
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool ProfilePolicyConnector::IsManaged() const {
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return !GetManagementDomain().empty();
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::string ProfilePolicyConnector::GetManagementDomain() const {
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!user_cloud_policy_manager_)
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return "";
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CloudPolicyStore* store = user_cloud_policy_manager_->core()->store();
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (store && store->is_managed() && store->policy()->has_username())
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return gaia::ExtractDomainName(store->policy()->username());
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return "";
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)bool ProfilePolicyConnector::IsPolicyFromCloudPolicy(const char* name) const {
16446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!HasChromePolicy(user_cloud_policy_manager_, name))
16546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return false;
16646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
16746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Check all the providers that have higher priority than the
16846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // |user_cloud_policy_manager_|. These checks must be kept in sync with the
16946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // order of the providers in Init().
17046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
17146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (HasChromePolicy(forwarding_policy_provider_.get(), name))
17246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return false;
17346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
17446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#if defined(OS_CHROMEOS)
17546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  BrowserPolicyConnectorChromeOS* connector =
17646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      g_browser_process->platform_part()->browser_policy_connector_chromeos();
17746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (HasChromePolicy(connector->GetDeviceCloudPolicyManager(), name))
17846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return false;
17946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#endif
18046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
18146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return true;
18246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
18346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace policy
185