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
3 // found in the LICENSE file.
5 #include "components/policy/core/common/policy_loader_mac.h"
8 #include "base/bind_helpers.h"
9 #include "base/callback.h"
10 #include "base/file_util.h"
11 #include "base/mac/foundation_util.h"
12 #include "base/mac/scoped_cftyperef.h"
13 #include "base/path_service.h"
14 #include "base/platform_file.h"
15 #include "base/sequenced_task_runner.h"
16 #include "base/strings/sys_string_conversions.h"
17 #include "base/values.h"
18 #include "components/policy/core/common/external_data_fetcher.h"
19 #include "components/policy/core/common/mac_util.h"
20 #include "components/policy/core/common/policy_bundle.h"
21 #include "components/policy/core/common/policy_load_status.h"
22 #include "components/policy/core/common/policy_map.h"
23 #include "components/policy/core/common/preferences_mac.h"
24 #include "components/policy/core/common/schema.h"
25 #include "components/policy/core/common/schema_map.h"
27 using base::ScopedCFTypeRef
;
31 PolicyLoaderMac::PolicyLoaderMac(
32 scoped_refptr
<base::SequencedTaskRunner
> task_runner
,
33 const base::FilePath
& managed_policy_path
,
34 MacPreferences
* preferences
)
35 : AsyncPolicyLoader(task_runner
),
36 preferences_(preferences
),
37 managed_policy_path_(managed_policy_path
) {}
39 PolicyLoaderMac::~PolicyLoaderMac() {}
41 void PolicyLoaderMac::InitOnBackgroundThread() {
42 if (!managed_policy_path_
.empty()) {
44 managed_policy_path_
, false,
45 base::Bind(&PolicyLoaderMac::OnFileUpdated
, base::Unretained(this)));
49 scoped_ptr
<PolicyBundle
> PolicyLoaderMac::Load() {
50 preferences_
->AppSynchronize(kCFPreferencesCurrentApplication
);
51 scoped_ptr
<PolicyBundle
> bundle(new PolicyBundle());
53 // Load Chrome's policy.
54 PolicyMap
& chrome_policy
=
55 bundle
->Get(PolicyNamespace(POLICY_DOMAIN_CHROME
, std::string()));
57 PolicyLoadStatusSample status
;
58 bool policy_present
= false;
59 const Schema
* schema
=
60 schema_map()->GetSchema(PolicyNamespace(POLICY_DOMAIN_CHROME
, ""));
61 for (Schema::Iterator it
= schema
->GetPropertiesIterator();
62 !it
.IsAtEnd(); it
.Advance()) {
63 base::ScopedCFTypeRef
<CFStringRef
> name(
64 base::SysUTF8ToCFStringRef(it
.key()));
65 base::ScopedCFTypeRef
<CFPropertyListRef
> value(
66 preferences_
->CopyAppValue(name
, kCFPreferencesCurrentApplication
));
69 policy_present
= true;
71 preferences_
->AppValueIsForced(name
, kCFPreferencesCurrentApplication
);
72 PolicyLevel level
= forced
? POLICY_LEVEL_MANDATORY
:
73 POLICY_LEVEL_RECOMMENDED
;
74 // TODO(joaodasilva): figure the policy scope.
75 scoped_ptr
<base::Value
> policy
= PropertyToValue(value
);
78 it
.key(), level
, POLICY_SCOPE_USER
, policy
.release(), NULL
);
80 status
.Add(POLICY_LOAD_STATUS_PARSE_ERROR
);
85 status
.Add(POLICY_LOAD_STATUS_NO_POLICY
);
87 // Load policy for the registered components.
88 LoadPolicyForDomain(POLICY_DOMAIN_EXTENSIONS
, "extensions", bundle
.get());
93 base::Time
PolicyLoaderMac::LastModificationTime() {
94 base::File::Info file_info
;
95 if (!base::GetFileInfo(managed_policy_path_
, &file_info
) ||
96 file_info
.is_directory
) {
100 return file_info
.last_modified
;
103 void PolicyLoaderMac::LoadPolicyForDomain(
105 const std::string
& domain_name
,
106 PolicyBundle
* bundle
) {
107 std::string
id_prefix(base::mac::BaseBundleID());
108 id_prefix
.append(".").append(domain_name
).append(".");
110 const ComponentMap
* components
= schema_map()->GetComponents(domain
);
114 for (ComponentMap::const_iterator it
= components
->begin();
115 it
!= components
->end(); ++it
) {
117 LoadPolicyForComponent(id_prefix
+ it
->first
, it
->second
, &policy
);
119 bundle
->Get(PolicyNamespace(domain
, it
->first
)).Swap(&policy
);
123 void PolicyLoaderMac::LoadPolicyForComponent(
124 const std::string
& bundle_id_string
,
125 const Schema
& schema
,
127 // TODO(joaodasilva): Extensions may be registered in a ComponentMap
128 // without a schema, to allow a graceful update of the Legacy Browser Support
129 // extension on Windows. Remove this check once that support is removed.
133 base::ScopedCFTypeRef
<CFStringRef
> bundle_id(
134 base::SysUTF8ToCFStringRef(bundle_id_string
));
135 preferences_
->AppSynchronize(bundle_id
);
137 for (Schema::Iterator it
= schema
.GetPropertiesIterator();
138 !it
.IsAtEnd(); it
.Advance()) {
139 base::ScopedCFTypeRef
<CFStringRef
> pref_name(
140 base::SysUTF8ToCFStringRef(it
.key()));
141 base::ScopedCFTypeRef
<CFPropertyListRef
> value(
142 preferences_
->CopyAppValue(pref_name
, bundle_id
));
146 preferences_
->AppValueIsForced(pref_name
, bundle_id
);
147 PolicyLevel level
= forced
? POLICY_LEVEL_MANDATORY
:
148 POLICY_LEVEL_RECOMMENDED
;
149 scoped_ptr
<base::Value
> policy_value
= PropertyToValue(value
);
151 policy
->Set(it
.key(), level
, POLICY_SCOPE_USER
,
152 policy_value
.release(), NULL
);
157 void PolicyLoaderMac::OnFileUpdated(const base::FilePath
& path
, bool error
) {
162 } // namespace policy