| // 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 "chromeos/tpm/install_attributes.h" |
| |
| #include <stddef.h> |
| |
| #include <utility> |
| |
| #include "base/bind.h" |
| #include "base/callback_helpers.h" |
| #include "base/files/file_util.h" |
| #include "base/location.h" |
| #include "base/logging.h" |
| #include "base/metrics/histogram_base.h" |
| #include "base/metrics/histogram_macros.h" |
| #include "base/path_service.h" |
| #include "base/single_thread_task_runner.h" |
| #include "base/stl_util.h" |
| #include "base/system/sys_info.h" |
| #include "base/threading/thread_task_runner_handle.h" |
| #include "base/time/time.h" |
| #include "chromeos/dbus/constants/dbus_paths.h" |
| #include "chromeos/dbus/cryptohome/rpc.pb.h" |
| #include "chromeos/dbus/tpm_manager/tpm_manager.pb.h" |
| #include "chromeos/dbus/tpm_manager/tpm_manager_client.h" |
| #include "chromeos/dbus/userdataauth/install_attributes_util.h" |
| #include "components/policy/proto/install_attributes.pb.h" |
| #include "google_apis/gaia/gaia_auth_util.h" |
| #include "third_party/cros_system_api/dbus/service_constants.h" |
| |
| namespace chromeos { |
| |
| namespace { |
| |
| InstallAttributes* g_install_attributes = nullptr; |
| |
| // Calling SetForTesting sets this flag. This flag means that the production |
| // code which calls Initialize and Shutdown will have no effect - the test |
| // install attributes will remain in place until ShutdownForTesting is called. |
| bool g_using_install_attributes_for_testing = false; |
| |
| // Number of TPM lock state query retries during consistency check. |
| const int kDbusRetryCount = 12; |
| |
| // Interval of TPM lock state query retries during consistency check. |
| constexpr base::TimeDelta kDbusRetryInterval = base::TimeDelta::FromSeconds(5); |
| |
| std::string ReadMapKey(const std::map<std::string, std::string>& map, |
| const std::string& key) { |
| std::map<std::string, std::string>::const_iterator entry = map.find(key); |
| if (entry != map.end()) { |
| return entry->second; |
| } |
| return std::string(); |
| } |
| |
| void WarnIfNonempty(const std::map<std::string, std::string>& map, |
| const std::string& key) { |
| if (!ReadMapKey(map, key).empty()) { |
| LOG(WARNING) << key << " expected to be empty."; |
| } |
| } |
| |
| } // namespace |
| |
| // static |
| void InstallAttributes::Initialize() { |
| // Don't reinitialize if a specific instance has already been set for test. |
| if (g_using_install_attributes_for_testing) |
| return; |
| |
| DCHECK(!g_install_attributes); |
| g_install_attributes = new InstallAttributes(InstallAttributesClient::Get()); |
| g_install_attributes->Init( |
| base::PathService::CheckedGet(dbus_paths::FILE_INSTALL_ATTRIBUTES)); |
| } |
| |
| // static |
| bool InstallAttributes::IsInitialized() { |
| return g_install_attributes; |
| } |
| |
| // static |
| void InstallAttributes::Shutdown() { |
| if (g_using_install_attributes_for_testing) |
| return; |
| |
| DCHECK(g_install_attributes); |
| delete g_install_attributes; |
| g_install_attributes = nullptr; |
| } |
| |
| // static |
| InstallAttributes* InstallAttributes::Get() { |
| DCHECK(g_install_attributes); |
| return g_install_attributes; |
| } |
| |
| // static |
| void InstallAttributes::SetForTesting(InstallAttributes* test_instance) { |
| DCHECK(!g_install_attributes); |
| DCHECK(!g_using_install_attributes_for_testing); |
| g_install_attributes = test_instance; |
| g_using_install_attributes_for_testing = true; |
| } |
| |
| // static |
| void InstallAttributes::ShutdownForTesting() { |
| DCHECK(g_using_install_attributes_for_testing); |
| // Don't delete the test instance, we are not the owner. |
| g_install_attributes = nullptr; |
| g_using_install_attributes_for_testing = false; |
| } |
| |
| InstallAttributes::InstallAttributes( |
| InstallAttributesClient* userdataauth_client) |
| : install_attributes_client_(userdataauth_client) {} |
| |
| InstallAttributes::~InstallAttributes() {} |
| |
| void InstallAttributes::Init(const base::FilePath& cache_file) { |
| DCHECK(!device_locked_); |
| |
| // Mark the consistency check as running to ensure that LockDevice() is |
| // blocked, but wait for the cryptohome service to be available before |
| // actually calling TriggerConsistencyCheck(). |
| consistency_check_running_ = true; |
| install_attributes_client_->WaitForServiceToBeAvailable( |
| base::BindOnce(&InstallAttributes::OnCryptohomeServiceInitiallyAvailable, |
| weak_ptr_factory_.GetWeakPtr())); |
| |
| if (!base::PathExists(cache_file)) { |
| LOG_IF(WARNING, base::SysInfo::IsRunningOnChromeOS()) |
| << "Install attributes missing, first sign in"; |
| return; |
| } |
| |
| device_locked_ = true; |
| |
| char buf[16384]; |
| int len = base::ReadFile(cache_file, buf, sizeof(buf)); |
| if (len == -1 || len >= static_cast<int>(sizeof(buf))) { |
| PLOG(ERROR) << "Failed to read " << cache_file.value(); |
| return; |
| } |
| |
| cryptohome::SerializedInstallAttributes install_attrs_proto; |
| if (!install_attrs_proto.ParseFromArray(buf, len)) { |
| LOG(ERROR) << "Failed to parse install attributes cache."; |
| return; |
| } |
| |
| google::protobuf::RepeatedPtrField< |
| const cryptohome::SerializedInstallAttributes::Attribute>::iterator entry; |
| std::map<std::string, std::string> attr_map; |
| for (entry = install_attrs_proto.attributes().begin(); |
| entry != install_attrs_proto.attributes().end(); ++entry) { |
| // The protobuf values contain terminating null characters, so we have to |
| // sanitize the value here. |
| attr_map.insert( |
| std::make_pair(entry->name(), std::string(entry->value().c_str()))); |
| } |
| |
| DecodeInstallAttributes(attr_map); |
| } |
| |
| void InstallAttributes::ReadImmutableAttributes(base::OnceClosure callback) { |
| if (device_locked_) { |
| std::move(callback).Run(); |
| return; |
| } |
| |
| // Get Install Attributes Status to know if it's ready. |
| install_attributes_client_->InstallAttributesGetStatus( |
| user_data_auth::InstallAttributesGetStatusRequest(), |
| base::BindOnce(&InstallAttributes::ReadAttributesIfReady, |
| weak_ptr_factory_.GetWeakPtr(), std::move(callback))); |
| } |
| |
| void InstallAttributes::ReadAttributesIfReady( |
| base::OnceClosure callback, |
| base::Optional<user_data_auth::InstallAttributesGetStatusReply> reply) { |
| base::ScopedClosureRunner callback_runner(std::move(callback)); |
| |
| // Can't proceed if the call failed. |
| if (!reply.has_value()) { |
| return; |
| } |
| |
| // Can't proceed if not ready. |
| if (reply->state() == ::user_data_auth::InstallAttributesState::UNKNOWN || |
| reply->state() == |
| ::user_data_auth::InstallAttributesState::TPM_NOT_OWNED) { |
| return; |
| } |
| |
| registration_mode_ = policy::DEVICE_MODE_NOT_SET; |
| // TODO(b/183608597): Migrate this to check reply->state() to avoid the |
| // blocking calls below. |
| if (!install_attributes_util::InstallAttributesIsInvalid() && |
| !install_attributes_util::InstallAttributesIsFirstInstall()) { |
| device_locked_ = true; |
| |
| static const char* const kEnterpriseAttributes[] = { |
| kAttrEnterpriseDeviceId, kAttrEnterpriseDomain, kAttrEnterpriseRealm, |
| kAttrEnterpriseMode, kAttrEnterpriseOwned, kAttrEnterpriseUser, |
| kAttrConsumerKioskEnabled, |
| }; |
| std::map<std::string, std::string> attr_map; |
| for (size_t i = 0; i < base::size(kEnterpriseAttributes); ++i) { |
| std::string value; |
| if (install_attributes_util::InstallAttributesGet( |
| kEnterpriseAttributes[i], &value)) |
| attr_map[kEnterpriseAttributes[i]] = value; |
| } |
| |
| DecodeInstallAttributes(attr_map); |
| } |
| } |
| |
| void InstallAttributes::SetBlockDevmodeInTpm( |
| bool block_devmode, |
| DBusMethodCallback<user_data_auth::SetFirmwareManagementParametersReply> |
| callback) { |
| DCHECK(!callback.is_null()); |
| DCHECK(!device_locked_); |
| |
| user_data_auth::SetFirmwareManagementParametersRequest request; |
| // Set the flags, according to enum FirmwareManagementParametersFlags from |
| // rpc.proto if devmode is blocked. |
| if (block_devmode) { |
| request.mutable_fwmp()->set_flags( |
| cryptohome::DEVELOPER_DISABLE_BOOT | |
| cryptohome::DEVELOPER_DISABLE_CASE_CLOSED_DEBUGGING_UNLOCK); |
| } |
| |
| install_attributes_client_->SetFirmwareManagementParameters( |
| request, std::move(callback)); |
| } |
| |
| void InstallAttributes::LockDevice(policy::DeviceMode device_mode, |
| const std::string& domain, |
| const std::string& realm, |
| const std::string& device_id, |
| LockResultCallback callback) { |
| CHECK((device_mode == policy::DEVICE_MODE_ENTERPRISE && !domain.empty() && |
| realm.empty() && !device_id.empty()) || |
| (device_mode == policy::DEVICE_MODE_ENTERPRISE_AD && domain.empty() && |
| !realm.empty() && !device_id.empty()) || |
| (device_mode == policy::DEVICE_MODE_DEMO && !domain.empty() && |
| realm.empty() && !device_id.empty()) || |
| (device_mode == policy::DEVICE_MODE_CONSUMER_KIOSK_AUTOLAUNCH && |
| domain.empty() && realm.empty() && device_id.empty())); |
| DCHECK(callback); |
| CHECK_EQ(device_lock_running_, false); |
| |
| // Check for existing lock first. |
| if (device_locked_) { |
| if (device_mode != registration_mode_) { |
| LOG(ERROR) << "Trying to re-lock with wrong mode: device_mode: " |
| << device_mode |
| << ", registration_mode: " << registration_mode_; |
| std::move(callback).Run(LOCK_WRONG_MODE); |
| return; |
| } |
| |
| if (domain != registration_domain_ || realm != registration_realm_ || |
| device_id != registration_device_id_) { |
| LOG(ERROR) << "Trying to re-lock with non-matching parameters."; |
| std::move(callback).Run(LOCK_WRONG_DOMAIN); |
| return; |
| } |
| |
| // Already locked in the right mode, signal success. |
| std::move(callback).Run(LOCK_SUCCESS); |
| return; |
| } |
| |
| // In case the consistency check is still running, postpone the device locking |
| // until it has finished. This should not introduce additional delay since |
| // device locking must wait for TPM initialization anyways. |
| if (consistency_check_running_) { |
| CHECK(post_check_action_.is_null()); |
| post_check_action_ = base::BindOnce( |
| &InstallAttributes::LockDevice, weak_ptr_factory_.GetWeakPtr(), |
| device_mode, domain, realm, device_id, std::move(callback)); |
| return; |
| } |
| |
| device_lock_running_ = true; |
| // Get Install Attributes Status to know if it's ready. |
| install_attributes_client_->InstallAttributesGetStatus( |
| user_data_auth::InstallAttributesGetStatusRequest(), |
| base::BindOnce(&InstallAttributes::LockDeviceIfAttributesIsReady, |
| weak_ptr_factory_.GetWeakPtr(), device_mode, domain, realm, |
| device_id, std::move(callback))); |
| } |
| |
| void InstallAttributes::LockDeviceIfAttributesIsReady( |
| policy::DeviceMode device_mode, |
| const std::string& domain, |
| const std::string& realm, |
| const std::string& device_id, |
| LockResultCallback callback, |
| base::Optional<user_data_auth::InstallAttributesGetStatusReply> reply) { |
| if (!reply.has_value() || |
| reply->state() == ::user_data_auth::InstallAttributesState::UNKNOWN || |
| reply->state() == |
| ::user_data_auth::InstallAttributesState::TPM_NOT_OWNED) { |
| device_lock_running_ = false; |
| std::move(callback).Run(LOCK_NOT_READY); |
| return; |
| } |
| |
| // Clearing the TPM password seems to be always a good deal. At this point |
| // install attributes is ready, which implies TPM readiness as well. |
| TpmManagerClient::Get()->ClearStoredOwnerPassword( |
| ::tpm_manager::ClearStoredOwnerPasswordRequest(), |
| base::BindOnce(&InstallAttributes::OnClearStoredOwnerPassword, |
| weak_ptr_factory_.GetWeakPtr())); |
| |
| // Make sure we really have a working InstallAttrs. |
| if (install_attributes_util::InstallAttributesIsInvalid()) { |
| LOG(ERROR) << "Install attributes invalid."; |
| device_lock_running_ = false; |
| std::move(callback).Run(LOCK_BACKEND_INVALID); |
| return; |
| } |
| |
| if (!install_attributes_util::InstallAttributesIsFirstInstall()) { |
| LOG(ERROR) << "Install attributes already installed."; |
| device_lock_running_ = false; |
| std::move(callback).Run(LOCK_ALREADY_LOCKED); |
| return; |
| } |
| |
| // Set values in the InstallAttrs. |
| std::string kiosk_enabled, enterprise_owned; |
| if (device_mode == policy::DEVICE_MODE_CONSUMER_KIOSK_AUTOLAUNCH) { |
| kiosk_enabled = "true"; |
| } else { |
| enterprise_owned = "true"; |
| } |
| std::string mode = GetDeviceModeString(device_mode); |
| if (!install_attributes_util::InstallAttributesSet(kAttrConsumerKioskEnabled, |
| kiosk_enabled) || |
| !install_attributes_util::InstallAttributesSet(kAttrEnterpriseOwned, |
| enterprise_owned) || |
| !install_attributes_util::InstallAttributesSet(kAttrEnterpriseMode, |
| mode) || |
| !install_attributes_util::InstallAttributesSet(kAttrEnterpriseDomain, |
| domain) || |
| !install_attributes_util::InstallAttributesSet(kAttrEnterpriseRealm, |
| realm) || |
| !install_attributes_util::InstallAttributesSet(kAttrEnterpriseDeviceId, |
| device_id)) { |
| LOG(ERROR) << "Failed writing attributes."; |
| device_lock_running_ = false; |
| std::move(callback).Run(LOCK_SET_ERROR); |
| return; |
| } |
| |
| if (!install_attributes_util::InstallAttributesFinalize() || |
| install_attributes_util::InstallAttributesIsFirstInstall()) { |
| LOG(ERROR) << "Failed locking."; |
| device_lock_running_ = false; |
| std::move(callback).Run(LOCK_FINALIZE_ERROR); |
| return; |
| } |
| |
| ReadImmutableAttributes( |
| base::BindOnce(&InstallAttributes::OnReadImmutableAttributes, |
| weak_ptr_factory_.GetWeakPtr(), device_mode, domain, realm, |
| device_id, std::move(callback))); |
| } |
| |
| void InstallAttributes::OnReadImmutableAttributes(policy::DeviceMode mode, |
| const std::string& domain, |
| const std::string& realm, |
| const std::string& device_id, |
| LockResultCallback callback) { |
| device_lock_running_ = false; |
| |
| if (registration_mode_ != mode || registration_domain_ != domain || |
| registration_realm_ != realm || registration_device_id_ != device_id) { |
| LOG(ERROR) << "Locked data doesn't match."; |
| std::move(callback).Run(LOCK_READBACK_ERROR); |
| return; |
| } |
| |
| std::move(callback).Run(LOCK_SUCCESS); |
| } |
| |
| bool InstallAttributes::IsEnterpriseManaged() const { |
| if (!device_locked_) { |
| return false; |
| } |
| return registration_mode_ == policy::DEVICE_MODE_ENTERPRISE || |
| registration_mode_ == policy::DEVICE_MODE_ENTERPRISE_AD || |
| registration_mode_ == policy::DEVICE_MODE_DEMO; |
| } |
| |
| bool InstallAttributes::IsActiveDirectoryManaged() const { |
| if (!device_locked_) { |
| return false; |
| } |
| return registration_mode_ == policy::DEVICE_MODE_ENTERPRISE_AD; |
| } |
| |
| bool InstallAttributes::IsCloudManaged() const { |
| if (!device_locked_) { |
| return false; |
| } |
| return registration_mode_ == policy::DEVICE_MODE_ENTERPRISE || |
| registration_mode_ == policy::DEVICE_MODE_DEMO; |
| } |
| |
| bool InstallAttributes::IsConsumerKioskDeviceWithAutoLaunch() { |
| return device_locked_ && |
| registration_mode_ == policy::DEVICE_MODE_CONSUMER_KIOSK_AUTOLAUNCH; |
| } |
| |
| void InstallAttributes::TriggerConsistencyCheck(int dbus_retries) { |
| TpmManagerClient::Get()->GetTpmNonsensitiveStatus( |
| ::tpm_manager::GetTpmNonsensitiveStatusRequest(), |
| base::BindOnce(&InstallAttributes::OnTpmStatusComplete, |
| weak_ptr_factory_.GetWeakPtr(), dbus_retries)); |
| } |
| |
| void InstallAttributes::OnTpmStatusComplete( |
| int dbus_retries_remaining, |
| const ::tpm_manager::GetTpmNonsensitiveStatusReply& reply) { |
| if (reply.status() != ::tpm_manager::STATUS_SUCCESS && |
| dbus_retries_remaining) { |
| LOG(WARNING) << "Failed to get tpm status reply; status: " |
| << reply.status(); |
| base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| FROM_HERE, |
| base::BindOnce(&InstallAttributes::TriggerConsistencyCheck, |
| weak_ptr_factory_.GetWeakPtr(), |
| dbus_retries_remaining - 1), |
| kDbusRetryInterval); |
| return; |
| } |
| |
| base::HistogramBase::Sample state; |
| // If we get the TPM status successfully, we are interested if install |
| // attributes file exists (device_locked_), if the device is enrolled |
| // (registration_mode_) and if the TPM is locked, meaning the TPM password |
| // is deleted so the value from result is empty. |
| if (reply.status() == ::tpm_manager::STATUS_SUCCESS) { |
| const bool is_cloud_managed = |
| registration_mode_ == policy::DEVICE_MODE_ENTERPRISE || |
| registration_mode_ == policy::DEVICE_MODE_DEMO; |
| state = (device_locked_ ? 1 : 0) | (is_cloud_managed ? 2 : 0) | |
| (!reply.is_owner_password_present() ? 4 : 0); |
| } else { |
| LOG(WARNING) << "Failed to get TPM status after retries; status: " |
| << reply.status(); |
| state = 8; |
| } |
| UMA_HISTOGRAM_ENUMERATION("Enterprise.AttributesTPMConsistency", state, 9); |
| |
| // Run any action (LockDevice call) that might have queued behind the |
| // consistency check. |
| consistency_check_running_ = false; |
| if (post_check_action_) { |
| std::move(post_check_action_).Run(); |
| post_check_action_.Reset(); |
| } |
| } |
| |
| void InstallAttributes::OnClearStoredOwnerPassword( |
| const ::tpm_manager::ClearStoredOwnerPasswordReply& reply) { |
| LOG_IF(WARNING, reply.status() != ::tpm_manager::STATUS_SUCCESS) |
| << "Failed to call ClearStoredOwnerPassword; status: " << reply.status(); |
| } |
| |
| // Warning: The values for these keys (but not the keys themselves) are stored |
| // in the protobuf with a trailing zero. Also note that some of these constants |
| // have been copied to login_manager/device_policy_service.cc. Please make sure |
| // that all changes to the constants are reflected there as well. |
| const char InstallAttributes::kConsumerDeviceMode[] = "consumer"; |
| const char InstallAttributes::kEnterpriseDeviceMode[] = "enterprise"; |
| const char InstallAttributes::kEnterpriseADDeviceMode[] = "enterprise_ad"; |
| const char InstallAttributes::kLegacyRetailDeviceMode[] = "kiosk"; |
| const char InstallAttributes::kConsumerKioskDeviceMode[] = "consumer_kiosk"; |
| const char InstallAttributes::kDemoDeviceMode[] = "demo_mode"; |
| |
| const char InstallAttributes::kAttrEnterpriseDeviceId[] = |
| "enterprise.device_id"; |
| const char InstallAttributes::kAttrEnterpriseDomain[] = "enterprise.domain"; |
| const char InstallAttributes::kAttrEnterpriseRealm[] = "enterprise.realm"; |
| const char InstallAttributes::kAttrEnterpriseMode[] = "enterprise.mode"; |
| const char InstallAttributes::kAttrEnterpriseOwned[] = "enterprise.owned"; |
| const char InstallAttributes::kAttrEnterpriseUser[] = "enterprise.user"; |
| const char InstallAttributes::kAttrConsumerKioskEnabled[] = |
| "consumer.app_kiosk_enabled"; |
| |
| void InstallAttributes::OnCryptohomeServiceInitiallyAvailable( |
| bool service_is_ready) { |
| if (!service_is_ready) |
| LOG(ERROR) << "Failed waiting for cryptohome D-Bus service availability."; |
| |
| // Start the consistency check even if we failed to wait for availability; |
| // hopefully the service will become available eventually. |
| TriggerConsistencyCheck(kDbusRetryCount); |
| } |
| |
| std::string InstallAttributes::GetDeviceModeString(policy::DeviceMode mode) { |
| switch (mode) { |
| case policy::DEVICE_MODE_CONSUMER: |
| return InstallAttributes::kConsumerDeviceMode; |
| case policy::DEVICE_MODE_ENTERPRISE: |
| return InstallAttributes::kEnterpriseDeviceMode; |
| case policy::DEVICE_MODE_ENTERPRISE_AD: |
| return InstallAttributes::kEnterpriseADDeviceMode; |
| case policy::DEPRECATED_DEVICE_MODE_LEGACY_RETAIL_MODE: |
| return InstallAttributes::kLegacyRetailDeviceMode; |
| case policy::DEVICE_MODE_CONSUMER_KIOSK_AUTOLAUNCH: |
| return InstallAttributes::kConsumerKioskDeviceMode; |
| case policy::DEVICE_MODE_DEMO: |
| return InstallAttributes::kDemoDeviceMode; |
| case policy::DEVICE_MODE_PENDING: |
| case policy::DEVICE_MODE_NOT_SET: |
| break; |
| } |
| NOTREACHED() << "Invalid device mode: " << mode; |
| return std::string(); |
| } |
| |
| policy::DeviceMode InstallAttributes::GetDeviceModeFromString( |
| const std::string& mode) { |
| if (mode == InstallAttributes::kConsumerDeviceMode) |
| return policy::DEVICE_MODE_CONSUMER; |
| if (mode == InstallAttributes::kEnterpriseDeviceMode) |
| return policy::DEVICE_MODE_ENTERPRISE; |
| if (mode == InstallAttributes::kEnterpriseADDeviceMode) |
| return policy::DEVICE_MODE_ENTERPRISE_AD; |
| if (mode == InstallAttributes::kLegacyRetailDeviceMode) |
| return policy::DEPRECATED_DEVICE_MODE_LEGACY_RETAIL_MODE; |
| if (mode == InstallAttributes::kConsumerKioskDeviceMode) |
| return policy::DEVICE_MODE_CONSUMER_KIOSK_AUTOLAUNCH; |
| if (mode == InstallAttributes::kDemoDeviceMode) |
| return policy::DEVICE_MODE_DEMO; |
| return policy::DEVICE_MODE_NOT_SET; |
| } |
| |
| void InstallAttributes::DecodeInstallAttributes( |
| const std::map<std::string, std::string>& attr_map) { |
| // Start from a clean slate. |
| registration_mode_ = policy::DEVICE_MODE_NOT_SET; |
| registration_domain_.clear(); |
| registration_realm_.clear(); |
| registration_device_id_.clear(); |
| |
| const std::string enterprise_owned = |
| ReadMapKey(attr_map, kAttrEnterpriseOwned); |
| const std::string consumer_kiosk_enabled = |
| ReadMapKey(attr_map, kAttrConsumerKioskEnabled); |
| const std::string mode = ReadMapKey(attr_map, kAttrEnterpriseMode); |
| const std::string domain = ReadMapKey(attr_map, kAttrEnterpriseDomain); |
| const std::string realm = ReadMapKey(attr_map, kAttrEnterpriseRealm); |
| const std::string device_id = ReadMapKey(attr_map, kAttrEnterpriseDeviceId); |
| const std::string user_deprecated = ReadMapKey(attr_map, kAttrEnterpriseUser); |
| |
| if (enterprise_owned == "true") { |
| WarnIfNonempty(attr_map, kAttrConsumerKioskEnabled); |
| registration_device_id_ = device_id; |
| |
| // Set registration_mode_. |
| registration_mode_ = GetDeviceModeFromString(mode); |
| if (registration_mode_ != policy::DEVICE_MODE_ENTERPRISE && |
| registration_mode_ != policy::DEVICE_MODE_ENTERPRISE_AD && |
| registration_mode_ != policy::DEVICE_MODE_DEMO) { |
| if (!mode.empty()) { |
| LOG(WARNING) << "Bad " << kAttrEnterpriseMode << ": " << mode; |
| } |
| registration_mode_ = policy::DEVICE_MODE_ENTERPRISE; |
| } |
| |
| if (registration_mode_ == policy::DEVICE_MODE_ENTERPRISE || |
| registration_mode_ == policy::DEVICE_MODE_DEMO) { |
| // Either set registration_domain_ ... |
| WarnIfNonempty(attr_map, kAttrEnterpriseRealm); |
| if (!domain.empty()) { |
| // The canonicalization is for compatibility with earlier versions. |
| registration_domain_ = gaia::CanonicalizeDomain(domain); |
| } else if (!user_deprecated.empty()) { |
| // Compatibility for pre M19 code. |
| registration_domain_ = gaia::ExtractDomainName(user_deprecated); |
| } else { |
| LOG(WARNING) << "Couldn't read domain."; |
| } |
| } else { |
| // ... or set registration_realm_. |
| WarnIfNonempty(attr_map, kAttrEnterpriseDomain); |
| if (!realm.empty()) { |
| registration_realm_ = realm; |
| } else { |
| LOG(WARNING) << "Couldn't read realm."; |
| } |
| } |
| |
| return; |
| } |
| |
| WarnIfNonempty(attr_map, kAttrEnterpriseOwned); |
| WarnIfNonempty(attr_map, kAttrEnterpriseDomain); |
| WarnIfNonempty(attr_map, kAttrEnterpriseRealm); |
| WarnIfNonempty(attr_map, kAttrEnterpriseDeviceId); |
| WarnIfNonempty(attr_map, kAttrEnterpriseUser); |
| if (consumer_kiosk_enabled == "true") { |
| registration_mode_ = policy::DEVICE_MODE_CONSUMER_KIOSK_AUTOLAUNCH; |
| return; |
| } |
| |
| WarnIfNonempty(attr_map, kAttrConsumerKioskEnabled); |
| if (user_deprecated.empty()) { |
| registration_mode_ = policy::DEVICE_MODE_CONSUMER; |
| } |
| } |
| |
| } // namespace chromeos |