summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordavidyu@chromium.org <davidyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-24 11:39:02 +0000
committerdavidyu@chromium.org <davidyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-24 11:39:02 +0000
commitd359450d7c55630a4bb3bed7c8c8ac5d3697c500 (patch)
treeda4589d4d5b9e4e42f3ac736c428bfd21ce561e6
parentc39e625ff5dec4b981d9c52529645d5682085fdc (diff)
downloadchromium_src-d359450d7c55630a4bb3bed7c8c8ac5d3697c500.zip
chromium_src-d359450d7c55630a4bb3bed7c8c8ac5d3697c500.tar.gz
chromium_src-d359450d7c55630a4bb3bed7c8c8ac5d3697c500.tar.bz2
Check for invalid management mode transition.
BUG=353050 TEST=unit_tests Review URL: https://codereview.chromium.org/240653004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@265910 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/chromeos/settings/device_settings_service.cc74
-rw-r--r--chrome/browser/chromeos/settings/device_settings_service.h13
-rw-r--r--chrome/browser/chromeos/settings/device_settings_service_unittest.cc114
-rw-r--r--chrome/browser/chromeos/settings/session_manager_operation.cc5
4 files changed, 194 insertions, 12 deletions
diff --git a/chrome/browser/chromeos/settings/device_settings_service.cc b/chrome/browser/chromeos/settings/device_settings_service.cc
index 20d8256..0895080 100644
--- a/chrome/browser/chromeos/settings/device_settings_service.cc
+++ b/chrome/browser/chromeos/settings/device_settings_service.cc
@@ -129,6 +129,11 @@ void DeviceSettingsService::SignAndStore(
scoped_ptr<em::ChromeDeviceSettingsProto> new_settings,
const base::Closure& callback) {
scoped_ptr<em::PolicyData> new_policy = AssemblePolicy(*new_settings);
+ if (!new_policy) {
+ HandleError(STORE_POLICY_ERROR, callback);
+ return;
+ }
+
Enqueue(
new SignAndStoreSettingsOperation(
base::Bind(&DeviceSettingsService::HandleCompletedOperation,
@@ -142,13 +147,23 @@ void DeviceSettingsService::SetManagementSettings(
const std::string& request_token,
const std::string& device_id,
const base::Closure& callback) {
- // TODO(davidyu): Check for invalid management mode transition.
+ if (!CheckManagementModeTransition(management_mode)) {
+ LOG(ERROR) << "Invalid management mode transition: current mode = "
+ << GetManagementMode() << ", new mode = " << management_mode;
+ HandleError(STORE_POLICY_ERROR, callback);
+ return;
+ }
+
scoped_ptr<em::PolicyData> policy = AssemblePolicy(*device_settings_);
- if (policy) {
- policy->set_management_mode(management_mode);
- policy->set_request_token(request_token);
- policy->set_device_id(device_id);
+ if (!policy) {
+ HandleError(STORE_POLICY_ERROR, callback);
+ return;
}
+
+ policy->set_management_mode(management_mode);
+ policy->set_request_token(request_token);
+ policy->set_device_id(device_id);
+
Enqueue(
new SignAndStoreSettingsOperation(
base::Bind(&DeviceSettingsService::HandleCompletedOperation,
@@ -382,8 +397,22 @@ void DeviceSettingsService::HandleCompletedOperation(
StartNextOperation();
}
+void DeviceSettingsService::HandleError(Status status,
+ const base::Closure& callback) {
+ store_status_ = status;
+
+ LOG(ERROR) << "Session manager operation failed: " << status;
+
+ FOR_EACH_OBSERVER(Observer, observers_, DeviceSettingsUpdated());
+
+ // The completion callback happens after the notification so clients can
+ // filter self-triggered updates.
+ if (!callback.is_null())
+ callback.Run();
+}
+
scoped_ptr<em::PolicyData> DeviceSettingsService::AssemblePolicy(
- const em::ChromeDeviceSettingsProto& settings) {
+ const em::ChromeDeviceSettingsProto& settings) const {
scoped_ptr<em::PolicyData> policy(new em::PolicyData());
if (policy_data_) {
// Preserve management settings.
@@ -408,6 +437,39 @@ scoped_ptr<em::PolicyData> DeviceSettingsService::AssemblePolicy(
return policy.Pass();
}
+em::PolicyData::ManagementMode DeviceSettingsService::GetManagementMode()
+ const {
+ if (policy_data_ && policy_data_->has_management_mode())
+ return policy_data_->management_mode();
+ return em::PolicyData::NOT_MANAGED;
+}
+
+bool DeviceSettingsService::CheckManagementModeTransition(
+ em::PolicyData::ManagementMode new_mode) const {
+ em::PolicyData::ManagementMode current_mode = GetManagementMode();
+
+ // Mode is not changed.
+ if (current_mode == new_mode)
+ return true;
+
+ switch (current_mode) {
+ case em::PolicyData::NOT_MANAGED:
+ // For consumer management enrollment.
+ return new_mode == em::PolicyData::CONSUMER_MANAGED;
+
+ case em::PolicyData::ENTERPRISE_MANAGED:
+ // Management mode cannot be set when it is currently ENTERPRISE_MANAGED.
+ return false;
+
+ case em::PolicyData::CONSUMER_MANAGED:
+ // For consumer management unenrollment.
+ return new_mode == em::PolicyData::NOT_MANAGED;
+ }
+
+ NOTREACHED();
+ return false;
+}
+
ScopedTestDeviceSettingsService::ScopedTestDeviceSettingsService() {
DeviceSettingsService::Initialize();
}
diff --git a/chrome/browser/chromeos/settings/device_settings_service.h b/chrome/browser/chromeos/settings/device_settings_service.h
index 9facc45..5b05513 100644
--- a/chrome/browser/chromeos/settings/device_settings_service.h
+++ b/chrome/browser/chromeos/settings/device_settings_service.h
@@ -235,10 +235,21 @@ class DeviceSettingsService : public SessionManagerClient::Observer,
SessionManagerOperation* operation,
Status status);
+ // Updates status and invokes the callback immediately.
+ void HandleError(Status status, const base::Closure& callback);
+
// Assembles PolicyData based on |settings| and the current |policy_data_|
// and |username_|.
scoped_ptr<enterprise_management::PolicyData> AssemblePolicy(
- const enterprise_management::ChromeDeviceSettingsProto& settings);
+ const enterprise_management::ChromeDeviceSettingsProto& settings) const;
+
+ // Returns the current management mode.
+ enterprise_management::PolicyData::ManagementMode GetManagementMode() const;
+
+ // Returns true if it is okay to transfer from the current mode to the new
+ // mode. This function should be called in SetManagementMode().
+ bool CheckManagementModeTransition(
+ enterprise_management::PolicyData::ManagementMode new_mode) const;
SessionManagerClient* session_manager_client_;
scoped_refptr<OwnerKeyUtil> owner_key_util_;
diff --git a/chrome/browser/chromeos/settings/device_settings_service_unittest.cc b/chrome/browser/chromeos/settings/device_settings_service_unittest.cc
index 0f0037b..727a34f 100644
--- a/chrome/browser/chromeos/settings/device_settings_service_unittest.cc
+++ b/chrome/browser/chromeos/settings/device_settings_service_unittest.cc
@@ -223,6 +223,120 @@ TEST_F(DeviceSettingsServiceTest, SignAndStoreSuccess) {
policy_data->username());
}
+TEST_F(DeviceSettingsServiceTest, SetManagementSettingsModeTransition) {
+ ReloadDeviceSettings();
+ EXPECT_EQ(DeviceSettingsService::STORE_SUCCESS,
+ device_settings_service_.status());
+
+ owner_key_util_->SetPrivateKey(device_policy_.GetSigningKey());
+ device_settings_service_.SetUsername(device_policy_.policy_data().username());
+ FlushDeviceSettings();
+
+ // The initial management mode should be NOT_MANAGED.
+ EXPECT_EQ(em::PolicyData::NOT_MANAGED,
+ device_settings_service_.policy_data()->management_mode());
+
+ // NOT_MANAGED -> CONSUMER_MANAGED: Okay.
+ device_settings_service_.SetManagementSettings(
+ em::PolicyData::CONSUMER_MANAGED,
+ "fake_request_token",
+ "fake_device_id",
+ base::Bind(&DeviceSettingsServiceTest::SetOperationCompleted,
+ base::Unretained(this)));
+ FlushDeviceSettings();
+
+ EXPECT_TRUE(operation_completed_);
+ EXPECT_EQ(DeviceSettingsService::STORE_SUCCESS,
+ device_settings_service_.status());
+ EXPECT_EQ(em::PolicyData::CONSUMER_MANAGED,
+ device_settings_service_.policy_data()->management_mode());
+
+ // CONSUMER_MANAGED -> ENTERPRISE_MANAGED: Invalid.
+ device_settings_service_.SetManagementSettings(
+ em::PolicyData::ENTERPRISE_MANAGED,
+ "fake_request_token",
+ "fake_device_id",
+ base::Bind(&DeviceSettingsServiceTest::SetOperationCompleted,
+ base::Unretained(this)));
+ FlushDeviceSettings();
+
+ EXPECT_TRUE(operation_completed_);
+ EXPECT_EQ(DeviceSettingsService::STORE_POLICY_ERROR,
+ device_settings_service_.status());
+ EXPECT_EQ(em::PolicyData::CONSUMER_MANAGED,
+ device_settings_service_.policy_data()->management_mode());
+
+ // CONSUMER_MANAGED -> NOT_MANAGED: Okay.
+ device_settings_service_.SetManagementSettings(
+ em::PolicyData::NOT_MANAGED,
+ "fake_request_token",
+ "fake_device_id",
+ base::Bind(&DeviceSettingsServiceTest::SetOperationCompleted,
+ base::Unretained(this)));
+ FlushDeviceSettings();
+
+ EXPECT_TRUE(operation_completed_);
+ EXPECT_EQ(DeviceSettingsService::STORE_SUCCESS,
+ device_settings_service_.status());
+ EXPECT_EQ(em::PolicyData::NOT_MANAGED,
+ device_settings_service_.policy_data()->management_mode());
+
+ // NOT_MANAGED -> ENTERPRISE_MANAGED: Invalid.
+ device_settings_service_.SetManagementSettings(
+ em::PolicyData::ENTERPRISE_MANAGED,
+ "fake_request_token",
+ "fake_device_id",
+ base::Bind(&DeviceSettingsServiceTest::SetOperationCompleted,
+ base::Unretained(this)));
+ FlushDeviceSettings();
+
+ EXPECT_TRUE(operation_completed_);
+ EXPECT_EQ(DeviceSettingsService::STORE_POLICY_ERROR,
+ device_settings_service_.status());
+ EXPECT_EQ(em::PolicyData::NOT_MANAGED,
+ device_settings_service_.policy_data()->management_mode());
+
+ // Inject a policy data with management mode set to ENTERPRISE_MANAGED.
+ device_policy_.policy_data().set_management_mode(
+ em::PolicyData::ENTERPRISE_MANAGED);
+ device_policy_.Build();
+ device_settings_test_helper_.set_policy_blob(device_policy_.GetBlob());
+ ReloadDeviceSettings();
+ EXPECT_EQ(em::PolicyData::ENTERPRISE_MANAGED,
+ device_settings_service_.policy_data()->management_mode());
+
+ // ENTERPRISE_MANAGED -> NOT_MANAGED: Invalid.
+ device_settings_service_.SetManagementSettings(
+ em::PolicyData::NOT_MANAGED,
+ "fake_request_token",
+ "fake_device_id",
+ base::Bind(&DeviceSettingsServiceTest::SetOperationCompleted,
+ base::Unretained(this)));
+ FlushDeviceSettings();
+
+ EXPECT_TRUE(operation_completed_);
+ EXPECT_EQ(DeviceSettingsService::STORE_POLICY_ERROR,
+ device_settings_service_.status());
+ EXPECT_EQ(em::PolicyData::ENTERPRISE_MANAGED,
+ device_settings_service_.policy_data()->management_mode());
+
+ // ENTERPRISE_MANAGED -> CONSUMER_MANAGED: Invalid.
+ device_settings_service_.SetManagementSettings(
+ em::PolicyData::CONSUMER_MANAGED,
+ "fake_request_token",
+ "fake_device_id",
+ base::Bind(&DeviceSettingsServiceTest::SetOperationCompleted,
+ base::Unretained(this)));
+ FlushDeviceSettings();
+
+ EXPECT_TRUE(operation_completed_);
+ EXPECT_EQ(DeviceSettingsService::STORE_POLICY_ERROR,
+ device_settings_service_.status());
+ EXPECT_EQ(em::PolicyData::ENTERPRISE_MANAGED,
+ device_settings_service_.policy_data()->management_mode());
+
+}
+
TEST_F(DeviceSettingsServiceTest, SetManagementSettingsSuccess) {
ReloadDeviceSettings();
EXPECT_EQ(DeviceSettingsService::STORE_SUCCESS,
diff --git a/chrome/browser/chromeos/settings/session_manager_operation.cc b/chrome/browser/chromeos/settings/session_manager_operation.cc
index 9cab08e..b95d283 100644
--- a/chrome/browser/chromeos/settings/session_manager_operation.cc
+++ b/chrome/browser/chromeos/settings/session_manager_operation.cc
@@ -257,11 +257,6 @@ SignAndStoreSettingsOperation::SignAndStoreSettingsOperation(
SignAndStoreSettingsOperation::~SignAndStoreSettingsOperation() {}
void SignAndStoreSettingsOperation::Run() {
- if (!new_policy_) {
- ReportResult(DeviceSettingsService::STORE_POLICY_ERROR);
- return;
- }
-
EnsureOwnerKey(base::Bind(&SignAndStoreSettingsOperation::StartSigning,
weak_factory_.GetWeakPtr()));
}