1 // Copyright 2019 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/user_policy_manager_builder_chromeos.h"
6 
7 #include <utility>
8 
9 #include "base/bind.h"
10 #include "base/command_line.h"
11 #include "base/feature_list.h"
12 #include "base/files/file_path.h"
13 #include "base/logging.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/metrics/histogram_functions.h"
16 #include "base/metrics/histogram_macros.h"
17 #include "base/path_service.h"
18 #include "base/sequenced_task_runner.h"
19 #include "base/task/post_task.h"
20 #include "base/task/thread_pool.h"
21 #include "base/threading/thread_task_runner_handle.h"
22 #include "base/time/time.h"
23 #include "chrome/browser/browser_process.h"
24 #include "chrome/browser/browser_process_platform_part.h"
25 #include "chrome/browser/chromeos/policy/active_directory_policy_manager.h"
26 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
27 #include "chrome/browser/chromeos/policy/user_cloud_external_data_manager.h"
28 #include "chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.h"
29 #include "chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos.h"
30 #include "chrome/browser/chromeos/profiles/profile_helper.h"
31 #include "chrome/browser/chromeos/settings/cros_settings.h"
32 #include "chrome/browser/lifetime/application_lifetime.h"
33 #include "chrome/browser/policy/schema_registry_service.h"
34 #include "chrome/common/chrome_features.h"
35 #include "chromeos/constants/chromeos_switches.h"
36 #include "chromeos/dbus/constants/dbus_paths.h"
37 #include "chromeos/dbus/cryptohome/cryptohome_client.h"
38 #include "chromeos/dbus/session_manager/session_manager_client.h"
39 #include "chromeos/tpm/install_attributes.h"
40 #include "components/arc/arc_features.h"
41 #include "components/policy/core/browser/browser_policy_connector.h"
42 #include "components/policy/core/common/cloud/cloud_external_data_manager.h"
43 #include "components/policy/core/common/cloud/device_management_service.h"
44 #include "components/policy/core/common/cloud/enterprise_metrics.h"
45 #include "components/policy/core/common/configuration_policy_provider.h"
46 #include "components/policy/policy_constants.h"
47 #include "components/user_manager/known_user.h"
48 #include "components/user_manager/user.h"
49 #include "components/user_manager/user_manager.h"
50 #include "services/network/public/cpp/shared_url_loader_factory.h"
51 
52 using user_manager::known_user::ProfileRequiresPolicy;
53 namespace policy {
54 
55 using PolicyEnforcement = UserCloudPolicyManagerChromeOS::PolicyEnforcement;
56 namespace {
57 
58 // Directory under the profile directory where policy-related resources are
59 // stored, see the following constants for details.
60 const base::FilePath::CharType kPolicy[] = FILE_PATH_LITERAL("Policy");
61 
62 // Directory under kPolicy, in the user's profile dir, where policy for
63 // components is cached.
64 const base::FilePath::CharType kComponentsDir[] =
65     FILE_PATH_LITERAL("Components");
66 
67 // Directory in which to store external policy data. This is specified relative
68 // to kPolicy.
69 const base::FilePath::CharType kPolicyExternalDataDir[] =
70     FILE_PATH_LITERAL("External Data");
71 
72 // How long we'll block session initialization to try to refresh policy.
73 constexpr base::TimeDelta kPolicyRefreshTimeout =
74     base::TimeDelta::FromSeconds(10);
75 
76 // Called when the user policy loading fails with a fatal error, and the user
77 // session has to be terminated.
OnUserPolicyFatalError(const AccountId & account_id,MetricUserPolicyChromeOSSessionAbortType metric_value)78 void OnUserPolicyFatalError(
79     const AccountId& account_id,
80     MetricUserPolicyChromeOSSessionAbortType metric_value) {
81   base::UmaHistogramEnumeration(
82       kMetricUserPolicyChromeOSSessionAbort, metric_value,
83       MetricUserPolicyChromeOSSessionAbortType::kCount);
84   user_manager::UserManager::Get()->SaveForceOnlineSignin(
85       account_id, true /* force_online_signin */);
86   chrome::AttemptUserExit();
87 }
88 
89 }  // namespace
90 
CreateConfigurationPolicyProvider(Profile * profile,bool force_immediate_load,scoped_refptr<base::SequencedTaskRunner> background_task_runner,std::unique_ptr<UserCloudPolicyManagerChromeOS> * user_cloud_policy_manager_chromeos_out,std::unique_ptr<ActiveDirectoryPolicyManager> * active_directory_policy_manager_out)91 void CreateConfigurationPolicyProvider(
92     Profile* profile,
93     bool force_immediate_load,
94     scoped_refptr<base::SequencedTaskRunner> background_task_runner,
95     std::unique_ptr<UserCloudPolicyManagerChromeOS>*
96         user_cloud_policy_manager_chromeos_out,
97     std::unique_ptr<ActiveDirectoryPolicyManager>*
98         active_directory_policy_manager_out) {
99   // Clear the two out parameters. Default return will be nullptr for both.
100   *user_cloud_policy_manager_chromeos_out = nullptr;
101   *active_directory_policy_manager_out = nullptr;
102 
103   // Don't initialize cloud policy for the signin and the lock screen app
104   // profile.
105   if (chromeos::ProfileHelper::IsSigninProfile(profile) ||
106       chromeos::ProfileHelper::IsLockScreenAppProfile(profile)) {
107     return;
108   }
109 
110   // |user| should never be nullptr except for the signin and lock screen app
111   // profile. This object is created as part of the Profile creation, which
112   // happens right after sign-in. The just-signed-in User is the active user
113   // during that time.
114   const user_manager::User* user =
115       chromeos::ProfileHelper::Get()->GetUserByProfile(profile);
116   CHECK(user);
117 
118   // User policy exists for enterprise accounts:
119   // - For regular cloud-managed users (those who have a GAIA account), a
120   //   |UserCloudPolicyManagerChromeOS| is created here.
121   // - For Active Directory managed users, an |ActiveDirectoryPolicyManager|
122   //   is created.
123   // - For device-local accounts, policy is provided by
124   //   |DeviceLocalAccountPolicyService|.
125   // For non-enterprise accounts only for users with type USER_TYPE_CHILD
126   //   |UserCloudPolicyManagerChromeOS| is created here.
127   // All other user types do not have user policy.
128   const AccountId& account_id = user->GetAccountId();
129   if (user->GetType() == user_manager::USER_TYPE_SUPERVISED ||
130       (user->GetType() != user_manager::USER_TYPE_CHILD &&
131        BrowserPolicyConnector::IsNonEnterpriseUser(
132            account_id.GetUserEmail()))) {
133     DLOG(WARNING) << "No policy loaded for known non-enterprise user";
134     // Mark this profile as not requiring policy.
135     user_manager::known_user::SetProfileRequiresPolicy(
136         account_id, ProfileRequiresPolicy::kNoPolicyRequired);
137     return;
138   }
139 
140   policy::BrowserPolicyConnectorChromeOS* connector =
141       g_browser_process->platform_part()->browser_policy_connector_chromeos();
142   bool is_active_directory = false;
143   switch (account_id.GetAccountType()) {
144     case AccountType::UNKNOWN:
145     case AccountType::GOOGLE:
146       // TODO(tnagel): Return nullptr for unknown accounts once AccountId
147       // migration is finished.  (KioskAppManager still needs to be migrated.)
148       if (!user->HasGaiaAccount()) {
149         DLOG(WARNING) << "No policy for users without Gaia accounts";
150         return;
151       }
152       is_active_directory = false;
153       break;
154     case AccountType::ACTIVE_DIRECTORY:
155       // Active Directory users only exist on devices whose install attributes
156       // are locked into Active Directory mode.
157       CHECK(connector->GetInstallAttributes()->IsActiveDirectoryManaged());
158       is_active_directory = true;
159       break;
160   }
161 
162   const ProfileRequiresPolicy requires_policy_user_property =
163       user_manager::known_user::GetProfileRequiresPolicy(account_id);
164   const base::CommandLine* command_line =
165       base::CommandLine::ForCurrentProcess();
166   const bool is_stub_user =
167       user_manager::UserManager::Get()->IsStubAccountId(account_id);
168 
169   // If true, we don't know if we've ever checked for policy for this user, so
170   // we need to do a policy check during initialization. This differs from
171   // |policy_required| in that it's OK if the server says we don't have policy.
172   // If this is true, then |policy_required| must be false.
173   const bool policy_check_required =
174       (requires_policy_user_property == ProfileRequiresPolicy::kUnknown) &&
175       !is_stub_user && !is_active_directory &&
176       !command_line->HasSwitch(chromeos::switches::kProfileRequiresPolicy) &&
177       !command_line->HasSwitch(
178           chromeos::switches::kAllowFailedPolicyFetchForTest);
179 
180   // |force_immediate_load| is true during Chrome restart, or during
181   // initialization of stub user profiles when running tests. If we ever get
182   // a Chrome restart before a real user session has been initialized, we should
183   // exit the user session entirely - it means that there was a crash during
184   // profile initialization, and we can't rely on the cached policy being valid
185   // (so can't force immediate load of policy).
186   if (policy_check_required && force_immediate_load) {
187     LOG(ERROR) << "Exiting non-stub session because browser restarted before"
188                << " profile was initialized.";
189     base::UmaHistogramEnumeration(
190         kMetricUserPolicyChromeOSSessionAbort,
191         is_active_directory ? MetricUserPolicyChromeOSSessionAbortType::
192                                   kBlockingInitWithActiveDirectoryManagement
193                             : MetricUserPolicyChromeOSSessionAbortType::
194                                   kBlockingInitWithGoogleCloudManagement,
195         MetricUserPolicyChromeOSSessionAbortType::kCount);
196     chrome::AttemptUserExit();
197     return;
198   }
199 
200   // If true, we must load policy for this user - we will abort profile
201   // initialization if we are unable to load policy (say, due to disk errors).
202   // We either read this flag from the known_user database, or from a
203   // command-line flag (required for ephemeral users who are not persisted
204   // in the known_user database).
205   const bool policy_required =
206       !command_line->HasSwitch(
207           chromeos::switches::kAllowFailedPolicyFetchForTest) &&
208       (is_active_directory ||
209        (requires_policy_user_property ==
210         ProfileRequiresPolicy::kPolicyRequired) ||
211        (command_line->GetSwitchValueASCII(
212             chromeos::switches::kProfileRequiresPolicy) == "true"));
213 
214   // We should never have |policy_required| and |policy_check_required| both
215   // set, since the |policy_required| implies that we already know that
216   // the user requires policy.
217   CHECK(!(policy_required && policy_check_required));
218 
219   // Determine whether we need to enforce policy load or not.
220   PolicyEnforcement enforcement_type = PolicyEnforcement::kPolicyOptional;
221   if (policy_required) {
222     enforcement_type = PolicyEnforcement::kPolicyRequired;
223   } else if (policy_check_required) {
224     enforcement_type = PolicyEnforcement::kServerCheckRequired;
225   }
226 
227   // If there's a chance the user might be managed (enforcement_type !=
228   // kPolicyOptional) then we can't let the profile complete initialization
229   // until we complete a policy check.
230   //
231   // The only exception is if |force_immediate_load| is true, then we can't
232   // block at all (loading from network is not allowed - only from cache). In
233   // this case, logic in UserCloudPolicyManagerChromeOS will exit the session
234   // if we fail to load policy from our cache.
235   const bool block_profile_init_on_policy_refresh =
236       (enforcement_type != PolicyEnforcement::kPolicyOptional) &&
237       !force_immediate_load && !is_stub_user;
238 
239   // If OAuth token is required for policy refresh for child user we should not
240   // block signin. Policy refresh will fail without the token that is available
241   // only after profile initialization.
242   const bool policy_refresh_requires_oauth_token =
243       user->GetType() == user_manager::USER_TYPE_CHILD &&
244       base::FeatureList::IsEnabled(features::kDMServerOAuthForChildUser);
245 
246   base::TimeDelta policy_refresh_timeout;
247   if (block_profile_init_on_policy_refresh &&
248       enforcement_type == PolicyEnforcement::kPolicyRequired &&
249       !policy_refresh_requires_oauth_token) {
250     // We already have policy, so block signin for a short period to check
251     // for a policy update, so we can pick up any important policy changes
252     // that can't easily change on the fly (like changes to the startup tabs).
253     // We can fallback to the cached policy if we can't access the policy
254     // server.
255     policy_refresh_timeout = kPolicyRefreshTimeout;
256   }
257 
258   DeviceManagementService* device_management_service =
259       connector->device_management_service();
260   if (block_profile_init_on_policy_refresh)
261     device_management_service->ScheduleInitialization(0);
262 
263   base::FilePath profile_dir = profile->GetPath();
264   const base::FilePath component_policy_cache_dir =
265       profile_dir.Append(kPolicy).Append(kComponentsDir);
266   const base::FilePath external_data_dir =
267       profile_dir.Append(kPolicy).Append(kPolicyExternalDataDir);
268   const base::FilePath policy_key_dir =
269       base::PathService::CheckedGet(chromeos::dbus_paths::DIR_USER_POLICY_KEYS);
270 
271   std::unique_ptr<UserCloudPolicyStoreChromeOS> store =
272       std::make_unique<UserCloudPolicyStoreChromeOS>(
273           chromeos::CryptohomeClient::Get(),
274           chromeos::SessionManagerClient::Get(), background_task_runner,
275           account_id, policy_key_dir, is_active_directory);
276 
277   scoped_refptr<base::SequencedTaskRunner> backend_task_runner =
278       base::ThreadPool::CreateSequencedTaskRunner(
279           {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
280            base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN});
281   std::unique_ptr<CloudExternalDataManager> external_data_manager(
282       new UserCloudExternalDataManager(
283           base::BindRepeating(&GetChromePolicyDetails), backend_task_runner,
284           external_data_dir, store.get()));
285   if (force_immediate_load)
286     store->LoadImmediately();
287 
288   if (is_active_directory) {
289     auto manager = std::make_unique<UserActiveDirectoryPolicyManager>(
290         account_id, policy_required, policy_refresh_timeout,
291         base::BindOnce(&OnUserPolicyFatalError, account_id,
292                        MetricUserPolicyChromeOSSessionAbortType::
293                            kInitWithActiveDirectoryManagement),
294         std::move(store), std::move(external_data_manager));
295     manager->Init(profile->GetPolicySchemaRegistryService()->registry());
296     *active_directory_policy_manager_out = std::move(manager);
297   } else {
298     std::unique_ptr<UserCloudPolicyManagerChromeOS> manager =
299         std::make_unique<UserCloudPolicyManagerChromeOS>(
300             profile, std::move(store), std::move(external_data_manager),
301             component_policy_cache_dir, enforcement_type,
302             policy_refresh_timeout,
303             base::BindOnce(&OnUserPolicyFatalError, account_id,
304                            MetricUserPolicyChromeOSSessionAbortType::
305                                kInitWithGoogleCloudManagement),
306             account_id, base::ThreadTaskRunnerHandle::Get());
307 
308     bool wildcard_match = false;
309     if (connector->IsEnterpriseManaged() &&
310         chromeos::CrosSettings::Get()->IsUserAllowlisted(
311             account_id.GetUserEmail(), &wildcard_match, user->GetType()) &&
312         wildcard_match &&
313         !connector->IsNonEnterpriseUser(account_id.GetUserEmail())) {
314       manager->EnableWildcardLoginCheck(account_id.GetUserEmail());
315     }
316 
317     manager->Init(profile->GetPolicySchemaRegistryService()->registry());
318     manager->Connect(g_browser_process->local_state(),
319                      device_management_service,
320                      g_browser_process->shared_url_loader_factory());
321     *user_cloud_policy_manager_chromeos_out = std::move(manager);
322   }
323 }
324 
325 }  // namespace policy
326