OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/chromeos/device_settings_provider.h" | 5 #include "chrome/browser/chromeos/device_settings_provider.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
9 #include "base/callback.h" | 9 #include "base/callback.h" |
10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "base/string_util.h" | 12 #include "base/string_util.h" |
13 #include "base/threading/thread_restrictions.h" | 13 #include "base/threading/thread_restrictions.h" |
14 #include "base/values.h" | 14 #include "base/values.h" |
15 #include "chrome/browser/browser_process.h" | 15 #include "chrome/browser/browser_process.h" |
16 #include "chrome/browser/chromeos/cros/cros_library.h" | 16 #include "chrome/browser/chromeos/cros/cros_library.h" |
17 #include "chrome/browser/chromeos/cros/network_library.h" | 17 #include "chrome/browser/chromeos/cros/network_library.h" |
18 #include "chrome/browser/chromeos/cros_settings.h" | 18 #include "chrome/browser/chromeos/cros_settings.h" |
19 #include "chrome/browser/chromeos/cros_settings_names.h" | 19 #include "chrome/browser/chromeos/cros_settings_names.h" |
20 #include "chrome/browser/chromeos/login/ownership_service.h" | 20 #include "chrome/browser/chromeos/login/ownership_service.h" |
21 #include "chrome/browser/chromeos/login/signed_settings_cache.h" | 21 #include "chrome/browser/chromeos/login/signed_settings_cache.h" |
22 #include "chrome/browser/chromeos/login/signed_settings_helper.h" | 22 #include "chrome/browser/chromeos/login/signed_settings_helper.h" |
23 #include "chrome/browser/chromeos/login/user_manager.h" | 23 #include "chrome/browser/chromeos/login/user_manager.h" |
24 #include "chrome/browser/policy/app_pack_updater.h" | 24 #include "chrome/browser/policy/app_pack_updater.h" |
25 #include "chrome/browser/policy/proto/chrome_device_policy.pb.h" | |
26 #include "chrome/browser/ui/options/options_util.h" | 25 #include "chrome/browser/ui/options/options_util.h" |
27 #include "chrome/common/chrome_notification_types.h" | 26 #include "chrome/common/chrome_notification_types.h" |
28 #include "chrome/installer/util/google_update_settings.h" | 27 #include "chrome/installer/util/google_update_settings.h" |
29 #include "content/public/browser/notification_service.h" | 28 #include "content/public/browser/notification_service.h" |
30 | 29 |
31 using google::protobuf::RepeatedPtrField; | 30 using google::protobuf::RepeatedPtrField; |
32 | 31 |
33 namespace em = enterprise_management; | 32 namespace em = enterprise_management; |
34 | 33 |
35 namespace chromeos { | 34 namespace chromeos { |
36 | 35 |
37 namespace { | 36 namespace { |
38 | 37 |
39 // List of settings handled by the DeviceSettingsProvider. | 38 // List of settings handled by the DeviceSettingsProvider. |
40 const char* kKnownSettings[] = { | 39 const char* kKnownSettings[] = { |
41 kAccountsPrefAllowGuest, | 40 kAccountsPrefAllowGuest, |
42 kAccountsPrefAllowNewUser, | 41 kAccountsPrefAllowNewUser, |
43 kAccountsPrefEphemeralUsersEnabled, | 42 kAccountsPrefEphemeralUsersEnabled, |
44 kAccountsPrefShowUserNamesOnSignIn, | 43 kAccountsPrefShowUserNamesOnSignIn, |
45 kAccountsPrefUsers, | 44 kAccountsPrefUsers, |
46 kAppPack, | 45 kAppPack, |
47 kDeviceOwner, | 46 kDeviceOwner, |
| 47 kIdleLogoutTimeout, |
| 48 kIdleLogoutWarningDuration, |
48 kReleaseChannel, | 49 kReleaseChannel, |
49 kReportDeviceActivityTimes, | 50 kReportDeviceActivityTimes, |
50 kReportDeviceBootMode, | 51 kReportDeviceBootMode, |
51 kReportDeviceVersionInfo, | 52 kReportDeviceVersionInfo, |
| 53 kScreenSaverExtensionId, |
| 54 kScreenSaverTimeout, |
52 kSettingProxyEverywhere, | 55 kSettingProxyEverywhere, |
53 kSignedDataRoamingEnabled, | 56 kSignedDataRoamingEnabled, |
54 kStatsReportingPref, | 57 kStatsReportingPref, |
55 }; | 58 }; |
56 | 59 |
57 // Upper bound for number of retries to fetch a signed setting. | 60 // Upper bound for number of retries to fetch a signed setting. |
58 static const int kNumRetriesLimit = 9; | 61 static const int kNumRetriesLimit = 9; |
59 | 62 |
60 // Legacy policy file location. Used to detect migration from pre v12 ChromeOS. | 63 // Legacy policy file location. Used to detect migration from pre v12 ChromeOS. |
61 const char kLegacyPolicyFile[] = "/var/lib/whitelist/preferences"; | 64 const char kLegacyPolicyFile[] = "/var/lib/whitelist/preferences"; |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
270 bool ephemeral_users_enabled_value = false; | 273 bool ephemeral_users_enabled_value = false; |
271 if (value->GetAsBoolean(&ephemeral_users_enabled_value)) | 274 if (value->GetAsBoolean(&ephemeral_users_enabled_value)) |
272 ephemeral_users_enabled->set_ephemeral_users_enabled( | 275 ephemeral_users_enabled->set_ephemeral_users_enabled( |
273 ephemeral_users_enabled_value); | 276 ephemeral_users_enabled_value); |
274 else | 277 else |
275 NOTREACHED(); | 278 NOTREACHED(); |
276 } else { | 279 } else { |
277 // The remaining settings don't support Set(), since they are not | 280 // The remaining settings don't support Set(), since they are not |
278 // intended to be customizable by the user: | 281 // intended to be customizable by the user: |
279 // kAppPack | 282 // kAppPack |
| 283 // kIdleLogoutTimeout, |
| 284 // kIdleLogoutWarningDuration, |
280 // kReportDeviceVersionInfo | 285 // kReportDeviceVersionInfo |
281 // kReportDeviceActivityTimes | 286 // kReportDeviceActivityTimes |
282 // kReportDeviceBootMode | 287 // kReportDeviceBootMode |
| 288 // kScreenSaverExtensionId, |
| 289 // kScreenSaverTimeout, |
| 290 |
283 NOTREACHED(); | 291 NOTREACHED(); |
284 } | 292 } |
285 data.set_policy_value(pol.SerializeAsString()); | 293 data.set_policy_value(pol.SerializeAsString()); |
286 // Set the cache to the updated value. | 294 // Set the cache to the updated value. |
287 policy_ = data; | 295 policy_ = data; |
288 UpdateValuesCache(); | 296 UpdateValuesCache(); |
289 | 297 |
290 if (!signed_settings_cache::Store(data, g_browser_process->local_state())) | 298 if (!signed_settings_cache::Store(data, g_browser_process->local_state())) |
291 LOG(ERROR) << "Couldn't store to the temp storage."; | 299 LOG(ERROR) << "Couldn't store to the temp storage."; |
292 | 300 |
(...skipping 22 matching lines...) Expand all Loading... |
315 Reload(); | 323 Reload(); |
316 return; | 324 return; |
317 } | 325 } |
318 // Update the internal caches and set the trusted flag to true so that we | 326 // Update the internal caches and set the trusted flag to true so that we |
319 // can pass the trustedness check in the second call to SetInPolicy. | 327 // can pass the trustedness check in the second call to SetInPolicy. |
320 OnRetrievePolicyCompleted(code, policy); | 328 OnRetrievePolicyCompleted(code, policy); |
321 | 329 |
322 SetInPolicy(); | 330 SetInPolicy(); |
323 } | 331 } |
324 | 332 |
325 void DeviceSettingsProvider::UpdateValuesCache() { | 333 void DeviceSettingsProvider::DecodeLoginPolicies( |
326 const em::PolicyData data = policy(); | 334 const em::ChromeDeviceSettingsProto& policy, |
327 PrefValueMap new_values_cache; | 335 PrefValueMap* new_values_cache) const { |
328 | |
329 if (data.has_username() && !data.has_request_token()) | |
330 new_values_cache.SetString(kDeviceOwner, data.username()); | |
331 | |
332 em::ChromeDeviceSettingsProto pol; | |
333 pol.ParseFromString(data.policy_value()); | |
334 | |
335 // For all our boolean settings the following is applicable: | 336 // For all our boolean settings the following is applicable: |
336 // true is default permissive value and false is safe prohibitive value. | 337 // true is default permissive value and false is safe prohibitive value. |
337 // Exceptions: | 338 // Exceptions: |
338 // kSignedDataRoamingEnabled has a default value of false. | 339 // kSignedDataRoamingEnabled has a default value of false. |
339 // kAccountsPrefEphemeralUsersEnabled has a default value of false. | 340 // kAccountsPrefEphemeralUsersEnabled has a default value of false. |
340 if (pol.has_allow_new_users() && | 341 if (policy.has_allow_new_users() && |
341 pol.allow_new_users().has_allow_new_users() && | 342 policy.allow_new_users().has_allow_new_users() && |
342 pol.allow_new_users().allow_new_users()) { | 343 policy.allow_new_users().allow_new_users()) { |
343 // New users allowed, user_whitelist() ignored. | 344 // New users allowed, user_whitelist() ignored. |
344 new_values_cache.SetBoolean(kAccountsPrefAllowNewUser, true); | 345 new_values_cache->SetBoolean(kAccountsPrefAllowNewUser, true); |
345 } else if (!pol.has_user_whitelist()) { | 346 } else if (!policy.has_user_whitelist()) { |
346 // If we have the allow_new_users bool, and it is true, we honor that above. | 347 // If we have the allow_new_users bool, and it is true, we honor that above. |
347 // In all other cases (don't have it, have it and it is set to false, etc), | 348 // In all other cases (don't have it, have it and it is set to false, etc), |
348 // We will honor the user_whitelist() if it is there and populated. | 349 // We will honor the user_whitelist() if it is there and populated. |
349 // Otherwise we default to allowing new users. | 350 // Otherwise we default to allowing new users. |
350 new_values_cache.SetBoolean(kAccountsPrefAllowNewUser, true); | 351 new_values_cache->SetBoolean(kAccountsPrefAllowNewUser, true); |
351 } else { | 352 } else { |
352 new_values_cache.SetBoolean( | 353 new_values_cache->SetBoolean( |
353 kAccountsPrefAllowNewUser, | 354 kAccountsPrefAllowNewUser, |
354 pol.user_whitelist().user_whitelist_size() == 0); | 355 policy.user_whitelist().user_whitelist_size() == 0); |
355 } | 356 } |
356 | 357 |
357 new_values_cache.SetBoolean( | 358 new_values_cache->SetBoolean( |
358 kAccountsPrefAllowGuest, | 359 kAccountsPrefAllowGuest, |
359 !pol.has_guest_mode_enabled() || | 360 !policy.has_guest_mode_enabled() || |
360 !pol.guest_mode_enabled().has_guest_mode_enabled() || | 361 !policy.guest_mode_enabled().has_guest_mode_enabled() || |
361 pol.guest_mode_enabled().guest_mode_enabled()); | 362 policy.guest_mode_enabled().guest_mode_enabled()); |
362 | 363 |
363 new_values_cache.SetBoolean( | 364 new_values_cache->SetBoolean( |
364 kAccountsPrefShowUserNamesOnSignIn, | 365 kAccountsPrefShowUserNamesOnSignIn, |
365 !pol.has_show_user_names() || | 366 !policy.has_show_user_names() || |
366 !pol.show_user_names().has_show_user_names() || | 367 !policy.show_user_names().has_show_user_names() || |
367 pol.show_user_names().show_user_names()); | 368 policy.show_user_names().show_user_names()); |
368 | 369 |
369 new_values_cache.SetBoolean( | 370 new_values_cache->SetBoolean( |
370 kSignedDataRoamingEnabled, | |
371 pol.has_data_roaming_enabled() && | |
372 pol.data_roaming_enabled().has_data_roaming_enabled() && | |
373 pol.data_roaming_enabled().data_roaming_enabled()); | |
374 | |
375 new_values_cache.SetBoolean( | |
376 kAccountsPrefEphemeralUsersEnabled, | 371 kAccountsPrefEphemeralUsersEnabled, |
377 pol.has_ephemeral_users_enabled() && | 372 policy.has_ephemeral_users_enabled() && |
378 pol.ephemeral_users_enabled().has_ephemeral_users_enabled() && | 373 policy.ephemeral_users_enabled().has_ephemeral_users_enabled() && |
379 pol.ephemeral_users_enabled().ephemeral_users_enabled()); | 374 policy.ephemeral_users_enabled().ephemeral_users_enabled()); |
380 | |
381 // TODO(cmasone): NOTIMPLEMENTED() once http://crosbug.com/13052 is fixed. | |
382 std::string serialized; | |
383 if (pol.has_device_proxy_settings() && | |
384 pol.device_proxy_settings().SerializeToString(&serialized)) { | |
385 new_values_cache.SetString(kSettingProxyEverywhere, serialized); | |
386 } | |
387 | |
388 if (!pol.has_release_channel() || | |
389 !pol.release_channel().has_release_channel()) { | |
390 // Default to an invalid channel (will be ignored). | |
391 new_values_cache.SetString(kReleaseChannel, ""); | |
392 } else { | |
393 new_values_cache.SetString(kReleaseChannel, | |
394 pol.release_channel().release_channel()); | |
395 } | |
396 | |
397 if (pol.has_metrics_enabled()) { | |
398 new_values_cache.SetBoolean(kStatsReportingPref, | |
399 pol.metrics_enabled().metrics_enabled()); | |
400 } else { | |
401 new_values_cache.SetBoolean(kStatsReportingPref, HasOldMetricsFile()); | |
402 } | |
403 | 375 |
404 base::ListValue* list = new base::ListValue(); | 376 base::ListValue* list = new base::ListValue(); |
405 const em::UserWhitelistProto& whitelist_proto = pol.user_whitelist(); | 377 const em::UserWhitelistProto& whitelist_proto = policy.user_whitelist(); |
406 const RepeatedPtrField<std::string>& whitelist = | 378 const RepeatedPtrField<std::string>& whitelist = |
407 whitelist_proto.user_whitelist(); | 379 whitelist_proto.user_whitelist(); |
408 for (RepeatedPtrField<std::string>::const_iterator it = whitelist.begin(); | 380 for (RepeatedPtrField<std::string>::const_iterator it = whitelist.begin(); |
409 it != whitelist.end(); ++it) { | 381 it != whitelist.end(); ++it) { |
410 list->Append(base::Value::CreateStringValue(*it)); | 382 list->Append(base::Value::CreateStringValue(*it)); |
411 } | 383 } |
412 new_values_cache.SetValue(kAccountsPrefUsers, list); | 384 new_values_cache->SetValue(kAccountsPrefUsers, list); |
| 385 } |
413 | 386 |
414 if (pol.has_device_reporting()) { | 387 void DeviceSettingsProvider::DecodeKioskPolicies( |
415 if (pol.device_reporting().has_report_version_info()) { | 388 const em::ChromeDeviceSettingsProto& policy, |
416 new_values_cache.SetBoolean(kReportDeviceVersionInfo, | 389 PrefValueMap* new_values_cache) const { |
417 pol.device_reporting().report_version_info()); | 390 if (policy.has_forced_logout_timeouts()) { |
| 391 if (policy.forced_logout_timeouts().has_idle_logout_timeout()) { |
| 392 new_values_cache->SetInteger( |
| 393 kIdleLogoutTimeout, |
| 394 policy.forced_logout_timeouts().idle_logout_timeout()); |
418 } | 395 } |
419 // TODO(dubroy): Re-add device activity time policy here when the UI | 396 |
420 // to notify the user has been implemented (http://crosbug.com/26252). | 397 if (policy.forced_logout_timeouts().has_idle_logout_warning_duration()) { |
421 if (pol.device_reporting().has_report_boot_mode()) { | 398 new_values_cache->SetInteger( |
422 new_values_cache.SetBoolean(kReportDeviceBootMode, | 399 kIdleLogoutWarningDuration, |
423 pol.device_reporting().report_boot_mode()); | 400 policy.forced_logout_timeouts().idle_logout_warning_duration()); |
424 } | 401 } |
425 } | 402 } |
426 | 403 |
427 if (pol.has_app_pack()) { | 404 if (policy.has_login_screen_saver()) { |
| 405 if (policy.login_screen_saver().has_screen_saver_timeout()) { |
| 406 new_values_cache->SetInteger( |
| 407 kScreenSaverTimeout, |
| 408 policy.login_screen_saver().screen_saver_timeout()); |
| 409 } |
| 410 |
| 411 if (policy.login_screen_saver().has_screen_saver_extension_id()) { |
| 412 new_values_cache->SetString( |
| 413 kScreenSaverExtensionId, |
| 414 policy.login_screen_saver().screen_saver_extension_id()); |
| 415 } |
| 416 } |
| 417 |
| 418 if (policy.has_app_pack()) { |
428 typedef RepeatedPtrField<em::AppPackEntryProto> proto_type; | 419 typedef RepeatedPtrField<em::AppPackEntryProto> proto_type; |
429 base::ListValue* list = new base::ListValue; | 420 base::ListValue* list = new base::ListValue; |
430 const proto_type& app_pack = pol.app_pack().app_pack(); | 421 const proto_type& app_pack = policy.app_pack().app_pack(); |
431 for (proto_type::const_iterator it = app_pack.begin(); | 422 for (proto_type::const_iterator it = app_pack.begin(); |
432 it != app_pack.end(); ++it) { | 423 it != app_pack.end(); ++it) { |
433 base::DictionaryValue* entry = new base::DictionaryValue; | 424 base::DictionaryValue* entry = new base::DictionaryValue; |
434 if (it->has_extension_id()) { | 425 if (it->has_extension_id()) { |
435 entry->SetString(policy::AppPackUpdater::kExtensionId, | 426 entry->SetString(policy::AppPackUpdater::kExtensionId, |
436 it->extension_id()); | 427 it->extension_id()); |
437 } | 428 } |
438 if (it->has_update_url()) | 429 if (it->has_update_url()) |
439 entry->SetString(policy::AppPackUpdater::kUpdateUrl, it->update_url()); | 430 entry->SetString(policy::AppPackUpdater::kUpdateUrl, it->update_url()); |
440 if (it->has_key_checksum()) { | 431 if (it->has_key_checksum()) { |
441 entry->SetString(policy::AppPackUpdater::kKeyChecksum, | 432 entry->SetString(policy::AppPackUpdater::kKeyChecksum, |
442 it->key_checksum()); | 433 it->key_checksum()); |
443 } | 434 } |
444 list->Append(entry); | 435 list->Append(entry); |
445 } | 436 } |
446 new_values_cache.SetValue(kAppPack, list); | 437 new_values_cache->SetValue(kAppPack, list); |
447 } | 438 } |
| 439 } |
| 440 |
| 441 void DeviceSettingsProvider::DecodeNetworkPolicies( |
| 442 const em::ChromeDeviceSettingsProto& policy, |
| 443 PrefValueMap* new_values_cache) const { |
| 444 new_values_cache->SetBoolean( |
| 445 kSignedDataRoamingEnabled, |
| 446 policy.has_data_roaming_enabled() && |
| 447 policy.data_roaming_enabled().has_data_roaming_enabled() && |
| 448 policy.data_roaming_enabled().data_roaming_enabled()); |
| 449 |
| 450 // TODO(cmasone): NOTIMPLEMENTED() once http://crosbug.com/13052 is fixed. |
| 451 std::string serialized; |
| 452 if (policy.has_device_proxy_settings() && |
| 453 policy.device_proxy_settings().SerializeToString(&serialized)) { |
| 454 new_values_cache->SetString(kSettingProxyEverywhere, serialized); |
| 455 } |
| 456 } |
| 457 |
| 458 void DeviceSettingsProvider::DecodeReportingPolicies( |
| 459 const em::ChromeDeviceSettingsProto& policy, |
| 460 PrefValueMap* new_values_cache) const { |
| 461 if (policy.has_device_reporting()) { |
| 462 if (policy.device_reporting().has_report_version_info()) { |
| 463 new_values_cache->SetBoolean( |
| 464 kReportDeviceVersionInfo, |
| 465 policy.device_reporting().report_version_info()); |
| 466 } |
| 467 // TODO(dubroy): Re-add device activity time policy here when the UI |
| 468 // to notify the user has been implemented (http://crosbug.com/26252). |
| 469 if (policy.device_reporting().has_report_boot_mode()) { |
| 470 new_values_cache->SetBoolean( |
| 471 kReportDeviceBootMode, |
| 472 policy.device_reporting().report_boot_mode()); |
| 473 } |
| 474 } |
| 475 } |
| 476 |
| 477 void DeviceSettingsProvider::DecodeGenericPolicies( |
| 478 const em::ChromeDeviceSettingsProto& policy, |
| 479 PrefValueMap* new_values_cache) const { |
| 480 if (policy.has_metrics_enabled()) { |
| 481 new_values_cache->SetBoolean(kStatsReportingPref, |
| 482 policy.metrics_enabled().metrics_enabled()); |
| 483 } else { |
| 484 new_values_cache->SetBoolean(kStatsReportingPref, HasOldMetricsFile()); |
| 485 } |
| 486 |
| 487 if (!policy.has_release_channel() || |
| 488 !policy.release_channel().has_release_channel()) { |
| 489 // Default to an invalid channel (will be ignored). |
| 490 new_values_cache->SetString(kReleaseChannel, ""); |
| 491 } else { |
| 492 new_values_cache->SetString(kReleaseChannel, |
| 493 policy.release_channel().release_channel()); |
| 494 } |
| 495 } |
| 496 |
| 497 void DeviceSettingsProvider::UpdateValuesCache() { |
| 498 const em::PolicyData data = policy(); |
| 499 PrefValueMap new_values_cache; |
| 500 |
| 501 if (data.has_username() && !data.has_request_token()) |
| 502 new_values_cache.SetString(kDeviceOwner, data.username()); |
| 503 |
| 504 em::ChromeDeviceSettingsProto pol; |
| 505 pol.ParseFromString(data.policy_value()); |
| 506 |
| 507 DecodeLoginPolicies(pol, &new_values_cache); |
| 508 DecodeKioskPolicies(pol, &new_values_cache); |
| 509 DecodeNetworkPolicies(pol, &new_values_cache); |
| 510 DecodeReportingPolicies(pol, &new_values_cache); |
| 511 DecodeGenericPolicies(pol, &new_values_cache); |
448 | 512 |
449 // Collect all notifications but send them only after we have swapped the | 513 // Collect all notifications but send them only after we have swapped the |
450 // cache so that if somebody actually reads the cache will be already valid. | 514 // cache so that if somebody actually reads the cache will be already valid. |
451 std::vector<std::string> notifications; | 515 std::vector<std::string> notifications; |
452 // Go through the new values and verify in the old ones. | 516 // Go through the new values and verify in the old ones. |
453 PrefValueMap::iterator iter = new_values_cache.begin(); | 517 PrefValueMap::iterator iter = new_values_cache.begin(); |
454 for (; iter != new_values_cache.end(); ++iter) { | 518 for (; iter != new_values_cache.end(); ++iter) { |
455 const base::Value* old_value; | 519 const base::Value* old_value; |
456 if (!values_cache_.GetValue(iter->first, &old_value) || | 520 if (!values_cache_.GetValue(iter->first, &old_value) || |
457 !old_value->Equals(iter->second)) { | 521 !old_value->Equals(iter->second)) { |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
650 Reload(); | 714 Reload(); |
651 return; | 715 return; |
652 } | 716 } |
653 LOG(ERROR) << "No retries left"; | 717 LOG(ERROR) << "No retries left"; |
654 break; | 718 break; |
655 } | 719 } |
656 } | 720 } |
657 } | 721 } |
658 | 722 |
659 } // namespace chromeos | 723 } // namespace chromeos |
OLD | NEW |