Home | History | Annotate | Download | only in policy
      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