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.
27 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       }
68 
69       result->target_version_prefix = *kiosk_required_platform_version_p;
70       LOG(INFO) << "Allow kiosk app to control Chrome version policy is set, "
71                 << "target version is " << result->target_version_prefix;
72       // TODO(hunyadym): Add support for allowing rollback using the manifest
73       // (if policy doesn't specify otherwise).
74     } else {
75       // Determine whether a target version prefix is dictated by policy.
76       const string* target_version_prefix_p =
77           ec->GetValue(dp_provider->var_target_version_prefix());
78       if (target_version_prefix_p)
79         result->target_version_prefix = *target_version_prefix_p;
80     }
81 
82     // Policy always overwrites whether rollback is allowed by the kiosk app
83     // manifest.
84     const RollbackToTargetVersion* rollback_to_target_version_p =
85         ec->GetValue(dp_provider->var_rollback_to_target_version());
86     if (rollback_to_target_version_p) {
87       switch (*rollback_to_target_version_p) {
88         case RollbackToTargetVersion::kUnspecified:
89           // We leave the default or the one specified by the kiosk app.
90           break;
91         case RollbackToTargetVersion::kDisabled:
92           LOG(INFO) << "Policy disables rollbacks.";
93           result->rollback_allowed = false;
94           break;
95         case RollbackToTargetVersion::kRollbackAndPowerwash:
96           LOG(INFO) << "Policy allows rollbacks with powerwash.";
97           result->rollback_allowed = true;
98           break;
99         case RollbackToTargetVersion::kRollbackAndRestoreIfPossible:
100           LOG(INFO)
101               << "Policy allows rollbacks, also tries to restore if possible.";
102           // We don't support restore yet, but policy still allows rollback.
103           result->rollback_allowed = true;
104           break;
105         case RollbackToTargetVersion::kRollbackOnlyIfRestorePossible:
106           LOG(INFO) << "Policy only allows rollbacks if restore is possible.";
107           // We don't support restore yet, policy doesn't allow rollback in this
108           // case.
109           result->rollback_allowed = false;
110           break;
111         case RollbackToTargetVersion::kMaxValue:
112           NOTREACHED();
113           // Don't add a default case to let the compiler warn about newly
114           // added enum values which should be added here.
115       }
116     }
117 
118     // Determine allowed milestones for rollback
119     const int* rollback_allowed_milestones_p =
120         ec->GetValue(dp_provider->var_rollback_allowed_milestones());
121     if (rollback_allowed_milestones_p)
122       result->rollback_allowed_milestones = *rollback_allowed_milestones_p;
123 
124     // Determine whether a target channel is dictated by policy.
125     const bool* release_channel_delegated_p =
126         ec->GetValue(dp_provider->var_release_channel_delegated());
127     if (release_channel_delegated_p && !(*release_channel_delegated_p)) {
128       const string* release_channel_p =
129           ec->GetValue(dp_provider->var_release_channel());
130       if (release_channel_p)
131         result->target_channel = *release_channel_p;
132     }
133   }
134   return EvalStatus::kContinue;
135 }
136 
137 }  // namespace chromeos_update_manager
138