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 |