OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "chrome/browser/policy/policy_loader_win.h" | 5 #include "chrome/browser/policy/policy_loader_win.h" |
6 | 6 |
7 #include <rpc.h> // For struct GUID | 7 #include <rpc.h> // For struct GUID |
8 #include <shlwapi.h> // For PathIsUNC() | 8 #include <shlwapi.h> // For PathIsUNC() |
9 #include <userenv.h> // For GPO functions | 9 #include <userenv.h> // For GPO functions |
10 #include <windows.h> | 10 #include <windows.h> |
(...skipping 13 matching lines...) Expand all Loading... | |
24 #include "base/logging.h" | 24 #include "base/logging.h" |
25 #include "base/scoped_native_library.h" | 25 #include "base/scoped_native_library.h" |
26 #include "base/stl_util.h" | 26 #include "base/stl_util.h" |
27 #include "base/string16.h" | 27 #include "base/string16.h" |
28 #include "base/string_util.h" | 28 #include "base/string_util.h" |
29 #include "base/strings/string_number_conversions.h" | 29 #include "base/strings/string_number_conversions.h" |
30 #include "base/sys_byteorder.h" | 30 #include "base/sys_byteorder.h" |
31 #include "base/utf_string_conversions.h" | 31 #include "base/utf_string_conversions.h" |
32 #include "base/win/registry.h" | 32 #include "base/win/registry.h" |
33 #include "chrome/browser/policy/policy_bundle.h" | 33 #include "chrome/browser/policy/policy_bundle.h" |
34 #include "chrome/browser/policy/policy_load_status.h" | |
34 #include "chrome/browser/policy/policy_map.h" | 35 #include "chrome/browser/policy/policy_map.h" |
35 #include "chrome/browser/policy/preg_parser_win.h" | 36 #include "chrome/browser/policy/preg_parser_win.h" |
36 #include "chrome/common/json_schema/json_schema_constants.h" | 37 #include "chrome/common/json_schema/json_schema_constants.h" |
37 #include "policy/policy_constants.h" | 38 #include "policy/policy_constants.h" |
38 | 39 |
39 namespace schema = json_schema_constants; | 40 namespace schema = json_schema_constants; |
40 | 41 |
41 using base::win::RegKey; | 42 using base::win::RegKey; |
42 using base::win::RegistryKeyIterator; | 43 using base::win::RegistryKeyIterator; |
43 using base::win::RegistryValueIterator; | 44 using base::win::RegistryValueIterator; |
(...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
503 { POLICY_SCOPE_MACHINE, HKEY_LOCAL_MACHINE }, | 504 { POLICY_SCOPE_MACHINE, HKEY_LOCAL_MACHINE }, |
504 { POLICY_SCOPE_USER, HKEY_CURRENT_USER }, | 505 { POLICY_SCOPE_USER, HKEY_CURRENT_USER }, |
505 }; | 506 }; |
506 | 507 |
507 // Load policy data for the different scopes/levels and merge them. | 508 // Load policy data for the different scopes/levels and merge them. |
508 scoped_ptr<PolicyBundle> bundle(new PolicyBundle()); | 509 scoped_ptr<PolicyBundle> bundle(new PolicyBundle()); |
509 PolicyMap* chrome_policy = | 510 PolicyMap* chrome_policy = |
510 &bundle->Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())); | 511 &bundle->Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())); |
511 for (size_t i = 0; i < arraysize(kScopes); ++i) { | 512 for (size_t i = 0; i < arraysize(kScopes); ++i) { |
512 PolicyScope scope = kScopes[i].scope; | 513 PolicyScope scope = kScopes[i].scope; |
514 PolicyLoadStatusSample status(scope, -1); | |
513 base::DictionaryValue gpo_dict; | 515 base::DictionaryValue gpo_dict; |
514 | 516 |
515 HANDLE policy_lock = | 517 HANDLE policy_lock = |
516 EnterCriticalPolicySection(scope == POLICY_SCOPE_MACHINE); | 518 EnterCriticalPolicySection(scope == POLICY_SCOPE_MACHINE); |
517 if (policy_lock == NULL) | 519 if (policy_lock == NULL) |
518 PLOG(ERROR) << "EnterCriticalPolicySection"; | 520 PLOG(ERROR) << "EnterCriticalPolicySection"; |
519 | 521 |
520 if (!ReadPolicyFromGPO(scope, &gpo_dict)) { | 522 if (!ReadPolicyFromGPO(scope, &gpo_dict, &status)) { |
521 VLOG(1) << "Failed to read GPO files for " << scope | 523 VLOG(1) << "Failed to read GPO files for " << scope |
522 << " falling back to registry."; | 524 << " falling back to registry."; |
523 ReadRegistry(kScopes[i].hive, chrome_policy_key_, &gpo_dict); | 525 ReadRegistry(kScopes[i].hive, chrome_policy_key_, &gpo_dict); |
Joao da Silva
2013/04/16 17:31:04
No sampling for this case?
Mattias Nissler (ping if slow)
2013/04/16 18:51:14
It's all good! :)
Assuming ReadPolicyFromGPO samp
| |
524 } | 526 } |
525 | 527 |
526 if (!LeaveCriticalPolicySection(policy_lock)) | 528 if (!LeaveCriticalPolicySection(policy_lock)) |
527 PLOG(ERROR) << "LeaveCriticalPolicySection"; | 529 PLOG(ERROR) << "LeaveCriticalPolicySection"; |
528 | 530 |
529 // Remove special-cased entries from the GPO dictionary. | 531 // Remove special-cased entries from the GPO dictionary. |
530 base::DictionaryValue* temp_dict = NULL; | 532 base::DictionaryValue* temp_dict = NULL; |
531 scoped_ptr<base::DictionaryValue> recommended_dict( | 533 scoped_ptr<base::DictionaryValue> recommended_dict( |
532 RemoveDict(&gpo_dict, kKeyRecommended)); | 534 RemoveDict(&gpo_dict, kKeyRecommended)); |
533 scoped_ptr<base::DictionaryValue> third_party_dict( | 535 scoped_ptr<base::DictionaryValue> third_party_dict( |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
565 } | 567 } |
566 properties->SetWithoutPathExpansion(e->name, entry_schema.release()); | 568 properties->SetWithoutPathExpansion(e->name, entry_schema.release()); |
567 } | 569 } |
568 chrome_policy_schema_.SetStringWithoutPathExpansion( | 570 chrome_policy_schema_.SetStringWithoutPathExpansion( |
569 json_schema_constants::kType, json_schema_constants::kObject); | 571 json_schema_constants::kType, json_schema_constants::kObject); |
570 chrome_policy_schema_.SetWithoutPathExpansion( | 572 chrome_policy_schema_.SetWithoutPathExpansion( |
571 json_schema_constants::kProperties, properties.release()); | 573 json_schema_constants::kProperties, properties.release()); |
572 } | 574 } |
573 | 575 |
574 bool PolicyLoaderWin::ReadPRegFile(const base::FilePath& preg_file, | 576 bool PolicyLoaderWin::ReadPRegFile(const base::FilePath& preg_file, |
575 base::DictionaryValue* policy) { | 577 base::DictionaryValue* policy, |
578 PolicyLoadStatusSample* status) { | |
576 // The following deals with the minor annoyance that Wow64 FS redirection | 579 // The following deals with the minor annoyance that Wow64 FS redirection |
577 // might need to be turned off: This is the case if running as a 32-bit | 580 // might need to be turned off: This is the case if running as a 32-bit |
578 // process on a 64-bit system, in which case Wow64 FS redirection redirects | 581 // process on a 64-bit system, in which case Wow64 FS redirection redirects |
579 // access to the %WINDIR%/System32/GroupPolicy directory to | 582 // access to the %WINDIR%/System32/GroupPolicy directory to |
580 // %WINDIR%/SysWOW64/GroupPolicy, but the file is actually in the | 583 // %WINDIR%/SysWOW64/GroupPolicy, but the file is actually in the |
581 // system-native directory. | 584 // system-native directory. |
582 if (file_util::PathExists(preg_file)) { | 585 if (file_util::PathExists(preg_file)) { |
583 return preg_parser::ReadFile(preg_file, chrome_policy_key_, policy); | 586 return preg_parser::ReadFile(preg_file, chrome_policy_key_, policy, status); |
584 } else { | 587 } else { |
585 // Try with redirection switched off. | 588 // Try with redirection switched off. |
586 ScopedDisableWow64Redirection redirection_disable; | 589 ScopedDisableWow64Redirection redirection_disable; |
587 if (redirection_disable.is_active() && file_util::PathExists(preg_file)) | 590 if (redirection_disable.is_active() && file_util::PathExists(preg_file)) { |
588 return preg_parser::ReadFile(preg_file, chrome_policy_key_, policy); | 591 status->Add(POLICY_LOAD_STATUS_WOW64_REDIRECTION_DISABLED); |
592 return preg_parser::ReadFile(preg_file, chrome_policy_key_, policy, | |
593 status); | |
594 } | |
589 } | 595 } |
590 | 596 |
591 // Report the error. | 597 // Report the error. |
592 LOG(ERROR) << "PReg file doesn't exist: " << preg_file.value(); | 598 LOG(ERROR) << "PReg file doesn't exist: " << preg_file.value(); |
599 status->Add(POLICY_LOAD_STATUS_MISSING); | |
593 return false; | 600 return false; |
594 } | 601 } |
595 | 602 |
596 bool PolicyLoaderWin::LoadGPOPolicy(PolicyScope scope, | 603 bool PolicyLoaderWin::LoadGPOPolicy(PolicyScope scope, |
597 PGROUP_POLICY_OBJECT policy_object_list, | 604 PGROUP_POLICY_OBJECT policy_object_list, |
598 base::DictionaryValue* policy) { | 605 base::DictionaryValue* policy, |
606 PolicyLoadStatusSample* status) { | |
599 base::DictionaryValue parsed_policy; | 607 base::DictionaryValue parsed_policy; |
600 base::DictionaryValue forced_policy; | 608 base::DictionaryValue forced_policy; |
601 for (GROUP_POLICY_OBJECT* policy_object = policy_object_list; | 609 for (GROUP_POLICY_OBJECT* policy_object = policy_object_list; |
602 policy_object; policy_object = policy_object->pNext) { | 610 policy_object; policy_object = policy_object->pNext) { |
603 if (policy_object->dwOptions & GPO_FLAG_DISABLE) | 611 if (policy_object->dwOptions & GPO_FLAG_DISABLE) |
604 continue; | 612 continue; |
605 | 613 |
606 if (PathIsUNC(policy_object->lpFileSysPath)) { | 614 if (PathIsUNC(policy_object->lpFileSysPath)) { |
607 // UNC path: Assume this is an AD-managed machine, which updates the | 615 // UNC path: Assume this is an AD-managed machine, which updates the |
608 // registry via GPO's standard registry CSE periodically. Fall back to | 616 // registry via GPO's standard registry CSE periodically. Fall back to |
609 // reading from the registry in this case. | 617 // reading from the registry in this case. |
618 status->Add(POLICY_LOAD_STATUS_INACCCESSIBLE); | |
610 return false; | 619 return false; |
611 } | 620 } |
612 | 621 |
613 base::FilePath preg_file_path( | 622 base::FilePath preg_file_path( |
614 base::FilePath(policy_object->lpFileSysPath).Append(kPRegFileName)); | 623 base::FilePath(policy_object->lpFileSysPath).Append(kPRegFileName)); |
615 if (policy_object->dwOptions & GPO_FLAG_FORCE) { | 624 if (policy_object->dwOptions & GPO_FLAG_FORCE) { |
616 base::DictionaryValue new_forced_policy; | 625 base::DictionaryValue new_forced_policy; |
617 if (!ReadPRegFile(preg_file_path, &new_forced_policy)) | 626 if (!ReadPRegFile(preg_file_path, &new_forced_policy, status)) |
618 return false; | 627 return false; |
619 | 628 |
620 // Merge with existing forced policy, giving precedence to the existing | 629 // Merge with existing forced policy, giving precedence to the existing |
621 // forced policy. | 630 // forced policy. |
622 new_forced_policy.MergeDictionary(&forced_policy); | 631 new_forced_policy.MergeDictionary(&forced_policy); |
623 forced_policy.Swap(&new_forced_policy); | 632 forced_policy.Swap(&new_forced_policy); |
624 } else { | 633 } else { |
625 if (!ReadPRegFile(preg_file_path, &parsed_policy)) | 634 if (!ReadPRegFile(preg_file_path, &parsed_policy, status)) |
626 return false; | 635 return false; |
627 } | 636 } |
628 } | 637 } |
629 | 638 |
630 // Merge, give precedence to forced policy. | 639 // Merge, give precedence to forced policy. |
631 parsed_policy.MergeDictionary(&forced_policy); | 640 parsed_policy.MergeDictionary(&forced_policy); |
632 policy->Swap(&parsed_policy); | 641 policy->Swap(&parsed_policy); |
633 | 642 |
634 return true; | 643 return true; |
635 } | 644 } |
636 | 645 |
637 | 646 |
638 bool PolicyLoaderWin::ReadPolicyFromGPO(PolicyScope scope, | 647 bool PolicyLoaderWin::ReadPolicyFromGPO(PolicyScope scope, |
639 base::DictionaryValue* policy) { | 648 base::DictionaryValue* policy, |
649 PolicyLoadStatusSample* status) { | |
640 PGROUP_POLICY_OBJECT policy_object_list = NULL; | 650 PGROUP_POLICY_OBJECT policy_object_list = NULL; |
641 DWORD flags = scope == POLICY_SCOPE_MACHINE ? GPO_LIST_FLAG_MACHINE : 0; | 651 DWORD flags = scope == POLICY_SCOPE_MACHINE ? GPO_LIST_FLAG_MACHINE : 0; |
642 if (gpo_provider_->GetAppliedGPOList( | 652 if (gpo_provider_->GetAppliedGPOList( |
643 flags, NULL, NULL, &kRegistrySettingsCSEGUID, | 653 flags, NULL, NULL, &kRegistrySettingsCSEGUID, |
644 &policy_object_list) != ERROR_SUCCESS) { | 654 &policy_object_list) != ERROR_SUCCESS) { |
645 PLOG(ERROR) << "GetAppliedGPOList scope " << scope; | 655 PLOG(ERROR) << "GetAppliedGPOList scope " << scope; |
656 status->Add(POLICY_LOAD_STATUS_QUERY_FAILED); | |
646 return false; | 657 return false; |
647 } | 658 } |
648 | 659 |
649 bool result = LoadGPOPolicy(scope, policy_object_list, policy); | 660 bool result = true; |
650 if (!gpo_provider_->FreeGPOList(policy_object_list)) | 661 if (policy_object_list) { |
651 LOG(WARNING) << "FreeGPOList"; | 662 result = LoadGPOPolicy(scope, policy_object_list, policy, status); |
663 if (!gpo_provider_->FreeGPOList(policy_object_list)) | |
664 LOG(WARNING) << "FreeGPOList"; | |
665 } else { | |
666 status->Add(POLICY_LOAD_STATUS_NO_POLICY); | |
667 } | |
652 | 668 |
653 return result; | 669 return result; |
654 } | 670 } |
655 | 671 |
656 void PolicyLoaderWin::LoadChromePolicy(const base::DictionaryValue* gpo_dict, | 672 void PolicyLoaderWin::LoadChromePolicy(const base::DictionaryValue* gpo_dict, |
657 PolicyLevel level, | 673 PolicyLevel level, |
658 PolicyScope scope, | 674 PolicyScope scope, |
659 PolicyMap* chrome_policy_map) { | 675 PolicyMap* chrome_policy_map) { |
660 PolicyMap policy; | 676 PolicyMap policy; |
661 ParsePolicy(gpo_dict, level, scope, &chrome_policy_schema_, &policy); | 677 ParsePolicy(gpo_dict, level, scope, &chrome_policy_schema_, &policy); |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
751 | 767 |
752 void PolicyLoaderWin::OnObjectSignaled(HANDLE object) { | 768 void PolicyLoaderWin::OnObjectSignaled(HANDLE object) { |
753 DCHECK(object == user_policy_changed_event_.handle() || | 769 DCHECK(object == user_policy_changed_event_.handle() || |
754 object == machine_policy_changed_event_.handle()) | 770 object == machine_policy_changed_event_.handle()) |
755 << "unexpected object signaled policy reload, obj = " | 771 << "unexpected object signaled policy reload, obj = " |
756 << std::showbase << std::hex << object; | 772 << std::showbase << std::hex << object; |
757 Reload(false); | 773 Reload(false); |
758 } | 774 } |
759 | 775 |
760 } // namespace policy | 776 } // namespace policy |
OLD | NEW |