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

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

Issue 10918027: Revert 154457 - Switch from SignedSettings to DeviceSettingsService. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 3 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/settings/device_settings_provider.h" 5 #include "chrome/browser/chromeos/settings/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/login/user_manager.h"
18 #include "chrome/browser/chromeos/settings/cros_settings.h" 19 #include "chrome/browser/chromeos/settings/cros_settings.h"
19 #include "chrome/browser/chromeos/settings/cros_settings_names.h" 20 #include "chrome/browser/chromeos/settings/cros_settings_names.h"
20 #include "chrome/browser/chromeos/settings/device_settings_cache.h" 21 #include "chrome/browser/chromeos/settings/signed_settings_cache.h"
22 #include "chrome/browser/chromeos/settings/signed_settings_helper.h"
21 #include "chrome/browser/policy/app_pack_updater.h" 23 #include "chrome/browser/policy/app_pack_updater.h"
22 #include "chrome/browser/policy/browser_policy_connector.h" 24 #include "chrome/browser/policy/browser_policy_connector.h"
23 #include "chrome/browser/policy/cloud_policy_constants.h" 25 #include "chrome/browser/policy/cloud_policy_constants.h"
24 #include "chrome/browser/policy/proto/device_management_backend.pb.h" 26 #include "chrome/browser/policy/proto/chrome_device_policy.pb.h"
25 #include "chrome/browser/ui/options/options_util.h" 27 #include "chrome/browser/ui/options/options_util.h"
28 #include "chrome/common/chrome_notification_types.h"
26 #include "chrome/installer/util/google_update_settings.h" 29 #include "chrome/installer/util/google_update_settings.h"
30 #include "content/public/browser/notification_service.h"
27 31
28 using google::protobuf::RepeatedPtrField; 32 using google::protobuf::RepeatedPtrField;
29 33
30 namespace em = enterprise_management; 34 namespace em = enterprise_management;
31 35
32 namespace chromeos { 36 namespace chromeos {
33 37
34 namespace { 38 namespace {
35 39
36 // List of settings handled by the DeviceSettingsProvider. 40 // List of settings handled by the DeviceSettingsProvider.
(...skipping 16 matching lines...) Expand all
53 kReportDeviceVersionInfo, 57 kReportDeviceVersionInfo,
54 kScreenSaverExtensionId, 58 kScreenSaverExtensionId,
55 kScreenSaverTimeout, 59 kScreenSaverTimeout,
56 kSettingProxyEverywhere, 60 kSettingProxyEverywhere,
57 kSignedDataRoamingEnabled, 61 kSignedDataRoamingEnabled,
58 kStartUpUrls, 62 kStartUpUrls,
59 kStatsReportingPref, 63 kStatsReportingPref,
60 kSystemTimezonePolicy, 64 kSystemTimezonePolicy,
61 }; 65 };
62 66
67 // Upper bound for number of retries to fetch a signed setting.
68 static const int kNumRetriesLimit = 9;
69
63 // Legacy policy file location. Used to detect migration from pre v12 ChromeOS. 70 // Legacy policy file location. Used to detect migration from pre v12 ChromeOS.
64 const char kLegacyPolicyFile[] = "/var/lib/whitelist/preferences"; 71 const char kLegacyPolicyFile[] = "/var/lib/whitelist/preferences";
65 72
66 bool IsControlledSetting(const std::string& pref_path) { 73 bool IsControlledSetting(const std::string& pref_path) {
67 const char** end = kKnownSettings + arraysize(kKnownSettings); 74 const char** end = kKnownSettings + arraysize(kKnownSettings);
68 return std::find(kKnownSettings, end, pref_path) != end; 75 return std::find(kKnownSettings, end, pref_path) != end;
69 } 76 }
70 77
71 bool HasOldMetricsFile() { 78 bool HasOldMetricsFile() {
72 // TODO(pastarmovj): Remove this once migration is not needed anymore. 79 // TODO(pastarmovj): Remove this once migration is not needed anymore.
73 // If the value is not set we should try to migrate legacy consent file. 80 // 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. 81 // Loading consent file state causes us to do blocking IO on UI thread.
75 // Temporarily allow it until we fix http://crbug.com/62626 82 // Temporarily allow it until we fix http://crbug.com/62626
76 base::ThreadRestrictions::ScopedAllowIO allow_io; 83 base::ThreadRestrictions::ScopedAllowIO allow_io;
77 return GoogleUpdateSettings::GetCollectStatsConsent(); 84 return GoogleUpdateSettings::GetCollectStatsConsent();
78 } 85 }
79 86
80 } // namespace 87 } // namespace
81 88
82 DeviceSettingsProvider::DeviceSettingsProvider( 89 DeviceSettingsProvider::DeviceSettingsProvider(
83 const NotifyObserversCallback& notify_cb, 90 const NotifyObserversCallback& notify_cb,
84 DeviceSettingsService* device_settings_service) 91 SignedSettingsHelper* signed_settings_helper)
85 : CrosSettingsProvider(notify_cb), 92 : CrosSettingsProvider(notify_cb),
86 device_settings_service_(device_settings_service), 93 signed_settings_helper_(signed_settings_helper),
87 trusted_status_(TEMPORARILY_UNTRUSTED), 94 ownership_status_(OwnershipService::GetSharedInstance()->GetStatus(true)),
88 ownership_status_(device_settings_service_->GetOwnershipStatus()), 95 migration_helper_(new SignedSettingsMigrationHelper()),
89 ALLOW_THIS_IN_INITIALIZER_LIST(store_callback_factory_(this)) { 96 retries_left_(kNumRetriesLimit),
90 device_settings_service_->AddObserver(this); 97 trusted_status_(TEMPORARILY_UNTRUSTED) {
91 98 // Register for notification when ownership is taken so that we can update
92 if (!UpdateFromService()) { 99 // the |ownership_status_| and reload if needed.
93 // Make sure we have at least the cache data immediately. 100 registrar_.Add(this, chrome::NOTIFICATION_OWNER_KEY_FETCH_ATTEMPT_SUCCEEDED,
94 RetrieveCachedData(); 101 content::NotificationService::AllSources());
95 } 102 // Make sure we have at least the cache data immediately.
103 RetrieveCachedData();
104 // Start prefetching preferences.
105 Reload();
96 } 106 }
97 107
98 DeviceSettingsProvider::~DeviceSettingsProvider() { 108 DeviceSettingsProvider::~DeviceSettingsProvider() {
99 device_settings_service_->RemoveObserver(this); 109 }
110
111 void DeviceSettingsProvider::Reload() {
112 // While fetching we can't trust the cache anymore.
113 trusted_status_ = TEMPORARILY_UNTRUSTED;
114 if (ownership_status_ == OwnershipService::OWNERSHIP_NONE) {
115 RetrieveCachedData();
116 } else {
117 // Retrieve the real data.
118 signed_settings_helper_->StartRetrievePolicyOp(
119 base::Bind(&DeviceSettingsProvider::OnRetrievePolicyCompleted,
120 base::Unretained(this)));
121 }
100 } 122 }
101 123
102 void DeviceSettingsProvider::DoSet(const std::string& path, 124 void DeviceSettingsProvider::DoSet(const std::string& path,
103 const base::Value& in_value) { 125 const base::Value& in_value) {
104 // Make sure that either the current user is the device owner or the 126 if (!UserManager::Get()->IsCurrentUserOwner() &&
105 // device doesn't have an owner yet. 127 ownership_status_ != OwnershipService::OWNERSHIP_NONE) {
106 if (!(device_settings_service_->HasPrivateOwnerKey() ||
107 ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE)) {
108 LOG(WARNING) << "Changing settings from non-owner, setting=" << path; 128 LOG(WARNING) << "Changing settings from non-owner, setting=" << path;
109 129
110 // Revert UI change. 130 // Revert UI change.
111 NotifyObservers(path); 131 NotifyObservers(path);
112 return; 132 return;
113 } 133 }
114 134
115 if (IsControlledSetting(path)) { 135 if (IsControlledSetting(path)) {
116 pending_changes_.push_back(PendingQueueElement(path, in_value.DeepCopy())); 136 pending_changes_.push_back(PendingQueueElement(path, in_value.DeepCopy()));
117 if (!store_callback_factory_.HasWeakPtrs()) 137 if (pending_changes_.size() == 1)
118 SetInPolicy(); 138 SetInPolicy();
119 } else { 139 } else {
120 NOTREACHED() << "Try to set unhandled cros setting " << path; 140 NOTREACHED() << "Try to set unhandled cros setting " << path;
121 } 141 }
122 } 142 }
123 143
124 void DeviceSettingsProvider::OwnershipStatusChanged() { 144 void DeviceSettingsProvider::Observe(
125 DeviceSettingsService::OwnershipStatus new_ownership_status = 145 int type,
126 device_settings_service_->GetOwnershipStatus(); 146 const content::NotificationSource& source,
127 147 const content::NotificationDetails& details) {
128 // If the device just became owned, write the settings accumulated in the 148 if (type == chrome::NOTIFICATION_OWNER_KEY_FETCH_ATTEMPT_SUCCEEDED) {
129 // cache to device settings proper. It is important that writing only happens 149 // Reload the policy blob once the owner key has been loaded or updated.
130 // in this case, as during normal operation, the contents of the cache should 150 ownership_status_ = OwnershipService::OWNERSHIP_TAKEN;
131 // never overwrite actual device settings. 151 Reload();
132 if (new_ownership_status == DeviceSettingsService::OWNERSHIP_TAKEN &&
133 ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE &&
134 device_settings_service_->HasPrivateOwnerKey()) {
135
136 // There shouldn't be any pending writes, since the cache writes are all
137 // immediate.
138 DCHECK(!store_callback_factory_.HasWeakPtrs());
139
140 // Apply the locally-accumulated device settings on top of the initial
141 // settings from the service and write back the result.
142 if (device_settings_service_->device_settings()) {
143 em::ChromeDeviceSettingsProto new_settings(
144 *device_settings_service_->device_settings());
145 new_settings.MergeFrom(device_settings_);
146 device_settings_.Swap(&new_settings);
147 }
148 StoreDeviceSettings();
149 } 152 }
150
151 // The owner key might have become available, allowing migration to happen.
152 AttemptMigration();
153
154 ownership_status_ = new_ownership_status;
155 } 153 }
156 154
157 void DeviceSettingsProvider::DeviceSettingsUpdated() { 155 const em::PolicyData DeviceSettingsProvider::policy() const {
158 if (!store_callback_factory_.HasWeakPtrs()) 156 return policy_;
159 UpdateAndProceedStoring();
160 } 157 }
161 158
162 void DeviceSettingsProvider::RetrieveCachedData() { 159 void DeviceSettingsProvider::RetrieveCachedData() {
163 em::PolicyData policy_data; 160 // If there is no owner yet, this function will pull the policy cache from the
164 if (!device_settings_cache::Retrieve(&policy_data, 161 // temp storage and use that instead.
165 g_browser_process->local_state()) || 162 em::PolicyData policy;
166 !device_settings_.ParseFromString(policy_data.policy_value())) { 163 if (!signed_settings_cache::Retrieve(&policy,
167 VLOG(1) << "Can't retrieve temp store, possibly not created yet."; 164 g_browser_process->local_state())) {
165 VLOG(1) << "Can't retrieve temp store possibly not created yet.";
166 // Prepare empty data for the case we don't have temp cache yet.
167 policy.set_policy_type(kDevicePolicyType);
168 em::ChromeDeviceSettingsProto pol;
169 policy.set_policy_value(pol.SerializeAsString());
168 } 170 }
169 171
170 UpdateValuesCache(policy_data, device_settings_); 172 policy_ = policy;
173 UpdateValuesCache();
171 } 174 }
172 175
173 void DeviceSettingsProvider::SetInPolicy() { 176 void DeviceSettingsProvider::SetInPolicy() {
174 if (pending_changes_.empty()) { 177 if (pending_changes_.empty()) {
175 NOTREACHED(); 178 NOTREACHED();
176 return; 179 return;
177 } 180 }
178 181
182 const std::string& prop = pending_changes_[0].first;
183 base::Value* value = pending_changes_[0].second;
184 if (prop == kDeviceOwner) {
185 // Just store it in the memory cache without trusted checks or persisting.
186 std::string owner;
187 if (value->GetAsString(&owner)) {
188 policy_.set_username(owner);
189 // In this case the |value_cache_| takes the ownership of |value|.
190 values_cache_.SetValue(prop, value);
191 NotifyObservers(prop);
192 // We can't trust this value anymore until we reload the real username.
193 trusted_status_ = TEMPORARILY_UNTRUSTED;
194 pending_changes_.erase(pending_changes_.begin());
195 if (!pending_changes_.empty())
196 SetInPolicy();
197 } else {
198 NOTREACHED();
199 }
200 return;
201 }
202
179 if (RequestTrustedEntity() != TRUSTED) { 203 if (RequestTrustedEntity() != TRUSTED) {
180 // Re-sync device settings before proceeding. 204 // Otherwise we should first reload and apply on top of that.
181 device_settings_service_->Load(); 205 signed_settings_helper_->StartRetrievePolicyOp(
206 base::Bind(&DeviceSettingsProvider::FinishSetInPolicy,
207 base::Unretained(this)));
182 return; 208 return;
183 } 209 }
184 210
185 std::string prop(pending_changes_.front().first);
186 scoped_ptr<base::Value> value(pending_changes_.front().second);
187 pending_changes_.pop_front();
188
189 trusted_status_ = TEMPORARILY_UNTRUSTED; 211 trusted_status_ = TEMPORARILY_UNTRUSTED;
212 em::PolicyData data = policy();
213 em::ChromeDeviceSettingsProto pol;
214 pol.ParseFromString(data.policy_value());
190 if (prop == kAccountsPrefAllowNewUser) { 215 if (prop == kAccountsPrefAllowNewUser) {
191 em::AllowNewUsersProto* allow = 216 em::AllowNewUsersProto* allow = pol.mutable_allow_new_users();
192 device_settings_.mutable_allow_new_users();
193 bool allow_value; 217 bool allow_value;
194 if (value->GetAsBoolean(&allow_value)) 218 if (value->GetAsBoolean(&allow_value))
195 allow->set_allow_new_users(allow_value); 219 allow->set_allow_new_users(allow_value);
196 else 220 else
197 NOTREACHED(); 221 NOTREACHED();
198 } else if (prop == kAccountsPrefAllowGuest) { 222 } else if (prop == kAccountsPrefAllowGuest) {
199 em::GuestModeEnabledProto* guest = 223 em::GuestModeEnabledProto* guest = pol.mutable_guest_mode_enabled();
200 device_settings_.mutable_guest_mode_enabled();
201 bool guest_value; 224 bool guest_value;
202 if (value->GetAsBoolean(&guest_value)) 225 if (value->GetAsBoolean(&guest_value))
203 guest->set_guest_mode_enabled(guest_value); 226 guest->set_guest_mode_enabled(guest_value);
204 else 227 else
205 NOTREACHED(); 228 NOTREACHED();
206 } else if (prop == kAccountsPrefShowUserNamesOnSignIn) { 229 } else if (prop == kAccountsPrefShowUserNamesOnSignIn) {
207 em::ShowUserNamesOnSigninProto* show = 230 em::ShowUserNamesOnSigninProto* show = pol.mutable_show_user_names();
208 device_settings_.mutable_show_user_names();
209 bool show_value; 231 bool show_value;
210 if (value->GetAsBoolean(&show_value)) 232 if (value->GetAsBoolean(&show_value))
211 show->set_show_user_names(show_value); 233 show->set_show_user_names(show_value);
212 else 234 else
213 NOTREACHED(); 235 NOTREACHED();
214 } else if (prop == kSignedDataRoamingEnabled) { 236 } else if (prop == kSignedDataRoamingEnabled) {
215 em::DataRoamingEnabledProto* roam = 237 em::DataRoamingEnabledProto* roam = pol.mutable_data_roaming_enabled();
216 device_settings_.mutable_data_roaming_enabled();
217 bool roaming_value = false; 238 bool roaming_value = false;
218 if (value->GetAsBoolean(&roaming_value)) 239 if (value->GetAsBoolean(&roaming_value))
219 roam->set_data_roaming_enabled(roaming_value); 240 roam->set_data_roaming_enabled(roaming_value);
220 else 241 else
221 NOTREACHED(); 242 NOTREACHED();
222 ApplyRoamingSetting(roaming_value); 243 ApplyRoamingSetting(roaming_value);
223 } else if (prop == kSettingProxyEverywhere) { 244 } else if (prop == kSettingProxyEverywhere) {
224 // TODO(cmasone): NOTIMPLEMENTED() once http://crosbug.com/13052 is fixed. 245 // TODO(cmasone): NOTIMPLEMENTED() once http://crosbug.com/13052 is fixed.
225 std::string proxy_value; 246 std::string proxy_value;
226 if (value->GetAsString(&proxy_value)) { 247 if (value->GetAsString(&proxy_value)) {
227 bool success = 248 bool success =
228 device_settings_.mutable_device_proxy_settings()->ParseFromString( 249 pol.mutable_device_proxy_settings()->ParseFromString(proxy_value);
229 proxy_value);
230 DCHECK(success); 250 DCHECK(success);
231 } else { 251 } else {
232 NOTREACHED(); 252 NOTREACHED();
233 } 253 }
234 } else if (prop == kReleaseChannel) { 254 } else if (prop == kReleaseChannel) {
235 em::ReleaseChannelProto* release_channel = 255 em::ReleaseChannelProto* release_channel = pol.mutable_release_channel();
236 device_settings_.mutable_release_channel();
237 std::string channel_value; 256 std::string channel_value;
238 if (value->GetAsString(&channel_value)) 257 if (value->GetAsString(&channel_value))
239 release_channel->set_release_channel(channel_value); 258 release_channel->set_release_channel(channel_value);
240 else 259 else
241 NOTREACHED(); 260 NOTREACHED();
242 } else if (prop == kStatsReportingPref) { 261 } else if (prop == kStatsReportingPref) {
243 em::MetricsEnabledProto* metrics = 262 em::MetricsEnabledProto* metrics = pol.mutable_metrics_enabled();
244 device_settings_.mutable_metrics_enabled();
245 bool metrics_value = false; 263 bool metrics_value = false;
246 if (value->GetAsBoolean(&metrics_value)) 264 if (value->GetAsBoolean(&metrics_value))
247 metrics->set_metrics_enabled(metrics_value); 265 metrics->set_metrics_enabled(metrics_value);
248 else 266 else
249 NOTREACHED(); 267 NOTREACHED();
250 ApplyMetricsSetting(false, metrics_value); 268 ApplyMetricsSetting(false, metrics_value);
251 } else if (prop == kAccountsPrefUsers) { 269 } else if (prop == kAccountsPrefUsers) {
252 em::UserWhitelistProto* whitelist_proto = 270 em::UserWhitelistProto* whitelist_proto = pol.mutable_user_whitelist();
253 device_settings_.mutable_user_whitelist();
254 whitelist_proto->clear_user_whitelist(); 271 whitelist_proto->clear_user_whitelist();
255 base::ListValue& users = static_cast<base::ListValue&>(*value); 272 base::ListValue& users = static_cast<base::ListValue&>(*value);
256 for (base::ListValue::const_iterator i = users.begin(); 273 for (base::ListValue::const_iterator i = users.begin();
257 i != users.end(); ++i) { 274 i != users.end(); ++i) {
258 std::string email; 275 std::string email;
259 if ((*i)->GetAsString(&email)) 276 if ((*i)->GetAsString(&email))
260 whitelist_proto->add_user_whitelist(email.c_str()); 277 whitelist_proto->add_user_whitelist(email.c_str());
261 } 278 }
262 } else if (prop == kAccountsPrefEphemeralUsersEnabled) { 279 } else if (prop == kAccountsPrefEphemeralUsersEnabled) {
263 em::EphemeralUsersEnabledProto* ephemeral_users_enabled = 280 em::EphemeralUsersEnabledProto* ephemeral_users_enabled =
264 device_settings_.mutable_ephemeral_users_enabled(); 281 pol.mutable_ephemeral_users_enabled();
265 bool ephemeral_users_enabled_value = false; 282 bool ephemeral_users_enabled_value = false;
266 if (value->GetAsBoolean(&ephemeral_users_enabled_value)) { 283 if (value->GetAsBoolean(&ephemeral_users_enabled_value))
267 ephemeral_users_enabled->set_ephemeral_users_enabled( 284 ephemeral_users_enabled->set_ephemeral_users_enabled(
268 ephemeral_users_enabled_value); 285 ephemeral_users_enabled_value);
269 } else { 286 else
270 NOTREACHED(); 287 NOTREACHED();
271 }
272 } else { 288 } else {
273 // The remaining settings don't support Set(), since they are not 289 // The remaining settings don't support Set(), since they are not
274 // intended to be customizable by the user: 290 // intended to be customizable by the user:
275 // kAppPack 291 // kAppPack
276 // kDeviceOwner
277 // kIdleLogoutTimeout 292 // kIdleLogoutTimeout
278 // kIdleLogoutWarningDuration 293 // kIdleLogoutWarningDuration
279 // kReleaseChannelDelegated 294 // kReleaseChannelDelegated
280 // kReportDeviceVersionInfo 295 // kReportDeviceVersionInfo
281 // kReportDeviceActivityTimes 296 // kReportDeviceActivityTimes
282 // kReportDeviceBootMode 297 // kReportDeviceBootMode
283 // kReportDeviceLocation 298 // kReportDeviceLocation
284 // kScreenSaverExtensionId 299 // kScreenSaverExtensionId
285 // kScreenSaverTimeout 300 // kScreenSaverTimeout
286 // kStartUpUrls 301 // kStartUpUrls
287 // kSystemTimezonePolicy 302 // kSystemTimezonePolicy
288 303
289 LOG(FATAL) << "Device setting " << prop << " is read-only."; 304 NOTREACHED();
290 } 305 }
306 data.set_policy_value(pol.SerializeAsString());
307 // Set the cache to the updated value.
308 policy_ = data;
309 UpdateValuesCache();
291 310
292 em::PolicyData data; 311 if (!signed_settings_cache::Store(data, g_browser_process->local_state()))
293 data.set_username(device_settings_service_->GetUsername());
294 CHECK(device_settings_.SerializeToString(data.mutable_policy_value()));
295
296 // Set the cache to the updated value.
297 UpdateValuesCache(data, device_settings_);
298
299 if (!device_settings_cache::Store(data, g_browser_process->local_state()))
300 LOG(ERROR) << "Couldn't store to the temp storage."; 312 LOG(ERROR) << "Couldn't store to the temp storage.";
301 313
302 if (ownership_status_ == DeviceSettingsService::OWNERSHIP_TAKEN) { 314 if (ownership_status_ == OwnershipService::OWNERSHIP_TAKEN) {
303 StoreDeviceSettings(); 315 em::PolicyFetchResponse policy_envelope;
316 policy_envelope.set_policy_data(policy_.SerializeAsString());
317 signed_settings_helper_->StartStorePolicyOp(
318 policy_envelope,
319 base::Bind(&DeviceSettingsProvider::OnStorePolicyCompleted,
320 base::Unretained(this)));
304 } else { 321 } else {
305 // OnStorePolicyCompleted won't get called in this case so proceed with any 322 // OnStorePolicyCompleted won't get called in this case so proceed with any
306 // pending operations immediately. 323 // pending operations immediately.
324 delete pending_changes_[0].second;
325 pending_changes_.erase(pending_changes_.begin());
307 if (!pending_changes_.empty()) 326 if (!pending_changes_.empty())
308 SetInPolicy(); 327 SetInPolicy();
309 } 328 }
310 } 329 }
311 330
331 void DeviceSettingsProvider::FinishSetInPolicy(
332 SignedSettings::ReturnCode code,
333 const em::PolicyFetchResponse& policy) {
334 if (code != SignedSettings::SUCCESS) {
335 LOG(ERROR) << "Can't serialize to policy error code: " << code;
336 Reload();
337 return;
338 }
339 // Update the internal caches and set the trusted flag to true so that we
340 // can pass the trustedness check in the second call to SetInPolicy.
341 OnRetrievePolicyCompleted(code, policy);
342
343 SetInPolicy();
344 }
345
312 void DeviceSettingsProvider::DecodeLoginPolicies( 346 void DeviceSettingsProvider::DecodeLoginPolicies(
313 const em::ChromeDeviceSettingsProto& policy, 347 const em::ChromeDeviceSettingsProto& policy,
314 PrefValueMap* new_values_cache) const { 348 PrefValueMap* new_values_cache) const {
315 // For all our boolean settings the following is applicable: 349 // For all our boolean settings the following is applicable:
316 // true is default permissive value and false is safe prohibitive value. 350 // true is default permissive value and false is safe prohibitive value.
317 // Exceptions: 351 // Exceptions:
318 // kSignedDataRoamingEnabled has a default value of false. 352 // kSignedDataRoamingEnabled has a default value of false.
319 // kAccountsPrefEphemeralUsersEnabled has a default value of false. 353 // kAccountsPrefEphemeralUsersEnabled has a default value of false.
320 if (policy.has_allow_new_users() && 354 if (policy.has_allow_new_users() &&
321 policy.allow_new_users().has_allow_new_users() && 355 policy.allow_new_users().has_allow_new_users() &&
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 531
498 if (policy.has_system_timezone()) { 532 if (policy.has_system_timezone()) {
499 if (policy.system_timezone().has_timezone()) { 533 if (policy.system_timezone().has_timezone()) {
500 new_values_cache->SetString( 534 new_values_cache->SetString(
501 kSystemTimezonePolicy, 535 kSystemTimezonePolicy,
502 policy.system_timezone().timezone()); 536 policy.system_timezone().timezone());
503 } 537 }
504 } 538 }
505 } 539 }
506 540
507 void DeviceSettingsProvider::UpdateValuesCache( 541 void DeviceSettingsProvider::UpdateValuesCache() {
508 const em::PolicyData& policy_data, 542 const em::PolicyData data = policy();
509 const em::ChromeDeviceSettingsProto& settings) {
510 PrefValueMap new_values_cache; 543 PrefValueMap new_values_cache;
511 544
512 if (policy_data.has_username() && !policy_data.has_request_token()) 545 if (data.has_username() && !data.has_request_token())
513 new_values_cache.SetString(kDeviceOwner, policy_data.username()); 546 new_values_cache.SetString(kDeviceOwner, data.username());
514 547
515 DecodeLoginPolicies(settings, &new_values_cache); 548 em::ChromeDeviceSettingsProto pol;
516 DecodeKioskPolicies(settings, &new_values_cache); 549 pol.ParseFromString(data.policy_value());
517 DecodeNetworkPolicies(settings, &new_values_cache); 550
518 DecodeReportingPolicies(settings, &new_values_cache); 551 DecodeLoginPolicies(pol, &new_values_cache);
519 DecodeGenericPolicies(settings, &new_values_cache); 552 DecodeKioskPolicies(pol, &new_values_cache);
553 DecodeNetworkPolicies(pol, &new_values_cache);
554 DecodeReportingPolicies(pol, &new_values_cache);
555 DecodeGenericPolicies(pol, &new_values_cache);
520 556
521 // Collect all notifications but send them only after we have swapped the 557 // Collect all notifications but send them only after we have swapped the
522 // cache so that if somebody actually reads the cache will be already valid. 558 // cache so that if somebody actually reads the cache will be already valid.
523 std::vector<std::string> notifications; 559 std::vector<std::string> notifications;
524 // Go through the new values and verify in the old ones. 560 // Go through the new values and verify in the old ones.
525 PrefValueMap::iterator iter = new_values_cache.begin(); 561 PrefValueMap::iterator iter = new_values_cache.begin();
526 for (; iter != new_values_cache.end(); ++iter) { 562 for (; iter != new_values_cache.end(); ++iter) {
527 const base::Value* old_value; 563 const base::Value* old_value;
528 if (!values_cache_.GetValue(iter->first, &old_value) || 564 if (!values_cache_.GetValue(iter->first, &old_value) ||
529 !old_value->Equals(iter->second)) { 565 !old_value->Equals(iter->second)) {
530 notifications.push_back(iter->first); 566 notifications.push_back(iter->first);
531 } 567 }
532 } 568 }
533 // Now check for values that have been removed from the policy blob. 569 // Now check for values that have been removed from the policy blob.
534 for (iter = values_cache_.begin(); iter != values_cache_.end(); ++iter) { 570 for (iter = values_cache_.begin(); iter != values_cache_.end(); ++iter) {
535 const base::Value* value; 571 const base::Value* value;
536 if (!new_values_cache.GetValue(iter->first, &value)) 572 if (!new_values_cache.GetValue(iter->first, &value))
537 notifications.push_back(iter->first); 573 notifications.push_back(iter->first);
538 } 574 }
539 // Swap and notify. 575 // Swap and notify.
540 values_cache_.Swap(&new_values_cache); 576 values_cache_.Swap(&new_values_cache);
541 for (size_t i = 0; i < notifications.size(); ++i) 577 for (size_t i = 0; i < notifications.size(); ++i)
542 NotifyObservers(notifications[i]); 578 NotifyObservers(notifications[i]);
543 } 579 }
544 580
545 void DeviceSettingsProvider::ApplyMetricsSetting(bool use_file, 581 void DeviceSettingsProvider::ApplyMetricsSetting(bool use_file,
546 bool new_value) { 582 bool new_value) const {
547 // TODO(pastarmovj): Remove this once migration is not needed anymore. 583 // TODO(pastarmovj): Remove this once migration is not needed anymore.
548 // If the value is not set we should try to migrate legacy consent file. 584 // If the value is not set we should try to migrate legacy consent file.
549 if (use_file) { 585 if (use_file) {
550 new_value = HasOldMetricsFile(); 586 new_value = HasOldMetricsFile();
551 // Make sure the values will get eventually written to the policy file. 587 // Make sure the values will get eventually written to the policy file.
552 migration_values_.SetValue(kStatsReportingPref, 588 migration_helper_->AddMigrationValue(
553 base::Value::CreateBooleanValue(new_value)); 589 kStatsReportingPref, base::Value::CreateBooleanValue(new_value));
554 AttemptMigration(); 590 migration_helper_->MigrateValues();
555 LOG(INFO) << "No metrics policy set will revert to checking " 591 LOG(INFO) << "No metrics policy set will revert to checking "
556 << "consent file which is " 592 << "consent file which is "
557 << (new_value ? "on." : "off."); 593 << (new_value ? "on." : "off.");
558 } 594 }
559 VLOG(1) << "Metrics policy is being set to : " << new_value 595 VLOG(1) << "Metrics policy is being set to : " << new_value
560 << "(use file : " << use_file << ")"; 596 << "(use file : " << use_file << ")";
561 // TODO(pastarmovj): Remove this once we don't need to regenerate the 597 // TODO(pastarmovj): Remove this once we don't need to regenerate the
562 // consent file for the GUID anymore. 598 // consent file for the GUID anymore.
563 OptionsUtil::ResolveMetricsReportingEnabled(new_value); 599 OptionsUtil::ResolveMetricsReportingEnabled(new_value);
564 } 600 }
565 601
566 void DeviceSettingsProvider::ApplyRoamingSetting(bool new_value) { 602 void DeviceSettingsProvider::ApplyRoamingSetting(bool new_value) const {
567 NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary(); 603 NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
568 const NetworkDevice* cellular = cros->FindCellularDevice(); 604 const NetworkDevice* cellular = cros->FindCellularDevice();
569 if (cellular) { 605 if (cellular) {
570 bool device_value = cellular->data_roaming_allowed(); 606 bool device_value = cellular->data_roaming_allowed();
571 if (!device_value && cros->IsCellularAlwaysInRoaming()) { 607 if (!device_value && cros->IsCellularAlwaysInRoaming()) {
572 // If operator requires roaming always enabled, ignore supplied value 608 // If operator requires roaming always enabled, ignore supplied value
573 // and set data roaming allowed in true always. 609 // and set data roaming allowed in true always.
574 cros->SetCellularDataRoamingAllowed(true); 610 cros->SetCellularDataRoamingAllowed(true);
575 } else if (device_value != new_value) { 611 } else if (device_value != new_value) {
576 cros->SetCellularDataRoamingAllowed(new_value); 612 cros->SetCellularDataRoamingAllowed(new_value);
577 } 613 }
578 } 614 }
579 } 615 }
580 616
581 void DeviceSettingsProvider::ApplySideEffects( 617 void DeviceSettingsProvider::ApplySideEffects() const {
582 const em::ChromeDeviceSettingsProto& settings) { 618 const em::PolicyData data = policy();
619 em::ChromeDeviceSettingsProto pol;
620 pol.ParseFromString(data.policy_value());
583 // First migrate metrics settings as needed. 621 // First migrate metrics settings as needed.
584 if (settings.has_metrics_enabled()) 622 if (pol.has_metrics_enabled())
585 ApplyMetricsSetting(false, settings.metrics_enabled().metrics_enabled()); 623 ApplyMetricsSetting(false, pol.metrics_enabled().metrics_enabled());
586 else 624 else
587 ApplyMetricsSetting(true, false); 625 ApplyMetricsSetting(true, false);
588
589 // Next set the roaming setting as needed. 626 // Next set the roaming setting as needed.
590 ApplyRoamingSetting( 627 ApplyRoamingSetting(pol.has_data_roaming_enabled() ?
591 settings.has_data_roaming_enabled() ? 628 pol.data_roaming_enabled().data_roaming_enabled() : false);
592 settings.data_roaming_enabled().data_roaming_enabled() :
593 false);
594 } 629 }
595 630
596 bool DeviceSettingsProvider::MitigateMissingPolicy() { 631 bool DeviceSettingsProvider::MitigateMissingPolicy() {
597 // First check if the device has been owned already and if not exit 632 // First check if the device has been owned already and if not exit
598 // immediately. 633 // immediately.
599 if (g_browser_process->browser_policy_connector()->GetDeviceMode() != 634 if (g_browser_process->browser_policy_connector()->GetDeviceMode() !=
600 policy::DEVICE_MODE_CONSUMER) { 635 policy::DEVICE_MODE_CONSUMER) {
601 return false; 636 return false;
602 } 637 }
603 638
604 // If we are here the policy file were corrupted or missing. This can happen 639 // If we are here the policy file were corrupted or missing. This can happen
605 // because we are migrating Pre R11 device to the new secure policies or there 640 // because we are migrating Pre R11 device to the new secure policies or there
606 // was an attempt to circumvent policy system. In this case we should populate 641 // was an attempt to circumvent policy system. In this case we should populate
607 // the policy cache with "safe-mode" defaults which should allow the owner to 642 // the policy cache with "safe-mode" defaults which should allow the owner to
608 // log in but lock the device for anyone else until the policy blob has been 643 // log in but lock the device for anyone else until the policy blob has been
609 // recreated by the session manager. 644 // recreated by the session manager.
610 LOG(ERROR) << "Corruption of the policy data has been detected." 645 LOG(ERROR) << "Corruption of the policy data has been detected."
611 << "Switching to \"safe-mode\" policies until the owner logs in " 646 << "Switching to \"safe-mode\" policies until the owner logs in "
612 << "to regenerate the policy data."; 647 << "to regenerate the policy data.";
613 648 values_cache_.SetBoolean(kAccountsPrefAllowNewUser, true);
614 device_settings_.Clear(); 649 values_cache_.SetBoolean(kAccountsPrefAllowGuest, true);
615 device_settings_.mutable_allow_new_users()->set_allow_new_users(true);
616 device_settings_.mutable_guest_mode_enabled()->set_guest_mode_enabled(true);
617 em::PolicyData empty_policy_data;
618 UpdateValuesCache(empty_policy_data, device_settings_);
619 values_cache_.SetBoolean(kPolicyMissingMitigationMode, true); 650 values_cache_.SetBoolean(kPolicyMissingMitigationMode, true);
620 trusted_status_ = TRUSTED; 651 trusted_status_ = TRUSTED;
621 652 // Make sure we will recreate the policy once the owner logs in.
653 // Any value not in this list will be left to the default which is fine as
654 // we repopulate the whitelist with the owner and all other existing users
655 // every time the owner enables whitelist filtering on the UI.
656 migration_helper_->AddMigrationValue(
657 kAccountsPrefAllowNewUser, base::Value::CreateBooleanValue(true));
658 migration_helper_->MigrateValues();
622 return true; 659 return true;
623 } 660 }
624 661
625 const base::Value* DeviceSettingsProvider::Get(const std::string& path) const { 662 const base::Value* DeviceSettingsProvider::Get(const std::string& path) const {
626 if (IsControlledSetting(path)) { 663 if (IsControlledSetting(path)) {
627 const base::Value* value; 664 const base::Value* value;
628 if (values_cache_.GetValue(path, &value)) 665 if (values_cache_.GetValue(path, &value))
629 return value; 666 return value;
630 } else { 667 } else {
631 NOTREACHED() << "Trying to get non cros setting."; 668 NOTREACHED() << "Trying to get non cros setting.";
632 } 669 }
633 670
634 return NULL; 671 return NULL;
635 } 672 }
636 673
637 DeviceSettingsProvider::TrustedStatus 674 DeviceSettingsProvider::TrustedStatus
638 DeviceSettingsProvider::PrepareTrustedValues(const base::Closure& cb) { 675 DeviceSettingsProvider::PrepareTrustedValues(const base::Closure& cb) {
639 TrustedStatus status = RequestTrustedEntity(); 676 TrustedStatus status = RequestTrustedEntity();
640 if (status == TEMPORARILY_UNTRUSTED && !cb.is_null()) 677 if (status == TEMPORARILY_UNTRUSTED && !cb.is_null())
641 callbacks_.push_back(cb); 678 callbacks_.push_back(cb);
642 return status; 679 return status;
643 } 680 }
644 681
645 bool DeviceSettingsProvider::HandlesSetting(const std::string& path) const { 682 bool DeviceSettingsProvider::HandlesSetting(const std::string& path) const {
646 return IsControlledSetting(path); 683 return IsControlledSetting(path);
647 } 684 }
648 685
649 DeviceSettingsProvider::TrustedStatus 686 DeviceSettingsProvider::TrustedStatus
650 DeviceSettingsProvider::RequestTrustedEntity() { 687 DeviceSettingsProvider::RequestTrustedEntity() {
651 if (ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE) 688 if (ownership_status_ == OwnershipService::OWNERSHIP_NONE)
652 return TRUSTED; 689 return TRUSTED;
653 return trusted_status_; 690 return trusted_status_;
654 } 691 }
655 692
656 void DeviceSettingsProvider::UpdateAndProceedStoring() { 693 void DeviceSettingsProvider::OnStorePolicyCompleted(
657 // Re-sync the cache from the service. 694 SignedSettings::ReturnCode code) {
658 UpdateFromService(); 695 // In any case reload the policy cache to now.
696 if (code != SignedSettings::SUCCESS) {
697 Reload();
698 } else {
699 trusted_status_ = TRUSTED;
700 // TODO(pastarmovj): Make those side effects responsibility of the
701 // respective subsystems.
702 ApplySideEffects();
703 // Notify the observers we are done.
704 std::vector<base::Closure> callbacks;
705 callbacks.swap(callbacks_);
706 for (size_t i = 0; i < callbacks.size(); ++i)
707 callbacks[i].Run();
708 }
659 709
660 // Trigger the next change if necessary. 710 // Clear the finished task and proceed with any other stores that could be
661 if (trusted_status_ == TRUSTED && 711 // pending by now.
662 !store_callback_factory_.HasWeakPtrs() && 712 delete pending_changes_[0].second;
663 !pending_changes_.empty()) { 713 pending_changes_.erase(pending_changes_.begin());
714 if (!pending_changes_.empty())
664 SetInPolicy(); 715 SetInPolicy();
665 }
666 } 716 }
667 717
668 bool DeviceSettingsProvider::UpdateFromService() { 718 void DeviceSettingsProvider::OnRetrievePolicyCompleted(
669 bool settings_loaded = false; 719 SignedSettings::ReturnCode code,
670 switch (device_settings_service_->status()) { 720 const em::PolicyFetchResponse& policy_data) {
671 case DeviceSettingsService::STORE_SUCCESS: { 721 VLOG(1) << "OnRetrievePolicyCompleted. Error code: " << code
672 const em::PolicyData* policy_data = 722 << ", trusted status : " << trusted_status_
673 device_settings_service_->policy_data(); 723 << ", ownership status : " << ownership_status_;
674 const em::ChromeDeviceSettingsProto* device_settings = 724 switch (code) {
675 device_settings_service_->device_settings(); 725 case SignedSettings::SUCCESS: {
676 if (policy_data && device_settings) { 726 DCHECK(policy_data.has_policy_data());
677 UpdateValuesCache(*policy_data, *device_settings); 727 policy_.ParseFromString(policy_data.policy_data());
678 device_settings_ = *device_settings; 728 signed_settings_cache::Store(policy(),
679 trusted_status_ = TRUSTED; 729 g_browser_process->local_state());
680 730 UpdateValuesCache();
681 // TODO(pastarmovj): Make those side effects responsibility of the 731 trusted_status_ = TRUSTED;
682 // respective subsystems. 732 // TODO(pastarmovj): Make those side effects responsibility of the
683 ApplySideEffects(*device_settings); 733 // respective subsystems.
684 734 ApplySideEffects();
685 settings_loaded = true;
686 } else {
687 // Initial policy load is still pending.
688 trusted_status_ = TEMPORARILY_UNTRUSTED;
689 }
690 break; 735 break;
691 } 736 }
692 case DeviceSettingsService::STORE_NO_POLICY: 737 case SignedSettings::NOT_FOUND:
693 if (MitigateMissingPolicy()) 738 if (MitigateMissingPolicy())
694 break; 739 break;
695 // fall through. 740 case SignedSettings::KEY_UNAVAILABLE: {
696 case DeviceSettingsService::STORE_KEY_UNAVAILABLE: 741 if (ownership_status_ != OwnershipService::OWNERSHIP_TAKEN)
697 VLOG(1) << "No policies present yet, will use the temp storage."; 742 NOTREACHED() << "No policies present yet, will use the temp storage.";
698 trusted_status_ = PERMANENTLY_UNTRUSTED; 743 trusted_status_ = PERMANENTLY_UNTRUSTED;
699 break; 744 break;
700 case DeviceSettingsService::STORE_POLICY_ERROR: 745 }
701 case DeviceSettingsService::STORE_VALIDATION_ERROR: 746 case SignedSettings::BAD_SIGNATURE:
702 case DeviceSettingsService::STORE_INVALID_POLICY: 747 case SignedSettings::OPERATION_FAILED: {
703 case DeviceSettingsService::STORE_OPERATION_FAILED: 748 LOG(ERROR) << "Failed to retrieve cros policies. Reason:" << code;
704 LOG(ERROR) << "Failed to retrieve cros policies. Reason: " 749 if (retries_left_ > 0) {
705 << device_settings_service_->status(); 750 trusted_status_ = TEMPORARILY_UNTRUSTED;
751 retries_left_ -= 1;
752 Reload();
753 return;
754 }
755 LOG(ERROR) << "No retries left";
706 trusted_status_ = PERMANENTLY_UNTRUSTED; 756 trusted_status_ = PERMANENTLY_UNTRUSTED;
707 break; 757 break;
758 }
708 } 759 }
709
710 // Notify the observers we are done. 760 // Notify the observers we are done.
711 std::vector<base::Closure> callbacks; 761 std::vector<base::Closure> callbacks;
712 callbacks.swap(callbacks_); 762 callbacks.swap(callbacks_);
713 for (size_t i = 0; i < callbacks.size(); ++i) 763 for (size_t i = 0; i < callbacks.size(); ++i)
714 callbacks[i].Run(); 764 callbacks[i].Run();
715
716 return settings_loaded;
717 }
718
719 void DeviceSettingsProvider::StoreDeviceSettings() {
720 // Mute all previous callbacks to guarantee the |pending_changes_| queue is
721 // processed serially.
722 store_callback_factory_.InvalidateWeakPtrs();
723
724 device_settings_service_->SignAndStore(
725 scoped_ptr<em::ChromeDeviceSettingsProto>(
726 new em::ChromeDeviceSettingsProto(device_settings_)),
727 base::Bind(&DeviceSettingsProvider::UpdateAndProceedStoring,
728 store_callback_factory_.GetWeakPtr()));
729 }
730
731 void DeviceSettingsProvider::AttemptMigration() {
732 if (device_settings_service_->HasPrivateOwnerKey()) {
733 PrefValueMap::const_iterator i;
734 for (i = migration_values_.begin(); i != migration_values_.end(); ++i)
735 DoSet(i->first, *i->second);
736 migration_values_.Clear();
737 }
738 } 765 }
739 766
740 } // namespace chromeos 767 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698