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