Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 <algorithm> | |
| 7 #include <string> | 8 #include <string> |
| 8 #include <utility> | 9 #include <utility> |
| 9 | 10 |
| 10 #include "base/logging.h" | 11 #include "base/logging.h" |
| 11 #include "base/memory/ptr_util.h" | 12 #include "base/memory/ptr_util.h" |
| 13 #include "base/threading/thread_task_runner_handle.h" | |
| 12 #include "chromeos/dbus/auth_policy_client.h" | 14 #include "chromeos/dbus/auth_policy_client.h" |
| 13 #include "chromeos/dbus/dbus_thread_manager.h" | 15 #include "chromeos/dbus/dbus_thread_manager.h" |
| 14 #include "components/policy/core/common/policy_bundle.h" | 16 #include "components/policy/core/common/policy_bundle.h" |
| 15 #include "components/policy/core/common/policy_types.h" | 17 #include "components/policy/core/common/policy_types.h" |
| 16 #include "components/policy/policy_constants.h" | 18 #include "components/policy/policy_constants.h" |
| 17 | 19 |
| 20 namespace { | |
| 21 | |
| 22 // Refresh policy every 90 minutes which matches the Windows default: | |
| 23 // https://technet.microsoft.com/en-us/library/cc940895.aspx | |
| 24 constexpr int kRefreshIntervalSeconds = 90 * 60; | |
| 25 | |
| 26 // Minimum delay when scheduling a policy refresh task (to rule out the | |
|
emaxx
2017/01/24 15:54:26
Have I understood correctly that this constant is
Thiemo Nagel
2017/01/26 20:14:17
I also used it for re-scheduling when refresh_in_p
| |
| 27 // possibility of a re-scheduling storm). | |
| 28 constexpr int kMinSchedulingDelaySeconds = 1; | |
| 29 | |
| 30 } // namespace | |
| 31 | |
| 18 namespace policy { | 32 namespace policy { |
| 19 | 33 |
| 20 ActiveDirectoryPolicyManager::~ActiveDirectoryPolicyManager() {} | 34 ActiveDirectoryPolicyManager::~ActiveDirectoryPolicyManager() {} |
| 21 | 35 |
| 22 // static | 36 // static |
| 23 std::unique_ptr<ActiveDirectoryPolicyManager> | 37 std::unique_ptr<ActiveDirectoryPolicyManager> |
| 24 ActiveDirectoryPolicyManager::CreateForDevicePolicy( | 38 ActiveDirectoryPolicyManager::CreateForDevicePolicy( |
| 25 std::unique_ptr<CloudPolicyStore> store) { | 39 std::unique_ptr<CloudPolicyStore> store) { |
| 26 return base::WrapUnique( | 40 return base::WrapUnique( |
| 27 new ActiveDirectoryPolicyManager(EmptyAccountId(), std::move(store))); | 41 new ActiveDirectoryPolicyManager(EmptyAccountId(), std::move(store))); |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 40 ConfigurationPolicyProvider::Init(registry); | 54 ConfigurationPolicyProvider::Init(registry); |
| 41 | 55 |
| 42 store_->AddObserver(this); | 56 store_->AddObserver(this); |
| 43 if (!store_->is_initialized()) { | 57 if (!store_->is_initialized()) { |
| 44 store_->Load(); | 58 store_->Load(); |
| 45 } | 59 } |
| 46 | 60 |
| 47 // Does nothing if |store_| hasn't yet initialized. | 61 // Does nothing if |store_| hasn't yet initialized. |
| 48 PublishPolicy(); | 62 PublishPolicy(); |
| 49 | 63 |
| 50 RefreshPolicies(); | 64 ScheduleRefresh(); |
| 51 } | 65 } |
| 52 | 66 |
| 53 void ActiveDirectoryPolicyManager::Shutdown() { | 67 void ActiveDirectoryPolicyManager::Shutdown() { |
| 54 store_->RemoveObserver(this); | 68 store_->RemoveObserver(this); |
| 55 ConfigurationPolicyProvider::Shutdown(); | 69 ConfigurationPolicyProvider::Shutdown(); |
| 56 } | 70 } |
| 57 | 71 |
| 58 bool ActiveDirectoryPolicyManager::IsInitializationComplete( | 72 bool ActiveDirectoryPolicyManager::IsInitializationComplete( |
| 59 PolicyDomain domain) const { | 73 PolicyDomain domain) const { |
| 60 if (domain == POLICY_DOMAIN_CHROME) | 74 if (domain == POLICY_DOMAIN_CHROME) { |
| 61 return store_->is_initialized(); | 75 return store_->is_initialized(); |
| 76 } | |
| 62 return true; | 77 return true; |
| 63 } | 78 } |
| 64 | 79 |
| 65 void ActiveDirectoryPolicyManager::RefreshPolicies() { | 80 void ActiveDirectoryPolicyManager::RefreshPolicies() { |
| 66 chromeos::DBusThreadManager* thread_manager = | 81 chromeos::DBusThreadManager* thread_manager = |
| 67 chromeos::DBusThreadManager::Get(); | 82 chromeos::DBusThreadManager::Get(); |
| 68 DCHECK(thread_manager); | 83 DCHECK(thread_manager); |
| 69 chromeos::AuthPolicyClient* auth_policy_client = | 84 chromeos::AuthPolicyClient* auth_policy_client = |
| 70 thread_manager->GetAuthPolicyClient(); | 85 thread_manager->GetAuthPolicyClient(); |
| 71 DCHECK(auth_policy_client); | 86 DCHECK(auth_policy_client); |
| 87 | |
| 88 refresh_in_progress_ = true; | |
| 72 if (account_id_ == EmptyAccountId()) { | 89 if (account_id_ == EmptyAccountId()) { |
| 73 auth_policy_client->RefreshDevicePolicy( | 90 auth_policy_client->RefreshDevicePolicy( |
| 74 base::Bind(&ActiveDirectoryPolicyManager::OnPolicyRefreshed, | 91 base::Bind(&ActiveDirectoryPolicyManager::OnPolicyRefreshed, |
| 75 weak_ptr_factory_.GetWeakPtr())); | 92 weak_ptr_factory_.GetWeakPtr())); |
| 76 } else { | 93 } else { |
| 77 auth_policy_client->RefreshUserPolicy( | 94 auth_policy_client->RefreshUserPolicy( |
| 78 account_id_, | 95 account_id_, |
| 79 base::Bind(&ActiveDirectoryPolicyManager::OnPolicyRefreshed, | 96 base::Bind(&ActiveDirectoryPolicyManager::OnPolicyRefreshed, |
| 80 weak_ptr_factory_.GetWeakPtr())); | 97 weak_ptr_factory_.GetWeakPtr())); |
| 81 } | 98 } |
| 82 } | 99 } |
| 83 | 100 |
| 84 void ActiveDirectoryPolicyManager::OnStoreLoaded( | 101 void ActiveDirectoryPolicyManager::OnStoreLoaded( |
| 85 CloudPolicyStore* cloud_policy_store) { | 102 CloudPolicyStore* cloud_policy_store) { |
| 86 DCHECK_EQ(store_.get(), cloud_policy_store); | 103 DCHECK_EQ(store_.get(), cloud_policy_store); |
| 87 PublishPolicy(); | 104 PublishPolicy(); |
| 105 | |
| 106 refresh_in_progress_ = false; | |
|
emaxx
2017/01/24 15:54:26
Shouldn't this be done in OnPolicyRefreshed instea
Thiemo Nagel
2017/01/26 20:14:17
I think it's paired correctly for user-initiated f
| |
| 107 last_refresh_ = base::TimeTicks::Now(); | |
| 108 ScheduleRefresh(); | |
| 88 } | 109 } |
| 89 | 110 |
| 90 void ActiveDirectoryPolicyManager::OnStoreError( | 111 void ActiveDirectoryPolicyManager::OnStoreError( |
| 91 CloudPolicyStore* cloud_policy_store) { | 112 CloudPolicyStore* cloud_policy_store) { |
| 92 DCHECK_EQ(store_.get(), cloud_policy_store); | 113 DCHECK_EQ(store_.get(), cloud_policy_store); |
| 93 // Publish policy (even though it hasn't changed) in order to signal load | 114 // Publish policy (even though it hasn't changed) in order to signal load |
| 94 // complete on the ConfigurationPolicyProvider interface. Technically, this is | 115 // complete on the ConfigurationPolicyProvider interface. Technically, this is |
| 95 // only required on the first load, but doesn't hurt in any case. | 116 // only required on the first load, but doesn't hurt in any case. |
| 96 PublishPolicy(); | 117 PublishPolicy(); |
| 118 | |
| 119 refresh_in_progress_ = false; | |
| 120 last_refresh_ = base::TimeTicks::Now(); | |
| 121 ScheduleRefresh(); | |
| 97 } | 122 } |
| 98 | 123 |
| 99 ActiveDirectoryPolicyManager::ActiveDirectoryPolicyManager( | 124 ActiveDirectoryPolicyManager::ActiveDirectoryPolicyManager( |
| 100 const AccountId& account_id, | 125 const AccountId& account_id, |
| 101 std::unique_ptr<CloudPolicyStore> store) | 126 std::unique_ptr<CloudPolicyStore> store) |
| 102 : account_id_(account_id), | 127 : account_id_(account_id), |
| 103 store_(std::move(store)), | 128 store_(std::move(store)), |
| 129 refresh_interval_(base::TimeDelta::FromSeconds(kRefreshIntervalSeconds)), | |
| 130 min_scheduling_delay_( | |
| 131 base::TimeDelta::FromSeconds(kMinSchedulingDelaySeconds)), | |
| 104 weak_ptr_factory_(this) {} | 132 weak_ptr_factory_(this) {} |
| 105 | 133 |
| 106 void ActiveDirectoryPolicyManager::PublishPolicy() { | 134 void ActiveDirectoryPolicyManager::PublishPolicy() { |
| 107 if (!store_->is_initialized()) { | 135 if (!store_->is_initialized()) { |
| 108 return; | 136 return; |
| 109 } | 137 } |
| 110 std::unique_ptr<PolicyBundle> bundle = base::MakeUnique<PolicyBundle>(); | 138 std::unique_ptr<PolicyBundle> bundle = base::MakeUnique<PolicyBundle>(); |
| 111 PolicyMap& policy_map = | 139 PolicyMap& policy_map = |
| 112 bundle->Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())); | 140 bundle->Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())); |
| 113 policy_map.CopyFrom(store_->policy_map()); | 141 policy_map.CopyFrom(store_->policy_map()); |
| 114 | 142 |
| 115 // Overwrite the source which is POLICY_SOURCE_CLOUD by default. | 143 // Overwrite the source which is POLICY_SOURCE_CLOUD by default. |
| 116 // TODO(tnagel): Rename CloudPolicyStore to PolicyStore and make the source | 144 // TODO(tnagel): Rename CloudPolicyStore to PolicyStore and make the source |
| 117 // configurable, then drop PolicyMap::SetSourceForAll(). | 145 // configurable, then drop PolicyMap::SetSourceForAll(). |
| 118 policy_map.SetSourceForAll(POLICY_SOURCE_ACTIVE_DIRECTORY); | 146 policy_map.SetSourceForAll(POLICY_SOURCE_ACTIVE_DIRECTORY); |
| 119 SetEnterpriseUsersDefaults(&policy_map); | 147 SetEnterpriseUsersDefaults(&policy_map); |
| 120 UpdatePolicy(std::move(bundle)); | 148 UpdatePolicy(std::move(bundle)); |
| 121 } | 149 } |
| 122 | 150 |
| 123 void ActiveDirectoryPolicyManager::OnPolicyRefreshed(bool success) { | 151 void ActiveDirectoryPolicyManager::OnPolicyRefreshed(bool success) { |
| 124 if (!success) { | 152 if (!success) { |
| 125 LOG(ERROR) << "Active Directory policy refresh failed."; | 153 LOG(ERROR) << "Active Directory policy refresh failed."; |
| 126 } | 154 } |
| 127 // Load independently of success or failure to keep up to date with whatever | 155 // Load independently of success or failure to keep up to date with whatever |
| 128 // has happened on the authpolicyd / session manager side. | 156 // has happened on the authpolicyd / session manager side. |
| 129 store_->Load(); | 157 store_->Load(); |
| 130 } | 158 } |
| 131 | 159 |
| 160 void ActiveDirectoryPolicyManager::ScheduleRefresh() { | |
| 161 const base::TimeTicks now(base::TimeTicks::Now()); | |
| 162 base::TimeDelta delay(min_scheduling_delay_); | |
| 163 if (now < last_refresh_ + refresh_interval_) { | |
|
emaxx
2017/01/24 15:54:26
I'm feeling a bit uncomfortable with the possibili
Thiemo Nagel
2017/01/26 20:14:18
This calculation is written with default-initializ
| |
| 164 delay = std::max(delay, last_refresh_ + refresh_interval_ - now); | |
| 165 } | |
| 166 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | |
| 167 FROM_HERE, base::Bind(&ActiveDirectoryPolicyManager::RunScheduledRefresh, | |
| 168 weak_ptr_factory_.GetWeakPtr(), ++task_number_), | |
|
emaxx
2017/01/24 15:54:26
Maybe do the increment before the call? It's a bit
Thiemo Nagel
2017/01/26 20:14:17
Thanks, that's obsolete now.
| |
| 169 delay); | |
| 170 } | |
| 171 | |
| 172 void ActiveDirectoryPolicyManager::RunScheduledRefresh(int task_number) { | |
| 173 // There may be multiple tasks in the queue at the same time (e.g. after | |
|
emaxx
2017/01/24 15:54:26
Hmm... I was going to suggest using base::Cancelab
Thiemo Nagel
2017/01/26 20:14:17
Seems like a good idea! Posting ScheduleRefresh()
| |
| 174 // manual policy refresh) but only the one that carries the current | |
| 175 // |task_number_| is valid. | |
| 176 if (task_number != task_number_) { | |
| 177 return; | |
| 178 } | |
| 179 | |
| 180 // Re-schedule in case the intended refresh interval has not yet been reached | |
|
emaxx
2017/01/24 15:54:26
Why is this really necessary? Shouldn't all the ca
Thiemo Nagel
2017/01/26 20:14:17
Seems a valid argument. ;)
| |
| 181 // (e.g. because of a manual policy fetch in between two scheduled fetches) or | |
| 182 // when a refresh is currently in progress (to avoid refresh jobs piling up | |
| 183 // behind each other which could possibly lead to resource exhaustion). | |
| 184 if (base::TimeTicks::Now() - last_refresh_ < refresh_interval_ || | |
| 185 refresh_in_progress_) { | |
| 186 ScheduleRefresh(); | |
| 187 return; | |
| 188 } | |
| 189 | |
| 190 RefreshPolicies(); | |
| 191 } | |
| 192 | |
| 132 } // namespace policy | 193 } // namespace policy |
| OLD | NEW |