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

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

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

Powered by Google App Engine
This is Rietveld 408576698