browser_policy_connector_chromeos.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
1// Copyright 2014 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/browser_policy_connector_chromeos.h"
6
7#include "base/files/file_path.h"
8#include "base/logging.h"
9#include "base/message_loop/message_loop_proxy.h"
10#include "base/path_service.h"
11#include "base/prefs/pref_registry_simple.h"
12#include "base/sequenced_task_runner.h"
13#include "base/strings/utf_string_conversions.h"
14#include "base/threading/sequenced_worker_pool.h"
15#include "chrome/browser/chromeos/policy/app_pack_updater.h"
16#include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h"
17#include "chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos.h"
18#include "chrome/browser/chromeos/policy/device_local_account.h"
19#include "chrome/browser/chromeos/policy/device_local_account_policy_service.h"
20#include "chrome/browser/chromeos/policy/device_network_configuration_updater.h"
21#include "chrome/browser/chromeos/policy/device_status_collector.h"
22#include "chrome/browser/chromeos/policy/enterprise_install_attributes.h"
23#include "chrome/browser/chromeos/settings/cros_settings.h"
24#include "chrome/browser/chromeos/settings/device_settings_service.h"
25#include "chrome/common/pref_names.h"
26#include "chromeos/chromeos_paths.h"
27#include "chromeos/chromeos_switches.h"
28#include "chromeos/cryptohome/system_salt_getter.h"
29#include "chromeos/dbus/dbus_thread_manager.h"
30#include "chromeos/network/network_handler.h"
31#include "chromeos/network/onc/onc_certificate_importer_impl.h"
32#include "chromeos/settings/cros_settings_names.h"
33#include "chromeos/settings/cros_settings_provider.h"
34#include "chromeos/settings/timezone_settings.h"
35#include "chromeos/system/statistics_provider.h"
36#include "components/policy/core/common/cloud/cloud_policy_client.h"
37#include "components/policy/core/common/cloud/cloud_policy_refresh_scheduler.h"
38#include "components/policy/core/common/proxy_policy_provider.h"
39#include "content/public/browser/browser_thread.h"
40#include "google_apis/gaia/gaia_auth_util.h"
41#include "net/url_request/url_request_context_getter.h"
42
43using content::BrowserThread;
44
45namespace policy {
46
47namespace {
48
49// Install attributes for tests.
50EnterpriseInstallAttributes* g_testing_install_attributes = NULL;
51
52// Helper that returns a new SequencedTaskRunner backed by the blocking pool.
53// Each SequencedTaskRunner returned is independent from the others.
54scoped_refptr<base::SequencedTaskRunner> GetBackgroundTaskRunner() {
55  base::SequencedWorkerPool* pool = BrowserThread::GetBlockingPool();
56  CHECK(pool);
57  return pool->GetSequencedTaskRunnerWithShutdownBehavior(
58      pool->GetSequenceToken(), base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
59}
60
61}  // namespace
62
63BrowserPolicyConnectorChromeOS::BrowserPolicyConnectorChromeOS()
64    : device_cloud_policy_manager_(NULL),
65      global_user_cloud_policy_provider_(NULL),
66      weak_ptr_factory_(this) {
67  if (g_testing_install_attributes)
68    install_attributes_.reset(g_testing_install_attributes);
69
70  // SystemSaltGetter or DBusThreadManager may be uninitialized on unit tests.
71
72  // TODO(satorux): Remove SystemSaltGetter::IsInitialized() when it's ready
73  // (removing it now breaks tests). crbug.com/141016.
74  if (chromeos::SystemSaltGetter::IsInitialized() &&
75      chromeos::DBusThreadManager::IsInitialized()) {
76    chromeos::CryptohomeClient* cryptohome_client =
77        chromeos::DBusThreadManager::Get()->GetCryptohomeClient();
78    if (!g_testing_install_attributes) {
79      install_attributes_.reset(
80          new EnterpriseInstallAttributes(cryptohome_client));
81    }
82    base::FilePath install_attrs_file;
83    CHECK(PathService::Get(chromeos::FILE_INSTALL_ATTRIBUTES,
84                           &install_attrs_file));
85    install_attributes_->ReadCacheFile(install_attrs_file);
86
87    scoped_ptr<DeviceCloudPolicyStoreChromeOS> device_cloud_policy_store(
88        new DeviceCloudPolicyStoreChromeOS(
89            chromeos::DeviceSettingsService::Get(),
90            install_attributes_.get(),
91            GetBackgroundTaskRunner()));
92    device_cloud_policy_manager_ =
93        new DeviceCloudPolicyManagerChromeOS(device_cloud_policy_store.Pass(),
94                                             base::MessageLoopProxy::current(),
95                                             GetBackgroundTaskRunner(),
96                                             install_attributes_.get());
97    AddPolicyProvider(
98        scoped_ptr<ConfigurationPolicyProvider>(device_cloud_policy_manager_));
99  }
100
101  global_user_cloud_policy_provider_ = new ProxyPolicyProvider();
102  AddPolicyProvider(scoped_ptr<ConfigurationPolicyProvider>(
103      global_user_cloud_policy_provider_));
104}
105
106BrowserPolicyConnectorChromeOS::~BrowserPolicyConnectorChromeOS() {}
107
108void BrowserPolicyConnectorChromeOS::Init(
109    PrefService* local_state,
110    scoped_refptr<net::URLRequestContextGetter> request_context) {
111  ChromeBrowserPolicyConnector::Init(local_state, request_context);
112
113  if (device_cloud_policy_manager_) {
114    // Note: for now the |device_cloud_policy_manager_| is using the global
115    // schema registry. Eventually it will have its own registry, once device
116    // cloud policy for extensions is introduced. That means it'd have to be
117    // initialized from here instead of BrowserPolicyConnector::Init().
118
119    scoped_ptr<CloudPolicyClient::StatusProvider> status_provider(
120        new DeviceStatusCollector(
121            local_state,
122            chromeos::system::StatisticsProvider::GetInstance(),
123            NULL));
124    device_cloud_policy_manager_->Connect(
125        local_state, device_management_service(), status_provider.Pass());
126  }
127
128  device_local_account_policy_service_.reset(
129      new DeviceLocalAccountPolicyService(
130          chromeos::DBusThreadManager::Get()->GetSessionManagerClient(),
131          chromeos::DeviceSettingsService::Get(),
132          chromeos::CrosSettings::Get(),
133          GetBackgroundTaskRunner(),
134          GetBackgroundTaskRunner(),
135          GetBackgroundTaskRunner(),
136          content::BrowserThread::GetMessageLoopProxyForThread(
137              content::BrowserThread::IO),
138          request_context));
139  device_local_account_policy_service_->Connect(device_management_service());
140
141  // request_context is NULL in unit tests.
142  if (request_context && install_attributes_) {
143    app_pack_updater_.reset(
144        new AppPackUpdater(request_context, install_attributes_.get()));
145  }
146
147  SetTimezoneIfPolicyAvailable();
148
149  network_configuration_updater_ =
150      DeviceNetworkConfigurationUpdater::CreateForDevicePolicy(
151          GetPolicyService(),
152          chromeos::NetworkHandler::Get()
153              ->managed_network_configuration_handler(),
154          chromeos::NetworkHandler::Get()->network_device_handler(),
155          chromeos::CrosSettings::Get());
156}
157
158void BrowserPolicyConnectorChromeOS::Shutdown() {
159  // The AppPackUpdater may be observing the |device_cloud_policy_manager_|.
160  // Delete it first.
161  app_pack_updater_.reset();
162
163  network_configuration_updater_.reset();
164
165  if (device_local_account_policy_service_)
166    device_local_account_policy_service_->Shutdown();
167
168  ChromeBrowserPolicyConnector::Shutdown();
169}
170
171bool BrowserPolicyConnectorChromeOS::IsEnterpriseManaged() {
172  return install_attributes_ && install_attributes_->IsEnterpriseDevice();
173}
174
175std::string BrowserPolicyConnectorChromeOS::GetEnterpriseDomain() {
176  return install_attributes_ ? install_attributes_->GetDomain() : std::string();
177}
178
179DeviceMode BrowserPolicyConnectorChromeOS::GetDeviceMode() {
180  return install_attributes_ ? install_attributes_->GetMode()
181                             : DEVICE_MODE_NOT_SET;
182}
183
184UserAffiliation BrowserPolicyConnectorChromeOS::GetUserAffiliation(
185    const std::string& user_name) {
186  // An empty username means incognito user in case of ChromiumOS and
187  // no logged-in user in case of Chromium (SigninService). Many tests use
188  // nonsense email addresses (e.g. 'test') so treat those as non-enterprise
189  // users.
190  if (user_name.empty() || user_name.find('@') == std::string::npos)
191    return USER_AFFILIATION_NONE;
192
193  if (install_attributes_ &&
194      (gaia::ExtractDomainName(gaia::CanonicalizeEmail(user_name)) ==
195           install_attributes_->GetDomain() ||
196       policy::IsDeviceLocalAccountUser(user_name, NULL))) {
197    return USER_AFFILIATION_MANAGED;
198  }
199
200  return USER_AFFILIATION_NONE;
201}
202
203AppPackUpdater* BrowserPolicyConnectorChromeOS::GetAppPackUpdater() {
204  return app_pack_updater_.get();
205}
206
207void BrowserPolicyConnectorChromeOS::SetUserPolicyDelegate(
208    ConfigurationPolicyProvider* user_policy_provider) {
209  global_user_cloud_policy_provider_->SetDelegate(user_policy_provider);
210}
211
212void BrowserPolicyConnectorChromeOS::SetInstallAttributesForTesting(
213    EnterpriseInstallAttributes* attributes) {
214  DCHECK(!g_testing_install_attributes);
215  g_testing_install_attributes = attributes;
216}
217
218// static
219void BrowserPolicyConnectorChromeOS::RegisterPrefs(
220    PrefRegistrySimple* registry) {
221  registry->RegisterIntegerPref(
222      prefs::kDevicePolicyRefreshRate,
223      CloudPolicyRefreshScheduler::kDefaultRefreshDelayMs);
224}
225
226void BrowserPolicyConnectorChromeOS::SetTimezoneIfPolicyAvailable() {
227  typedef chromeos::CrosSettingsProvider Provider;
228  Provider::TrustedStatus result =
229      chromeos::CrosSettings::Get()->PrepareTrustedValues(base::Bind(
230          &BrowserPolicyConnectorChromeOS::SetTimezoneIfPolicyAvailable,
231          weak_ptr_factory_.GetWeakPtr()));
232
233  if (result != Provider::TRUSTED)
234    return;
235
236  std::string timezone;
237  if (chromeos::CrosSettings::Get()->GetString(chromeos::kSystemTimezonePolicy,
238                                               &timezone) &&
239      !timezone.empty()) {
240    chromeos::system::TimezoneSettings::GetInstance()->SetTimezoneFromID(
241        base::UTF8ToUTF16(timezone));
242  }
243}
244
245}  // namespace policy
246