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 22namespace { 23 24const FilePath::CharType kPolicyDir[] = FILE_PATH_LITERAL("Device Management"); 25const FilePath::CharType kTokenCacheFile[] = FILE_PATH_LITERAL("Token"); 26const FilePath::CharType kPolicyCacheFile[] = FILE_PATH_LITERAL("Policy"); 27 28} // namespace 29 30namespace policy { 31 32ProfilePolicyConnector::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 72ProfilePolicyConnector::~ProfilePolicyConnector() { 73 managed_cloud_provider_.reset(); 74 recommended_cloud_provider_.reset(); 75 cloud_policy_subsystem_.reset(); 76 identity_strategy_.reset(); 77} 78 79void 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 87void ProfilePolicyConnector::Shutdown() { 88 if (cloud_policy_subsystem_.get()) 89 cloud_policy_subsystem_->Shutdown(); 90} 91 92ConfigurationPolicyProvider* 93 ProfilePolicyConnector::GetManagedCloudProvider() { 94 return managed_cloud_provider_.get(); 95} 96 97ConfigurationPolicyProvider* 98 ProfilePolicyConnector::GetRecommendedCloudProvider() { 99 return recommended_cloud_provider_.get(); 100} 101 102MergingPolicyProvider::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 117MergingPolicyProvider::~MergingPolicyProvider() { 118 if (browser_policy_provider_ || profile_policy_provider_) { 119 FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer, 120 observer_list_, OnProviderGoingAway()); 121 } 122} 123 124bool 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 144void MergingPolicyProvider::AddObserver( 145 ConfigurationPolicyProvider::Observer* observer) { 146 observer_list_.AddObserver(observer); 147} 148 149void MergingPolicyProvider::RemoveObserver( 150 ConfigurationPolicyProvider::Observer* observer) { 151 observer_list_.RemoveObserver(observer); 152} 153 154void MergingPolicyProvider::OnUpdatePolicy() { 155 FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer, 156 observer_list_, OnUpdatePolicy()); 157} 158 159void 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