1// Copyright (c) 2013 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/policy/profile_policy_connector.h"
6
7#include <vector>
8
9#include "base/bind.h"
10#include "base/logging.h"
11#include "base/values.h"
12#include "chrome/browser/browser_process.h"
13#include "components/policy/core/browser/browser_policy_connector.h"
14#include "components/policy/core/common/cloud/cloud_policy_core.h"
15#include "components/policy/core/common/cloud/cloud_policy_manager.h"
16#include "components/policy/core/common/cloud/cloud_policy_store.h"
17#include "components/policy/core/common/configuration_policy_provider.h"
18#include "components/policy/core/common/forwarding_policy_provider.h"
19#include "components/policy/core/common/policy_service_impl.h"
20#include "google_apis/gaia/gaia_auth_util.h"
21
22#if defined(OS_CHROMEOS)
23#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
24#include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h"
25#include "chrome/browser/chromeos/policy/device_local_account_policy_provider.h"
26#include "chrome/browser/chromeos/policy/login_profile_policy_provider.h"
27#include "components/user_manager/user.h"
28#include "components/user_manager/user_manager.h"
29#endif
30
31namespace policy {
32
33namespace {
34
35bool HasChromePolicy(ConfigurationPolicyProvider* provider,
36                     const char* name) {
37  if (!provider)
38    return false;
39  PolicyNamespace chrome_ns(POLICY_DOMAIN_CHROME, "");
40  return provider->policies().Get(chrome_ns).Get(name) != NULL;
41}
42
43}  // namespace
44
45ProfilePolicyConnector::ProfilePolicyConnector()
46#if defined(OS_CHROMEOS)
47    : is_primary_user_(false),
48      user_cloud_policy_manager_(NULL)
49#else
50    : user_cloud_policy_manager_(NULL)
51#endif
52      {}
53
54ProfilePolicyConnector::~ProfilePolicyConnector() {}
55
56void ProfilePolicyConnector::Init(
57    bool force_immediate_load,
58#if defined(OS_CHROMEOS)
59    const user_manager::User* user,
60#endif
61    SchemaRegistry* schema_registry,
62    CloudPolicyManager* user_cloud_policy_manager) {
63  user_cloud_policy_manager_ = user_cloud_policy_manager;
64
65  // |providers| contains a list of the policy providers available for the
66  // PolicyService of this connector, in decreasing order of priority.
67  //
68  // Note: all the providers appended to this vector must eventually become
69  // initialized for every policy domain, otherwise some subsystems will never
70  // use the policies exposed by the PolicyService!
71  // The default ConfigurationPolicyProvider::IsInitializationComplete()
72  // result is true, so take care if a provider overrides that.
73  //
74  // Note: if you append a new provider then make sure IsPolicyFromCloudPolicy()
75  // is also updated below.
76  std::vector<ConfigurationPolicyProvider*> providers;
77
78#if defined(OS_CHROMEOS)
79  BrowserPolicyConnectorChromeOS* connector =
80      g_browser_process->platform_part()->browser_policy_connector_chromeos();
81#else
82  BrowserPolicyConnector* connector =
83      g_browser_process->browser_policy_connector();
84#endif
85
86  if (connector->GetPlatformProvider()) {
87    forwarding_policy_provider_.reset(
88        new ForwardingPolicyProvider(connector->GetPlatformProvider()));
89    forwarding_policy_provider_->Init(schema_registry);
90    providers.push_back(forwarding_policy_provider_.get());
91  }
92
93#if defined(OS_CHROMEOS)
94  if (connector->GetDeviceCloudPolicyManager())
95    providers.push_back(connector->GetDeviceCloudPolicyManager());
96#endif
97
98  if (user_cloud_policy_manager)
99    providers.push_back(user_cloud_policy_manager);
100
101#if defined(OS_CHROMEOS)
102  if (!user) {
103    DCHECK(schema_registry);
104    // This case occurs for the signin profile.
105    special_user_policy_provider_.reset(
106        new LoginProfilePolicyProvider(connector->GetPolicyService()));
107  } else {
108    // |user| should never be NULL except for the signin profile.
109    is_primary_user_ =
110        user == user_manager::UserManager::Get()->GetPrimaryUser();
111    special_user_policy_provider_ = DeviceLocalAccountPolicyProvider::Create(
112        user->email(),
113        connector->GetDeviceLocalAccountPolicyService());
114  }
115  if (special_user_policy_provider_) {
116    special_user_policy_provider_->Init(schema_registry);
117    providers.push_back(special_user_policy_provider_.get());
118  }
119#endif
120
121  policy_service_.reset(new PolicyServiceImpl(providers));
122
123#if defined(OS_CHROMEOS)
124  if (is_primary_user_) {
125    if (user_cloud_policy_manager)
126      connector->SetUserPolicyDelegate(user_cloud_policy_manager);
127    else if (special_user_policy_provider_)
128      connector->SetUserPolicyDelegate(special_user_policy_provider_.get());
129  }
130#endif
131}
132
133void ProfilePolicyConnector::InitForTesting(scoped_ptr<PolicyService> service) {
134  policy_service_ = service.Pass();
135}
136
137void ProfilePolicyConnector::Shutdown() {
138#if defined(OS_CHROMEOS)
139  BrowserPolicyConnectorChromeOS* connector =
140      g_browser_process->platform_part()->browser_policy_connector_chromeos();
141  if (is_primary_user_)
142    connector->SetUserPolicyDelegate(NULL);
143  if (special_user_policy_provider_)
144    special_user_policy_provider_->Shutdown();
145#endif
146  if (forwarding_policy_provider_)
147    forwarding_policy_provider_->Shutdown();
148}
149
150bool ProfilePolicyConnector::IsManaged() const {
151  return !GetManagementDomain().empty();
152}
153
154std::string ProfilePolicyConnector::GetManagementDomain() const {
155  if (!user_cloud_policy_manager_)
156    return "";
157  CloudPolicyStore* store = user_cloud_policy_manager_->core()->store();
158  if (store && store->is_managed() && store->policy()->has_username())
159    return gaia::ExtractDomainName(store->policy()->username());
160  return "";
161}
162
163bool ProfilePolicyConnector::IsPolicyFromCloudPolicy(const char* name) const {
164  if (!HasChromePolicy(user_cloud_policy_manager_, name))
165    return false;
166
167  // Check all the providers that have higher priority than the
168  // |user_cloud_policy_manager_|. These checks must be kept in sync with the
169  // order of the providers in Init().
170
171  if (HasChromePolicy(forwarding_policy_provider_.get(), name))
172    return false;
173
174#if defined(OS_CHROMEOS)
175  BrowserPolicyConnectorChromeOS* connector =
176      g_browser_process->platform_part()->browser_policy_connector_chromeos();
177  if (HasChromePolicy(connector->GetDeviceCloudPolicyManager(), name))
178    return false;
179#endif
180
181  return true;
182}
183
184}  // namespace policy
185