Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(45)

Side by Side Diff: chrome/browser/chromeos/policy/active_directory_policy_manager.cc

Issue 2954293002: Chromad: Prevent session from starting without policy (Closed)
Patch Set: Address nits Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 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 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/policy/active_directory_policy_manager.h" 5 #include "chrome/browser/chromeos/policy/active_directory_policy_manager.h"
6 6
7 #include <string> 7 #include <string>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 13 matching lines...) Expand all
24 } // namespace 24 } // namespace
25 25
26 namespace policy { 26 namespace policy {
27 27
28 ActiveDirectoryPolicyManager::~ActiveDirectoryPolicyManager() {} 28 ActiveDirectoryPolicyManager::~ActiveDirectoryPolicyManager() {}
29 29
30 // static 30 // static
31 std::unique_ptr<ActiveDirectoryPolicyManager> 31 std::unique_ptr<ActiveDirectoryPolicyManager>
32 ActiveDirectoryPolicyManager::CreateForDevicePolicy( 32 ActiveDirectoryPolicyManager::CreateForDevicePolicy(
33 std::unique_ptr<CloudPolicyStore> store) { 33 std::unique_ptr<CloudPolicyStore> store) {
34 return base::WrapUnique( 34 // Can't use MakeUnique<> because the constructor is private.
35 new ActiveDirectoryPolicyManager(EmptyAccountId(), std::move(store))); 35 return base::WrapUnique(new ActiveDirectoryPolicyManager(
36 EmptyAccountId(), false, base::TimeDelta(), base::OnceClosure(),
37 std::move(store)));
36 } 38 }
37 39
38 // static 40 // static
39 std::unique_ptr<ActiveDirectoryPolicyManager> 41 std::unique_ptr<ActiveDirectoryPolicyManager>
40 ActiveDirectoryPolicyManager::CreateForUserPolicy( 42 ActiveDirectoryPolicyManager::CreateForUserPolicy(
41 const AccountId& account_id, 43 const AccountId& account_id,
44 bool wait_for_policy_fetch,
45 base::TimeDelta initial_policy_fetch_timeout,
46 base::OnceClosure exit_session,
42 std::unique_ptr<CloudPolicyStore> store) { 47 std::unique_ptr<CloudPolicyStore> store) {
43 return base::WrapUnique( 48 // Can't use MakeUnique<> because the constructor is private.
44 new ActiveDirectoryPolicyManager(account_id, std::move(store))); 49 return base::WrapUnique(new ActiveDirectoryPolicyManager(
50 account_id, wait_for_policy_fetch, initial_policy_fetch_timeout,
51 std::move(exit_session), std::move(store)));
45 } 52 }
46 53
47 void ActiveDirectoryPolicyManager::Init(SchemaRegistry* registry) { 54 void ActiveDirectoryPolicyManager::Init(SchemaRegistry* registry) {
48 ConfigurationPolicyProvider::Init(registry); 55 ConfigurationPolicyProvider::Init(registry);
49 56
50 store_->AddObserver(this); 57 store_->AddObserver(this);
51 if (!store_->is_initialized()) { 58 if (!store_->is_initialized()) {
52 store_->Load(); 59 store_->Load();
53 } 60 }
54 61
55 // Does nothing if |store_| hasn't yet initialized. 62 // Does nothing if |store_| hasn't yet initialized.
56 PublishPolicy(); 63 PublishPolicy();
57 64
58 scheduler_ = base::MakeUnique<PolicyScheduler>( 65 scheduler_ = base::MakeUnique<PolicyScheduler>(
59 base::BindRepeating(&ActiveDirectoryPolicyManager::DoFetch, 66 base::BindRepeating(&ActiveDirectoryPolicyManager::DoPolicyFetch,
60 weak_ptr_factory_.GetWeakPtr()), 67 weak_ptr_factory_.GetWeakPtr()),
61 base::BindRepeating(&ActiveDirectoryPolicyManager::OnPolicyFetched, 68 base::BindRepeating(&ActiveDirectoryPolicyManager::OnPolicyFetched,
62 weak_ptr_factory_.GetWeakPtr()), 69 weak_ptr_factory_.GetWeakPtr()),
63 kFetchInterval); 70 kFetchInterval);
64 } 71 }
65 72
66 void ActiveDirectoryPolicyManager::Shutdown() { 73 void ActiveDirectoryPolicyManager::Shutdown() {
67 store_->RemoveObserver(this); 74 store_->RemoveObserver(this);
68 ConfigurationPolicyProvider::Shutdown(); 75 ConfigurationPolicyProvider::Shutdown();
69 } 76 }
70 77
71 bool ActiveDirectoryPolicyManager::IsInitializationComplete( 78 bool ActiveDirectoryPolicyManager::IsInitializationComplete(
72 PolicyDomain domain) const { 79 PolicyDomain domain) const {
80 if (waiting_for_initial_policy_fetch_) {
81 return false;
82 }
73 if (domain == POLICY_DOMAIN_CHROME) { 83 if (domain == POLICY_DOMAIN_CHROME) {
74 return store_->is_initialized(); 84 return store_->is_initialized();
75 } 85 }
76 return true; 86 return true;
77 } 87 }
78 88
79 void ActiveDirectoryPolicyManager::RefreshPolicies() { 89 void ActiveDirectoryPolicyManager::RefreshPolicies() {
80 scheduler_->ScheduleTaskNow(); 90 scheduler_->ScheduleTaskNow();
81 } 91 }
82 92
83 void ActiveDirectoryPolicyManager::OnStoreLoaded( 93 void ActiveDirectoryPolicyManager::OnStoreLoaded(
84 CloudPolicyStore* cloud_policy_store) { 94 CloudPolicyStore* cloud_policy_store) {
85 DCHECK_EQ(store_.get(), cloud_policy_store); 95 DCHECK_EQ(store_.get(), cloud_policy_store);
86 PublishPolicy(); 96 PublishPolicy();
97 if (fetch_ever_completed_) {
98 // Policy is guaranteed to be up to date with the previous fetch result
99 // because OnPolicyFetched() cancels any potentially running Load()
100 // operations.
101 CancelWaitForInitialPolicy(fetch_ever_succeeded_ /* success */);
102 }
87 } 103 }
88 104
89 void ActiveDirectoryPolicyManager::OnStoreError( 105 void ActiveDirectoryPolicyManager::OnStoreError(
90 CloudPolicyStore* cloud_policy_store) { 106 CloudPolicyStore* cloud_policy_store) {
91 DCHECK_EQ(store_.get(), cloud_policy_store); 107 DCHECK_EQ(store_.get(), cloud_policy_store);
92 // Publish policy (even though it hasn't changed) in order to signal load 108 // Publish policy (even though it hasn't changed) in order to signal load
93 // complete on the ConfigurationPolicyProvider interface. Technically, this is 109 // complete on the ConfigurationPolicyProvider interface. Technically, this is
94 // only required on the first load, but doesn't hurt in any case. 110 // only required on the first load, but doesn't hurt in any case.
95 PublishPolicy(); 111 PublishPolicy();
112 if (fetch_ever_completed_) {
113 CancelWaitForInitialPolicy(false /* success */);
114 }
115 }
116
117 void ActiveDirectoryPolicyManager::ForceTimeoutForTest() {
118 DCHECK(initial_policy_timeout_.IsRunning());
119 // Stop the timer to mimic what happens when a real timer fires, then invoke
120 // the timer callback directly.
121 initial_policy_timeout_.Stop();
122 OnBlockingFetchTimeout();
96 } 123 }
97 124
98 ActiveDirectoryPolicyManager::ActiveDirectoryPolicyManager( 125 ActiveDirectoryPolicyManager::ActiveDirectoryPolicyManager(
99 const AccountId& account_id, 126 const AccountId& account_id,
127 bool wait_for_policy_fetch,
128 base::TimeDelta initial_policy_fetch_timeout,
129 base::OnceClosure exit_session,
100 std::unique_ptr<CloudPolicyStore> store) 130 std::unique_ptr<CloudPolicyStore> store)
101 : account_id_(account_id), store_(std::move(store)) {} 131 : account_id_(account_id),
132 waiting_for_initial_policy_fetch_(wait_for_policy_fetch),
133 exit_session_(std::move(exit_session)),
134 store_(std::move(store)) {
135 // Delaying initialization complete is intended for user policy only.
136 DCHECK(!(account_id == EmptyAccountId() && wait_for_policy_fetch));
137 DCHECK_NE(wait_for_policy_fetch, initial_policy_fetch_timeout.is_zero());
stevenjb 2017/07/17 16:07:37 nit: Do we need |wait_for_policy_fetch| as a param
Thiemo Nagel 2017/07/18 13:02:18 I like that very much. Thanks!
138 initial_policy_fetch_may_fail_ = !initial_policy_fetch_timeout.is_max();
139 if (wait_for_policy_fetch && !initial_policy_fetch_timeout.is_max()) {
140 initial_policy_timeout_.Start(
141 FROM_HERE, initial_policy_fetch_timeout,
142 base::Bind(&ActiveDirectoryPolicyManager::OnBlockingFetchTimeout,
143 weak_ptr_factory_.GetWeakPtr()));
144 }
145 }
102 146
103 void ActiveDirectoryPolicyManager::PublishPolicy() { 147 void ActiveDirectoryPolicyManager::PublishPolicy() {
104 if (!store_->is_initialized()) { 148 if (!store_->is_initialized()) {
105 return; 149 return;
106 } 150 }
107 std::unique_ptr<PolicyBundle> bundle = base::MakeUnique<PolicyBundle>(); 151 std::unique_ptr<PolicyBundle> bundle = base::MakeUnique<PolicyBundle>();
108 PolicyMap& policy_map = 152 PolicyMap& policy_map =
109 bundle->Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())); 153 bundle->Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()));
110 policy_map.CopyFrom(store_->policy_map()); 154 policy_map.CopyFrom(store_->policy_map());
111 155
112 // Overwrite the source which is POLICY_SOURCE_CLOUD by default. 156 // Overwrite the source which is POLICY_SOURCE_CLOUD by default.
113 // TODO(tnagel): Rename CloudPolicyStore to PolicyStore and make the source 157 // TODO(tnagel): Rename CloudPolicyStore to PolicyStore and make the source
114 // configurable, then drop PolicyMap::SetSourceForAll(). 158 // configurable, then drop PolicyMap::SetSourceForAll().
115 policy_map.SetSourceForAll(POLICY_SOURCE_ACTIVE_DIRECTORY); 159 policy_map.SetSourceForAll(POLICY_SOURCE_ACTIVE_DIRECTORY);
116 SetEnterpriseUsersDefaults(&policy_map); 160 SetEnterpriseUsersDefaults(&policy_map);
117 UpdatePolicy(std::move(bundle)); 161 UpdatePolicy(std::move(bundle));
118 } 162 }
119 163
120 void ActiveDirectoryPolicyManager::DoFetch( 164 void ActiveDirectoryPolicyManager::DoPolicyFetch(
121 base::OnceCallback<void(bool success)> callback) { 165 base::OnceCallback<void(bool success)> callback) {
122 chromeos::DBusThreadManager* thread_manager = 166 chromeos::DBusThreadManager* thread_manager =
123 chromeos::DBusThreadManager::Get(); 167 chromeos::DBusThreadManager::Get();
124 DCHECK(thread_manager); 168 DCHECK(thread_manager);
125 chromeos::AuthPolicyClient* auth_policy_client = 169 chromeos::AuthPolicyClient* auth_policy_client =
126 thread_manager->GetAuthPolicyClient(); 170 thread_manager->GetAuthPolicyClient();
127 DCHECK(auth_policy_client); 171 DCHECK(auth_policy_client);
128 if (account_id_ == EmptyAccountId()) { 172 if (account_id_ == EmptyAccountId()) {
129 auth_policy_client->RefreshDevicePolicy(std::move(callback)); 173 auth_policy_client->RefreshDevicePolicy(std::move(callback));
130 } else { 174 } else {
131 auth_policy_client->RefreshUserPolicy(account_id_, std::move(callback)); 175 auth_policy_client->RefreshUserPolicy(account_id_, std::move(callback));
132 } 176 }
133 } 177 }
134 178
135 void ActiveDirectoryPolicyManager::OnPolicyFetched(bool success) { 179 void ActiveDirectoryPolicyManager::OnPolicyFetched(bool success) {
136 if (!success) { 180 fetch_ever_completed_ = true;
181 if (success) {
182 fetch_ever_succeeded_ = true;
183 } else {
137 LOG(ERROR) << "Active Directory policy fetch failed."; 184 LOG(ERROR) << "Active Directory policy fetch failed.";
185 if (store_->is_initialized()) {
186 CancelWaitForInitialPolicy(false /* success */);
187 }
138 } 188 }
139 // Load independently of success or failure to keep up to date with whatever 189 // Load independently of success or failure to keep in sync with the state in
140 // has happened on the authpolicyd / session manager side. 190 // session manager. This cancels any potentially running Load() operations
191 // thus it is guaranteed that at the next OnStoreLoaded() invocation the
192 // policy is up-to-date with what was fetched.
141 store_->Load(); 193 store_->Load();
142 } 194 }
143 195
196 void ActiveDirectoryPolicyManager::OnBlockingFetchTimeout() {
197 DCHECK(waiting_for_initial_policy_fetch_);
198 LOG(WARNING) << "Timed out while waiting for the policy fetch. "
199 << "The session will start with the cached policy.";
200 CancelWaitForInitialPolicy(false);
201 }
202
203 void ActiveDirectoryPolicyManager::CancelWaitForInitialPolicy(bool success) {
204 if (!waiting_for_initial_policy_fetch_)
205 return;
206
207 initial_policy_timeout_.Stop();
208
209 // If the conditions to continue profile initialization are not met, the user
210 // session is exited and initialization is not set as completed.
211 // TODO(tnagel): Maybe add code to retry policy fetch?
212 if (!store_->has_policy()) {
213 // If there's no policy at all (not even cached) the user session must not
214 // continue.
215 LOG(ERROR) << "Policy could not be obtained. "
216 << "Aborting profile initialization";
217 // Prevent duplicate exit session calls.
218 if (exit_session_) {
219 std::move(exit_session_).Run();
220 }
221 return;
222 }
223 if (!success && !initial_policy_fetch_may_fail_) {
224 LOG(ERROR) << "Policy fetch failed for the user. "
225 << "Aborting profile initialization";
226 // Prevent duplicate exit session calls.
227 if (exit_session_) {
228 std::move(exit_session_).Run();
229 }
230 return;
231 }
232
233 // Set initialization complete.
234 waiting_for_initial_policy_fetch_ = false;
235
236 // Publish policy (even though it hasn't changed) in order to signal load
237 // complete on the ConfigurationPolicyProvider interface.
238 PublishPolicy();
239 }
240
144 } // namespace policy 241 } // namespace policy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698