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

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

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

Powered by Google App Engine
This is Rietveld 408576698