OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/policy/configuration_policy_pref_store.h" | 5 #include "chrome/browser/policy/configuration_policy_pref_store.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/lazy_instance.h" | 8 #include "base/lazy_instance.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/path_service.h" | 10 #include "base/path_service.h" |
11 #include "base/string16.h" | 11 #include "base/string16.h" |
12 #include "base/string_util.h" | 12 #include "base/string_util.h" |
13 #include "base/utf_string_conversions.h" | 13 #include "base/utf_string_conversions.h" |
14 #include "base/values.h" | 14 #include "base/values.h" |
| 15 #include "chrome/browser/prefs/proxy_prefs.h" |
15 #include "chrome/browser/profiles/profile.h" | 16 #include "chrome/browser/profiles/profile.h" |
16 #include "chrome/browser/policy/configuration_policy_provider.h" | 17 #include "chrome/browser/policy/configuration_policy_provider.h" |
17 #if defined(OS_WIN) | 18 #if defined(OS_WIN) |
18 #include "chrome/browser/policy/configuration_policy_provider_win.h" | 19 #include "chrome/browser/policy/configuration_policy_provider_win.h" |
19 #elif defined(OS_MACOSX) | 20 #elif defined(OS_MACOSX) |
20 #include "chrome/browser/policy/configuration_policy_provider_mac.h" | 21 #include "chrome/browser/policy/configuration_policy_provider_mac.h" |
21 #elif defined(OS_POSIX) | 22 #elif defined(OS_POSIX) |
22 #include "chrome/browser/policy/config_dir_policy_provider.h" | 23 #include "chrome/browser/policy/config_dir_policy_provider.h" |
23 #endif | 24 #endif |
24 #include "chrome/browser/policy/device_management_policy_provider.h" | 25 #include "chrome/browser/policy/device_management_policy_provider.h" |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
241 { kPolicyDefaultSearchProviderKeyword, Value::TYPE_STRING, | 242 { kPolicyDefaultSearchProviderKeyword, Value::TYPE_STRING, |
242 key::kDefaultSearchProviderKeyword }, | 243 key::kDefaultSearchProviderKeyword }, |
243 { kPolicyDefaultSearchProviderSearchURL, Value::TYPE_STRING, | 244 { kPolicyDefaultSearchProviderSearchURL, Value::TYPE_STRING, |
244 key::kDefaultSearchProviderSearchURL }, | 245 key::kDefaultSearchProviderSearchURL }, |
245 { kPolicyDefaultSearchProviderSuggestURL, Value::TYPE_STRING, | 246 { kPolicyDefaultSearchProviderSuggestURL, Value::TYPE_STRING, |
246 key::kDefaultSearchProviderSuggestURL }, | 247 key::kDefaultSearchProviderSuggestURL }, |
247 { kPolicyDefaultSearchProviderIconURL, Value::TYPE_STRING, | 248 { kPolicyDefaultSearchProviderIconURL, Value::TYPE_STRING, |
248 key::kDefaultSearchProviderIconURL }, | 249 key::kDefaultSearchProviderIconURL }, |
249 { kPolicyDefaultSearchProviderEncodings, Value::TYPE_STRING, | 250 { kPolicyDefaultSearchProviderEncodings, Value::TYPE_STRING, |
250 key::kDefaultSearchProviderEncodings }, | 251 key::kDefaultSearchProviderEncodings }, |
251 { kPolicyProxyServerMode, Value::TYPE_INTEGER, key::kProxyServerMode }, | 252 { kPolicyProxyMode, Value::TYPE_INTEGER, key::kProxyMode }, |
252 { kPolicyProxyServer, Value::TYPE_STRING, key::kProxyServer }, | 253 { kPolicyProxyServer, Value::TYPE_STRING, key::kProxyServer }, |
253 { kPolicyProxyPacUrl, Value::TYPE_STRING, key::kProxyPacUrl }, | 254 { kPolicyProxyPacUrl, Value::TYPE_STRING, key::kProxyPacUrl }, |
254 { kPolicyProxyBypassList, Value::TYPE_STRING, key::kProxyBypassList }, | 255 { kPolicyProxyBypassList, Value::TYPE_STRING, key::kProxyBypassList }, |
255 { kPolicyAlternateErrorPagesEnabled, Value::TYPE_BOOLEAN, | 256 { kPolicyAlternateErrorPagesEnabled, Value::TYPE_BOOLEAN, |
256 key::kAlternateErrorPagesEnabled }, | 257 key::kAlternateErrorPagesEnabled }, |
257 { kPolicySearchSuggestEnabled, Value::TYPE_BOOLEAN, | 258 { kPolicySearchSuggestEnabled, Value::TYPE_BOOLEAN, |
258 key::kSearchSuggestEnabled }, | 259 key::kSearchSuggestEnabled }, |
259 { kPolicyDnsPrefetchingEnabled, Value::TYPE_BOOLEAN, | 260 { kPolicyDnsPrefetchingEnabled, Value::TYPE_BOOLEAN, |
260 key::kDnsPrefetchingEnabled }, | 261 key::kDnsPrefetchingEnabled }, |
261 { kPolicyDisableSpdy, Value::TYPE_BOOLEAN, key::kDisableSpdy }, | 262 { kPolicyDisableSpdy, Value::TYPE_BOOLEAN, key::kDisableSpdy }, |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
324 static ConfigurationPolicyProvider::PolicyDefinitionList policy_list = { | 325 static ConfigurationPolicyProvider::PolicyDefinitionList policy_list = { |
325 entries, | 326 entries, |
326 entries + arraysize(entries), | 327 entries + arraysize(entries), |
327 }; | 328 }; |
328 return &policy_list; | 329 return &policy_list; |
329 } | 330 } |
330 | 331 |
331 ConfigurationPolicyPrefStore::ConfigurationPolicyPrefStore( | 332 ConfigurationPolicyPrefStore::ConfigurationPolicyPrefStore( |
332 ConfigurationPolicyProvider* provider) | 333 ConfigurationPolicyProvider* provider) |
333 : provider_(provider), | 334 : provider_(provider), |
334 prefs_(new DictionaryValue()), | 335 prefs_(new DictionaryValue()) { |
335 lower_priority_proxy_settings_overridden_(false), | |
336 proxy_disabled_(false), | |
337 proxy_configuration_specified_(false), | |
338 use_system_proxy_(false) { | |
339 if (!provider_->Provide(this)) | 336 if (!provider_->Provide(this)) |
340 LOG(WARNING) << "Failed to get policy from provider."; | 337 LOG(WARNING) << "Failed to get policy from provider."; |
| 338 FinalizeProxyPolicySettings(); |
341 FinalizeDefaultSearchPolicySettings(); | 339 FinalizeDefaultSearchPolicySettings(); |
342 } | 340 } |
343 | 341 |
344 ConfigurationPolicyPrefStore::~ConfigurationPolicyPrefStore() {} | 342 ConfigurationPolicyPrefStore::~ConfigurationPolicyPrefStore() {} |
345 | 343 |
346 PrefStore::ReadResult ConfigurationPolicyPrefStore::GetValue( | 344 PrefStore::ReadResult ConfigurationPolicyPrefStore::GetValue( |
347 const std::string& key, | 345 const std::string& key, |
348 Value** value) const { | 346 Value** value) const { |
349 Value* configured_value = NULL; | 347 Value* configured_value = NULL; |
350 if (!prefs_->Get(key, &configured_value) || !configured_value) | 348 if (!prefs_->Get(key, &configured_value) || !configured_value) |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 return new ConfigurationPolicyPrefStore(provider); | 406 return new ConfigurationPolicyPrefStore(provider); |
409 } | 407 } |
410 | 408 |
411 // static | 409 // static |
412 ConfigurationPolicyPrefStore* | 410 ConfigurationPolicyPrefStore* |
413 ConfigurationPolicyPrefStore::CreateRecommendedPolicyPrefStore() { | 411 ConfigurationPolicyPrefStore::CreateRecommendedPolicyPrefStore() { |
414 return new ConfigurationPolicyPrefStore( | 412 return new ConfigurationPolicyPrefStore( |
415 g_configuration_policy_provider_keeper.Get().recommended_provider()); | 413 g_configuration_policy_provider_keeper.Get().recommended_provider()); |
416 } | 414 } |
417 | 415 |
418 // static | |
419 void ConfigurationPolicyPrefStore::GetProxyPreferenceSet( | |
420 ProxyPreferenceSet* proxy_pref_set) { | |
421 proxy_pref_set->clear(); | |
422 for (size_t current = 0; current < arraysize(kProxyPolicyMap); ++current) { | |
423 proxy_pref_set->insert(kProxyPolicyMap[current].preference_path); | |
424 } | |
425 proxy_pref_set->insert(prefs::kNoProxyServer); | |
426 proxy_pref_set->insert(prefs::kProxyAutoDetect); | |
427 } | |
428 | |
429 const ConfigurationPolicyPrefStore::PolicyToPreferenceMapEntry* | 416 const ConfigurationPolicyPrefStore::PolicyToPreferenceMapEntry* |
430 ConfigurationPolicyPrefStore::FindPolicyInMap( | 417 ConfigurationPolicyPrefStore::FindPolicyInMap( |
431 ConfigurationPolicyType policy, | 418 ConfigurationPolicyType policy, |
432 const PolicyToPreferenceMapEntry* map, | 419 const PolicyToPreferenceMapEntry* map, |
433 int table_size) const { | 420 int table_size) const { |
434 for (int i = 0; i < table_size; ++i) { | 421 for (int i = 0; i < table_size; ++i) { |
435 if (map[i].policy_type == policy) | 422 if (map[i].policy_type == policy) |
436 return map + i; | 423 return map + i; |
437 } | 424 } |
438 return NULL; | 425 return NULL; |
(...skipping 23 matching lines...) Expand all Loading... |
462 prefs_->Set(map[current].preference_path, value); | 449 prefs_->Set(map[current].preference_path, value); |
463 return true; | 450 return true; |
464 } | 451 } |
465 } | 452 } |
466 return false; | 453 return false; |
467 } | 454 } |
468 | 455 |
469 bool ConfigurationPolicyPrefStore::ApplyProxyPolicy( | 456 bool ConfigurationPolicyPrefStore::ApplyProxyPolicy( |
470 ConfigurationPolicyType policy, | 457 ConfigurationPolicyType policy, |
471 Value* value) { | 458 Value* value) { |
472 bool result = false; | 459 // We only collect the values until we have sufficient information when |
473 bool warn_about_proxy_disable_config = false; | 460 // FinalizeProxyPolicySettings() is called to determine whether the presented |
474 bool warn_about_proxy_system_config = false; | 461 // values were correct and apply them in that case. |
| 462 scoped_ptr<Value>* target_container = NULL; |
| 463 switch (policy) { |
| 464 case kPolicyProxyMode: |
| 465 target_container = &proxy_mode_container_; |
| 466 break; |
| 467 case kPolicyProxyServer: |
| 468 target_container = &proxy_server_container_; |
| 469 break; |
| 470 case kPolicyProxyPacUrl: |
| 471 target_container = &proxy_pac_url_container_; |
| 472 break; |
| 473 case kPolicyProxyBypassList: |
| 474 target_container = &proxy_bypass_list_container_; |
| 475 break; |
| 476 default: |
| 477 // We are not interested in this policy. |
| 478 return false; |
| 479 } |
| 480 CHECK(target_container); |
475 | 481 |
476 const PolicyToPreferenceMapEntry* match_entry = | 482 if ((*target_container).get()) { |
477 FindPolicyInMap(policy, kProxyPolicyMap, arraysize(kProxyPolicyMap)); | 483 LOG(ERROR) << "Ignoring proxy policies because a policy was defined twice."; |
478 | 484 delete value; |
479 // When the first proxy-related policy is applied, ALL proxy-related | 485 return true; |
480 // preferences that have been set by command-line switches, extensions, | |
481 // user preferences or any other mechanism are overridden. Otherwise | |
482 // it's possible for a user to interfere with proxy policy by setting | |
483 // proxy-related command-line switches or set proxy-related prefs in an | |
484 // extension that are related, but not identical, to the ones set through | |
485 // policy. | |
486 if (!lower_priority_proxy_settings_overridden_ && | |
487 (match_entry || | |
488 policy == kPolicyProxyServerMode)) { | |
489 ProxyPreferenceSet proxy_preference_set; | |
490 GetProxyPreferenceSet(&proxy_preference_set); | |
491 for (ProxyPreferenceSet::const_iterator i = proxy_preference_set.begin(); | |
492 i != proxy_preference_set.end(); ++i) { | |
493 // We use values of TYPE_NULL to mark preferences for which | |
494 // READ_USE_DEFAULT should be returned by GetValue(). | |
495 prefs_->Set(*i, Value::CreateNullValue()); | |
496 } | |
497 lower_priority_proxy_settings_overridden_ = true; | |
498 } | 486 } |
499 | 487 |
500 // Translate the proxy policy into preferences. | 488 (*target_container).reset(value); |
501 if (policy == kPolicyProxyServerMode) { | 489 return true; |
502 int int_value; | 490 } |
503 bool proxy_auto_detect = false; | |
504 if (value->GetAsInteger(&int_value)) { | |
505 result = true; | |
506 switch (int_value) { | |
507 case kPolicyNoProxyServerMode: | |
508 if (!proxy_disabled_) { | |
509 if (proxy_configuration_specified_) | |
510 warn_about_proxy_disable_config = true; | |
511 proxy_disabled_ = true; | |
512 } | |
513 break; | |
514 case kPolicyAutoDetectProxyMode: | |
515 proxy_auto_detect = true; | |
516 break; | |
517 case kPolicyManuallyConfiguredProxyMode: | |
518 break; | |
519 case kPolicyUseSystemProxyMode: | |
520 if (!use_system_proxy_) { | |
521 if (proxy_configuration_specified_) | |
522 warn_about_proxy_system_config = true; | |
523 use_system_proxy_ = true; | |
524 } | |
525 break; | |
526 default: | |
527 // Not a valid policy, don't assume ownership of |value| | |
528 result = false; | |
529 break; | |
530 } | |
531 | 491 |
532 if (int_value != kPolicyUseSystemProxyMode) { | 492 void ConfigurationPolicyPrefStore::FinalizeProxyPolicySettings() { |
533 prefs_->Set(prefs::kNoProxyServer, | 493 if (CheckProxySettings()) |
534 Value::CreateBooleanValue(proxy_disabled_)); | 494 ApplyProxySettings(); |
535 prefs_->Set(prefs::kProxyAutoDetect, | 495 proxy_mode_container_.reset(NULL); |
536 Value::CreateBooleanValue(proxy_auto_detect)); | 496 proxy_server_container_.reset(NULL); |
537 } | 497 proxy_pac_url_container_.reset(NULL); |
538 } | 498 proxy_bypass_list_container_.reset(NULL); |
539 } else if (match_entry) { | 499 } |
540 // Determine if the applied proxy policy settings conflict and issue | 500 |
541 // a corresponding warning if they do. | 501 bool ConfigurationPolicyPrefStore::CheckProxySettings() { |
542 if (!proxy_configuration_specified_) { | 502 bool mode = proxy_mode_container_.get() && |
543 if (proxy_disabled_) | 503 !proxy_mode_container_->IsType(Value::TYPE_NULL); |
544 warn_about_proxy_disable_config = true; | 504 bool server = proxy_server_container_.get() && |
545 if (use_system_proxy_) | 505 !proxy_server_container_->IsType(Value::TYPE_NULL); |
546 warn_about_proxy_system_config = true; | 506 bool pac_url = proxy_pac_url_container_.get() && |
547 proxy_configuration_specified_ = true; | 507 !proxy_pac_url_container_->IsType(Value::TYPE_NULL); |
548 } | 508 bool bypass_list = proxy_bypass_list_container_.get() && |
549 if (!use_system_proxy_ && !proxy_disabled_) { | 509 !proxy_bypass_list_container_->IsType(Value::TYPE_NULL); |
550 prefs_->Set(match_entry->preference_path, value); | 510 |
551 // The ownership of value has been passed on to |prefs_|, | 511 if ((server || pac_url || bypass_list) && !mode) { |
552 // don't clean it up later. | 512 LOG(WARNING) << "A centrally-administered policy defines proxy setting" |
553 value = NULL; | 513 << " details without setting a proxy mode."; |
554 } | 514 return false; |
555 result = true; | |
556 } | 515 } |
557 | 516 |
558 if (warn_about_proxy_disable_config) { | 517 if (!mode) |
559 LOG(WARNING) << "A centrally-administered policy disables the use of" | 518 return true; |
560 << " a proxy but also specifies an explicit proxy" | 519 |
561 << " configuration."; | 520 int mode_value; |
| 521 if (!proxy_mode_container_->GetAsInteger(&mode_value)) { |
| 522 LOG(WARNING) << "Invalid proxy mode value."; |
| 523 return false; |
562 } | 524 } |
563 | 525 |
564 if (warn_about_proxy_system_config) { | 526 switch (mode_value) { |
565 LOG(WARNING) << "A centrally-administered policy dictates that the" | 527 case kPolicyNoProxyServerMode: |
566 << " system proxy settings should be used but also specifies" | 528 if (server || pac_url || bypass_list) { |
567 << " an explicit proxy configuration."; | 529 LOG(WARNING) << "A centrally-administered policy disables the use of" |
| 530 << " a proxy but also specifies an explicit proxy" |
| 531 << " configuration."; |
| 532 return false; |
| 533 } |
| 534 break; |
| 535 case kPolicyAutoDetectProxyMode: |
| 536 if (server || bypass_list) { |
| 537 LOG(WARNING) << "A centrally-administered policy dictates that a proxy" |
| 538 << " shall be auto configured but specifies fixed proxy" |
| 539 << " servers or a by-pass list."; |
| 540 return false; |
| 541 } |
| 542 break; |
| 543 case kPolicyManuallyConfiguredProxyMode: |
| 544 if (!server) { |
| 545 LOG(WARNING) << "A centrally-administered policy dictates that the" |
| 546 << " system proxy settings should use fixed proxy servers" |
| 547 << " without specifying which ones."; |
| 548 return false; |
| 549 } |
| 550 if (pac_url) { |
| 551 LOG(WARNING) << "A centrally-administered policy dictates that the" |
| 552 << " system proxy settings should use fixed proxy servers" |
| 553 << " but also specifies a PAC script."; |
| 554 return false; |
| 555 } |
| 556 break; |
| 557 case kPolicyUseSystemProxyMode: |
| 558 if (server || pac_url || bypass_list) { |
| 559 LOG(WARNING) << "A centrally-administered policy dictates that the" |
| 560 << " system proxy settings should be used but also " |
| 561 << " specifies an explicit proxy configuration."; |
| 562 return false; |
| 563 } |
| 564 break; |
| 565 default: |
| 566 LOG(WARNING) << "Invalid proxy mode " << mode_value; |
| 567 return false; |
568 } | 568 } |
| 569 return true; |
| 570 } |
569 | 571 |
570 // If the policy was a proxy policy, cleanup |value|. | 572 void ConfigurationPolicyPrefStore::ApplyProxySettings() { |
571 if (result && value) | 573 if (proxy_mode_container_.get() == NULL || |
572 delete value; | 574 proxy_mode_container_->IsType(Value::TYPE_NULL)) |
573 return result; | 575 return; |
| 576 |
| 577 int int_mode; |
| 578 CHECK(proxy_mode_container_->GetAsInteger(&int_mode)); |
| 579 ProxyPrefs::ProxyMode mode; |
| 580 switch (int_mode) { |
| 581 case kPolicyNoProxyServerMode: |
| 582 mode = ProxyPrefs::DISABLED; |
| 583 break; |
| 584 case kPolicyAutoDetectProxyMode: |
| 585 mode = ProxyPrefs::AUTO_DETECT; |
| 586 if (proxy_pac_url_container_.get() && |
| 587 !proxy_pac_url_container_->IsType(Value::TYPE_NULL)) { |
| 588 mode = ProxyPrefs::PAC_SCRIPT; |
| 589 } |
| 590 break; |
| 591 case kPolicyManuallyConfiguredProxyMode: |
| 592 mode = ProxyPrefs::FIXED_SERVERS; |
| 593 break; |
| 594 case kPolicyUseSystemProxyMode: |
| 595 mode = ProxyPrefs::SYSTEM; |
| 596 break; |
| 597 default: |
| 598 mode = ProxyPrefs::DISABLED; |
| 599 NOTREACHED(); |
| 600 } |
| 601 prefs_->Set(prefs::kProxyMode, Value::CreateIntegerValue(mode)); |
| 602 |
| 603 if (proxy_server_container_.get() && |
| 604 !proxy_server_container_->IsType(Value::TYPE_NULL)) { |
| 605 prefs_->Set(prefs::kProxyServer, proxy_server_container_.release()); |
| 606 } else { |
| 607 prefs_->Set(prefs::kProxyServer, Value::CreateNullValue()); |
| 608 } |
| 609 if (proxy_pac_url_container_.get() && |
| 610 !proxy_pac_url_container_->IsType(Value::TYPE_NULL)) { |
| 611 prefs_->Set(prefs::kProxyPacUrl, proxy_pac_url_container_.release()); |
| 612 } else { |
| 613 prefs_->Set(prefs::kProxyPacUrl, Value::CreateNullValue()); |
| 614 } |
| 615 if (proxy_bypass_list_container_.get() && |
| 616 !proxy_bypass_list_container_->IsType(Value::TYPE_NULL)) { |
| 617 prefs_->Set(prefs::kProxyBypassList, |
| 618 proxy_bypass_list_container_.release()); |
| 619 } else { |
| 620 prefs_->Set(prefs::kProxyBypassList, Value::CreateNullValue()); |
| 621 } |
574 } | 622 } |
575 | 623 |
576 bool ConfigurationPolicyPrefStore::ApplySyncPolicy( | 624 bool ConfigurationPolicyPrefStore::ApplySyncPolicy( |
577 ConfigurationPolicyType policy, Value* value) { | 625 ConfigurationPolicyType policy, Value* value) { |
578 if (policy == kPolicySyncDisabled) { | 626 if (policy == kPolicySyncDisabled) { |
579 bool disable_sync; | 627 bool disable_sync; |
580 if (value->GetAsBoolean(&disable_sync) && disable_sync) | 628 if (value->GetAsBoolean(&disable_sync) && disable_sync) |
581 prefs_->Set(prefs::kSyncManaged, value); | 629 prefs_->Set(prefs::kSyncManaged, value); |
582 else | 630 else |
583 delete value; | 631 delete value; |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
671 std::string()); | 719 std::string()); |
672 return; | 720 return; |
673 } | 721 } |
674 } | 722 } |
675 // Required entries are not there. Remove any related entries. | 723 // Required entries are not there. Remove any related entries. |
676 RemovePreferencesOfMap(kDefaultSearchPolicyMap, | 724 RemovePreferencesOfMap(kDefaultSearchPolicyMap, |
677 arraysize(kDefaultSearchPolicyMap)); | 725 arraysize(kDefaultSearchPolicyMap)); |
678 } | 726 } |
679 | 727 |
680 } // namespace policy | 728 } // namespace policy |
OLD | NEW |