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/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" 28 29 using google::protobuf::RepeatedField; 30 using google::protobuf::RepeatedPtrField; 31 32 namespace em = enterprise_management; 33 34 namespace chromeos { 35 36 namespace { 37 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, 51 kAccountsPrefUsers, 52 kAllowRedeemChromeOsRegistrationOffers, 53 kAllowedConnectionTypesForUpdate, 54 kAppPack, 55 kAttestationForContentProtectionEnabled, 56 kDeviceAttestationEnabled, 57 kDeviceOwner, 58 kIdleLogoutTimeout, 59 kIdleLogoutWarningDuration, 60 kPolicyMissingMitigationMode, 61 kReleaseChannel, 62 kReleaseChannelDelegated, 63 kReportDeviceActivityTimes, 64 kReportDeviceBootMode, 65 kReportDeviceLocation, 66 kReportDeviceNetworkInterfaces, 67 kReportDeviceUsers, 68 kReportDeviceVersionInfo, 69 kScreenSaverExtensionId, 70 kScreenSaverTimeout, 71 kServiceAccountIdentity, 72 kSignedDataRoamingEnabled, 73 kStartUpFlags, 74 kStartUpUrls, 75 kStatsReportingPref, 76 kSystemTimezonePolicy, 77 kSystemUse24HourClock, 78 kUpdateDisabled, 79 kVariationsRestrictParameter, 80 }; 81 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(); 89 } 90 91 void DecodeLoginPolicies( 92 const em::ChromeDeviceSettingsProto& policy, 93 PrefValueMap* new_values_cache) { 94 // For all our boolean settings the following is applicable: 95 // true is default permissive value and false is safe prohibitive value. 96 // Exceptions: 97 // kAccountsPrefEphemeralUsersEnabled has a default value of false. 98 // kAccountsPrefSupervisedUsersEnabled has a default value of false 99 // for enterprise devices and true for consumer devices. 100 // kAccountsPrefTransferSAMLCookies has a default value of false. 101 if (policy.has_allow_new_users() && 102 policy.allow_new_users().has_allow_new_users()) { 103 if (policy.allow_new_users().allow_new_users()) { 104 // New users allowed, user whitelist ignored. 105 new_values_cache->SetBoolean(kAccountsPrefAllowNewUser, true); 106 } else { 107 // New users not allowed, enforce user whitelist if present. 108 new_values_cache->SetBoolean(kAccountsPrefAllowNewUser, 109 !policy.has_user_whitelist()); 110 } 111 } else { 112 // No configured allow-new-users value, enforce whitelist if non-empty. 113 new_values_cache->SetBoolean( 114 kAccountsPrefAllowNewUser, 115 policy.user_whitelist().user_whitelist_size() == 0); 116 } 117 118 new_values_cache->SetBoolean( 119 kAccountsPrefAllowGuest, 120 !policy.has_guest_mode_enabled() || 121 !policy.guest_mode_enabled().has_guest_mode_enabled() || 122 policy.guest_mode_enabled().guest_mode_enabled()); 123 124 policy::BrowserPolicyConnectorChromeOS* connector = 125 g_browser_process->platform_part()->browser_policy_connector_chromeos(); 126 bool supervised_users_enabled = false; 127 if (connector->IsEnterpriseManaged()) { 128 supervised_users_enabled = 129 policy.has_supervised_users_settings() && 130 policy.supervised_users_settings().has_supervised_users_enabled() && 131 policy.supervised_users_settings().supervised_users_enabled(); 132 } else { 133 supervised_users_enabled = 134 !policy.has_supervised_users_settings() || 135 !policy.supervised_users_settings().has_supervised_users_enabled() || 136 policy.supervised_users_settings().supervised_users_enabled(); 137 } 138 new_values_cache->SetBoolean( 139 kAccountsPrefSupervisedUsersEnabled, supervised_users_enabled); 140 141 new_values_cache->SetBoolean( 142 kAccountsPrefShowUserNamesOnSignIn, 143 !policy.has_show_user_names() || 144 !policy.show_user_names().has_show_user_names() || 145 policy.show_user_names().show_user_names()); 146 147 new_values_cache->SetBoolean( 148 kAccountsPrefEphemeralUsersEnabled, 149 policy.has_ephemeral_users_enabled() && 150 policy.ephemeral_users_enabled().has_ephemeral_users_enabled() && 151 policy.ephemeral_users_enabled().ephemeral_users_enabled()); 152 153 base::ListValue* list = new base::ListValue(); 154 const em::UserWhitelistProto& whitelist_proto = policy.user_whitelist(); 155 const RepeatedPtrField<std::string>& whitelist = 156 whitelist_proto.user_whitelist(); 157 for (RepeatedPtrField<std::string>::const_iterator it = whitelist.begin(); 158 it != whitelist.end(); ++it) { 159 list->Append(new base::StringValue(*it)); 160 } 161 new_values_cache->SetValue(kAccountsPrefUsers, list); 162 163 scoped_ptr<base::ListValue> account_list(new base::ListValue()); 164 const em::DeviceLocalAccountsProto device_local_accounts_proto = 165 policy.device_local_accounts(); 166 const RepeatedPtrField<em::DeviceLocalAccountInfoProto>& accounts = 167 device_local_accounts_proto.account(); 168 RepeatedPtrField<em::DeviceLocalAccountInfoProto>::const_iterator entry; 169 for (entry = accounts.begin(); entry != accounts.end(); ++entry) { 170 scoped_ptr<base::DictionaryValue> entry_dict(new base::DictionaryValue()); 171 if (entry->has_type()) { 172 if (entry->has_account_id()) { 173 entry_dict->SetStringWithoutPathExpansion( 174 kAccountsPrefDeviceLocalAccountsKeyId, entry->account_id()); 175 } 176 entry_dict->SetIntegerWithoutPathExpansion( 177 kAccountsPrefDeviceLocalAccountsKeyType, entry->type()); 178 if (entry->kiosk_app().has_app_id()) { 179 entry_dict->SetStringWithoutPathExpansion( 180 kAccountsPrefDeviceLocalAccountsKeyKioskAppId, 181 entry->kiosk_app().app_id()); 182 } 183 } else if (entry->has_deprecated_public_session_id()) { 184 // Deprecated public session specification. 185 entry_dict->SetStringWithoutPathExpansion( 186 kAccountsPrefDeviceLocalAccountsKeyId, 187 entry->deprecated_public_session_id()); 188 entry_dict->SetIntegerWithoutPathExpansion( 189 kAccountsPrefDeviceLocalAccountsKeyType, 190 policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION); 191 } 192 account_list->Append(entry_dict.release()); 193 } 194 new_values_cache->SetValue(kAccountsPrefDeviceLocalAccounts, 195 account_list.release()); 196 197 if (policy.has_device_local_accounts()) { 198 if (policy.device_local_accounts().has_auto_login_id()) { 199 new_values_cache->SetString( 200 kAccountsPrefDeviceLocalAccountAutoLoginId, 201 policy.device_local_accounts().auto_login_id()); 202 } 203 if (policy.device_local_accounts().has_auto_login_delay()) { 204 new_values_cache->SetInteger( 205 kAccountsPrefDeviceLocalAccountAutoLoginDelay, 206 policy.device_local_accounts().auto_login_delay()); 207 } 208 } 209 210 new_values_cache->SetBoolean( 211 kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled, 212 policy.device_local_accounts().enable_auto_login_bailout()); 213 new_values_cache->SetBoolean( 214 kAccountsPrefDeviceLocalAccountPromptForNetworkWhenOffline, 215 policy.device_local_accounts().prompt_for_network_when_offline()); 216 217 if (policy.has_start_up_flags()) { 218 base::ListValue* list = new base::ListValue(); 219 const em::StartUpFlagsProto& flags_proto = policy.start_up_flags(); 220 const RepeatedPtrField<std::string>& flags = flags_proto.flags(); 221 for (RepeatedPtrField<std::string>::const_iterator it = flags.begin(); 222 it != flags.end(); ++it) { 223 list->Append(new base::StringValue(*it)); 224 } 225 new_values_cache->SetValue(kStartUpFlags, list); 226 } 227 228 if (policy.has_saml_settings()) { 229 new_values_cache->SetBoolean( 230 kAccountsPrefTransferSAMLCookies, 231 policy.saml_settings().transfer_saml_cookies()); 232 } 233 } 234 235 void DecodeKioskPolicies( 236 const em::ChromeDeviceSettingsProto& policy, 237 PrefValueMap* new_values_cache) { 238 if (policy.has_forced_logout_timeouts()) { 239 if (policy.forced_logout_timeouts().has_idle_logout_timeout()) { 240 new_values_cache->SetInteger( 241 kIdleLogoutTimeout, 242 policy.forced_logout_timeouts().idle_logout_timeout()); 243 } 244 245 if (policy.forced_logout_timeouts().has_idle_logout_warning_duration()) { 246 new_values_cache->SetInteger( 247 kIdleLogoutWarningDuration, 248 policy.forced_logout_timeouts().idle_logout_warning_duration()); 249 } 250 } 251 252 if (policy.has_login_screen_saver()) { 253 if (policy.login_screen_saver().has_screen_saver_timeout()) { 254 new_values_cache->SetInteger( 255 kScreenSaverTimeout, 256 policy.login_screen_saver().screen_saver_timeout()); 257 } 258 259 if (policy.login_screen_saver().has_screen_saver_extension_id()) { 260 new_values_cache->SetString( 261 kScreenSaverExtensionId, 262 policy.login_screen_saver().screen_saver_extension_id()); 263 } 264 } 265 266 if (policy.has_app_pack()) { 267 typedef RepeatedPtrField<em::AppPackEntryProto> proto_type; 268 base::ListValue* list = new base::ListValue; 269 const proto_type& app_pack = policy.app_pack().app_pack(); 270 for (proto_type::const_iterator it = app_pack.begin(); 271 it != app_pack.end(); ++it) { 272 base::DictionaryValue* entry = new base::DictionaryValue; 273 if (it->has_extension_id()) { 274 entry->SetStringWithoutPathExpansion(kAppPackKeyExtensionId, 275 it->extension_id()); 276 } 277 if (it->has_update_url()) { 278 entry->SetStringWithoutPathExpansion(kAppPackKeyUpdateUrl, 279 it->update_url()); 280 } 281 list->Append(entry); 282 } 283 new_values_cache->SetValue(kAppPack, list); 284 } 285 286 if (policy.has_start_up_urls()) { 287 base::ListValue* list = new base::ListValue(); 288 const em::StartUpUrlsProto& urls_proto = policy.start_up_urls(); 289 const RepeatedPtrField<std::string>& urls = urls_proto.start_up_urls(); 290 for (RepeatedPtrField<std::string>::const_iterator it = urls.begin(); 291 it != urls.end(); ++it) { 292 list->Append(new base::StringValue(*it)); 293 } 294 new_values_cache->SetValue(kStartUpUrls, list); 295 } 296 } 297 298 void DecodeNetworkPolicies( 299 const em::ChromeDeviceSettingsProto& policy, 300 PrefValueMap* new_values_cache) { 301 // kSignedDataRoamingEnabled has a default value of false. 302 new_values_cache->SetBoolean( 303 kSignedDataRoamingEnabled, 304 policy.has_data_roaming_enabled() && 305 policy.data_roaming_enabled().has_data_roaming_enabled() && 306 policy.data_roaming_enabled().data_roaming_enabled()); 307 } 308 309 void DecodeAutoUpdatePolicies( 310 const em::ChromeDeviceSettingsProto& policy, 311 PrefValueMap* new_values_cache) { 312 if (policy.has_auto_update_settings()) { 313 const em::AutoUpdateSettingsProto& au_settings_proto = 314 policy.auto_update_settings(); 315 if (au_settings_proto.has_update_disabled()) { 316 new_values_cache->SetBoolean(kUpdateDisabled, 317 au_settings_proto.update_disabled()); 318 } 319 const RepeatedField<int>& allowed_connection_types = 320 au_settings_proto.allowed_connection_types(); 321 base::ListValue* list = new base::ListValue(); 322 for (RepeatedField<int>::const_iterator i(allowed_connection_types.begin()); 323 i != allowed_connection_types.end(); ++i) { 324 list->Append(new base::FundamentalValue(*i)); 325 } 326 new_values_cache->SetValue(kAllowedConnectionTypesForUpdate, list); 327 } 328 } 329 330 void DecodeReportingPolicies( 331 const em::ChromeDeviceSettingsProto& policy, 332 PrefValueMap* new_values_cache) { 333 if (policy.has_device_reporting()) { 334 const em::DeviceReportingProto& reporting_policy = 335 policy.device_reporting(); 336 if (reporting_policy.has_report_version_info()) { 337 new_values_cache->SetBoolean( 338 kReportDeviceVersionInfo, 339 reporting_policy.report_version_info()); 340 } 341 if (reporting_policy.has_report_activity_times()) { 342 new_values_cache->SetBoolean( 343 kReportDeviceActivityTimes, 344 reporting_policy.report_activity_times()); 345 } 346 if (reporting_policy.has_report_boot_mode()) { 347 new_values_cache->SetBoolean( 348 kReportDeviceBootMode, 349 reporting_policy.report_boot_mode()); 350 } 351 if (reporting_policy.has_report_network_interfaces()) { 352 new_values_cache->SetBoolean( 353 kReportDeviceNetworkInterfaces, 354 reporting_policy.report_network_interfaces()); 355 } 356 if (reporting_policy.has_report_users()) { 357 new_values_cache->SetBoolean( 358 kReportDeviceUsers, 359 reporting_policy.report_users()); 360 } 361 } 362 } 363 364 void DecodeGenericPolicies( 365 const em::ChromeDeviceSettingsProto& policy, 366 PrefValueMap* new_values_cache) { 367 if (policy.has_metrics_enabled()) { 368 new_values_cache->SetBoolean(kStatsReportingPref, 369 policy.metrics_enabled().metrics_enabled()); 370 } else { 371 new_values_cache->SetBoolean(kStatsReportingPref, HasOldMetricsFile()); 372 } 373 374 if (!policy.has_release_channel() || 375 !policy.release_channel().has_release_channel()) { 376 // Default to an invalid channel (will be ignored). 377 new_values_cache->SetString(kReleaseChannel, ""); 378 } else { 379 new_values_cache->SetString(kReleaseChannel, 380 policy.release_channel().release_channel()); 381 } 382 383 new_values_cache->SetBoolean( 384 kReleaseChannelDelegated, 385 policy.has_release_channel() && 386 policy.release_channel().has_release_channel_delegated() && 387 policy.release_channel().release_channel_delegated()); 388 389 if (policy.has_system_timezone()) { 390 if (policy.system_timezone().has_timezone()) { 391 new_values_cache->SetString( 392 kSystemTimezonePolicy, 393 policy.system_timezone().timezone()); 394 } 395 } 396 397 if (policy.has_use_24hour_clock()) { 398 if (policy.use_24hour_clock().has_use_24hour_clock()) { 399 new_values_cache->SetBoolean( 400 kSystemUse24HourClock, policy.use_24hour_clock().use_24hour_clock()); 401 } 402 } 403 404 if (policy.has_allow_redeem_offers()) { 405 new_values_cache->SetBoolean( 406 kAllowRedeemChromeOsRegistrationOffers, 407 policy.allow_redeem_offers().allow_redeem_offers()); 408 } else { 409 new_values_cache->SetBoolean( 410 kAllowRedeemChromeOsRegistrationOffers, 411 true); 412 } 413 414 if (policy.has_variations_parameter()) { 415 new_values_cache->SetString( 416 kVariationsRestrictParameter, 417 policy.variations_parameter().parameter()); 418 } 419 420 new_values_cache->SetBoolean( 421 kDeviceAttestationEnabled, 422 policy.attestation_settings().attestation_enabled()); 423 424 if (policy.has_attestation_settings() && 425 policy.attestation_settings().has_content_protection_enabled()) { 426 new_values_cache->SetBoolean( 427 kAttestationForContentProtectionEnabled, 428 policy.attestation_settings().content_protection_enabled()); 429 } else { 430 new_values_cache->SetBoolean(kAttestationForContentProtectionEnabled, true); 431 } 432 } 433 434 } // namespace 435 436 DeviceSettingsProvider::DeviceSettingsProvider( 437 const NotifyObserversCallback& notify_cb, 438 DeviceSettingsService* device_settings_service) 439 : CrosSettingsProvider(notify_cb), 440 device_settings_service_(device_settings_service), 441 trusted_status_(TEMPORARILY_UNTRUSTED), 442 ownership_status_(device_settings_service_->GetOwnershipStatus()), 443 store_callback_factory_(this) { 444 device_settings_service_->AddObserver(this); 445 if (!UpdateFromService()) { 446 // Make sure we have at least the cache data immediately. 447 RetrieveCachedData(); 448 } 449 } 450 451 DeviceSettingsProvider::~DeviceSettingsProvider() { 452 device_settings_service_->RemoveObserver(this); 453 } 454 455 // static 456 bool DeviceSettingsProvider::IsDeviceSetting(const std::string& name) { 457 const char** end = kKnownSettings + arraysize(kKnownSettings); 458 return std::find(kKnownSettings, end, name) != end; 459 } 460 461 void DeviceSettingsProvider::DoSet(const std::string& path, 462 const base::Value& in_value) { 463 // Make sure that either the current user is the device owner or the 464 // device doesn't have an owner yet. 465 if (!(device_settings_service_->HasPrivateOwnerKey() || 466 ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE)) { 467 LOG(WARNING) << "Changing settings from non-owner, setting=" << path; 468 469 // Revert UI change. 470 NotifyObservers(path); 471 return; 472 } 473 474 if (IsDeviceSetting(path)) { 475 pending_changes_.push_back(PendingQueueElement(path, in_value.DeepCopy())); 476 if (!store_callback_factory_.HasWeakPtrs()) 477 SetInPolicy(); 478 } else { 479 NOTREACHED() << "Try to set unhandled cros setting " << path; 480 } 481 } 482 483 void DeviceSettingsProvider::OwnershipStatusChanged() { 484 DeviceSettingsService::OwnershipStatus new_ownership_status = 485 device_settings_service_->GetOwnershipStatus(); 486 487 // If the device just became owned, write the settings accumulated in the 488 // cache to device settings proper. It is important that writing only happens 489 // in this case, as during normal operation, the contents of the cache should 490 // never overwrite actual device settings. 491 if (new_ownership_status == DeviceSettingsService::OWNERSHIP_TAKEN && 492 ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE && 493 device_settings_service_->HasPrivateOwnerKey()) { 494 // There shouldn't be any pending writes, since the cache writes are all 495 // immediate. 496 DCHECK(!store_callback_factory_.HasWeakPtrs()); 497 498 trusted_status_ = TEMPORARILY_UNTRUSTED; 499 // Apply the locally-accumulated device settings on top of the initial 500 // settings from the service and write back the result. 501 if (device_settings_service_->device_settings()) { 502 em::ChromeDeviceSettingsProto new_settings( 503 *device_settings_service_->device_settings()); 504 new_settings.MergeFrom(device_settings_); 505 device_settings_.Swap(&new_settings); 506 } 507 StoreDeviceSettings(); 508 } 509 510 // The owner key might have become available, allowing migration to happen. 511 AttemptMigration(); 512 513 ownership_status_ = new_ownership_status; 514 } 515 516 void DeviceSettingsProvider::DeviceSettingsUpdated() { 517 if (!store_callback_factory_.HasWeakPtrs()) 518 UpdateAndProceedStoring(); 519 } 520 521 void DeviceSettingsProvider::RetrieveCachedData() { 522 em::PolicyData policy_data; 523 if (!device_settings_cache::Retrieve(&policy_data, 524 g_browser_process->local_state()) || 525 !device_settings_.ParseFromString(policy_data.policy_value())) { 526 VLOG(1) << "Can't retrieve temp store, possibly not created yet."; 527 } 528 529 UpdateValuesCache(policy_data, device_settings_, trusted_status_); 530 } 531 532 void DeviceSettingsProvider::SetInPolicy() { 533 if (pending_changes_.empty()) { 534 NOTREACHED(); 535 return; 536 } 537 538 if (RequestTrustedEntity() != TRUSTED) { 539 // Re-sync device settings before proceeding. 540 device_settings_service_->Load(); 541 return; 542 } 543 544 std::string prop(pending_changes_.front().first); 545 scoped_ptr<base::Value> value(pending_changes_.front().second); 546 pending_changes_.pop_front(); 547 548 trusted_status_ = TEMPORARILY_UNTRUSTED; 549 if (prop == kAccountsPrefAllowNewUser) { 550 em::AllowNewUsersProto* allow = 551 device_settings_.mutable_allow_new_users(); 552 bool allow_value; 553 if (value->GetAsBoolean(&allow_value)) 554 allow->set_allow_new_users(allow_value); 555 else 556 NOTREACHED(); 557 } else if (prop == kAccountsPrefAllowGuest) { 558 em::GuestModeEnabledProto* guest = 559 device_settings_.mutable_guest_mode_enabled(); 560 bool guest_value; 561 if (value->GetAsBoolean(&guest_value)) 562 guest->set_guest_mode_enabled(guest_value); 563 else 564 NOTREACHED(); 565 } else if (prop == kAccountsPrefSupervisedUsersEnabled) { 566 em::SupervisedUsersSettingsProto* supervised = 567 device_settings_.mutable_supervised_users_settings(); 568 bool supervised_value; 569 if (value->GetAsBoolean(&supervised_value)) 570 supervised->set_supervised_users_enabled(supervised_value); 571 else 572 NOTREACHED(); 573 } else if (prop == kAccountsPrefShowUserNamesOnSignIn) { 574 em::ShowUserNamesOnSigninProto* show = 575 device_settings_.mutable_show_user_names(); 576 bool show_value; 577 if (value->GetAsBoolean(&show_value)) 578 show->set_show_user_names(show_value); 579 else 580 NOTREACHED(); 581 } else if (prop == kAccountsPrefDeviceLocalAccounts) { 582 em::DeviceLocalAccountsProto* device_local_accounts = 583 device_settings_.mutable_device_local_accounts(); 584 device_local_accounts->clear_account(); 585 const base::ListValue* accounts_list = NULL; 586 if (value->GetAsList(&accounts_list)) { 587 for (base::ListValue::const_iterator entry(accounts_list->begin()); 588 entry != accounts_list->end(); ++entry) { 589 const base::DictionaryValue* entry_dict = NULL; 590 if ((*entry)->GetAsDictionary(&entry_dict)) { 591 em::DeviceLocalAccountInfoProto* account = 592 device_local_accounts->add_account(); 593 std::string account_id; 594 if (entry_dict->GetStringWithoutPathExpansion( 595 kAccountsPrefDeviceLocalAccountsKeyId, &account_id)) { 596 account->set_account_id(account_id); 597 } 598 int type; 599 if (entry_dict->GetIntegerWithoutPathExpansion( 600 kAccountsPrefDeviceLocalAccountsKeyType, &type)) { 601 account->set_type( 602 static_cast<em::DeviceLocalAccountInfoProto::AccountType>( 603 type)); 604 } 605 std::string kiosk_app_id; 606 if (entry_dict->GetStringWithoutPathExpansion( 607 kAccountsPrefDeviceLocalAccountsKeyKioskAppId, 608 &kiosk_app_id)) { 609 account->mutable_kiosk_app()->set_app_id(kiosk_app_id); 610 } 611 } else { 612 NOTREACHED(); 613 } 614 } 615 } else { 616 NOTREACHED(); 617 } 618 } else if (prop == kAccountsPrefDeviceLocalAccountAutoLoginId) { 619 em::DeviceLocalAccountsProto* device_local_accounts = 620 device_settings_.mutable_device_local_accounts(); 621 std::string id; 622 if (value->GetAsString(&id)) 623 device_local_accounts->set_auto_login_id(id); 624 else 625 NOTREACHED(); 626 } else if (prop == kAccountsPrefDeviceLocalAccountAutoLoginDelay) { 627 em::DeviceLocalAccountsProto* device_local_accounts = 628 device_settings_.mutable_device_local_accounts(); 629 int delay; 630 if (value->GetAsInteger(&delay)) 631 device_local_accounts->set_auto_login_delay(delay); 632 else 633 NOTREACHED(); 634 } else if (prop == kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled) { 635 em::DeviceLocalAccountsProto* device_local_accounts = 636 device_settings_.mutable_device_local_accounts(); 637 bool enabled; 638 if (value->GetAsBoolean(&enabled)) 639 device_local_accounts->set_enable_auto_login_bailout(enabled); 640 else 641 NOTREACHED(); 642 } else if (prop == 643 kAccountsPrefDeviceLocalAccountPromptForNetworkWhenOffline) { 644 em::DeviceLocalAccountsProto* device_local_accounts = 645 device_settings_.mutable_device_local_accounts(); 646 bool should_prompt; 647 if (value->GetAsBoolean(&should_prompt)) 648 device_local_accounts->set_prompt_for_network_when_offline(should_prompt); 649 else 650 NOTREACHED(); 651 } else if (prop == kSignedDataRoamingEnabled) { 652 em::DataRoamingEnabledProto* roam = 653 device_settings_.mutable_data_roaming_enabled(); 654 bool roaming_value = false; 655 if (value->GetAsBoolean(&roaming_value)) 656 roam->set_data_roaming_enabled(roaming_value); 657 else 658 NOTREACHED(); 659 } else if (prop == kReleaseChannel) { 660 em::ReleaseChannelProto* release_channel = 661 device_settings_.mutable_release_channel(); 662 std::string channel_value; 663 if (value->GetAsString(&channel_value)) 664 release_channel->set_release_channel(channel_value); 665 else 666 NOTREACHED(); 667 } else if (prop == kStatsReportingPref) { 668 em::MetricsEnabledProto* metrics = 669 device_settings_.mutable_metrics_enabled(); 670 bool metrics_value = false; 671 if (value->GetAsBoolean(&metrics_value)) 672 metrics->set_metrics_enabled(metrics_value); 673 else 674 NOTREACHED(); 675 ApplyMetricsSetting(false, metrics_value); 676 } else if (prop == kAccountsPrefUsers) { 677 em::UserWhitelistProto* whitelist_proto = 678 device_settings_.mutable_user_whitelist(); 679 whitelist_proto->clear_user_whitelist(); 680 const base::ListValue* users; 681 if (value->GetAsList(&users)) { 682 for (base::ListValue::const_iterator i = users->begin(); 683 i != users->end(); ++i) { 684 std::string email; 685 if ((*i)->GetAsString(&email)) 686 whitelist_proto->add_user_whitelist(email); 687 } 688 } 689 } else if (prop == kAccountsPrefEphemeralUsersEnabled) { 690 em::EphemeralUsersEnabledProto* ephemeral_users_enabled = 691 device_settings_.mutable_ephemeral_users_enabled(); 692 bool ephemeral_users_enabled_value = false; 693 if (value->GetAsBoolean(&ephemeral_users_enabled_value)) { 694 ephemeral_users_enabled->set_ephemeral_users_enabled( 695 ephemeral_users_enabled_value); 696 } else { 697 NOTREACHED(); 698 } 699 } else if (prop == kAllowRedeemChromeOsRegistrationOffers) { 700 em::AllowRedeemChromeOsRegistrationOffersProto* allow_redeem_offers = 701 device_settings_.mutable_allow_redeem_offers(); 702 bool allow_redeem_offers_value; 703 if (value->GetAsBoolean(&allow_redeem_offers_value)) { 704 allow_redeem_offers->set_allow_redeem_offers( 705 allow_redeem_offers_value); 706 } else { 707 NOTREACHED(); 708 } 709 } else if (prop == kStartUpFlags) { 710 em::StartUpFlagsProto* flags_proto = 711 device_settings_.mutable_start_up_flags(); 712 flags_proto->Clear(); 713 const base::ListValue* flags; 714 if (value->GetAsList(&flags)) { 715 for (base::ListValue::const_iterator i = flags->begin(); 716 i != flags->end(); ++i) { 717 std::string flag; 718 if ((*i)->GetAsString(&flag)) 719 flags_proto->add_flags(flag); 720 } 721 } 722 } else if (prop == kSystemUse24HourClock) { 723 em::SystemUse24HourClockProto* use_24hour_clock_proto = 724 device_settings_.mutable_use_24hour_clock(); 725 use_24hour_clock_proto->Clear(); 726 bool use_24hour_clock_value; 727 if (value->GetAsBoolean(&use_24hour_clock_value)) { 728 use_24hour_clock_proto->set_use_24hour_clock(use_24hour_clock_value); 729 } else { 730 NOTREACHED(); 731 } 732 } else if (prop == kAttestationForContentProtectionEnabled) { 733 em::AttestationSettingsProto* attestation_settings = 734 device_settings_.mutable_attestation_settings(); 735 bool setting_enabled; 736 if (value->GetAsBoolean(&setting_enabled)) { 737 attestation_settings->set_content_protection_enabled(setting_enabled); 738 } else { 739 NOTREACHED(); 740 } 741 } else { 742 // The remaining settings don't support Set(), since they are not 743 // intended to be customizable by the user: 744 // kAccountsPrefTransferSAMLCookies 745 // kAppPack 746 // kDeviceAttestationEnabled 747 // kDeviceOwner 748 // kIdleLogoutTimeout 749 // kIdleLogoutWarningDuration 750 // kReleaseChannelDelegated 751 // kReportDeviceActivityTimes 752 // kReportDeviceBootMode 753 // kReportDeviceLocation 754 // kReportDeviceVersionInfo 755 // kReportDeviceNetworkInterfaces 756 // kReportDeviceUsers 757 // kScreenSaverExtensionId 758 // kScreenSaverTimeout 759 // kServiceAccountIdentity 760 // kStartUpUrls 761 // kSystemTimezonePolicy 762 // kVariationsRestrictParameter 763 764 LOG(FATAL) << "Device setting " << prop << " is read-only."; 765 } 766 767 em::PolicyData data; 768 data.set_username(device_settings_service_->GetUsername()); 769 CHECK(device_settings_.SerializeToString(data.mutable_policy_value())); 770 771 // Set the cache to the updated value. 772 UpdateValuesCache(data, device_settings_, trusted_status_); 773 774 if (ownership_status_ == DeviceSettingsService::OWNERSHIP_TAKEN) { 775 StoreDeviceSettings(); 776 } else { 777 if (!device_settings_cache::Store(data, g_browser_process->local_state())) 778 LOG(ERROR) << "Couldn't store to the temp storage."; 779 780 // OnStorePolicyCompleted won't get called in this case so proceed with any 781 // pending operations immediately. 782 if (!pending_changes_.empty()) 783 SetInPolicy(); 784 } 785 } 786 787 void DeviceSettingsProvider::UpdateValuesCache( 788 const em::PolicyData& policy_data, 789 const em::ChromeDeviceSettingsProto& settings, 790 TrustedStatus trusted_status) { 791 PrefValueMap new_values_cache; 792 793 if (policy_data.has_username() && !policy_data.has_request_token()) 794 new_values_cache.SetString(kDeviceOwner, policy_data.username()); 795 796 if (policy_data.has_service_account_identity()) { 797 new_values_cache.SetString(kServiceAccountIdentity, 798 policy_data.service_account_identity()); 799 } 800 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); 807 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); 818 } 819 } 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); 825 } 826 // Swap and notify. 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]); 831 } 832 833 void DeviceSettingsProvider::ApplyMetricsSetting(bool use_file, 834 bool new_value) { 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. 837 if (use_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); 841 AttemptMigration(); 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); 846 } 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 InitiateMetricsReportingChange(new_value, OnMetricsReportingCallbackType()); 852 } 853 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()); 859 else 860 ApplyMetricsSetting(true, false); 861 } 862 863 bool DeviceSettingsProvider::MitigateMissingPolicy() { 864 // First check if the device has been owned already and if not exit 865 // immediately. 866 policy::BrowserPolicyConnectorChromeOS* connector = 867 g_browser_process->platform_part()->browser_policy_connector_chromeos(); 868 if (connector->GetDeviceMode() != policy::DEVICE_MODE_CONSUMER) 869 return false; 870 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."; 880 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); 887 888 return true; 889 } 890 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)) 895 return value; 896 } else { 897 NOTREACHED() << "Trying to get non cros setting."; 898 } 899 900 return NULL; 901 } 902 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); 908 return status; 909 } 910 911 bool DeviceSettingsProvider::HandlesSetting(const std::string& path) const { 912 return IsDeviceSetting(path); 913 } 914 915 DeviceSettingsProvider::TrustedStatus 916 DeviceSettingsProvider::RequestTrustedEntity() { 917 if (ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE) 918 return TRUSTED; 919 return trusted_status_; 920 } 921 922 void DeviceSettingsProvider::UpdateAndProceedStoring() { 923 // Re-sync the cache from the service. 924 UpdateFromService(); 925 926 // Trigger the next change if necessary. 927 if (trusted_status_ == TRUSTED && !pending_changes_.empty()) 928 SetInPolicy(); 929 } 930 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."; 943 } 944 UpdateValuesCache(*policy_data, *device_settings, TRUSTED); 945 device_settings_ = *device_settings; 946 947 // TODO(pastarmovj): Make those side effects responsibility of the 948 // respective subsystems. 949 ApplySideEffects(*device_settings); 950 951 settings_loaded = true; 952 } else { 953 // Initial policy load is still pending. 954 trusted_status_ = TEMPORARILY_UNTRUSTED; 955 } 956 break; 957 } 958 case DeviceSettingsService::STORE_NO_POLICY: 959 if (MitigateMissingPolicy()) 960 break; 961 // fall through. 962 case DeviceSettingsService::STORE_KEY_UNAVAILABLE: 963 VLOG(1) << "No policies present yet, will use the temp storage."; 964 trusted_status_ = PERMANENTLY_UNTRUSTED; 965 break; 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; 973 break; 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; 980 break; 981 } 982 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) 987 callbacks[i].Run(); 988 989 return settings_loaded; 990 } 991 992 void DeviceSettingsProvider::StoreDeviceSettings() { 993 // Mute all previous callbacks to guarantee the |pending_changes_| queue is 994 // processed serially. 995 store_callback_factory_.InvalidateWeakPtrs(); 996 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())); 1002 } 1003 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(); 1010 } 1011 } 1012 1013 } // namespace chromeos 1014