| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/chromeos/device_settings_provider.h" | 5 #include "chrome/browser/chromeos/device_settings_provider.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/callback.h" | 9 #include "base/callback.h" |
| 10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/string_util.h" | 12 #include "base/string_util.h" |
| 13 #include "base/threading/thread_restrictions.h" | 13 #include "base/threading/thread_restrictions.h" |
| 14 #include "base/values.h" | 14 #include "base/values.h" |
| 15 #include "chrome/browser/browser_process.h" | 15 #include "chrome/browser/browser_process.h" |
| 16 #include "chrome/browser/chromeos/cros/cros_library.h" | 16 #include "chrome/browser/chromeos/cros/cros_library.h" |
| 17 #include "chrome/browser/chromeos/cros/network_library.h" | 17 #include "chrome/browser/chromeos/cros/network_library.h" |
| 18 #include "chrome/browser/chromeos/cros_settings.h" | 18 #include "chrome/browser/chromeos/cros_settings.h" |
| 19 #include "chrome/browser/chromeos/cros_settings_names.h" | 19 #include "chrome/browser/chromeos/cros_settings_names.h" |
| 20 #include "chrome/browser/chromeos/login/ownership_service.h" | 20 #include "chrome/browser/chromeos/login/ownership_service.h" |
| 21 #include "chrome/browser/chromeos/login/signed_settings_cache.h" | 21 #include "chrome/browser/chromeos/login/signed_settings_cache.h" |
| 22 #include "chrome/browser/chromeos/login/signed_settings_helper.h" | 22 #include "chrome/browser/chromeos/login/signed_settings_helper.h" |
| 23 #include "chrome/browser/chromeos/login/user_manager.h" | 23 #include "chrome/browser/chromeos/login/user_manager.h" |
| 24 #include "chrome/browser/policy/app_pack_updater.h" | 24 #include "chrome/browser/policy/app_pack_updater.h" |
| 25 #include "chrome/browser/policy/browser_policy_connector.h" |
| 26 #include "chrome/browser/policy/cloud_policy_constants.h" |
| 25 #include "chrome/browser/ui/options/options_util.h" | 27 #include "chrome/browser/ui/options/options_util.h" |
| 26 #include "chrome/common/chrome_notification_types.h" | 28 #include "chrome/common/chrome_notification_types.h" |
| 27 #include "chrome/installer/util/google_update_settings.h" | 29 #include "chrome/installer/util/google_update_settings.h" |
| 28 #include "content/public/browser/notification_service.h" | 30 #include "content/public/browser/notification_service.h" |
| 29 | 31 |
| 30 using google::protobuf::RepeatedPtrField; | 32 using google::protobuf::RepeatedPtrField; |
| 31 | 33 |
| 32 namespace em = enterprise_management; | 34 namespace em = enterprise_management; |
| 33 | 35 |
| 34 namespace chromeos { | 36 namespace chromeos { |
| 35 | 37 |
| 36 namespace { | 38 namespace { |
| 37 | 39 |
| 38 // List of settings handled by the DeviceSettingsProvider. | 40 // List of settings handled by the DeviceSettingsProvider. |
| 39 const char* kKnownSettings[] = { | 41 const char* kKnownSettings[] = { |
| 40 kAccountsPrefAllowGuest, | 42 kAccountsPrefAllowGuest, |
| 41 kAccountsPrefAllowNewUser, | 43 kAccountsPrefAllowNewUser, |
| 42 kAccountsPrefEphemeralUsersEnabled, | 44 kAccountsPrefEphemeralUsersEnabled, |
| 43 kAccountsPrefShowUserNamesOnSignIn, | 45 kAccountsPrefShowUserNamesOnSignIn, |
| 44 kAccountsPrefUsers, | 46 kAccountsPrefUsers, |
| 45 kAppPack, | 47 kAppPack, |
| 48 |
| 46 kDeviceOwner, | 49 kDeviceOwner, |
| 47 kIdleLogoutTimeout, | 50 kIdleLogoutTimeout, |
| 48 kIdleLogoutWarningDuration, | 51 kIdleLogoutWarningDuration, |
| 52 kPolicyMissingMitigationMode, |
| 49 kReleaseChannel, | 53 kReleaseChannel, |
| 50 kReportDeviceActivityTimes, | 54 kReportDeviceActivityTimes, |
| 51 kReportDeviceBootMode, | 55 kReportDeviceBootMode, |
| 52 kReportDeviceVersionInfo, | 56 kReportDeviceVersionInfo, |
| 53 kScreenSaverExtensionId, | 57 kScreenSaverExtensionId, |
| 54 kScreenSaverTimeout, | 58 kScreenSaverTimeout, |
| 55 kSettingProxyEverywhere, | 59 kSettingProxyEverywhere, |
| 56 kSignedDataRoamingEnabled, | 60 kSignedDataRoamingEnabled, |
| 57 kStatsReportingPref, | 61 kStatsReportingPref, |
| 58 }; | 62 }; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 73 // If the value is not set we should try to migrate legacy consent file. | 77 // If the value is not set we should try to migrate legacy consent file. |
| 74 // Loading consent file state causes us to do blocking IO on UI thread. | 78 // Loading consent file state causes us to do blocking IO on UI thread. |
| 75 // Temporarily allow it until we fix http://crbug.com/62626 | 79 // Temporarily allow it until we fix http://crbug.com/62626 |
| 76 base::ThreadRestrictions::ScopedAllowIO allow_io; | 80 base::ThreadRestrictions::ScopedAllowIO allow_io; |
| 77 return GoogleUpdateSettings::GetCollectStatsConsent(); | 81 return GoogleUpdateSettings::GetCollectStatsConsent(); |
| 78 } | 82 } |
| 79 | 83 |
| 80 } // namespace | 84 } // namespace |
| 81 | 85 |
| 82 DeviceSettingsProvider::DeviceSettingsProvider( | 86 DeviceSettingsProvider::DeviceSettingsProvider( |
| 87 const NotifyObserversCallback& notify_cb, |
| 88 SignedSettingsHelper* signed_settings_helper, |
| 89 OwnershipService::Status ownership_status) |
| 90 : CrosSettingsProvider(notify_cb), |
| 91 signed_settings_helper_(signed_settings_helper), |
| 92 ownership_status_(ownership_status), |
| 93 migration_helper_(new SignedSettingsMigrationHelper()), |
| 94 retries_left_(kNumRetriesLimit), |
| 95 trusted_(false) { |
| 96 Initialize(); |
| 97 } |
| 98 |
| 99 DeviceSettingsProvider::DeviceSettingsProvider( |
| 83 const NotifyObserversCallback& notify_cb) | 100 const NotifyObserversCallback& notify_cb) |
| 84 : CrosSettingsProvider(notify_cb), | 101 : CrosSettingsProvider(notify_cb), |
| 102 signed_settings_helper_(SignedSettingsHelper::Get()), |
| 85 ownership_status_(OwnershipService::GetSharedInstance()->GetStatus(true)), | 103 ownership_status_(OwnershipService::GetSharedInstance()->GetStatus(true)), |
| 86 migration_helper_(new SignedSettingsMigrationHelper()), | 104 migration_helper_(new SignedSettingsMigrationHelper()), |
| 87 retries_left_(kNumRetriesLimit), | 105 retries_left_(kNumRetriesLimit), |
| 88 trusted_(false) { | 106 trusted_(false) { |
| 107 Initialize(); |
| 108 } |
| 109 |
| 110 DeviceSettingsProvider::~DeviceSettingsProvider() { |
| 111 } |
| 112 |
| 113 void DeviceSettingsProvider::Initialize() { |
| 89 // Register for notification when ownership is taken so that we can update | 114 // Register for notification when ownership is taken so that we can update |
| 90 // the |ownership_status_| and reload if needed. | 115 // the |ownership_status_| and reload if needed. |
| 91 registrar_.Add(this, chrome::NOTIFICATION_OWNER_KEY_FETCH_ATTEMPT_SUCCEEDED, | 116 registrar_.Add(this, chrome::NOTIFICATION_OWNER_KEY_FETCH_ATTEMPT_SUCCEEDED, |
| 92 content::NotificationService::AllSources()); | 117 content::NotificationService::AllSources()); |
| 93 // Make sure we have at least the cache data immediately. | 118 // Make sure we have at least the cache data immediately. |
| 94 RetrieveCachedData(); | 119 RetrieveCachedData(); |
| 95 // Start prefetching preferences. | 120 // Start prefetching preferences. |
| 96 Reload(); | 121 Reload(); |
| 97 } | 122 } |
| 98 | 123 |
| 99 DeviceSettingsProvider::~DeviceSettingsProvider() { | |
| 100 } | |
| 101 | |
| 102 void DeviceSettingsProvider::Reload() { | 124 void DeviceSettingsProvider::Reload() { |
| 103 // While fetching we can't trust the cache anymore. | 125 // While fetching we can't trust the cache anymore. |
| 104 trusted_ = false; | 126 trusted_ = false; |
| 105 if (ownership_status_ == OwnershipService::OWNERSHIP_NONE) { | 127 if (ownership_status_ == OwnershipService::OWNERSHIP_NONE) { |
| 106 RetrieveCachedData(); | 128 RetrieveCachedData(); |
| 107 } else { | 129 } else { |
| 108 // Retrieve the real data. | 130 // Retrieve the real data. |
| 109 SignedSettingsHelper::Get()->StartRetrievePolicyOp( | 131 signed_settings_helper_->StartRetrievePolicyOp( |
| 110 base::Bind(&DeviceSettingsProvider::OnRetrievePolicyCompleted, | 132 base::Bind(&DeviceSettingsProvider::OnRetrievePolicyCompleted, |
| 111 base::Unretained(this))); | 133 base::Unretained(this))); |
| 112 } | 134 } |
| 113 } | 135 } |
| 114 | 136 |
| 115 void DeviceSettingsProvider::DoSet(const std::string& path, | 137 void DeviceSettingsProvider::DoSet(const std::string& path, |
| 116 const base::Value& in_value) { | 138 const base::Value& in_value) { |
| 117 if (!UserManager::Get()->IsCurrentUserOwner() && | 139 if (!UserManager::Get()->IsCurrentUserOwner() && |
| 118 ownership_status_ != OwnershipService::OWNERSHIP_NONE) { | 140 ownership_status_ != OwnershipService::OWNERSHIP_NONE) { |
| 119 LOG(WARNING) << "Changing settings from non-owner, setting=" << path; | 141 LOG(WARNING) << "Changing settings from non-owner, setting=" << path; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 if (!pending_changes_.empty()) | 208 if (!pending_changes_.empty()) |
| 187 SetInPolicy(); | 209 SetInPolicy(); |
| 188 } else { | 210 } else { |
| 189 NOTREACHED(); | 211 NOTREACHED(); |
| 190 } | 212 } |
| 191 return; | 213 return; |
| 192 } | 214 } |
| 193 | 215 |
| 194 if (!RequestTrustedEntity()) { | 216 if (!RequestTrustedEntity()) { |
| 195 // Otherwise we should first reload and apply on top of that. | 217 // Otherwise we should first reload and apply on top of that. |
| 196 SignedSettingsHelper::Get()->StartRetrievePolicyOp( | 218 signed_settings_helper_->StartRetrievePolicyOp( |
| 197 base::Bind(&DeviceSettingsProvider::FinishSetInPolicy, | 219 base::Bind(&DeviceSettingsProvider::FinishSetInPolicy, |
| 198 base::Unretained(this))); | 220 base::Unretained(this))); |
| 199 return; | 221 return; |
| 200 } | 222 } |
| 201 | 223 |
| 202 trusted_ = false; | 224 trusted_ = false; |
| 203 em::PolicyData data = policy(); | 225 em::PolicyData data = policy(); |
| 204 em::ChromeDeviceSettingsProto pol; | 226 em::ChromeDeviceSettingsProto pol; |
| 205 pol.ParseFromString(data.policy_value()); | 227 pol.ParseFromString(data.policy_value()); |
| 206 if (prop == kAccountsPrefAllowNewUser) { | 228 if (prop == kAccountsPrefAllowNewUser) { |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 // Set the cache to the updated value. | 316 // Set the cache to the updated value. |
| 295 policy_ = data; | 317 policy_ = data; |
| 296 UpdateValuesCache(); | 318 UpdateValuesCache(); |
| 297 | 319 |
| 298 if (!signed_settings_cache::Store(data, g_browser_process->local_state())) | 320 if (!signed_settings_cache::Store(data, g_browser_process->local_state())) |
| 299 LOG(ERROR) << "Couldn't store to the temp storage."; | 321 LOG(ERROR) << "Couldn't store to the temp storage."; |
| 300 | 322 |
| 301 if (ownership_status_ == OwnershipService::OWNERSHIP_TAKEN) { | 323 if (ownership_status_ == OwnershipService::OWNERSHIP_TAKEN) { |
| 302 em::PolicyFetchResponse policy_envelope; | 324 em::PolicyFetchResponse policy_envelope; |
| 303 policy_envelope.set_policy_data(policy_.SerializeAsString()); | 325 policy_envelope.set_policy_data(policy_.SerializeAsString()); |
| 304 SignedSettingsHelper::Get()->StartStorePolicyOp( | 326 signed_settings_helper_->StartStorePolicyOp( |
| 305 policy_envelope, | 327 policy_envelope, |
| 306 base::Bind(&DeviceSettingsProvider::OnStorePolicyCompleted, | 328 base::Bind(&DeviceSettingsProvider::OnStorePolicyCompleted, |
| 307 base::Unretained(this))); | 329 base::Unretained(this))); |
| 308 } else { | 330 } else { |
| 309 // OnStorePolicyCompleted won't get called in this case so proceed with any | 331 // OnStorePolicyCompleted won't get called in this case so proceed with any |
| 310 // pending operations immediately. | 332 // pending operations immediately. |
| 311 delete pending_changes_[0].second; | 333 delete pending_changes_[0].second; |
| 312 pending_changes_.erase(pending_changes_.begin()); | 334 pending_changes_.erase(pending_changes_.begin()); |
| 313 if (!pending_changes_.empty()) | 335 if (!pending_changes_.empty()) |
| 314 SetInPolicy(); | 336 SetInPolicy(); |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 578 if (pol.has_metrics_enabled()) | 600 if (pol.has_metrics_enabled()) |
| 579 ApplyMetricsSetting(false, pol.metrics_enabled().metrics_enabled()); | 601 ApplyMetricsSetting(false, pol.metrics_enabled().metrics_enabled()); |
| 580 else | 602 else |
| 581 ApplyMetricsSetting(true, false); | 603 ApplyMetricsSetting(true, false); |
| 582 // Next set the roaming setting as needed. | 604 // Next set the roaming setting as needed. |
| 583 ApplyRoamingSetting(pol.has_data_roaming_enabled() ? | 605 ApplyRoamingSetting(pol.has_data_roaming_enabled() ? |
| 584 pol.data_roaming_enabled().data_roaming_enabled() : false); | 606 pol.data_roaming_enabled().data_roaming_enabled() : false); |
| 585 } | 607 } |
| 586 | 608 |
| 587 bool DeviceSettingsProvider::MitigateMissingPolicy() { | 609 bool DeviceSettingsProvider::MitigateMissingPolicy() { |
| 588 // As this code runs only in exceptional cases it's fine to allow I/O here. | 610 // First check if the device has been owned already and if not exit |
| 589 base::ThreadRestrictions::ScopedAllowIO allow_io; | 611 // immediately. |
| 590 FilePath legacy_policy_file(kLegacyPolicyFile); | 612 if (g_browser_process->browser_policy_connector()->GetDeviceMode() != |
| 591 // Check if legacy file exists but is not writable to avoid possible | 613 policy::DEVICE_MODE_CONSUMER) { |
| 592 // attack of creating this file through chronos (although this should be | 614 return false; |
| 593 // not possible in root owned location), but better be safe than sorry. | |
| 594 // TODO(pastarmovj): Remove this workaround once we have proper checking | |
| 595 // for policy corruption or when Cr48 is phased out the very latest. | |
| 596 // See: http://crosbug.com/24916. | |
| 597 if (file_util::PathExists(legacy_policy_file) && | |
| 598 !file_util::PathIsWritable(legacy_policy_file)) { | |
| 599 // We are in pre 11 dev upgrading to post 17 version mode. | |
| 600 LOG(ERROR) << "Detected system upgraded from ChromeOS 11 or older with " | |
| 601 << "missing policies. Switching to migration policy mode " | |
| 602 << "until the owner logs in to regenerate the policy data."; | |
| 603 // In this situation we should pretend we have policy even though we | |
| 604 // don't until the owner logs in and restores the policy blob. | |
| 605 values_cache_.SetBoolean(kAccountsPrefAllowNewUser, true); | |
| 606 values_cache_.SetBoolean(kAccountsPrefAllowGuest, true); | |
| 607 trusted_ = true; | |
| 608 // Make sure we will recreate the policy once the owner logs in. | |
| 609 // Any value not in this list will be left to the default which is fine as | |
| 610 // we repopulate the whitelist with the owner and any other possible every | |
| 611 // time the user enables whitelist filtering on the UI. | |
| 612 migration_helper_->AddMigrationValue( | |
| 613 kAccountsPrefAllowNewUser, base::Value::CreateBooleanValue(true)); | |
| 614 migration_helper_->MigrateValues(); | |
| 615 // The last step is to pretend we loaded policy correctly and call everyone. | |
| 616 for (size_t i = 0; i < callbacks_.size(); ++i) | |
| 617 callbacks_[i].Run(); | |
| 618 callbacks_.clear(); | |
| 619 return true; | |
| 620 } | 615 } |
| 621 return false; | 616 |
| 617 // If we are here the policy file were corrupted or missing. This can happen |
| 618 // because we are migrating Pre R11 device to the new secure policies or there |
| 619 // was an attempt to circumvent policy system. In this case we should populate |
| 620 // the policy cache with "safe-mode" defaults which should allow the owner to |
| 621 // log in but lock the device for anyone else until the policy blob has been |
| 622 // recreated by the session manager. |
| 623 LOG(ERROR) << "Corruption of the policy data has been detected." |
| 624 << "Switching to \"safe-mode\" policies until the owner logs in " |
| 625 << "to regenerate the policy data."; |
| 626 values_cache_.SetBoolean(kAccountsPrefAllowNewUser, true); |
| 627 values_cache_.SetBoolean(kAccountsPrefAllowGuest, true); |
| 628 values_cache_.SetBoolean(kPolicyMissingMitigationMode, true); |
| 629 trusted_ = true; |
| 630 // Make sure we will recreate the policy once the owner logs in. |
| 631 // Any value not in this list will be left to the default which is fine as |
| 632 // we repopulate the whitelist with the owner and all other existing users |
| 633 // every time the owner enables whitelist filtering on the UI. |
| 634 migration_helper_->AddMigrationValue( |
| 635 kAccountsPrefAllowNewUser, base::Value::CreateBooleanValue(true)); |
| 636 migration_helper_->MigrateValues(); |
| 637 // The last step is to pretend we loaded policy correctly and call everyone. |
| 638 for (size_t i = 0; i < callbacks_.size(); ++i) |
| 639 callbacks_[i].Run(); |
| 640 callbacks_.clear(); |
| 641 return true; |
| 622 } | 642 } |
| 623 | 643 |
| 624 const base::Value* DeviceSettingsProvider::Get(const std::string& path) const { | 644 const base::Value* DeviceSettingsProvider::Get(const std::string& path) const { |
| 625 if (IsControlledSetting(path)) { | 645 if (IsControlledSetting(path)) { |
| 626 const base::Value* value; | 646 const base::Value* value; |
| 627 if (values_cache_.GetValue(path, &value)) | 647 if (values_cache_.GetValue(path, &value)) |
| 628 return value; | 648 return value; |
| 629 } else { | 649 } else { |
| 630 NOTREACHED() << "Trying to get non cros setting."; | 650 NOTREACHED() << "Trying to get non cros setting."; |
| 631 } | 651 } |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 690 trusted_ = true; | 710 trusted_ = true; |
| 691 for (size_t i = 0; i < callbacks_.size(); ++i) | 711 for (size_t i = 0; i < callbacks_.size(); ++i) |
| 692 callbacks_[i].Run(); | 712 callbacks_[i].Run(); |
| 693 callbacks_.clear(); | 713 callbacks_.clear(); |
| 694 // TODO(pastarmovj): Make those side effects responsibility of the | 714 // TODO(pastarmovj): Make those side effects responsibility of the |
| 695 // respective subsystems. | 715 // respective subsystems. |
| 696 ApplySideEffects(); | 716 ApplySideEffects(); |
| 697 break; | 717 break; |
| 698 } | 718 } |
| 699 case SignedSettings::NOT_FOUND: | 719 case SignedSettings::NOT_FOUND: |
| 700 // Verify if we don't have to mitigate pre Chrome 12 machine here and if | |
| 701 // needed do the magic. | |
| 702 if (MitigateMissingPolicy()) | 720 if (MitigateMissingPolicy()) |
| 703 break; | 721 break; |
| 704 case SignedSettings::KEY_UNAVAILABLE: { | 722 case SignedSettings::KEY_UNAVAILABLE: { |
| 705 if (ownership_status_ != OwnershipService::OWNERSHIP_TAKEN) | 723 if (ownership_status_ != OwnershipService::OWNERSHIP_TAKEN) |
| 706 NOTREACHED() << "No policies present yet, will use the temp storage."; | 724 NOTREACHED() << "No policies present yet, will use the temp storage."; |
| 707 break; | 725 break; |
| 708 } | 726 } |
| 709 case SignedSettings::BAD_SIGNATURE: | 727 case SignedSettings::BAD_SIGNATURE: |
| 710 case SignedSettings::OPERATION_FAILED: { | 728 case SignedSettings::OPERATION_FAILED: { |
| 711 LOG(ERROR) << "Failed to retrieve cros policies. Reason:" << code; | 729 LOG(ERROR) << "Failed to retrieve cros policies. Reason:" << code; |
| 712 if (retries_left_ > 0) { | 730 if (retries_left_ > 0) { |
| 713 retries_left_ -= 1; | 731 retries_left_ -= 1; |
| 714 Reload(); | 732 Reload(); |
| 715 return; | 733 return; |
| 716 } | 734 } |
| 717 LOG(ERROR) << "No retries left"; | 735 LOG(ERROR) << "No retries left"; |
| 718 break; | 736 break; |
| 719 } | 737 } |
| 720 } | 738 } |
| 721 } | 739 } |
| 722 | 740 |
| 723 } // namespace chromeos | 741 } // namespace chromeos |
| OLD | NEW |