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 // Most of this code is copied from: | 5 // Most of this code is copied from: |
6 // src/chrome/browser/policy/asynchronous_policy_loader.{h,cc} | 6 // src/chrome/browser/policy/asynchronous_policy_loader.{h,cc} |
7 | 7 |
8 #include "remoting/host/policy_hack/policy_watcher.h" | 8 #include "remoting/host/policy_hack/policy_watcher.h" |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
112 | 112 |
113 const char PolicyWatcher::kUdpPortRangePolicyName[] = | 113 const char PolicyWatcher::kUdpPortRangePolicyName[] = |
114 "RemoteAccessHostUdpPortRange"; | 114 "RemoteAccessHostUdpPortRange"; |
115 | 115 |
116 const char PolicyWatcher::kHostDebugOverridePoliciesName[] = | 116 const char PolicyWatcher::kHostDebugOverridePoliciesName[] = |
117 "RemoteAccessHostDebugOverridePolicies"; | 117 "RemoteAccessHostDebugOverridePolicies"; |
118 | 118 |
119 PolicyWatcher::PolicyWatcher( | 119 PolicyWatcher::PolicyWatcher( |
120 scoped_refptr<base::SingleThreadTaskRunner> task_runner) | 120 scoped_refptr<base::SingleThreadTaskRunner> task_runner) |
121 : task_runner_(task_runner), | 121 : task_runner_(task_runner), |
122 transient_policy_error_retry_counter_(0), | |
122 old_policies_(new base::DictionaryValue()), | 123 old_policies_(new base::DictionaryValue()), |
123 default_values_(new base::DictionaryValue()), | 124 default_values_(new base::DictionaryValue()), |
124 weak_factory_(this) { | 125 weak_factory_(this) { |
125 // Initialize the default values for each policy. | 126 // Initialize the default values for each policy. |
126 default_values_->SetBoolean(kNatPolicyName, true); | 127 default_values_->SetBoolean(kNatPolicyName, true); |
127 default_values_->SetBoolean(kHostRequireTwoFactorPolicyName, false); | 128 default_values_->SetBoolean(kHostRequireTwoFactorPolicyName, false); |
128 default_values_->SetBoolean(kHostRequireCurtainPolicyName, false); | 129 default_values_->SetBoolean(kHostRequireCurtainPolicyName, false); |
129 default_values_->SetBoolean(kHostMatchUsernamePolicyName, false); | 130 default_values_->SetBoolean(kHostMatchUsernamePolicyName, false); |
130 default_values_->SetString(kHostDomainPolicyName, std::string()); | 131 default_values_->SetString(kHostDomainPolicyName, std::string()); |
131 default_values_->SetString(kHostTalkGadgetPrefixPolicyName, | 132 default_values_->SetString(kHostTalkGadgetPrefixPolicyName, |
(...skipping 13 matching lines...) Expand all Loading... | |
145 // Initialize the fall-back values to use for unreadable policies. | 146 // Initialize the fall-back values to use for unreadable policies. |
146 // For most policies these match the defaults. | 147 // For most policies these match the defaults. |
147 bad_type_values_.reset(default_values_->DeepCopy()); | 148 bad_type_values_.reset(default_values_->DeepCopy()); |
148 bad_type_values_->SetBoolean(kNatPolicyName, false); | 149 bad_type_values_->SetBoolean(kNatPolicyName, false); |
149 bad_type_values_->SetBoolean(kRelayPolicyName, false); | 150 bad_type_values_->SetBoolean(kRelayPolicyName, false); |
150 } | 151 } |
151 | 152 |
152 PolicyWatcher::~PolicyWatcher() { | 153 PolicyWatcher::~PolicyWatcher() { |
153 } | 154 } |
154 | 155 |
155 void PolicyWatcher::StartWatching(const PolicyCallback& policy_callback) { | 156 void PolicyWatcher::StartWatching( |
157 const PolicyUpdatedCallback& policy_updated_callback, | |
158 const PolicyErrorCallback& policy_error_callback) { | |
156 if (!OnPolicyWatcherThread()) { | 159 if (!OnPolicyWatcherThread()) { |
157 task_runner_->PostTask(FROM_HERE, | 160 task_runner_->PostTask(FROM_HERE, |
158 base::Bind(&PolicyWatcher::StartWatching, | 161 base::Bind(&PolicyWatcher::StartWatching, |
159 base::Unretained(this), | 162 base::Unretained(this), |
160 policy_callback)); | 163 policy_updated_callback, |
164 policy_error_callback)); | |
161 return; | 165 return; |
162 } | 166 } |
163 | 167 |
164 policy_callback_ = policy_callback; | 168 policy_updated_callback_ = policy_updated_callback; |
169 policy_error_callback_ = policy_error_callback; | |
165 StartWatchingInternal(); | 170 StartWatchingInternal(); |
166 } | 171 } |
167 | 172 |
168 void PolicyWatcher::StopWatching(base::WaitableEvent* done) { | 173 void PolicyWatcher::StopWatching(base::WaitableEvent* done) { |
169 if (!OnPolicyWatcherThread()) { | 174 if (!OnPolicyWatcherThread()) { |
170 task_runner_->PostTask(FROM_HERE, | 175 task_runner_->PostTask(FROM_HERE, |
171 base::Bind(&PolicyWatcher::StopWatching, | 176 base::Bind(&PolicyWatcher::StopWatching, |
172 base::Unretained(this), done)); | 177 base::Unretained(this), done)); |
173 return; | 178 return; |
174 } | 179 } |
175 | 180 |
176 StopWatchingInternal(); | 181 StopWatchingInternal(); |
177 weak_factory_.InvalidateWeakPtrs(); | 182 weak_factory_.InvalidateWeakPtrs(); |
178 policy_callback_.Reset(); | 183 policy_updated_callback_.Reset(); |
184 policy_error_callback_.Reset(); | |
179 | 185 |
180 done->Signal(); | 186 done->Signal(); |
181 } | 187 } |
182 | 188 |
183 void PolicyWatcher::ScheduleFallbackReloadTask() { | 189 void PolicyWatcher::ScheduleFallbackReloadTask() { |
184 DCHECK(OnPolicyWatcherThread()); | 190 DCHECK(OnPolicyWatcherThread()); |
185 ScheduleReloadTask( | 191 ScheduleReloadTask( |
186 base::TimeDelta::FromMinutes(kFallbackReloadDelayMinutes)); | 192 base::TimeDelta::FromMinutes(kFallbackReloadDelayMinutes)); |
187 } | 193 } |
188 | 194 |
(...skipping 10 matching lines...) Expand all Loading... | |
199 } | 205 } |
200 | 206 |
201 bool PolicyWatcher::OnPolicyWatcherThread() const { | 207 bool PolicyWatcher::OnPolicyWatcherThread() const { |
202 return task_runner_->BelongsToCurrentThread(); | 208 return task_runner_->BelongsToCurrentThread(); |
203 } | 209 } |
204 | 210 |
205 void PolicyWatcher::UpdatePolicies( | 211 void PolicyWatcher::UpdatePolicies( |
206 const base::DictionaryValue* new_policies_raw) { | 212 const base::DictionaryValue* new_policies_raw) { |
207 DCHECK(OnPolicyWatcherThread()); | 213 DCHECK(OnPolicyWatcherThread()); |
208 | 214 |
215 transient_policy_error_retry_counter_ = 0; | |
216 | |
209 // Use default values for any missing policies. | 217 // Use default values for any missing policies. |
210 scoped_ptr<base::DictionaryValue> new_policies = | 218 scoped_ptr<base::DictionaryValue> new_policies = |
211 CopyGoodValuesAndAddDefaults( | 219 CopyGoodValuesAndAddDefaults( |
212 new_policies_raw, default_values_.get(), bad_type_values_.get()); | 220 new_policies_raw, default_values_.get(), bad_type_values_.get()); |
213 | 221 |
214 // Find the changed policies. | 222 // Find the changed policies. |
215 scoped_ptr<base::DictionaryValue> changed_policies( | 223 scoped_ptr<base::DictionaryValue> changed_policies( |
216 new base::DictionaryValue()); | 224 new base::DictionaryValue()); |
217 base::DictionaryValue::Iterator iter(*new_policies); | 225 base::DictionaryValue::Iterator iter(*new_policies); |
218 while (!iter.IsAtEnd()) { | 226 while (!iter.IsAtEnd()) { |
219 base::Value* old_policy; | 227 base::Value* old_policy; |
220 if (!(old_policies_->Get(iter.key(), &old_policy) && | 228 if (!(old_policies_->Get(iter.key(), &old_policy) && |
221 old_policy->Equals(&iter.value()))) { | 229 old_policy->Equals(&iter.value()))) { |
222 changed_policies->Set(iter.key(), iter.value().DeepCopy()); | 230 changed_policies->Set(iter.key(), iter.value().DeepCopy()); |
223 } | 231 } |
224 iter.Advance(); | 232 iter.Advance(); |
225 } | 233 } |
226 | 234 |
227 // Save the new policies. | 235 // Save the new policies. |
228 old_policies_.swap(new_policies); | 236 old_policies_.swap(new_policies); |
229 | 237 |
230 // Notify our client of the changed policies. | 238 // Notify our client of the changed policies. |
231 if (!changed_policies->empty()) { | 239 if (!changed_policies->empty()) { |
232 policy_callback_.Run(changed_policies.Pass()); | 240 policy_updated_callback_.Run(changed_policies.Pass()); |
233 } | 241 } |
234 } | 242 } |
235 | 243 |
244 void PolicyWatcher::SignalPolicyError() { | |
245 policy_error_callback_.Run(); | |
Lambros
2014/11/13 00:30:26
Depending on what you think should happen, you mig
Łukasz Anforowicz
2014/11/13 17:48:08
Good point. Done.
| |
246 } | |
247 | |
248 void PolicyWatcher::SignalTransientPolicyError() { | |
249 // TODO(lukasza): max=5 helps recover from transient errors of short | |
250 // duration (i.e. reading a partially written file), | |
Lambros
2014/11/13 00:30:26
nit: Don't indent the whole TODO block. See exampl
| |
251 // but won't help with longer problems (i.e. malformed | |
252 // policy pushed out via group policy or puppet will | |
253 // most likely still trigger SignalPolicyError) | |
Lambros
2014/11/13 00:30:26
Is it this class's responsibility to figure out wh
Łukasz Anforowicz
2014/11/13 17:48:08
Good point on documenting in the header the curren
| |
254 // Potential solution #1: keep the host running in | |
255 // security-lock-down mode to keep reparsing the policies | |
256 // (i.e. don't call Shutdown in me2me's OnPolicyError) | |
257 // Potential solution #2: maybe retry at init.d-level? | |
258 // Potential solution #3: maybe using Chrome-wide policy | |
259 // libraries rather than policy_hack will help? | |
260 const int MAX_RETRY_COUNT = 5; | |
Lambros
2014/11/13 00:30:27
nit: kMaxRetryCount
Łukasz Anforowicz
2014/11/13 17:48:08
Done.
| |
261 transient_policy_error_retry_counter_ += 1; | |
262 if (transient_policy_error_retry_counter_ >= MAX_RETRY_COUNT) { | |
263 SignalPolicyError(); | |
264 } | |
265 } | |
266 | |
236 } // namespace policy_hack | 267 } // namespace policy_hack |
237 } // namespace remoting | 268 } // namespace remoting |
OLD | NEW |