OLD | NEW |
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/chromeos/login/enrollment/enterprise_enrollment_screen.
h" | 5 #include "chrome/browser/chromeos/login/enrollment/enterprise_enrollment_screen.
h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
11 #include "base/metrics/histogram.h" | 11 #include "base/metrics/histogram.h" |
12 #include "chrome/browser/browser_process.h" | 12 #include "chrome/browser/browser_process.h" |
13 #include "chrome/browser/chromeos/cros/cros_library.h" | 13 #include "chrome/browser/chromeos/cros/cros_library.h" |
14 #include "chrome/browser/chromeos/cros/cryptohome_library.h" | 14 #include "chrome/browser/chromeos/cros/cryptohome_library.h" |
15 #include "chrome/browser/chromeos/login/login_utils.h" | 15 #include "chrome/browser/chromeos/login/login_utils.h" |
16 #include "chrome/browser/chromeos/login/screen_observer.h" | 16 #include "chrome/browser/chromeos/login/screen_observer.h" |
17 #include "chrome/browser/chromeos/login/wizard_controller.h" | 17 #include "chrome/browser/chromeos/login/wizard_controller.h" |
18 #include "chrome/browser/policy/auto_enrollment_client.h" | 18 #include "chrome/browser/policy/auto_enrollment_client.h" |
19 #include "chrome/browser/policy/browser_policy_connector.h" | 19 #include "chrome/browser/policy/browser_policy_connector.h" |
20 #include "chrome/browser/policy/cloud_policy_data_store.h" | |
21 #include "chrome/browser/policy/device_cloud_policy_manager_chromeos.h" | 20 #include "chrome/browser/policy/device_cloud_policy_manager_chromeos.h" |
22 #include "chrome/browser/policy/enterprise_metrics.h" | 21 #include "chrome/browser/policy/enterprise_metrics.h" |
23 #include "chromeos/dbus/dbus_thread_manager.h" | 22 #include "chromeos/dbus/dbus_thread_manager.h" |
24 #include "chromeos/dbus/session_manager_client.h" | 23 #include "chromeos/dbus/session_manager_client.h" |
25 #include "google_apis/gaia/gaia_auth_util.h" | 24 #include "google_apis/gaia/gaia_auth_util.h" |
26 #include "google_apis/gaia/google_service_auth_error.h" | 25 #include "google_apis/gaia/google_service_auth_error.h" |
27 | 26 |
28 namespace chromeos { | 27 namespace chromeos { |
29 | 28 |
30 namespace { | 29 namespace { |
31 | 30 |
32 // Retry for InstallAttrs initialization every 500ms. | |
33 const int kLockRetryIntervalMs = 500; | |
34 // Maximum time to retry InstallAttrs initialization before we give up. | |
35 const int kLockRetryTimeoutMs = 10 * 60 * 1000; // 10 minutes. | |
36 | |
37 void UMA(int sample) { | 31 void UMA(int sample) { |
38 UMA_HISTOGRAM_ENUMERATION(policy::kMetricEnrollment, | 32 UMA_HISTOGRAM_ENUMERATION(policy::kMetricEnrollment, |
39 sample, | 33 sample, |
40 policy::kMetricEnrollmentSize); | 34 policy::kMetricEnrollmentSize); |
41 } | 35 } |
42 | 36 |
43 } // namespace | 37 } // namespace |
44 | 38 |
45 EnterpriseEnrollmentScreen::EnterpriseEnrollmentScreen( | 39 EnterpriseEnrollmentScreen::EnterpriseEnrollmentScreen( |
46 ScreenObserver* observer, | 40 ScreenObserver* observer, |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 get_screen_observer()->OnExit( | 175 get_screen_observer()->OnExit( |
182 ScreenObserver::ENTERPRISE_AUTO_MAGIC_ENROLLMENT_COMPLETED); | 176 ScreenObserver::ENTERPRISE_AUTO_MAGIC_ENROLLMENT_COMPLETED); |
183 } else { | 177 } else { |
184 actor_->ResetAuth( | 178 actor_->ResetAuth( |
185 base::Bind(&ScreenObserver::OnExit, | 179 base::Bind(&ScreenObserver::OnExit, |
186 base::Unretained(get_screen_observer()), | 180 base::Unretained(get_screen_observer()), |
187 ScreenObserver::ENTERPRISE_ENROLLMENT_COMPLETED)); | 181 ScreenObserver::ENTERPRISE_ENROLLMENT_COMPLETED)); |
188 } | 182 } |
189 } | 183 } |
190 | 184 |
191 void EnterpriseEnrollmentScreen::OnPolicyStateChanged( | |
192 policy::CloudPolicySubsystem::PolicySubsystemState state, | |
193 policy::CloudPolicySubsystem::ErrorDetails error_details) { | |
194 | |
195 switch (state) { | |
196 case policy::CloudPolicySubsystem::UNENROLLED: | |
197 switch (error_details) { | |
198 case policy::CloudPolicySubsystem::BAD_SERIAL_NUMBER: | |
199 ReportEnrollmentStatus( | |
200 policy::EnrollmentStatus::ForRegistrationError( | |
201 policy::DM_STATUS_SERVICE_INVALID_SERIAL_NUMBER)); | |
202 break; | |
203 case policy::CloudPolicySubsystem::BAD_ENROLLMENT_MODE: | |
204 ReportEnrollmentStatus( | |
205 policy::EnrollmentStatus::ForStatus( | |
206 policy::EnrollmentStatus::STATUS_REGISTRATION_BAD_MODE)); | |
207 break; | |
208 case policy::CloudPolicySubsystem::MISSING_LICENSES: | |
209 ReportEnrollmentStatus( | |
210 policy::EnrollmentStatus::ForRegistrationError( | |
211 policy::DM_STATUS_SERVICE_MISSING_LICENSES)); | |
212 break; | |
213 default: // Still working... | |
214 return; | |
215 } | |
216 break; | |
217 case policy::CloudPolicySubsystem::BAD_GAIA_TOKEN: | |
218 ReportEnrollmentStatus( | |
219 policy::EnrollmentStatus::ForRegistrationError( | |
220 policy::DM_STATUS_SERVICE_MANAGEMENT_TOKEN_INVALID)); | |
221 break; | |
222 case policy::CloudPolicySubsystem::LOCAL_ERROR: | |
223 ReportEnrollmentStatus( | |
224 policy::EnrollmentStatus::ForStoreError( | |
225 policy::CloudPolicyStore::STATUS_STORE_ERROR, | |
226 policy::CloudPolicyValidatorBase::VALIDATION_OK)); | |
227 break; | |
228 case policy::CloudPolicySubsystem::UNMANAGED: | |
229 ReportEnrollmentStatus( | |
230 policy::EnrollmentStatus::ForRegistrationError( | |
231 policy::DM_STATUS_SERVICE_MANAGEMENT_NOT_SUPPORTED)); | |
232 break; | |
233 case policy::CloudPolicySubsystem::NETWORK_ERROR: | |
234 ReportEnrollmentStatus( | |
235 policy::EnrollmentStatus::ForRegistrationError( | |
236 policy::DM_STATUS_REQUEST_FAILED)); | |
237 break; | |
238 case policy::CloudPolicySubsystem::TOKEN_FETCHED: | |
239 if (!is_auto_enrollment_ || | |
240 g_browser_process->browser_policy_connector()-> | |
241 GetDeviceCloudPolicyDataStore()->device_mode() == | |
242 policy::DEVICE_MODE_ENTERPRISE) { | |
243 WriteInstallAttributesData(); | |
244 return; | |
245 } else { | |
246 LOG(ERROR) << "Enrollment cannot proceed because Auto-enrollment is " | |
247 << "not supported for non-enterprise enrollment modes."; | |
248 policy::AutoEnrollmentClient::CancelAutoEnrollment(); | |
249 is_auto_enrollment_ = false; | |
250 UMAFailure(policy::kMetricEnrollmentAutoEnrollmentNotSupported); | |
251 actor_->ShowUIError( | |
252 EnterpriseEnrollmentScreenActor::UI_ERROR_AUTO_ENROLLMENT_BAD_MODE); | |
253 NotifyTestingObservers(false); | |
254 // Set the error state to something distinguishable in the logs. | |
255 state = policy::CloudPolicySubsystem::LOCAL_ERROR; | |
256 error_details = policy::CloudPolicySubsystem::AUTO_ENROLLMENT_ERROR; | |
257 } | |
258 break; | |
259 case policy::CloudPolicySubsystem::SUCCESS: | |
260 // Success! | |
261 registrar_.reset(); | |
262 ReportEnrollmentStatus( | |
263 policy::EnrollmentStatus::ForStatus( | |
264 policy::EnrollmentStatus::STATUS_SUCCESS)); | |
265 return; | |
266 } | |
267 | |
268 // We have an error. | |
269 if (!is_auto_enrollment_) | |
270 UMAFailure(policy::kMetricEnrollmentPolicyFailed); | |
271 | |
272 LOG(WARNING) << "Policy subsystem error during enrollment: " << state | |
273 << " details: " << error_details; | |
274 | |
275 // Stop the policy infrastructure. | |
276 registrar_.reset(); | |
277 g_browser_process->browser_policy_connector()->ResetDevicePolicy(); | |
278 } | |
279 | |
280 void EnterpriseEnrollmentScreen::AddTestingObserver(TestingObserver* observer) { | 185 void EnterpriseEnrollmentScreen::AddTestingObserver(TestingObserver* observer) { |
281 observers_.AddObserver(observer); | 186 observers_.AddObserver(observer); |
282 } | 187 } |
283 | 188 |
284 void EnterpriseEnrollmentScreen::RemoveTestingObserver( | 189 void EnterpriseEnrollmentScreen::RemoveTestingObserver( |
285 TestingObserver* observer) { | 190 TestingObserver* observer) { |
286 observers_.RemoveObserver(observer); | 191 observers_.RemoveObserver(observer); |
287 } | 192 } |
288 | 193 |
289 void EnterpriseEnrollmentScreen::WriteInstallAttributesData() { | |
290 // Since this method is also called directly. | |
291 weak_ptr_factory_.InvalidateWeakPtrs(); | |
292 | |
293 switch (g_browser_process->browser_policy_connector()->LockDevice(user_)) { | |
294 case policy::EnterpriseInstallAttributes::LOCK_SUCCESS: { | |
295 // Proceed with policy fetch. | |
296 policy::BrowserPolicyConnector* connector = | |
297 g_browser_process->browser_policy_connector(); | |
298 connector->FetchCloudPolicy(); | |
299 return; | |
300 } | |
301 case policy::EnterpriseInstallAttributes::LOCK_NOT_READY: { | |
302 // We wait up to |kLockRetryTimeoutMs| milliseconds and if it hasn't | |
303 // succeeded by then show an error to the user and stop the enrollment. | |
304 if (lockbox_init_duration_ < kLockRetryTimeoutMs) { | |
305 // InstallAttributes not ready yet, retry later. | |
306 LOG(WARNING) << "Install Attributes not ready yet will retry in " | |
307 << kLockRetryIntervalMs << "ms."; | |
308 MessageLoop::current()->PostDelayedTask( | |
309 FROM_HERE, | |
310 base::Bind(&EnterpriseEnrollmentScreen::WriteInstallAttributesData, | |
311 weak_ptr_factory_.GetWeakPtr()), | |
312 base::TimeDelta::FromMilliseconds(kLockRetryIntervalMs)); | |
313 lockbox_init_duration_ += kLockRetryIntervalMs; | |
314 } else { | |
315 ReportEnrollmentStatus( | |
316 policy::EnrollmentStatus::ForStatus( | |
317 policy::EnrollmentStatus::STATUS_LOCK_TIMEOUT)); | |
318 } | |
319 return; | |
320 } | |
321 case policy::EnterpriseInstallAttributes::LOCK_BACKEND_ERROR: { | |
322 ReportEnrollmentStatus( | |
323 policy::EnrollmentStatus::ForStatus( | |
324 policy::EnrollmentStatus::STATUS_LOCK_ERROR)); | |
325 return; | |
326 } | |
327 case policy::EnterpriseInstallAttributes::LOCK_WRONG_USER: { | |
328 LOG(ERROR) << "Enrollment can not proceed because the InstallAttrs " | |
329 << "has been locked already!"; | |
330 ReportEnrollmentStatus( | |
331 policy::EnrollmentStatus::ForStatus( | |
332 policy::EnrollmentStatus::STATUS_LOCK_WRONG_USER)); | |
333 return; | |
334 } | |
335 } | |
336 | |
337 NOTREACHED(); | |
338 ReportEnrollmentStatus( | |
339 policy::EnrollmentStatus::ForStatus( | |
340 policy::EnrollmentStatus::STATUS_LOCK_ERROR)); | |
341 } | |
342 | |
343 void EnterpriseEnrollmentScreen::RegisterForDevicePolicy( | 194 void EnterpriseEnrollmentScreen::RegisterForDevicePolicy( |
344 const std::string& token) { | 195 const std::string& token) { |
345 policy::BrowserPolicyConnector* connector = | 196 policy::BrowserPolicyConnector* connector = |
346 g_browser_process->browser_policy_connector(); | 197 g_browser_process->browser_policy_connector(); |
347 if (connector->IsEnterpriseManaged() && | 198 if (connector->IsEnterpriseManaged() && |
348 connector->GetEnterpriseDomain() != gaia::ExtractDomainName(user_)) { | 199 connector->GetEnterpriseDomain() != gaia::ExtractDomainName(user_)) { |
349 LOG(ERROR) << "Trying to re-enroll to a different domain than " | 200 LOG(ERROR) << "Trying to re-enroll to a different domain than " |
350 << connector->GetEnterpriseDomain(); | 201 << connector->GetEnterpriseDomain(); |
351 UMAFailure(policy::kMetricEnrollmentWrongUserError); | 202 UMAFailure(policy::kMetricEnrollmentWrongUserError); |
352 actor_->ShowUIError( | 203 actor_->ShowUIError( |
353 EnterpriseEnrollmentScreenActor::UI_ERROR_DOMAIN_MISMATCH); | 204 EnterpriseEnrollmentScreenActor::UI_ERROR_DOMAIN_MISMATCH); |
354 NotifyTestingObservers(false); | 205 NotifyTestingObservers(false); |
355 return; | 206 return; |
356 } | 207 } |
357 | 208 |
358 // If a device cloud policy manager instance is available (i.e. new-style | 209 policy::DeviceCloudPolicyManagerChromeOS::AllowedDeviceModes modes; |
359 // policy is switched on), use that path. | 210 modes[policy::DEVICE_MODE_ENTERPRISE] = true; |
360 // TODO(mnissler): Remove the old-style enrollment code path once the code has | 211 modes[policy::DEVICE_MODE_KIOSK] = !is_auto_enrollment_; |
361 // switched to the new policy code by default. | 212 connector->ScheduleServiceInitialization(0); |
362 if (connector->GetDeviceCloudPolicyManager()) { | 213 connector->GetDeviceCloudPolicyManager()->StartEnrollment( |
363 policy::DeviceCloudPolicyManagerChromeOS::AllowedDeviceModes modes; | 214 token, is_auto_enrollment_, modes, |
364 modes[policy::DEVICE_MODE_ENTERPRISE] = true; | 215 base::Bind(&EnterpriseEnrollmentScreen::ReportEnrollmentStatus, |
365 modes[policy::DEVICE_MODE_KIOSK] = !is_auto_enrollment_; | 216 weak_ptr_factory_.GetWeakPtr())); |
366 connector->ScheduleServiceInitialization(0); | |
367 connector->GetDeviceCloudPolicyManager()->StartEnrollment( | |
368 token, is_auto_enrollment_, modes, | |
369 base::Bind(&EnterpriseEnrollmentScreen::ReportEnrollmentStatus, | |
370 weak_ptr_factory_.GetWeakPtr())); | |
371 return; | |
372 } else if (!connector->device_cloud_policy_subsystem()) { | |
373 LOG(ERROR) << "Cloud policy subsystem not initialized."; | |
374 } else if (connector->device_cloud_policy_subsystem()->state() == | |
375 policy::CloudPolicySubsystem::SUCCESS) { | |
376 LOG(ERROR) << "A previous enrollment already succeeded!"; | |
377 } else { | |
378 // Make sure the device policy subsystem is in a clean slate. | |
379 connector->ResetDevicePolicy(); | |
380 connector->ScheduleServiceInitialization(0); | |
381 registrar_.reset(new policy::CloudPolicySubsystem::ObserverRegistrar( | |
382 connector->device_cloud_policy_subsystem(), this)); | |
383 // Push the credentials to the policy infrastructure. It'll start enrollment | |
384 // and notify us of progress through CloudPolicySubsystem::Observer. | |
385 connector->RegisterForDevicePolicy(user_, token, | |
386 is_auto_enrollment_, | |
387 connector->IsEnterpriseManaged()); | |
388 return; | |
389 } | |
390 | |
391 NOTREACHED(); | |
392 UMAFailure(policy::kMetricEnrollmentOtherFailed); | |
393 actor_->ShowUIError(EnterpriseEnrollmentScreenActor::UI_ERROR_FATAL); | |
394 NotifyTestingObservers(false); | |
395 } | 217 } |
396 | 218 |
397 void EnterpriseEnrollmentScreen::ReportEnrollmentStatus( | 219 void EnterpriseEnrollmentScreen::ReportEnrollmentStatus( |
398 policy::EnrollmentStatus status) { | 220 policy::EnrollmentStatus status) { |
399 bool success = status.status() == policy::EnrollmentStatus::STATUS_SUCCESS; | 221 bool success = status.status() == policy::EnrollmentStatus::STATUS_SUCCESS; |
400 enrollment_failed_once_ |= !success; | 222 enrollment_failed_once_ |= !success; |
401 actor_->ShowEnrollmentStatus(status); | 223 actor_->ShowEnrollmentStatus(status); |
402 NotifyTestingObservers(success); | 224 NotifyTestingObservers(success); |
403 | 225 |
404 switch (status.status()) { | 226 switch (status.status()) { |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
465 actor_->Show(); | 287 actor_->Show(); |
466 actor_->ShowSigninScreen(); | 288 actor_->ShowSigninScreen(); |
467 } | 289 } |
468 | 290 |
469 void EnterpriseEnrollmentScreen::NotifyTestingObservers(bool succeeded) { | 291 void EnterpriseEnrollmentScreen::NotifyTestingObservers(bool succeeded) { |
470 FOR_EACH_OBSERVER(TestingObserver, observers_, | 292 FOR_EACH_OBSERVER(TestingObserver, observers_, |
471 OnEnrollmentComplete(succeeded)); | 293 OnEnrollmentComplete(succeeded)); |
472 } | 294 } |
473 | 295 |
474 } // namespace chromeos | 296 } // namespace chromeos |
OLD | NEW |