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
3 // found in the LICENSE file.
5 #include "chrome/browser/chromeos/settings/device_settings_provider.h"
8 #include "base/bind_helpers.h"
9 #include "base/callback.h"
10 #include "base/logging.h"
11 #include "base/metrics/histogram.h"
12 #include "base/prefs/pref_service.h"
13 #include "base/threading/thread_restrictions.h"
14 #include "base/values.h"
15 #include "chrome/browser/browser_process.h"
16 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
17 #include "chrome/browser/chromeos/policy/device_local_account.h"
18 #include "chrome/browser/chromeos/policy/enterprise_install_attributes.h"
19 #include "chrome/browser/chromeos/settings/cros_settings.h"
20 #include "chrome/browser/chromeos/settings/device_settings_cache.h"
21 #include "chrome/browser/metrics/metrics_reporting_state.h"
22 #include "chrome/installer/util/google_update_settings.h"
23 #include "chromeos/chromeos_switches.h"
24 #include "chromeos/dbus/cryptohome_client.h"
25 #include "chromeos/dbus/dbus_thread_manager.h"
26 #include "chromeos/settings/cros_settings_names.h"
27 #include "policy/proto/device_management_backend.pb.h"
29 using google::protobuf::RepeatedField;
30 using google::protobuf::RepeatedPtrField;
32 namespace em = enterprise_management;
38 // List of settings handled by the DeviceSettingsProvider.
39 const char* kKnownSettings[] = {
40 kAccountsPrefAllowGuest,
41 kAccountsPrefAllowNewUser,
42 kAccountsPrefDeviceLocalAccounts,
43 kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled,
44 kAccountsPrefDeviceLocalAccountAutoLoginDelay,
45 kAccountsPrefDeviceLocalAccountAutoLoginId,
46 kAccountsPrefDeviceLocalAccountPromptForNetworkWhenOffline,
47 kAccountsPrefEphemeralUsersEnabled,
48 kAccountsPrefShowUserNamesOnSignIn,
49 kAccountsPrefSupervisedUsersEnabled,
50 kAccountsPrefTransferSAMLCookies,
52 kAllowRedeemChromeOsRegistrationOffers,
53 kAllowedConnectionTypesForUpdate,
55 kAttestationForContentProtectionEnabled,
56 kDeviceAttestationEnabled,
59 kIdleLogoutWarningDuration,
60 kPolicyMissingMitigationMode,
62 kReleaseChannelDelegated,
63 kReportDeviceActivityTimes,
64 kReportDeviceBootMode,
65 kReportDeviceLocation,
66 kReportDeviceNetworkInterfaces,
68 kReportDeviceVersionInfo,
69 kScreenSaverExtensionId,
71 kServiceAccountIdentity,
72 kSignedDataRoamingEnabled,
76 kSystemTimezonePolicy,
77 kSystemUse24HourClock,
79 kVariationsRestrictParameter,
82 bool HasOldMetricsFile() {
83 // TODO(pastarmovj): Remove this once migration is not needed anymore.
84 // If the value is not set we should try to migrate legacy consent file.
85 // Loading consent file state causes us to do blocking IO on UI thread.
86 // Temporarily allow it until we fix http://crbug.com/62626
87 base::ThreadRestrictions::ScopedAllowIO allow_io;
88 return GoogleUpdateSettings::GetCollectStatsConsent();
93 DeviceSettingsProvider::DeviceSettingsProvider(
94 const NotifyObserversCallback& notify_cb,
95 DeviceSettingsService* device_settings_service)
96 : CrosSettingsProvider(notify_cb),
97 device_settings_service_(device_settings_service),
98 trusted_status_(TEMPORARILY_UNTRUSTED),
99 ownership_status_(device_settings_service_->GetOwnershipStatus()),
100 store_callback_factory_(this) {
101 device_settings_service_->AddObserver(this);
102 if (!UpdateFromService()) {
103 // Make sure we have at least the cache data immediately.
104 RetrieveCachedData();
108 DeviceSettingsProvider::~DeviceSettingsProvider() {
109 device_settings_service_->RemoveObserver(this);
113 bool DeviceSettingsProvider::IsDeviceSetting(const std::string& name) {
114 const char** end = kKnownSettings + arraysize(kKnownSettings);
115 return std::find(kKnownSettings, end, name) != end;
118 void DeviceSettingsProvider::DoSet(const std::string& path,
119 const base::Value& in_value) {
120 // Make sure that either the current user is the device owner or the
121 // device doesn't have an owner yet.
122 if (!(device_settings_service_->HasPrivateOwnerKey() ||
123 ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE)) {
124 LOG(WARNING) << "Changing settings from non-owner, setting=" << path;
127 NotifyObservers(path);
131 if (IsDeviceSetting(path)) {
132 pending_changes_.push_back(PendingQueueElement(path, in_value.DeepCopy()));
133 if (!store_callback_factory_.HasWeakPtrs())
136 NOTREACHED() << "Try to set unhandled cros setting " << path;
140 void DeviceSettingsProvider::OwnershipStatusChanged() {
141 DeviceSettingsService::OwnershipStatus new_ownership_status =
142 device_settings_service_->GetOwnershipStatus();
144 // If the device just became owned, write the settings accumulated in the
145 // cache to device settings proper. It is important that writing only happens
146 // in this case, as during normal operation, the contents of the cache should
147 // never overwrite actual device settings.
148 if (new_ownership_status == DeviceSettingsService::OWNERSHIP_TAKEN &&
149 ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE &&
150 device_settings_service_->HasPrivateOwnerKey()) {
151 // There shouldn't be any pending writes, since the cache writes are all
153 DCHECK(!store_callback_factory_.HasWeakPtrs());
155 trusted_status_ = TEMPORARILY_UNTRUSTED;
156 // Apply the locally-accumulated device settings on top of the initial
157 // settings from the service and write back the result.
158 if (device_settings_service_->device_settings()) {
159 em::ChromeDeviceSettingsProto new_settings(
160 *device_settings_service_->device_settings());
161 new_settings.MergeFrom(device_settings_);
162 device_settings_.Swap(&new_settings);
164 StoreDeviceSettings();
167 // The owner key might have become available, allowing migration to happen.
170 ownership_status_ = new_ownership_status;
173 void DeviceSettingsProvider::DeviceSettingsUpdated() {
174 if (!store_callback_factory_.HasWeakPtrs())
175 UpdateAndProceedStoring();
178 void DeviceSettingsProvider::RetrieveCachedData() {
179 em::PolicyData policy_data;
180 if (!device_settings_cache::Retrieve(&policy_data,
181 g_browser_process->local_state()) ||
182 !device_settings_.ParseFromString(policy_data.policy_value())) {
183 VLOG(1) << "Can't retrieve temp store, possibly not created yet.";
186 UpdateValuesCache(policy_data, device_settings_, trusted_status_);
189 void DeviceSettingsProvider::SetInPolicy() {
190 if (pending_changes_.empty()) {
195 if (RequestTrustedEntity() != TRUSTED) {
196 // Re-sync device settings before proceeding.
197 device_settings_service_->Load();
201 std::string prop(pending_changes_.front().first);
202 scoped_ptr<base::Value> value(pending_changes_.front().second);
203 pending_changes_.pop_front();
205 trusted_status_ = TEMPORARILY_UNTRUSTED;
206 if (prop == kAccountsPrefAllowNewUser) {
207 em::AllowNewUsersProto* allow =
208 device_settings_.mutable_allow_new_users();
210 if (value->GetAsBoolean(&allow_value))
211 allow->set_allow_new_users(allow_value);
214 } else if (prop == kAccountsPrefAllowGuest) {
215 em::GuestModeEnabledProto* guest =
216 device_settings_.mutable_guest_mode_enabled();
218 if (value->GetAsBoolean(&guest_value))
219 guest->set_guest_mode_enabled(guest_value);
222 } else if (prop == kAccountsPrefSupervisedUsersEnabled) {
223 em::SupervisedUsersSettingsProto* supervised =
224 device_settings_.mutable_supervised_users_settings();
225 bool supervised_value;
226 if (value->GetAsBoolean(&supervised_value))
227 supervised->set_supervised_users_enabled(supervised_value);
230 } else if (prop == kAccountsPrefShowUserNamesOnSignIn) {
231 em::ShowUserNamesOnSigninProto* show =
232 device_settings_.mutable_show_user_names();
234 if (value->GetAsBoolean(&show_value))
235 show->set_show_user_names(show_value);
238 } else if (prop == kAccountsPrefDeviceLocalAccounts) {
239 em::DeviceLocalAccountsProto* device_local_accounts =
240 device_settings_.mutable_device_local_accounts();
241 device_local_accounts->clear_account();
242 const base::ListValue* accounts_list = NULL;
243 if (value->GetAsList(&accounts_list)) {
244 for (base::ListValue::const_iterator entry(accounts_list->begin());
245 entry != accounts_list->end(); ++entry) {
246 const base::DictionaryValue* entry_dict = NULL;
247 if ((*entry)->GetAsDictionary(&entry_dict)) {
248 em::DeviceLocalAccountInfoProto* account =
249 device_local_accounts->add_account();
250 std::string account_id;
251 if (entry_dict->GetStringWithoutPathExpansion(
252 kAccountsPrefDeviceLocalAccountsKeyId, &account_id)) {
253 account->set_account_id(account_id);
256 if (entry_dict->GetIntegerWithoutPathExpansion(
257 kAccountsPrefDeviceLocalAccountsKeyType, &type)) {
259 static_cast<em::DeviceLocalAccountInfoProto::AccountType>(
262 std::string kiosk_app_id;
263 if (entry_dict->GetStringWithoutPathExpansion(
264 kAccountsPrefDeviceLocalAccountsKeyKioskAppId,
266 account->mutable_kiosk_app()->set_app_id(kiosk_app_id);
275 } else if (prop == kAccountsPrefDeviceLocalAccountAutoLoginId) {
276 em::DeviceLocalAccountsProto* device_local_accounts =
277 device_settings_.mutable_device_local_accounts();
279 if (value->GetAsString(&id))
280 device_local_accounts->set_auto_login_id(id);
283 } else if (prop == kAccountsPrefDeviceLocalAccountAutoLoginDelay) {
284 em::DeviceLocalAccountsProto* device_local_accounts =
285 device_settings_.mutable_device_local_accounts();
287 if (value->GetAsInteger(&delay))
288 device_local_accounts->set_auto_login_delay(delay);
291 } else if (prop == kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled) {
292 em::DeviceLocalAccountsProto* device_local_accounts =
293 device_settings_.mutable_device_local_accounts();
295 if (value->GetAsBoolean(&enabled))
296 device_local_accounts->set_enable_auto_login_bailout(enabled);
300 kAccountsPrefDeviceLocalAccountPromptForNetworkWhenOffline) {
301 em::DeviceLocalAccountsProto* device_local_accounts =
302 device_settings_.mutable_device_local_accounts();
304 if (value->GetAsBoolean(&should_prompt))
305 device_local_accounts->set_prompt_for_network_when_offline(should_prompt);
308 } else if (prop == kSignedDataRoamingEnabled) {
309 em::DataRoamingEnabledProto* roam =
310 device_settings_.mutable_data_roaming_enabled();
311 bool roaming_value = false;
312 if (value->GetAsBoolean(&roaming_value))
313 roam->set_data_roaming_enabled(roaming_value);
316 } else if (prop == kReleaseChannel) {
317 em::ReleaseChannelProto* release_channel =
318 device_settings_.mutable_release_channel();
319 std::string channel_value;
320 if (value->GetAsString(&channel_value))
321 release_channel->set_release_channel(channel_value);
324 } else if (prop == kStatsReportingPref) {
325 em::MetricsEnabledProto* metrics =
326 device_settings_.mutable_metrics_enabled();
327 bool metrics_value = false;
328 if (value->GetAsBoolean(&metrics_value))
329 metrics->set_metrics_enabled(metrics_value);
332 ApplyMetricsSetting(false, metrics_value);
333 } else if (prop == kAccountsPrefUsers) {
334 em::UserWhitelistProto* whitelist_proto =
335 device_settings_.mutable_user_whitelist();
336 whitelist_proto->clear_user_whitelist();
337 const base::ListValue* users;
338 if (value->GetAsList(&users)) {
339 for (base::ListValue::const_iterator i = users->begin();
340 i != users->end(); ++i) {
342 if ((*i)->GetAsString(&email))
343 whitelist_proto->add_user_whitelist(email);
346 } else if (prop == kAccountsPrefEphemeralUsersEnabled) {
347 em::EphemeralUsersEnabledProto* ephemeral_users_enabled =
348 device_settings_.mutable_ephemeral_users_enabled();
349 bool ephemeral_users_enabled_value = false;
350 if (value->GetAsBoolean(&ephemeral_users_enabled_value)) {
351 ephemeral_users_enabled->set_ephemeral_users_enabled(
352 ephemeral_users_enabled_value);
356 } else if (prop == kAllowRedeemChromeOsRegistrationOffers) {
357 em::AllowRedeemChromeOsRegistrationOffersProto* allow_redeem_offers =
358 device_settings_.mutable_allow_redeem_offers();
359 bool allow_redeem_offers_value;
360 if (value->GetAsBoolean(&allow_redeem_offers_value)) {
361 allow_redeem_offers->set_allow_redeem_offers(
362 allow_redeem_offers_value);
366 } else if (prop == kStartUpFlags) {
367 em::StartUpFlagsProto* flags_proto =
368 device_settings_.mutable_start_up_flags();
369 flags_proto->Clear();
370 const base::ListValue* flags;
371 if (value->GetAsList(&flags)) {
372 for (base::ListValue::const_iterator i = flags->begin();
373 i != flags->end(); ++i) {
375 if ((*i)->GetAsString(&flag))
376 flags_proto->add_flags(flag);
379 } else if (prop == kSystemUse24HourClock) {
380 em::SystemUse24HourClockProto* use_24hour_clock_proto =
381 device_settings_.mutable_use_24hour_clock();
382 use_24hour_clock_proto->Clear();
383 bool use_24hour_clock_value;
384 if (value->GetAsBoolean(&use_24hour_clock_value)) {
385 use_24hour_clock_proto->set_use_24hour_clock(use_24hour_clock_value);
389 } else if (prop == kAttestationForContentProtectionEnabled) {
390 em::AttestationSettingsProto* attestation_settings =
391 device_settings_.mutable_attestation_settings();
392 bool setting_enabled;
393 if (value->GetAsBoolean(&setting_enabled)) {
394 attestation_settings->set_content_protection_enabled(setting_enabled);
399 // The remaining settings don't support Set(), since they are not
400 // intended to be customizable by the user:
401 // kAccountsPrefTransferSAMLCookies
403 // kDeviceAttestationEnabled
405 // kIdleLogoutTimeout
406 // kIdleLogoutWarningDuration
407 // kReleaseChannelDelegated
408 // kReportDeviceActivityTimes
409 // kReportDeviceBootMode
410 // kReportDeviceLocation
411 // kReportDeviceVersionInfo
412 // kReportDeviceNetworkInterfaces
413 // kReportDeviceUsers
414 // kScreenSaverExtensionId
415 // kScreenSaverTimeout
416 // kServiceAccountIdentity
418 // kSystemTimezonePolicy
419 // kVariationsRestrictParameter
421 LOG(FATAL) << "Device setting " << prop << " is read-only.";
425 data.set_username(device_settings_service_->GetUsername());
426 CHECK(device_settings_.SerializeToString(data.mutable_policy_value()));
428 // Set the cache to the updated value.
429 UpdateValuesCache(data, device_settings_, trusted_status_);
431 if (ownership_status_ == DeviceSettingsService::OWNERSHIP_TAKEN) {
432 StoreDeviceSettings();
434 if (!device_settings_cache::Store(data, g_browser_process->local_state()))
435 LOG(ERROR) << "Couldn't store to the temp storage.";
437 // OnStorePolicyCompleted won't get called in this case so proceed with any
438 // pending operations immediately.
439 if (!pending_changes_.empty())
444 void DeviceSettingsProvider::DecodeLoginPolicies(
445 const em::ChromeDeviceSettingsProto& policy,
446 PrefValueMap* new_values_cache) const {
447 // For all our boolean settings the following is applicable:
448 // true is default permissive value and false is safe prohibitive value.
450 // kAccountsPrefEphemeralUsersEnabled has a default value of false.
451 // kAccountsPrefSupervisedUsersEnabled has a default value of false
452 // for enterprise devices and true for consumer devices.
453 // kAccountsPrefTransferSAMLCookies has a default value of false.
454 if (policy.has_allow_new_users() &&
455 policy.allow_new_users().has_allow_new_users()) {
456 if (policy.allow_new_users().allow_new_users()) {
457 // New users allowed, user whitelist ignored.
458 new_values_cache->SetBoolean(kAccountsPrefAllowNewUser, true);
460 // New users not allowed, enforce user whitelist if present.
461 new_values_cache->SetBoolean(kAccountsPrefAllowNewUser,
462 !policy.has_user_whitelist());
465 // No configured allow-new-users value, enforce whitelist if non-empty.
466 new_values_cache->SetBoolean(
467 kAccountsPrefAllowNewUser,
468 policy.user_whitelist().user_whitelist_size() == 0);
471 new_values_cache->SetBoolean(
472 kAccountsPrefAllowGuest,
473 !policy.has_guest_mode_enabled() ||
474 !policy.guest_mode_enabled().has_guest_mode_enabled() ||
475 policy.guest_mode_enabled().guest_mode_enabled());
477 policy::BrowserPolicyConnectorChromeOS* connector =
478 g_browser_process->platform_part()->browser_policy_connector_chromeos();
479 bool supervised_users_enabled = false;
480 if (connector->IsEnterpriseManaged()) {
481 supervised_users_enabled =
482 policy.has_supervised_users_settings() &&
483 policy.supervised_users_settings().has_supervised_users_enabled() &&
484 policy.supervised_users_settings().supervised_users_enabled();
486 supervised_users_enabled =
487 !policy.has_supervised_users_settings() ||
488 !policy.supervised_users_settings().has_supervised_users_enabled() ||
489 policy.supervised_users_settings().supervised_users_enabled();
491 new_values_cache->SetBoolean(
492 kAccountsPrefSupervisedUsersEnabled, supervised_users_enabled);
494 new_values_cache->SetBoolean(
495 kAccountsPrefShowUserNamesOnSignIn,
496 !policy.has_show_user_names() ||
497 !policy.show_user_names().has_show_user_names() ||
498 policy.show_user_names().show_user_names());
500 new_values_cache->SetBoolean(
501 kAccountsPrefEphemeralUsersEnabled,
502 policy.has_ephemeral_users_enabled() &&
503 policy.ephemeral_users_enabled().has_ephemeral_users_enabled() &&
504 policy.ephemeral_users_enabled().ephemeral_users_enabled());
506 base::ListValue* list = new base::ListValue();
507 const em::UserWhitelistProto& whitelist_proto = policy.user_whitelist();
508 const RepeatedPtrField<std::string>& whitelist =
509 whitelist_proto.user_whitelist();
510 for (RepeatedPtrField<std::string>::const_iterator it = whitelist.begin();
511 it != whitelist.end(); ++it) {
512 list->Append(new base::StringValue(*it));
514 new_values_cache->SetValue(kAccountsPrefUsers, list);
516 scoped_ptr<base::ListValue> account_list(new base::ListValue());
517 const em::DeviceLocalAccountsProto device_local_accounts_proto =
518 policy.device_local_accounts();
519 const RepeatedPtrField<em::DeviceLocalAccountInfoProto>& accounts =
520 device_local_accounts_proto.account();
521 RepeatedPtrField<em::DeviceLocalAccountInfoProto>::const_iterator entry;
522 for (entry = accounts.begin(); entry != accounts.end(); ++entry) {
523 scoped_ptr<base::DictionaryValue> entry_dict(new base::DictionaryValue());
524 if (entry->has_type()) {
525 if (entry->has_account_id()) {
526 entry_dict->SetStringWithoutPathExpansion(
527 kAccountsPrefDeviceLocalAccountsKeyId, entry->account_id());
529 entry_dict->SetIntegerWithoutPathExpansion(
530 kAccountsPrefDeviceLocalAccountsKeyType, entry->type());
531 if (entry->kiosk_app().has_app_id()) {
532 entry_dict->SetStringWithoutPathExpansion(
533 kAccountsPrefDeviceLocalAccountsKeyKioskAppId,
534 entry->kiosk_app().app_id());
536 } else if (entry->has_deprecated_public_session_id()) {
537 // Deprecated public session specification.
538 entry_dict->SetStringWithoutPathExpansion(
539 kAccountsPrefDeviceLocalAccountsKeyId,
540 entry->deprecated_public_session_id());
541 entry_dict->SetIntegerWithoutPathExpansion(
542 kAccountsPrefDeviceLocalAccountsKeyType,
543 policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION);
545 account_list->Append(entry_dict.release());
547 new_values_cache->SetValue(kAccountsPrefDeviceLocalAccounts,
548 account_list.release());
550 if (policy.has_device_local_accounts()) {
551 if (policy.device_local_accounts().has_auto_login_id()) {
552 new_values_cache->SetString(
553 kAccountsPrefDeviceLocalAccountAutoLoginId,
554 policy.device_local_accounts().auto_login_id());
556 if (policy.device_local_accounts().has_auto_login_delay()) {
557 new_values_cache->SetInteger(
558 kAccountsPrefDeviceLocalAccountAutoLoginDelay,
559 policy.device_local_accounts().auto_login_delay());
563 new_values_cache->SetBoolean(
564 kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled,
565 policy.device_local_accounts().enable_auto_login_bailout());
566 new_values_cache->SetBoolean(
567 kAccountsPrefDeviceLocalAccountPromptForNetworkWhenOffline,
568 policy.device_local_accounts().prompt_for_network_when_offline());
570 if (policy.has_start_up_flags()) {
571 base::ListValue* list = new base::ListValue();
572 const em::StartUpFlagsProto& flags_proto = policy.start_up_flags();
573 const RepeatedPtrField<std::string>& flags = flags_proto.flags();
574 for (RepeatedPtrField<std::string>::const_iterator it = flags.begin();
575 it != flags.end(); ++it) {
576 list->Append(new base::StringValue(*it));
578 new_values_cache->SetValue(kStartUpFlags, list);
581 if (policy.has_saml_settings()) {
582 new_values_cache->SetBoolean(
583 kAccountsPrefTransferSAMLCookies,
584 policy.saml_settings().transfer_saml_cookies());
588 void DeviceSettingsProvider::DecodeKioskPolicies(
589 const em::ChromeDeviceSettingsProto& policy,
590 PrefValueMap* new_values_cache) const {
591 if (policy.has_forced_logout_timeouts()) {
592 if (policy.forced_logout_timeouts().has_idle_logout_timeout()) {
593 new_values_cache->SetInteger(
595 policy.forced_logout_timeouts().idle_logout_timeout());
598 if (policy.forced_logout_timeouts().has_idle_logout_warning_duration()) {
599 new_values_cache->SetInteger(
600 kIdleLogoutWarningDuration,
601 policy.forced_logout_timeouts().idle_logout_warning_duration());
605 if (policy.has_login_screen_saver()) {
606 if (policy.login_screen_saver().has_screen_saver_timeout()) {
607 new_values_cache->SetInteger(
609 policy.login_screen_saver().screen_saver_timeout());
612 if (policy.login_screen_saver().has_screen_saver_extension_id()) {
613 new_values_cache->SetString(
614 kScreenSaverExtensionId,
615 policy.login_screen_saver().screen_saver_extension_id());
619 if (policy.has_app_pack()) {
620 typedef RepeatedPtrField<em::AppPackEntryProto> proto_type;
621 base::ListValue* list = new base::ListValue;
622 const proto_type& app_pack = policy.app_pack().app_pack();
623 for (proto_type::const_iterator it = app_pack.begin();
624 it != app_pack.end(); ++it) {
625 base::DictionaryValue* entry = new base::DictionaryValue;
626 if (it->has_extension_id()) {
627 entry->SetStringWithoutPathExpansion(kAppPackKeyExtensionId,
630 if (it->has_update_url()) {
631 entry->SetStringWithoutPathExpansion(kAppPackKeyUpdateUrl,
636 new_values_cache->SetValue(kAppPack, list);
639 if (policy.has_start_up_urls()) {
640 base::ListValue* list = new base::ListValue();
641 const em::StartUpUrlsProto& urls_proto = policy.start_up_urls();
642 const RepeatedPtrField<std::string>& urls = urls_proto.start_up_urls();
643 for (RepeatedPtrField<std::string>::const_iterator it = urls.begin();
644 it != urls.end(); ++it) {
645 list->Append(new base::StringValue(*it));
647 new_values_cache->SetValue(kStartUpUrls, list);
651 void DeviceSettingsProvider::DecodeNetworkPolicies(
652 const em::ChromeDeviceSettingsProto& policy,
653 PrefValueMap* new_values_cache) const {
654 // kSignedDataRoamingEnabled has a default value of false.
655 new_values_cache->SetBoolean(
656 kSignedDataRoamingEnabled,
657 policy.has_data_roaming_enabled() &&
658 policy.data_roaming_enabled().has_data_roaming_enabled() &&
659 policy.data_roaming_enabled().data_roaming_enabled());
662 void DeviceSettingsProvider::DecodeAutoUpdatePolicies(
663 const em::ChromeDeviceSettingsProto& policy,
664 PrefValueMap* new_values_cache) const {
665 if (policy.has_auto_update_settings()) {
666 const em::AutoUpdateSettingsProto& au_settings_proto =
667 policy.auto_update_settings();
668 if (au_settings_proto.has_update_disabled()) {
669 new_values_cache->SetBoolean(kUpdateDisabled,
670 au_settings_proto.update_disabled());
672 const RepeatedField<int>& allowed_connection_types =
673 au_settings_proto.allowed_connection_types();
674 base::ListValue* list = new base::ListValue();
675 for (RepeatedField<int>::const_iterator i(allowed_connection_types.begin());
676 i != allowed_connection_types.end(); ++i) {
677 list->Append(new base::FundamentalValue(*i));
679 new_values_cache->SetValue(kAllowedConnectionTypesForUpdate, list);
683 void DeviceSettingsProvider::DecodeReportingPolicies(
684 const em::ChromeDeviceSettingsProto& policy,
685 PrefValueMap* new_values_cache) const {
686 if (policy.has_device_reporting()) {
687 const em::DeviceReportingProto& reporting_policy =
688 policy.device_reporting();
689 if (reporting_policy.has_report_version_info()) {
690 new_values_cache->SetBoolean(
691 kReportDeviceVersionInfo,
692 reporting_policy.report_version_info());
694 if (reporting_policy.has_report_activity_times()) {
695 new_values_cache->SetBoolean(
696 kReportDeviceActivityTimes,
697 reporting_policy.report_activity_times());
699 if (reporting_policy.has_report_boot_mode()) {
700 new_values_cache->SetBoolean(
701 kReportDeviceBootMode,
702 reporting_policy.report_boot_mode());
704 if (reporting_policy.has_report_network_interfaces()) {
705 new_values_cache->SetBoolean(
706 kReportDeviceNetworkInterfaces,
707 reporting_policy.report_network_interfaces());
709 if (reporting_policy.has_report_users()) {
710 new_values_cache->SetBoolean(
712 reporting_policy.report_users());
717 void DeviceSettingsProvider::DecodeGenericPolicies(
718 const em::ChromeDeviceSettingsProto& policy,
719 PrefValueMap* new_values_cache) const {
720 if (policy.has_metrics_enabled()) {
721 new_values_cache->SetBoolean(kStatsReportingPref,
722 policy.metrics_enabled().metrics_enabled());
724 new_values_cache->SetBoolean(kStatsReportingPref, HasOldMetricsFile());
727 if (!policy.has_release_channel() ||
728 !policy.release_channel().has_release_channel()) {
729 // Default to an invalid channel (will be ignored).
730 new_values_cache->SetString(kReleaseChannel, "");
732 new_values_cache->SetString(kReleaseChannel,
733 policy.release_channel().release_channel());
736 new_values_cache->SetBoolean(
737 kReleaseChannelDelegated,
738 policy.has_release_channel() &&
739 policy.release_channel().has_release_channel_delegated() &&
740 policy.release_channel().release_channel_delegated());
742 if (policy.has_system_timezone()) {
743 if (policy.system_timezone().has_timezone()) {
744 new_values_cache->SetString(
745 kSystemTimezonePolicy,
746 policy.system_timezone().timezone());
750 if (policy.has_use_24hour_clock()) {
751 if (policy.use_24hour_clock().has_use_24hour_clock()) {
752 new_values_cache->SetBoolean(
753 kSystemUse24HourClock, policy.use_24hour_clock().use_24hour_clock());
757 if (policy.has_allow_redeem_offers()) {
758 new_values_cache->SetBoolean(
759 kAllowRedeemChromeOsRegistrationOffers,
760 policy.allow_redeem_offers().allow_redeem_offers());
762 new_values_cache->SetBoolean(
763 kAllowRedeemChromeOsRegistrationOffers,
767 if (policy.has_variations_parameter()) {
768 new_values_cache->SetString(
769 kVariationsRestrictParameter,
770 policy.variations_parameter().parameter());
773 new_values_cache->SetBoolean(
774 kDeviceAttestationEnabled,
775 policy.attestation_settings().attestation_enabled());
777 if (policy.has_attestation_settings() &&
778 policy.attestation_settings().has_content_protection_enabled()) {
779 new_values_cache->SetBoolean(
780 kAttestationForContentProtectionEnabled,
781 policy.attestation_settings().content_protection_enabled());
783 new_values_cache->SetBoolean(kAttestationForContentProtectionEnabled, true);
787 void DeviceSettingsProvider::UpdateValuesCache(
788 const em::PolicyData& policy_data,
789 const em::ChromeDeviceSettingsProto& settings,
790 TrustedStatus trusted_status) {
791 PrefValueMap new_values_cache;
793 if (policy_data.has_username() && !policy_data.has_request_token())
794 new_values_cache.SetString(kDeviceOwner, policy_data.username());
796 if (policy_data.has_service_account_identity()) {
797 new_values_cache.SetString(kServiceAccountIdentity,
798 policy_data.service_account_identity());
801 DecodeLoginPolicies(settings, &new_values_cache);
802 DecodeKioskPolicies(settings, &new_values_cache);
803 DecodeNetworkPolicies(settings, &new_values_cache);
804 DecodeAutoUpdatePolicies(settings, &new_values_cache);
805 DecodeReportingPolicies(settings, &new_values_cache);
806 DecodeGenericPolicies(settings, &new_values_cache);
808 // Collect all notifications but send them only after we have swapped the
809 // cache so that if somebody actually reads the cache will be already valid.
810 std::vector<std::string> notifications;
811 // Go through the new values and verify in the old ones.
812 PrefValueMap::iterator iter = new_values_cache.begin();
813 for (; iter != new_values_cache.end(); ++iter) {
814 const base::Value* old_value;
815 if (!values_cache_.GetValue(iter->first, &old_value) ||
816 !old_value->Equals(iter->second)) {
817 notifications.push_back(iter->first);
820 // Now check for values that have been removed from the policy blob.
821 for (iter = values_cache_.begin(); iter != values_cache_.end(); ++iter) {
822 const base::Value* value;
823 if (!new_values_cache.GetValue(iter->first, &value))
824 notifications.push_back(iter->first);
827 values_cache_.Swap(&new_values_cache);
828 trusted_status_ = trusted_status;
829 for (size_t i = 0; i < notifications.size(); ++i)
830 NotifyObservers(notifications[i]);
833 void DeviceSettingsProvider::ApplyMetricsSetting(bool use_file,
835 // TODO(pastarmovj): Remove this once migration is not needed anymore.
836 // If the value is not set we should try to migrate legacy consent file.
838 new_value = HasOldMetricsFile();
839 // Make sure the values will get eventually written to the policy file.
840 migration_values_.SetBoolean(kStatsReportingPref, new_value);
842 VLOG(1) << "No metrics policy set will revert to checking "
843 << "consent file which is "
844 << (new_value ? "on." : "off.");
845 UMA_HISTOGRAM_COUNTS("DeviceSettings.MetricsMigrated", 1);
847 VLOG(1) << "Metrics policy is being set to : " << new_value
848 << "(use file : " << use_file << ")";
849 // TODO(pastarmovj): Remove this once we don't need to regenerate the
850 // consent file for the GUID anymore.
851 ResolveMetricsReportingEnabled(new_value);
854 void DeviceSettingsProvider::ApplySideEffects(
855 const em::ChromeDeviceSettingsProto& settings) {
856 // First migrate metrics settings as needed.
857 if (settings.has_metrics_enabled())
858 ApplyMetricsSetting(false, settings.metrics_enabled().metrics_enabled());
860 ApplyMetricsSetting(true, false);
863 bool DeviceSettingsProvider::MitigateMissingPolicy() {
864 // First check if the device has been owned already and if not exit
866 policy::BrowserPolicyConnectorChromeOS* connector =
867 g_browser_process->platform_part()->browser_policy_connector_chromeos();
868 if (connector->GetDeviceMode() != policy::DEVICE_MODE_CONSUMER)
871 // If we are here the policy file were corrupted or missing. This can happen
872 // because we are migrating Pre R11 device to the new secure policies or there
873 // was an attempt to circumvent policy system. In this case we should populate
874 // the policy cache with "safe-mode" defaults which should allow the owner to
875 // log in but lock the device for anyone else until the policy blob has been
876 // recreated by the session manager.
877 LOG(ERROR) << "Corruption of the policy data has been detected."
878 << "Switching to \"safe-mode\" policies until the owner logs in "
879 << "to regenerate the policy data.";
881 device_settings_.Clear();
882 device_settings_.mutable_allow_new_users()->set_allow_new_users(true);
883 device_settings_.mutable_guest_mode_enabled()->set_guest_mode_enabled(true);
884 em::PolicyData empty_policy_data;
885 UpdateValuesCache(empty_policy_data, device_settings_, TRUSTED);
886 values_cache_.SetBoolean(kPolicyMissingMitigationMode, true);
891 const base::Value* DeviceSettingsProvider::Get(const std::string& path) const {
892 if (IsDeviceSetting(path)) {
893 const base::Value* value;
894 if (values_cache_.GetValue(path, &value))
897 NOTREACHED() << "Trying to get non cros setting.";
903 DeviceSettingsProvider::TrustedStatus
904 DeviceSettingsProvider::PrepareTrustedValues(const base::Closure& cb) {
905 TrustedStatus status = RequestTrustedEntity();
906 if (status == TEMPORARILY_UNTRUSTED && !cb.is_null())
907 callbacks_.push_back(cb);
911 bool DeviceSettingsProvider::HandlesSetting(const std::string& path) const {
912 return IsDeviceSetting(path);
915 DeviceSettingsProvider::TrustedStatus
916 DeviceSettingsProvider::RequestTrustedEntity() {
917 if (ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE)
919 return trusted_status_;
922 void DeviceSettingsProvider::UpdateAndProceedStoring() {
923 // Re-sync the cache from the service.
926 // Trigger the next change if necessary.
927 if (trusted_status_ == TRUSTED && !pending_changes_.empty())
931 bool DeviceSettingsProvider::UpdateFromService() {
932 bool settings_loaded = false;
933 switch (device_settings_service_->status()) {
934 case DeviceSettingsService::STORE_SUCCESS: {
935 const em::PolicyData* policy_data =
936 device_settings_service_->policy_data();
937 const em::ChromeDeviceSettingsProto* device_settings =
938 device_settings_service_->device_settings();
939 if (policy_data && device_settings) {
940 if (!device_settings_cache::Store(*policy_data,
941 g_browser_process->local_state())) {
942 LOG(ERROR) << "Couldn't update the local state cache.";
944 UpdateValuesCache(*policy_data, *device_settings, TRUSTED);
945 device_settings_ = *device_settings;
947 // TODO(pastarmovj): Make those side effects responsibility of the
948 // respective subsystems.
949 ApplySideEffects(*device_settings);
951 settings_loaded = true;
953 // Initial policy load is still pending.
954 trusted_status_ = TEMPORARILY_UNTRUSTED;
958 case DeviceSettingsService::STORE_NO_POLICY:
959 if (MitigateMissingPolicy())
962 case DeviceSettingsService::STORE_KEY_UNAVAILABLE:
963 VLOG(1) << "No policies present yet, will use the temp storage.";
964 trusted_status_ = PERMANENTLY_UNTRUSTED;
966 case DeviceSettingsService::STORE_POLICY_ERROR:
967 case DeviceSettingsService::STORE_VALIDATION_ERROR:
968 case DeviceSettingsService::STORE_INVALID_POLICY:
969 case DeviceSettingsService::STORE_OPERATION_FAILED:
970 LOG(ERROR) << "Failed to retrieve cros policies. Reason: "
971 << device_settings_service_->status();
972 trusted_status_ = PERMANENTLY_UNTRUSTED;
974 case DeviceSettingsService::STORE_TEMP_VALIDATION_ERROR:
975 // The policy has failed to validate due to temporary error but it might
976 // take a long time until we recover so behave as it is a permanent error.
977 LOG(ERROR) << "Failed to retrieve cros policies because a temporary "
978 << "validation error has occurred. Retrying might succeed.";
979 trusted_status_ = PERMANENTLY_UNTRUSTED;
983 // Notify the observers we are done.
984 std::vector<base::Closure> callbacks;
985 callbacks.swap(callbacks_);
986 for (size_t i = 0; i < callbacks.size(); ++i)
989 return settings_loaded;
992 void DeviceSettingsProvider::StoreDeviceSettings() {
993 // Mute all previous callbacks to guarantee the |pending_changes_| queue is
994 // processed serially.
995 store_callback_factory_.InvalidateWeakPtrs();
997 device_settings_service_->SignAndStore(
998 scoped_ptr<em::ChromeDeviceSettingsProto>(
999 new em::ChromeDeviceSettingsProto(device_settings_)),
1000 base::Bind(&DeviceSettingsProvider::UpdateAndProceedStoring,
1001 store_callback_factory_.GetWeakPtr()));
1004 void DeviceSettingsProvider::AttemptMigration() {
1005 if (device_settings_service_->HasPrivateOwnerKey()) {
1006 PrefValueMap::const_iterator i;
1007 for (i = migration_values_.begin(); i != migration_values_.end(); ++i)
1008 DoSet(i->first, *i->second);
1009 migration_values_.Clear();
1013 } // namespace chromeos