device_settings_provider.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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. 4 5#include "chrome/browser/chromeos/settings/device_settings_provider.h" 6 7#include "base/bind.h" 8#include "base/bind_helpers.h" 9#include "base/callback.h" 10#include "base/command_line.h" 11#include "base/logging.h" 12#include "base/metrics/histogram.h" 13#include "base/prefs/pref_service.h" 14#include "base/threading/thread_restrictions.h" 15#include "base/values.h" 16#include "chrome/browser/browser_process.h" 17#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" 18#include "chrome/browser/chromeos/policy/device_local_account.h" 19#include "chrome/browser/chromeos/settings/cros_settings.h" 20#include "chrome/browser/chromeos/settings/device_settings_cache.h" 21#include "chrome/browser/ui/options/options_util.h" 22#include "chrome/installer/util/google_update_settings.h" 23#include "chromeos/chromeos_switches.h" 24#include "chromeos/settings/cros_settings_names.h" 25#include "components/policy/core/common/cloud/cloud_policy_constants.h" 26#include "policy/proto/device_management_backend.pb.h" 27 28using google::protobuf::RepeatedField; 29using google::protobuf::RepeatedPtrField; 30 31namespace em = enterprise_management; 32 33namespace chromeos { 34 35namespace { 36 37// List of settings handled by the DeviceSettingsProvider. 38const char* kKnownSettings[] = { 39 kAccountsPrefAllowGuest, 40 kAccountsPrefAllowNewUser, 41 kAccountsPrefDeviceLocalAccounts, 42 kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled, 43 kAccountsPrefDeviceLocalAccountAutoLoginDelay, 44 kAccountsPrefDeviceLocalAccountAutoLoginId, 45 kAccountsPrefDeviceLocalAccountPromptForNetworkWhenOffline, 46 kAccountsPrefEphemeralUsersEnabled, 47 kAccountsPrefShowUserNamesOnSignIn, 48 kAccountsPrefSupervisedUsersEnabled, 49 kAccountsPrefUsers, 50 kAllowRedeemChromeOsRegistrationOffers, 51 kAllowedConnectionTypesForUpdate, 52 kAppPack, 53 kAttestationForContentProtectionEnabled, 54 kDeviceAttestationEnabled, 55 kDeviceOwner, 56 kIdleLogoutTimeout, 57 kIdleLogoutWarningDuration, 58 kPolicyMissingMitigationMode, 59 kReleaseChannel, 60 kReleaseChannelDelegated, 61 kReportDeviceActivityTimes, 62 kReportDeviceBootMode, 63 kReportDeviceLocation, 64 kReportDeviceNetworkInterfaces, 65 kReportDeviceUsers, 66 kReportDeviceVersionInfo, 67 kScreenSaverExtensionId, 68 kScreenSaverTimeout, 69 kSignedDataRoamingEnabled, 70 kStartUpFlags, 71 kStartUpUrls, 72 kStatsReportingPref, 73 kSystemTimezonePolicy, 74 kSystemUse24HourClock, 75 kUpdateDisabled, 76 kVariationsRestrictParameter, 77}; 78 79bool HasOldMetricsFile() { 80 // TODO(pastarmovj): Remove this once migration is not needed anymore. 81 // If the value is not set we should try to migrate legacy consent file. 82 // Loading consent file state causes us to do blocking IO on UI thread. 83 // Temporarily allow it until we fix http://crbug.com/62626 84 base::ThreadRestrictions::ScopedAllowIO allow_io; 85 return GoogleUpdateSettings::GetCollectStatsConsent(); 86} 87 88} // namespace 89 90DeviceSettingsProvider::DeviceSettingsProvider( 91 const NotifyObserversCallback& notify_cb, 92 DeviceSettingsService* device_settings_service) 93 : CrosSettingsProvider(notify_cb), 94 device_settings_service_(device_settings_service), 95 trusted_status_(TEMPORARILY_UNTRUSTED), 96 ownership_status_(device_settings_service_->GetOwnershipStatus()), 97 store_callback_factory_(this) { 98 device_settings_service_->AddObserver(this); 99 if (!UpdateFromService()) { 100 // Make sure we have at least the cache data immediately. 101 RetrieveCachedData(); 102 } 103} 104 105DeviceSettingsProvider::~DeviceSettingsProvider() { 106 device_settings_service_->RemoveObserver(this); 107} 108 109// static 110bool DeviceSettingsProvider::IsDeviceSetting(const std::string& name) { 111 const char** end = kKnownSettings + arraysize(kKnownSettings); 112 return std::find(kKnownSettings, end, name) != end; 113} 114 115void DeviceSettingsProvider::DoSet(const std::string& path, 116 const base::Value& in_value) { 117 // Make sure that either the current user is the device owner or the 118 // device doesn't have an owner yet. 119 if (!(device_settings_service_->HasPrivateOwnerKey() || 120 ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE)) { 121 LOG(WARNING) << "Changing settings from non-owner, setting=" << path; 122 123 // Revert UI change. 124 NotifyObservers(path); 125 return; 126 } 127 128 if (IsDeviceSetting(path)) { 129 pending_changes_.push_back(PendingQueueElement(path, in_value.DeepCopy())); 130 if (!store_callback_factory_.HasWeakPtrs()) 131 SetInPolicy(); 132 } else { 133 NOTREACHED() << "Try to set unhandled cros setting " << path; 134 } 135} 136 137void DeviceSettingsProvider::OwnershipStatusChanged() { 138 DeviceSettingsService::OwnershipStatus new_ownership_status = 139 device_settings_service_->GetOwnershipStatus(); 140 141 // If the device just became owned, write the settings accumulated in the 142 // cache to device settings proper. It is important that writing only happens 143 // in this case, as during normal operation, the contents of the cache should 144 // never overwrite actual device settings. 145 if (new_ownership_status == DeviceSettingsService::OWNERSHIP_TAKEN && 146 ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE && 147 device_settings_service_->HasPrivateOwnerKey()) { 148 // There shouldn't be any pending writes, since the cache writes are all 149 // immediate. 150 DCHECK(!store_callback_factory_.HasWeakPtrs()); 151 152 // Apply the locally-accumulated device settings on top of the initial 153 // settings from the service and write back the result. 154 if (device_settings_service_->device_settings()) { 155 em::ChromeDeviceSettingsProto new_settings( 156 *device_settings_service_->device_settings()); 157 new_settings.MergeFrom(device_settings_); 158 device_settings_.Swap(&new_settings); 159 } 160 StoreDeviceSettings(); 161 } 162 163 // The owner key might have become available, allowing migration to happen. 164 AttemptMigration(); 165 166 ownership_status_ = new_ownership_status; 167} 168 169void DeviceSettingsProvider::DeviceSettingsUpdated() { 170 if (!store_callback_factory_.HasWeakPtrs()) 171 UpdateAndProceedStoring(); 172} 173 174void DeviceSettingsProvider::RetrieveCachedData() { 175 em::PolicyData policy_data; 176 if (!device_settings_cache::Retrieve(&policy_data, 177 g_browser_process->local_state()) || 178 !device_settings_.ParseFromString(policy_data.policy_value())) { 179 VLOG(1) << "Can't retrieve temp store, possibly not created yet."; 180 } 181 182 UpdateValuesCache(policy_data, device_settings_, trusted_status_); 183} 184 185void DeviceSettingsProvider::SetInPolicy() { 186 if (pending_changes_.empty()) { 187 NOTREACHED(); 188 return; 189 } 190 191 if (RequestTrustedEntity() != TRUSTED) { 192 // Re-sync device settings before proceeding. 193 device_settings_service_->Load(); 194 return; 195 } 196 197 std::string prop(pending_changes_.front().first); 198 scoped_ptr<base::Value> value(pending_changes_.front().second); 199 pending_changes_.pop_front(); 200 201 trusted_status_ = TEMPORARILY_UNTRUSTED; 202 if (prop == kAccountsPrefAllowNewUser) { 203 em::AllowNewUsersProto* allow = 204 device_settings_.mutable_allow_new_users(); 205 bool allow_value; 206 if (value->GetAsBoolean(&allow_value)) 207 allow->set_allow_new_users(allow_value); 208 else 209 NOTREACHED(); 210 } else if (prop == kAccountsPrefAllowGuest) { 211 em::GuestModeEnabledProto* guest = 212 device_settings_.mutable_guest_mode_enabled(); 213 bool guest_value; 214 if (value->GetAsBoolean(&guest_value)) 215 guest->set_guest_mode_enabled(guest_value); 216 else 217 NOTREACHED(); 218 } else if (prop == kAccountsPrefShowUserNamesOnSignIn) { 219 em::ShowUserNamesOnSigninProto* show = 220 device_settings_.mutable_show_user_names(); 221 bool show_value; 222 if (value->GetAsBoolean(&show_value)) 223 show->set_show_user_names(show_value); 224 else 225 NOTREACHED(); 226 } else if (prop == kAccountsPrefDeviceLocalAccounts) { 227 em::DeviceLocalAccountsProto* device_local_accounts = 228 device_settings_.mutable_device_local_accounts(); 229 device_local_accounts->clear_account(); 230 const base::ListValue* accounts_list = NULL; 231 if (value->GetAsList(&accounts_list)) { 232 for (base::ListValue::const_iterator entry(accounts_list->begin()); 233 entry != accounts_list->end(); ++entry) { 234 const base::DictionaryValue* entry_dict = NULL; 235 if ((*entry)->GetAsDictionary(&entry_dict)) { 236 em::DeviceLocalAccountInfoProto* account = 237 device_local_accounts->add_account(); 238 std::string account_id; 239 if (entry_dict->GetStringWithoutPathExpansion( 240 kAccountsPrefDeviceLocalAccountsKeyId, &account_id)) { 241 account->set_account_id(account_id); 242 } 243 int type; 244 if (entry_dict->GetIntegerWithoutPathExpansion( 245 kAccountsPrefDeviceLocalAccountsKeyType, &type)) { 246 account->set_type( 247 static_cast<em::DeviceLocalAccountInfoProto::AccountType>( 248 type)); 249 } 250 std::string kiosk_app_id; 251 if (entry_dict->GetStringWithoutPathExpansion( 252 kAccountsPrefDeviceLocalAccountsKeyKioskAppId, 253 &kiosk_app_id)) { 254 account->mutable_kiosk_app()->set_app_id(kiosk_app_id); 255 } 256 } else { 257 NOTREACHED(); 258 } 259 } 260 } else { 261 NOTREACHED(); 262 } 263 } else if (prop == kAccountsPrefDeviceLocalAccountAutoLoginId) { 264 em::DeviceLocalAccountsProto* device_local_accounts = 265 device_settings_.mutable_device_local_accounts(); 266 std::string id; 267 if (value->GetAsString(&id)) 268 device_local_accounts->set_auto_login_id(id); 269 else 270 NOTREACHED(); 271 } else if (prop == kAccountsPrefDeviceLocalAccountAutoLoginDelay) { 272 em::DeviceLocalAccountsProto* device_local_accounts = 273 device_settings_.mutable_device_local_accounts(); 274 int delay; 275 if (value->GetAsInteger(&delay)) 276 device_local_accounts->set_auto_login_delay(delay); 277 else 278 NOTREACHED(); 279 } else if (prop == kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled) { 280 em::DeviceLocalAccountsProto* device_local_accounts = 281 device_settings_.mutable_device_local_accounts(); 282 bool enabled; 283 if (value->GetAsBoolean(&enabled)) 284 device_local_accounts->set_enable_auto_login_bailout(enabled); 285 else 286 NOTREACHED(); 287 } else if (prop == 288 kAccountsPrefDeviceLocalAccountPromptForNetworkWhenOffline) { 289 em::DeviceLocalAccountsProto* device_local_accounts = 290 device_settings_.mutable_device_local_accounts(); 291 bool should_prompt; 292 if (value->GetAsBoolean(&should_prompt)) 293 device_local_accounts->set_prompt_for_network_when_offline(should_prompt); 294 else 295 NOTREACHED(); 296 } else if (prop == kSignedDataRoamingEnabled) { 297 em::DataRoamingEnabledProto* roam = 298 device_settings_.mutable_data_roaming_enabled(); 299 bool roaming_value = false; 300 if (value->GetAsBoolean(&roaming_value)) 301 roam->set_data_roaming_enabled(roaming_value); 302 else 303 NOTREACHED(); 304 } else if (prop == kReleaseChannel) { 305 em::ReleaseChannelProto* release_channel = 306 device_settings_.mutable_release_channel(); 307 std::string channel_value; 308 if (value->GetAsString(&channel_value)) 309 release_channel->set_release_channel(channel_value); 310 else 311 NOTREACHED(); 312 } else if (prop == kStatsReportingPref) { 313 em::MetricsEnabledProto* metrics = 314 device_settings_.mutable_metrics_enabled(); 315 bool metrics_value = false; 316 if (value->GetAsBoolean(&metrics_value)) 317 metrics->set_metrics_enabled(metrics_value); 318 else 319 NOTREACHED(); 320 ApplyMetricsSetting(false, metrics_value); 321 } else if (prop == kAccountsPrefUsers) { 322 em::UserWhitelistProto* whitelist_proto = 323 device_settings_.mutable_user_whitelist(); 324 whitelist_proto->clear_user_whitelist(); 325 const base::ListValue* users; 326 if (value->GetAsList(&users)) { 327 for (base::ListValue::const_iterator i = users->begin(); 328 i != users->end(); ++i) { 329 std::string email; 330 if ((*i)->GetAsString(&email)) 331 whitelist_proto->add_user_whitelist(email); 332 } 333 } 334 } else if (prop == kAccountsPrefEphemeralUsersEnabled) { 335 em::EphemeralUsersEnabledProto* ephemeral_users_enabled = 336 device_settings_.mutable_ephemeral_users_enabled(); 337 bool ephemeral_users_enabled_value = false; 338 if (value->GetAsBoolean(&ephemeral_users_enabled_value)) { 339 ephemeral_users_enabled->set_ephemeral_users_enabled( 340 ephemeral_users_enabled_value); 341 } else { 342 NOTREACHED(); 343 } 344 } else if (prop == kAllowRedeemChromeOsRegistrationOffers) { 345 em::AllowRedeemChromeOsRegistrationOffersProto* allow_redeem_offers = 346 device_settings_.mutable_allow_redeem_offers(); 347 bool allow_redeem_offers_value; 348 if (value->GetAsBoolean(&allow_redeem_offers_value)) { 349 allow_redeem_offers->set_allow_redeem_offers( 350 allow_redeem_offers_value); 351 } else { 352 NOTREACHED(); 353 } 354 } else if (prop == kStartUpFlags) { 355 em::StartUpFlagsProto* flags_proto = 356 device_settings_.mutable_start_up_flags(); 357 flags_proto->Clear(); 358 const base::ListValue* flags; 359 if (value->GetAsList(&flags)) { 360 for (base::ListValue::const_iterator i = flags->begin(); 361 i != flags->end(); ++i) { 362 std::string flag; 363 if ((*i)->GetAsString(&flag)) 364 flags_proto->add_flags(flag); 365 } 366 } 367 } else if (prop == kSystemUse24HourClock) { 368 em::SystemUse24HourClockProto* use_24hour_clock_proto = 369 device_settings_.mutable_use_24hour_clock(); 370 use_24hour_clock_proto->Clear(); 371 bool use_24hour_clock_value; 372 if (value->GetAsBoolean(&use_24hour_clock_value)) { 373 use_24hour_clock_proto->set_use_24hour_clock(use_24hour_clock_value); 374 } else { 375 NOTREACHED(); 376 } 377 } else if (prop == kAttestationForContentProtectionEnabled) { 378 em::AttestationSettingsProto* attestation_settings = 379 device_settings_.mutable_attestation_settings(); 380 bool setting_enabled; 381 if (value->GetAsBoolean(&setting_enabled)) { 382 attestation_settings->set_content_protection_enabled(setting_enabled); 383 } else { 384 NOTREACHED(); 385 } 386 } else { 387 // The remaining settings don't support Set(), since they are not 388 // intended to be customizable by the user: 389 // kAccountsPrefSupervisedUsersEnabled 390 // kAppPack 391 // kDeviceAttestationEnabled 392 // kDeviceOwner 393 // kIdleLogoutTimeout 394 // kIdleLogoutWarningDuration 395 // kReleaseChannelDelegated 396 // kReportDeviceActivityTimes 397 // kReportDeviceBootMode 398 // kReportDeviceLocation 399 // kReportDeviceVersionInfo 400 // kReportDeviceNetworkInterfaces 401 // kReportDeviceUsers 402 // kScreenSaverExtensionId 403 // kScreenSaverTimeout 404 // kStartUpUrls 405 // kSystemTimezonePolicy 406 // kVariationsRestrictParameter 407 408 LOG(FATAL) << "Device setting " << prop << " is read-only."; 409 } 410 411 em::PolicyData data; 412 data.set_username(device_settings_service_->GetUsername()); 413 CHECK(device_settings_.SerializeToString(data.mutable_policy_value())); 414 415 // Set the cache to the updated value. 416 UpdateValuesCache(data, device_settings_, trusted_status_); 417 418 if (ownership_status_ == DeviceSettingsService::OWNERSHIP_TAKEN) { 419 StoreDeviceSettings(); 420 } else { 421 if (!device_settings_cache::Store(data, g_browser_process->local_state())) 422 LOG(ERROR) << "Couldn't store to the temp storage."; 423 424 // OnStorePolicyCompleted won't get called in this case so proceed with any 425 // pending operations immediately. 426 if (!pending_changes_.empty()) 427 SetInPolicy(); 428 } 429} 430 431void DeviceSettingsProvider::DecodeLoginPolicies( 432 const em::ChromeDeviceSettingsProto& policy, 433 PrefValueMap* new_values_cache) const { 434 // For all our boolean settings the following is applicable: 435 // true is default permissive value and false is safe prohibitive value. 436 // Exceptions: 437 // kAccountsPrefEphemeralUsersEnabled has a default value of false. 438 if (policy.has_allow_new_users() && 439 policy.allow_new_users().has_allow_new_users()) { 440 if (policy.allow_new_users().allow_new_users()) { 441 // New users allowed, user whitelist ignored. 442 new_values_cache->SetBoolean(kAccountsPrefAllowNewUser, true); 443 } else { 444 // New users not allowed, enforce user whitelist if present. 445 new_values_cache->SetBoolean(kAccountsPrefAllowNewUser, 446 !policy.has_user_whitelist()); 447 } 448 } else { 449 // No configured allow-new-users value, enforce whitelist if non-empty. 450 new_values_cache->SetBoolean( 451 kAccountsPrefAllowNewUser, 452 policy.user_whitelist().user_whitelist_size() == 0); 453 } 454 455 new_values_cache->SetBoolean( 456 kAccountsPrefAllowGuest, 457 !policy.has_guest_mode_enabled() || 458 !policy.guest_mode_enabled().has_guest_mode_enabled() || 459 policy.guest_mode_enabled().guest_mode_enabled()); 460 461 new_values_cache->SetBoolean( 462 kAccountsPrefShowUserNamesOnSignIn, 463 !policy.has_show_user_names() || 464 !policy.show_user_names().has_show_user_names() || 465 policy.show_user_names().show_user_names()); 466 467 new_values_cache->SetBoolean( 468 kAccountsPrefEphemeralUsersEnabled, 469 policy.has_ephemeral_users_enabled() && 470 policy.ephemeral_users_enabled().has_ephemeral_users_enabled() && 471 policy.ephemeral_users_enabled().ephemeral_users_enabled()); 472 473 new_values_cache->SetBoolean( 474 kAccountsPrefSupervisedUsersEnabled, 475 policy.has_supervised_users_settings() && 476 policy.supervised_users_settings().supervised_users_enabled()); 477 478 base::ListValue* list = new base::ListValue(); 479 const em::UserWhitelistProto& whitelist_proto = policy.user_whitelist(); 480 const RepeatedPtrField<std::string>& whitelist = 481 whitelist_proto.user_whitelist(); 482 for (RepeatedPtrField<std::string>::const_iterator it = whitelist.begin(); 483 it != whitelist.end(); ++it) { 484 list->Append(new base::StringValue(*it)); 485 } 486 new_values_cache->SetValue(kAccountsPrefUsers, list); 487 488 scoped_ptr<base::ListValue> account_list(new base::ListValue()); 489 CommandLine* command_line = CommandLine::ForCurrentProcess(); 490 if (!command_line->HasSwitch(switches::kDisableLocalAccounts)) { 491 const em::DeviceLocalAccountsProto device_local_accounts_proto = 492 policy.device_local_accounts(); 493 const RepeatedPtrField<em::DeviceLocalAccountInfoProto>& accounts = 494 device_local_accounts_proto.account(); 495 RepeatedPtrField<em::DeviceLocalAccountInfoProto>::const_iterator entry; 496 for (entry = accounts.begin(); entry != accounts.end(); ++entry) { 497 scoped_ptr<base::DictionaryValue> entry_dict(new base::DictionaryValue()); 498 if (entry->has_type()) { 499 if (entry->has_account_id()) { 500 entry_dict->SetStringWithoutPathExpansion( 501 kAccountsPrefDeviceLocalAccountsKeyId, entry->account_id()); 502 } 503 entry_dict->SetIntegerWithoutPathExpansion( 504 kAccountsPrefDeviceLocalAccountsKeyType, entry->type()); 505 if (entry->kiosk_app().has_app_id()) { 506 entry_dict->SetStringWithoutPathExpansion( 507 kAccountsPrefDeviceLocalAccountsKeyKioskAppId, 508 entry->kiosk_app().app_id()); 509 } 510 } else if (entry->has_deprecated_public_session_id()) { 511 // Deprecated public session specification. 512 entry_dict->SetStringWithoutPathExpansion( 513 kAccountsPrefDeviceLocalAccountsKeyId, 514 entry->deprecated_public_session_id()); 515 entry_dict->SetIntegerWithoutPathExpansion( 516 kAccountsPrefDeviceLocalAccountsKeyType, 517 policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION); 518 } 519 account_list->Append(entry_dict.release()); 520 } 521 } 522 new_values_cache->SetValue(kAccountsPrefDeviceLocalAccounts, 523 account_list.release()); 524 525 if (policy.has_device_local_accounts()) { 526 if (policy.device_local_accounts().has_auto_login_id()) { 527 new_values_cache->SetString( 528 kAccountsPrefDeviceLocalAccountAutoLoginId, 529 policy.device_local_accounts().auto_login_id()); 530 } 531 if (policy.device_local_accounts().has_auto_login_delay()) { 532 new_values_cache->SetInteger( 533 kAccountsPrefDeviceLocalAccountAutoLoginDelay, 534 policy.device_local_accounts().auto_login_delay()); 535 } 536 } 537 538 new_values_cache->SetBoolean( 539 kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled, 540 policy.device_local_accounts().enable_auto_login_bailout()); 541 new_values_cache->SetBoolean( 542 kAccountsPrefDeviceLocalAccountPromptForNetworkWhenOffline, 543 policy.device_local_accounts().prompt_for_network_when_offline()); 544 545 if (policy.has_start_up_flags()) { 546 base::ListValue* list = new base::ListValue(); 547 const em::StartUpFlagsProto& flags_proto = policy.start_up_flags(); 548 const RepeatedPtrField<std::string>& flags = flags_proto.flags(); 549 for (RepeatedPtrField<std::string>::const_iterator it = flags.begin(); 550 it != flags.end(); ++it) { 551 list->Append(new base::StringValue(*it)); 552 } 553 new_values_cache->SetValue(kStartUpFlags, list); 554 } 555} 556 557void DeviceSettingsProvider::DecodeKioskPolicies( 558 const em::ChromeDeviceSettingsProto& policy, 559 PrefValueMap* new_values_cache) const { 560 if (policy.has_forced_logout_timeouts()) { 561 if (policy.forced_logout_timeouts().has_idle_logout_timeout()) { 562 new_values_cache->SetInteger( 563 kIdleLogoutTimeout, 564 policy.forced_logout_timeouts().idle_logout_timeout()); 565 } 566 567 if (policy.forced_logout_timeouts().has_idle_logout_warning_duration()) { 568 new_values_cache->SetInteger( 569 kIdleLogoutWarningDuration, 570 policy.forced_logout_timeouts().idle_logout_warning_duration()); 571 } 572 } 573 574 if (policy.has_login_screen_saver()) { 575 if (policy.login_screen_saver().has_screen_saver_timeout()) { 576 new_values_cache->SetInteger( 577 kScreenSaverTimeout, 578 policy.login_screen_saver().screen_saver_timeout()); 579 } 580 581 if (policy.login_screen_saver().has_screen_saver_extension_id()) { 582 new_values_cache->SetString( 583 kScreenSaverExtensionId, 584 policy.login_screen_saver().screen_saver_extension_id()); 585 } 586 } 587 588 if (policy.has_app_pack()) { 589 typedef RepeatedPtrField<em::AppPackEntryProto> proto_type; 590 base::ListValue* list = new base::ListValue; 591 const proto_type& app_pack = policy.app_pack().app_pack(); 592 for (proto_type::const_iterator it = app_pack.begin(); 593 it != app_pack.end(); ++it) { 594 base::DictionaryValue* entry = new base::DictionaryValue; 595 if (it->has_extension_id()) { 596 entry->SetStringWithoutPathExpansion(kAppPackKeyExtensionId, 597 it->extension_id()); 598 } 599 if (it->has_update_url()) { 600 entry->SetStringWithoutPathExpansion(kAppPackKeyUpdateUrl, 601 it->update_url()); 602 } 603 list->Append(entry); 604 } 605 new_values_cache->SetValue(kAppPack, list); 606 } 607 608 if (policy.has_start_up_urls()) { 609 base::ListValue* list = new base::ListValue(); 610 const em::StartUpUrlsProto& urls_proto = policy.start_up_urls(); 611 const RepeatedPtrField<std::string>& urls = urls_proto.start_up_urls(); 612 for (RepeatedPtrField<std::string>::const_iterator it = urls.begin(); 613 it != urls.end(); ++it) { 614 list->Append(new base::StringValue(*it)); 615 } 616 new_values_cache->SetValue(kStartUpUrls, list); 617 } 618} 619 620void DeviceSettingsProvider::DecodeNetworkPolicies( 621 const em::ChromeDeviceSettingsProto& policy, 622 PrefValueMap* new_values_cache) const { 623 // kSignedDataRoamingEnabled has a default value of false. 624 new_values_cache->SetBoolean( 625 kSignedDataRoamingEnabled, 626 policy.has_data_roaming_enabled() && 627 policy.data_roaming_enabled().has_data_roaming_enabled() && 628 policy.data_roaming_enabled().data_roaming_enabled()); 629} 630 631void DeviceSettingsProvider::DecodeAutoUpdatePolicies( 632 const em::ChromeDeviceSettingsProto& policy, 633 PrefValueMap* new_values_cache) const { 634 if (policy.has_auto_update_settings()) { 635 const em::AutoUpdateSettingsProto& au_settings_proto = 636 policy.auto_update_settings(); 637 if (au_settings_proto.has_update_disabled()) { 638 new_values_cache->SetBoolean(kUpdateDisabled, 639 au_settings_proto.update_disabled()); 640 } 641 const RepeatedField<int>& allowed_connection_types = 642 au_settings_proto.allowed_connection_types(); 643 base::ListValue* list = new base::ListValue(); 644 for (RepeatedField<int>::const_iterator i(allowed_connection_types.begin()); 645 i != allowed_connection_types.end(); ++i) { 646 list->Append(new base::FundamentalValue(*i)); 647 } 648 new_values_cache->SetValue(kAllowedConnectionTypesForUpdate, list); 649 } 650} 651 652void DeviceSettingsProvider::DecodeReportingPolicies( 653 const em::ChromeDeviceSettingsProto& policy, 654 PrefValueMap* new_values_cache) const { 655 if (policy.has_device_reporting()) { 656 const em::DeviceReportingProto& reporting_policy = 657 policy.device_reporting(); 658 if (reporting_policy.has_report_version_info()) { 659 new_values_cache->SetBoolean( 660 kReportDeviceVersionInfo, 661 reporting_policy.report_version_info()); 662 } 663 if (reporting_policy.has_report_activity_times()) { 664 new_values_cache->SetBoolean( 665 kReportDeviceActivityTimes, 666 reporting_policy.report_activity_times()); 667 } 668 if (reporting_policy.has_report_boot_mode()) { 669 new_values_cache->SetBoolean( 670 kReportDeviceBootMode, 671 reporting_policy.report_boot_mode()); 672 } 673 if (reporting_policy.has_report_network_interfaces()) { 674 new_values_cache->SetBoolean( 675 kReportDeviceNetworkInterfaces, 676 reporting_policy.report_network_interfaces()); 677 } 678 if (reporting_policy.has_report_users()) { 679 new_values_cache->SetBoolean( 680 kReportDeviceUsers, 681 reporting_policy.report_users()); 682 } 683 } 684} 685 686void DeviceSettingsProvider::DecodeGenericPolicies( 687 const em::ChromeDeviceSettingsProto& policy, 688 PrefValueMap* new_values_cache) const { 689 if (policy.has_metrics_enabled()) { 690 new_values_cache->SetBoolean(kStatsReportingPref, 691 policy.metrics_enabled().metrics_enabled()); 692 } else { 693 new_values_cache->SetBoolean(kStatsReportingPref, HasOldMetricsFile()); 694 } 695 696 if (!policy.has_release_channel() || 697 !policy.release_channel().has_release_channel()) { 698 // Default to an invalid channel (will be ignored). 699 new_values_cache->SetString(kReleaseChannel, ""); 700 } else { 701 new_values_cache->SetString(kReleaseChannel, 702 policy.release_channel().release_channel()); 703 } 704 705 new_values_cache->SetBoolean( 706 kReleaseChannelDelegated, 707 policy.has_release_channel() && 708 policy.release_channel().has_release_channel_delegated() && 709 policy.release_channel().release_channel_delegated()); 710 711 if (policy.has_system_timezone()) { 712 if (policy.system_timezone().has_timezone()) { 713 new_values_cache->SetString( 714 kSystemTimezonePolicy, 715 policy.system_timezone().timezone()); 716 } 717 } 718 719 if (policy.has_use_24hour_clock()) { 720 if (policy.use_24hour_clock().has_use_24hour_clock()) { 721 new_values_cache->SetBoolean( 722 kSystemUse24HourClock, policy.use_24hour_clock().use_24hour_clock()); 723 } 724 } 725 726 if (policy.has_allow_redeem_offers()) { 727 new_values_cache->SetBoolean( 728 kAllowRedeemChromeOsRegistrationOffers, 729 policy.allow_redeem_offers().allow_redeem_offers()); 730 } else { 731 new_values_cache->SetBoolean( 732 kAllowRedeemChromeOsRegistrationOffers, 733 true); 734 } 735 736 if (policy.has_variations_parameter()) { 737 new_values_cache->SetString( 738 kVariationsRestrictParameter, 739 policy.variations_parameter().parameter()); 740 } 741 742 new_values_cache->SetBoolean( 743 kDeviceAttestationEnabled, 744 policy.attestation_settings().attestation_enabled()); 745 746 if (policy.has_attestation_settings() && 747 policy.attestation_settings().has_content_protection_enabled()) { 748 new_values_cache->SetBoolean( 749 kAttestationForContentProtectionEnabled, 750 policy.attestation_settings().content_protection_enabled()); 751 } else { 752 new_values_cache->SetBoolean(kAttestationForContentProtectionEnabled, true); 753 } 754} 755 756void DeviceSettingsProvider::UpdateValuesCache( 757 const em::PolicyData& policy_data, 758 const em::ChromeDeviceSettingsProto& settings, 759 TrustedStatus trusted_status) { 760 PrefValueMap new_values_cache; 761 762 if (policy_data.has_username() && !policy_data.has_request_token()) 763 new_values_cache.SetString(kDeviceOwner, policy_data.username()); 764 765 DecodeLoginPolicies(settings, &new_values_cache); 766 DecodeKioskPolicies(settings, &new_values_cache); 767 DecodeNetworkPolicies(settings, &new_values_cache); 768 DecodeAutoUpdatePolicies(settings, &new_values_cache); 769 DecodeReportingPolicies(settings, &new_values_cache); 770 DecodeGenericPolicies(settings, &new_values_cache); 771 772 // Collect all notifications but send them only after we have swapped the 773 // cache so that if somebody actually reads the cache will be already valid. 774 std::vector<std::string> notifications; 775 // Go through the new values and verify in the old ones. 776 PrefValueMap::iterator iter = new_values_cache.begin(); 777 for (; iter != new_values_cache.end(); ++iter) { 778 const base::Value* old_value; 779 if (!values_cache_.GetValue(iter->first, &old_value) || 780 !old_value->Equals(iter->second)) { 781 notifications.push_back(iter->first); 782 } 783 } 784 // Now check for values that have been removed from the policy blob. 785 for (iter = values_cache_.begin(); iter != values_cache_.end(); ++iter) { 786 const base::Value* value; 787 if (!new_values_cache.GetValue(iter->first, &value)) 788 notifications.push_back(iter->first); 789 } 790 // Swap and notify. 791 values_cache_.Swap(&new_values_cache); 792 trusted_status_ = trusted_status; 793 for (size_t i = 0; i < notifications.size(); ++i) 794 NotifyObservers(notifications[i]); 795} 796 797void DeviceSettingsProvider::ApplyMetricsSetting(bool use_file, 798 bool new_value) { 799 // TODO(pastarmovj): Remove this once migration is not needed anymore. 800 // If the value is not set we should try to migrate legacy consent file. 801 if (use_file) { 802 new_value = HasOldMetricsFile(); 803 // Make sure the values will get eventually written to the policy file. 804 migration_values_.SetValue(kStatsReportingPref, 805 base::Value::CreateBooleanValue(new_value)); 806 AttemptMigration(); 807 VLOG(1) << "No metrics policy set will revert to checking " 808 << "consent file which is " 809 << (new_value ? "on." : "off."); 810 UMA_HISTOGRAM_COUNTS("DeviceSettings.MetricsMigrated", 1); 811 } 812 VLOG(1) << "Metrics policy is being set to : " << new_value 813 << "(use file : " << use_file << ")"; 814 // TODO(pastarmovj): Remove this once we don't need to regenerate the 815 // consent file for the GUID anymore. 816 OptionsUtil::ResolveMetricsReportingEnabled(new_value); 817} 818 819void DeviceSettingsProvider::ApplySideEffects( 820 const em::ChromeDeviceSettingsProto& settings) { 821 // First migrate metrics settings as needed. 822 if (settings.has_metrics_enabled()) 823 ApplyMetricsSetting(false, settings.metrics_enabled().metrics_enabled()); 824 else 825 ApplyMetricsSetting(true, false); 826} 827 828bool DeviceSettingsProvider::MitigateMissingPolicy() { 829 // First check if the device has been owned already and if not exit 830 // immediately. 831 policy::BrowserPolicyConnectorChromeOS* connector = 832 g_browser_process->platform_part()->browser_policy_connector_chromeos(); 833 if (connector->GetDeviceMode() != policy::DEVICE_MODE_CONSUMER) 834 return false; 835 836 // If we are here the policy file were corrupted or missing. This can happen 837 // because we are migrating Pre R11 device to the new secure policies or there 838 // was an attempt to circumvent policy system. In this case we should populate 839 // the policy cache with "safe-mode" defaults which should allow the owner to 840 // log in but lock the device for anyone else until the policy blob has been 841 // recreated by the session manager. 842 LOG(ERROR) << "Corruption of the policy data has been detected." 843 << "Switching to \"safe-mode\" policies until the owner logs in " 844 << "to regenerate the policy data."; 845 846 device_settings_.Clear(); 847 device_settings_.mutable_allow_new_users()->set_allow_new_users(true); 848 device_settings_.mutable_guest_mode_enabled()->set_guest_mode_enabled(true); 849 em::PolicyData empty_policy_data; 850 UpdateValuesCache(empty_policy_data, device_settings_, TRUSTED); 851 values_cache_.SetBoolean(kPolicyMissingMitigationMode, true); 852 853 return true; 854} 855 856const base::Value* DeviceSettingsProvider::Get(const std::string& path) const { 857 if (IsDeviceSetting(path)) { 858 const base::Value* value; 859 if (values_cache_.GetValue(path, &value)) 860 return value; 861 } else { 862 NOTREACHED() << "Trying to get non cros setting."; 863 } 864 865 return NULL; 866} 867 868DeviceSettingsProvider::TrustedStatus 869 DeviceSettingsProvider::PrepareTrustedValues(const base::Closure& cb) { 870 TrustedStatus status = RequestTrustedEntity(); 871 if (status == TEMPORARILY_UNTRUSTED && !cb.is_null()) 872 callbacks_.push_back(cb); 873 return status; 874} 875 876bool DeviceSettingsProvider::HandlesSetting(const std::string& path) const { 877 return IsDeviceSetting(path); 878} 879 880DeviceSettingsProvider::TrustedStatus 881 DeviceSettingsProvider::RequestTrustedEntity() { 882 if (ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE) 883 return TRUSTED; 884 return trusted_status_; 885} 886 887void DeviceSettingsProvider::UpdateAndProceedStoring() { 888 // Re-sync the cache from the service. 889 UpdateFromService(); 890 891 // Trigger the next change if necessary. 892 if (trusted_status_ == TRUSTED && !pending_changes_.empty()) 893 SetInPolicy(); 894} 895 896bool DeviceSettingsProvider::UpdateFromService() { 897 bool settings_loaded = false; 898 switch (device_settings_service_->status()) { 899 case DeviceSettingsService::STORE_SUCCESS: { 900 const em::PolicyData* policy_data = 901 device_settings_service_->policy_data(); 902 const em::ChromeDeviceSettingsProto* device_settings = 903 device_settings_service_->device_settings(); 904 if (policy_data && device_settings) { 905 if (!device_settings_cache::Store(*policy_data, 906 g_browser_process->local_state())) { 907 LOG(ERROR) << "Couldn't update the local state cache."; 908 } 909 UpdateValuesCache(*policy_data, *device_settings, TRUSTED); 910 device_settings_ = *device_settings; 911 912 // TODO(pastarmovj): Make those side effects responsibility of the 913 // respective subsystems. 914 ApplySideEffects(*device_settings); 915 916 settings_loaded = true; 917 } else { 918 // Initial policy load is still pending. 919 trusted_status_ = TEMPORARILY_UNTRUSTED; 920 } 921 break; 922 } 923 case DeviceSettingsService::STORE_NO_POLICY: 924 if (MitigateMissingPolicy()) 925 break; 926 // fall through. 927 case DeviceSettingsService::STORE_KEY_UNAVAILABLE: 928 VLOG(1) << "No policies present yet, will use the temp storage."; 929 trusted_status_ = PERMANENTLY_UNTRUSTED; 930 break; 931 case DeviceSettingsService::STORE_POLICY_ERROR: 932 case DeviceSettingsService::STORE_VALIDATION_ERROR: 933 case DeviceSettingsService::STORE_INVALID_POLICY: 934 case DeviceSettingsService::STORE_OPERATION_FAILED: 935 LOG(ERROR) << "Failed to retrieve cros policies. Reason: " 936 << device_settings_service_->status(); 937 trusted_status_ = PERMANENTLY_UNTRUSTED; 938 break; 939 case DeviceSettingsService::STORE_TEMP_VALIDATION_ERROR: 940 // The policy has failed to validate due to temporary error but it might 941 // take a long time until we recover so behave as it is a permanent error. 942 LOG(ERROR) << "Failed to retrieve cros policies because a temporary " 943 << "validation error has occurred. Retrying might succeed."; 944 trusted_status_ = PERMANENTLY_UNTRUSTED; 945 break; 946 } 947 948 // Notify the observers we are done. 949 std::vector<base::Closure> callbacks; 950 callbacks.swap(callbacks_); 951 for (size_t i = 0; i < callbacks.size(); ++i) 952 callbacks[i].Run(); 953 954 return settings_loaded; 955} 956 957void DeviceSettingsProvider::StoreDeviceSettings() { 958 // Mute all previous callbacks to guarantee the |pending_changes_| queue is 959 // processed serially. 960 store_callback_factory_.InvalidateWeakPtrs(); 961 962 device_settings_service_->SignAndStore( 963 scoped_ptr<em::ChromeDeviceSettingsProto>( 964 new em::ChromeDeviceSettingsProto(device_settings_)), 965 base::Bind(&DeviceSettingsProvider::UpdateAndProceedStoring, 966 store_callback_factory_.GetWeakPtr())); 967} 968 969void DeviceSettingsProvider::AttemptMigration() { 970 if (device_settings_service_->HasPrivateOwnerKey()) { 971 PrefValueMap::const_iterator i; 972 for (i = migration_values_.begin(); i != migration_values_.end(); ++i) 973 DoSet(i->first, *i->second); 974 migration_values_.Clear(); 975 } 976} 977 978} // namespace chromeos 979