Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(220)

Side by Side Diff: chromeos/network/managed_network_configuration_handler.cc

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

Powered by Google App Engine
This is Rietveld 408576698