device_policy_decoder_chromeos.cc revision b2df76ea8fec9e32f6f3718986dba0d95315b29c
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/policy/device_policy_decoder_chromeos.h" 6 7#include <limits> 8 9#include "base/logging.h" 10#include "base/values.h" 11#include "chrome/browser/chromeos/policy/enterprise_install_attributes.h" 12#include "chrome/browser/chromeos/settings/cros_settings_names.h" 13#include "chrome/browser/policy/policy_map.h" 14#include "chrome/browser/policy/proto/chromeos/chrome_device_policy.pb.h" 15#include "chromeos/dbus/dbus_thread_manager.h" 16#include "chromeos/dbus/update_engine_client.h" 17#include "policy/policy_constants.h" 18#include "third_party/cros_system_api/dbus/service_constants.h" 19 20using google::protobuf::RepeatedField; 21using google::protobuf::RepeatedPtrField; 22 23namespace em = enterprise_management; 24 25namespace policy { 26 27namespace { 28 29// Decodes a protobuf integer to an IntegerValue. The caller assumes ownership 30// of the return Value*. Returns NULL in case the input value is out of bounds. 31Value* DecodeIntegerValue(google::protobuf::int64 value) { 32 if (value < std::numeric_limits<int>::min() || 33 value > std::numeric_limits<int>::max()) { 34 LOG(WARNING) << "Integer value " << value 35 << " out of numeric limits, ignoring."; 36 return NULL; 37 } 38 39 return Value::CreateIntegerValue(static_cast<int>(value)); 40} 41 42Value* DecodeConnectionType(int value) { 43 static const char* const kConnectionTypes[] = { 44 flimflam::kTypeEthernet, 45 flimflam::kTypeWifi, 46 flimflam::kTypeWimax, 47 flimflam::kTypeBluetooth, 48 flimflam::kTypeCellular, 49 }; 50 51 if (value < 0 || value >= static_cast<int>(arraysize(kConnectionTypes))) 52 return NULL; 53 54 return Value::CreateStringValue(kConnectionTypes[value]); 55} 56 57void DecodeLoginPolicies(const em::ChromeDeviceSettingsProto& policy, 58 PolicyMap* policies) { 59 if (policy.has_guest_mode_enabled()) { 60 const em::GuestModeEnabledProto& container(policy.guest_mode_enabled()); 61 if (container.has_guest_mode_enabled()) { 62 policies->Set(key::kDeviceGuestModeEnabled, 63 POLICY_LEVEL_MANDATORY, 64 POLICY_SCOPE_MACHINE, 65 Value::CreateBooleanValue(container.guest_mode_enabled())); 66 } 67 } 68 69 if (policy.has_show_user_names()) { 70 const em::ShowUserNamesOnSigninProto& container(policy.show_user_names()); 71 if (container.has_show_user_names()) { 72 policies->Set(key::kDeviceShowUserNamesOnSignin, 73 POLICY_LEVEL_MANDATORY, 74 POLICY_SCOPE_MACHINE, 75 Value::CreateBooleanValue(container.show_user_names())); 76 } 77 } 78 79 if (policy.has_allow_new_users()) { 80 const em::AllowNewUsersProto& container(policy.allow_new_users()); 81 if (container.has_allow_new_users()) { 82 policies->Set(key::kDeviceAllowNewUsers, 83 POLICY_LEVEL_MANDATORY, 84 POLICY_SCOPE_MACHINE, 85 Value::CreateBooleanValue(container.allow_new_users())); 86 } 87 } 88 89 if (policy.has_user_whitelist()) { 90 const em::UserWhitelistProto& container(policy.user_whitelist()); 91 ListValue* whitelist = new ListValue(); 92 RepeatedPtrField<std::string>::const_iterator entry; 93 for (entry = container.user_whitelist().begin(); 94 entry != container.user_whitelist().end(); 95 ++entry) { 96 whitelist->Append(Value::CreateStringValue(*entry)); 97 } 98 policies->Set(key::kDeviceUserWhitelist, 99 POLICY_LEVEL_MANDATORY, 100 POLICY_SCOPE_MACHINE, 101 whitelist); 102 } 103 104 if (policy.has_ephemeral_users_enabled()) { 105 const em::EphemeralUsersEnabledProto& container( 106 policy.ephemeral_users_enabled()); 107 if (container.has_ephemeral_users_enabled()) { 108 policies->Set(key::kDeviceEphemeralUsersEnabled, 109 POLICY_LEVEL_MANDATORY, 110 POLICY_SCOPE_MACHINE, 111 Value::CreateBooleanValue( 112 container.ephemeral_users_enabled())); 113 } 114 } 115 116 if (policy.has_device_local_accounts()) { 117 const em::DeviceLocalAccountsProto& container( 118 policy.device_local_accounts()); 119 const RepeatedPtrField<em::DeviceLocalAccountInfoProto>& accounts = 120 container.account(); 121 scoped_ptr<base::ListValue> account_list(new base::ListValue()); 122 RepeatedPtrField<em::DeviceLocalAccountInfoProto>::const_iterator entry; 123 for (entry = accounts.begin(); entry != accounts.end(); ++entry) { 124 scoped_ptr<base::DictionaryValue> entry_dict( 125 new base::DictionaryValue()); 126 if (entry->has_type()) { 127 if (entry->has_account_id()) { 128 entry_dict->SetStringWithoutPathExpansion( 129 chromeos::kAccountsPrefDeviceLocalAccountsKeyId, 130 entry->account_id()); 131 } 132 entry_dict->SetIntegerWithoutPathExpansion( 133 chromeos::kAccountsPrefDeviceLocalAccountsKeyType, entry->type()); 134 if (entry->kiosk_app().has_app_id()) { 135 entry_dict->SetStringWithoutPathExpansion( 136 chromeos::kAccountsPrefDeviceLocalAccountsKeyKioskAppId, 137 entry->kiosk_app().app_id()); 138 } 139 if (entry->kiosk_app().has_update_url()) { 140 entry_dict->SetStringWithoutPathExpansion( 141 chromeos::kAccountsPrefDeviceLocalAccountsKeyKioskAppUpdateURL, 142 entry->kiosk_app().update_url()); 143 } 144 } else if (entry->has_deprecated_public_session_id()) { 145 // Deprecated public session specification. 146 entry_dict->SetStringWithoutPathExpansion( 147 chromeos::kAccountsPrefDeviceLocalAccountsKeyId, 148 entry->deprecated_public_session_id()); 149 entry_dict->SetIntegerWithoutPathExpansion( 150 chromeos::kAccountsPrefDeviceLocalAccountsKeyType, 151 chromeos::DEVICE_LOCAL_ACCOUNT_TYPE_PUBLIC_SESSION); 152 } 153 account_list->Append(entry_dict.release()); 154 } 155 policies->Set(key::kDeviceLocalAccounts, 156 POLICY_LEVEL_MANDATORY, 157 POLICY_SCOPE_MACHINE, 158 account_list.release()); 159 if (container.has_auto_login_id()) { 160 policies->Set(key::kDeviceLocalAccountAutoLoginId, 161 POLICY_LEVEL_MANDATORY, 162 POLICY_SCOPE_MACHINE, 163 Value::CreateStringValue(container.auto_login_id())); 164 } 165 if (container.has_auto_login_delay()) { 166 policies->Set(key::kDeviceLocalAccountAutoLoginDelay, 167 POLICY_LEVEL_MANDATORY, 168 POLICY_SCOPE_MACHINE, 169 DecodeIntegerValue(container.auto_login_delay())); 170 } 171 if (container.has_enable_auto_login_bailout()) { 172 policies->Set(key::kDeviceLocalAccountAutoLoginBailoutEnabled, 173 POLICY_LEVEL_MANDATORY, 174 POLICY_SCOPE_MACHINE, 175 Value::CreateBooleanValue( 176 container.enable_auto_login_bailout())); 177 } 178 } 179} 180 181void DecodeKioskPolicies(const em::ChromeDeviceSettingsProto& policy, 182 PolicyMap* policies, 183 EnterpriseInstallAttributes* install_attributes) { 184 // No policies if this is not KIOSK. 185 if (install_attributes->GetMode() != DEVICE_MODE_KIOSK) 186 return; 187 188 if (policy.has_forced_logout_timeouts()) { 189 const em::ForcedLogoutTimeoutsProto& container( 190 policy.forced_logout_timeouts()); 191 if (container.has_idle_logout_timeout()) { 192 policies->Set(key::kDeviceIdleLogoutTimeout, 193 POLICY_LEVEL_MANDATORY, 194 POLICY_SCOPE_MACHINE, 195 DecodeIntegerValue(container.idle_logout_timeout())); 196 } 197 if (container.has_idle_logout_warning_duration()) { 198 policies->Set(key::kDeviceIdleLogoutWarningDuration, 199 POLICY_LEVEL_MANDATORY, 200 POLICY_SCOPE_MACHINE, 201 DecodeIntegerValue( 202 container.idle_logout_warning_duration())); 203 } 204 } 205 206 if (policy.has_login_screen_saver()) { 207 const em::ScreenSaverProto& container( 208 policy.login_screen_saver()); 209 if (container.has_screen_saver_extension_id()) { 210 policies->Set(key::kDeviceLoginScreenSaverId, 211 POLICY_LEVEL_MANDATORY, 212 POLICY_SCOPE_MACHINE, 213 Value::CreateStringValue( 214 container.screen_saver_extension_id())); 215 } 216 if (container.has_screen_saver_timeout()) { 217 policies->Set(key::kDeviceLoginScreenSaverTimeout, 218 POLICY_LEVEL_MANDATORY, 219 POLICY_SCOPE_MACHINE, 220 DecodeIntegerValue(container.screen_saver_timeout())); 221 } 222 } 223 224 if (policy.has_app_pack()) { 225 const em::AppPackProto& container(policy.app_pack()); 226 base::ListValue* app_pack_list = new base::ListValue(); 227 for (int i = 0; i < container.app_pack_size(); ++i) { 228 const em::AppPackEntryProto& entry(container.app_pack(i)); 229 if (entry.has_extension_id() && entry.has_update_url()) { 230 base::DictionaryValue* dict = new base::DictionaryValue(); 231 dict->SetString(chromeos::kAppPackKeyExtensionId, entry.extension_id()); 232 dict->SetString(chromeos::kAppPackKeyUpdateUrl, entry.update_url()); 233 app_pack_list->Append(dict); 234 } 235 } 236 policies->Set(key::kDeviceAppPack, 237 POLICY_LEVEL_MANDATORY, 238 POLICY_SCOPE_MACHINE, 239 app_pack_list); 240 } 241 242 if (policy.has_pinned_apps()) { 243 const em::PinnedAppsProto& container(policy.pinned_apps()); 244 base::ListValue* pinned_apps_list = new base::ListValue(); 245 for (int i = 0; i < container.app_id_size(); ++i) 246 pinned_apps_list->Append(Value::CreateStringValue(container.app_id(i))); 247 248 policies->Set(key::kPinnedLauncherApps, 249 POLICY_LEVEL_RECOMMENDED, 250 POLICY_SCOPE_MACHINE, 251 pinned_apps_list); 252 } 253} 254 255void DecodeNetworkPolicies(const em::ChromeDeviceSettingsProto& policy, 256 PolicyMap* policies, 257 EnterpriseInstallAttributes* install_attributes) { 258 if (policy.has_device_proxy_settings()) { 259 const em::DeviceProxySettingsProto& container( 260 policy.device_proxy_settings()); 261 scoped_ptr<DictionaryValue> proxy_settings(new DictionaryValue); 262 if (container.has_proxy_mode()) 263 proxy_settings->SetString(key::kProxyMode, container.proxy_mode()); 264 if (container.has_proxy_server()) 265 proxy_settings->SetString(key::kProxyServer, container.proxy_server()); 266 if (container.has_proxy_pac_url()) 267 proxy_settings->SetString(key::kProxyPacUrl, container.proxy_pac_url()); 268 if (container.has_proxy_bypass_list()) { 269 proxy_settings->SetString(key::kProxyBypassList, 270 container.proxy_bypass_list()); 271 } 272 273 // Figure out the level. Proxy policy is mandatory in kiosk mode. 274 PolicyLevel level = POLICY_LEVEL_RECOMMENDED; 275 if (install_attributes->GetMode() == DEVICE_MODE_KIOSK) 276 level = POLICY_LEVEL_MANDATORY; 277 278 if (!proxy_settings->empty()) { 279 policies->Set(key::kProxySettings, 280 level, 281 POLICY_SCOPE_MACHINE, 282 proxy_settings.release()); 283 } 284 } 285 286 if (policy.has_data_roaming_enabled()) { 287 const em::DataRoamingEnabledProto& container(policy.data_roaming_enabled()); 288 if (container.has_data_roaming_enabled()) { 289 policies->Set(key::kDeviceDataRoamingEnabled, 290 POLICY_LEVEL_MANDATORY, 291 POLICY_SCOPE_MACHINE, 292 Value::CreateBooleanValue( 293 container.data_roaming_enabled())); 294 } 295 } 296 297 if (policy.has_open_network_configuration() && 298 policy.open_network_configuration().has_open_network_configuration()) { 299 std::string config( 300 policy.open_network_configuration().open_network_configuration()); 301 policies->Set(key::kDeviceOpenNetworkConfiguration, 302 POLICY_LEVEL_MANDATORY, 303 POLICY_SCOPE_MACHINE, 304 Value::CreateStringValue(config)); 305 } 306} 307 308void DecodeReportingPolicies(const em::ChromeDeviceSettingsProto& policy, 309 PolicyMap* policies) { 310 if (policy.has_device_reporting()) { 311 const em::DeviceReportingProto& container(policy.device_reporting()); 312 if (container.has_report_version_info()) { 313 policies->Set(key::kReportDeviceVersionInfo, 314 POLICY_LEVEL_MANDATORY, 315 POLICY_SCOPE_MACHINE, 316 Value::CreateBooleanValue(container.report_version_info())); 317 } 318 if (container.has_report_activity_times()) { 319 policies->Set(key::kReportDeviceActivityTimes, 320 POLICY_LEVEL_MANDATORY, 321 POLICY_SCOPE_MACHINE, 322 Value::CreateBooleanValue( 323 container.report_activity_times())); 324 } 325 if (container.has_report_boot_mode()) { 326 policies->Set(key::kReportDeviceBootMode, 327 POLICY_LEVEL_MANDATORY, 328 POLICY_SCOPE_MACHINE, 329 Value::CreateBooleanValue(container.report_boot_mode())); 330 } 331 if (container.has_report_location()) { 332 policies->Set(key::kReportDeviceLocation, 333 POLICY_LEVEL_MANDATORY, 334 POLICY_SCOPE_MACHINE, 335 Value::CreateBooleanValue(container.report_location())); 336 } 337 } 338} 339 340void DecodeAutoUpdatePolicies(const em::ChromeDeviceSettingsProto& policy, 341 PolicyMap* policies) { 342 if (policy.has_release_channel()) { 343 const em::ReleaseChannelProto& container(policy.release_channel()); 344 if (container.has_release_channel()) { 345 std::string channel(container.release_channel()); 346 policies->Set(key::kChromeOsReleaseChannel, 347 POLICY_LEVEL_MANDATORY, 348 POLICY_SCOPE_MACHINE, 349 Value::CreateStringValue(channel)); 350 // TODO(dubroy): Once http://crosbug.com/17015 is implemented, we won't 351 // have to pass the channel in here, only ping the update engine to tell 352 // it to fetch the channel from the policy. 353 chromeos::DBusThreadManager::Get()->GetUpdateEngineClient()-> 354 SetReleaseTrack(channel); 355 } 356 if (container.has_release_channel_delegated()) { 357 policies->Set(key::kChromeOsReleaseChannelDelegated, 358 POLICY_LEVEL_MANDATORY, 359 POLICY_SCOPE_MACHINE, 360 Value::CreateBooleanValue( 361 container.release_channel_delegated())); 362 } 363 } 364 365 if (policy.has_auto_update_settings()) { 366 const em::AutoUpdateSettingsProto& container(policy.auto_update_settings()); 367 if (container.has_update_disabled()) { 368 policies->Set(key::kDeviceAutoUpdateDisabled, 369 POLICY_LEVEL_MANDATORY, 370 POLICY_SCOPE_MACHINE, 371 Value::CreateBooleanValue(container.update_disabled())); 372 } 373 374 if (container.has_target_version_prefix()) { 375 policies->Set(key::kDeviceTargetVersionPrefix, 376 POLICY_LEVEL_MANDATORY, 377 POLICY_SCOPE_MACHINE, 378 Value::CreateStringValue( 379 container.target_version_prefix())); 380 } 381 382 // target_version_display_name is not actually a policy, but a display 383 // string for target_version_prefix, so we ignore it. 384 385 if (container.has_scatter_factor_in_seconds()) { 386 policies->Set(key::kDeviceUpdateScatterFactor, 387 POLICY_LEVEL_MANDATORY, 388 POLICY_SCOPE_MACHINE, 389 Value::CreateIntegerValue( 390 container.scatter_factor_in_seconds())); 391 } 392 393 if (container.allowed_connection_types_size()) { 394 ListValue* allowed_connection_types = new ListValue(); 395 RepeatedField<int>::const_iterator entry; 396 for (entry = container.allowed_connection_types().begin(); 397 entry != container.allowed_connection_types().end(); 398 ++entry) { 399 base::Value* value = DecodeConnectionType(*entry); 400 if (value) 401 allowed_connection_types->Append(value); 402 } 403 policies->Set(key::kDeviceUpdateAllowedConnectionTypes, 404 POLICY_LEVEL_MANDATORY, 405 POLICY_SCOPE_MACHINE, 406 allowed_connection_types); 407 } 408 409 if (container.has_reboot_after_update()) { 410 policies->Set(key::kRebootAfterUpdate, 411 POLICY_LEVEL_MANDATORY, 412 POLICY_SCOPE_MACHINE, 413 Value::CreateBooleanValue(container.reboot_after_update())); 414 } 415 } 416} 417 418void DecodeGenericPolicies(const em::ChromeDeviceSettingsProto& policy, 419 PolicyMap* policies) { 420 if (policy.has_device_policy_refresh_rate()) { 421 const em::DevicePolicyRefreshRateProto& container( 422 policy.device_policy_refresh_rate()); 423 if (container.has_device_policy_refresh_rate()) { 424 policies->Set(key::kDevicePolicyRefreshRate, 425 POLICY_LEVEL_MANDATORY, 426 POLICY_SCOPE_MACHINE, 427 DecodeIntegerValue(container.device_policy_refresh_rate())); 428 } 429 } 430 431 if (policy.has_metrics_enabled()) { 432 const em::MetricsEnabledProto& container(policy.metrics_enabled()); 433 if (container.has_metrics_enabled()) { 434 policies->Set(key::kDeviceMetricsReportingEnabled, 435 POLICY_LEVEL_MANDATORY, 436 POLICY_SCOPE_MACHINE, 437 Value::CreateBooleanValue(container.metrics_enabled())); 438 } 439 } 440 441 if (policy.has_start_up_urls()) { 442 const em::StartUpUrlsProto& container(policy.start_up_urls()); 443 ListValue* urls = new ListValue(); 444 RepeatedPtrField<std::string>::const_iterator entry; 445 for (entry = container.start_up_urls().begin(); 446 entry != container.start_up_urls().end(); 447 ++entry) { 448 urls->Append(Value::CreateStringValue(*entry)); 449 } 450 policies->Set(key::kDeviceStartUpUrls, 451 POLICY_LEVEL_MANDATORY, 452 POLICY_SCOPE_MACHINE, 453 urls); 454 } 455 456 if (policy.has_system_timezone()) { 457 if (policy.system_timezone().has_timezone()) { 458 policies->Set(key::kSystemTimezone, 459 POLICY_LEVEL_MANDATORY, 460 POLICY_SCOPE_MACHINE, 461 Value::CreateStringValue( 462 policy.system_timezone().timezone())); 463 } 464 } 465 466 if (policy.has_allow_redeem_offers()) { 467 const em::AllowRedeemChromeOsRegistrationOffersProto& container( 468 policy.allow_redeem_offers()); 469 if (container.has_allow_redeem_offers()) { 470 policies->Set(key::kDeviceAllowRedeemChromeOsRegistrationOffers, 471 POLICY_LEVEL_MANDATORY, 472 POLICY_SCOPE_MACHINE, 473 Value::CreateBooleanValue( 474 container.allow_redeem_offers())); 475 } 476 } 477 478 if (policy.has_uptime_limit()) { 479 const em::UptimeLimitProto& container(policy.uptime_limit()); 480 if (container.has_uptime_limit()) { 481 policies->Set(key::kUptimeLimit, 482 POLICY_LEVEL_MANDATORY, 483 POLICY_SCOPE_MACHINE, 484 DecodeIntegerValue(container.uptime_limit())); 485 } 486 } 487 488 if (policy.has_start_up_flags()) { 489 const em::StartUpFlagsProto& container(policy.start_up_flags()); 490 ListValue* flags = new ListValue(); 491 RepeatedPtrField<std::string>::const_iterator entry; 492 for (entry = container.flags().begin(); 493 entry != container.flags().end(); 494 ++entry) { 495 flags->Append(Value::CreateStringValue(*entry)); 496 } 497 policies->Set(key::kDeviceStartUpFlags, 498 POLICY_LEVEL_MANDATORY, 499 POLICY_SCOPE_MACHINE, 500 flags); 501 } 502 503 if (policy.has_variations_parameter()) { 504 if (policy.variations_parameter().has_parameter()) { 505 policies->Set(key::kDeviceVariationsRestrictParameter, 506 POLICY_LEVEL_MANDATORY, 507 POLICY_SCOPE_MACHINE, 508 Value::CreateStringValue( 509 policy.variations_parameter().parameter())); 510 } 511 } 512} 513 514} // namespace 515 516void DecodeDevicePolicy(const em::ChromeDeviceSettingsProto& policy, 517 PolicyMap* policies, 518 EnterpriseInstallAttributes* install_attributes) { 519 // Decode the various groups of policies. 520 DecodeLoginPolicies(policy, policies); 521 DecodeKioskPolicies(policy, policies, install_attributes); 522 DecodeNetworkPolicies(policy, policies, install_attributes); 523 DecodeReportingPolicies(policy, policies); 524 DecodeAutoUpdatePolicies(policy, policies); 525 DecodeGenericPolicies(policy, policies); 526} 527 528} // namespace policy 529