1 // Copyright 2016 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.
4 
5 #include "chrome/browser/chromeos/policy/active_directory_policy_manager.h"
6 
7 #include <string>
8 #include <utility>
9 
10 #include "base/logging.h"
11 #include "chrome/browser/browser_process.h"
12 #include "chrome/browser/chromeos/authpolicy/authpolicy_helper.h"
13 #include "chrome/browser/chromeos/login/users/affiliation.h"
14 #include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
15 #include "chrome/browser/net/system_network_context_manager.h"
16 #include "chromeos/cryptohome/cryptohome_parameters.h"
17 #include "chromeos/dbus/login_manager/policy_descriptor.pb.h"
18 #include "chromeos/network/onc/variable_expander.h"
19 #include "components/policy/core/common/cloud/cloud_external_data_manager.h"
20 #include "components/policy/core/common/cloud/component_cloud_policy_store.h"
21 #include "components/policy/core/common/policy_bundle.h"
22 #include "components/policy/core/common/policy_namespace.h"
23 #include "components/policy/policy_constants.h"
24 #include "services/network/public/cpp/shared_url_loader_factory.h"
25 
26 namespace em = enterprise_management;
27 
28 namespace policy {
29 namespace {
30 
31 // List of policies where variables like ${MACHINE_NAME} should be expanded.
32 constexpr const char* kPoliciesToExpand[] = {key::kNativePrinters,
33                                              key::kPrinters};
34 
35 // Fetch policy every 90 minutes which matches the Windows default:
36 // https://technet.microsoft.com/en-us/library/cc940895.aspx
37 constexpr base::TimeDelta kFetchInterval = base::TimeDelta::FromMinutes(90);
38 
RunRefreshCallback(base::OnceCallback<void (bool success)> callback,authpolicy::ErrorType error)39 void RunRefreshCallback(base::OnceCallback<void(bool success)> callback,
40                         authpolicy::ErrorType error) {
41   std::move(callback).Run(error == authpolicy::ERROR_NONE);
42 }
43 
44 }  // namespace
45 
46 ActiveDirectoryPolicyManager::~ActiveDirectoryPolicyManager() = default;
47 
Init(SchemaRegistry * registry)48 void ActiveDirectoryPolicyManager::Init(SchemaRegistry* registry) {
49   ConfigurationPolicyProvider::Init(registry);
50 
51   store_->AddObserver(this);
52   if (!store_->is_initialized()) {
53     store_->Load();
54   }
55 
56   // Does nothing if |store_| hasn't yet initialized.
57   PublishPolicy();
58 
59   scheduler_ = std::make_unique<PolicyScheduler>(
60       base::BindRepeating(&ActiveDirectoryPolicyManager::DoPolicyFetch,
61                           weak_ptr_factory_.GetWeakPtr()),
62       base::BindRepeating(&ActiveDirectoryPolicyManager::OnPolicyFetched,
63                           weak_ptr_factory_.GetWeakPtr()),
64       kFetchInterval);
65 
66   if (external_data_manager_) {
67     // Use the system network context here instead of a context derived from the
68     // Profile because Connect() is called before the profile is fully
69     // initialized (required so we can perform the initial policy load).
70     // Note: The network context can be null for tests and for device policy.
71     external_data_manager_->Connect(
72         g_browser_process->system_network_context_manager()
73             ? g_browser_process->system_network_context_manager()
74                   ->GetSharedURLLoaderFactory()
75             : nullptr);
76   }
77 
78   authpolicy_helper_ = std::make_unique<chromeos::AuthPolicyHelper>();
79 }
80 
Shutdown()81 void ActiveDirectoryPolicyManager::Shutdown() {
82   if (external_data_manager_)
83     external_data_manager_->Disconnect();
84   extension_policy_service_.reset();
85   store_->RemoveObserver(this);
86   ConfigurationPolicyProvider::Shutdown();
87 }
88 
IsInitializationComplete(PolicyDomain domain) const89 bool ActiveDirectoryPolicyManager::IsInitializationComplete(
90     PolicyDomain domain) const {
91   if (domain == POLICY_DOMAIN_CHROME)
92     return store_->is_initialized();
93   if (domain == extension_policy_domain_) {
94     return extension_policy_service_ &&
95            extension_policy_service_->policy() != nullptr;
96   }
97   return true;
98 }
99 
IsFirstPolicyLoadComplete(PolicyDomain domain) const100 bool ActiveDirectoryPolicyManager::IsFirstPolicyLoadComplete(
101     PolicyDomain domain) const {
102   if (domain == POLICY_DOMAIN_CHROME)
103     return store()->first_policies_loaded();
104   if (domain == extension_policy_domain_) {
105     return extension_policy_service_ &&
106            extension_policy_service_->policy() != nullptr;
107   }
108   return true;
109 }
110 
RefreshPolicies()111 void ActiveDirectoryPolicyManager::RefreshPolicies() {
112   scheduler_->ScheduleTaskNow();
113 }
114 
OnStoreLoaded(CloudPolicyStore * cloud_policy_store)115 void ActiveDirectoryPolicyManager::OnStoreLoaded(
116     CloudPolicyStore* cloud_policy_store) {
117   DCHECK_EQ(store_.get(), cloud_policy_store);
118   PublishPolicy();
119   if (fetch_ever_completed_) {
120     // Policy is guaranteed to be up to date with the previous fetch result
121     // because OnPolicyFetched() cancels any potentially running Load()
122     // operations.
123     CancelWaitForInitialPolicy();
124   }
125 }
126 
OnStoreError(CloudPolicyStore * cloud_policy_store)127 void ActiveDirectoryPolicyManager::OnStoreError(
128     CloudPolicyStore* cloud_policy_store) {
129   DCHECK_EQ(store_.get(), cloud_policy_store);
130   // Publish policy (even though it hasn't changed) in order to signal load
131   // complete on the ConfigurationPolicyProvider interface. Technically, this is
132   // only required on the first load, but doesn't hurt in any case.
133   PublishPolicy();
134   if (fetch_ever_completed_) {
135     CancelWaitForInitialPolicy();
136   }
137 }
138 
ActiveDirectoryPolicyManager(std::unique_ptr<CloudPolicyStore> store,std::unique_ptr<CloudExternalDataManager> external_data_manager,PolicyDomain extension_policy_domain)139 ActiveDirectoryPolicyManager::ActiveDirectoryPolicyManager(
140     std::unique_ptr<CloudPolicyStore> store,
141     std::unique_ptr<CloudExternalDataManager> external_data_manager,
142     PolicyDomain extension_policy_domain)
143     : store_(std::move(store)),
144       external_data_manager_(std::move(external_data_manager)),
145       extension_policy_domain_(extension_policy_domain) {
146   DCHECK(extension_policy_domain_ == POLICY_DOMAIN_EXTENSIONS ||
147          extension_policy_domain_ == POLICY_DOMAIN_SIGNIN_EXTENSIONS);
148 }
149 
OnComponentActiveDirectoryPolicyUpdated()150 void ActiveDirectoryPolicyManager::OnComponentActiveDirectoryPolicyUpdated() {
151   PublishPolicy();
152 }
153 
PublishPolicy()154 void ActiveDirectoryPolicyManager::PublishPolicy() {
155   if (!store_->is_initialized())
156     return;
157   OnPublishPolicy();
158 
159   std::unique_ptr<PolicyBundle> bundle = std::make_unique<PolicyBundle>();
160   PolicyMap& policy_map =
161       bundle->Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()));
162   policy_map.CopyFrom(store_->policy_map());
163   if (extension_policy_service_ && extension_policy_service_->policy())
164     bundle->MergeFrom(*extension_policy_service_->policy());
165 
166   // Overwrite the source which is POLICY_SOURCE_CLOUD by default.
167   // TODO(tnagel): Rename CloudPolicyStore to PolicyStore and make the source
168   // configurable, then drop PolicyMap::SetSourceForAll().
169   policy_map.SetSourceForAll(POLICY_SOURCE_ACTIVE_DIRECTORY);
170   SetEnterpriseUsersDefaults(&policy_map);
171 
172   // Expand e.g. ${MACHINE_NAME} for a selected set of policies.
173   ExpandVariables(&policy_map);
174 
175   // Policy is ready, send it off.
176   UpdatePolicy(std::move(bundle));
177 }
178 
CreateExtensionPolicyService(PolicyScope scope,login_manager::PolicyAccountType account_type,const AccountId & account_id,SchemaRegistry * schema_registry)179 void ActiveDirectoryPolicyManager::CreateExtensionPolicyService(
180     PolicyScope scope,
181     login_manager::PolicyAccountType account_type,
182     const AccountId& account_id,
183     SchemaRegistry* schema_registry) {
184   std::string cryptohome_id;
185   if (!account_id.empty())
186     cryptohome_id = cryptohome::Identification(account_id).id();
187 
188   // Create the service for sign-in extensions (device scope) or user profile
189   // extensions (user scope).
190   DCHECK(!extension_policy_service_);
191   extension_policy_service_ =
192       std::make_unique<ComponentActiveDirectoryPolicyService>(
193           scope, extension_policy_domain_, account_type, cryptohome_id, this,
194           schema_registry);
195 }
196 
OnPolicyFetched(bool success)197 void ActiveDirectoryPolicyManager::OnPolicyFetched(bool success) {
198   fetch_ever_completed_ = true;
199   // In case of failure try to proceed with cached policy.
200   if (!success && store()->is_initialized())
201     CancelWaitForInitialPolicy();
202   // Load/retrieve independently of success or failure to keep in sync with the
203   // state in session manager. This cancels any potentially running Load()
204   // operations thus it is guaranteed that at the next OnStoreLoaded()
205   // invocation the policy is up-to-date with what was fetched.
206   store_->Load();
207   if (extension_policy_service_)
208     extension_policy_service_->RetrievePolicies();
209 }
210 
ExpandVariables(PolicyMap * policy_map)211 void ActiveDirectoryPolicyManager::ExpandVariables(PolicyMap* policy_map) {
212   const em::PolicyData* policy = store_->policy();
213   if (!policy || policy_map->empty())
214     return;
215   if (policy->machine_name().empty()) {
216     LOG(ERROR) << "Cannot expand machine_name (empty string in policy)";
217     return;
218   }
219 
220   chromeos::VariableExpander expander(
221       {{"MACHINE_NAME", policy->machine_name()}});
222   for (const char* policy_name : kPoliciesToExpand) {
223     base::Value* value = policy_map->GetMutableValue(policy_name);
224     if (value) {
225       if (!expander.ExpandValue(value)) {
226         LOG(ERROR) << "Failed to expand at least one variable in policy "
227                    << policy_name;
228       }
229     }
230   }
231 }
232 
UserActiveDirectoryPolicyManager(const AccountId & account_id,bool policy_required,base::TimeDelta initial_policy_fetch_timeout,base::OnceClosure exit_session,std::unique_ptr<CloudPolicyStore> store,std::unique_ptr<CloudExternalDataManager> external_data_manager)233 UserActiveDirectoryPolicyManager::UserActiveDirectoryPolicyManager(
234     const AccountId& account_id,
235     bool policy_required,
236     base::TimeDelta initial_policy_fetch_timeout,
237     base::OnceClosure exit_session,
238     std::unique_ptr<CloudPolicyStore> store,
239     std::unique_ptr<CloudExternalDataManager> external_data_manager)
240     : ActiveDirectoryPolicyManager(
241           std::move(store),
242           std::move(external_data_manager),
243           POLICY_DOMAIN_EXTENSIONS /* extension_policy_domain */),
244       account_id_(account_id),
245       policy_required_(policy_required),
246       waiting_for_initial_policy_fetch_(
247           !initial_policy_fetch_timeout.is_zero()),
248       exit_session_(std::move(exit_session)) {
249   DCHECK(!initial_policy_fetch_timeout.is_max());
250   // Delaying initialization complete is intended for user policy only.
251   if (waiting_for_initial_policy_fetch_) {
252     initial_policy_timeout_.Start(
253         FROM_HERE, initial_policy_fetch_timeout,
254         base::BindOnce(
255             &UserActiveDirectoryPolicyManager::OnBlockingFetchTimeout,
256             weak_ptr_factory_.GetWeakPtr()));
257   }
258 }
259 
260 UserActiveDirectoryPolicyManager::~UserActiveDirectoryPolicyManager() = default;
261 
Init(SchemaRegistry * registry)262 void UserActiveDirectoryPolicyManager::Init(SchemaRegistry* registry) {
263   DCHECK(store()->is_initialized() || waiting_for_initial_policy_fetch_ ||
264          !policy_required_ /* policy may not be required in tests */);
265   if (store()->is_initialized() && !store()->has_policy() && policy_required_) {
266     // Exit the session in case of immediate load if policy is required.
267     LOG(ERROR) << "Policy from forced immediate load could not be obtained. "
268                << "Aborting profile initialization";
269     if (exit_session_)
270       std::move(exit_session_).Run();
271   }
272   ActiveDirectoryPolicyManager::Init(registry);
273 
274   // Create the extension policy handler here. This is different from the device
275   // policy manager, which can't do this in Init() because it needs to wait for
276   // the sign-in profile's schema registry.
277   CreateExtensionPolicyService(POLICY_SCOPE_USER,
278                                login_manager::ACCOUNT_TYPE_USER, account_id_,
279                                registry);
280 }
281 
IsInitializationComplete(PolicyDomain domain) const282 bool UserActiveDirectoryPolicyManager::IsInitializationComplete(
283     PolicyDomain domain) const {
284   if (waiting_for_initial_policy_fetch_)
285     return false;
286 
287   return ActiveDirectoryPolicyManager::IsInitializationComplete(domain);
288 }
289 
ForceTimeoutForTesting()290 void UserActiveDirectoryPolicyManager::ForceTimeoutForTesting() {
291   DCHECK(initial_policy_timeout_.IsRunning());
292   // Stop the timer to mimic what happens when a real timer fires, then invoke
293   // the timer callback directly.
294   initial_policy_timeout_.Stop();
295   OnBlockingFetchTimeout();
296 }
297 
DoPolicyFetch(PolicyScheduler::TaskCallback callback)298 void UserActiveDirectoryPolicyManager::DoPolicyFetch(
299     PolicyScheduler::TaskCallback callback) {
300   authpolicy_helper()->RefreshUserPolicy(
301       account_id_, base::BindOnce(&RunRefreshCallback, std::move(callback)));
302 }
303 
CancelWaitForInitialPolicy()304 void UserActiveDirectoryPolicyManager::CancelWaitForInitialPolicy() {
305   if (!waiting_for_initial_policy_fetch_)
306     return;
307 
308   initial_policy_timeout_.Stop();
309 
310   // If the conditions to continue profile initialization are not met, the user
311   // session is exited and initialization is not set as completed.
312   if (!store()->has_policy() && policy_required_) {
313     // If there's no policy at all (not even cached), but policy is required,
314     // the user session must not continue.
315     LOG(ERROR) << "Policy could not be obtained. "
316                << "Aborting profile initialization";
317     if (exit_session_)
318       std::move(exit_session_).Run();
319     return;
320   }
321 
322   // Set initialization complete.
323   waiting_for_initial_policy_fetch_ = false;
324 
325   // Publish policy (even though it hasn't changed) in order to signal load
326   // complete on the ConfigurationPolicyProvider interface.
327   PublishPolicy();
328 }
329 
OnPublishPolicy()330 void UserActiveDirectoryPolicyManager::OnPublishPolicy() {
331   const em::PolicyData* policy_data = store()->policy();
332   if (!policy_data)
333     return;
334 
335   // Update user affiliation IDs.
336   chromeos::AffiliationIDSet set_of_user_affiliation_ids(
337       policy_data->user_affiliation_ids().begin(),
338       policy_data->user_affiliation_ids().end());
339 
340   chromeos::ChromeUserManager::Get()->SetUserAffiliation(
341       account_id_, set_of_user_affiliation_ids);
342 }
343 
OnBlockingFetchTimeout()344 void UserActiveDirectoryPolicyManager::OnBlockingFetchTimeout() {
345   DCHECK(waiting_for_initial_policy_fetch_);
346   LOG(WARNING) << "Timed out while waiting for the policy fetch. "
347                << "The session will start with the cached policy.";
348   if ((fetch_ever_completed_ && !store()->is_initialized()) ||
349       (!fetch_ever_completed_ && !store()->has_policy())) {
350     // Waiting for store to load if policy was fetched. Or for policy fetch to
351     // complete if there is no cached policy.
352     return;
353   }
354   CancelWaitForInitialPolicy();
355 }
356 
DeviceActiveDirectoryPolicyManager(std::unique_ptr<CloudPolicyStore> store)357 DeviceActiveDirectoryPolicyManager::DeviceActiveDirectoryPolicyManager(
358     std::unique_ptr<CloudPolicyStore> store)
359     : ActiveDirectoryPolicyManager(
360           std::move(store),
361           nullptr /* external_data_manager */,
362           POLICY_DOMAIN_SIGNIN_EXTENSIONS /* extension_policy_domain */) {}
363 
Shutdown()364 void DeviceActiveDirectoryPolicyManager::Shutdown() {
365   ActiveDirectoryPolicyManager::Shutdown();
366   signin_profile_forwarding_schema_registry_.reset();
367 }
368 
SetSigninProfileSchemaRegistry(SchemaRegistry * schema_registry)369 void DeviceActiveDirectoryPolicyManager::SetSigninProfileSchemaRegistry(
370     SchemaRegistry* schema_registry) {
371   DCHECK(!signin_profile_forwarding_schema_registry_);
372   signin_profile_forwarding_schema_registry_ =
373       std::make_unique<ForwardingSchemaRegistry>(schema_registry);
374 
375   CreateExtensionPolicyService(
376       POLICY_SCOPE_MACHINE, login_manager::ACCOUNT_TYPE_DEVICE,
377       EmptyAccountId(), signin_profile_forwarding_schema_registry_.get());
378 }
379 
380 DeviceActiveDirectoryPolicyManager::~DeviceActiveDirectoryPolicyManager() =
381     default;
382 
DoPolicyFetch(base::OnceCallback<void (bool success)> callback)383 void DeviceActiveDirectoryPolicyManager::DoPolicyFetch(
384     base::OnceCallback<void(bool success)> callback) {
385   authpolicy_helper()->RefreshDevicePolicy(
386       base::BindOnce(&RunRefreshCallback, std::move(callback)));
387 }
388 
389 }  // namespace policy
390