1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261
|
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_UPDATER_POLICY_SERVICE_H_
#define CHROME_UPDATER_POLICY_SERVICE_H_
#include <optional>
#include <set>
#include <string>
#include <vector>
#include "base/containers/flat_map.h"
#include "base/functional/callback_forward.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_refptr.h"
#include "base/sequence_checker.h"
#include "base/time/time.h"
#include "base/values.h"
#include "chrome/updater/external_constants.h"
#include "chrome/updater/persisted_data.h"
#include "chrome/updater/policy/manager.h"
namespace policy {
enum class PolicyFetchReason;
} // namespace policy
namespace updater {
class PolicyFetcher;
// This class contains the aggregate status of a policy value. It determines
// whether a conflict exists when multiple policy providers set the same policy.
// Instances are logically true if an effective policy is set.
template <typename T>
class PolicyStatus {
public:
struct Entry {
Entry(const std::string& s, T p) : source(s), policy(p) {}
std::string source;
T policy{};
};
PolicyStatus() = default;
PolicyStatus(const PolicyStatus&) = default;
PolicyStatus& operator=(const PolicyStatus&) = default;
void AddPolicyIfNeeded(bool is_managed,
const std::string& source,
const T& policy) {
if (conflict_policy_) {
return; // We already have enough policies.
}
if (!effective_policy_ && is_managed) {
effective_policy_ = std::make_optional<Entry>(source, policy);
} else if (effective_policy_ &&
policy != effective_policy_.value().policy) {
conflict_policy_ = std::make_optional<Entry>(source, policy);
}
}
const std::optional<Entry>& effective_policy() const {
return effective_policy_;
}
const std::optional<Entry>& conflict_policy() const {
return conflict_policy_;
}
std::optional<T> effective_policy_value() const {
return effective_policy_ ? std::optional<T>(effective_policy_->policy)
: std::nullopt;
}
explicit operator bool() const { return effective_policy_.has_value(); }
// Convenience method to extract the effective policy's value.
const T& policy() const {
CHECK(effective_policy_);
return effective_policy_->policy;
}
const T& policy_or(const T& fallback) const {
return effective_policy_ ? policy() : fallback;
}
private:
std::optional<Entry> effective_policy_;
std::optional<Entry> conflict_policy_;
};
// The PolicyService returns policies for enterprise managed machines from the
// source with the highest priority where the policy available.
// This class is sequence affine and its instance is bound to the main sequence.
class PolicyService : public base::RefCountedThreadSafe<PolicyService> {
public:
class PolicyManagers {
public:
explicit PolicyManagers(
scoped_refptr<ExternalConstants> external_constants);
~PolicyManagers();
void ResetDeviceManagementManager(
scoped_refptr<PolicyManagerInterface> dm_manager);
std::vector<scoped_refptr<PolicyManagerInterface>> managers() const {
return managers_;
}
void SetManagersForTesting(
std::vector<scoped_refptr<PolicyManagerInterface>> managers);
private:
void CreateManagers(scoped_refptr<ExternalConstants> external_constants);
void InitializeManagersVector();
void SortManagersVector();
static bool CloudPolicyOverridesPlatformPolicy(
const std::vector<scoped_refptr<PolicyManagerInterface>>& providers);
std::vector<scoped_refptr<PolicyManagerInterface>> managers_;
scoped_refptr<PolicyManagerInterface> dm_policy_manager_;
scoped_refptr<PolicyManagerInterface> external_constants_policy_manager_;
scoped_refptr<PolicyManagerInterface> platform_policy_manager_;
scoped_refptr<PolicyManagerInterface> default_policy_manager_;
};
PolicyService(scoped_refptr<ExternalConstants> external_constants,
scoped_refptr<PersistedData> persisted_data);
PolicyService(const PolicyService&) = delete;
PolicyService& operator=(const PolicyService&) = delete;
// Fetches policies from device management and updates the PolicyService
// instance. `callback` is passed a result that is `kErrorOk` on success,
// `kErrorDMRegistrationFailed` if DM registration fails, or any other error.
// While a call to FetchPolicies is outstanding (i.e. has not invoked the
// callback), concurrent calls to FetchPolicies will reuse the results of the
// outstanding request.
void FetchPolicies(policy::PolicyFetchReason reason,
base::OnceCallback<void(int)> callback);
std::string source() const;
// These methods call and aggregate the results from the policy managers.
PolicyStatus<bool> CloudPolicyOverridesPlatformPolicy() const;
PolicyStatus<base::TimeDelta> GetLastCheckPeriod() const;
PolicyStatus<UpdatesSuppressedTimes> GetUpdatesSuppressedTimes() const;
PolicyStatus<std::string> GetDownloadPreference() const;
PolicyStatus<int> GetPackageCacheSizeLimitMBytes() const;
PolicyStatus<int> GetPackageCacheExpirationTimeDays() const;
PolicyStatus<int> GetPolicyForAppInstalls(const std::string& app_id) const;
PolicyStatus<int> GetPolicyForAppUpdates(const std::string& app_id) const;
PolicyStatus<std::string> GetTargetChannel(const std::string& app_id) const;
PolicyStatus<std::string> GetTargetVersionPrefix(
const std::string& app_id) const;
PolicyStatus<bool> IsRollbackToTargetVersionAllowed(
const std::string& app_id) const;
PolicyStatus<int> GetMajorVersionRolloutPolicy(
const std::string& app_id) const;
PolicyStatus<int> GetMinorVersionRolloutPolicy(
const std::string& app_id) const;
PolicyStatus<std::string> GetProxyMode() const;
PolicyStatus<std::string> GetProxyPacUrl() const;
PolicyStatus<std::string> GetProxyServer() const;
PolicyStatus<std::vector<std::string>> GetForceInstallApps() const;
// DEPRECATED: Prefer |GetLastCheckPeriod|. This function should only be used
// in legacy interfaces where a PolicyStatus<int> is required.
PolicyStatus<int> DeprecatedGetLastCheckPeriodMinutes() const;
// Helper methods.
base::Value GetAllPolicies() const;
std::string GetAllPoliciesAsString() const;
bool AreUpdatesSuppressedNow(base::Time now = base::Time::Now()) const;
void SetManagersForTesting(
std::vector<scoped_refptr<PolicyManagerInterface>> managers);
protected:
virtual ~PolicyService();
private:
friend class base::RefCountedThreadSafe<PolicyService>;
template <typename T>
using PolicyQueryFunction =
std::optional<T> (PolicyManagerInterface::*)() const;
template <typename T>
using AppPolicyQueryFunction =
std::optional<T> (PolicyManagerInterface::*)(const std::string&) const;
void DoFetchPolicies(policy::PolicyFetchReason reason,
base::OnceCallback<void(int)> callback,
bool has_enrollment_token);
// Called when `FetchPolicies` has completed. If `dm_policy_manager` is valid,
// the policy managers within the policy service are reloaded/reset with the
// provided DM policy manager.
void FetchPoliciesDone(
scoped_refptr<PolicyFetcher> fetcher,
int result,
scoped_refptr<PolicyManagerInterface> dm_policy_manager);
// Queries the policy from the managed policy providers and determines the
// policy status. The provided `transform` can be used to modify the queried
// value to be a different type, or to nullify it when invalid.
template <typename T, typename U = T>
PolicyStatus<U> QueryPolicy(
PolicyQueryFunction<T> policy_query_function,
const base::RepeatingCallback<std::optional<U>(std::optional<T>)>&
transform = base::NullCallback()) const;
// Queries app policy from the managed policy providers and determines the
// policy status.
template <typename T>
PolicyStatus<T> QueryAppPolicy(
AppPolicyQueryFunction<T> policy_query_function,
const std::string& app_id) const;
std::set<std::string> GetAppsWithPolicy() const;
SEQUENCE_CHECKER(sequence_checker_);
// List of policy providers in descending order of priority. All managed
// providers should be ahead of non-managed providers.
// Also contains a named map indexed by `source()` for all the policy
// managers.
PolicyManagers policy_managers_;
const scoped_refptr<ExternalConstants> external_constants_;
base::OnceCallback<void(int)> fetch_policies_callback_;
scoped_refptr<PersistedData> persisted_data_;
};
// Decouples the proxy configuration from `PolicyService`.
struct PolicyServiceProxyConfiguration {
PolicyServiceProxyConfiguration();
~PolicyServiceProxyConfiguration();
PolicyServiceProxyConfiguration(const PolicyServiceProxyConfiguration&);
PolicyServiceProxyConfiguration(PolicyServiceProxyConfiguration&&);
PolicyServiceProxyConfiguration& operator=(
const PolicyServiceProxyConfiguration&);
PolicyServiceProxyConfiguration& operator=(PolicyServiceProxyConfiguration&&);
// Note `Get()` returns a nullopt when there's no proxy policies. Otherwise
// `proxy_auto_detect` must have a value, and is only set to true when the
// policy chooses "auto-detect".
static std::optional<PolicyServiceProxyConfiguration> Get(
scoped_refptr<PolicyService> policy_service);
bool proxy_auto_detect = false;
std::optional<std::string> proxy_pac_url;
std::optional<std::string> proxy_url;
};
// Queries whether the machine appears to be cloud managed by Chrome
// Enterprise Core (formerly Chrome Enterprise Cloud Management). Performs
// blocking IO.
bool IsCloudManaged();
} // namespace updater
#endif // CHROME_UPDATER_POLICY_SERVICE_H_
|