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 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 72 ProfilePolicyConnector::~ProfilePolicyConnector() { 73 managed_cloud_provider_.reset(); 74 recommended_cloud_provider_.reset(); 75 cloud_policy_subsystem_.reset(); 76 identity_strategy_.reset(); 77 } 78 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 87 void ProfilePolicyConnector::Shutdown() { 88 if (cloud_policy_subsystem_.get()) 89 cloud_policy_subsystem_->Shutdown(); 90 } 91 92 ConfigurationPolicyProvider* 93 ProfilePolicyConnector::GetManagedCloudProvider() { 94 return managed_cloud_provider_.get(); 95 } 96 97 ConfigurationPolicyProvider* 98 ProfilePolicyConnector::GetRecommendedCloudProvider() { 99 return recommended_cloud_provider_.get(); 100 } 101 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 117 MergingPolicyProvider::~MergingPolicyProvider() { 118 if (browser_policy_provider_ || profile_policy_provider_) { 119 FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer, 120 observer_list_, OnProviderGoingAway()); 121 } 122 } 123 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 144 void MergingPolicyProvider::AddObserver( 145 ConfigurationPolicyProvider::Observer* observer) { 146 observer_list_.AddObserver(observer); 147 } 148 149 void MergingPolicyProvider::RemoveObserver( 150 ConfigurationPolicyProvider::Observer* observer) { 151 observer_list_.RemoveObserver(observer); 152 } 153 154 void MergingPolicyProvider::OnUpdatePolicy() { 155 FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer, 156 observer_list_, OnUpdatePolicy()); 157 } 158 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