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

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, remove blocking GetOwnershipStatus() 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/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 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)), 86 migration_helper_(new DeviceSettingsMigrationHelper()),
94 migration_helper_(new SignedSettingsMigrationHelper()), 87 trusted_status_(TEMPORARILY_UNTRUSTED),
95 retries_left_(kNumRetriesLimit), 88 ownership_status_(device_settings_service_->GetOwnershipStatus()),
96 trusted_status_(TEMPORARILY_UNTRUSTED) { 89 ALLOW_THIS_IN_INITIALIZER_LIST(store_callback_factory_(this)) {
97 // Register for notification when ownership is taken so that we can update 90 device_settings_service_->AddObserver(this);
98 // the |ownership_status_| and reload if needed. 91
99 registrar_.Add(this, chrome::NOTIFICATION_OWNER_KEY_FETCH_ATTEMPT_SUCCEEDED, 92 if (!UpdateFromService()) {
100 content::NotificationService::AllSources()); 93 // Make sure we have at least the cache data immediately.
101 // Make sure we have at least the cache data immediately. 94 RetrieveCachedData();
102 RetrieveCachedData(); 95 }
103 // Start prefetching preferences.
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();
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 // 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();
151 } 149 }
150
151 migration_helper_->MigrateValues();
152
153 ownership_status_ = new_ownership_status;
152 } 154 }
153 155
154 const em::PolicyData DeviceSettingsProvider::policy() const { 156 void DeviceSettingsProvider::DeviceSettingsUpdated() {
155 return policy_; 157 if (!store_callback_factory_.HasWeakPtrs())
158 UpdateFromService();
156 } 159 }
157 160
158 void DeviceSettingsProvider::RetrieveCachedData() { 161 void DeviceSettingsProvider::RetrieveCachedData() {
159 // If there is no owner yet, this function will pull the policy cache from the 162 em::PolicyData policy_data;
160 // temp storage and use that instead. 163 em::ChromeDeviceSettingsProto device_settings;
161 em::PolicyData policy; 164 if (!device_settings_cache::Retrieve(&policy_data,
162 if (!signed_settings_cache::Retrieve(&policy, 165 g_browser_process->local_state()) ||
163 g_browser_process->local_state())) { 166 !device_settings_.ParseFromString(policy_data.policy_value())) {
164 VLOG(1) << "Can't retrieve temp store possibly not created yet."; 167 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 } 168 }
170 169
171 policy_ = policy; 170 UpdateValuesCache(policy_data, device_settings_);
172 UpdateValuesCache();
173 } 171 }
174 172
175 void DeviceSettingsProvider::SetInPolicy() { 173 void DeviceSettingsProvider::SetInPolicy() {
176 if (pending_changes_.empty()) { 174 if (pending_changes_.empty()) {
177 NOTREACHED(); 175 NOTREACHED();
178 return; 176 return;
179 } 177 }
180 178
181 const std::string& prop = pending_changes_[0].first; 179 std::string prop(pending_changes_.front().first);
182 base::Value* value = pending_changes_[0].second; 180 scoped_ptr<base::Value> value(pending_changes_.front().second);
183 if (prop == kDeviceOwner) { 181 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 182
202 if (RequestTrustedEntity() != TRUSTED) { 183 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 184
210 trusted_status_ = TEMPORARILY_UNTRUSTED; 185 trusted_status_ = TEMPORARILY_UNTRUSTED;
211 em::PolicyData data = policy();
212 em::ChromeDeviceSettingsProto pol;
213 pol.ParseFromString(data.policy_value());
214 if (prop == kAccountsPrefAllowNewUser) { 186 if (prop == kAccountsPrefAllowNewUser) {
215 em::AllowNewUsersProto* allow = pol.mutable_allow_new_users(); 187 em::AllowNewUsersProto* allow =
188 device_settings_.mutable_allow_new_users();
216 bool allow_value; 189 bool allow_value;
217 if (value->GetAsBoolean(&allow_value)) 190 if (value->GetAsBoolean(&allow_value))
218 allow->set_allow_new_users(allow_value); 191 allow->set_allow_new_users(allow_value);
219 else 192 else
220 NOTREACHED(); 193 NOTREACHED();
221 } else if (prop == kAccountsPrefAllowGuest) { 194 } else if (prop == kAccountsPrefAllowGuest) {
222 em::GuestModeEnabledProto* guest = pol.mutable_guest_mode_enabled(); 195 em::GuestModeEnabledProto* guest =
196 device_settings_.mutable_guest_mode_enabled();
223 bool guest_value; 197 bool guest_value;
224 if (value->GetAsBoolean(&guest_value)) 198 if (value->GetAsBoolean(&guest_value))
225 guest->set_guest_mode_enabled(guest_value); 199 guest->set_guest_mode_enabled(guest_value);
226 else 200 else
227 NOTREACHED(); 201 NOTREACHED();
228 } else if (prop == kAccountsPrefShowUserNamesOnSignIn) { 202 } else if (prop == kAccountsPrefShowUserNamesOnSignIn) {
229 em::ShowUserNamesOnSigninProto* show = pol.mutable_show_user_names(); 203 em::ShowUserNamesOnSigninProto* show =
204 device_settings_.mutable_show_user_names();
230 bool show_value; 205 bool show_value;
231 if (value->GetAsBoolean(&show_value)) 206 if (value->GetAsBoolean(&show_value))
232 show->set_show_user_names(show_value); 207 show->set_show_user_names(show_value);
233 else 208 else
234 NOTREACHED(); 209 NOTREACHED();
235 } else if (prop == kSignedDataRoamingEnabled) { 210 } else if (prop == kSignedDataRoamingEnabled) {
236 em::DataRoamingEnabledProto* roam = pol.mutable_data_roaming_enabled(); 211 em::DataRoamingEnabledProto* roam =
212 device_settings_.mutable_data_roaming_enabled();
237 bool roaming_value = false; 213 bool roaming_value = false;
238 if (value->GetAsBoolean(&roaming_value)) 214 if (value->GetAsBoolean(&roaming_value))
239 roam->set_data_roaming_enabled(roaming_value); 215 roam->set_data_roaming_enabled(roaming_value);
240 else 216 else
241 NOTREACHED(); 217 NOTREACHED();
242 ApplyRoamingSetting(roaming_value); 218 ApplyRoamingSetting(roaming_value);
243 } else if (prop == kSettingProxyEverywhere) { 219 } else if (prop == kSettingProxyEverywhere) {
244 // TODO(cmasone): NOTIMPLEMENTED() once http://crosbug.com/13052 is fixed. 220 // TODO(cmasone): NOTIMPLEMENTED() once http://crosbug.com/13052 is fixed.
245 std::string proxy_value; 221 std::string proxy_value;
246 if (value->GetAsString(&proxy_value)) { 222 if (value->GetAsString(&proxy_value)) {
247 bool success = 223 bool success =
248 pol.mutable_device_proxy_settings()->ParseFromString(proxy_value); 224 device_settings_.mutable_device_proxy_settings()->ParseFromString(
225 proxy_value);
249 DCHECK(success); 226 DCHECK(success);
250 } else { 227 } else {
251 NOTREACHED(); 228 NOTREACHED();
252 } 229 }
253 } else if (prop == kReleaseChannel) { 230 } else if (prop == kReleaseChannel) {
254 em::ReleaseChannelProto* release_channel = pol.mutable_release_channel(); 231 em::ReleaseChannelProto* release_channel =
232 device_settings_.mutable_release_channel();
255 std::string channel_value; 233 std::string channel_value;
256 if (value->GetAsString(&channel_value)) 234 if (value->GetAsString(&channel_value))
257 release_channel->set_release_channel(channel_value); 235 release_channel->set_release_channel(channel_value);
258 else 236 else
259 NOTREACHED(); 237 NOTREACHED();
260 } else if (prop == kStatsReportingPref) { 238 } else if (prop == kStatsReportingPref) {
261 em::MetricsEnabledProto* metrics = pol.mutable_metrics_enabled(); 239 em::MetricsEnabledProto* metrics =
240 device_settings_.mutable_metrics_enabled();
262 bool metrics_value = false; 241 bool metrics_value = false;
263 if (value->GetAsBoolean(&metrics_value)) 242 if (value->GetAsBoolean(&metrics_value))
264 metrics->set_metrics_enabled(metrics_value); 243 metrics->set_metrics_enabled(metrics_value);
265 else 244 else
266 NOTREACHED(); 245 NOTREACHED();
267 ApplyMetricsSetting(false, metrics_value); 246 ApplyMetricsSetting(false, metrics_value);
268 } else if (prop == kAccountsPrefUsers) { 247 } else if (prop == kAccountsPrefUsers) {
269 em::UserWhitelistProto* whitelist_proto = pol.mutable_user_whitelist(); 248 em::UserWhitelistProto* whitelist_proto =
249 device_settings_.mutable_user_whitelist();
270 whitelist_proto->clear_user_whitelist(); 250 whitelist_proto->clear_user_whitelist();
271 base::ListValue& users = static_cast<base::ListValue&>(*value); 251 base::ListValue& users = static_cast<base::ListValue&>(*value);
272 for (base::ListValue::const_iterator i = users.begin(); 252 for (base::ListValue::const_iterator i = users.begin();
273 i != users.end(); ++i) { 253 i != users.end(); ++i) {
274 std::string email; 254 std::string email;
275 if ((*i)->GetAsString(&email)) 255 if ((*i)->GetAsString(&email))
276 whitelist_proto->add_user_whitelist(email.c_str()); 256 whitelist_proto->add_user_whitelist(email.c_str());
277 } 257 }
278 } else if (prop == kAccountsPrefEphemeralUsersEnabled) { 258 } else if (prop == kAccountsPrefEphemeralUsersEnabled) {
279 em::EphemeralUsersEnabledProto* ephemeral_users_enabled = 259 em::EphemeralUsersEnabledProto* ephemeral_users_enabled =
280 pol.mutable_ephemeral_users_enabled(); 260 device_settings_.mutable_ephemeral_users_enabled();
281 bool ephemeral_users_enabled_value = false; 261 bool ephemeral_users_enabled_value = false;
282 if (value->GetAsBoolean(&ephemeral_users_enabled_value)) 262 if (value->GetAsBoolean(&ephemeral_users_enabled_value)) {
283 ephemeral_users_enabled->set_ephemeral_users_enabled( 263 ephemeral_users_enabled->set_ephemeral_users_enabled(
284 ephemeral_users_enabled_value); 264 ephemeral_users_enabled_value);
285 else 265 } else {
286 NOTREACHED(); 266 NOTREACHED();
267 }
287 } else { 268 } else {
288 // The remaining settings don't support Set(), since they are not 269 // The remaining settings don't support Set(), since they are not
289 // intended to be customizable by the user: 270 // intended to be customizable by the user:
290 // kAppPack 271 // kAppPack
272 // kDeviceOwner
291 // kIdleLogoutTimeout 273 // kIdleLogoutTimeout
292 // kIdleLogoutWarningDuration 274 // kIdleLogoutWarningDuration
293 // kReleaseChannelDelegated 275 // kReleaseChannelDelegated
294 // kReportDeviceVersionInfo 276 // kReportDeviceVersionInfo
295 // kReportDeviceActivityTimes 277 // kReportDeviceActivityTimes
296 // kReportDeviceBootMode 278 // kReportDeviceBootMode
297 // kReportDeviceLocation 279 // kReportDeviceLocation
298 // kScreenSaverExtensionId 280 // kScreenSaverExtensionId
299 // kScreenSaverTimeout 281 // kScreenSaverTimeout
300 // kStartUpUrls 282 // kStartUpUrls
301 283
302 NOTREACHED(); 284 LOG(FATAL) << "Device setting " << prop << " is read-only.";
303 } 285 }
304 data.set_policy_value(pol.SerializeAsString()); 286
287 em::PolicyData data;
288 data.set_username(device_settings_service_->GetUsername());
289 CHECK(device_settings_.SerializeToString(data.mutable_policy_value()));
290
305 // Set the cache to the updated value. 291 // Set the cache to the updated value.
306 policy_ = data; 292 UpdateValuesCache(data, device_settings_);
307 UpdateValuesCache();
308 293
309 if (!signed_settings_cache::Store(data, g_browser_process->local_state())) 294 if (!device_settings_cache::Store(data, g_browser_process->local_state()))
310 LOG(ERROR) << "Couldn't store to the temp storage."; 295 LOG(ERROR) << "Couldn't store to the temp storage.";
311 296
312 if (ownership_status_ == OwnershipService::OWNERSHIP_TAKEN) { 297 if (ownership_status_ == DeviceSettingsService::OWNERSHIP_TAKEN) {
313 em::PolicyFetchResponse policy_envelope; 298 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 { 299 } else {
320 // OnStorePolicyCompleted won't get called in this case so proceed with any 300 // OnStorePolicyCompleted won't get called in this case so proceed with any
321 // pending operations immediately. 301 // pending operations immediately.
322 delete pending_changes_[0].second;
323 pending_changes_.erase(pending_changes_.begin());
324 if (!pending_changes_.empty()) 302 if (!pending_changes_.empty())
325 SetInPolicy(); 303 SetInPolicy();
326 } 304 }
327 } 305 }
328 306
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( 307 void DeviceSettingsProvider::DecodeLoginPolicies(
345 const em::ChromeDeviceSettingsProto& policy, 308 const em::ChromeDeviceSettingsProto& policy,
346 PrefValueMap* new_values_cache) const { 309 PrefValueMap* new_values_cache) const {
347 // For all our boolean settings the following is applicable: 310 // For all our boolean settings the following is applicable:
348 // true is default permissive value and false is safe prohibitive value. 311 // true is default permissive value and false is safe prohibitive value.
349 // Exceptions: 312 // Exceptions:
350 // kSignedDataRoamingEnabled has a default value of false. 313 // kSignedDataRoamingEnabled has a default value of false.
351 // kAccountsPrefEphemeralUsersEnabled has a default value of false. 314 // kAccountsPrefEphemeralUsersEnabled has a default value of false.
352 if (policy.has_allow_new_users() && 315 if (policy.has_allow_new_users() &&
353 policy.allow_new_users().has_allow_new_users() && 316 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()); 484 policy.release_channel().release_channel());
522 } 485 }
523 486
524 new_values_cache->SetBoolean( 487 new_values_cache->SetBoolean(
525 kReleaseChannelDelegated, 488 kReleaseChannelDelegated,
526 policy.has_release_channel() && 489 policy.has_release_channel() &&
527 policy.release_channel().has_release_channel_delegated() && 490 policy.release_channel().has_release_channel_delegated() &&
528 policy.release_channel().release_channel_delegated()); 491 policy.release_channel().release_channel_delegated());
529 } 492 }
530 493
531 void DeviceSettingsProvider::UpdateValuesCache() { 494 void DeviceSettingsProvider::UpdateValuesCache(
532 const em::PolicyData data = policy(); 495 const em::PolicyData& policy_data,
496 const em::ChromeDeviceSettingsProto& settings) {
533 PrefValueMap new_values_cache; 497 PrefValueMap new_values_cache;
534 498
535 if (data.has_username() && !data.has_request_token()) 499 if (policy_data.has_username() && !policy_data.has_request_token())
536 new_values_cache.SetString(kDeviceOwner, data.username()); 500 new_values_cache.SetString(kDeviceOwner, policy_data.username());
537 501
538 em::ChromeDeviceSettingsProto pol; 502 DecodeLoginPolicies(settings, &new_values_cache);
539 pol.ParseFromString(data.policy_value()); 503 DecodeKioskPolicies(settings, &new_values_cache);
540 504 DecodeNetworkPolicies(settings, &new_values_cache);
541 DecodeLoginPolicies(pol, &new_values_cache); 505 DecodeReportingPolicies(settings, &new_values_cache);
542 DecodeKioskPolicies(pol, &new_values_cache); 506 DecodeGenericPolicies(settings, &new_values_cache);
543 DecodeNetworkPolicies(pol, &new_values_cache);
544 DecodeReportingPolicies(pol, &new_values_cache);
545 DecodeGenericPolicies(pol, &new_values_cache);
546 507
547 // Collect all notifications but send them only after we have swapped the 508 // 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. 509 // cache so that if somebody actually reads the cache will be already valid.
549 std::vector<std::string> notifications; 510 std::vector<std::string> notifications;
550 // Go through the new values and verify in the old ones. 511 // Go through the new values and verify in the old ones.
551 PrefValueMap::iterator iter = new_values_cache.begin(); 512 PrefValueMap::iterator iter = new_values_cache.begin();
552 for (; iter != new_values_cache.end(); ++iter) { 513 for (; iter != new_values_cache.end(); ++iter) {
553 const base::Value* old_value; 514 const base::Value* old_value;
554 if (!values_cache_.GetValue(iter->first, &old_value) || 515 if (!values_cache_.GetValue(iter->first, &old_value) ||
555 !old_value->Equals(iter->second)) { 516 !old_value->Equals(iter->second)) {
(...skipping 16 matching lines...) Expand all
572 bool new_value) const { 533 bool new_value) const {
573 // TODO(pastarmovj): Remove this once migration is not needed anymore. 534 // TODO(pastarmovj): Remove this once migration is not needed anymore.
574 // If the value is not set we should try to migrate legacy consent file. 535 // If the value is not set we should try to migrate legacy consent file.
575 if (use_file) { 536 if (use_file) {
576 new_value = HasOldMetricsFile(); 537 new_value = HasOldMetricsFile();
577 // Make sure the values will get eventually written to the policy file. 538 // Make sure the values will get eventually written to the policy file.
578 migration_helper_->AddMigrationValue( 539 migration_helper_->AddMigrationValue(
579 kStatsReportingPref, base::Value::CreateBooleanValue(new_value)); 540 kStatsReportingPref, base::Value::CreateBooleanValue(new_value));
580 migration_helper_->MigrateValues(); 541 migration_helper_->MigrateValues();
581 LOG(INFO) << "No metrics policy set will revert to checking " 542 LOG(INFO) << "No metrics policy set will revert to checking "
582 << "consent file which is " 543 << "consent file which is "
583 << (new_value ? "on." : "off."); 544 << (new_value ? "on." : "off.");
584 } 545 }
585 VLOG(1) << "Metrics policy is being set to : " << new_value 546 VLOG(1) << "Metrics policy is being set to : " << new_value
586 << "(use file : " << use_file << ")"; 547 << "(use file : " << use_file << ")";
587 // TODO(pastarmovj): Remove this once we don't need to regenerate the 548 // TODO(pastarmovj): Remove this once we don't need to regenerate the
588 // consent file for the GUID anymore. 549 // consent file for the GUID anymore.
589 OptionsUtil::ResolveMetricsReportingEnabled(new_value); 550 OptionsUtil::ResolveMetricsReportingEnabled(new_value);
590 } 551 }
591 552
592 void DeviceSettingsProvider::ApplyRoamingSetting(bool new_value) const { 553 void DeviceSettingsProvider::ApplyRoamingSetting(bool new_value) const {
593 NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary(); 554 NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
594 const NetworkDevice* cellular = cros->FindCellularDevice(); 555 const NetworkDevice* cellular = cros->FindCellularDevice();
595 if (cellular) { 556 if (cellular) {
596 bool device_value = cellular->data_roaming_allowed(); 557 bool device_value = cellular->data_roaming_allowed();
597 if (!device_value && cros->IsCellularAlwaysInRoaming()) { 558 if (!device_value && cros->IsCellularAlwaysInRoaming()) {
598 // If operator requires roaming always enabled, ignore supplied value 559 // If operator requires roaming always enabled, ignore supplied value
599 // and set data roaming allowed in true always. 560 // and set data roaming allowed in true always.
600 cros->SetCellularDataRoamingAllowed(true); 561 cros->SetCellularDataRoamingAllowed(true);
601 } else if (device_value != new_value) { 562 } else if (device_value != new_value) {
602 cros->SetCellularDataRoamingAllowed(new_value); 563 cros->SetCellularDataRoamingAllowed(new_value);
603 } 564 }
604 } 565 }
605 } 566 }
606 567
607 void DeviceSettingsProvider::ApplySideEffects() const { 568 void DeviceSettingsProvider::ApplySideEffects(
608 const em::PolicyData data = policy(); 569 const em::ChromeDeviceSettingsProto& settings) const {
609 em::ChromeDeviceSettingsProto pol;
610 pol.ParseFromString(data.policy_value());
611 // First migrate metrics settings as needed. 570 // First migrate metrics settings as needed.
612 if (pol.has_metrics_enabled()) 571 if (settings.has_metrics_enabled())
613 ApplyMetricsSetting(false, pol.metrics_enabled().metrics_enabled()); 572 ApplyMetricsSetting(false, settings.metrics_enabled().metrics_enabled());
614 else 573 else
615 ApplyMetricsSetting(true, false); 574 ApplyMetricsSetting(true, false);
575
616 // Next set the roaming setting as needed. 576 // Next set the roaming setting as needed.
617 ApplyRoamingSetting(pol.has_data_roaming_enabled() ? 577 ApplyRoamingSetting(
618 pol.data_roaming_enabled().data_roaming_enabled() : false); 578 settings.has_data_roaming_enabled() ?
579 settings.data_roaming_enabled().data_roaming_enabled() :
580 false);
619 } 581 }
620 582
621 bool DeviceSettingsProvider::MitigateMissingPolicy() { 583 bool DeviceSettingsProvider::MitigateMissingPolicy() {
622 // First check if the device has been owned already and if not exit 584 // First check if the device has been owned already and if not exit
623 // immediately. 585 // immediately.
624 if (g_browser_process->browser_policy_connector()->GetDeviceMode() != 586 if (g_browser_process->browser_policy_connector()->GetDeviceMode() !=
625 policy::DEVICE_MODE_CONSUMER) { 587 policy::DEVICE_MODE_CONSUMER) {
626 return false; 588 return false;
627 } 589 }
628 590
629 // If we are here the policy file were corrupted or missing. This can happen 591 // 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 592 // 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 593 // 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 594 // 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 595 // log in but lock the device for anyone else until the policy blob has been
634 // recreated by the session manager. 596 // recreated by the session manager.
635 LOG(ERROR) << "Corruption of the policy data has been detected." 597 LOG(ERROR) << "Corruption of the policy data has been detected."
636 << "Switching to \"safe-mode\" policies until the owner logs in " 598 << "Switching to \"safe-mode\" policies until the owner logs in "
637 << "to regenerate the policy data."; 599 << "to regenerate the policy data.";
638 values_cache_.SetBoolean(kAccountsPrefAllowNewUser, true); 600 values_cache_.SetBoolean(kAccountsPrefAllowNewUser, true);
639 values_cache_.SetBoolean(kAccountsPrefAllowGuest, true); 601 values_cache_.SetBoolean(kAccountsPrefAllowGuest, true);
640 values_cache_.SetBoolean(kPolicyMissingMitigationMode, true); 602 values_cache_.SetBoolean(kPolicyMissingMitigationMode, true);
641 trusted_status_ = TRUSTED; 603 trusted_status_ = TRUSTED;
642 // Make sure we will recreate the policy once the owner logs in. 604 // 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 605 // 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 606 // we repopulate the whitelist with the owner and all other existing users
645 // every time the owner enables whitelist filtering on the UI. 607 // every time the owner enables whitelist filtering on the UI.
646 migration_helper_->AddMigrationValue( 608 migration_helper_->AddMigrationValue(kAccountsPrefAllowNewUser,
647 kAccountsPrefAllowNewUser, base::Value::CreateBooleanValue(true)); 609 base::Value::CreateBooleanValue(true));
648 migration_helper_->MigrateValues(); 610 migration_helper_->MigrateValues();
649 return true; 611 return true;
650 } 612 }
651 613
652 const base::Value* DeviceSettingsProvider::Get(const std::string& path) const { 614 const base::Value* DeviceSettingsProvider::Get(const std::string& path) const {
653 if (IsControlledSetting(path)) { 615 if (IsControlledSetting(path)) {
654 const base::Value* value; 616 const base::Value* value;
655 if (values_cache_.GetValue(path, &value)) 617 if (values_cache_.GetValue(path, &value))
656 return value; 618 return value;
657 } else { 619 } else {
(...skipping 10 matching lines...) Expand all
668 callbacks_.push_back(cb); 630 callbacks_.push_back(cb);
669 return status; 631 return status;
670 } 632 }
671 633
672 bool DeviceSettingsProvider::HandlesSetting(const std::string& path) const { 634 bool DeviceSettingsProvider::HandlesSetting(const std::string& path) const {
673 return IsControlledSetting(path); 635 return IsControlledSetting(path);
674 } 636 }
675 637
676 DeviceSettingsProvider::TrustedStatus 638 DeviceSettingsProvider::TrustedStatus
677 DeviceSettingsProvider::RequestTrustedEntity() { 639 DeviceSettingsProvider::RequestTrustedEntity() {
678 if (ownership_status_ == OwnershipService::OWNERSHIP_NONE) 640 if (ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE)
679 return TRUSTED; 641 return TRUSTED;
680 return trusted_status_; 642 return trusted_status_;
681 } 643 }
682 644
683 void DeviceSettingsProvider::OnStorePolicyCompleted( 645 void DeviceSettingsProvider::OnStorePolicyCompleted() {
684 SignedSettings::ReturnCode code) { 646 // Re-sync the cache from the service.
685 // In any case reload the policy cache to now. 647 UpdateFromService();
686 if (code != SignedSettings::SUCCESS)
687 Reload();
688 else
689 trusted_status_ = TRUSTED;
690 648
691 // Clear the finished task and proceed with any other stores that could be 649 // If the backend is in healthy state, trigger the next change.
692 // pending by now. 650 if (trusted_status_ == TRUSTED) {
693 delete pending_changes_[0].second; 651 if (!pending_changes_.empty())
694 pending_changes_.erase(pending_changes_.begin()); 652 SetInPolicy();
695 if (!pending_changes_.empty()) 653 }
696 SetInPolicy();
697 } 654 }
698 655
699 void DeviceSettingsProvider::OnRetrievePolicyCompleted( 656 bool DeviceSettingsProvider::UpdateFromService() {
700 SignedSettings::ReturnCode code, 657 bool settings_loaded = false;
701 const em::PolicyFetchResponse& policy_data) { 658 switch (device_settings_service_->status()) {
702 VLOG(1) << "OnRetrievePolicyCompleted. Error code: " << code 659 case DeviceSettingsService::STORE_SUCCESS: {
703 << ", trusted status : " << trusted_status_ 660 const em::PolicyData* policy_data =
704 << ", ownership status : " << ownership_status_; 661 device_settings_service_->policy_data();
705 switch (code) { 662 const em::ChromeDeviceSettingsProto* device_settings =
706 case SignedSettings::SUCCESS: { 663 device_settings_service_->device_settings();
707 DCHECK(policy_data.has_policy_data()); 664 if (policy_data && device_settings) {
708 policy_.ParseFromString(policy_data.policy_data()); 665 UpdateValuesCache(*policy_data, *device_settings);
709 signed_settings_cache::Store(policy(), 666 trusted_status_ = TRUSTED;
710 g_browser_process->local_state()); 667
711 UpdateValuesCache(); 668 // TODO(pastarmovj): Make those side effects responsibility of the
712 trusted_status_ = TRUSTED; 669 // respective subsystems.
713 // TODO(pastarmovj): Make those side effects responsibility of the 670 ApplySideEffects(*device_settings);
714 // respective subsystems. 671
715 ApplySideEffects(); 672 settings_loaded = true;
673 } else {
674 // Initial policy load is still pending.
675 trusted_status_ = TEMPORARILY_UNTRUSTED;
676 }
716 break; 677 break;
717 } 678 }
718 case SignedSettings::NOT_FOUND: 679 case DeviceSettingsService::STORE_NO_POLICY:
719 if (MitigateMissingPolicy()) 680 if (MitigateMissingPolicy())
720 break; 681 break;
721 case SignedSettings::KEY_UNAVAILABLE: { 682 // fall through.
722 if (ownership_status_ != OwnershipService::OWNERSHIP_TAKEN) 683 case DeviceSettingsService::STORE_KEY_UNAVAILABLE:
723 NOTREACHED() << "No policies present yet, will use the temp storage."; 684 VLOG(1) << "No policies present yet, will use the temp storage.";
724 trusted_status_ = PERMANENTLY_UNTRUSTED; 685 trusted_status_ = PERMANENTLY_UNTRUSTED;
725 break; 686 break;
726 } 687 case DeviceSettingsService::STORE_POLICY_ERROR:
727 case SignedSettings::BAD_SIGNATURE: 688 case DeviceSettingsService::STORE_VALIDATION_ERROR:
728 case SignedSettings::OPERATION_FAILED: { 689 case DeviceSettingsService::STORE_INVALID_POLICY:
729 LOG(ERROR) << "Failed to retrieve cros policies. Reason:" << code; 690 case DeviceSettingsService::STORE_OPERATION_FAILED:
730 if (retries_left_ > 0) { 691 LOG(ERROR) << "Failed to retrieve cros policies. Reason:"
731 trusted_status_ = TEMPORARILY_UNTRUSTED; 692 << device_settings_service_->status();
732 retries_left_ -= 1;
733 Reload();
734 return;
735 }
736 LOG(ERROR) << "No retries left";
737 trusted_status_ = PERMANENTLY_UNTRUSTED; 693 trusted_status_ = PERMANENTLY_UNTRUSTED;
738 break; 694 break;
739 }
740 } 695 }
696
741 // Notify the observers we are done. 697 // Notify the observers we are done.
742 std::vector<base::Closure> callbacks; 698 std::vector<base::Closure> callbacks;
743 callbacks.swap(callbacks_); 699 callbacks.swap(callbacks_);
744 for (size_t i = 0; i < callbacks.size(); ++i) 700 for (size_t i = 0; i < callbacks.size(); ++i)
745 callbacks[i].Run(); 701 callbacks[i].Run();
702
703 return settings_loaded;
704 }
705
706 void DeviceSettingsProvider::StoreDeviceSettings() {
707 // Mute all previous callbacks to guarantee the |pending_changes_| queue is
708 // processed serially.
709 store_callback_factory_.InvalidateWeakPtrs();
710
711 device_settings_service_->SignAndStore(
712 scoped_ptr<em::ChromeDeviceSettingsProto>(
713 new em::ChromeDeviceSettingsProto(device_settings_)),
714 base::Bind(&DeviceSettingsProvider::OnStorePolicyCompleted,
715 store_callback_factory_.GetWeakPtr()));
746 } 716 }
747 717
748 } // namespace chromeos 718 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698