OLD | NEW |
1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2014 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 "components/policy/core/common/policy_loader_win.h" | 5 #include "components/policy/core/common/policy_loader_win.h" |
6 | 6 |
7 #include <windows.h> | 7 #include <windows.h> |
8 #include <ntdsapi.h> // For Ds[Un]Bind | 8 #include <ntdsapi.h> // For Ds[Un]Bind |
9 #include <rpc.h> // For struct GUID | 9 #include <rpc.h> // For struct GUID |
10 #include <shlwapi.h> // For PathIsUNC() | 10 #include <shlwapi.h> // For PathIsUNC() |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 // Hence, | 83 // Hence, |
84 // (a) existing enumerated constants should never be deleted or reordered, and | 84 // (a) existing enumerated constants should never be deleted or reordered, and |
85 // (b) new constants should only be appended at the end of the enumeration. | 85 // (b) new constants should only be appended at the end of the enumeration. |
86 enum DomainCheckErrors { | 86 enum DomainCheckErrors { |
87 // The check error below is no longer possible. | 87 // The check error below is no longer possible. |
88 DEPRECATED_DOMAIN_CHECK_ERROR_GET_JOIN_INFO = 0, | 88 DEPRECATED_DOMAIN_CHECK_ERROR_GET_JOIN_INFO = 0, |
89 DOMAIN_CHECK_ERROR_DS_BIND = 1, | 89 DOMAIN_CHECK_ERROR_DS_BIND = 1, |
90 DOMAIN_CHECK_ERROR_SIZE, // Not a DomainCheckError. Must be last. | 90 DOMAIN_CHECK_ERROR_SIZE, // Not a DomainCheckError. Must be last. |
91 }; | 91 }; |
92 | 92 |
| 93 bool ShouldHonorPolicies() { |
| 94 return base::win::IsEnterpriseManaged(); |
| 95 } |
| 96 |
93 // Verifies that untrusted policies contain only safe values. Modifies the | 97 // Verifies that untrusted policies contain only safe values. Modifies the |
94 // |policy| in place. | 98 // |policy| in place. |
95 void FilterUntrustedPolicy(PolicyMap* policy) { | 99 void FilterUntrustedPolicy(PolicyMap* policy) { |
96 if (base::win::IsEnrolledToDomain()) | 100 if (ShouldHonorPolicies()) |
97 return; | 101 return; |
98 | 102 |
99 int invalid_policies = 0; | 103 int invalid_policies = 0; |
100 const PolicyMap::Entry* map_entry = | 104 const PolicyMap::Entry* map_entry = |
101 policy->Get(key::kExtensionInstallForcelist); | 105 policy->Get(key::kExtensionInstallForcelist); |
102 if (map_entry && map_entry->value) { | 106 if (map_entry && map_entry->value) { |
103 const base::ListValue* policy_list_value = NULL; | 107 const base::ListValue* policy_list_value = NULL; |
104 if (!map_entry->value->GetAsList(&policy_list_value)) | 108 if (!map_entry->value->GetAsList(&policy_list_value)) |
105 return; | 109 return; |
106 | 110 |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
284 } | 288 } |
285 | 289 |
286 // Collects stats about the enterprise environment that can be used to decide | 290 // Collects stats about the enterprise environment that can be used to decide |
287 // how to parse the existing policy information. | 291 // how to parse the existing policy information. |
288 void CollectEnterpriseUMAs() { | 292 void CollectEnterpriseUMAs() { |
289 // Collect statistics about the windows suite. | 293 // Collect statistics about the windows suite. |
290 UMA_HISTOGRAM_ENUMERATION("EnterpriseCheck.OSType", | 294 UMA_HISTOGRAM_ENUMERATION("EnterpriseCheck.OSType", |
291 base::win::OSInfo::GetInstance()->version_type(), | 295 base::win::OSInfo::GetInstance()->version_type(), |
292 base::win::SUITE_LAST); | 296 base::win::SUITE_LAST); |
293 | 297 |
294 bool in_domain = base::win::IsEnrolledToDomain(); | 298 UMA_HISTOGRAM_BOOLEAN("EnterpriseCheck.InDomain", |
295 UMA_HISTOGRAM_BOOLEAN("EnterpriseCheck.InDomain", in_domain); | 299 base::win::IsEnrolledToDomain()); |
| 300 UMA_HISTOGRAM_BOOLEAN("EnterpriseCheck.IsManaged", |
| 301 base::win::IsDeviceRegisteredWithManagement()); |
| 302 UMA_HISTOGRAM_BOOLEAN("EnterpriseCheck.IsEnterpriseUser", |
| 303 base::win::IsEnterpriseManaged()); |
296 } | 304 } |
297 | 305 |
298 } // namespace | 306 } // namespace |
299 | 307 |
300 const base::FilePath::CharType PolicyLoaderWin::kPRegFileName[] = | 308 const base::FilePath::CharType PolicyLoaderWin::kPRegFileName[] = |
301 FILE_PATH_LITERAL("Registry.pol"); | 309 FILE_PATH_LITERAL("Registry.pol"); |
302 | 310 |
303 PolicyLoaderWin::PolicyLoaderWin( | 311 PolicyLoaderWin::PolicyLoaderWin( |
304 scoped_refptr<base::SequencedTaskRunner> task_runner, | 312 scoped_refptr<base::SequencedTaskRunner> task_runner, |
305 const base::string16& chrome_policy_key, | 313 const base::string16& chrome_policy_key, |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
359 | 367 |
360 // Policy scope and corresponding hive. | 368 // Policy scope and corresponding hive. |
361 static const struct { | 369 static const struct { |
362 PolicyScope scope; | 370 PolicyScope scope; |
363 HKEY hive; | 371 HKEY hive; |
364 } kScopes[] = { | 372 } kScopes[] = { |
365 { POLICY_SCOPE_MACHINE, HKEY_LOCAL_MACHINE }, | 373 { POLICY_SCOPE_MACHINE, HKEY_LOCAL_MACHINE }, |
366 { POLICY_SCOPE_USER, HKEY_CURRENT_USER }, | 374 { POLICY_SCOPE_USER, HKEY_CURRENT_USER }, |
367 }; | 375 }; |
368 | 376 |
369 bool is_enterprise = base::win::IsEnrolledToDomain(); | 377 bool honor_policies = ShouldHonorPolicies(); |
370 VLOG(1) << "Reading policy from the registry is " | 378 VLOG(1) << "Reading policy from the registry is " |
371 << (is_enterprise ? "enabled." : "disabled."); | 379 << (honor_policies ? "enabled." : "disabled."); |
372 | 380 |
373 // Load policy data for the different scopes/levels and merge them. | 381 // Load policy data for the different scopes/levels and merge them. |
374 std::unique_ptr<PolicyBundle> bundle(new PolicyBundle()); | 382 std::unique_ptr<PolicyBundle> bundle(new PolicyBundle()); |
375 PolicyMap* chrome_policy = | 383 PolicyMap* chrome_policy = |
376 &bundle->Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())); | 384 &bundle->Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())); |
377 for (size_t i = 0; i < arraysize(kScopes); ++i) { | 385 for (size_t i = 0; i < arraysize(kScopes); ++i) { |
378 PolicyScope scope = kScopes[i].scope; | 386 PolicyScope scope = kScopes[i].scope; |
379 PolicyLoadStatusSample status; | 387 PolicyLoadStatusSample status; |
380 RegistryDict gpo_dict; | 388 RegistryDict gpo_dict; |
381 | 389 |
382 // Note: GPO rules mandate a call to EnterCriticalPolicySection() here, and | 390 // Note: GPO rules mandate a call to EnterCriticalPolicySection() here, and |
383 // a matching LeaveCriticalPolicySection() call below after the | 391 // a matching LeaveCriticalPolicySection() call below after the |
384 // ReadPolicyFromGPO() block. Unfortunately, the policy mutex may be | 392 // ReadPolicyFromGPO() block. Unfortunately, the policy mutex may be |
385 // unavailable for extended periods of time, and there are reports of this | 393 // unavailable for extended periods of time, and there are reports of this |
386 // happening in the wild: http://crbug.com/265862. | 394 // happening in the wild: http://crbug.com/265862. |
387 // | 395 // |
388 // Blocking for minutes is neither acceptable for Chrome startup, nor on | 396 // Blocking for minutes is neither acceptable for Chrome startup, nor on |
389 // the FILE thread on which this code runs in steady state. Given that | 397 // the FILE thread on which this code runs in steady state. Given that |
390 // there have never been any reports of issues due to partially-applied / | 398 // there have never been any reports of issues due to partially-applied / |
391 // corrupt group policy, this code intentionally omits the | 399 // corrupt group policy, this code intentionally omits the |
392 // EnterCriticalPolicySection() call. | 400 // EnterCriticalPolicySection() call. |
393 // | 401 // |
394 // If there's ever reason to revisit this decision, one option could be to | 402 // If there's ever reason to revisit this decision, one option could be to |
395 // make the EnterCriticalPolicySection() call on a dedicated thread and | 403 // make the EnterCriticalPolicySection() call on a dedicated thread and |
396 // timeout on it more aggressively. For now, there's no justification for | 404 // timeout on it more aggressively. For now, there's no justification for |
397 // the additional effort this would introduce. | 405 // the additional effort this would introduce. |
398 | 406 |
399 bool is_registry_forced = is_enterprise || gpo_provider_ == nullptr; | 407 bool is_registry_forced = honor_policies || gpo_provider_ == nullptr; |
400 if (is_registry_forced || !ReadPolicyFromGPO(scope, &gpo_dict, &status)) { | 408 if (is_registry_forced || !ReadPolicyFromGPO(scope, &gpo_dict, &status)) { |
401 VLOG_IF(1, !is_registry_forced) << "Failed to read GPO files for " | 409 VLOG_IF(1, !is_registry_forced) << "Failed to read GPO files for " |
402 << scope << " falling back to registry."; | 410 << scope << " falling back to registry."; |
403 gpo_dict.ReadRegistry(kScopes[i].hive, chrome_policy_key_); | 411 gpo_dict.ReadRegistry(kScopes[i].hive, chrome_policy_key_); |
404 } | 412 } |
405 | 413 |
406 // Remove special-cased entries from the GPO dictionary. | 414 // Remove special-cased entries from the GPO dictionary. |
407 std::unique_ptr<RegistryDict> recommended_dict( | 415 std::unique_ptr<RegistryDict> recommended_dict( |
408 gpo_dict.RemoveKey(kKeyRecommended)); | 416 gpo_dict.RemoveKey(kKeyRecommended)); |
409 std::unique_ptr<RegistryDict> third_party_dict( | 417 std::unique_ptr<RegistryDict> third_party_dict( |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
610 | 618 |
611 void PolicyLoaderWin::OnObjectSignaled(HANDLE object) { | 619 void PolicyLoaderWin::OnObjectSignaled(HANDLE object) { |
612 DCHECK(object == user_policy_changed_event_.handle() || | 620 DCHECK(object == user_policy_changed_event_.handle() || |
613 object == machine_policy_changed_event_.handle()) | 621 object == machine_policy_changed_event_.handle()) |
614 << "unexpected object signaled policy reload, obj = " | 622 << "unexpected object signaled policy reload, obj = " |
615 << std::showbase << std::hex << object; | 623 << std::showbase << std::hex << object; |
616 Reload(false); | 624 Reload(false); |
617 } | 625 } |
618 | 626 |
619 } // namespace policy | 627 } // namespace policy |
OLD | NEW |