1 //
2 // Copyright (C) 2017 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 #include "update_engine/update_manager/enterprise_device_policy_impl.h"
18
19 #include "update_engine/common/utils.h"
20
21 using std::string;
22
23 namespace chromeos_update_manager {
24
25 // Check to see if Enterprise-managed (has DevicePolicy) and/or Kiosk-mode. If
26 // so, then defer to those settings.
UpdateCheckAllowed(EvaluationContext * ec,State * state,std::string * error,UpdateCheckParams * result) const27 EvalStatus EnterpriseDevicePolicyImpl::UpdateCheckAllowed(
28 EvaluationContext* ec,
29 State* state,
30 std::string* error,
31 UpdateCheckParams* result) const {
32 DevicePolicyProvider* const dp_provider = state->device_policy_provider();
33 SystemProvider* const system_provider = state->system_provider();
34
35 const bool* device_policy_is_loaded_p =
36 ec->GetValue(dp_provider->var_device_policy_is_loaded());
37 if (device_policy_is_loaded_p && *device_policy_is_loaded_p) {
38 bool kiosk_app_control_chrome_version = false;
39
40 // Check whether updates are disabled by policy.
41 const bool* update_disabled_p =
42 ec->GetValue(dp_provider->var_update_disabled());
43 if (update_disabled_p && *update_disabled_p) {
44 // Check whether allow kiosk app to control chrome version policy. This
45 // policy is only effective when AU is disabled by admin.
46 const bool* allow_kiosk_app_control_chrome_version_p = ec->GetValue(
47 dp_provider->var_allow_kiosk_app_control_chrome_version());
48 kiosk_app_control_chrome_version =
49 allow_kiosk_app_control_chrome_version_p &&
50 *allow_kiosk_app_control_chrome_version_p;
51 if (!kiosk_app_control_chrome_version) {
52 // No kiosk pin chrome version policy. AU is really disabled.
53 LOG(INFO) << "Updates disabled by policy, blocking update checks.";
54 return EvalStatus::kAskMeAgainLater;
55 }
56 }
57
58 // By default, result->rollback_allowed is false.
59 if (kiosk_app_control_chrome_version) {
60 // Get the required platform version from Chrome.
61 const string* kiosk_required_platform_version_p =
62 ec->GetValue(system_provider->var_kiosk_required_platform_version());
63 if (!kiosk_required_platform_version_p) {
64 LOG(INFO) << "Kiosk app required platform version is not fetched, "
65 "blocking update checks.";
66 return EvalStatus::kAskMeAgainLater;
67 } else if (kiosk_required_platform_version_p->empty()) {
68 // The platform version could not be fetched several times. Update
69 // based on |DeviceMinimumVersion| instead (crbug.com/1048931).
70 const base::Version* device_minimum_version_p =
71 ec->GetValue(dp_provider->var_device_minimum_version());
72 const base::Version* current_version_p(
73 ec->GetValue(system_provider->var_chromeos_version()));
74 if (device_minimum_version_p && device_minimum_version_p->IsValid() &&
75 current_version_p && current_version_p->IsValid() &&
76 *current_version_p > *device_minimum_version_p) {
77 // Do not update if the current version is newer than the minimum
78 // version.
79 LOG(INFO) << "Reading kiosk app required platform version failed "
80 "repeatedly but current version is newer than "
81 "DeviceMinimumVersion. Blocking update checks. "
82 "Current version: "
83 << *current_version_p
84 << " DeviceMinimumVersion: " << *device_minimum_version_p;
85 return EvalStatus::kAskMeAgainLater;
86 }
87 LOG(WARNING) << "Reading kiosk app required platform version failed "
88 "repeatedly. Attempting an update without it now.";
89 // An empty string for |target_version_prefix| allows arbitrary updates.
90 result->target_version_prefix = "";
91 } else {
92 result->target_version_prefix = *kiosk_required_platform_version_p;
93 LOG(INFO) << "Allow kiosk app to control Chrome version policy is set, "
94 << "target version is " << result->target_version_prefix;
95 }
96 // TODO(hunyadym): Add support for allowing rollback using the manifest
97 // (if policy doesn't specify otherwise).
98 } else {
99 // Determine whether a target version prefix is dictated by policy.
100 const string* target_version_prefix_p =
101 ec->GetValue(dp_provider->var_target_version_prefix());
102 if (target_version_prefix_p)
103 result->target_version_prefix = *target_version_prefix_p;
104 }
105
106 // Policy always overwrites whether rollback is allowed by the kiosk app
107 // manifest.
108 const RollbackToTargetVersion* rollback_to_target_version_p =
109 ec->GetValue(dp_provider->var_rollback_to_target_version());
110 if (rollback_to_target_version_p) {
111 switch (*rollback_to_target_version_p) {
112 case RollbackToTargetVersion::kUnspecified:
113 // We leave the default or the one specified by the kiosk app.
114 break;
115 case RollbackToTargetVersion::kDisabled:
116 LOG(INFO) << "Policy disables rollbacks.";
117 result->rollback_allowed = false;
118 result->rollback_data_save_requested = false;
119 break;
120 case RollbackToTargetVersion::kRollbackAndPowerwash:
121 LOG(INFO) << "Policy allows rollbacks with powerwash.";
122 result->rollback_allowed = true;
123 result->rollback_data_save_requested = false;
124 break;
125 case RollbackToTargetVersion::kRollbackAndRestoreIfPossible:
126 LOG(INFO)
127 << "Policy allows rollbacks, also tries to restore if possible.";
128 result->rollback_allowed = true;
129 result->rollback_data_save_requested = true;
130 break;
131 case RollbackToTargetVersion::kMaxValue:
132 NOTREACHED();
133 // Don't add a default case to let the compiler warn about newly
134 // added enum values which should be added here.
135 }
136 }
137
138 // Determine allowed milestones for rollback
139 const int* rollback_allowed_milestones_p =
140 ec->GetValue(dp_provider->var_rollback_allowed_milestones());
141 if (rollback_allowed_milestones_p)
142 result->rollback_allowed_milestones = *rollback_allowed_milestones_p;
143
144 // Determine whether a target channel is dictated by policy and whether we
145 // should rollback in case that channel is more stable.
146 const bool* release_channel_delegated_p =
147 ec->GetValue(dp_provider->var_release_channel_delegated());
148 if (release_channel_delegated_p && !(*release_channel_delegated_p)) {
149 const string* release_channel_p =
150 ec->GetValue(dp_provider->var_release_channel());
151 if (release_channel_p) {
152 result->target_channel = *release_channel_p;
153 const ChannelDowngradeBehavior* channel_downgrade_behavior_p =
154 ec->GetValue(dp_provider->var_channel_downgrade_behavior());
155 if (channel_downgrade_behavior_p &&
156 *channel_downgrade_behavior_p ==
157 ChannelDowngradeBehavior::kRollback) {
158 result->rollback_on_channel_downgrade = true;
159 }
160 }
161 }
162
163 const string* release_lts_tag_p =
164 ec->GetValue(dp_provider->var_release_lts_tag());
165 if (release_lts_tag_p) {
166 result->lts_tag = *release_lts_tag_p;
167 }
168
169 const string* quick_fix_build_token_p =
170 ec->GetValue(dp_provider->var_quick_fix_build_token());
171 if (quick_fix_build_token_p) {
172 result->quick_fix_build_token = *quick_fix_build_token_p;
173 }
174 }
175 return EvalStatus::kContinue;
176 }
177
178 } // namespace chromeos_update_manager
179