configuration_policy_pref_store.cc revision 72a454cd3513ac24fbdd0e0cb9ad70b86a99b801
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 "chrome/browser/policy/configuration_policy_pref_store.h" 6 7#include <map> 8#include <set> 9#include <string> 10#include <vector> 11 12#include "base/command_line.h" 13#include "base/lazy_instance.h" 14#include "base/logging.h" 15#include "base/stl_util-inl.h" 16#include "base/string16.h" 17#include "base/string_util.h" 18#include "base/utf_string_conversions.h" 19#include "base/values.h" 20#include "chrome/browser/browser_process.h" 21#include "chrome/browser/policy/configuration_policy_provider.h" 22#include "chrome/browser/policy/configuration_policy_provider_keeper.h" 23#include "chrome/browser/policy/device_management_policy_provider.h" 24#include "chrome/browser/policy/profile_policy_context.h" 25#include "chrome/browser/prefs/pref_value_map.h" 26#include "chrome/browser/prefs/proxy_config_dictionary.h" 27#include "chrome/browser/profiles/profile.h" 28#include "chrome/browser/search_engines/search_terms_data.h" 29#include "chrome/browser/search_engines/template_url.h" 30#include "chrome/common/notification_service.h" 31#include "chrome/common/pref_names.h" 32#include "policy/policy_constants.h" 33 34namespace policy { 35 36// Accepts policy settings from a ConfigurationPolicyProvider, converts them 37// to preferences and caches the result. 38class ConfigurationPolicyPrefKeeper 39 : private ConfigurationPolicyStoreInterface { 40 public: 41 explicit ConfigurationPolicyPrefKeeper(ConfigurationPolicyProvider* provider); 42 virtual ~ConfigurationPolicyPrefKeeper(); 43 44 // Get a preference value. 45 PrefStore::ReadResult GetValue(const std::string& key, Value** result) const; 46 47 // Compute the set of preference names that are different in |keeper|. This 48 // includes preferences that are missing in either one. 49 void GetDifferingPrefPaths(const ConfigurationPolicyPrefKeeper* other, 50 std::vector<std::string>* differing_prefs) const; 51 52 private: 53 // ConfigurationPolicyStore methods: 54 virtual void Apply(ConfigurationPolicyType setting, Value* value); 55 56 // Policies that map to a single preference are handled 57 // by an automated converter. Each one of these policies 58 // has an entry in |simple_policy_map_| with the following type. 59 struct PolicyToPreferenceMapEntry { 60 Value::ValueType value_type; 61 ConfigurationPolicyType policy_type; 62 const char* preference_path; // A DictionaryValue path, not a file path. 63 }; 64 65 // Returns the map entry that corresponds to |policy| in the map. 66 const PolicyToPreferenceMapEntry* FindPolicyInMap( 67 ConfigurationPolicyType policy, 68 const PolicyToPreferenceMapEntry* map, 69 int size) const; 70 71 // Remove the preferences found in the map from |prefs_|. Returns true if any 72 // such preferences were found and removed. 73 bool RemovePreferencesOfMap(const PolicyToPreferenceMapEntry* map, 74 int table_size); 75 76 bool ApplyPolicyFromMap(ConfigurationPolicyType policy, 77 Value* value, 78 const PolicyToPreferenceMapEntry* map, 79 int size); 80 81 // Processes proxy-specific policies. Returns true if the specified policy 82 // is a proxy-related policy. ApplyProxyPolicy assumes the ownership 83 // of |value| in the case that the policy is proxy-specific. 84 bool ApplyProxyPolicy(ConfigurationPolicyType policy, Value* value); 85 86 // Handles sync-related policies. Returns true if the policy was handled. 87 // Assumes ownership of |value| in that case. 88 bool ApplySyncPolicy(ConfigurationPolicyType policy, Value* value); 89 90 // Handles policies that affect AutoFill. Returns true if the policy was 91 // handled and assumes ownership of |value| in that case. 92 bool ApplyAutoFillPolicy(ConfigurationPolicyType policy, Value* value); 93 94 // Make sure that the |path| if present in |prefs_|. If not, set it to 95 // a blank string. 96 void EnsureStringPrefExists(const std::string& path); 97 98 // If the required entries for default search are specified and valid, 99 // finalizes the policy-specified configuration by initializing the 100 // unspecified map entries. Otherwise wipes all default search related 101 // map entries from |prefs_|. 102 void FinalizeDefaultSearchPolicySettings(); 103 104 // If the required entries for the proxy settings are specified and valid, 105 // finalizes the policy-specified configuration by initializing the 106 // respective values in |prefs_|. 107 void FinalizeProxyPolicySettings(); 108 109 // Returns true if the policy values stored in proxy_* represent a valid proxy 110 // configuration, including the case in which there is no configuration at 111 // all. 112 bool CheckProxySettings(); 113 114 // Assumes CheckProxySettings returns true and applies the values stored 115 // in proxy_*. 116 void ApplyProxySettings(); 117 118 bool HasProxyPolicy(ConfigurationPolicyType policy) const; 119 120 // Temporary cache that stores values until FinalizeProxyPolicySettings() 121 // is called. 122 std::map<ConfigurationPolicyType, Value*> proxy_policies_; 123 124 // Set to false until the first proxy-relevant policy is applied. At that 125 // time, default values are provided for all proxy-relevant prefs 126 // to override any values set from stores with a lower priority. 127 bool lower_priority_proxy_settings_overridden_; 128 129 // The following are used to track what proxy-relevant policy has been applied 130 // accross calls to Apply to provide a warning if a policy specifies a 131 // contradictory proxy configuration. |proxy_disabled_| is set to true if and 132 // only if the kPolicyNoProxyServer has been applied, 133 // |proxy_configuration_specified_| is set to true if and only if any other 134 // proxy policy other than kPolicyNoProxyServer has been applied. 135 bool proxy_disabled_; 136 bool proxy_configuration_specified_; 137 138 // Set to true if a the proxy mode policy has been set to force Chrome 139 // to use the system proxy. 140 bool use_system_proxy_; 141 142 PrefValueMap prefs_; 143 144 static const PolicyToPreferenceMapEntry kSimplePolicyMap[]; 145 static const PolicyToPreferenceMapEntry kProxyPolicyMap[]; 146 static const PolicyToPreferenceMapEntry kDefaultSearchPolicyMap[]; 147 148 DISALLOW_COPY_AND_ASSIGN(ConfigurationPolicyPrefKeeper); 149}; 150 151const ConfigurationPolicyPrefKeeper::PolicyToPreferenceMapEntry 152 ConfigurationPolicyPrefKeeper::kSimplePolicyMap[] = { 153 { Value::TYPE_STRING, kPolicyHomepageLocation, prefs::kHomePage }, 154 { Value::TYPE_BOOLEAN, kPolicyHomepageIsNewTabPage, 155 prefs::kHomePageIsNewTabPage }, 156 { Value::TYPE_INTEGER, kPolicyRestoreOnStartup, 157 prefs::kRestoreOnStartup}, 158 { Value::TYPE_LIST, kPolicyRestoreOnStartupURLs, 159 prefs::kURLsToRestoreOnStartup }, 160 { Value::TYPE_BOOLEAN, kPolicyAlternateErrorPagesEnabled, 161 prefs::kAlternateErrorPagesEnabled }, 162 { Value::TYPE_BOOLEAN, kPolicySearchSuggestEnabled, 163 prefs::kSearchSuggestEnabled }, 164 { Value::TYPE_BOOLEAN, kPolicyDnsPrefetchingEnabled, 165 prefs::kDnsPrefetchingEnabled }, 166 { Value::TYPE_BOOLEAN, kPolicyDisableSpdy, 167 prefs::kDisableSpdy }, 168 { Value::TYPE_BOOLEAN, kPolicySafeBrowsingEnabled, 169 prefs::kSafeBrowsingEnabled }, 170 { Value::TYPE_BOOLEAN, kPolicyPasswordManagerEnabled, 171 prefs::kPasswordManagerEnabled }, 172 { Value::TYPE_BOOLEAN, kPolicyPasswordManagerAllowShowPasswords, 173 prefs::kPasswordManagerAllowShowPasswords }, 174 { Value::TYPE_BOOLEAN, kPolicyPrintingEnabled, 175 prefs::kPrintingEnabled }, 176 { Value::TYPE_BOOLEAN, kPolicyMetricsReportingEnabled, 177 prefs::kMetricsReportingEnabled }, 178 { Value::TYPE_STRING, kPolicyApplicationLocaleValue, 179 prefs::kApplicationLocale}, 180 { Value::TYPE_LIST, kPolicyExtensionInstallWhitelist, 181 prefs::kExtensionInstallAllowList}, 182 { Value::TYPE_LIST, kPolicyExtensionInstallBlacklist, 183 prefs::kExtensionInstallDenyList}, 184 { Value::TYPE_LIST, kPolicyExtensionInstallForcelist, 185 prefs::kExtensionInstallForceList}, 186 { Value::TYPE_LIST, kPolicyDisabledPlugins, 187 prefs::kPluginsPluginsBlacklist}, 188 { Value::TYPE_BOOLEAN, kPolicyShowHomeButton, 189 prefs::kShowHomeButton }, 190 { Value::TYPE_BOOLEAN, kPolicyJavascriptEnabled, 191 prefs::kWebKitJavascriptEnabled }, 192 { Value::TYPE_BOOLEAN, kPolicyIncognitoEnabled, 193 prefs::kIncognitoEnabled }, 194 { Value::TYPE_BOOLEAN, kPolicySavingBrowserHistoryDisabled, 195 prefs::kSavingBrowserHistoryDisabled }, 196 { Value::TYPE_BOOLEAN, kPolicyDeveloperToolsDisabled, 197 prefs::kDevToolsDisabled }, 198 { Value::TYPE_BOOLEAN, kPolicyBlockThirdPartyCookies, 199 prefs::kBlockThirdPartyCookies }, 200 { Value::TYPE_INTEGER, kPolicyDefaultCookiesSetting, 201 prefs::kManagedDefaultCookiesSetting }, 202 { Value::TYPE_INTEGER, kPolicyDefaultImagesSetting, 203 prefs::kManagedDefaultImagesSetting }, 204 { Value::TYPE_INTEGER, kPolicyDefaultJavaScriptSetting, 205 prefs::kManagedDefaultJavaScriptSetting }, 206 { Value::TYPE_INTEGER, kPolicyDefaultPluginsSetting, 207 prefs::kManagedDefaultPluginsSetting }, 208 { Value::TYPE_INTEGER, kPolicyDefaultPopupsSetting, 209 prefs::kManagedDefaultPopupsSetting }, 210 { Value::TYPE_INTEGER, kPolicyDefaultNotificationSetting, 211 prefs::kDesktopNotificationDefaultContentSetting }, 212 { Value::TYPE_INTEGER, kPolicyDefaultGeolocationSetting, 213 prefs::kGeolocationDefaultContentSetting }, 214 { Value::TYPE_STRING, kPolicyAuthSchemes, 215 prefs::kAuthSchemes }, 216 { Value::TYPE_BOOLEAN, kPolicyDisableAuthNegotiateCnameLookup, 217 prefs::kDisableAuthNegotiateCnameLookup }, 218 { Value::TYPE_BOOLEAN, kPolicyEnableAuthNegotiatePort, 219 prefs::kEnableAuthNegotiatePort }, 220 { Value::TYPE_STRING, kPolicyAuthServerWhitelist, 221 prefs::kAuthServerWhitelist }, 222 { Value::TYPE_STRING, kPolicyAuthNegotiateDelegateWhitelist, 223 prefs::kAuthNegotiateDelegateWhitelist }, 224 { Value::TYPE_STRING, kPolicyGSSAPILibraryName, 225 prefs::kGSSAPILibraryName }, 226 { Value::TYPE_BOOLEAN, kPolicyDisable3DAPIs, 227 prefs::kDisable3DAPIs }, 228 { Value::TYPE_INTEGER, kPolicyPolicyRefreshRate, 229 prefs::kPolicyRefreshRate }, 230 { Value::TYPE_BOOLEAN, kPolicyInstantEnabled, prefs::kInstantEnabled }, 231 { Value::TYPE_BOOLEAN, kPolicyDefaultBrowserSettingEnabled, 232 prefs::kDefaultBrowserSettingEnabled }, 233 { Value::TYPE_BOOLEAN, kPolicyCloudPrintProxyEnabled, 234 prefs::kCloudPrintProxyEnabled }, 235 236#if defined(OS_CHROMEOS) 237 { Value::TYPE_BOOLEAN, kPolicyChromeOsLockOnIdleSuspend, 238 prefs::kEnableScreenLock }, 239#endif 240}; 241 242const ConfigurationPolicyPrefKeeper::PolicyToPreferenceMapEntry 243 ConfigurationPolicyPrefKeeper::kDefaultSearchPolicyMap[] = { 244 { Value::TYPE_BOOLEAN, kPolicyDefaultSearchProviderEnabled, 245 prefs::kDefaultSearchProviderEnabled }, 246 { Value::TYPE_STRING, kPolicyDefaultSearchProviderName, 247 prefs::kDefaultSearchProviderName }, 248 { Value::TYPE_STRING, kPolicyDefaultSearchProviderKeyword, 249 prefs::kDefaultSearchProviderKeyword }, 250 { Value::TYPE_STRING, kPolicyDefaultSearchProviderSearchURL, 251 prefs::kDefaultSearchProviderSearchURL }, 252 { Value::TYPE_STRING, kPolicyDefaultSearchProviderSuggestURL, 253 prefs::kDefaultSearchProviderSuggestURL }, 254 { Value::TYPE_STRING, kPolicyDefaultSearchProviderIconURL, 255 prefs::kDefaultSearchProviderIconURL }, 256 { Value::TYPE_STRING, kPolicyDefaultSearchProviderEncodings, 257 prefs::kDefaultSearchProviderEncodings }, 258}; 259 260ConfigurationPolicyPrefKeeper::ConfigurationPolicyPrefKeeper( 261 ConfigurationPolicyProvider* provider) 262 : lower_priority_proxy_settings_overridden_(false), 263 proxy_disabled_(false), 264 proxy_configuration_specified_(false), 265 use_system_proxy_(false) { 266 if (!provider->Provide(this)) 267 LOG(WARNING) << "Failed to get policy from provider."; 268 FinalizeProxyPolicySettings(); 269 FinalizeDefaultSearchPolicySettings(); 270} 271 272ConfigurationPolicyPrefKeeper::~ConfigurationPolicyPrefKeeper() { 273 DCHECK(proxy_policies_.empty()); 274} 275 276PrefStore::ReadResult 277ConfigurationPolicyPrefKeeper::GetValue(const std::string& key, 278 Value** result) const { 279 Value* stored_value = NULL; 280 if (!prefs_.GetValue(key, &stored_value)) 281 return PrefStore::READ_NO_VALUE; 282 283 // Check whether there's a default value, which indicates READ_USE_DEFAULT 284 // should be returned. 285 if (stored_value->IsType(Value::TYPE_NULL)) 286 return PrefStore::READ_USE_DEFAULT; 287 288 *result = stored_value; 289 return PrefStore::READ_OK; 290} 291 292void ConfigurationPolicyPrefKeeper::GetDifferingPrefPaths( 293 const ConfigurationPolicyPrefKeeper* other, 294 std::vector<std::string>* differing_prefs) const { 295 prefs_.GetDifferingKeys(&other->prefs_, differing_prefs); 296} 297 298void ConfigurationPolicyPrefKeeper::Apply(ConfigurationPolicyType policy, 299 Value* value) { 300 if (ApplyProxyPolicy(policy, value)) 301 return; 302 303 if (ApplySyncPolicy(policy, value)) 304 return; 305 306 if (ApplyAutoFillPolicy(policy, value)) 307 return; 308 309 if (ApplyPolicyFromMap(policy, value, kDefaultSearchPolicyMap, 310 arraysize(kDefaultSearchPolicyMap))) 311 return; 312 313 if (ApplyPolicyFromMap(policy, value, kSimplePolicyMap, 314 arraysize(kSimplePolicyMap))) 315 return; 316 317 // Other policy implementations go here. 318 NOTIMPLEMENTED(); 319 delete value; 320} 321 322const ConfigurationPolicyPrefKeeper::PolicyToPreferenceMapEntry* 323ConfigurationPolicyPrefKeeper::FindPolicyInMap( 324 ConfigurationPolicyType policy, 325 const PolicyToPreferenceMapEntry* map, 326 int table_size) const { 327 for (int i = 0; i < table_size; ++i) { 328 if (map[i].policy_type == policy) 329 return map + i; 330 } 331 return NULL; 332} 333 334bool ConfigurationPolicyPrefKeeper::RemovePreferencesOfMap( 335 const PolicyToPreferenceMapEntry* map, int table_size) { 336 bool found_any = false; 337 for (int i = 0; i < table_size; ++i) { 338 if (prefs_.RemoveValue(map[i].preference_path)) 339 found_any = true; 340 } 341 return found_any; 342} 343 344bool ConfigurationPolicyPrefKeeper::ApplyPolicyFromMap( 345 ConfigurationPolicyType policy, 346 Value* value, 347 const PolicyToPreferenceMapEntry* map, 348 int size) { 349 for (int current = 0; current < size; ++current) { 350 if (map[current].policy_type == policy) { 351 DCHECK_EQ(map[current].value_type, value->GetType()) 352 << "mismatch in provided and expected policy value for preferences" 353 << map[current].preference_path << ". expected = " 354 << map[current].value_type << ", actual = "<< value->GetType(); 355 prefs_.SetValue(map[current].preference_path, value); 356 return true; 357 } 358 } 359 return false; 360} 361 362bool ConfigurationPolicyPrefKeeper::ApplyProxyPolicy( 363 ConfigurationPolicyType policy, 364 Value* value) { 365 // We only collect the values until we have sufficient information when 366 // FinalizeProxyPolicySettings() is called to determine whether the presented 367 // values were correct and apply them in that case. 368 if (policy == kPolicyProxyMode || 369 policy == kPolicyProxyServerMode || 370 policy == kPolicyProxyServer || 371 policy == kPolicyProxyPacUrl || 372 policy == kPolicyProxyBypassList) { 373 delete proxy_policies_[policy]; 374 proxy_policies_[policy] = value; 375 return true; 376 } 377 // We are not interested in this policy. 378 return false; 379} 380 381bool ConfigurationPolicyPrefKeeper::ApplySyncPolicy( 382 ConfigurationPolicyType policy, Value* value) { 383 if (policy == kPolicySyncDisabled) { 384 bool disable_sync; 385 if (value->GetAsBoolean(&disable_sync) && disable_sync) 386 prefs_.SetValue(prefs::kSyncManaged, value); 387 else 388 delete value; 389 return true; 390 } 391 return false; 392} 393 394bool ConfigurationPolicyPrefKeeper::ApplyAutoFillPolicy( 395 ConfigurationPolicyType policy, Value* value) { 396 if (policy == kPolicyAutoFillEnabled) { 397 bool auto_fill_enabled; 398 if (value->GetAsBoolean(&auto_fill_enabled) && !auto_fill_enabled) 399 prefs_.SetValue(prefs::kAutoFillEnabled, 400 Value::CreateBooleanValue(false)); 401 delete value; 402 return true; 403 } 404 return false; 405} 406 407void ConfigurationPolicyPrefKeeper::EnsureStringPrefExists( 408 const std::string& path) { 409 std::string value; 410 if (!prefs_.GetString(path, &value)) 411 prefs_.SetString(path, value); 412} 413 414namespace { 415 416// Implementation of SearchTermsData just for validation. 417class SearchTermsDataForValidation : public SearchTermsData { 418 public: 419 SearchTermsDataForValidation() {} 420 421 // Implementation of SearchTermsData. 422 virtual std::string GoogleBaseURLValue() const { 423 return "http://www.google.com/"; 424 } 425 virtual std::string GetApplicationLocale() const { 426 return "en"; 427 } 428#if defined(OS_WIN) && defined(GOOGLE_CHROME_BUILD) 429 virtual string16 GetRlzParameterValue() const { 430 return string16(); 431 } 432#endif 433 private: 434 DISALLOW_COPY_AND_ASSIGN(SearchTermsDataForValidation); 435}; 436 437} // namespace 438 439void ConfigurationPolicyPrefKeeper::FinalizeDefaultSearchPolicySettings() { 440 bool enabled = true; 441 if (prefs_.GetBoolean(prefs::kDefaultSearchProviderEnabled, &enabled) && 442 !enabled) { 443 // If default search is disabled, we ignore the other fields. 444 prefs_.SetString(prefs::kDefaultSearchProviderName, std::string()); 445 prefs_.SetString(prefs::kDefaultSearchProviderSearchURL, std::string()); 446 prefs_.SetString(prefs::kDefaultSearchProviderSuggestURL, std::string()); 447 prefs_.SetString(prefs::kDefaultSearchProviderIconURL, std::string()); 448 prefs_.SetString(prefs::kDefaultSearchProviderEncodings, std::string()); 449 prefs_.SetString(prefs::kDefaultSearchProviderKeyword, std::string()); 450 prefs_.SetString(prefs::kDefaultSearchProviderInstantURL, std::string()); 451 return; 452 } 453 std::string search_url; 454 // The search URL is required. 455 if (prefs_.GetString(prefs::kDefaultSearchProviderSearchURL, &search_url) && 456 !search_url.empty()) { 457 SearchTermsDataForValidation search_terms_data; 458 const TemplateURLRef search_url_ref(search_url, 0, 0); 459 // It must support replacement (which implies it is valid). 460 if (search_url_ref.SupportsReplacementUsingTermsData(search_terms_data)) { 461 // The other entries are optional. Just make sure that they are all 462 // specified via policy, so that we don't use regular prefs. 463 EnsureStringPrefExists(prefs::kDefaultSearchProviderSuggestURL); 464 EnsureStringPrefExists(prefs::kDefaultSearchProviderIconURL); 465 EnsureStringPrefExists(prefs::kDefaultSearchProviderEncodings); 466 EnsureStringPrefExists(prefs::kDefaultSearchProviderKeyword); 467 EnsureStringPrefExists(prefs::kDefaultSearchProviderInstantURL); 468 469 // For the name, default to the host if not specified. 470 std::string name; 471 if (!prefs_.GetString(prefs::kDefaultSearchProviderName, &name) || 472 name.empty()) 473 prefs_.SetString(prefs::kDefaultSearchProviderName, 474 GURL(search_url).host()); 475 476 // And clear the IDs since these are not specified via policy. 477 prefs_.SetString(prefs::kDefaultSearchProviderID, std::string()); 478 prefs_.SetString(prefs::kDefaultSearchProviderPrepopulateID, 479 std::string()); 480 return; 481 } 482 } 483 // Required entries are not there. Remove any related entries. 484 RemovePreferencesOfMap(kDefaultSearchPolicyMap, 485 arraysize(kDefaultSearchPolicyMap)); 486} 487 488void ConfigurationPolicyPrefKeeper::FinalizeProxyPolicySettings() { 489 if (CheckProxySettings()) 490 ApplyProxySettings(); 491 492 STLDeleteContainerPairSecondPointers(proxy_policies_.begin(), 493 proxy_policies_.end()); 494 proxy_policies_.clear(); 495} 496 497bool ConfigurationPolicyPrefKeeper::CheckProxySettings() { 498 bool mode = HasProxyPolicy(kPolicyProxyMode); 499 bool server_mode = HasProxyPolicy(kPolicyProxyServerMode); // deprecated 500 bool server = HasProxyPolicy(kPolicyProxyServer); 501 bool pac_url = HasProxyPolicy(kPolicyProxyPacUrl); 502 bool bypass_list = HasProxyPolicy(kPolicyProxyBypassList); 503 504 if ((server || pac_url || bypass_list) && !(mode || server_mode)) { 505 LOG(WARNING) << "A centrally-administered policy defines proxy setting" 506 << " details without setting a proxy mode."; 507 return false; 508 } 509 510 // If there's a server mode, convert it into a mode. 511 std::string mode_value; 512 if (mode) { 513 if (server_mode) 514 LOG(WARNING) << "Both ProxyMode and ProxyServerMode policies defined, " 515 << "ignoring ProxyMode."; 516 if (!proxy_policies_[kPolicyProxyMode]->GetAsString(&mode_value)) { 517 LOG(WARNING) << "Invalid ProxyMode value."; 518 return false; 519 } 520 } else if (server_mode) { 521 int server_mode_value; 522 if (!proxy_policies_[kPolicyProxyServerMode]->GetAsInteger( 523 &server_mode_value)) { 524 LOG(WARNING) << "Invalid ProxyServerMode value."; 525 return false; 526 } 527 528 switch (server_mode_value) { 529 case kPolicyNoProxyServerMode: 530 mode_value = ProxyPrefs::kDirectProxyModeName; 531 break; 532 case kPolicyAutoDetectProxyServerMode: 533 mode_value = ProxyPrefs::kAutoDetectProxyModeName; 534 break; 535 case kPolicyManuallyConfiguredProxyServerMode: 536 if (server && pac_url) { 537 LOG(WARNING) << "A centrally-administered policy dictates that" 538 << " both fixed proxy servers and a .pac url. should" 539 << " be used for proxy configuration."; 540 return false; 541 } 542 if (!server && !pac_url) { 543 LOG(WARNING) << "A centrally-administered policy dictates that the" 544 << " proxy settings should use either fixed proxy" 545 << " servers or a .pac url, but specifies neither."; 546 return false; 547 } 548 if (pac_url) 549 mode_value = ProxyPrefs::kPacScriptProxyModeName; 550 else 551 mode_value = ProxyPrefs::kFixedServersProxyModeName; 552 break; 553 case kPolicyUseSystemProxyServerMode: 554 mode_value = ProxyPrefs::kSystemProxyModeName; 555 break; 556 default: 557 LOG(WARNING) << "Invalid proxy mode " << server_mode_value; 558 return false; 559 } 560 } 561 562 // If neither ProxyMode nor ProxyServerMode are specified, mode_value will be 563 // empty and the proxy shouldn't be configured at all. 564 if (mode_value.empty()) 565 return true; 566 567 if (mode_value == ProxyPrefs::kDirectProxyModeName) { 568 if (server || pac_url || bypass_list) { 569 LOG(WARNING) << "A centrally-administered policy disables the use of" 570 << " a proxy but also specifies an explicit proxy" 571 << " configuration."; 572 return false; 573 } 574 } else if (mode_value == ProxyPrefs::kAutoDetectProxyModeName) { 575 if (server || bypass_list || pac_url) { 576 LOG(WARNING) << "A centrally-administered policy dictates that a proxy" 577 << " shall be auto configured but specifies fixed proxy" 578 << " servers, a by-pass list or a .pac script URL."; 579 return false; 580 } 581 } else if (mode_value == ProxyPrefs::kPacScriptProxyModeName) { 582 if (server || bypass_list) { 583 LOG(WARNING) << "A centrally-administered policy dictates that a .pac" 584 << " script URL should be used for proxy configuration but" 585 << " also specifies policies required only for fixed" 586 << " proxy servers."; 587 return false; 588 } 589 } else if (mode_value == ProxyPrefs::kFixedServersProxyModeName) { 590 if (pac_url) { 591 LOG(WARNING) << "A centrally-administered policy dictates that" 592 << " fixed proxy servers should be used but also" 593 << " specifies a .pac script URL."; 594 return false; 595 } 596 } else if (mode_value == ProxyPrefs::kSystemProxyModeName) { 597 if (server || pac_url || bypass_list) { 598 LOG(WARNING) << "A centrally-administered policy dictates that the" 599 << " system proxy settings should be used but also " 600 << " specifies an explicit proxy configuration."; 601 return false; 602 } 603 } else { 604 LOG(WARNING) << "Invalid proxy mode " << mode_value; 605 return false; 606 } 607 return true; 608} 609 610void ConfigurationPolicyPrefKeeper::ApplyProxySettings() { 611 ProxyPrefs::ProxyMode mode; 612 if (HasProxyPolicy(kPolicyProxyMode)) { 613 std::string string_mode; 614 CHECK(proxy_policies_[kPolicyProxyMode]->GetAsString(&string_mode)); 615 if (!ProxyPrefs::StringToProxyMode(string_mode, &mode)) { 616 LOG(WARNING) << "A centrally-administered policy specifies a value for" 617 << "the ProxyMode policy that isn't recognized."; 618 return; 619 } 620 } else if (HasProxyPolicy(kPolicyProxyServerMode)) { 621 int int_mode = 0; 622 CHECK(proxy_policies_[kPolicyProxyServerMode]->GetAsInteger(&int_mode)); 623 switch (int_mode) { 624 case kPolicyNoProxyServerMode: 625 mode = ProxyPrefs::MODE_DIRECT; 626 break; 627 case kPolicyAutoDetectProxyServerMode: 628 mode = ProxyPrefs::MODE_AUTO_DETECT; 629 break; 630 case kPolicyManuallyConfiguredProxyServerMode: 631 mode = ProxyPrefs::MODE_FIXED_SERVERS; 632 if (HasProxyPolicy(kPolicyProxyPacUrl)) 633 mode = ProxyPrefs::MODE_PAC_SCRIPT; 634 break; 635 case kPolicyUseSystemProxyServerMode: 636 mode = ProxyPrefs::MODE_SYSTEM; 637 break; 638 default: 639 mode = ProxyPrefs::MODE_DIRECT; 640 NOTREACHED(); 641 } 642 } else { 643 return; 644 } 645 switch (mode) { 646 case ProxyPrefs::MODE_DIRECT: 647 prefs_.SetValue(prefs::kProxy, ProxyConfigDictionary::CreateDirect()); 648 break; 649 case ProxyPrefs::MODE_AUTO_DETECT: 650 prefs_.SetValue(prefs::kProxy, ProxyConfigDictionary::CreateAutoDetect()); 651 break; 652 case ProxyPrefs::MODE_PAC_SCRIPT: { 653 std::string pac_url; 654 proxy_policies_[kPolicyProxyPacUrl]->GetAsString(&pac_url); 655 prefs_.SetValue(prefs::kProxy, 656 ProxyConfigDictionary::CreatePacScript(pac_url)); 657 break; 658 } 659 case ProxyPrefs::MODE_FIXED_SERVERS: { 660 std::string proxy_server; 661 proxy_policies_[kPolicyProxyServer]->GetAsString(&proxy_server); 662 std::string bypass_list; 663 if (HasProxyPolicy(kPolicyProxyBypassList)) 664 proxy_policies_[kPolicyProxyBypassList]->GetAsString(&bypass_list); 665 prefs_.SetValue(prefs::kProxy, 666 ProxyConfigDictionary::CreateFixedServers(proxy_server, 667 bypass_list)); 668 break; 669 } 670 case ProxyPrefs::MODE_SYSTEM: 671 prefs_.SetValue(prefs::kProxy, 672 ProxyConfigDictionary::CreateSystem()); 673 break; 674 case ProxyPrefs::kModeCount: 675 NOTREACHED(); 676 } 677} 678 679bool ConfigurationPolicyPrefKeeper::HasProxyPolicy( 680 ConfigurationPolicyType policy) const { 681 std::map<ConfigurationPolicyType, Value*>::const_iterator iter; 682 iter = proxy_policies_.find(policy); 683 return iter != proxy_policies_.end() && 684 iter->second && !iter->second->IsType(Value::TYPE_NULL); 685} 686 687ConfigurationPolicyPrefStore::ConfigurationPolicyPrefStore( 688 ConfigurationPolicyProvider* provider) 689 : provider_(provider), 690 initialization_complete_(false) { 691 if (provider_) { 692 // Read initial policy. 693 policy_keeper_.reset(new ConfigurationPolicyPrefKeeper(provider)); 694 registrar_.Init(provider_, this); 695 initialization_complete_ = provider->IsInitializationComplete(); 696 } else { 697 initialization_complete_ = true; 698 } 699} 700 701ConfigurationPolicyPrefStore::~ConfigurationPolicyPrefStore() { 702} 703 704void ConfigurationPolicyPrefStore::AddObserver(PrefStore::Observer* observer) { 705 observers_.AddObserver(observer); 706} 707 708void ConfigurationPolicyPrefStore::RemoveObserver( 709 PrefStore::Observer* observer) { 710 observers_.RemoveObserver(observer); 711} 712 713bool ConfigurationPolicyPrefStore::IsInitializationComplete() const { 714 return initialization_complete_; 715} 716 717PrefStore::ReadResult 718ConfigurationPolicyPrefStore::GetValue(const std::string& key, 719 Value** value) const { 720 if (policy_keeper_.get()) 721 return policy_keeper_->GetValue(key, value); 722 723 return PrefStore::READ_NO_VALUE; 724} 725 726void ConfigurationPolicyPrefStore::OnUpdatePolicy() { 727 Refresh(); 728} 729 730void ConfigurationPolicyPrefStore::OnProviderGoingAway() { 731 provider_ = NULL; 732} 733 734// static 735ConfigurationPolicyPrefStore* 736ConfigurationPolicyPrefStore::CreateManagedPlatformPolicyPrefStore() { 737 ConfigurationPolicyProviderKeeper* keeper = 738 g_browser_process->configuration_policy_provider_keeper(); 739 return new ConfigurationPolicyPrefStore(keeper->managed_platform_provider()); 740} 741 742// static 743ConfigurationPolicyPrefStore* 744ConfigurationPolicyPrefStore::CreateManagedCloudPolicyPrefStore( 745 Profile* profile) { 746 if (profile) { 747 return new ConfigurationPolicyPrefStore( 748 profile->GetPolicyContext()->GetDeviceManagementPolicyProvider()); 749 } 750 return new ConfigurationPolicyPrefStore(NULL); 751} 752 753// static 754ConfigurationPolicyPrefStore* 755ConfigurationPolicyPrefStore::CreateRecommendedPlatformPolicyPrefStore() { 756 ConfigurationPolicyProviderKeeper* keeper = 757 g_browser_process->configuration_policy_provider_keeper(); 758 return new ConfigurationPolicyPrefStore(keeper->recommended_provider()); 759} 760 761// static 762ConfigurationPolicyPrefStore* 763ConfigurationPolicyPrefStore::CreateRecommendedCloudPolicyPrefStore( 764 Profile* profile) { 765 return new ConfigurationPolicyPrefStore(NULL); 766} 767 768/* static */ 769const ConfigurationPolicyProvider::PolicyDefinitionList* 770ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList() { 771 static ConfigurationPolicyProvider::PolicyDefinitionList::Entry entries[] = { 772 { kPolicyHomepageLocation, Value::TYPE_STRING, key::kHomepageLocation }, 773 { kPolicyHomepageIsNewTabPage, Value::TYPE_BOOLEAN, 774 key::kHomepageIsNewTabPage }, 775 { kPolicyRestoreOnStartup, Value::TYPE_INTEGER, key::kRestoreOnStartup }, 776 { kPolicyRestoreOnStartupURLs, Value::TYPE_LIST, 777 key::kRestoreOnStartupURLs }, 778 { kPolicyDefaultSearchProviderEnabled, Value::TYPE_BOOLEAN, 779 key::kDefaultSearchProviderEnabled }, 780 { kPolicyDefaultSearchProviderName, Value::TYPE_STRING, 781 key::kDefaultSearchProviderName }, 782 { kPolicyDefaultSearchProviderKeyword, Value::TYPE_STRING, 783 key::kDefaultSearchProviderKeyword }, 784 { kPolicyDefaultSearchProviderSearchURL, Value::TYPE_STRING, 785 key::kDefaultSearchProviderSearchURL }, 786 { kPolicyDefaultSearchProviderSuggestURL, Value::TYPE_STRING, 787 key::kDefaultSearchProviderSuggestURL }, 788 { kPolicyDefaultSearchProviderInstantURL, Value::TYPE_STRING, 789 key::kDefaultSearchProviderInstantURL }, 790 { kPolicyDefaultSearchProviderIconURL, Value::TYPE_STRING, 791 key::kDefaultSearchProviderIconURL }, 792 { kPolicyDefaultSearchProviderEncodings, Value::TYPE_STRING, 793 key::kDefaultSearchProviderEncodings }, 794 { kPolicyProxyMode, Value::TYPE_STRING, key::kProxyMode }, 795 { kPolicyProxyServerMode, Value::TYPE_INTEGER, key::kProxyServerMode }, 796 { kPolicyProxyServer, Value::TYPE_STRING, key::kProxyServer }, 797 { kPolicyProxyPacUrl, Value::TYPE_STRING, key::kProxyPacUrl }, 798 { kPolicyProxyBypassList, Value::TYPE_STRING, key::kProxyBypassList }, 799 { kPolicyAlternateErrorPagesEnabled, Value::TYPE_BOOLEAN, 800 key::kAlternateErrorPagesEnabled }, 801 { kPolicySearchSuggestEnabled, Value::TYPE_BOOLEAN, 802 key::kSearchSuggestEnabled }, 803 { kPolicyDnsPrefetchingEnabled, Value::TYPE_BOOLEAN, 804 key::kDnsPrefetchingEnabled }, 805 { kPolicyDisableSpdy, Value::TYPE_BOOLEAN, key::kDisableSpdy }, 806 { kPolicySafeBrowsingEnabled, Value::TYPE_BOOLEAN, 807 key::kSafeBrowsingEnabled }, 808 { kPolicyMetricsReportingEnabled, Value::TYPE_BOOLEAN, 809 key::kMetricsReportingEnabled }, 810 { kPolicyPasswordManagerEnabled, Value::TYPE_BOOLEAN, 811 key::kPasswordManagerEnabled }, 812 { kPolicyPasswordManagerAllowShowPasswords, Value::TYPE_BOOLEAN, 813 key::kPasswordManagerAllowShowPasswords }, 814 { kPolicyAutoFillEnabled, Value::TYPE_BOOLEAN, key::kAutoFillEnabled }, 815 { kPolicyDisabledPlugins, Value::TYPE_LIST, key::kDisabledPlugins }, 816 { kPolicyApplicationLocaleValue, Value::TYPE_STRING, 817 key::kApplicationLocaleValue }, 818 { kPolicySyncDisabled, Value::TYPE_BOOLEAN, key::kSyncDisabled }, 819 { kPolicyExtensionInstallWhitelist, Value::TYPE_LIST, 820 key::kExtensionInstallWhitelist }, 821 { kPolicyExtensionInstallBlacklist, Value::TYPE_LIST, 822 key::kExtensionInstallBlacklist }, 823 { kPolicyExtensionInstallForcelist, Value::TYPE_LIST, 824 key::kExtensionInstallForcelist }, 825 { kPolicyShowHomeButton, Value::TYPE_BOOLEAN, key::kShowHomeButton }, 826 { kPolicyPrintingEnabled, Value::TYPE_BOOLEAN, key::kPrintingEnabled }, 827 { kPolicyJavascriptEnabled, Value::TYPE_BOOLEAN, key::kJavascriptEnabled }, 828 { kPolicyIncognitoEnabled, Value::TYPE_BOOLEAN, key::kIncognitoEnabled }, 829 { kPolicySavingBrowserHistoryDisabled, Value::TYPE_BOOLEAN, 830 key::kSavingBrowserHistoryDisabled }, 831 { kPolicyDeveloperToolsDisabled, Value::TYPE_BOOLEAN, 832 key::kDeveloperToolsDisabled }, 833 { kPolicyBlockThirdPartyCookies, Value::TYPE_BOOLEAN, 834 key::kBlockThirdPartyCookies }, 835 { kPolicyDefaultCookiesSetting, Value::TYPE_INTEGER, 836 key::kDefaultCookiesSetting }, 837 { kPolicyDefaultImagesSetting, Value::TYPE_INTEGER, 838 key::kDefaultImagesSetting }, 839 { kPolicyDefaultJavaScriptSetting, Value::TYPE_INTEGER, 840 key::kDefaultJavaScriptSetting }, 841 { kPolicyDefaultPluginsSetting, Value::TYPE_INTEGER, 842 key::kDefaultPluginsSetting }, 843 { kPolicyDefaultPopupsSetting, Value::TYPE_INTEGER, 844 key::kDefaultPopupsSetting }, 845 { kPolicyDefaultNotificationSetting, Value::TYPE_INTEGER, 846 key::kDefaultNotificationSetting }, 847 { kPolicyDefaultGeolocationSetting, Value::TYPE_INTEGER, 848 key::kDefaultGeolocationSetting }, 849 { kPolicyAuthSchemes, Value::TYPE_STRING, key::kAuthSchemes }, 850 { kPolicyDisableAuthNegotiateCnameLookup, Value::TYPE_BOOLEAN, 851 key::kDisableAuthNegotiateCnameLookup }, 852 { kPolicyEnableAuthNegotiatePort, Value::TYPE_BOOLEAN, 853 key::kEnableAuthNegotiatePort }, 854 { kPolicyAuthServerWhitelist, Value::TYPE_STRING, 855 key::kAuthServerWhitelist }, 856 { kPolicyAuthNegotiateDelegateWhitelist, Value::TYPE_STRING, 857 key::kAuthNegotiateDelegateWhitelist }, 858 { kPolicyGSSAPILibraryName, Value::TYPE_STRING, 859 key::kGSSAPILibraryName }, 860 { kPolicyDisable3DAPIs, Value::TYPE_BOOLEAN, 861 key::kDisable3DAPIs }, 862 { kPolicyPolicyRefreshRate, Value::TYPE_INTEGER, 863 key::kPolicyRefreshRate }, 864 { kPolicyInstantEnabled, Value::TYPE_BOOLEAN, key::kInstantEnabled }, 865 { kPolicyDefaultBrowserSettingEnabled, Value::TYPE_BOOLEAN, 866 key::kDefaultBrowserSettingEnabled }, 867 { kPolicyCloudPrintProxyEnabled, Value::TYPE_BOOLEAN, 868 key::kCloudPrintProxyEnabled }, 869 870#if defined(OS_CHROMEOS) 871 { kPolicyChromeOsLockOnIdleSuspend, Value::TYPE_BOOLEAN, 872 key::kChromeOsLockOnIdleSuspend }, 873#endif 874 }; 875 876 static ConfigurationPolicyProvider::PolicyDefinitionList policy_list = { 877 entries, 878 entries + arraysize(entries), 879 }; 880 return &policy_list; 881} 882 883void ConfigurationPolicyPrefStore::Refresh() { 884 if (!provider_) 885 return; 886 887 // Construct a new keeper, determine what changed and swap the keeper in. 888 scoped_ptr<ConfigurationPolicyPrefKeeper> new_keeper( 889 new ConfigurationPolicyPrefKeeper(provider_)); 890 std::vector<std::string> changed_prefs; 891 new_keeper->GetDifferingPrefPaths(policy_keeper_.get(), &changed_prefs); 892 policy_keeper_.reset(new_keeper.release()); 893 894 // Send out change notifications. 895 for (std::vector<std::string>::const_iterator pref(changed_prefs.begin()); 896 pref != changed_prefs.end(); 897 ++pref) { 898 FOR_EACH_OBSERVER(PrefStore::Observer, observers_, 899 OnPrefValueChanged(*pref)); 900 } 901 902 // Update the initialization flag. 903 if (!initialization_complete_ && 904 provider_->IsInitializationComplete()) { 905 initialization_complete_ = true; 906 FOR_EACH_OBSERVER(PrefStore::Observer, observers_, 907 OnInitializationCompleted()); 908 } 909} 910 911} // namespace policy 912