#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/logging.h"
-#include "base/message_loop/message_loop_proxy.h"
#include "base/metrics/histogram.h"
#include "base/metrics/sparse_histogram.h"
#include "base/sequenced_task_runner.h"
+#include "base/values.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/policy/policy_oauth2_token_fetcher.h"
#include "chrome/browser/chromeos/policy/user_cloud_policy_manager_factory_chromeos.h"
+#include "chrome/browser/chromeos/policy/wildcard_login_checker.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
-#include "chrome/browser/policy/cloud/cloud_external_data_manager.h"
-#include "chrome/browser/policy/cloud/cloud_policy_refresh_scheduler.h"
-#include "chrome/browser/policy/cloud/resource_cache.h"
-#include "chrome/browser/policy/policy_bundle.h"
-#include "chrome/browser/policy/policy_domain_descriptor.h"
+#include "chrome/browser/lifetime/application_lifetime.h"
+#include "chrome/common/chrome_content_client.h"
+#include "components/policy/core/common/cloud/cloud_external_data_manager.h"
+#include "components/policy/core/common/cloud/cloud_policy_refresh_scheduler.h"
+#include "components/policy/core/common/cloud/device_management_service.h"
+#include "components/policy/core/common/cloud/system_policy_request_context.h"
+#include "components/policy/core/common/policy_map.h"
#include "components/policy/core/common/policy_pref_names.h"
-#include "content/public/browser/browser_thread.h"
+#include "components/policy/core/common/policy_types.h"
+#include "components/user_manager/user_manager.h"
#include "net/url_request/url_request_context_getter.h"
+#include "policy/policy_constants.h"
+#include "url/gurl.h"
namespace em = enterprise_management;
const char kUMAInitialFetchOAuth2NetworkError[] =
"Enterprise.UserPolicyChromeOS.InitialFetch.OAuth2NetworkError";
+void OnWildcardCheckCompleted(const std::string& username,
+ WildcardLoginChecker::Result result) {
+ if (result == WildcardLoginChecker::RESULT_BLOCKED) {
+ LOG(ERROR) << "Online wildcard login check failed, terminating session.";
+
+ // TODO(mnissler): This only removes the user pod from the login screen, but
+ // the cryptohome remains. This is because deleting the cryptohome for a
+ // logged-in session is not possible. Fix this either by delaying the
+ // cryptohome deletion operation or by getting rid of the in-session
+ // wildcard check.
+ user_manager::UserManager::Get()->RemoveUserFromList(username);
+ chrome::AttemptUserExit();
+ }
+}
+
} // namespace
UserCloudPolicyManagerChromeOS::UserCloudPolicyManagerChromeOS(
scoped_ptr<CloudPolicyStore> store,
scoped_ptr<CloudExternalDataManager> external_data_manager,
- const scoped_refptr<base::SequencedTaskRunner>& task_runner,
- scoped_ptr<ResourceCache> resource_cache,
+ const base::FilePath& component_policy_cache_path,
bool wait_for_policy_fetch,
- base::TimeDelta initial_policy_fetch_timeout)
+ base::TimeDelta initial_policy_fetch_timeout,
+ const scoped_refptr<base::SequencedTaskRunner>& task_runner,
+ const scoped_refptr<base::SequencedTaskRunner>& file_task_runner,
+ const scoped_refptr<base::SequencedTaskRunner>& io_task_runner)
: CloudPolicyManager(
PolicyNamespaceKey(dm_protocol::kChromeUserPolicyType, std::string()),
store.get(),
- task_runner),
+ task_runner,
+ file_task_runner,
+ io_task_runner),
store_(store.Pass()),
external_data_manager_(external_data_manager.Pass()),
+ component_policy_cache_path_(component_policy_cache_path),
wait_for_policy_fetch_(wait_for_policy_fetch),
policy_fetch_timeout_(false, false) {
time_init_started_ = base::Time::Now();
- if (wait_for_policy_fetch_) {
+ if (wait_for_policy_fetch_ && !initial_policy_fetch_timeout.is_max()) {
policy_fetch_timeout_.Start(
FROM_HERE,
initial_policy_fetch_timeout,
- base::Bind(&UserCloudPolicyManagerChromeOS::CancelWaitForPolicyFetch,
+ base::Bind(&UserCloudPolicyManagerChromeOS::OnBlockingFetchTimeout,
base::Unretained(this)));
}
- if (resource_cache) {
- // TODO(joaodasilva): Move the backend from the FILE thread to the blocking
- // pool.
- component_policy_service_.reset(new ComponentCloudPolicyService(
- this,
- store_.get(),
- resource_cache.Pass(),
- content::BrowserThread::GetMessageLoopProxyForThread(
- content::BrowserThread::FILE),
- content::BrowserThread::GetMessageLoopProxyForThread(
- content::BrowserThread::IO)));
- }
}
UserCloudPolicyManagerChromeOS::~UserCloudPolicyManagerChromeOS() {}
void UserCloudPolicyManagerChromeOS::Connect(
PrefService* local_state,
DeviceManagementService* device_management_service,
- scoped_refptr<net::URLRequestContextGetter> request_context,
+ scoped_refptr<net::URLRequestContextGetter> system_request_context,
UserAffiliation user_affiliation) {
DCHECK(device_management_service);
DCHECK(local_state);
local_state_ = local_state;
+ scoped_refptr<net::URLRequestContextGetter> request_context;
+ if (system_request_context) {
+ // |system_request_context| can be null for tests.
+ // Use the system request context here instead of a context derived
+ // from the Profile because Connect() is called before the profile is
+ // fully initialized (required so we can perform the initial policy load).
+ // TODO(atwilson): Change this to use a UserPolicyRequestContext once
+ // Connect() is called after profile initialization. http://crbug.com/323591
+ request_context = new SystemPolicyRequestContext(
+ system_request_context, GetUserAgent());
+ }
scoped_ptr<CloudPolicyClient> cloud_policy_client(
- new CloudPolicyClient(std::string(), std::string(), user_affiliation,
- NULL, device_management_service));
+ new CloudPolicyClient(std::string(), std::string(),
+ kPolicyVerificationKeyHash, user_affiliation,
+ NULL, device_management_service,
+ request_context));
core()->Connect(cloud_policy_client.Pass());
client()->AddObserver(this);
external_data_manager_->Connect(request_context);
- if (component_policy_service_)
- component_policy_service_->Connect(client(), request_context);
+ CreateComponentCloudPolicyService(component_policy_cache_path_,
+ request_context);
// Determine the next step after the CloudPolicyService initializes.
if (service()->IsInitializationComplete()) {
void UserCloudPolicyManagerChromeOS::OnAccessTokenAvailable(
const std::string& access_token) {
access_token_ = access_token;
+
+ if (!wildcard_username_.empty()) {
+ wildcard_login_checker_.reset(new WildcardLoginChecker());
+ wildcard_login_checker_->StartWithAccessToken(
+ access_token,
+ base::Bind(&OnWildcardCheckCompleted, wildcard_username_));
+ }
+
if (service() && service()->IsInitializationComplete() &&
client() && !client()->is_registered()) {
OnOAuth2PolicyTokenFetched(
return client() && client()->is_registered();
}
+void UserCloudPolicyManagerChromeOS::EnableWildcardLoginCheck(
+ const std::string& username) {
+ DCHECK(access_token_.empty());
+ wildcard_username_ = username;
+}
+
void UserCloudPolicyManagerChromeOS::Shutdown() {
if (client())
client()->RemoveObserver(this);
if (service())
service()->RemoveObserver(this);
token_fetcher_.reset();
- component_policy_service_.reset();
external_data_manager_->Disconnect();
CloudPolicyManager::Shutdown();
}
return false;
if (domain == POLICY_DOMAIN_CHROME)
return !wait_for_policy_fetch_;
- if (ComponentCloudPolicyService::SupportsDomain(domain) &&
- component_policy_service_) {
- return component_policy_service_->is_initialized();
- }
return true;
}
-void UserCloudPolicyManagerChromeOS::RegisterPolicyDomain(
- scoped_refptr<const PolicyDomainDescriptor> descriptor) {
- if (ComponentCloudPolicyService::SupportsDomain(descriptor->domain()) &&
- component_policy_service_) {
- component_policy_service_->RegisterPolicyDomain(descriptor);
- }
-}
-
-scoped_ptr<PolicyBundle> UserCloudPolicyManagerChromeOS::CreatePolicyBundle() {
- scoped_ptr<PolicyBundle> bundle = CloudPolicyManager::CreatePolicyBundle();
- if (component_policy_service_)
- bundle->MergeFrom(component_policy_service_->policy());
- return bundle.Pass();
-}
-
void UserCloudPolicyManagerChromeOS::OnInitializationCompleted(
CloudPolicyService* cloud_policy_service) {
DCHECK_EQ(service(), cloud_policy_service);
cloud_policy_service->RemoveObserver(this);
time_init_completed_ = base::Time::Now();
- UMA_HISTOGRAM_TIMES(kUMADelayInitialization,
- time_init_completed_ - time_init_started_);
+ UMA_HISTOGRAM_MEDIUM_TIMES(kUMADelayInitialization,
+ time_init_completed_ - time_init_started_);
// If the CloudPolicyClient isn't registered at this stage then it needs an
// OAuth token for the initial registration.
if (wait_for_policy_fetch_) {
FetchPolicyOAuthTokenUsingSigninProfile();
} else if (!access_token_.empty()) {
- OnOAuth2PolicyTokenFetched(
- access_token_, GoogleServiceAuthError(GoogleServiceAuthError::NONE));
+ OnAccessTokenAvailable(access_token_);
}
}
if (wait_for_policy_fetch_) {
time_client_registered_ = base::Time::Now();
if (!time_token_available_.is_null()) {
- UMA_HISTOGRAM_TIMES(kUMAInitialFetchDelayClientRegister,
- time_client_registered_ - time_token_available_);
+ UMA_HISTOGRAM_MEDIUM_TIMES(
+ kUMAInitialFetchDelayClientRegister,
+ time_client_registered_ - time_token_available_);
}
// If we're blocked on the policy fetch, now is a good time to issue it.
CancelWaitForPolicyFetch();
}
-void UserCloudPolicyManagerChromeOS::OnComponentCloudPolicyRefreshNeeded() {
- core()->RefreshSoon();
-}
-
void UserCloudPolicyManagerChromeOS::OnComponentCloudPolicyUpdated() {
- CheckAndPublishPolicy();
+ CloudPolicyManager::OnComponentCloudPolicyUpdated();
StartRefreshSchedulerIfReady();
}
+void UserCloudPolicyManagerChromeOS::GetChromePolicy(PolicyMap* policy_map) {
+ CloudPolicyManager::GetChromePolicy(policy_map);
+
+ // Default multi-profile behavior for managed accounts to primary-only.
+ if (store()->has_policy() &&
+ !policy_map->Get(key::kChromeOsMultiProfileUserBehavior)) {
+ policy_map->Set(key::kChromeOsMultiProfileUserBehavior,
+ POLICY_LEVEL_MANDATORY,
+ POLICY_SCOPE_USER,
+ new base::StringValue("primary-only"),
+ NULL);
+ }
+}
+
void UserCloudPolicyManagerChromeOS::FetchPolicyOAuthTokenUsingSigninProfile() {
scoped_refptr<net::URLRequestContextGetter> signin_context;
Profile* signin_profile = chromeos::ProfileHelper::GetSigninProfile();
const std::string& policy_token,
const GoogleServiceAuthError& error) {
DCHECK(!client()->is_registered());
-
time_token_available_ = base::Time::Now();
if (wait_for_policy_fetch_) {
- UMA_HISTOGRAM_TIMES(kUMAInitialFetchDelayOAuth2Token,
- time_token_available_ - time_init_completed_);
+ UMA_HISTOGRAM_MEDIUM_TIMES(kUMAInitialFetchDelayOAuth2Token,
+ time_token_available_ - time_init_completed_);
}
if (error.state() == GoogleServiceAuthError::NONE) {
// Start client registration. Either OnRegistrationStateChanged() or
// OnClientError() will be called back.
- client()->Register(em::DeviceRegisterRequest::USER,
- policy_token, std::string(), false, std::string());
+ client()->Register(em::DeviceRegisterRequest::USER, policy_token,
+ std::string(), false, std::string(), std::string());
} else {
// Failed to get a token, stop waiting and use an empty policy.
CancelWaitForPolicyFetch();
void UserCloudPolicyManagerChromeOS::OnInitialPolicyFetchComplete(
bool success) {
const base::Time now = base::Time::Now();
- UMA_HISTOGRAM_TIMES(kUMAInitialFetchDelayPolicyFetch,
- now - time_client_registered_);
- UMA_HISTOGRAM_TIMES(kUMAInitialFetchDelayTotal, now - time_init_started_);
+ UMA_HISTOGRAM_MEDIUM_TIMES(kUMAInitialFetchDelayPolicyFetch,
+ now - time_client_registered_);
+ UMA_HISTOGRAM_MEDIUM_TIMES(kUMAInitialFetchDelayTotal,
+ now - time_init_started_);
+ CancelWaitForPolicyFetch();
+}
+
+void UserCloudPolicyManagerChromeOS::OnBlockingFetchTimeout() {
+ if (!wait_for_policy_fetch_)
+ return;
+ LOG(WARNING) << "Timed out while waiting for the initial policy fetch. "
+ << "The first session will start without policy.";
CancelWaitForPolicyFetch();
}
return;
wait_for_policy_fetch_ = false;
+ policy_fetch_timeout_.Stop();
CheckAndPublishPolicy();
// Now that |wait_for_policy_fetch_| is guaranteed to be false, the scheduler
// can be started.
if (!service() || !local_state_)
return; // Not connected.
- if (component_policy_service_ &&
- !component_policy_service_->is_initialized()) {
+ if (component_policy_service() &&
+ !component_policy_service()->is_initialized()) {
// If the client doesn't have the list of components to fetch yet then don't
// start the scheduler. The |component_policy_service_| will call back into
// OnComponentCloudPolicyUpdated() once it's ready.