OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 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/policy_applicator.h" | 5 #include "chromeos/network/policy_applicator.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/location.h" | 10 #include "base/location.h" |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
165 << "configuration."; | 165 << "configuration."; |
166 | 166 |
167 if (old_guid == new_guid && | 167 if (old_guid == new_guid && |
168 remaining_policies_.find(new_guid) == remaining_policies_.end()) { | 168 remaining_policies_.find(new_guid) == remaining_policies_.end()) { |
169 VLOG(1) << "Not updating existing managed configuration with guid " | 169 VLOG(1) << "Not updating existing managed configuration with guid " |
170 << new_guid << " because the policy didn't change."; | 170 << new_guid << " because the policy didn't change."; |
171 } else { | 171 } else { |
172 const base::DictionaryValue* user_settings = | 172 const base::DictionaryValue* user_settings = |
173 ui_data ? ui_data->user_settings() : NULL; | 173 ui_data ? ui_data->user_settings() : NULL; |
174 scoped_ptr<base::DictionaryValue> new_shill_properties = | 174 scoped_ptr<base::DictionaryValue> new_shill_properties = |
175 policy_util::CreateShillConfiguration( | 175 policy_util::CreateShillConfiguration(profile_, |
176 profile_, new_guid, new_policy, user_settings); | 176 new_guid, |
| 177 &global_network_config_, |
| 178 new_policy, |
| 179 user_settings); |
177 // A new policy has to be applied to this profile entry. In order to keep | 180 // A new policy has to be applied to this profile entry. In order to keep |
178 // implicit state of Shill like "connected successfully before", keep the | 181 // implicit state of Shill like "connected successfully before", keep the |
179 // entry if a policy is reapplied (e.g. after reboot) or is updated. | 182 // entry if a policy is reapplied (e.g. after reboot) or is updated. |
180 // However, some Shill properties are used to identify the network and | 183 // However, some Shill properties are used to identify the network and |
181 // cannot be modified after initial configuration, so we have to delete | 184 // cannot be modified after initial configuration, so we have to delete |
182 // the profile entry in these cases. Also, keeping Shill's state if the | 185 // the profile entry in these cases. Also, keeping Shill's state if the |
183 // SSID changed might not be a good idea anyways. If the policy GUID | 186 // SSID changed might not be a good idea anyways. If the policy GUID |
184 // changed, or there was no policy before, we delete the entry at first to | 187 // changed, or there was no policy before, we delete the entry at first to |
185 // ensure that no old configuration remains. | 188 // ensure that no old configuration remains. |
186 if (old_guid == new_guid && | 189 if (old_guid == new_guid && |
(...skipping 10 matching lines...) Expand all Loading... |
197 // In general, old entries should at first be deleted before new | 200 // In general, old entries should at first be deleted before new |
198 // configurations are written to prevent inconsistencies. Therefore, we | 201 // configurations are written to prevent inconsistencies. Therefore, we |
199 // delay the writing of the new config here until ~PolicyApplicator. | 202 // delay the writing of the new config here until ~PolicyApplicator. |
200 // E.g. one problematic case is if a policy { {GUID=X, SSID=Y} } is | 203 // E.g. one problematic case is if a policy { {GUID=X, SSID=Y} } is |
201 // applied to the profile entries | 204 // applied to the profile entries |
202 // { ENTRY1 = {GUID=X, SSID=X, USER_SETTINGS=X}, | 205 // { ENTRY1 = {GUID=X, SSID=X, USER_SETTINGS=X}, |
203 // ENTRY2 = {SSID=Y, ... } }. | 206 // ENTRY2 = {SSID=Y, ... } }. |
204 // At first ENTRY1 and ENTRY2 should be removed, then the new config be | 207 // At first ENTRY1 and ENTRY2 should be removed, then the new config be |
205 // written and the result should be: | 208 // written and the result should be: |
206 // { {GUID=X, SSID=Y, USER_SETTINGS=X} } | 209 // { {GUID=X, SSID=Y, USER_SETTINGS=X} } |
207 WriteNewShillConfiguration(*new_shill_properties, *new_policy, true); | 210 WriteNewShillConfiguration( |
| 211 *new_shill_properties, *new_policy, true /* write later */); |
208 remaining_policies_.erase(new_guid); | 212 remaining_policies_.erase(new_guid); |
209 } | 213 } |
210 } else if (was_managed) { | 214 } else if (was_managed) { |
211 VLOG(1) << "Removing configuration previously managed by policy " | 215 VLOG(1) << "Removing configuration previously managed by policy " |
212 << old_guid << ", because the policy was removed."; | 216 << old_guid << ", because the policy was removed."; |
213 | 217 |
214 // Remove the entry, because the network was managed but isn't anymore. | 218 // Remove the entry, because the network was managed but isn't anymore. |
215 // Note: An alternative might be to preserve the user settings, but it's | 219 // Note: An alternative might be to preserve the user settings, but it's |
216 // unclear which values originating the policy should be removed. | 220 // unclear which values originating the policy should be removed. |
217 DeleteEntry(entry); | 221 DeleteEntry(entry); |
218 } else { | 222 } else { |
219 // The entry wasn't managed and doesn't match any current policy. Global | 223 // The entry wasn't managed and doesn't match any current policy. Global |
220 // network settings have to be applied. | 224 // network settings have to be applied. |
221 base::DictionaryValue shill_properties_to_update; | 225 base::DictionaryValue shill_properties_to_update; |
222 GetPropertiesForUnmanagedEntry(entry_properties, | 226 policy_util::SetShillPropertiesForGlobalPolicy( |
223 &shill_properties_to_update); | 227 entry_properties, global_network_config_, &shill_properties_to_update); |
224 if (shill_properties_to_update.empty()) { | 228 if (shill_properties_to_update.empty()) { |
225 VLOG(2) << "Ignore unmanaged entry."; | 229 VLOG(2) << "Ignore unmanaged entry."; |
226 // Calling a SetProperties of Shill with an empty dictionary is a no op. | 230 // Calling a SetProperties of Shill with an empty dictionary is a no op. |
227 } else { | 231 } else { |
228 VLOG(2) << "Apply global network config to unmanaged entry."; | 232 VLOG(2) << "Apply global network config to unmanaged entry."; |
229 handler_->UpdateExistingConfigurationWithPropertiesFromPolicy( | 233 handler_->UpdateExistingConfigurationWithPropertiesFromPolicy( |
230 entry_properties, shill_properties_to_update); | 234 entry_properties, shill_properties_to_update); |
231 } | 235 } |
232 } | 236 } |
233 } | 237 } |
(...skipping 25 matching lines...) Expand all Loading... |
259 if (auth == ::onc::ethernet::kAuthenticationNone) | 263 if (auth == ::onc::ethernet::kAuthenticationNone) |
260 return; | 264 return; |
261 } | 265 } |
262 | 266 |
263 if (write_later) | 267 if (write_later) |
264 new_shill_configurations_.push_back(shill_dictionary.DeepCopy()); | 268 new_shill_configurations_.push_back(shill_dictionary.DeepCopy()); |
265 else | 269 else |
266 handler_->CreateConfigurationFromPolicy(shill_dictionary); | 270 handler_->CreateConfigurationFromPolicy(shill_dictionary); |
267 } | 271 } |
268 | 272 |
269 void PolicyApplicator::GetPropertiesForUnmanagedEntry( | |
270 const base::DictionaryValue& entry_properties, | |
271 base::DictionaryValue* properties_to_update) const { | |
272 // kAllowOnlyPolicyNetworksToAutoconnect is currently the only global config. | |
273 | |
274 std::string type; | |
275 entry_properties.GetStringWithoutPathExpansion(shill::kTypeProperty, &type); | |
276 if (NetworkTypePattern::Ethernet().MatchesType(type)) | |
277 return; // Autoconnect for Ethernet cannot be configured. | |
278 | |
279 // By default all networks are allowed to autoconnect. | |
280 bool only_policy_autoconnect = false; | |
281 global_network_config_.GetBooleanWithoutPathExpansion( | |
282 ::onc::global_network_config::kAllowOnlyPolicyNetworksToAutoconnect, | |
283 &only_policy_autoconnect); | |
284 if (!only_policy_autoconnect) | |
285 return; | |
286 | |
287 bool old_autoconnect = false; | |
288 if (entry_properties.GetBooleanWithoutPathExpansion( | |
289 shill::kAutoConnectProperty, &old_autoconnect) && | |
290 !old_autoconnect) { | |
291 // Autoconnect is already explictly disabled. No need to set it again. | |
292 return; | |
293 } | |
294 // If autconnect is not explicitly set yet, it might automatically be enabled | |
295 // by Shill. To prevent that, disable it explicitly. | |
296 properties_to_update->SetBooleanWithoutPathExpansion( | |
297 shill::kAutoConnectProperty, false); | |
298 } | |
299 | |
300 PolicyApplicator::~PolicyApplicator() { | 273 PolicyApplicator::~PolicyApplicator() { |
301 ApplyRemainingPolicies(); | 274 ApplyRemainingPolicies(); |
302 STLDeleteValues(&all_policies_); | 275 STLDeleteValues(&all_policies_); |
303 // Notify the handler about all policies being applied, so that the network | 276 // Notify the handler about all policies being applied, so that the network |
304 // lists can be updated. | 277 // lists can be updated. |
305 if (handler_) | 278 if (handler_) |
306 handler_->OnPoliciesApplied(); | 279 handler_->OnPoliciesApplied(); |
307 } | 280 } |
308 | 281 |
309 void PolicyApplicator::ApplyRemainingPolicies() { | 282 void PolicyApplicator::ApplyRemainingPolicies() { |
(...skipping 14 matching lines...) Expand all Loading... |
324 if (remaining_policies_.empty()) | 297 if (remaining_policies_.empty()) |
325 return; | 298 return; |
326 | 299 |
327 VLOG(2) << "Create new managed network configurations in profile" | 300 VLOG(2) << "Create new managed network configurations in profile" |
328 << profile_.ToDebugString() << "."; | 301 << profile_.ToDebugString() << "."; |
329 // All profile entries were compared to policies. |remaining_policies_| | 302 // All profile entries were compared to policies. |remaining_policies_| |
330 // contains all modified policies that didn't match any entry. For these | 303 // contains all modified policies that didn't match any entry. For these |
331 // remaining policies, new configurations have to be created. | 304 // remaining policies, new configurations have to be created. |
332 for (std::set<std::string>::iterator it = remaining_policies_.begin(); | 305 for (std::set<std::string>::iterator it = remaining_policies_.begin(); |
333 it != remaining_policies_.end(); ++it) { | 306 it != remaining_policies_.end(); ++it) { |
334 const base::DictionaryValue* policy = GetByGUID(all_policies_, *it); | 307 const base::DictionaryValue* network_policy = GetByGUID(all_policies_, *it); |
335 DCHECK(policy); | 308 DCHECK(network_policy); |
336 | 309 |
337 VLOG(1) << "Creating new configuration managed by policy " << *it | 310 VLOG(1) << "Creating new configuration managed by policy " << *it |
338 << " in profile " << profile_.ToDebugString() << "."; | 311 << " in profile " << profile_.ToDebugString() << "."; |
339 | 312 |
340 scoped_ptr<base::DictionaryValue> shill_dictionary = | 313 scoped_ptr<base::DictionaryValue> shill_dictionary = |
341 policy_util::CreateShillConfiguration( | 314 policy_util::CreateShillConfiguration(profile_, |
342 profile_, *it, policy, NULL /* no user settings */); | 315 *it, |
343 WriteNewShillConfiguration(*shill_dictionary, *policy, false); | 316 &global_network_config_, |
| 317 network_policy, |
| 318 NULL /* no user settings */); |
| 319 WriteNewShillConfiguration( |
| 320 *shill_dictionary, *network_policy, false /* write now */); |
344 } | 321 } |
345 } | 322 } |
346 | 323 |
347 } // namespace chromeos | 324 } // namespace chromeos |
OLD | NEW |