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

Side by Side Diff: chrome/browser/policy/policy_loader_win.cc

Issue 14294008: Add UMA histograms for policy loading. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 8 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) 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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698