1 // Copyright (c) 2011 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 <algorithm>
6 #include <string>
7
8 #include "base/command_line.h"
9 #include "base/file_util.h"
10 #include "chrome/browser/browser_process.h"
11 #include "chrome/browser/policy/browser_policy_connector.h"
12 #include "chrome/browser/policy/configuration_policy_pref_store.h"
13 #include "chrome/browser/policy/cloud_policy_subsystem.h"
14 #include "chrome/browser/policy/profile_policy_connector.h"
15 #include "chrome/browser/policy/user_policy_cache.h"
16 #include "chrome/browser/policy/user_policy_identity_strategy.h"
17 #include "chrome/browser/prefs/pref_service.h"
18 #include "chrome/browser/profiles/profile.h"
19 #include "chrome/common/chrome_switches.h"
20 #include "net/url_request/url_request_context_getter.h"
21
22 namespace {
23
24 const FilePath::CharType kPolicyDir[] = FILE_PATH_LITERAL("Device Management");
25 const FilePath::CharType kTokenCacheFile[] = FILE_PATH_LITERAL("Token");
26 const FilePath::CharType kPolicyCacheFile[] = FILE_PATH_LITERAL("Policy");
27
28 } // namespace
29
30 namespace policy {
31
ProfilePolicyConnector(Profile * profile)32 ProfilePolicyConnector::ProfilePolicyConnector(Profile* profile)
33 : profile_(profile) {
34 // TODO(mnissler): We access the file system here. The cloud policy context
35 // below needs to do so anyway, since it needs to read the policy cache from
36 // disk. If this proves to be a problem, we need to do this initialization
37 // asynchronously on the file thread and put in synchronization that allows us
38 // to wait for the cache to be read during the browser startup code paths.
39 // Another option would be to provide a generic IO-safe initializer called
40 // from the PrefService that we could hook up with through the policy
41 // provider.
42 CommandLine* command_line = CommandLine::ForCurrentProcess();
43 if (command_line->HasSwitch(switches::kDeviceManagementUrl)) {
44 FilePath policy_cache_dir(profile_->GetPath());
45 policy_cache_dir = policy_cache_dir.Append(kPolicyDir);
46 if (!file_util::CreateDirectory(policy_cache_dir)) {
47 LOG(WARNING) << "Failed to create policy state dir "
48 << policy_cache_dir.value()
49 << ", skipping cloud policy initialization.";
50 return;
51 }
52
53 identity_strategy_.reset(new UserPolicyIdentityStrategy(
54 profile_,
55 policy_cache_dir.Append(kTokenCacheFile)));
56 cloud_policy_subsystem_.reset(new CloudPolicySubsystem(
57 identity_strategy_.get(),
58 new UserPolicyCache(policy_cache_dir.Append(kPolicyCacheFile))));
59
60 BrowserPolicyConnector* browser_connector =
61 g_browser_process->browser_policy_connector();
62
63 managed_cloud_provider_.reset(new MergingPolicyProvider(
64 browser_connector->GetManagedCloudProvider(),
65 cloud_policy_subsystem_->GetManagedPolicyProvider()));
66 recommended_cloud_provider_.reset(new MergingPolicyProvider(
67 browser_connector->GetRecommendedCloudProvider(),
68 cloud_policy_subsystem_->GetRecommendedPolicyProvider()));
69 }
70 }
71
~ProfilePolicyConnector()72 ProfilePolicyConnector::~ProfilePolicyConnector() {
73 managed_cloud_provider_.reset();
74 recommended_cloud_provider_.reset();
75 cloud_policy_subsystem_.reset();
76 identity_strategy_.reset();
77 }
78
Initialize()79 void ProfilePolicyConnector::Initialize() {
80 // TODO(jkummerow, mnissler): Move this out of the browser startup path.
81 if (cloud_policy_subsystem_.get()) {
82 cloud_policy_subsystem_->Initialize(profile_->GetPrefs(),
83 profile_->GetRequestContext());
84 }
85 }
86
Shutdown()87 void ProfilePolicyConnector::Shutdown() {
88 if (cloud_policy_subsystem_.get())
89 cloud_policy_subsystem_->Shutdown();
90 }
91
92 ConfigurationPolicyProvider*
GetManagedCloudProvider()93 ProfilePolicyConnector::GetManagedCloudProvider() {
94 return managed_cloud_provider_.get();
95 }
96
97 ConfigurationPolicyProvider*
GetRecommendedCloudProvider()98 ProfilePolicyConnector::GetRecommendedCloudProvider() {
99 return recommended_cloud_provider_.get();
100 }
101
MergingPolicyProvider(ConfigurationPolicyProvider * browser_policy_provider,ConfigurationPolicyProvider * profile_policy_provider)102 MergingPolicyProvider::MergingPolicyProvider(
103 ConfigurationPolicyProvider* browser_policy_provider,
104 ConfigurationPolicyProvider* profile_policy_provider)
105 : ConfigurationPolicyProvider(
106 ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList()),
107 browser_policy_provider_(browser_policy_provider),
108 profile_policy_provider_(profile_policy_provider),
109 browser_registrar_(new ConfigurationPolicyObserverRegistrar()),
110 profile_registrar_(new ConfigurationPolicyObserverRegistrar()) {
111 if (browser_policy_provider_)
112 browser_registrar_->Init(browser_policy_provider_, this);
113 if (profile_policy_provider_)
114 profile_registrar_->Init(profile_policy_provider_, this);
115 }
116
~MergingPolicyProvider()117 MergingPolicyProvider::~MergingPolicyProvider() {
118 if (browser_policy_provider_ || profile_policy_provider_) {
119 FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer,
120 observer_list_, OnProviderGoingAway());
121 }
122 }
123
Provide(ConfigurationPolicyStoreInterface * store)124 bool MergingPolicyProvider::Provide(ConfigurationPolicyStoreInterface* store) {
125 // First, apply the profile policies and observe if interesting policies
126 // have been applied.
127 ObservingPolicyStoreInterface observe(store);
128 bool rv = true;
129 if (profile_policy_provider_)
130 rv = profile_policy_provider_->Provide(&observe);
131
132 // Now apply policies from the browser provider, if they were not applied
133 // by the profile provider.
134 // Currently, these include only the proxy settings.
135 if (browser_policy_provider_) {
136 FilteringPolicyStoreInterface filter(store,
137 !observe.IsProxyPolicyApplied());
138 rv = rv && browser_policy_provider_->Provide(&filter);
139 }
140
141 return rv;
142 }
143
AddObserver(ConfigurationPolicyProvider::Observer * observer)144 void MergingPolicyProvider::AddObserver(
145 ConfigurationPolicyProvider::Observer* observer) {
146 observer_list_.AddObserver(observer);
147 }
148
RemoveObserver(ConfigurationPolicyProvider::Observer * observer)149 void MergingPolicyProvider::RemoveObserver(
150 ConfigurationPolicyProvider::Observer* observer) {
151 observer_list_.RemoveObserver(observer);
152 }
153
OnUpdatePolicy()154 void MergingPolicyProvider::OnUpdatePolicy() {
155 FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer,
156 observer_list_, OnUpdatePolicy());
157 }
158
OnProviderGoingAway()159 void MergingPolicyProvider::OnProviderGoingAway() {
160 if (browser_policy_provider_ || profile_policy_provider_) {
161 FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer,
162 observer_list_, OnProviderGoingAway());
163 browser_registrar_.reset();
164 profile_registrar_.reset();
165 browser_policy_provider_ = NULL;
166 profile_policy_provider_ = NULL;
167 }
168 }
169
170 } // namespace policy
171