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