Commit fe3e74f3 authored by pneubeck's avatar pneubeck Committed by Commit bot

Apply global auto connect ONC policy in GetManagedProperties.

BUG=279351

Review URL: https://codereview.chromium.org/510123004

Cr-Commit-Position: refs/heads/master@{#293091}
parent 4423aeda
...@@ -149,15 +149,9 @@ void ManagedNetworkConfigurationHandlerImpl::SendManagedProperties( ...@@ -149,15 +149,9 @@ void ManagedNetworkConfigurationHandlerImpl::SendManagedProperties(
shill_property_util::GetUIDataFromProperties(*shill_properties); shill_property_util::GetUIDataFromProperties(*shill_properties);
const base::DictionaryValue* user_settings = NULL; const base::DictionaryValue* user_settings = NULL;
const base::DictionaryValue* shared_settings = NULL;
if (ui_data && profile) { if (ui_data && profile) {
if (profile->type() == NetworkProfile::TYPE_SHARED) user_settings = ui_data->user_settings();
shared_settings = ui_data->user_settings();
else if (profile->type() == NetworkProfile::TYPE_USER)
user_settings = ui_data->user_settings();
else
NOTREACHED();
} else if (profile) { } else if (profile) {
NET_LOG_ERROR("Service contains empty or invalid UIData", service_path); NET_LOG_ERROR("Service contains empty or invalid UIData", service_path);
// TODO(pneubeck): add a conversion of user configured entries of old // TODO(pneubeck): add a conversion of user configured entries of old
...@@ -174,34 +168,26 @@ void ManagedNetworkConfigurationHandlerImpl::SendManagedProperties( ...@@ -174,34 +168,26 @@ void ManagedNetworkConfigurationHandlerImpl::SendManagedProperties(
active_settings->GetStringWithoutPathExpansion(::onc::network_config::kGUID, active_settings->GetStringWithoutPathExpansion(::onc::network_config::kGUID,
&guid); &guid);
const base::DictionaryValue* user_policy = NULL; const base::DictionaryValue* network_policy = NULL;
const base::DictionaryValue* device_policy = NULL; const base::DictionaryValue* global_policy = NULL;
if (!guid.empty() && profile) { if (profile) {
const Policies* policies = GetPoliciesForProfile(*profile); const Policies* policies = GetPoliciesForProfile(*profile);
if (!policies) { if (!policies) {
InvokeErrorCallback( InvokeErrorCallback(
service_path, error_callback, kPoliciesNotInitialized); service_path, error_callback, kPoliciesNotInitialized);
return; return;
} }
const base::DictionaryValue* policy = if (!guid.empty())
GetByGUID(policies->per_network_config, guid); network_policy = GetByGUID(policies->per_network_config, guid);
if (profile->type() == NetworkProfile::TYPE_SHARED) global_policy = &policies->global_network_config;
device_policy = policy;
else if (profile->type() == NetworkProfile::TYPE_USER)
user_policy = policy;
else
NOTREACHED();
} }
// This call also removes credentials from policies. scoped_ptr<base::DictionaryValue> augmented_properties(
scoped_ptr<base::DictionaryValue> augmented_properties = policy_util::CreateManagedONC(global_policy,
onc::MergeSettingsAndPoliciesToAugmented( network_policy,
onc::kNetworkConfigurationSignature, user_settings,
user_policy, active_settings.get(),
device_policy, profile));
user_settings,
shared_settings,
active_settings.get());
callback.Run(service_path, *augmented_properties); callback.Run(service_path, *augmented_properties);
} }
...@@ -297,13 +283,17 @@ void ManagedNetworkConfigurationHandlerImpl::SetProperties( ...@@ -297,13 +283,17 @@ void ManagedNetworkConfigurationHandlerImpl::SetProperties(
if (validation_result == onc::Validator::VALID_WITH_WARNINGS) if (validation_result == onc::Validator::VALID_WITH_WARNINGS)
LOG(WARNING) << "Validation of ONC user settings produced warnings."; LOG(WARNING) << "Validation of ONC user settings produced warnings.";
const base::DictionaryValue* policy = const base::DictionaryValue* network_policy =
GetByGUID(policies->per_network_config, guid); GetByGUID(policies->per_network_config, guid);
VLOG(2) << "This configuration is " << (policy ? "" : "not ") << "managed."; VLOG(2) << "This configuration is " << (network_policy ? "" : "not ")
<< "managed.";
scoped_ptr<base::DictionaryValue> shill_dictionary( scoped_ptr<base::DictionaryValue> shill_dictionary(
policy_util::CreateShillConfiguration( policy_util::CreateShillConfiguration(*profile,
*profile, guid, policy, validated_user_settings.get())); guid,
&policies->global_network_config,
network_policy,
validated_user_settings.get()));
network_configuration_handler_->SetProperties( network_configuration_handler_->SetProperties(
service_path, *shill_dictionary, callback, error_callback); service_path, *shill_dictionary, callback, error_callback);
...@@ -341,8 +331,11 @@ void ManagedNetworkConfigurationHandlerImpl::CreateConfiguration( ...@@ -341,8 +331,11 @@ void ManagedNetworkConfigurationHandlerImpl::CreateConfiguration(
// in |properties| as it is not our own and from an untrusted source. // in |properties| as it is not our own and from an untrusted source.
std::string guid = base::GenerateGUID(); std::string guid = base::GenerateGUID();
scoped_ptr<base::DictionaryValue> shill_dictionary( scoped_ptr<base::DictionaryValue> shill_dictionary(
policy_util::CreateShillConfiguration( policy_util::CreateShillConfiguration(*profile,
*profile, guid, NULL /*no policy*/, &properties)); guid,
NULL, // no global policy
NULL, // no network policy
&properties));
network_configuration_handler_->CreateConfiguration( network_configuration_handler_->CreateConfiguration(
*shill_dictionary, callback, error_callback); *shill_dictionary, callback, error_callback);
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/mock_shill_manager_client.h" #include "chromeos/dbus/mock_shill_manager_client.h"
#include "chromeos/dbus/mock_shill_profile_client.h" #include "chromeos/dbus/mock_shill_profile_client.h"
#include "chromeos/dbus/mock_shill_service_client.h"
#include "chromeos/dbus/shill_client_helper.h" #include "chromeos/dbus/shill_client_helper.h"
#include "chromeos/network/managed_network_configuration_handler_impl.h" #include "chromeos/network/managed_network_configuration_handler_impl.h"
#include "chromeos/network/network_configuration_handler.h" #include "chromeos/network/network_configuration_handler.h"
...@@ -130,6 +131,27 @@ class ShillProfileTestClient { ...@@ -130,6 +131,27 @@ class ShillProfileTestClient {
std::map<std::string, std::string> profile_to_user_; std::map<std::string, std::string> profile_to_user_;
}; };
class ShillServiceTestClient {
public:
typedef ShillClientHelper::DictionaryValueCallback DictionaryValueCallback;
void SetFakeProperties(const base::DictionaryValue& service_properties) {
service_properties_.Clear();
service_properties_.MergeDictionary(&service_properties);
}
void GetProperties(const dbus::ObjectPath& service_path,
const DictionaryValueCallback& callback) {
base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(callback,
DBUS_METHOD_CALL_SUCCESS,
base::ConstRef(service_properties_)));
}
protected:
base::DictionaryValue service_properties_;
};
class TestNetworkProfileHandler : public NetworkProfileHandler { class TestNetworkProfileHandler : public NetworkProfileHandler {
public: public:
TestNetworkProfileHandler() { TestNetworkProfileHandler() {
...@@ -151,7 +173,8 @@ class ManagedNetworkConfigurationHandlerTest : public testing::Test { ...@@ -151,7 +173,8 @@ class ManagedNetworkConfigurationHandlerTest : public testing::Test {
public: public:
ManagedNetworkConfigurationHandlerTest() ManagedNetworkConfigurationHandlerTest()
: mock_manager_client_(NULL), : mock_manager_client_(NULL),
mock_profile_client_(NULL) { mock_profile_client_(NULL),
mock_service_client_(NULL) {
} }
virtual ~ManagedNetworkConfigurationHandlerTest() { virtual ~ManagedNetworkConfigurationHandlerTest() {
...@@ -162,10 +185,13 @@ class ManagedNetworkConfigurationHandlerTest : public testing::Test { ...@@ -162,10 +185,13 @@ class ManagedNetworkConfigurationHandlerTest : public testing::Test {
DBusThreadManager::GetSetterForTesting(); DBusThreadManager::GetSetterForTesting();
mock_manager_client_ = new StrictMock<MockShillManagerClient>(); mock_manager_client_ = new StrictMock<MockShillManagerClient>();
mock_profile_client_ = new StrictMock<MockShillProfileClient>(); mock_profile_client_ = new StrictMock<MockShillProfileClient>();
mock_service_client_ = new StrictMock<MockShillServiceClient>();
dbus_setter->SetShillManagerClient( dbus_setter->SetShillManagerClient(
scoped_ptr<ShillManagerClient>(mock_manager_client_).Pass()); scoped_ptr<ShillManagerClient>(mock_manager_client_).Pass());
dbus_setter->SetShillProfileClient( dbus_setter->SetShillProfileClient(
scoped_ptr<ShillProfileClient>(mock_profile_client_).Pass()); scoped_ptr<ShillProfileClient>(mock_profile_client_).Pass());
dbus_setter->SetShillServiceClient(
scoped_ptr<ShillServiceClient>(mock_service_client_).Pass());
SetNetworkConfigurationHandlerExpectations(); SetNetworkConfigurationHandlerExpectations();
...@@ -177,6 +203,10 @@ class ManagedNetworkConfigurationHandlerTest : public testing::Test { ...@@ -177,6 +203,10 @@ class ManagedNetworkConfigurationHandlerTest : public testing::Test {
.WillByDefault(Invoke(&profiles_stub_, .WillByDefault(Invoke(&profiles_stub_,
&ShillProfileTestClient::GetEntry)); &ShillProfileTestClient::GetEntry));
ON_CALL(*mock_service_client_, GetProperties(_,_))
.WillByDefault(Invoke(&services_stub_,
&ShillServiceTestClient::GetProperties));
network_profile_handler_.reset(new TestNetworkProfileHandler()); network_profile_handler_.reset(new TestNetworkProfileHandler());
network_configuration_handler_.reset( network_configuration_handler_.reset(
NetworkConfigurationHandler::InitializeForTest( NetworkConfigurationHandler::InitializeForTest(
...@@ -209,9 +239,12 @@ class ManagedNetworkConfigurationHandlerTest : public testing::Test { ...@@ -209,9 +239,12 @@ class ManagedNetworkConfigurationHandlerTest : public testing::Test {
profiles_stub_.AddProfile(kUser1ProfilePath, kUser1); profiles_stub_.AddProfile(kUser1ProfilePath, kUser1);
network_profile_handler_-> network_profile_handler_->
AddProfileForTest(NetworkProfile(kUser1ProfilePath, kUser1)); AddProfileForTest(NetworkProfile(kUser1ProfilePath, kUser1));
network_profile_handler_->
AddProfileForTest(NetworkProfile( profiles_stub_.AddProfile(NetworkProfileHandler::GetSharedProfilePath(),
NetworkProfileHandler::GetSharedProfilePath(), std::string())); std::string() /* no userhash */);
network_profile_handler_->AddProfileForTest(
NetworkProfile(NetworkProfileHandler::GetSharedProfilePath(),
std::string() /* no userhash */));
} }
void SetUpEntry(const std::string& path_to_shill_json, void SetUpEntry(const std::string& path_to_shill_json,
...@@ -259,16 +292,44 @@ class ManagedNetworkConfigurationHandlerTest : public testing::Test { ...@@ -259,16 +292,44 @@ class ManagedNetworkConfigurationHandlerTest : public testing::Test {
return managed_network_configuration_handler_.get(); return managed_network_configuration_handler_.get();
} }
void GetManagedProperties(const std::string& userhash,
const std::string& service_path) {
managed_handler()->GetManagedProperties(
userhash,
service_path,
base::Bind(
&ManagedNetworkConfigurationHandlerTest::GetPropertiesCallback,
base::Unretained(this)),
base::Bind(&ManagedNetworkConfigurationHandlerTest::UnexpectedError));
}
void GetPropertiesCallback(const std::string& service_path,
const base::DictionaryValue& dictionary) {
get_properties_service_path_ = service_path;
get_properties_result_.Clear();
get_properties_result_.MergeDictionary(&dictionary);
}
static void UnexpectedError(const std::string& error_name,
scoped_ptr<base::DictionaryValue> error_data) {
ASSERT_FALSE(true);
}
protected: protected:
MockShillManagerClient* mock_manager_client_; MockShillManagerClient* mock_manager_client_;
MockShillProfileClient* mock_profile_client_; MockShillProfileClient* mock_profile_client_;
MockShillServiceClient* mock_service_client_;
ShillProfileTestClient profiles_stub_; ShillProfileTestClient profiles_stub_;
ShillServiceTestClient services_stub_;
scoped_ptr<TestNetworkProfileHandler> network_profile_handler_; scoped_ptr<TestNetworkProfileHandler> network_profile_handler_;
scoped_ptr<NetworkConfigurationHandler> network_configuration_handler_; scoped_ptr<NetworkConfigurationHandler> network_configuration_handler_;
scoped_ptr<ManagedNetworkConfigurationHandlerImpl> scoped_ptr<ManagedNetworkConfigurationHandlerImpl>
managed_network_configuration_handler_; managed_network_configuration_handler_;
base::MessageLoop message_loop_; base::MessageLoop message_loop_;
std::string get_properties_service_path_;
base::DictionaryValue get_properties_result_;
private: private:
DISALLOW_COPY_AND_ASSIGN(ManagedNetworkConfigurationHandlerTest); DISALLOW_COPY_AND_ASSIGN(ManagedNetworkConfigurationHandlerTest);
}; };
...@@ -660,10 +721,13 @@ TEST_F(ManagedNetworkConfigurationHandlerTest, SetPolicyIgnoreUnmanaged) { ...@@ -660,10 +721,13 @@ TEST_F(ManagedNetworkConfigurationHandlerTest, SetPolicyIgnoreUnmanaged) {
TEST_F(ManagedNetworkConfigurationHandlerTest, AutoConnectDisallowed) { TEST_F(ManagedNetworkConfigurationHandlerTest, AutoConnectDisallowed) {
InitializeStandardProfiles(); InitializeStandardProfiles();
// Setup an unmanaged network.
SetUpEntry("policy/shill_unmanaged_wifi2.json", SetUpEntry("policy/shill_unmanaged_wifi2.json",
kUser1ProfilePath, kUser1ProfilePath,
"wifi2_entry_path"); "wifi2_entry_path");
// Apply the user policy with global autoconnect config and expect that
// autoconnect is disabled in the network's profile entry.
EXPECT_CALL(*mock_profile_client_, EXPECT_CALL(*mock_profile_client_,
GetProperties(dbus::ObjectPath(kUser1ProfilePath), _, _)); GetProperties(dbus::ObjectPath(kUser1ProfilePath), _, _));
...@@ -685,6 +749,38 @@ TEST_F(ManagedNetworkConfigurationHandlerTest, AutoConnectDisallowed) { ...@@ -685,6 +749,38 @@ TEST_F(ManagedNetworkConfigurationHandlerTest, AutoConnectDisallowed) {
kUser1, kUser1,
"policy/policy_disallow_autoconnect.onc"); "policy/policy_disallow_autoconnect.onc");
message_loop_.RunUntilIdle(); message_loop_.RunUntilIdle();
// Verify that GetManagedProperties correctly augments the properties with the
// global config from the user policy.
// GetManagedProperties requires the device policy to be set or explicitly
// unset.
EXPECT_CALL(*mock_profile_client_,
GetProperties(dbus::ObjectPath(
NetworkProfileHandler::GetSharedProfilePath()),
_,
_));
managed_handler()->SetPolicy(
::onc::ONC_SOURCE_DEVICE_POLICY,
std::string(), // no userhash
base::ListValue(), // no device network policy
base::DictionaryValue()); // no device global config
services_stub_.SetFakeProperties(*expected_shill_properties);
EXPECT_CALL(*mock_service_client_,
GetProperties(dbus::ObjectPath(
"wifi2"),_));
GetManagedProperties(kUser1, "wifi2");
message_loop_.RunUntilIdle();
EXPECT_EQ("wifi2", get_properties_service_path_);
scoped_ptr<base::DictionaryValue> expected_managed_onc =
test_utils::ReadTestDictionary(
"policy/managed_onc_disallow_autoconnect_on_unmanaged_wifi2.onc");
EXPECT_TRUE(onc::test_utils::Equals(expected_managed_onc.get(),
&get_properties_result_));
} }
TEST_F(ManagedNetworkConfigurationHandlerTest, LateProfileLoading) { TEST_F(ManagedNetworkConfigurationHandlerTest, LateProfileLoading) {
......
...@@ -172,8 +172,11 @@ void PolicyApplicator::GetEntryCallback( ...@@ -172,8 +172,11 @@ void PolicyApplicator::GetEntryCallback(
const base::DictionaryValue* user_settings = const base::DictionaryValue* user_settings =
ui_data ? ui_data->user_settings() : NULL; ui_data ? ui_data->user_settings() : NULL;
scoped_ptr<base::DictionaryValue> new_shill_properties = scoped_ptr<base::DictionaryValue> new_shill_properties =
policy_util::CreateShillConfiguration( policy_util::CreateShillConfiguration(profile_,
profile_, new_guid, new_policy, user_settings); new_guid,
&global_network_config_,
new_policy,
user_settings);
// A new policy has to be applied to this profile entry. In order to keep // A new policy has to be applied to this profile entry. In order to keep
// implicit state of Shill like "connected successfully before", keep the // implicit state of Shill like "connected successfully before", keep the
// entry if a policy is reapplied (e.g. after reboot) or is updated. // entry if a policy is reapplied (e.g. after reboot) or is updated.
...@@ -204,7 +207,8 @@ void PolicyApplicator::GetEntryCallback( ...@@ -204,7 +207,8 @@ void PolicyApplicator::GetEntryCallback(
// At first ENTRY1 and ENTRY2 should be removed, then the new config be // At first ENTRY1 and ENTRY2 should be removed, then the new config be
// written and the result should be: // written and the result should be:
// { {GUID=X, SSID=Y, USER_SETTINGS=X} } // { {GUID=X, SSID=Y, USER_SETTINGS=X} }
WriteNewShillConfiguration(*new_shill_properties, *new_policy, true); WriteNewShillConfiguration(
*new_shill_properties, *new_policy, true /* write later */);
remaining_policies_.erase(new_guid); remaining_policies_.erase(new_guid);
} }
} else if (was_managed) { } else if (was_managed) {
...@@ -219,8 +223,8 @@ void PolicyApplicator::GetEntryCallback( ...@@ -219,8 +223,8 @@ void PolicyApplicator::GetEntryCallback(
// The entry wasn't managed and doesn't match any current policy. Global // The entry wasn't managed and doesn't match any current policy. Global
// network settings have to be applied. // network settings have to be applied.
base::DictionaryValue shill_properties_to_update; base::DictionaryValue shill_properties_to_update;
GetPropertiesForUnmanagedEntry(entry_properties, policy_util::SetShillPropertiesForGlobalPolicy(
&shill_properties_to_update); entry_properties, global_network_config_, &shill_properties_to_update);
if (shill_properties_to_update.empty()) { if (shill_properties_to_update.empty()) {
VLOG(2) << "Ignore unmanaged entry."; VLOG(2) << "Ignore unmanaged entry.";
// Calling a SetProperties of Shill with an empty dictionary is a no op. // Calling a SetProperties of Shill with an empty dictionary is a no op.
...@@ -266,37 +270,6 @@ void PolicyApplicator::WriteNewShillConfiguration( ...@@ -266,37 +270,6 @@ void PolicyApplicator::WriteNewShillConfiguration(
handler_->CreateConfigurationFromPolicy(shill_dictionary); handler_->CreateConfigurationFromPolicy(shill_dictionary);
} }
void PolicyApplicator::GetPropertiesForUnmanagedEntry(
const base::DictionaryValue& entry_properties,
base::DictionaryValue* properties_to_update) const {
// kAllowOnlyPolicyNetworksToAutoconnect is currently the only global config.
std::string type;
entry_properties.GetStringWithoutPathExpansion(shill::kTypeProperty, &type);
if (NetworkTypePattern::Ethernet().MatchesType(type))
return; // Autoconnect for Ethernet cannot be configured.
// By default all networks are allowed to autoconnect.
bool only_policy_autoconnect = false;
global_network_config_.GetBooleanWithoutPathExpansion(
::onc::global_network_config::kAllowOnlyPolicyNetworksToAutoconnect,
&only_policy_autoconnect);
if (!only_policy_autoconnect)
return;
bool old_autoconnect = false;
if (entry_properties.GetBooleanWithoutPathExpansion(
shill::kAutoConnectProperty, &old_autoconnect) &&
!old_autoconnect) {
// Autoconnect is already explictly disabled. No need to set it again.
return;
}
// If autconnect is not explicitly set yet, it might automatically be enabled
// by Shill. To prevent that, disable it explicitly.
properties_to_update->SetBooleanWithoutPathExpansion(
shill::kAutoConnectProperty, false);
}
PolicyApplicator::~PolicyApplicator() { PolicyApplicator::~PolicyApplicator() {
ApplyRemainingPolicies(); ApplyRemainingPolicies();
STLDeleteValues(&all_policies_); STLDeleteValues(&all_policies_);
...@@ -331,16 +304,20 @@ void PolicyApplicator::ApplyRemainingPolicies() { ...@@ -331,16 +304,20 @@ void PolicyApplicator::ApplyRemainingPolicies() {
// remaining policies, new configurations have to be created. // remaining policies, new configurations have to be created.
for (std::set<std::string>::iterator it = remaining_policies_.begin(); for (std::set<std::string>::iterator it = remaining_policies_.begin();
it != remaining_policies_.end(); ++it) { it != remaining_policies_.end(); ++it) {
const base::DictionaryValue* policy = GetByGUID(all_policies_, *it); const base::DictionaryValue* network_policy = GetByGUID(all_policies_, *it);
DCHECK(policy); DCHECK(network_policy);
VLOG(1) << "Creating new configuration managed by policy " << *it VLOG(1) << "Creating new configuration managed by policy " << *it
<< " in profile " << profile_.ToDebugString() << "."; << " in profile " << profile_.ToDebugString() << ".";
scoped_ptr<base::DictionaryValue> shill_dictionary = scoped_ptr<base::DictionaryValue> shill_dictionary =
policy_util::CreateShillConfiguration( policy_util::CreateShillConfiguration(profile_,
profile_, *it, policy, NULL /* no user settings */); *it,
WriteNewShillConfiguration(*shill_dictionary, *policy, false); &global_network_config_,
network_policy,
NULL /* no user settings */);
WriteNewShillConfiguration(
*shill_dictionary, *network_policy, false /* write now */);
} }
} }
......
...@@ -80,14 +80,6 @@ class PolicyApplicator : public base::RefCounted<PolicyApplicator> { ...@@ -80,14 +80,6 @@ class PolicyApplicator : public base::RefCounted<PolicyApplicator> {
const base::DictionaryValue& policy, const base::DictionaryValue& policy,
bool write_later); bool write_later);
// Adds properties to |properties_to_update|, which are enforced on an
// unamaged network by the global network config of the policy.
// |entry_properties| are the network's current properties read from its
// profile entry.
void GetPropertiesForUnmanagedEntry(
const base::DictionaryValue& entry_properties,
base::DictionaryValue* properties_to_update) const;
// Called once all Profile entries are processed. Calls // Called once all Profile entries are processed. Calls
// ApplyRemainingPolicies. // ApplyRemainingPolicies.
virtual ~PolicyApplicator(); virtual ~PolicyApplicator();
......
...@@ -125,26 +125,172 @@ bool IsPolicyMatching(const base::DictionaryValue& policy, ...@@ -125,26 +125,172 @@ bool IsPolicyMatching(const base::DictionaryValue& policy,
return false; return false;
} }
base::DictionaryValue* GetOrCreateDictionary(const std::string& key,
base::DictionaryValue* dict) {
base::DictionaryValue* inner_dict = NULL;
if (!dict->GetDictionaryWithoutPathExpansion(key, &inner_dict)) {
inner_dict = new base::DictionaryValue;
dict->SetWithoutPathExpansion(key, inner_dict);
}
return inner_dict;
}
base::DictionaryValue* GetOrCreateNestedDictionary(
const std::string& key1,
const std::string& key2,
base::DictionaryValue* dict) {
base::DictionaryValue* inner_dict = GetOrCreateDictionary(key1, dict);
return GetOrCreateDictionary(key2, inner_dict);
}
void ApplyGlobalAutoconnectPolicy(
NetworkProfile::Type profile_type,
base::DictionaryValue* augmented_onc_network) {
base::DictionaryValue* type_dictionary = NULL;
augmented_onc_network->GetDictionaryWithoutPathExpansion(
::onc::network_config::kType, &type_dictionary);
std::string type;
if (!type_dictionary ||
!type_dictionary->GetStringWithoutPathExpansion(
::onc::kAugmentationActiveSetting, &type) ||
type.empty()) {
LOG(ERROR) << "ONC dictionary with no Type.";
return;
}
// Managed dictionaries don't contain empty dictionaries (see onc_merger.cc),
// so add the Autoconnect dictionary in case Shill didn't report a value.
base::DictionaryValue* auto_connect_dictionary = NULL;
if (type == ::onc::network_type::kWiFi) {
auto_connect_dictionary =
GetOrCreateNestedDictionary(::onc::network_config::kWiFi,
::onc::wifi::kAutoConnect,
augmented_onc_network);
} else if (type == ::onc::network_type::kVPN) {
auto_connect_dictionary =
GetOrCreateNestedDictionary(::onc::network_config::kVPN,
::onc::vpn::kAutoConnect,
augmented_onc_network);
} else {
return; // Network type without auto-connect property.
}
std::string policy_source;
if (profile_type == NetworkProfile::TYPE_USER)
policy_source = ::onc::kAugmentationUserPolicy;
else if(profile_type == NetworkProfile::TYPE_SHARED)
policy_source = ::onc::kAugmentationDevicePolicy;
else
NOTREACHED();
auto_connect_dictionary->SetBooleanWithoutPathExpansion(policy_source, false);
auto_connect_dictionary->SetStringWithoutPathExpansion(
::onc::kAugmentationEffectiveSetting, policy_source);
}
} // namespace } // namespace
scoped_ptr<base::DictionaryValue> CreateManagedONC(
const base::DictionaryValue* global_policy,
const base::DictionaryValue* network_policy,
const base::DictionaryValue* user_settings,
const base::DictionaryValue* active_settings,
const NetworkProfile* profile) {
const base::DictionaryValue* user_policy = NULL;
const base::DictionaryValue* device_policy = NULL;
const base::DictionaryValue* nonshared_user_settings = NULL;
const base::DictionaryValue* shared_user_settings = NULL;
if (profile) {
if (profile->type() == NetworkProfile::TYPE_SHARED) {
device_policy = network_policy;
shared_user_settings = user_settings;
} else if (profile->type() == NetworkProfile::TYPE_USER) {
user_policy = network_policy;
nonshared_user_settings = user_settings;
} else {
NOTREACHED();
}
}
// This call also removes credentials from policies.
scoped_ptr<base::DictionaryValue> augmented_onc_network =
onc::MergeSettingsAndPoliciesToAugmented(
onc::kNetworkConfigurationSignature,
user_policy,
device_policy,
nonshared_user_settings,
shared_user_settings,
active_settings);
// If present, apply the Autoconnect policy only to networks that are not
// managed by policy.
if (!network_policy && global_policy && profile) {
bool allow_only_policy_autoconnect = false;
global_policy->GetBooleanWithoutPathExpansion(
::onc::global_network_config::kAllowOnlyPolicyNetworksToAutoconnect,
&allow_only_policy_autoconnect);
if (allow_only_policy_autoconnect) {
ApplyGlobalAutoconnectPolicy(profile->type(),
augmented_onc_network.get());
}
}
return augmented_onc_network.Pass();
}
void SetShillPropertiesForGlobalPolicy(
const base::DictionaryValue& shill_dictionary,
const base::DictionaryValue& global_network_policy,
base::DictionaryValue* shill_properties_to_update) {
// kAllowOnlyPolicyNetworksToAutoconnect is currently the only global config.
std::string type;
shill_dictionary.GetStringWithoutPathExpansion(shill::kTypeProperty, &type);
if (NetworkTypePattern::Ethernet().MatchesType(type))
return; // Autoconnect for Ethernet cannot be configured.
// By default all networks are allowed to autoconnect.
bool only_policy_autoconnect = false;
global_network_policy.GetBooleanWithoutPathExpansion(
::onc::global_network_config::kAllowOnlyPolicyNetworksToAutoconnect,
&only_policy_autoconnect);
if (!only_policy_autoconnect)
return;
bool old_autoconnect = false;
if (shill_dictionary.GetBooleanWithoutPathExpansion(
shill::kAutoConnectProperty, &old_autoconnect) &&
!old_autoconnect) {
// Autoconnect is already explictly disabled. No need to set it again.
return;
}
// If autconnect is not explicitly set yet, it might automatically be enabled
// by Shill. To prevent that, disable it explicitly.
shill_properties_to_update->SetBooleanWithoutPathExpansion(
shill::kAutoConnectProperty, false);
}
scoped_ptr<base::DictionaryValue> CreateShillConfiguration( scoped_ptr<base::DictionaryValue> CreateShillConfiguration(
const NetworkProfile& profile, const NetworkProfile& profile,
const std::string& guid, const std::string& guid,
const base::DictionaryValue* policy, const base::DictionaryValue* global_policy,
const base::DictionaryValue* network_policy,
const base::DictionaryValue* user_settings) { const base::DictionaryValue* user_settings) {
scoped_ptr<base::DictionaryValue> effective; scoped_ptr<base::DictionaryValue> effective;
::onc::ONCSource onc_source = ::onc::ONC_SOURCE_NONE; ::onc::ONCSource onc_source = ::onc::ONC_SOURCE_NONE;
if (policy) { if (network_policy) {
if (profile.type() == NetworkProfile::TYPE_SHARED) { if (profile.type() == NetworkProfile::TYPE_SHARED) {
effective = onc::MergeSettingsAndPoliciesToEffective( effective = onc::MergeSettingsAndPoliciesToEffective(
NULL, // no user policy NULL, // no user policy
policy, // device policy network_policy, // device policy
NULL, // no user settings NULL, // no user settings
user_settings); // shared settings user_settings); // shared settings
onc_source = ::onc::ONC_SOURCE_DEVICE_POLICY; onc_source = ::onc::ONC_SOURCE_DEVICE_POLICY;
} else if (profile.type() == NetworkProfile::TYPE_USER) { } else if (profile.type() == NetworkProfile::TYPE_USER) {
effective = onc::MergeSettingsAndPoliciesToEffective( effective = onc::MergeSettingsAndPoliciesToEffective(
policy, // user policy network_policy, // user policy
NULL, // no device policy NULL, // no device policy
user_settings, // user settings user_settings, // user settings
NULL); // no shared settings NULL); // no shared settings
...@@ -178,6 +324,12 @@ scoped_ptr<base::DictionaryValue> CreateShillConfiguration( ...@@ -178,6 +324,12 @@ scoped_ptr<base::DictionaryValue> CreateShillConfiguration(
shill_dictionary->SetStringWithoutPathExpansion(shill::kProfileProperty, shill_dictionary->SetStringWithoutPathExpansion(shill::kProfileProperty,
profile.path); profile.path);
if (!network_policy && global_policy) {
// The network isn't managed. Global network policies have to be applied.
SetShillPropertiesForGlobalPolicy(
*shill_dictionary, *global_policy, shill_dictionary.get());
}
scoped_ptr<NetworkUIData> ui_data(NetworkUIData::CreateFromONC(onc_source)); scoped_ptr<NetworkUIData> ui_data(NetworkUIData::CreateFromONC(onc_source));
if (user_settings) { if (user_settings) {
......
...@@ -22,15 +22,37 @@ namespace policy_util { ...@@ -22,15 +22,37 @@ namespace policy_util {
typedef std::map<std::string, const base::DictionaryValue*> GuidToPolicyMap; typedef std::map<std::string, const base::DictionaryValue*> GuidToPolicyMap;
// Creates a managed ONC dictionary from the given arguments. Depending on the
// profile type, the policies are assumed to come from the user or device policy
// and and |user_settings| to be the user's non-shared or shared settings.
// Each of the arguments can be NULL.
// TODO(pneubeck): Add documentation of the returned format, see
// https://crbug.com/408990 .
scoped_ptr<base::DictionaryValue> CreateManagedONC(
const base::DictionaryValue* global_policy,
const base::DictionaryValue* network_policy,
const base::DictionaryValue* user_settings,
const base::DictionaryValue* active_settings,
const NetworkProfile* profile);
// Adds properties to |shill_properties_to_update|, which are enforced on an
// unamaged network by the global config |global_network_policy| of the policy.
// |shill_dictionary| are the network's current properties read from Shill.
void SetShillPropertiesForGlobalPolicy(
const base::DictionaryValue& shill_dictionary,
const base::DictionaryValue& global_network_policy,
base::DictionaryValue* shill_properties_to_update);
// Creates a Shill property dictionary from the given arguments. The resulting // Creates a Shill property dictionary from the given arguments. The resulting
// dictionary will be sent to Shill by the caller. Depending on the profile // dictionary will be sent to Shill by the caller. Depending on the profile
// type, |policy| is interpreted as the user or device policy and // type, |network_policy| is interpreted as the user or device policy and
// |user_settings| as the user or shared settings. |policy| or |user_settings| // |user_settings| as the user or shared settings. |network_policy| or
// can be NULL, but not both. // |user_settings| can be NULL, but not both.
scoped_ptr<base::DictionaryValue> CreateShillConfiguration( scoped_ptr<base::DictionaryValue> CreateShillConfiguration(
const NetworkProfile& profile, const NetworkProfile& profile,
const std::string& guid, const std::string& guid,
const base::DictionaryValue* policy, const base::DictionaryValue* global_policy,
const base::DictionaryValue* network_policy,
const base::DictionaryValue* user_settings); const base::DictionaryValue* user_settings);
// Returns the policy from |policies| matching |actual_network|, if any exists. // Returns the policy from |policies| matching |actual_network|, if any exists.
......
{
"Name": {
"Active": "wifi2"
},
"Type": {
"Active": "WiFi"
},
"WiFi": {
"AutoConnect": {
"Active": false,
"Effective": "UserPolicy",
"UserPolicy": false
},
"SSID": {
"Active": "wifi2"
},
"Security": {
"Active": "WPA-PSK"
}
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment