Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chromeos/network/managed_network_configuration_handler.h" | 5 #include "chromeos/network/managed_network_configuration_handler.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/guid.h" | 11 #include "base/guid.h" |
| 12 #include "base/json/json_writer.h" | 12 #include "base/json/json_writer.h" |
| 13 #include "base/location.h" | 13 #include "base/location.h" |
| 14 #include "base/logging.h" | 14 #include "base/logging.h" |
| 15 #include "base/memory/ref_counted.h" | 15 #include "base/memory/ref_counted.h" |
| 16 #include "base/memory/scoped_ptr.h" | 16 #include "base/memory/scoped_ptr.h" |
| 17 #include "base/stl_util.h" | 17 #include "base/stl_util.h" |
| 18 #include "base/string_util.h" | |
| 18 #include "base/values.h" | 19 #include "base/values.h" |
| 19 #include "chromeos/dbus/dbus_method_call_status.h" | 20 #include "chromeos/dbus/dbus_method_call_status.h" |
| 20 #include "chromeos/dbus/dbus_thread_manager.h" | 21 #include "chromeos/dbus/dbus_thread_manager.h" |
| 21 #include "chromeos/dbus/shill_manager_client.h" | 22 #include "chromeos/dbus/shill_manager_client.h" |
| 22 #include "chromeos/dbus/shill_profile_client.h" | 23 #include "chromeos/dbus/shill_profile_client.h" |
| 23 #include "chromeos/dbus/shill_service_client.h" | 24 #include "chromeos/dbus/shill_service_client.h" |
| 24 #include "chromeos/network/network_configuration_handler.h" | 25 #include "chromeos/network/network_configuration_handler.h" |
| 25 #include "chromeos/network/network_event_log.h" | 26 #include "chromeos/network/network_event_log.h" |
| 26 #include "chromeos/network/network_handler_callbacks.h" | 27 #include "chromeos/network/network_handler_callbacks.h" |
| 28 #include "chromeos/network/network_profile.h" | |
| 29 #include "chromeos/network/network_profile_handler.h" | |
| 27 #include "chromeos/network/network_state.h" | 30 #include "chromeos/network/network_state.h" |
| 28 #include "chromeos/network/network_state_handler.h" | 31 #include "chromeos/network/network_state_handler.h" |
| 29 #include "chromeos/network/network_ui_data.h" | 32 #include "chromeos/network/network_ui_data.h" |
| 30 #include "chromeos/network/onc/onc_constants.h" | 33 #include "chromeos/network/onc/onc_constants.h" |
| 31 #include "chromeos/network/onc/onc_merger.h" | 34 #include "chromeos/network/onc/onc_merger.h" |
| 32 #include "chromeos/network/onc/onc_signature.h" | 35 #include "chromeos/network/onc/onc_signature.h" |
| 33 #include "chromeos/network/onc/onc_translator.h" | 36 #include "chromeos/network/onc/onc_translator.h" |
| 34 #include "chromeos/network/onc/onc_utils.h" | 37 #include "chromeos/network/onc/onc_utils.h" |
| 35 #include "chromeos/network/onc/onc_validator.h" | 38 #include "chromeos/network/onc/onc_validator.h" |
| 36 #include "dbus/object_path.h" | 39 #include "dbus/object_path.h" |
| 37 #include "third_party/cros_system_api/dbus/service_constants.h" | 40 #include "third_party/cros_system_api/dbus/service_constants.h" |
| 38 | 41 |
| 39 namespace chromeos { | 42 namespace chromeos { |
| 40 | 43 |
| 41 namespace { | 44 namespace { |
| 42 | 45 |
| 43 ManagedNetworkConfigurationHandler* g_configuration_handler_instance = NULL; | |
| 44 | |
| 45 const char kLogModule[] = "ManagedNetworkConfigurationHandler"; | 46 const char kLogModule[] = "ManagedNetworkConfigurationHandler"; |
| 46 | 47 |
| 47 // These are error strings used for error callbacks. None of these error | 48 // These are error strings used for error callbacks. None of these error |
| 48 // messages are user-facing: they should only appear in logs. | 49 // messages are user-facing: they should only appear in logs. |
| 49 const char kInvalidUserSettingsMessage[] = "User settings are invalid."; | 50 const char kInvalidUserSettingsMessage[] = "User settings are invalid."; |
| 50 const char kInvalidUserSettings[] = "Error.InvalidUserSettings"; | 51 const char kInvalidUserSettings[] = "Error.InvalidUserSettings"; |
| 51 const char kNetworkAlreadyConfiguredMessage[] = | 52 const char kNetworkAlreadyConfiguredMessage[] = |
| 52 "Network is already configured."; | 53 "Network is already configured."; |
| 53 const char kNetworkAlreadyConfigured[] = "Error.NetworkAlreadyConfigured"; | 54 const char kNetworkAlreadyConfigured[] = "Error.NetworkAlreadyConfigured"; |
| 54 const char kPoliciesNotInitializedMessage[] = "Policies not initialized."; | 55 const char kPoliciesNotInitializedMessage[] = "Policies not initialized."; |
| 55 const char kPoliciesNotInitialized[] = "Error.PoliciesNotInitialized"; | 56 const char kPoliciesNotInitialized[] = "Error.PoliciesNotInitialized"; |
| 57 const char kProfileNotInitializedMessage[] = "Profile not initialized."; | |
| 58 const char kProfileNotInitialized[] = "Error.ProflieNotInitialized"; | |
| 56 const char kServicePath[] = "servicePath"; | 59 const char kServicePath[] = "servicePath"; |
|
Joao da Silva
2013/05/07 14:31:36
This is not used.
pneubeck (no reviews)
2013/05/07 15:03:19
Done.
| |
| 57 const char kSetOnUnconfiguredNetworkMessage[] = | 60 const char kSetOnUnconfiguredNetworkMessage[] = |
| 58 "Unable to modify properties of an unconfigured network."; | 61 "Unable to modify properties of an unconfigured network."; |
| 59 const char kSetOnUnconfiguredNetwork[] = "Error.SetCalledOnUnconfiguredNetwork"; | 62 const char kSetOnUnconfiguredNetwork[] = "Error.SetCalledOnUnconfiguredNetwork"; |
| 60 const char kUIDataErrorMessage[] = "UI data contains errors."; | 63 const char kUIDataErrorMessage[] = "UI data contains errors."; |
| 61 const char kUIDataError[] = "Error.UIData"; | 64 const char kUIDataError[] = "Error.UIData"; |
|
Joao da Silva
2013/05/07 14:31:36
These 2 are not used.
pneubeck (no reviews)
2013/05/07 15:03:19
Done.
| |
| 65 const char kUnknownProfilePathMessage[] = "Profile path is unknown."; | |
| 66 const char kUnknownProfilePath[] = "Error.UnknownProfilePath"; | |
| 62 const char kUnknownServicePathMessage[] = "Service path is unknown."; | 67 const char kUnknownServicePathMessage[] = "Service path is unknown."; |
| 63 const char kUnknownServicePath[] = "Error.UnknownServicePath"; | 68 const char kUnknownServicePath[] = "Error.UnknownServicePath"; |
| 64 | 69 |
| 65 enum ProfileType { | |
| 66 PROFILE_NONE, // Not in any profile. | |
| 67 PROFILE_SHARED, // In the shared profile, shared by all users on device. | |
| 68 PROFILE_USER // In the user profile, not visible to other users. | |
| 69 }; | |
| 70 | |
| 71 const char kSharedProfilePath[] = "/profile/default"; | |
| 72 const char kUserProfilePath[] = "/profile/chronos/shill"; | |
| 73 | |
| 74 // This fake credential contains a random postfix which is extremly unlikely to | 70 // This fake credential contains a random postfix which is extremly unlikely to |
| 75 // be used by any user. | 71 // be used by any user. |
| 76 const char kFakeCredential[] = "FAKE_CREDENTIAL_VPaJDV9x"; | 72 const char kFakeCredential[] = "FAKE_CREDENTIAL_VPaJDV9x"; |
| 77 | 73 |
| 74 std::string ToDebugString(onc::ONCSource source, | |
| 75 const std::string& userhash) { | |
| 76 return source == onc::ONC_SOURCE_USER_POLICY ? | |
| 77 ("user policy of " + userhash) : "device policy"; | |
| 78 } | |
| 79 | |
| 78 void RunErrorCallback(const std::string& service_path, | 80 void RunErrorCallback(const std::string& service_path, |
| 79 const std::string& error_name, | 81 const std::string& error_name, |
| 80 const std::string& error_message, | 82 const std::string& error_message, |
| 81 const network_handler::ErrorCallback& error_callback) { | 83 const network_handler::ErrorCallback& error_callback) { |
| 82 network_event_log::AddEntry(kLogModule, error_name, error_message); | 84 network_event_log::AddEntry(kLogModule, error_name, error_message); |
| 83 error_callback.Run( | 85 error_callback.Run( |
| 84 error_name, | 86 error_name, |
| 85 make_scoped_ptr( | 87 make_scoped_ptr( |
| 86 network_handler::CreateErrorData(service_path, | 88 network_handler::CreateErrorData(service_path, |
| 87 error_name, | 89 error_name, |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 175 // value to overwrite whatever is stored in Shill. | 177 // value to overwrite whatever is stored in Shill. |
| 176 } | 178 } |
| 177 } | 179 } |
| 178 } | 180 } |
| 179 | 181 |
| 180 // Creates a Shill property dictionary from the given arguments. The resulting | 182 // Creates a Shill property dictionary from the given arguments. The resulting |
| 181 // dictionary will be sent to Shill by the caller. Depending on the profile | 183 // dictionary will be sent to Shill by the caller. Depending on the profile |
| 182 // path, |policy| is interpreted as the user or device policy and |settings| as | 184 // path, |policy| is interpreted as the user or device policy and |settings| as |
| 183 // the user or shared settings. | 185 // the user or shared settings. |
| 184 scoped_ptr<base::DictionaryValue> CreateShillConfiguration( | 186 scoped_ptr<base::DictionaryValue> CreateShillConfiguration( |
| 185 const std::string& profile_path, | 187 const NetworkProfile& profile, |
| 186 const std::string& guid, | 188 const std::string& guid, |
| 187 const base::DictionaryValue* policy, | 189 const base::DictionaryValue* policy, |
| 188 const base::DictionaryValue* settings) { | 190 const base::DictionaryValue* settings) { |
| 189 scoped_ptr<base::DictionaryValue> effective; | 191 scoped_ptr<base::DictionaryValue> effective; |
| 190 | |
| 191 onc::ONCSource onc_source; | 192 onc::ONCSource onc_source; |
| 192 if (policy) { | 193 if (policy) { |
| 193 if (profile_path == kSharedProfilePath) { | 194 if (profile.type() == NetworkProfile::TYPE_SHARED) { |
| 194 effective = onc::MergeSettingsAndPoliciesToEffective( | 195 effective = onc::MergeSettingsAndPoliciesToEffective( |
| 195 NULL, // no user policy | 196 NULL, // no user policy |
| 196 policy, // device policy | 197 policy, // device policy |
| 197 NULL, // no user settings | 198 NULL, // no user settings |
| 198 settings); // shared settings | 199 settings); // shared settings |
| 199 onc_source = onc::ONC_SOURCE_DEVICE_POLICY; | 200 onc_source = onc::ONC_SOURCE_DEVICE_POLICY; |
| 200 } else { | 201 } else if (profile.type() == NetworkProfile::TYPE_USER) { |
| 201 effective = onc::MergeSettingsAndPoliciesToEffective( | 202 effective = onc::MergeSettingsAndPoliciesToEffective( |
| 202 policy, // user policy | 203 policy, // user policy |
| 203 NULL, // no device policy | 204 NULL, // no device policy |
| 204 settings, // user settings | 205 settings, // user settings |
| 205 NULL); // no shared settings | 206 NULL); // no shared settings |
| 206 onc_source = onc::ONC_SOURCE_USER_POLICY; | 207 onc_source = onc::ONC_SOURCE_USER_POLICY; |
| 208 } else { | |
| 209 NOTREACHED(); | |
| 207 } | 210 } |
| 208 } else if (settings) { | 211 } else if (settings) { |
| 209 effective.reset(settings->DeepCopy()); | 212 effective.reset(settings->DeepCopy()); |
| 210 // TODO(pneubeck): change to source ONC_SOURCE_USER | 213 // TODO(pneubeck): change to source ONC_SOURCE_USER |
| 211 onc_source = onc::ONC_SOURCE_NONE; | 214 onc_source = onc::ONC_SOURCE_NONE; |
| 212 } else { | 215 } else { |
| 213 NOTREACHED(); | 216 NOTREACHED(); |
| 214 onc_source = onc::ONC_SOURCE_NONE; | 217 onc_source = onc::ONC_SOURCE_NONE; |
| 215 } | 218 } |
| 216 | 219 |
| 217 RemoveFakeCredentials(onc::kNetworkConfigurationSignature, | 220 RemoveFakeCredentials(onc::kNetworkConfigurationSignature, |
| 218 effective.get()); | 221 effective.get()); |
| 219 | 222 |
| 220 effective->SetStringWithoutPathExpansion(onc::network_config::kGUID, guid); | 223 effective->SetStringWithoutPathExpansion(onc::network_config::kGUID, guid); |
| 221 | 224 |
| 222 scoped_ptr<base::DictionaryValue> shill_dictionary( | 225 scoped_ptr<base::DictionaryValue> shill_dictionary( |
| 223 onc::TranslateONCObjectToShill(&onc::kNetworkConfigurationSignature, | 226 onc::TranslateONCObjectToShill(&onc::kNetworkConfigurationSignature, |
| 224 *effective)); | 227 *effective)); |
| 225 | 228 |
| 226 shill_dictionary->SetStringWithoutPathExpansion(flimflam::kProfileProperty, | 229 shill_dictionary->SetStringWithoutPathExpansion(flimflam::kProfileProperty, |
| 227 profile_path); | 230 profile.path); |
| 228 | 231 |
| 229 scoped_ptr<NetworkUIData> ui_data; | 232 scoped_ptr<NetworkUIData> ui_data; |
| 230 if (policy) | 233 if (policy) |
| 231 ui_data = CreateUIDataFromONC(onc_source, *policy); | 234 ui_data = CreateUIDataFromONC(onc_source, *policy); |
| 232 else | 235 else |
| 233 ui_data.reset(new NetworkUIData()); | 236 ui_data.reset(new NetworkUIData()); |
| 234 | 237 |
| 235 if (settings) { | 238 if (settings) { |
| 236 // Shill doesn't know that sensitive data is contained in the UIData | 239 // Shill doesn't know that sensitive data is contained in the UIData |
| 237 // property and might write it into logs or other insecure places. Thus, we | 240 // property and might write it into logs or other insecure places. Thus, we |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 276 policy.GetStringWithoutPathExpansion(onc::wifi::kSSID, &policy_ssid); | 279 policy.GetStringWithoutPathExpansion(onc::wifi::kSSID, &policy_ssid); |
| 277 std::string network_ssid; | 280 std::string network_ssid; |
| 278 onc_network_part.GetStringWithoutPathExpansion(onc::wifi::kSSID, | 281 onc_network_part.GetStringWithoutPathExpansion(onc::wifi::kSSID, |
| 279 &network_ssid); | 282 &network_ssid); |
| 280 return (policy_ssid == network_ssid); | 283 return (policy_ssid == network_ssid); |
| 281 } | 284 } |
| 282 | 285 |
| 283 // Returns the policy of |policies| matching |onc_network_part|, if any | 286 // Returns the policy of |policies| matching |onc_network_part|, if any |
| 284 // exists. Returns NULL otherwise. | 287 // exists. Returns NULL otherwise. |
| 285 const base::DictionaryValue* FindMatchingPolicy( | 288 const base::DictionaryValue* FindMatchingPolicy( |
| 286 const ManagedNetworkConfigurationHandler::PolicyMap &policies, | 289 const ManagedNetworkConfigurationHandler::GuidToPolicyMap &policies, |
| 287 const base::DictionaryValue& onc_network_part) { | 290 const base::DictionaryValue& onc_network_part) { |
| 288 for (ManagedNetworkConfigurationHandler::PolicyMap::const_iterator it = | 291 for (ManagedNetworkConfigurationHandler::GuidToPolicyMap::const_iterator it = |
| 289 policies.begin(); it != policies.end(); ++it) { | 292 policies.begin(); it != policies.end(); ++it) { |
| 290 if (IsPolicyMatching(*it->second, onc_network_part)) | 293 if (IsPolicyMatching(*it->second, onc_network_part)) |
| 291 return it->second; | 294 return it->second; |
| 292 } | 295 } |
| 293 return NULL; | 296 return NULL; |
| 294 } | 297 } |
| 295 | 298 |
| 299 const base::DictionaryValue* GetByGUID( | |
| 300 const ManagedNetworkConfigurationHandler::GuidToPolicyMap &policies, | |
| 301 const std::string& guid) { | |
| 302 ManagedNetworkConfigurationHandler::GuidToPolicyMap::const_iterator it = | |
| 303 policies.find(guid); | |
| 304 if (it == policies.end()) | |
| 305 return NULL; | |
| 306 return it->second; | |
| 307 | |
|
Joao da Silva
2013/05/07 14:31:36
nit: remove newline
pneubeck (no reviews)
2013/05/07 15:03:19
Done.
| |
| 308 } | |
| 309 | |
| 296 void TranslatePropertiesToOncAndRunCallback( | 310 void TranslatePropertiesToOncAndRunCallback( |
| 297 const network_handler::DictionaryResultCallback& callback, | 311 const network_handler::DictionaryResultCallback& callback, |
| 298 const std::string& service_path, | 312 const std::string& service_path, |
| 299 const base::DictionaryValue& shill_properties) { | 313 const base::DictionaryValue& shill_properties) { |
| 300 scoped_ptr<base::DictionaryValue> onc_network( | 314 scoped_ptr<base::DictionaryValue> onc_network( |
| 301 onc::TranslateShillServiceToONCPart( | 315 onc::TranslateShillServiceToONCPart( |
| 302 shill_properties, | 316 shill_properties, |
| 303 &onc::kNetworkWithStateSignature)); | 317 &onc::kNetworkWithStateSignature)); |
| 304 callback.Run(service_path, *onc_network); | 318 callback.Run(service_path, *onc_network); |
| 305 } | 319 } |
| 306 | 320 |
| 307 } // namespace | 321 } // namespace |
| 308 | 322 |
| 323 static ManagedNetworkConfigurationHandler* | |
| 324 g_configuration_handler_instance = NULL; | |
| 325 | |
| 309 // static | 326 // static |
| 310 void ManagedNetworkConfigurationHandler::Initialize() { | 327 void ManagedNetworkConfigurationHandler::Initialize( |
| 328 NetworkProfileHandler* profile_handler) { | |
| 311 CHECK(!g_configuration_handler_instance); | 329 CHECK(!g_configuration_handler_instance); |
| 312 g_configuration_handler_instance = new ManagedNetworkConfigurationHandler; | 330 g_configuration_handler_instance = |
| 331 new ManagedNetworkConfigurationHandler(profile_handler); | |
| 313 } | 332 } |
| 314 | 333 |
| 315 // static | 334 // static |
| 316 bool ManagedNetworkConfigurationHandler::IsInitialized() { | 335 bool ManagedNetworkConfigurationHandler::IsInitialized() { |
| 317 return g_configuration_handler_instance; | 336 return g_configuration_handler_instance; |
| 318 } | 337 } |
| 319 | 338 |
| 320 // static | 339 // static |
| 321 void ManagedNetworkConfigurationHandler::Shutdown() { | 340 void ManagedNetworkConfigurationHandler::Shutdown() { |
| 322 CHECK(g_configuration_handler_instance); | 341 CHECK(g_configuration_handler_instance); |
| 323 delete g_configuration_handler_instance; | 342 delete g_configuration_handler_instance; |
| 324 g_configuration_handler_instance = NULL; | 343 g_configuration_handler_instance = NULL; |
| 325 } | 344 } |
| 326 | 345 |
| 327 // static | 346 // static |
| 328 ManagedNetworkConfigurationHandler* ManagedNetworkConfigurationHandler::Get() { | 347 ManagedNetworkConfigurationHandler* ManagedNetworkConfigurationHandler::Get() { |
| 329 CHECK(g_configuration_handler_instance); | 348 CHECK(g_configuration_handler_instance); |
| 330 return g_configuration_handler_instance; | 349 return g_configuration_handler_instance; |
| 331 } | 350 } |
| 332 | 351 |
| 333 void ManagedNetworkConfigurationHandler::GetManagedProperties( | 352 void ManagedNetworkConfigurationHandler::GetManagedProperties( |
| 353 const std::string& userhash, | |
| 334 const std::string& service_path, | 354 const std::string& service_path, |
| 335 const network_handler::DictionaryResultCallback& callback, | 355 const network_handler::DictionaryResultCallback& callback, |
| 336 const network_handler::ErrorCallback& error_callback) { | 356 const network_handler::ErrorCallback& error_callback) { |
| 337 if (!user_policies_initialized_ || !device_policies_initialized_) { | 357 if (!GetPoliciesForUser(userhash) || !GetPoliciesForUser(std::string())) { |
| 338 RunErrorCallback(service_path, | 358 RunErrorCallback(service_path, |
| 339 kPoliciesNotInitialized, | 359 kPoliciesNotInitialized, |
| 340 kPoliciesNotInitializedMessage, | 360 kPoliciesNotInitializedMessage, |
| 341 error_callback); | 361 error_callback); |
| 342 return; | 362 return; |
| 343 } | 363 } |
| 344 NetworkConfigurationHandler::Get()->GetProperties( | 364 NetworkConfigurationHandler::Get()->GetProperties( |
| 345 service_path, | 365 service_path, |
| 346 base::Bind( | 366 base::Bind( |
| 347 &ManagedNetworkConfigurationHandler::GetManagedPropertiesCallback, | 367 &ManagedNetworkConfigurationHandler::GetManagedPropertiesCallback, |
| 348 weak_ptr_factory_.GetWeakPtr(), | 368 weak_ptr_factory_.GetWeakPtr(), |
| 349 callback, | 369 callback, |
| 350 error_callback), | 370 error_callback), |
| 351 error_callback); | 371 error_callback); |
| 352 } | 372 } |
| 353 | 373 |
| 354 void ManagedNetworkConfigurationHandler::GetManagedPropertiesCallback( | 374 void ManagedNetworkConfigurationHandler::GetManagedPropertiesCallback( |
| 355 const network_handler::DictionaryResultCallback& callback, | 375 const network_handler::DictionaryResultCallback& callback, |
| 356 const network_handler::ErrorCallback& error_callback, | 376 const network_handler::ErrorCallback& error_callback, |
| 357 const std::string& service_path, | 377 const std::string& service_path, |
| 358 const base::DictionaryValue& shill_properties) { | 378 const base::DictionaryValue& shill_properties) { |
| 359 std::string profile_path; | 379 std::string profile_path; |
| 360 ProfileType profile_type = PROFILE_NONE; | 380 shill_properties.GetStringWithoutPathExpansion(flimflam::kProfileProperty, |
| 361 if (shill_properties.GetStringWithoutPathExpansion( | 381 &profile_path); |
| 362 flimflam::kProfileProperty, &profile_path)) { | 382 const NetworkProfile* profile = |
| 363 if (profile_path == kSharedProfilePath) | 383 profile_handler_->GetProfileForPath(profile_path); |
| 364 profile_type = PROFILE_SHARED; | 384 if (!profile) { |
| 365 else if (!profile_path.empty()) | 385 VLOG(1) << "No or no known profile received for service " |
| 366 profile_type = PROFILE_USER; | 386 << service_path << "."; |
| 367 } else { | |
| 368 VLOG(1) << "No profile path for service " << service_path << "."; | |
| 369 } | 387 } |
| 370 | 388 |
| 371 scoped_ptr<NetworkUIData> ui_data = GetUIData(shill_properties); | 389 scoped_ptr<NetworkUIData> ui_data = GetUIData(shill_properties); |
| 372 | 390 |
| 373 const base::DictionaryValue* user_settings = NULL; | 391 const base::DictionaryValue* user_settings = NULL; |
| 374 const base::DictionaryValue* shared_settings = NULL; | 392 const base::DictionaryValue* shared_settings = NULL; |
| 375 | 393 |
| 376 if (ui_data) { | 394 if (ui_data && profile) { |
| 377 if (profile_type == PROFILE_SHARED) | 395 if (profile->type() == NetworkProfile::TYPE_SHARED) |
| 378 shared_settings = ui_data->user_settings(); | 396 shared_settings = ui_data->user_settings(); |
| 379 else if (profile_type == PROFILE_USER) | 397 else if (profile->type() == NetworkProfile::TYPE_USER) |
| 380 user_settings = ui_data->user_settings(); | 398 user_settings = ui_data->user_settings(); |
| 381 } else if (profile_type != PROFILE_NONE) { | 399 else |
| 400 NOTREACHED(); | |
| 401 } else if (profile) { | |
| 382 LOG(WARNING) << "Service " << service_path << " of profile " | 402 LOG(WARNING) << "Service " << service_path << " of profile " |
| 383 << profile_path << " contains no or no valid UIData."; | 403 << profile_path << " contains no or no valid UIData."; |
| 384 // TODO(pneubeck): add a conversion of user configured entries of old | 404 // TODO(pneubeck): add a conversion of user configured entries of old |
| 385 // ChromeOS versions. We will have to use a heuristic to determine which | 405 // ChromeOS versions. We will have to use a heuristic to determine which |
| 386 // properties _might_ be user configured. | 406 // properties _might_ be user configured. |
| 387 } | 407 } |
| 388 | 408 |
| 389 scoped_ptr<base::DictionaryValue> active_settings( | 409 scoped_ptr<base::DictionaryValue> active_settings( |
| 390 onc::TranslateShillServiceToONCPart( | 410 onc::TranslateShillServiceToONCPart( |
| 391 shill_properties, | 411 shill_properties, |
| 392 &onc::kNetworkWithStateSignature)); | 412 &onc::kNetworkWithStateSignature)); |
| 393 | 413 |
| 394 std::string guid; | 414 std::string guid; |
| 395 active_settings->GetStringWithoutPathExpansion(onc::network_config::kGUID, | 415 active_settings->GetStringWithoutPathExpansion(onc::network_config::kGUID, |
| 396 &guid); | 416 &guid); |
| 397 | 417 |
| 398 const base::DictionaryValue* user_policy = NULL; | 418 const base::DictionaryValue* user_policy = NULL; |
| 399 const base::DictionaryValue* device_policy = NULL; | 419 const base::DictionaryValue* device_policy = NULL; |
| 400 if (!guid.empty()) { | 420 if (!guid.empty() && profile) { |
| 401 // We already checked that the policies were initialized. No need to do that | 421 const GuidToPolicyMap* policies = GetPoliciesForProfile(*profile); |
| 402 // again. | 422 if (!policies) { |
| 403 if (profile_type == PROFILE_SHARED) | 423 RunErrorCallback(service_path, |
| 404 device_policy = device_policies_by_guid_[guid]; | 424 kPoliciesNotInitialized, |
| 405 else if (profile_type == PROFILE_USER) | 425 kPoliciesNotInitializedMessage, |
| 406 user_policy = user_policies_by_guid_[guid]; | 426 error_callback); |
| 427 return; | |
| 428 } | |
| 429 const base::DictionaryValue* policy = GetByGUID(*policies, guid); | |
| 430 if (profile->type() == NetworkProfile::TYPE_SHARED) | |
| 431 device_policy = policy; | |
| 432 else if (profile->type() == NetworkProfile::TYPE_USER) | |
| 433 user_policy = policy; | |
| 434 else | |
| 435 NOTREACHED(); | |
| 407 } | 436 } |
| 408 | 437 |
| 409 // This call also removes credentials from policies. | 438 // This call also removes credentials from policies. |
| 410 scoped_ptr<base::DictionaryValue> augmented_properties = | 439 scoped_ptr<base::DictionaryValue> augmented_properties = |
| 411 onc::MergeSettingsAndPoliciesToAugmented( | 440 onc::MergeSettingsAndPoliciesToAugmented( |
| 412 onc::kNetworkConfigurationSignature, | 441 onc::kNetworkConfigurationSignature, |
| 413 user_policy, | 442 user_policy, |
| 414 device_policy, | 443 device_policy, |
| 415 user_settings, | 444 user_settings, |
| 416 shared_settings, | 445 shared_settings, |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 449 // TODO(pneubeck): create an initial configuration in this case. As for | 478 // TODO(pneubeck): create an initial configuration in this case. As for |
| 450 // CreateConfiguration, user settings from older ChromeOS versions have to | 479 // CreateConfiguration, user settings from older ChromeOS versions have to |
| 451 // determined here. | 480 // determined here. |
| 452 RunErrorCallback(service_path, | 481 RunErrorCallback(service_path, |
| 453 kSetOnUnconfiguredNetwork, | 482 kSetOnUnconfiguredNetwork, |
| 454 kSetOnUnconfiguredNetworkMessage, | 483 kSetOnUnconfiguredNetworkMessage, |
| 455 error_callback); | 484 error_callback); |
| 456 return; | 485 return; |
| 457 } | 486 } |
| 458 | 487 |
| 488 const std::string& profile_path = state->profile_path(); | |
| 489 const NetworkProfile *profile = | |
| 490 profile_handler_->GetProfileForPath(profile_path); | |
| 491 if (!profile) { | |
| 492 RunErrorCallback(service_path, | |
| 493 kUnknownProfilePath, | |
| 494 kUnknownProfilePathMessage, | |
| 495 error_callback); | |
| 496 return; | |
| 497 } | |
| 498 | |
| 499 VLOG(2) << "SetProperties: Found GUID " << guid << " and profile " | |
| 500 << profile->ToDebugString(); | |
| 501 | |
| 502 const GuidToPolicyMap* policies = GetPoliciesForProfile(*profile); | |
| 503 if (!policies) { | |
| 504 RunErrorCallback(service_path, | |
| 505 kPoliciesNotInitialized, | |
| 506 kPoliciesNotInitializedMessage, | |
| 507 error_callback); | |
| 508 return; | |
| 509 } | |
| 510 | |
| 459 // Validate the ONC dictionary. We are liberal and ignore unknown field | 511 // Validate the ONC dictionary. We are liberal and ignore unknown field |
| 460 // names. User settings are only partial ONC, thus we ignore missing fields. | 512 // names. User settings are only partial ONC, thus we ignore missing fields. |
| 461 onc::Validator validator(false, // Ignore unknown fields. | 513 onc::Validator validator(false, // Ignore unknown fields. |
| 462 false, // Ignore invalid recommended field names. | 514 false, // Ignore invalid recommended field names. |
| 463 false, // Ignore missing fields. | 515 false, // Ignore missing fields. |
| 464 false); // This ONC does not comes from policy. | 516 false); // This ONC does not comes from policy. |
| 465 | 517 |
| 466 onc::Validator::Result validation_result; | 518 onc::Validator::Result validation_result; |
| 467 scoped_ptr<base::DictionaryValue> validated_user_settings = | 519 scoped_ptr<base::DictionaryValue> validated_user_settings = |
| 468 validator.ValidateAndRepairObject( | 520 validator.ValidateAndRepairObject( |
| 469 &onc::kNetworkConfigurationSignature, | 521 &onc::kNetworkConfigurationSignature, |
| 470 user_settings, | 522 user_settings, |
| 471 &validation_result); | 523 &validation_result); |
| 472 | 524 |
| 473 if (validation_result == onc::Validator::INVALID) { | 525 if (validation_result == onc::Validator::INVALID) { |
| 474 LOG(ERROR) << "ONC user settings are invalid and couldn't be repaired."; | |
| 475 RunErrorCallback(service_path, | 526 RunErrorCallback(service_path, |
| 476 kInvalidUserSettings, | 527 kInvalidUserSettings, |
| 477 kInvalidUserSettingsMessage, | 528 kInvalidUserSettingsMessage, |
| 478 error_callback); | 529 error_callback); |
| 479 return; | 530 return; |
| 480 } | 531 } |
| 481 if (validation_result == onc::Validator::VALID_WITH_WARNINGS) | 532 if (validation_result == onc::Validator::VALID_WITH_WARNINGS) |
| 482 LOG(WARNING) << "Validation of ONC user settings produced warnings."; | 533 LOG(WARNING) << "Validation of ONC user settings produced warnings."; |
| 483 | 534 |
| 484 VLOG(2) << "SetProperties: Found GUID " << guid << " and profile " | 535 const base::DictionaryValue* policy = GetByGUID(*policies, guid); |
| 485 << state->profile_path(); | |
| 486 | |
| 487 const PolicyMap* policies_by_guid = | |
| 488 GetPoliciesForProfile(state->profile_path()); | |
| 489 | |
| 490 if (!policies_by_guid) { | |
| 491 RunErrorCallback(service_path, | |
| 492 kPoliciesNotInitialized, | |
| 493 kPoliciesNotInitializedMessage, | |
| 494 error_callback); | |
| 495 return; | |
| 496 } | |
| 497 | |
| 498 const base::DictionaryValue* policy = NULL; | |
| 499 PolicyMap::const_iterator it = policies_by_guid->find(guid); | |
| 500 if (it != policies_by_guid->end()) | |
| 501 policy = it->second; | |
| 502 | |
| 503 VLOG(2) << "This configuration is " << (policy ? "" : "not ") << "managed."; | 536 VLOG(2) << "This configuration is " << (policy ? "" : "not ") << "managed."; |
| 504 | 537 |
| 505 scoped_ptr<base::DictionaryValue> shill_dictionary( | 538 scoped_ptr<base::DictionaryValue> shill_dictionary( |
| 506 CreateShillConfiguration(state->profile_path(), guid, policy, | 539 CreateShillConfiguration(*profile, guid, policy, &user_settings)); |
| 507 &user_settings)); | |
| 508 | 540 |
| 509 NetworkConfigurationHandler::Get()->SetProperties(service_path, | 541 NetworkConfigurationHandler::Get()->SetProperties(service_path, |
| 510 *shill_dictionary, | 542 *shill_dictionary, |
| 511 callback, | 543 callback, |
| 512 error_callback); | 544 error_callback); |
| 513 } | 545 } |
| 514 | 546 |
| 515 void ManagedNetworkConfigurationHandler::Connect( | 547 void ManagedNetworkConfigurationHandler::Connect( |
| 516 const std::string& service_path, | 548 const std::string& service_path, |
| 517 const base::Closure& callback, | 549 const base::Closure& callback, |
| 518 const network_handler::ErrorCallback& error_callback) const { | 550 const network_handler::ErrorCallback& error_callback) const { |
| 519 NetworkConfigurationHandler::Get()->Connect(service_path, | 551 NetworkConfigurationHandler::Get()->Connect(service_path, |
| 520 callback, | 552 callback, |
| 521 error_callback); | 553 error_callback); |
| 522 } | 554 } |
| 523 | 555 |
| 524 void ManagedNetworkConfigurationHandler::Disconnect( | 556 void ManagedNetworkConfigurationHandler::Disconnect( |
| 525 const std::string& service_path, | 557 const std::string& service_path, |
| 526 const base::Closure& callback, | 558 const base::Closure& callback, |
| 527 const network_handler::ErrorCallback& error_callback) const { | 559 const network_handler::ErrorCallback& error_callback) const { |
| 528 NetworkConfigurationHandler::Get()->Disconnect(service_path, | 560 NetworkConfigurationHandler::Get()->Disconnect(service_path, |
| 529 callback, | 561 callback, |
| 530 error_callback); | 562 error_callback); |
| 531 } | 563 } |
| 532 | 564 |
| 533 void ManagedNetworkConfigurationHandler::CreateConfiguration( | 565 void ManagedNetworkConfigurationHandler::CreateConfiguration( |
| 566 const std::string& userhash, | |
| 534 const base::DictionaryValue& properties, | 567 const base::DictionaryValue& properties, |
| 535 const network_handler::StringResultCallback& callback, | 568 const network_handler::StringResultCallback& callback, |
| 536 const network_handler::ErrorCallback& error_callback) const { | 569 const network_handler::ErrorCallback& error_callback) const { |
| 537 std::string profile_path = kUserProfilePath; | 570 const GuidToPolicyMap* policies = GetPoliciesForUser(userhash); |
| 538 const PolicyMap* policies_by_guid = GetPoliciesForProfile(profile_path); | 571 if (!policies) { |
| 539 | |
| 540 if (!policies_by_guid) { | |
| 541 RunErrorCallback("", | 572 RunErrorCallback("", |
| 542 kPoliciesNotInitialized, | 573 kPoliciesNotInitialized, |
| 543 kPoliciesNotInitializedMessage, | 574 kPoliciesNotInitializedMessage, |
| 544 error_callback); | 575 error_callback); |
| 545 return; | 576 return; |
| 546 } | 577 } |
| 547 | 578 |
| 548 if (FindMatchingPolicy(*policies_by_guid, properties)) { | 579 if (FindMatchingPolicy(*policies, properties)) { |
| 549 RunErrorCallback("", | 580 RunErrorCallback("", |
| 550 kNetworkAlreadyConfigured, | 581 kNetworkAlreadyConfigured, |
| 551 kNetworkAlreadyConfiguredMessage, | 582 kNetworkAlreadyConfiguredMessage, |
| 552 error_callback); | 583 error_callback); |
| 553 } | 584 } |
| 554 | 585 |
| 586 const NetworkProfile* profile = | |
| 587 profile_handler_->GetProfileForUserhash(userhash); | |
| 588 if (!profile) { | |
| 589 RunErrorCallback("", | |
| 590 kProfileNotInitialized, | |
| 591 kProfileNotInitializedMessage, | |
| 592 error_callback); | |
| 593 } | |
| 594 | |
| 555 // TODO(pneubeck): In case of WiFi, check that no other configuration for the | 595 // TODO(pneubeck): In case of WiFi, check that no other configuration for the |
| 556 // same {SSID, mode, security} exists. We don't support such multiple | 596 // same {SSID, mode, security} exists. We don't support such multiple |
| 557 // configurations, yet. | 597 // configurations, yet. |
| 558 | 598 |
| 559 // Generate a new GUID for this configuration. Ignore the maybe provided GUID | 599 // Generate a new GUID for this configuration. Ignore the maybe provided GUID |
| 560 // in |properties| as it is not our own and from an untrusted source. | 600 // in |properties| as it is not our own and from an untrusted source. |
| 561 std::string guid = base::GenerateGUID(); | 601 std::string guid = base::GenerateGUID(); |
| 562 | |
| 563 scoped_ptr<base::DictionaryValue> shill_dictionary( | 602 scoped_ptr<base::DictionaryValue> shill_dictionary( |
| 564 CreateShillConfiguration(profile_path, guid, NULL /*no policy*/, | 603 CreateShillConfiguration(*profile, guid, NULL /*no policy*/, |
| 565 &properties)); | 604 &properties)); |
| 566 | 605 |
| 567 NetworkConfigurationHandler::Get()->CreateConfiguration(*shill_dictionary, | 606 NetworkConfigurationHandler::Get()->CreateConfiguration(*shill_dictionary, |
| 568 callback, | 607 callback, |
| 569 error_callback); | 608 error_callback); |
| 570 } | 609 } |
| 571 | 610 |
| 572 void ManagedNetworkConfigurationHandler::RemoveConfiguration( | 611 void ManagedNetworkConfigurationHandler::RemoveConfiguration( |
| 573 const std::string& service_path, | 612 const std::string& service_path, |
| 574 const base::Closure& callback, | 613 const base::Closure& callback, |
| 575 const network_handler::ErrorCallback& error_callback) const { | 614 const network_handler::ErrorCallback& error_callback) const { |
| 576 NetworkConfigurationHandler::Get()->RemoveConfiguration(service_path, | 615 NetworkConfigurationHandler::Get()->RemoveConfiguration(service_path, |
| 577 callback, | 616 callback, |
| 578 error_callback); | 617 error_callback); |
| 579 } | 618 } |
| 580 | 619 |
| 581 // This class compares (entry point is Run()) |modified_policies| with the | 620 // This class compares (entry point is Run()) |modified_policies| with the |
| 582 // existing entries in the provided Shill profile |profile|. It fetches all | 621 // existing entries in the provided Shill profile |profile|. It fetches all |
| 583 // entries in parallel (GetProfileProperties), compares each entry with the | 622 // entries in parallel (GetProfileProperties), compares each entry with the |
| 584 // current policies (GetEntry) and adds all missing policies | 623 // current policies (GetEntry) and adds all missing policies |
| 585 // (~PolicyApplicator). | 624 // (~PolicyApplicator). |
| 586 class ManagedNetworkConfigurationHandler::PolicyApplicator | 625 class ManagedNetworkConfigurationHandler::PolicyApplicator |
| 587 : public base::RefCounted<PolicyApplicator> { | 626 : public base::RefCounted<PolicyApplicator> { |
| 588 public: | 627 public: |
| 589 typedef ManagedNetworkConfigurationHandler::PolicyMap PolicyMap; | 628 typedef ManagedNetworkConfigurationHandler::GuidToPolicyMap GuidToPolicyMap; |
| 590 | 629 |
| 591 // |modified_policies| must not be NULL and will be empty afterwards. | 630 // |modified_policies| must not be NULL and will be empty afterwards. |
| 592 PolicyApplicator(base::WeakPtr<ManagedNetworkConfigurationHandler> handler, | 631 PolicyApplicator(base::WeakPtr<ManagedNetworkConfigurationHandler> handler, |
| 593 const std::string& profile, | 632 const NetworkProfile& profile, |
| 594 std::set<std::string>* modified_policies) | 633 std::set<std::string>* modified_policies) |
| 595 : handler_(handler), | 634 : handler_(handler), |
| 596 profile_path_(profile) { | 635 profile_(profile) { |
| 597 remaining_policies_.swap(*modified_policies); | 636 remaining_policies_.swap(*modified_policies); |
| 598 } | 637 } |
| 599 | 638 |
| 600 void Run() { | 639 void Run() { |
| 601 DBusThreadManager::Get()->GetShillProfileClient()->GetProperties( | 640 DBusThreadManager::Get()->GetShillProfileClient()->GetProperties( |
| 602 dbus::ObjectPath(profile_path_), | 641 dbus::ObjectPath(profile_.path), |
| 603 base::Bind(&PolicyApplicator::GetProfileProperties, this), | 642 base::Bind(&PolicyApplicator::GetProfileProperties, this), |
| 604 base::Bind(&LogErrorMessage, FROM_HERE)); | 643 base::Bind(&LogErrorMessage, FROM_HERE)); |
| 605 } | 644 } |
| 606 | 645 |
| 607 private: | 646 private: |
| 608 friend class base::RefCounted<PolicyApplicator>; | 647 friend class base::RefCounted<PolicyApplicator>; |
| 609 | 648 |
| 610 void GetProfileProperties(const base::DictionaryValue& profile_properties) { | 649 void GetProfileProperties(const base::DictionaryValue& profile_properties) { |
| 611 if (!handler_) { | 650 if (!handler_) { |
| 612 LOG(WARNING) << "Handler destructed during policy application to profile " | 651 LOG(WARNING) << "Handler destructed during policy application to profile " |
| 613 << profile_path_; | 652 << profile_.ToDebugString(); |
| 614 return; | 653 return; |
| 615 } | 654 } |
| 616 | 655 |
| 617 VLOG(2) << "Received properties for profile " << profile_path_; | 656 VLOG(2) << "Received properties for profile " << profile_.ToDebugString(); |
| 618 const base::ListValue* entries = NULL; | 657 const base::ListValue* entries = NULL; |
| 619 if (!profile_properties.GetListWithoutPathExpansion( | 658 if (!profile_properties.GetListWithoutPathExpansion( |
| 620 flimflam::kEntriesProperty, &entries)) { | 659 flimflam::kEntriesProperty, &entries)) { |
| 621 LOG(ERROR) << "Profile " << profile_path_ | 660 LOG(ERROR) << "Profile " << profile_.ToDebugString() |
| 622 << " doesn't contain the property " | 661 << " doesn't contain the property " |
| 623 << flimflam::kEntriesProperty; | 662 << flimflam::kEntriesProperty; |
| 624 return; | 663 return; |
| 625 } | 664 } |
| 626 | 665 |
| 627 for (base::ListValue::const_iterator it = entries->begin(); | 666 for (base::ListValue::const_iterator it = entries->begin(); |
| 628 it != entries->end(); ++it) { | 667 it != entries->end(); ++it) { |
| 629 std::string entry; | 668 std::string entry; |
| 630 (*it)->GetAsString(&entry); | 669 (*it)->GetAsString(&entry); |
| 631 | 670 |
| 632 std::ostringstream entry_failure; | 671 std::ostringstream entry_failure; |
| 633 DBusThreadManager::Get()->GetShillProfileClient()->GetEntry( | 672 DBusThreadManager::Get()->GetShillProfileClient()->GetEntry( |
| 634 dbus::ObjectPath(profile_path_), | 673 dbus::ObjectPath(profile_.path), |
| 635 entry, | 674 entry, |
| 636 base::Bind(&PolicyApplicator::GetEntry, this, entry), | 675 base::Bind(&PolicyApplicator::GetEntry, this, entry), |
| 637 base::Bind(&LogErrorMessage, FROM_HERE)); | 676 base::Bind(&LogErrorMessage, FROM_HERE)); |
| 638 } | 677 } |
| 639 } | 678 } |
| 640 | 679 |
| 641 void GetEntry(const std::string& entry, | 680 void GetEntry(const std::string& entry, |
| 642 const base::DictionaryValue& entry_properties) { | 681 const base::DictionaryValue& entry_properties) { |
| 643 if (!handler_) { | 682 if (!handler_) { |
| 644 LOG(WARNING) << "Handler destructed during policy application to profile " | 683 LOG(WARNING) << "Handler destructed during policy application to profile " |
| 645 << profile_path_; | 684 << profile_.ToDebugString(); |
| 646 return; | 685 return; |
| 647 } | 686 } |
| 648 | 687 |
| 649 VLOG(2) << "Received properties for entry " << entry << " of profile " | 688 VLOG(2) << "Received properties for entry " << entry << " of profile " |
| 650 << profile_path_; | 689 << profile_.ToDebugString(); |
| 651 | 690 |
| 652 scoped_ptr<base::DictionaryValue> onc_part( | 691 scoped_ptr<base::DictionaryValue> onc_part( |
| 653 onc::TranslateShillServiceToONCPart( | 692 onc::TranslateShillServiceToONCPart( |
| 654 entry_properties, | 693 entry_properties, |
| 655 &onc::kNetworkWithStateSignature)); | 694 &onc::kNetworkWithStateSignature)); |
| 656 | 695 |
| 657 std::string old_guid; | 696 std::string old_guid; |
| 658 if (!onc_part->GetStringWithoutPathExpansion(onc::network_config::kGUID, | 697 if (!onc_part->GetStringWithoutPathExpansion(onc::network_config::kGUID, |
| 659 &old_guid)) { | 698 &old_guid)) { |
| 660 LOG(WARNING) << "Entry " << entry << " of profile " << profile_path_ | 699 LOG(WARNING) << "Entry " << entry << " of profile " |
| 661 << " doesn't contain a GUID."; | 700 << profile_.ToDebugString() << " doesn't contain a GUID."; |
| 662 // This might be an entry of an older ChromeOS version. Assume it to be | 701 // This might be an entry of an older ChromeOS version. Assume it to be |
| 663 // unmanaged. | 702 // unmanaged. |
| 664 return; | 703 return; |
| 665 } | 704 } |
| 666 | 705 |
| 667 scoped_ptr<NetworkUIData> ui_data = GetUIData(entry_properties); | 706 scoped_ptr<NetworkUIData> ui_data = GetUIData(entry_properties); |
| 668 if (!ui_data) { | 707 if (!ui_data) { |
| 669 VLOG(1) << "Entry " << entry << " of profile " << profile_path_ | 708 VLOG(1) << "Entry " << entry << " of profile " |
| 709 << profile_.ToDebugString() | |
| 670 << " contains no or no valid UIData."; | 710 << " contains no or no valid UIData."; |
| 671 // This might be an entry of an older ChromeOS version. Assume it to be | 711 // This might be an entry of an older ChromeOS version. Assume it to be |
| 672 // unmanaged. | 712 // unmanaged. |
| 673 return; | 713 return; |
| 674 } | 714 } |
| 675 | 715 |
| 676 bool was_managed = | 716 bool was_managed = |
| 677 (ui_data->onc_source() == onc::ONC_SOURCE_DEVICE_POLICY || | 717 (ui_data->onc_source() == onc::ONC_SOURCE_DEVICE_POLICY || |
| 678 ui_data->onc_source() == onc::ONC_SOURCE_USER_POLICY); | 718 ui_data->onc_source() == onc::ONC_SOURCE_USER_POLICY); |
| 679 | 719 |
| 680 // The relevant policy must have been initialized, otherwise we hadn't Run | 720 // The relevant policy must have been initialized, otherwise we hadn't Run |
| 681 // this PolicyApplicator. | 721 // this PolicyApplicator. |
| 682 const PolicyMap& policies_by_guid = | 722 const GuidToPolicyMap& policies = |
| 683 *handler_->GetPoliciesForProfile(profile_path_); | 723 *handler_->GetPoliciesForProfile(profile_); |
| 684 | 724 |
| 685 const base::DictionaryValue* new_policy = NULL; | 725 const base::DictionaryValue* new_policy = NULL; |
| 686 if (was_managed) { | 726 if (was_managed) { |
| 687 // If we have a GUID that might match a current policy, do a lookup using | 727 // If we have a GUID that might match a current policy, do a lookup using |
| 688 // that GUID at first. In particular this is necessary, as some networks | 728 // that GUID at first. In particular this is necessary, as some networks |
| 689 // can't be matched to policies by properties (e.g. VPN). | 729 // can't be matched to policies by properties (e.g. VPN). |
| 690 PolicyMap::const_iterator it = policies_by_guid.find(old_guid); | 730 new_policy = GetByGUID(policies, old_guid); |
| 691 if (it != policies_by_guid.end()) | |
| 692 new_policy = it->second; | |
| 693 } | 731 } |
| 694 | 732 |
| 695 if (!new_policy) { | 733 if (!new_policy) { |
| 696 // If we didn't find a policy by GUID, still a new policy might match. | 734 // If we didn't find a policy by GUID, still a new policy might match. |
| 697 new_policy = FindMatchingPolicy(policies_by_guid, *onc_part); | 735 new_policy = FindMatchingPolicy(policies, *onc_part); |
| 698 } | 736 } |
| 699 | 737 |
| 700 if (new_policy) { | 738 if (new_policy) { |
| 701 std::string new_guid; | 739 std::string new_guid; |
| 702 new_policy->GetStringWithoutPathExpansion(onc::network_config::kGUID, | 740 new_policy->GetStringWithoutPathExpansion(onc::network_config::kGUID, |
| 703 &new_guid); | 741 &new_guid); |
| 704 | 742 |
| 705 VLOG_IF(1, was_managed && old_guid != new_guid) | 743 VLOG_IF(1, was_managed && old_guid != new_guid) |
| 706 << "Updating configuration previously managed by policy " << old_guid | 744 << "Updating configuration previously managed by policy " << old_guid |
| 707 << " with new policy " << new_guid << "."; | 745 << " with new policy " << new_guid << "."; |
| 708 VLOG_IF(1, !was_managed) | 746 VLOG_IF(1, !was_managed) |
| 709 << "Applying policy " << new_guid << " to previously unmanaged " | 747 << "Applying policy " << new_guid << " to previously unmanaged " |
| 710 << "configuration."; | 748 << "configuration."; |
| 711 | 749 |
| 712 if (old_guid == new_guid && | 750 if (old_guid == new_guid && |
| 713 remaining_policies_.find(new_guid) == remaining_policies_.end()) { | 751 remaining_policies_.find(new_guid) == remaining_policies_.end()) { |
| 714 VLOG(1) << "Not updating existing managed configuration with guid " | 752 VLOG(1) << "Not updating existing managed configuration with guid " |
| 715 << new_guid << " because the policy didn't change."; | 753 << new_guid << " because the policy didn't change."; |
| 716 } else { | 754 } else { |
| 717 VLOG_IF(1, old_guid == new_guid) | 755 VLOG_IF(1, old_guid == new_guid) |
| 718 << "Updating previously managed configuration with the updated " | 756 << "Updating previously managed configuration with the updated " |
| 719 << "policy " << new_guid << "."; | 757 << "policy " << new_guid << "."; |
| 720 | 758 |
| 721 // Update the existing configuration with the maybe changed | 759 // Update the existing configuration with the maybe changed |
| 722 // policy. Thereby the GUID might change. | 760 // policy. Thereby the GUID might change. |
| 723 scoped_ptr<base::DictionaryValue> shill_dictionary = | 761 scoped_ptr<base::DictionaryValue> shill_dictionary = |
| 724 CreateShillConfiguration(profile_path_, new_guid, new_policy, | 762 CreateShillConfiguration(profile_, new_guid, new_policy, |
| 725 ui_data->user_settings()); | 763 ui_data->user_settings()); |
| 726 NetworkConfigurationHandler::Get()->CreateConfiguration( | 764 NetworkConfigurationHandler::Get()->CreateConfiguration( |
| 727 *shill_dictionary, | 765 *shill_dictionary, |
| 728 base::Bind(&IgnoreString), | 766 base::Bind(&IgnoreString), |
| 729 base::Bind(&LogErrorWithDict, FROM_HERE)); | 767 base::Bind(&LogErrorWithDict, FROM_HERE)); |
| 730 remaining_policies_.erase(new_guid); | 768 remaining_policies_.erase(new_guid); |
| 731 } | 769 } |
| 732 } else if (was_managed) { | 770 } else if (was_managed) { |
| 733 VLOG(1) << "Removing configuration previously managed by policy " | 771 VLOG(1) << "Removing configuration previously managed by policy " |
| 734 << old_guid << ", because the policy was removed."; | 772 << old_guid << ", because the policy was removed."; |
| 735 | 773 |
| 736 // Remove the entry, because the network was managed but isn't anymore. | 774 // Remove the entry, because the network was managed but isn't anymore. |
| 737 // Note: An alternative might be to preserve the user settings, but it's | 775 // Note: An alternative might be to preserve the user settings, but it's |
| 738 // unclear which values originating the policy should be removed. | 776 // unclear which values originating the policy should be removed. |
| 739 DeleteEntry(entry); | 777 DeleteEntry(entry); |
| 740 } else { | 778 } else { |
| 741 VLOG(2) << "Ignore unmanaged entry."; | 779 VLOG(2) << "Ignore unmanaged entry."; |
| 742 | 780 |
| 743 // The entry wasn't managed and doesn't match any current policy. Thus | 781 // The entry wasn't managed and doesn't match any current policy. Thus |
| 744 // leave it as it is. | 782 // leave it as it is. |
| 745 } | 783 } |
| 746 } | 784 } |
| 747 | 785 |
| 748 void DeleteEntry(const std::string& entry) { | 786 void DeleteEntry(const std::string& entry) { |
| 749 DBusThreadManager::Get()->GetShillProfileClient()->DeleteEntry( | 787 DBusThreadManager::Get()->GetShillProfileClient()->DeleteEntry( |
| 750 dbus::ObjectPath(profile_path_), | 788 dbus::ObjectPath(profile_.path), |
| 751 entry, | 789 entry, |
| 752 base::Bind(&base::DoNothing), | 790 base::Bind(&base::DoNothing), |
| 753 base::Bind(&LogErrorMessage, FROM_HERE)); | 791 base::Bind(&LogErrorMessage, FROM_HERE)); |
| 754 } | 792 } |
| 755 | 793 |
| 756 virtual ~PolicyApplicator() { | 794 virtual ~PolicyApplicator() { |
| 795 if (!handler_) { | |
| 796 LOG(WARNING) << "Handler destructed during policy application to profile " | |
| 797 << profile_.ToDebugString(); | |
| 798 return; | |
| 799 } | |
| 800 | |
| 757 if (remaining_policies_.empty()) | 801 if (remaining_policies_.empty()) |
| 758 return; | 802 return; |
| 759 | 803 |
| 760 VLOG(2) << "Create new managed network configurations in profile" | 804 VLOG(2) << "Create new managed network configurations in profile" |
| 761 << profile_path_ << "."; | 805 << profile_.ToDebugString() << "."; |
| 762 // All profile entries were compared to policies. |configureGUIDs_| contains | 806 // All profile entries were compared to policies. |configureGUIDs_| contains |
| 763 // all matched policies. From the remainder of policies, new configurations | 807 // all matched policies. From the remainder of policies, new configurations |
| 764 // have to be created. | 808 // have to be created. |
| 765 | 809 |
| 766 // The relevant policy must have been initialized, otherwise we hadn't Run | 810 // The relevant policy must have been initialized, otherwise we hadn't Run |
| 767 // this PolicyApplicator. | 811 // this PolicyApplicator. |
| 768 const PolicyMap& policies_by_guid = | 812 const GuidToPolicyMap& policies = |
| 769 *handler_->GetPoliciesForProfile(profile_path_); | 813 *handler_->GetPoliciesForProfile(profile_); |
| 770 | 814 |
| 771 for (std::set<std::string>::iterator it = remaining_policies_.begin(); | 815 for (std::set<std::string>::iterator it = remaining_policies_.begin(); |
| 772 it != remaining_policies_.end(); ++it) { | 816 it != remaining_policies_.end(); ++it) { |
| 773 PolicyMap::const_iterator policy_it = policies_by_guid.find(*it); | 817 const base::DictionaryValue* policy = GetByGUID(policies, *it); |
| 774 if (policy_it == policies_by_guid.end()) { | 818 if (!policy) { |
| 775 LOG(ERROR) << "Policy " << *it << " doesn't exist anymore."; | 819 LOG(ERROR) << "Policy " << *it << " doesn't exist anymore."; |
| 776 continue; | 820 continue; |
| 777 } | 821 } |
| 778 | 822 |
| 779 const base::DictionaryValue* policy = policy_it->second; | |
| 780 | |
| 781 VLOG(1) << "Creating new configuration managed by policy " << *it | 823 VLOG(1) << "Creating new configuration managed by policy " << *it |
| 782 << " in profile " << profile_path_ << "."; | 824 << " in profile " << profile_.ToDebugString() << "."; |
| 783 | 825 |
| 784 scoped_ptr<base::DictionaryValue> shill_dictionary = | 826 scoped_ptr<base::DictionaryValue> shill_dictionary = |
| 785 CreateShillConfiguration(profile_path_, *it, policy, NULL); | 827 CreateShillConfiguration(profile_, *it, policy, |
| 828 NULL /* no user settings */); | |
| 786 NetworkConfigurationHandler::Get()->CreateConfiguration( | 829 NetworkConfigurationHandler::Get()->CreateConfiguration( |
| 787 *shill_dictionary, | 830 *shill_dictionary, |
| 788 base::Bind(&IgnoreString), | 831 base::Bind(&IgnoreString), |
| 789 base::Bind(&LogErrorWithDict, FROM_HERE)); | 832 base::Bind(&LogErrorWithDict, FROM_HERE)); |
| 790 } | 833 } |
| 791 } | 834 } |
| 792 | 835 |
| 793 std::set<std::string> remaining_policies_; | 836 std::set<std::string> remaining_policies_; |
| 794 base::WeakPtr<ManagedNetworkConfigurationHandler> handler_; | 837 base::WeakPtr<ManagedNetworkConfigurationHandler> handler_; |
| 795 std::string profile_path_; | 838 NetworkProfile profile_; |
| 796 | 839 |
| 797 DISALLOW_COPY_AND_ASSIGN(PolicyApplicator); | 840 DISALLOW_COPY_AND_ASSIGN(PolicyApplicator); |
| 798 }; | 841 }; |
| 799 | 842 |
| 800 void ManagedNetworkConfigurationHandler::SetPolicy( | 843 void ManagedNetworkConfigurationHandler::SetPolicy( |
| 801 onc::ONCSource onc_source, | 844 onc::ONCSource onc_source, |
| 845 const std::string& userhash, | |
| 802 const base::ListValue& network_configs_onc) { | 846 const base::ListValue& network_configs_onc) { |
| 803 VLOG(1) << "Setting policies for ONC source " | 847 VLOG(1) << "Setting policies from " << ToDebugString(onc_source, userhash) |
| 804 << onc::GetSourceAsString(onc_source) << "."; | 848 << "."; |
| 805 | 849 |
| 806 PolicyMap* policies; | 850 // |userhash| must be empty for device policies. |
| 807 std::string profile; | 851 DCHECK(onc_source != chromeos::onc::ONC_SOURCE_DEVICE_POLICY || |
| 808 if (onc_source == chromeos::onc::ONC_SOURCE_USER_POLICY) { | 852 userhash.empty()); |
| 809 policies = &user_policies_by_guid_; | 853 GuidToPolicyMap& policies = policies_by_user_[userhash]; |
| 810 profile = kUserProfilePath; | |
| 811 user_policies_initialized_ = true; | |
| 812 } else { | |
| 813 policies = &device_policies_by_guid_; | |
| 814 profile = kSharedProfilePath; | |
| 815 device_policies_initialized_ = true; | |
| 816 } | |
| 817 | 854 |
| 818 PolicyMap old_policies; | 855 GuidToPolicyMap old_policies; |
| 819 policies->swap(old_policies); | 856 policies.swap(old_policies); |
| 820 | 857 |
| 821 // This stores all GUIDs of policies that have changed or are new. | 858 // This stores all GUIDs of policies that have changed or are new. |
| 822 std::set<std::string> modified_policies; | 859 std::set<std::string> modified_policies; |
| 823 | 860 |
| 824 for (base::ListValue::const_iterator it = network_configs_onc.begin(); | 861 for (base::ListValue::const_iterator it = network_configs_onc.begin(); |
| 825 it != network_configs_onc.end(); ++it) { | 862 it != network_configs_onc.end(); ++it) { |
| 826 const base::DictionaryValue* network = NULL; | 863 const base::DictionaryValue* network = NULL; |
| 827 (*it)->GetAsDictionary(&network); | 864 (*it)->GetAsDictionary(&network); |
| 828 DCHECK(network); | 865 DCHECK(network); |
| 829 | 866 |
| 830 std::string guid; | 867 std::string guid; |
| 831 network->GetStringWithoutPathExpansion(onc::network_config::kGUID, &guid); | 868 network->GetStringWithoutPathExpansion(onc::network_config::kGUID, &guid); |
| 832 DCHECK(!guid.empty()); | 869 DCHECK(!guid.empty()); |
| 833 | 870 |
| 834 if (policies->count(guid) > 0) { | 871 if (policies.count(guid) > 0) { |
| 835 LOG(ERROR) << "ONC from " << onc::GetSourceAsString(onc_source) | 872 LOG(ERROR) << "ONC from " << ToDebugString(onc_source, userhash) |
| 836 << " contains several entries for the same GUID " | 873 << " contains several entries for the same GUID " |
| 837 << guid << "."; | 874 << guid << "."; |
| 838 delete (*policies)[guid]; | 875 delete policies[guid]; |
| 839 } | 876 } |
| 840 const base::DictionaryValue* new_entry = network->DeepCopy(); | 877 const base::DictionaryValue* new_entry = network->DeepCopy(); |
| 841 (*policies)[guid] = new_entry; | 878 policies[guid] = new_entry; |
| 842 | 879 |
| 843 const base::DictionaryValue* old_entry = old_policies[guid]; | 880 const base::DictionaryValue* old_entry = old_policies[guid]; |
| 844 if (!old_entry || !old_entry->Equals(new_entry)) | 881 if (!old_entry || !old_entry->Equals(new_entry)) |
| 845 modified_policies.insert(guid); | 882 modified_policies.insert(guid); |
| 846 } | 883 } |
| 847 | 884 |
| 848 STLDeleteValues(&old_policies); | 885 STLDeleteValues(&old_policies); |
| 849 | 886 |
| 887 const NetworkProfile* profile = | |
| 888 profile_handler_->GetProfileForUserhash(userhash); | |
| 889 if (!profile) { | |
| 890 VLOG(1) << "The relevant Shill profile isn't initialized yet, postponing " | |
| 891 << "policy application."; | |
| 892 return; | |
| 893 } | |
| 894 | |
| 895 scoped_refptr<PolicyApplicator> applicator = new PolicyApplicator( | |
| 896 weak_ptr_factory_.GetWeakPtr(), | |
| 897 *profile, | |
| 898 &modified_policies); | |
| 899 applicator->Run(); | |
| 900 } | |
| 901 | |
| 902 void ManagedNetworkConfigurationHandler::OnProfileAdded( | |
| 903 const NetworkProfile& profile) { | |
| 904 VLOG(1) << "Adding profile " << profile.ToDebugString() << "'."; | |
| 905 | |
| 906 const GuidToPolicyMap* policies = GetPoliciesForProfile(profile); | |
| 907 if (!policies) { | |
| 908 VLOG(1) << "The relevant policy is not initialized, " | |
| 909 << "postponing policy application."; | |
| 910 return; | |
| 911 } | |
| 912 | |
| 913 std::set<std::string> policy_guids; | |
| 914 for (GuidToPolicyMap::const_iterator it = policies->begin(); | |
| 915 it != policies->end(); ++it) { | |
| 916 policy_guids.insert(it->first); | |
| 917 } | |
| 918 | |
| 850 scoped_refptr<PolicyApplicator> applicator = new PolicyApplicator( | 919 scoped_refptr<PolicyApplicator> applicator = new PolicyApplicator( |
| 851 weak_ptr_factory_.GetWeakPtr(), | 920 weak_ptr_factory_.GetWeakPtr(), |
| 852 profile, | 921 profile, |
| 853 &modified_policies); | 922 &policy_guids); |
| 854 applicator->Run(); | 923 applicator->Run(); |
| 855 } | 924 } |
| 856 | 925 |
| 857 const ManagedNetworkConfigurationHandler::PolicyMap* | 926 void ManagedNetworkConfigurationHandler::OnProfileRemoved( |
| 858 ManagedNetworkConfigurationHandler::GetPoliciesForProfile( | 927 const NetworkProfile& profile) { |
| 859 const std::string& profile) const { | 928 // Nothing to do in this case. |
| 860 if (profile == kSharedProfilePath) { | |
| 861 if (device_policies_initialized_) | |
| 862 return &device_policies_by_guid_; | |
| 863 } else if (user_policies_initialized_) { | |
| 864 return &user_policies_by_guid_; | |
| 865 } | |
| 866 return NULL; | |
| 867 } | 929 } |
| 868 | 930 |
| 869 ManagedNetworkConfigurationHandler::ManagedNetworkConfigurationHandler() | 931 const ManagedNetworkConfigurationHandler::GuidToPolicyMap* |
| 870 : user_policies_initialized_(false), | 932 ManagedNetworkConfigurationHandler::GetPoliciesForUser( |
| 871 device_policies_initialized_(false), | 933 const std::string& userhash) const { |
| 934 UserToPoliciesMap::const_iterator it = policies_by_user_.find(userhash); | |
| 935 if (it == policies_by_user_.end()) | |
| 936 return NULL; | |
| 937 return &it->second; | |
| 938 } | |
| 939 | |
| 940 const ManagedNetworkConfigurationHandler::GuidToPolicyMap* | |
| 941 ManagedNetworkConfigurationHandler::GetPoliciesForProfile( | |
| 942 const NetworkProfile& profile) const { | |
| 943 DCHECK(profile.type() != NetworkProfile::TYPE_SHARED || | |
| 944 profile.userhash.empty()); | |
| 945 return GetPoliciesForUser(profile.userhash); | |
| 946 } | |
| 947 | |
| 948 ManagedNetworkConfigurationHandler::ManagedNetworkConfigurationHandler( | |
| 949 NetworkProfileHandler* profile_handler) | |
| 950 : profile_handler_(profile_handler), | |
| 872 weak_ptr_factory_(this) { | 951 weak_ptr_factory_(this) { |
| 952 profile_handler_->AddObserver(this); | |
| 873 } | 953 } |
| 874 | 954 |
| 875 ManagedNetworkConfigurationHandler::~ManagedNetworkConfigurationHandler() { | 955 ManagedNetworkConfigurationHandler::~ManagedNetworkConfigurationHandler() { |
| 876 STLDeleteValues(&user_policies_by_guid_); | 956 profile_handler_->RemoveObserver(this); |
| 877 STLDeleteValues(&device_policies_by_guid_); | 957 for (UserToPoliciesMap::iterator it = policies_by_user_.begin(); |
| 958 it != policies_by_user_.end(); ++it) { | |
| 959 STLDeleteValues(&it->second); | |
| 960 } | |
| 878 } | 961 } |
| 879 | 962 |
| 880 } // namespace chromeos | 963 } // namespace chromeos |
| OLD | NEW |