Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(127)

Side by Side Diff: chrome/browser/chromeos/device_settings_provider.cc

Issue 9466005: Make sure the device recovers from policy loss in the consumer case. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Now with proper testing. Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698