OLD | NEW |
1 // Copyright (c) 2011 The Chromium OS Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium OS 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 "login_manager/device_policy.h" | 5 #include "login_manager/device_policy.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include <base/basictypes.h> | 9 #include <base/basictypes.h> |
10 #include <base/file_path.h> | 10 #include <base/file_path.h> |
11 #include <base/file_util.h> | 11 #include <base/file_util.h> |
12 #include <base/logging.h> | 12 #include <base/logging.h> |
13 | 13 |
| 14 #include "login_manager/bindings/chrome_device_policy.pb.h" |
14 #include "login_manager/bindings/device_management_backend.pb.h" | 15 #include "login_manager/bindings/device_management_backend.pb.h" |
| 16 #include "login_manager/owner_key.h" |
15 #include "login_manager/system_utils.h" | 17 #include "login_manager/system_utils.h" |
16 | 18 |
| 19 namespace em = enterprise_management; |
| 20 |
17 namespace login_manager { | 21 namespace login_manager { |
| 22 using google::protobuf::RepeatedPtrField; |
| 23 using std::string; |
| 24 |
18 // static | 25 // static |
19 const char DevicePolicy::kDefaultPath[] = "/var/lib/whitelist/policy"; | 26 const char DevicePolicy::kDefaultPath[] = "/var/lib/whitelist/policy"; |
| 27 // static |
| 28 const char DevicePolicy::kDevicePolicyType[] = "google/chromeos/device"; |
20 | 29 |
21 DevicePolicy::DevicePolicy(const FilePath& policy_path) | 30 DevicePolicy::DevicePolicy(const FilePath& policy_path) |
22 : policy_path_(policy_path) { | 31 : policy_path_(policy_path) { |
23 } | 32 } |
24 | 33 |
25 DevicePolicy::~DevicePolicy() { | 34 DevicePolicy::~DevicePolicy() { |
26 } | 35 } |
27 | 36 |
28 bool DevicePolicy::LoadOrCreate() { | 37 bool DevicePolicy::LoadOrCreate() { |
29 if (!file_util::PathExists(policy_path_)) | 38 if (!file_util::PathExists(policy_path_)) |
30 return true; | 39 return true; |
31 std::string polstr; | 40 std::string polstr; |
32 if (!file_util::ReadFileToString(policy_path_, &polstr) || polstr.empty()) { | 41 if (!file_util::ReadFileToString(policy_path_, &polstr) || polstr.empty()) { |
33 PLOG(ERROR) << "Could not read policy off disk"; | 42 PLOG(ERROR) << "Could not read policy off disk"; |
34 return false; | 43 return false; |
35 } | 44 } |
36 if (!policy_.ParseFromString(polstr)) { | 45 if (!policy_.ParseFromString(polstr)) { |
37 LOG(ERROR) << "Policy on disk could not be parsed!"; | 46 LOG(ERROR) << "Policy on disk could not be parsed!"; |
38 return false; | 47 return false; |
39 } | 48 } |
40 return true; | 49 return true; |
41 } | 50 } |
42 | 51 |
43 bool DevicePolicy::Get(std::string* output) const { | 52 const enterprise_management::PolicyFetchResponse& DevicePolicy::Get() const { |
44 return policy_.SerializeToString(output); | 53 return policy_; |
45 } | 54 } |
46 | 55 |
47 bool DevicePolicy::Persist() { | 56 bool DevicePolicy::Persist() { |
48 SystemUtils utils; | 57 SystemUtils utils; |
49 std::string polstr; | 58 std::string polstr; |
50 if (!policy_.SerializeToString(&polstr)) { | 59 if (!policy_.SerializeToString(&polstr)) { |
51 LOG(ERROR) << "Could not be serialize policy!"; | 60 LOG(ERROR) << "Could not be serialize policy!"; |
52 return false; | 61 return false; |
53 } | 62 } |
54 return utils.AtomicFileWrite(policy_path_, polstr.c_str(), polstr.length()); | 63 return utils.AtomicFileWrite(policy_path_, polstr.c_str(), polstr.length()); |
55 } | 64 } |
56 | 65 |
| 66 bool DevicePolicy::SerializeToString(std::string* output) const { |
| 67 return policy_.SerializeToString(output); |
| 68 } |
| 69 |
57 void DevicePolicy::Set( | 70 void DevicePolicy::Set( |
58 const enterprise_management::PolicyFetchResponse& policy) { | 71 const enterprise_management::PolicyFetchResponse& policy) { |
59 policy_.Clear(); | 72 policy_.Clear(); |
60 // This can only fail if |policy| and |policy_| are different types. | 73 // This can only fail if |policy| and |policy_| are different types. |
61 policy_.CheckTypeAndMergeFrom(policy); | 74 policy_.CheckTypeAndMergeFrom(policy); |
62 } | 75 } |
63 | 76 |
| 77 bool DevicePolicy::StoreOwnerProperties(OwnerKey* key, |
| 78 const std::string& current_user, |
| 79 GError** error) { |
| 80 em::PolicyData poldata; |
| 81 if (policy_.has_policy_data()) |
| 82 poldata.ParseFromString(policy_.policy_data()); |
| 83 em::ChromeDeviceSettingsProto polval; |
| 84 if (poldata.has_policy_type() && |
| 85 poldata.policy_type() == kDevicePolicyType) { |
| 86 if (poldata.has_policy_value()) |
| 87 polval.ParseFromString(poldata.policy_value()); |
| 88 } else { |
| 89 poldata.set_policy_type(kDevicePolicyType); |
| 90 } |
| 91 // If there existed some device policy, we've got it now! |
| 92 // Update the UserWhitelistProto inside the ChromeDeviceSettingsProto we made. |
| 93 em::UserWhitelistProto* whitelist_proto = polval.mutable_user_whitelist(); |
| 94 bool on_whitelist = false; |
| 95 const RepeatedPtrField<string>& whitelist = whitelist_proto->user_whitelist(); |
| 96 for (RepeatedPtrField<string>::const_iterator it = whitelist.begin(); |
| 97 it != whitelist.end(); |
| 98 ++it) { |
| 99 if (on_whitelist = (current_user == *it)) |
| 100 break; |
| 101 } |
| 102 if (!on_whitelist) |
| 103 whitelist_proto->add_user_whitelist(current_user); |
| 104 bool current_user_is_owner = true; |
| 105 // TODO(cmasone): once ChromeDeviceSettingsProto contains an owner name field |
| 106 // check that against |current_user| here. |
| 107 if (current_user_is_owner && on_whitelist) |
| 108 return true; // No changes are needed. |
| 109 |
| 110 // We have now updated the whitelist and owner setting in |polval|. |
| 111 // We need to put it into |poldata|, serialize that, sign it, and |
| 112 // put both into |policy_|. |
| 113 poldata.set_policy_value(polval.SerializeAsString()); |
| 114 std::string new_data = poldata.SerializeAsString(); |
| 115 std::vector<uint8> sig; |
| 116 const uint8* data = reinterpret_cast<const uint8*>(new_data.c_str()); |
| 117 if (!key || !key->Sign(data, new_data.length(), &sig)) { |
| 118 SystemUtils utils; |
| 119 const char err_msg[] = "Could not sign policy containing new owner data."; |
| 120 LOG_IF(ERROR, error) << err_msg; |
| 121 LOG_IF(WARNING, !error) << err_msg; |
| 122 utils.SetGError(error, CHROMEOS_LOGIN_ERROR_ILLEGAL_PUBKEY, err_msg); |
| 123 return false; |
| 124 } |
| 125 |
| 126 em::PolicyFetchResponse new_policy; |
| 127 new_policy.CheckTypeAndMergeFrom(policy_); |
| 128 new_policy.set_policy_data(new_data); |
| 129 new_policy.set_policy_data_signature( |
| 130 std::string(reinterpret_cast<const char*>(&sig[0]), sig.size())); |
| 131 Set(new_policy); |
| 132 return true; |
| 133 } |
| 134 |
64 } // namespace login_manager | 135 } // namespace login_manager |
OLD | NEW |