| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/chromeos/policy/device_policy_decoder_chromeos.h" |
| |
| #include <limits> |
| #include <memory> |
| #include <string> |
| |
| #include "base/callback.h" |
| #include "base/json/json_reader.h" |
| #include "base/logging.h" |
| #include "base/stl_util.h" |
| #include "base/strings/stringprintf.h" |
| #include "base/syslog_logging.h" |
| #include "base/values.h" |
| #include "chrome/browser/chromeos/policy/device_local_account.h" |
| #include "chrome/browser/chromeos/policy/off_hours/off_hours_proto_parser.h" |
| #include "chrome/browser/chromeos/tpm_firmware_update.h" |
| #include "chrome/browser/policy/chrome_browser_policy_connector.h" |
| #include "chromeos/dbus/dbus_thread_manager.h" |
| #include "chromeos/dbus/update_engine_client.h" |
| #include "chromeos/settings/cros_settings_names.h" |
| #include "components/policy/core/common/chrome_schema.h" |
| #include "components/policy/core/common/external_data_fetcher.h" |
| #include "components/policy/core/common/external_data_manager.h" |
| #include "components/policy/core/common/policy_map.h" |
| #include "components/policy/core/common/policy_types.h" |
| #include "components/policy/core/common/schema.h" |
| #include "components/policy/policy_constants.h" |
| #include "components/policy/proto/chrome_device_policy.pb.h" |
| #include "third_party/cros_system_api/dbus/service_constants.h" |
| |
| using google::protobuf::RepeatedField; |
| using google::protobuf::RepeatedPtrField; |
| |
| namespace em = enterprise_management; |
| |
| namespace policy { |
| |
| namespace { |
| |
| // If the |json_string| can be decoded and validated against the schema |
| // identified by |policy_name| in policy_templates.json, the policy |
| // |policy_name| in |policies| will be set to the decoded base::Value. |
| // Otherwise, the policy will be set to a base::Value of the original |
| // |json_string|. This way, the faulty value can still be seen in |
| // chrome://policy along with any errors/warnings. |
| void SetJsonDevicePolicy( |
| const std::string& policy_name, |
| const std::string& json_string, |
| std::unique_ptr<ExternalDataFetcher> external_data_fetcher, |
| PolicyMap* policies) { |
| std::string error; |
| std::unique_ptr<base::Value> decoded_json = |
| DecodeJsonStringAndNormalize(json_string, policy_name, &error); |
| auto value_to_set = decoded_json ? std::move(decoded_json) |
| : std::make_unique<base::Value>(json_string); |
| policies->Set(policy_name, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, |
| POLICY_SOURCE_CLOUD, std::move(value_to_set), |
| std::move(external_data_fetcher)); |
| if (!error.empty()) |
| policies->AddError(policy_name, error); |
| } |
| |
| void SetJsonDevicePolicy(const std::string& policy_name, |
| const std::string& json_string, |
| PolicyMap* policies) { |
| SetJsonDevicePolicy(policy_name, json_string, |
| /* external_data_fetcher */ nullptr, policies); |
| } |
| |
| void SetExternalDataDevicePolicy( |
| const std::string& policy_name, |
| const std::string& json_string, |
| base::WeakPtr<ExternalDataManager> external_data_manager, |
| PolicyMap* policies) { |
| SetJsonDevicePolicy( |
| policy_name, json_string, |
| std::make_unique<ExternalDataFetcher>(external_data_manager, policy_name), |
| policies); |
| } |
| |
| // Decodes a protobuf integer to an IntegerValue. Returns NULL in case the input |
| // value is out of bounds. |
| std::unique_ptr<base::Value> DecodeIntegerValue(google::protobuf::int64 value) { |
| if (value < std::numeric_limits<int>::min() || |
| value > std::numeric_limits<int>::max()) { |
| LOG(WARNING) << "Integer value " << value |
| << " out of numeric limits, ignoring."; |
| return std::unique_ptr<base::Value>(); |
| } |
| |
| return std::unique_ptr<base::Value>(new base::Value(static_cast<int>(value))); |
| } |
| |
| std::unique_ptr<base::Value> DecodeConnectionType(int value) { |
| static const char* const kConnectionTypes[] = { |
| shill::kTypeEthernet, shill::kTypeWifi, shill::kTypeWimax, |
| shill::kTypeBluetooth, shill::kTypeCellular, |
| }; |
| |
| if (value < 0 || value >= static_cast<int>(base::size(kConnectionTypes))) |
| return nullptr; |
| |
| return std::make_unique<base::Value>(kConnectionTypes[value]); |
| } |
| |
| void DecodeLoginPolicies(const em::ChromeDeviceSettingsProto& policy, |
| PolicyMap* policies) { |
| if (policy.has_guest_mode_enabled()) { |
| const em::GuestModeEnabledProto& container(policy.guest_mode_enabled()); |
| if (container.has_guest_mode_enabled()) { |
| policies->Set( |
| key::kDeviceGuestModeEnabled, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>(container.guest_mode_enabled()), |
| nullptr); |
| } |
| } |
| |
| if (policy.has_reboot_on_shutdown()) { |
| const em::RebootOnShutdownProto& container(policy.reboot_on_shutdown()); |
| if (container.has_reboot_on_shutdown()) { |
| policies->Set( |
| key::kDeviceRebootOnShutdown, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>(container.reboot_on_shutdown()), |
| nullptr); |
| } |
| } |
| |
| if (policy.has_show_user_names()) { |
| const em::ShowUserNamesOnSigninProto& container(policy.show_user_names()); |
| if (container.has_show_user_names()) { |
| policies->Set(key::kDeviceShowUserNamesOnSignin, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>(container.show_user_names()), |
| nullptr); |
| } |
| } |
| |
| if (policy.has_allow_new_users()) { |
| const em::AllowNewUsersProto& container(policy.allow_new_users()); |
| if (container.has_allow_new_users()) { |
| policies->Set(key::kDeviceAllowNewUsers, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>(container.allow_new_users()), |
| nullptr); |
| } |
| } |
| |
| if (policy.has_user_whitelist()) { |
| const em::UserWhitelistProto& container(policy.user_whitelist()); |
| std::unique_ptr<base::ListValue> whitelist(new base::ListValue); |
| for (const auto& entry : container.user_whitelist()) |
| whitelist->AppendString(entry); |
| policies->Set(key::kDeviceUserWhitelist, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::move(whitelist), nullptr); |
| } |
| |
| if (policy.has_ephemeral_users_enabled()) { |
| const em::EphemeralUsersEnabledProto& container( |
| policy.ephemeral_users_enabled()); |
| if (container.has_ephemeral_users_enabled()) { |
| policies->Set( |
| key::kDeviceEphemeralUsersEnabled, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>(container.ephemeral_users_enabled()), |
| nullptr); |
| } |
| } |
| |
| if (policy.has_device_local_accounts()) { |
| const em::DeviceLocalAccountsProto& container( |
| policy.device_local_accounts()); |
| const RepeatedPtrField<em::DeviceLocalAccountInfoProto>& accounts = |
| container.account(); |
| std::unique_ptr<base::ListValue> account_list(new base::ListValue()); |
| for (const auto& entry : accounts) { |
| std::unique_ptr<base::DictionaryValue> entry_dict( |
| new base::DictionaryValue()); |
| if (entry.has_type()) { |
| if (entry.has_account_id()) { |
| entry_dict->SetKey(chromeos::kAccountsPrefDeviceLocalAccountsKeyId, |
| base::Value(entry.account_id())); |
| } |
| entry_dict->SetKey(chromeos::kAccountsPrefDeviceLocalAccountsKeyType, |
| base::Value(entry.type())); |
| if (entry.kiosk_app().has_app_id()) { |
| entry_dict->SetKey( |
| chromeos::kAccountsPrefDeviceLocalAccountsKeyKioskAppId, |
| base::Value(entry.kiosk_app().app_id())); |
| } |
| if (entry.kiosk_app().has_update_url()) { |
| entry_dict->SetKey( |
| chromeos::kAccountsPrefDeviceLocalAccountsKeyKioskAppUpdateURL, |
| base::Value(entry.kiosk_app().update_url())); |
| } |
| if (entry.android_kiosk_app().has_package_name()) { |
| entry_dict->SetKey( |
| chromeos::kAccountsPrefDeviceLocalAccountsKeyArcKioskPackage, |
| base::Value(entry.android_kiosk_app().package_name())); |
| } |
| if (entry.android_kiosk_app().has_class_name()) { |
| entry_dict->SetKey( |
| chromeos::kAccountsPrefDeviceLocalAccountsKeyArcKioskClass, |
| base::Value(entry.android_kiosk_app().class_name())); |
| } |
| if (entry.android_kiosk_app().has_action()) { |
| entry_dict->SetKey( |
| chromeos::kAccountsPrefDeviceLocalAccountsKeyArcKioskAction, |
| base::Value(entry.android_kiosk_app().action())); |
| } |
| if (entry.android_kiosk_app().has_display_name()) { |
| entry_dict->SetKey( |
| chromeos::kAccountsPrefDeviceLocalAccountsKeyArcKioskDisplayName, |
| base::Value(entry.android_kiosk_app().display_name())); |
| } |
| } else if (entry.has_deprecated_public_session_id()) { |
| // Deprecated public session specification. |
| entry_dict->SetKey(chromeos::kAccountsPrefDeviceLocalAccountsKeyId, |
| base::Value(entry.deprecated_public_session_id())); |
| entry_dict->SetKey( |
| chromeos::kAccountsPrefDeviceLocalAccountsKeyType, |
| base::Value(DeviceLocalAccount::TYPE_PUBLIC_SESSION)); |
| } |
| account_list->Append(std::move(entry_dict)); |
| } |
| policies->Set(key::kDeviceLocalAccounts, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::move(account_list), nullptr); |
| if (container.has_auto_login_id()) { |
| policies->Set(key::kDeviceLocalAccountAutoLoginId, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>(container.auto_login_id()), |
| nullptr); |
| } |
| if (container.has_auto_login_delay()) { |
| policies->Set(key::kDeviceLocalAccountAutoLoginDelay, |
| POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, |
| POLICY_SOURCE_CLOUD, |
| DecodeIntegerValue(container.auto_login_delay()), nullptr); |
| } |
| if (container.has_enable_auto_login_bailout()) { |
| policies->Set( |
| key::kDeviceLocalAccountAutoLoginBailoutEnabled, |
| POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>(container.enable_auto_login_bailout()), |
| nullptr); |
| } |
| if (container.has_prompt_for_network_when_offline()) { |
| policies->Set(key::kDeviceLocalAccountPromptForNetworkWhenOffline, |
| POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, |
| POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>( |
| container.prompt_for_network_when_offline()), |
| nullptr); |
| } |
| } |
| |
| if (policy.has_saml_settings()) { |
| const em::SAMLSettingsProto& container(policy.saml_settings()); |
| if (container.has_transfer_saml_cookies()) { |
| policies->Set( |
| key::kDeviceTransferSAMLCookies, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>(container.transfer_saml_cookies()), |
| nullptr); |
| } |
| } |
| |
| if (policy.has_login_authentication_behavior()) { |
| const em::LoginAuthenticationBehaviorProto& container( |
| policy.login_authentication_behavior()); |
| if (container.has_login_authentication_behavior()) { |
| policies->Set( |
| key::kLoginAuthenticationBehavior, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| DecodeIntegerValue(container.login_authentication_behavior()), |
| nullptr); |
| } |
| } |
| |
| if (policy.has_allow_bluetooth()) { |
| const em::AllowBluetoothProto& container(policy.allow_bluetooth()); |
| if (container.has_allow_bluetooth()) { |
| policies->Set(key::kDeviceAllowBluetooth, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>(container.allow_bluetooth()), |
| nullptr); |
| } |
| } |
| |
| if (policy.has_login_video_capture_allowed_urls()) { |
| const em::LoginVideoCaptureAllowedUrlsProto& container( |
| policy.login_video_capture_allowed_urls()); |
| std::unique_ptr<base::ListValue> urls(new base::ListValue()); |
| for (const auto& entry : container.urls()) { |
| urls->AppendString(entry); |
| } |
| policies->Set(key::kLoginVideoCaptureAllowedUrls, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, std::move(urls), |
| nullptr); |
| } |
| |
| if (policy.has_device_login_screen_app_install_list()) { |
| const em::DeviceLoginScreenAppInstallListProto& proto( |
| policy.device_login_screen_app_install_list()); |
| std::unique_ptr<base::ListValue> apps(new base::ListValue); |
| for (const auto& app : proto.device_login_screen_app_install_list()) |
| apps->AppendString(app); |
| policies->Set(key::kDeviceLoginScreenAppInstallList, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, std::move(apps), |
| nullptr); |
| } |
| |
| if (policy.has_login_screen_power_management()) { |
| const em::LoginScreenPowerManagementProto& container( |
| policy.login_screen_power_management()); |
| if (container.has_login_screen_power_management()) { |
| SetJsonDevicePolicy(key::kDeviceLoginScreenPowerManagement, |
| container.login_screen_power_management(), policies); |
| } |
| } |
| |
| if (policy.has_login_screen_domain_auto_complete()) { |
| const em::LoginScreenDomainAutoCompleteProto& container( |
| policy.login_screen_domain_auto_complete()); |
| policies->Set(key::kDeviceLoginScreenDomainAutoComplete, |
| POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, |
| POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>( |
| container.login_screen_domain_auto_complete()), |
| nullptr); |
| } |
| |
| if (policy.has_login_screen_locales()) { |
| std::unique_ptr<base::ListValue> locales(new base::ListValue); |
| const em::LoginScreenLocalesProto& login_screen_locales( |
| policy.login_screen_locales()); |
| for (const auto& locale : login_screen_locales.login_screen_locales()) |
| locales->AppendString(locale); |
| policies->Set(key::kDeviceLoginScreenLocales, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, std::move(locales), |
| nullptr); |
| } |
| |
| if (policy.has_login_screen_input_methods()) { |
| std::unique_ptr<base::ListValue> input_methods(new base::ListValue); |
| const em::LoginScreenInputMethodsProto& login_screen_input_methods( |
| policy.login_screen_input_methods()); |
| for (const auto& input_method : |
| login_screen_input_methods.login_screen_input_methods()) { |
| input_methods->AppendString(input_method); |
| } |
| policies->Set(key::kDeviceLoginScreenInputMethods, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::move(input_methods), nullptr); |
| } |
| |
| if (policy.has_device_login_screen_auto_select_certificate_for_urls()) { |
| std::unique_ptr<base::ListValue> rules(new base::ListValue); |
| const em::DeviceLoginScreenAutoSelectCertificateForUrls& proto_rules( |
| policy.device_login_screen_auto_select_certificate_for_urls()); |
| for (const auto& rule : |
| proto_rules.login_screen_auto_select_certificate_rules()) { |
| rules->AppendString(rule); |
| } |
| policies->Set(key::kDeviceLoginScreenAutoSelectCertificateForUrls, |
| POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, |
| POLICY_SOURCE_CLOUD, std::move(rules), nullptr); |
| } |
| |
| if (policy.has_saml_login_authentication_type()) { |
| const em::SamlLoginAuthenticationTypeProto& container( |
| policy.saml_login_authentication_type()); |
| if (container.has_saml_login_authentication_type()) { |
| policies->Set(key::kDeviceSamlLoginAuthenticationType, |
| POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, |
| POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>( |
| container.saml_login_authentication_type()), |
| nullptr); |
| } |
| } |
| } |
| |
| void DecodeNetworkPolicies(const em::ChromeDeviceSettingsProto& policy, |
| PolicyMap* policies) { |
| if (policy.has_data_roaming_enabled()) { |
| const em::DataRoamingEnabledProto& container(policy.data_roaming_enabled()); |
| if (container.has_data_roaming_enabled()) { |
| policies->Set( |
| key::kDeviceDataRoamingEnabled, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>(container.data_roaming_enabled()), |
| nullptr); |
| } |
| } |
| |
| if (policy.has_device_wifi_fast_transition_enabled()) { |
| const em::DeviceWiFiFastTransitionEnabledProto& container( |
| policy.device_wifi_fast_transition_enabled()); |
| if (container.has_device_wifi_fast_transition_enabled()) { |
| policies->Set(key::kDeviceWiFiFastTransitionEnabled, |
| POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, |
| POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>( |
| container.device_wifi_fast_transition_enabled()), |
| nullptr); |
| } |
| } |
| |
| if (policy.has_network_throttling()) { |
| const em::NetworkThrottlingEnabledProto& container( |
| policy.network_throttling()); |
| std::unique_ptr<base::DictionaryValue> throttling_status( |
| new base::DictionaryValue()); |
| bool enabled = (container.has_enabled()) ? container.enabled() : false; |
| uint32_t upload_rate_kbits = |
| (container.has_upload_rate_kbits()) ? container.upload_rate_kbits() : 0; |
| uint32_t download_rate_kbits = (container.has_download_rate_kbits()) |
| ? container.download_rate_kbits() |
| : 0; |
| |
| throttling_status->SetBoolean("enabled", enabled); |
| throttling_status->SetInteger("upload_rate_kbits", upload_rate_kbits); |
| throttling_status->SetInteger("download_rate_kbits", download_rate_kbits); |
| policies->Set(key::kNetworkThrottlingEnabled, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::move(throttling_status), nullptr); |
| } |
| |
| if (policy.has_open_network_configuration() && |
| policy.open_network_configuration().has_open_network_configuration()) { |
| std::string config( |
| policy.open_network_configuration().open_network_configuration()); |
| policies->Set(key::kDeviceOpenNetworkConfiguration, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>(config), nullptr); |
| } |
| |
| if (policy.has_network_hostname() && |
| policy.network_hostname().has_device_hostname_template()) { |
| std::string hostname(policy.network_hostname().device_hostname_template()); |
| policies->Set(key::kDeviceHostnameTemplate, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>(hostname), nullptr); |
| } |
| |
| if (policy.has_device_kerberos_encryption_types()) { |
| const em::DeviceKerberosEncryptionTypesProto& container( |
| policy.device_kerberos_encryption_types()); |
| if (container.has_types()) { |
| policies->Set(key::kDeviceKerberosEncryptionTypes, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| DecodeIntegerValue(container.types()), nullptr); |
| } |
| } |
| } |
| |
| void DecodeReportingPolicies(const em::ChromeDeviceSettingsProto& policy, |
| PolicyMap* policies) { |
| if (policy.has_device_reporting()) { |
| const em::DeviceReportingProto& container(policy.device_reporting()); |
| if (container.has_report_version_info()) { |
| policies->Set( |
| key::kReportDeviceVersionInfo, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>(container.report_version_info()), |
| nullptr); |
| } |
| if (container.has_report_activity_times()) { |
| policies->Set( |
| key::kReportDeviceActivityTimes, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>(container.report_activity_times()), |
| nullptr); |
| } |
| if (container.has_report_boot_mode()) { |
| policies->Set(key::kReportDeviceBootMode, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>(container.report_boot_mode()), |
| nullptr); |
| } |
| if (container.has_report_location()) { |
| policies->Set(key::kReportDeviceLocation, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>(container.report_location()), |
| nullptr); |
| } |
| if (container.has_report_network_interfaces()) { |
| policies->Set( |
| key::kReportDeviceNetworkInterfaces, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>(container.report_network_interfaces()), |
| nullptr); |
| } |
| if (container.has_report_users()) { |
| policies->Set(key::kReportDeviceUsers, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>(container.report_users()), |
| nullptr); |
| } |
| if (container.has_report_hardware_status()) { |
| policies->Set( |
| key::kReportDeviceHardwareStatus, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>(container.report_hardware_status()), |
| nullptr); |
| } |
| if (container.has_report_session_status()) { |
| policies->Set( |
| key::kReportDeviceSessionStatus, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>(container.report_session_status()), |
| nullptr); |
| } |
| if (container.has_device_status_frequency()) { |
| policies->Set(key::kReportUploadFrequency, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| DecodeIntegerValue(container.device_status_frequency()), |
| nullptr); |
| } |
| } |
| |
| if (policy.has_device_heartbeat_settings()) { |
| const em::DeviceHeartbeatSettingsProto& container( |
| policy.device_heartbeat_settings()); |
| if (container.has_heartbeat_enabled()) { |
| policies->Set( |
| key::kHeartbeatEnabled, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, |
| POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>(container.heartbeat_enabled()), |
| nullptr); |
| } |
| if (container.has_heartbeat_frequency()) { |
| policies->Set(key::kHeartbeatFrequency, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| DecodeIntegerValue(container.heartbeat_frequency()), |
| nullptr); |
| } |
| } |
| |
| if (policy.has_device_log_upload_settings()) { |
| const em::DeviceLogUploadSettingsProto& container( |
| policy.device_log_upload_settings()); |
| if (container.has_system_log_upload_enabled()) { |
| policies->Set( |
| key::kLogUploadEnabled, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, |
| POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>(container.system_log_upload_enabled()), |
| nullptr); |
| } |
| } |
| } |
| |
| void DecodeAutoUpdatePolicies(const em::ChromeDeviceSettingsProto& policy, |
| PolicyMap* policies) { |
| if (policy.has_release_channel()) { |
| const em::ReleaseChannelProto& container(policy.release_channel()); |
| if (container.has_release_channel()) { |
| std::string channel(container.release_channel()); |
| policies->Set(key::kChromeOsReleaseChannel, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>(channel), nullptr); |
| // TODO(dubroy): Once http://crosbug.com/17015 is implemented, we won't |
| // have to pass the channel in here, only ping the update engine to tell |
| // it to fetch the channel from the policy. |
| chromeos::DBusThreadManager::Get()->GetUpdateEngineClient()->SetChannel( |
| channel, false); |
| } |
| if (container.has_release_channel_delegated()) { |
| policies->Set( |
| key::kChromeOsReleaseChannelDelegated, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>(container.release_channel_delegated()), |
| nullptr); |
| } |
| } |
| |
| if (policy.has_auto_update_settings()) { |
| const em::AutoUpdateSettingsProto& container(policy.auto_update_settings()); |
| if (container.has_update_disabled()) { |
| policies->Set(key::kDeviceAutoUpdateDisabled, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>(container.update_disabled()), |
| nullptr); |
| } |
| |
| if (container.has_target_version_prefix()) { |
| policies->Set( |
| key::kDeviceTargetVersionPrefix, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>(container.target_version_prefix()), |
| nullptr); |
| } |
| |
| // target_version_display_name is not actually a policy, but a display |
| // string for target_version_prefix, so we ignore it. |
| |
| if (container.has_rollback_to_target_version()) { |
| policies->Set( |
| key::kDeviceRollbackToTargetVersion, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>(container.rollback_to_target_version()), |
| nullptr); |
| } |
| |
| if (container.has_rollback_allowed_milestones()) { |
| policies->Set(key::kDeviceRollbackAllowedMilestones, |
| POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, |
| POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>( |
| container.rollback_allowed_milestones()), |
| nullptr); |
| } |
| |
| if (container.has_scatter_factor_in_seconds()) { |
| // TODO(dcheng): Shouldn't this use DecodeIntegerValue? |
| policies->Set(key::kDeviceUpdateScatterFactor, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>(static_cast<int>( |
| container.scatter_factor_in_seconds())), |
| nullptr); |
| } |
| |
| if (container.allowed_connection_types_size()) { |
| std::unique_ptr<base::ListValue> allowed_connection_types( |
| new base::ListValue); |
| for (const auto& entry : container.allowed_connection_types()) { |
| std::unique_ptr<base::Value> value = DecodeConnectionType(entry); |
| if (value) |
| allowed_connection_types->Append(std::move(value)); |
| } |
| policies->Set(key::kDeviceUpdateAllowedConnectionTypes, |
| POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, |
| POLICY_SOURCE_CLOUD, std::move(allowed_connection_types), |
| nullptr); |
| } |
| |
| if (container.has_http_downloads_enabled()) { |
| policies->Set( |
| key::kDeviceUpdateHttpDownloadsEnabled, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>(container.http_downloads_enabled()), |
| nullptr); |
| } |
| |
| if (container.has_reboot_after_update()) { |
| policies->Set( |
| key::kRebootAfterUpdate, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, |
| POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>(container.reboot_after_update()), |
| nullptr); |
| } |
| |
| if (container.has_p2p_enabled()) { |
| policies->Set(key::kDeviceAutoUpdateP2PEnabled, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>(container.p2p_enabled()), |
| nullptr); |
| } |
| |
| if (container.has_disallowed_time_intervals()) { |
| SetJsonDevicePolicy(key::kDeviceAutoUpdateTimeRestrictions, |
| container.disallowed_time_intervals(), policies); |
| } |
| |
| if (container.has_staging_schedule()) { |
| SetJsonDevicePolicy(key::kDeviceUpdateStagingSchedule, |
| container.staging_schedule(), policies); |
| } |
| } |
| |
| if (policy.has_allow_kiosk_app_control_chrome_version()) { |
| const em::AllowKioskAppControlChromeVersionProto& container( |
| policy.allow_kiosk_app_control_chrome_version()); |
| if (container.has_allow_kiosk_app_control_chrome_version()) { |
| policies->Set(key::kAllowKioskAppControlChromeVersion, |
| POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, |
| POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>( |
| container.allow_kiosk_app_control_chrome_version()), |
| nullptr); |
| } |
| } |
| } |
| |
| void DecodeAccessibilityPolicies(const em::ChromeDeviceSettingsProto& policy, |
| PolicyMap* policies) { |
| if (policy.has_accessibility_settings()) { |
| const em::AccessibilitySettingsProto& container( |
| policy.accessibility_settings()); |
| |
| if (container.has_login_screen_default_large_cursor_enabled()) { |
| policies->Set(key::kDeviceLoginScreenDefaultLargeCursorEnabled, |
| POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, |
| POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>( |
| container.login_screen_default_large_cursor_enabled()), |
| nullptr); |
| } |
| |
| if (container.has_login_screen_default_spoken_feedback_enabled()) { |
| policies->Set( |
| key::kDeviceLoginScreenDefaultSpokenFeedbackEnabled, |
| POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>( |
| container.login_screen_default_spoken_feedback_enabled()), |
| nullptr); |
| } |
| |
| if (container.has_login_screen_default_high_contrast_enabled()) { |
| policies->Set(key::kDeviceLoginScreenDefaultHighContrastEnabled, |
| POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, |
| POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>( |
| container.login_screen_default_high_contrast_enabled()), |
| nullptr); |
| } |
| |
| if (container.has_login_screen_default_screen_magnifier_type()) { |
| policies->Set(key::kDeviceLoginScreenDefaultScreenMagnifierType, |
| POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, |
| POLICY_SOURCE_CLOUD, |
| DecodeIntegerValue( |
| container.login_screen_default_screen_magnifier_type()), |
| nullptr); |
| } |
| |
| if (container.has_login_screen_default_virtual_keyboard_enabled()) { |
| policies->Set( |
| key::kDeviceLoginScreenDefaultVirtualKeyboardEnabled, |
| POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>( |
| container.login_screen_default_virtual_keyboard_enabled()), |
| nullptr); |
| } |
| } |
| } |
| |
| void DecodeExternalDataPolicies( |
| const em::ChromeDeviceSettingsProto& policy, |
| base::WeakPtr<ExternalDataManager> external_data_manager, |
| PolicyMap* policies) { |
| // TODO(https://crbug.com/814364): Migrate device wallpaper here. |
| if (policy.has_native_device_printers()) { |
| const em::DeviceNativePrintersProto& container( |
| policy.native_device_printers()); |
| if (container.has_external_policy()) { |
| SetExternalDataDevicePolicy(key::kDeviceNativePrinters, |
| container.external_policy(), |
| external_data_manager, policies); |
| } |
| } |
| } |
| |
| void DecodeGenericPolicies(const em::ChromeDeviceSettingsProto& policy, |
| PolicyMap* policies) { |
| if (policy.has_device_policy_refresh_rate()) { |
| const em::DevicePolicyRefreshRateProto& container( |
| policy.device_policy_refresh_rate()); |
| if (container.has_device_policy_refresh_rate()) { |
| policies->Set(key::kDevicePolicyRefreshRate, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| DecodeIntegerValue(container.device_policy_refresh_rate()), |
| nullptr); |
| } |
| } |
| |
| if (policy.has_metrics_enabled()) { |
| const em::MetricsEnabledProto& container(policy.metrics_enabled()); |
| if (container.has_metrics_enabled()) { |
| policies->Set(key::kDeviceMetricsReportingEnabled, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>(container.metrics_enabled()), |
| nullptr); |
| } |
| } |
| |
| if (policy.has_system_timezone()) { |
| if (policy.system_timezone().has_timezone()) { |
| policies->Set( |
| key::kSystemTimezone, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, |
| POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>(policy.system_timezone().timezone()), |
| nullptr); |
| } |
| |
| if (policy.system_timezone().has_timezone_detection_type()) { |
| std::unique_ptr<base::Value> value(DecodeIntegerValue( |
| policy.system_timezone().timezone_detection_type())); |
| if (value) { |
| policies->Set(key::kSystemTimezoneAutomaticDetection, |
| POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, |
| POLICY_SOURCE_CLOUD, std::move(value), nullptr); |
| } |
| } |
| } |
| |
| if (policy.has_use_24hour_clock()) { |
| if (policy.use_24hour_clock().has_use_24hour_clock()) { |
| policies->Set(key::kSystemUse24HourClock, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>( |
| policy.use_24hour_clock().use_24hour_clock()), |
| nullptr); |
| } |
| } |
| |
| if (policy.has_allow_redeem_offers()) { |
| const em::AllowRedeemChromeOsRegistrationOffersProto& container( |
| policy.allow_redeem_offers()); |
| if (container.has_allow_redeem_offers()) { |
| policies->Set( |
| key::kDeviceAllowRedeemChromeOsRegistrationOffers, |
| POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>(container.allow_redeem_offers()), |
| nullptr); |
| } |
| } |
| |
| if (policy.has_uptime_limit()) { |
| const em::UptimeLimitProto& container(policy.uptime_limit()); |
| if (container.has_uptime_limit()) { |
| policies->Set(key::kUptimeLimit, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| DecodeIntegerValue(container.uptime_limit()), nullptr); |
| } |
| } |
| |
| if (policy.has_variations_parameter()) { |
| if (policy.variations_parameter().has_parameter()) { |
| policies->Set(key::kDeviceVariationsRestrictParameter, |
| POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, |
| POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>( |
| policy.variations_parameter().parameter()), |
| nullptr); |
| } |
| } |
| |
| if (policy.has_attestation_settings()) { |
| if (policy.attestation_settings().has_attestation_enabled()) { |
| policies->Set(key::kAttestationEnabledForDevice, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>( |
| policy.attestation_settings().attestation_enabled()), |
| nullptr); |
| } |
| if (policy.attestation_settings().has_content_protection_enabled()) { |
| policies->Set( |
| key::kAttestationForContentProtectionEnabled, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>( |
| policy.attestation_settings().content_protection_enabled()), |
| nullptr); |
| } |
| } |
| |
| if (policy.has_system_settings()) { |
| const em::SystemSettingsProto& container(policy.system_settings()); |
| if (container.has_block_devmode()) { |
| policies->Set(key::kDeviceBlockDevmode, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>(container.block_devmode()), |
| nullptr); |
| } |
| } |
| |
| if (policy.has_extension_cache_size()) { |
| const em::ExtensionCacheSizeProto& container(policy.extension_cache_size()); |
| if (container.has_extension_cache_size()) { |
| policies->Set(key::kExtensionCacheSize, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| DecodeIntegerValue(container.extension_cache_size()), |
| nullptr); |
| } |
| } |
| |
| if (policy.has_display_rotation_default()) { |
| const em::DisplayRotationDefaultProto& container( |
| policy.display_rotation_default()); |
| if (container.has_display_rotation_default()) { |
| policies->Set(key::kDisplayRotationDefault, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| DecodeIntegerValue(container.display_rotation_default()), |
| nullptr); |
| } |
| } |
| |
| if (policy.has_device_display_resolution()) { |
| const em::DeviceDisplayResolutionProto& container( |
| policy.device_display_resolution()); |
| if (container.has_device_display_resolution()) { |
| SetJsonDevicePolicy(key::kDeviceDisplayResolution, |
| container.device_display_resolution(), policies); |
| } |
| } |
| |
| if (policy.has_usb_detachable_whitelist()) { |
| const em::UsbDetachableWhitelistProto& container( |
| policy.usb_detachable_whitelist()); |
| std::unique_ptr<base::ListValue> whitelist(new base::ListValue); |
| for (const auto& entry : container.id()) { |
| std::unique_ptr<base::DictionaryValue> ids(new base::DictionaryValue()); |
| if (entry.has_vendor_id()) { |
| ids->SetString("vid", base::StringPrintf("%04X", entry.vendor_id())); |
| } |
| if (entry.has_product_id()) { |
| ids->SetString("pid", base::StringPrintf("%04X", entry.product_id())); |
| } |
| whitelist->Append(std::move(ids)); |
| } |
| policies->Set(key::kUsbDetachableWhitelist, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::move(whitelist), nullptr); |
| } |
| |
| if (policy.has_quirks_download_enabled()) { |
| const em::DeviceQuirksDownloadEnabledProto& container( |
| policy.quirks_download_enabled()); |
| if (container.has_quirks_download_enabled()) { |
| policies->Set( |
| key::kDeviceQuirksDownloadEnabled, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>(container.quirks_download_enabled()), |
| nullptr); |
| } |
| } |
| |
| if (policy.has_device_wallpaper_image()) { |
| const em::DeviceWallpaperImageProto& container( |
| policy.device_wallpaper_image()); |
| if (container.has_device_wallpaper_image()) { |
| SetJsonDevicePolicy(key::kDeviceWallpaperImage, |
| container.device_wallpaper_image(), policies); |
| } |
| } |
| |
| if (policy.has_device_second_factor_authentication()) { |
| const em::DeviceSecondFactorAuthenticationProto& container( |
| policy.device_second_factor_authentication()); |
| policies->Set(key::kDeviceSecondFactorAuthentication, |
| POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, |
| POLICY_SOURCE_CLOUD, DecodeIntegerValue(container.mode()), |
| nullptr); |
| } |
| |
| if (policy.has_device_off_hours()) { |
| auto off_hours_policy = |
| off_hours::ConvertOffHoursProtoToValue(policy.device_off_hours()); |
| if (off_hours_policy) |
| policies->Set(key::kDeviceOffHours, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::move(off_hours_policy), nullptr); |
| } |
| |
| if (policy.has_cast_receiver_name()) { |
| const em::CastReceiverNameProto& container(policy.cast_receiver_name()); |
| if (container.has_name()) |
| policies->Set(key::kCastReceiverName, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>(container.name()), nullptr); |
| } |
| |
| if (policy.has_native_device_printers_access_mode()) { |
| const em::DeviceNativePrintersAccessModeProto& container( |
| policy.native_device_printers_access_mode()); |
| if (container.has_access_mode()) { |
| policies->Set(key::kDeviceNativePrintersAccessMode, |
| POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, |
| POLICY_SOURCE_CLOUD, |
| DecodeIntegerValue(container.access_mode()), nullptr); |
| } |
| } |
| |
| if (policy.has_native_device_printers_blacklist()) { |
| const em::DeviceNativePrintersBlacklistProto& container( |
| policy.native_device_printers_blacklist()); |
| std::unique_ptr<base::ListValue> blacklist = |
| std::make_unique<base::ListValue>(); |
| for (const auto& entry : container.blacklist()) |
| blacklist->AppendString(entry); |
| |
| policies->Set(key::kDeviceNativePrintersBlacklist, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::move(blacklist), nullptr); |
| } |
| |
| if (policy.has_native_device_printers_whitelist()) { |
| const em::DeviceNativePrintersWhitelistProto& container( |
| policy.native_device_printers_whitelist()); |
| std::unique_ptr<base::ListValue> whitelist = |
| std::make_unique<base::ListValue>(); |
| for (const auto& entry : container.whitelist()) |
| whitelist->AppendString(entry); |
| |
| policies->Set(key::kDeviceNativePrintersWhitelist, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::move(whitelist), nullptr); |
| } |
| |
| if (policy.has_tpm_firmware_update_settings()) { |
| policies->Set(key::kTPMFirmwareUpdateSettings, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| chromeos::tpm_firmware_update::DecodeSettingsProto( |
| policy.tpm_firmware_update_settings()), |
| nullptr); |
| } |
| |
| if (policy.has_minimum_required_version()) { |
| const em::MinimumRequiredVersionProto& container( |
| policy.minimum_required_version()); |
| if (container.has_chrome_version()) |
| policies->Set(key::kMinimumRequiredChromeVersion, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>(container.chrome_version()), |
| nullptr); |
| } |
| |
| if (policy.has_unaffiliated_arc_allowed()) { |
| const em::UnaffiliatedArcAllowedProto& container( |
| policy.unaffiliated_arc_allowed()); |
| if (container.has_unaffiliated_arc_allowed()) { |
| policies->Set( |
| key::kUnaffiliatedArcAllowed, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>(container.unaffiliated_arc_allowed()), |
| nullptr); |
| } |
| } |
| |
| if (policy.has_device_user_policy_loopback_processing_mode()) { |
| const em::DeviceUserPolicyLoopbackProcessingModeProto& container( |
| policy.device_user_policy_loopback_processing_mode()); |
| if (container.has_mode()) { |
| policies->Set(key::kDeviceUserPolicyLoopbackProcessingMode, |
| POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, |
| POLICY_SOURCE_CLOUD, DecodeIntegerValue(container.mode()), |
| nullptr); |
| } |
| } |
| |
| if (policy.has_device_login_screen_isolate_origins()) { |
| const em::DeviceLoginScreenIsolateOriginsProto& container( |
| policy.device_login_screen_isolate_origins()); |
| if (container.has_isolate_origins()) { |
| policies->Set( |
| key::kDeviceLoginScreenIsolateOrigins, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>(container.isolate_origins()), nullptr); |
| } |
| } |
| |
| if (policy.has_device_login_screen_site_per_process()) { |
| const em::DeviceLoginScreenSitePerProcessProto& container( |
| policy.device_login_screen_site_per_process()); |
| if (container.has_site_per_process()) { |
| policies->Set( |
| key::kDeviceLoginScreenSitePerProcess, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>(container.site_per_process()), nullptr); |
| } |
| } |
| |
| if (policy.has_virtual_machines_allowed()) { |
| const em::VirtualMachinesAllowedProto& container( |
| policy.virtual_machines_allowed()); |
| if (container.has_virtual_machines_allowed()) { |
| policies->Set( |
| key::kVirtualMachinesAllowed, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>(container.virtual_machines_allowed()), |
| nullptr); |
| } |
| } |
| |
| if (policy.has_device_machine_password_change_rate()) { |
| const em::DeviceMachinePasswordChangeRateProto& container( |
| policy.device_machine_password_change_rate()); |
| if (container.has_rate_days()) { |
| policies->Set(key::kDeviceMachinePasswordChangeRate, |
| POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, |
| POLICY_SOURCE_CLOUD, |
| DecodeIntegerValue(container.rate_days()), nullptr); |
| } |
| } |
| |
| if (policy.has_device_gpo_cache_lifetime()) { |
| const em::DeviceGpoCacheLifetimeProto& container( |
| policy.device_gpo_cache_lifetime()); |
| if (container.has_lifetime_hours()) { |
| policies->Set(key::kDeviceGpoCacheLifetime, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| DecodeIntegerValue(container.lifetime_hours()), nullptr); |
| } |
| } |
| |
| if (policy.has_device_auth_data_cache_lifetime()) { |
| const em::DeviceAuthDataCacheLifetimeProto& container( |
| policy.device_auth_data_cache_lifetime()); |
| if (container.has_lifetime_hours()) { |
| policies->Set(key::kDeviceAuthDataCacheLifetime, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, |
| DecodeIntegerValue(container.lifetime_hours()), nullptr); |
| } |
| } |
| |
| if (policy.has_device_unaffiliated_crostini_allowed()) { |
| const em::DeviceUnaffiliatedCrostiniAllowedProto& container( |
| policy.device_unaffiliated_crostini_allowed()); |
| if (container.has_device_unaffiliated_crostini_allowed()) { |
| policies->Set(key::kDeviceUnaffiliatedCrostiniAllowed, |
| POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, |
| POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>( |
| container.device_unaffiliated_crostini_allowed()), |
| nullptr); |
| } |
| } |
| |
| if (policy.has_plugin_vm_allowed()) { |
| const em::PluginVmAllowedProto& container(policy.plugin_vm_allowed()); |
| if (container.has_plugin_vm_allowed()) { |
| policies->Set( |
| key::kPluginVmAllowed, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, |
| POLICY_SOURCE_CLOUD, |
| std::make_unique<base::Value>(container.plugin_vm_allowed()), |
| nullptr); |
| } |
| } |
| } |
| |
| } // namespace |
| |
| std::unique_ptr<base::Value> DecodeJsonStringAndNormalize( |
| const std::string& json_string, |
| const std::string& policy_name, |
| std::string* error) { |
| std::string json_error; |
| std::unique_ptr<base::Value> root = base::JSONReader::ReadAndReturnError( |
| json_string, base::JSON_ALLOW_TRAILING_COMMAS, NULL, &json_error); |
| if (!root) { |
| *error = "Invalid JSON string: " + json_error; |
| return nullptr; |
| } |
| |
| const Schema& schema = |
| policy::GetChromeSchema().GetKnownProperty(policy_name); |
| CHECK(schema.valid()); |
| |
| std::string schema_error; |
| std::string error_path; |
| bool changed = false; |
| if (!schema.Normalize(root.get(), SCHEMA_ALLOW_UNKNOWN, &error_path, |
| &schema_error, &changed)) { |
| std::ostringstream msg; |
| msg << "Invalid policy value: " << schema_error << " (at " |
| << (error_path.empty() ? "toplevel" : error_path) << ")"; |
| *error = msg.str(); |
| return nullptr; |
| } |
| if (changed) { |
| std::ostringstream msg; |
| msg << "Dropped unknown properties: " << schema_error << " (at " |
| << (error_path.empty() ? "toplevel" : error_path) << ")"; |
| *error = msg.str(); |
| } |
| |
| return root; |
| } |
| |
| void DecodeDevicePolicy( |
| const em::ChromeDeviceSettingsProto& policy, |
| base::WeakPtr<ExternalDataManager> external_data_manager, |
| PolicyMap* policies) { |
| // Decode the various groups of policies. |
| DecodeLoginPolicies(policy, policies); |
| DecodeNetworkPolicies(policy, policies); |
| DecodeReportingPolicies(policy, policies); |
| DecodeAutoUpdatePolicies(policy, policies); |
| DecodeAccessibilityPolicies(policy, policies); |
| DecodeExternalDataPolicies(policy, external_data_manager, policies); |
| DecodeGenericPolicies(policy, policies); |
| } |
| |
| } // namespace policy |