| // Copyright 2012 The ChromiumOS Authors | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include "login_manager/policy_store.h" | |
| #include <base/files/file_util.h> | |
| #include <base/logging.h> | |
| #include <base/notreached.h> | |
| #include <brillo/files/file_util.h> | |
| #include <policy/policy_util.h> | |
| #include "login_manager/system_utils_impl.h" | |
| namespace login_manager { | |
| PolicyStore::PolicyStore(const base::FilePath& policy_path) | |
| : PolicyStore(policy_path, /*is_resilient=*/false) {} | |
| PolicyStore::PolicyStore(const base::FilePath& policy_path, bool is_resilient) | |
| : policy_path_(policy_path), is_resilient_store_(is_resilient) {} | |
| PolicyStore::~PolicyStore() {} | |
| bool PolicyStore::EnsureLoadedOrCreated() { | |
| if (load_result_ == NOT_LOADED) | |
| load_result_ = LoadOrCreate() ? LOAD_SUCCEEDED : LOAD_FAILED; | |
| return load_result_ == LOAD_SUCCEEDED; | |
| } | |
| const enterprise_management::PolicyFetchResponse& PolicyStore::Get() const { | |
| return policy_; | |
| } | |
| bool PolicyStore::Persist() { | |
| return PersistToPath(policy_path_); | |
| } | |
| bool PolicyStore::LoadOrCreate() { | |
| return LoadOrCreateFromPath(policy_path_); | |
| } | |
| bool PolicyStore::LoadOrCreateFromPath(const base::FilePath& policy_path) { | |
| DCHECK(!is_resilient_store_); | |
| std::string polstr; | |
| policy::LoadPolicyResult result = | |
| policy::LoadPolicyFromPath(policy_path, &polstr, &policy_); | |
| switch (result) { | |
| case policy::LoadPolicyResult::kSuccess: | |
| return true; | |
| case policy::LoadPolicyResult::kFileNotFound: | |
| return true; | |
| case policy::LoadPolicyResult::kFailedToReadFile: | |
| LOG(WARNING) << "Failed to read policy file: " << policy_path.value(); | |
| return false; | |
| case policy::LoadPolicyResult::kEmptyFile: | |
| LOG(WARNING) << "Empty policy file: " << policy_path.value(); | |
| return false; | |
| case policy::LoadPolicyResult::kInvalidPolicyData: | |
| LOG(WARNING) << "Invalid policy data: " << policy_path.value(); | |
| brillo::DeleteFile(policy_path); | |
| policy_.Clear(); | |
| return false; | |
| } | |
| NOTREACHED(); | |
| } | |
| bool PolicyStore::PersistToPath(const base::FilePath& policy_path) { | |
| // Skip if there's no change in policy data. | |
| if (!explicit_update_persist_pending_) | |
| return true; | |
| SystemUtilsImpl utils; | |
| std::string policy_blob; | |
| if (!policy_.SerializeToString(&policy_blob)) { | |
| LOG(ERROR) << "Could not serialize policy!"; | |
| return false; | |
| } | |
| if (!utils.AtomicFileWrite(policy_path, policy_blob)) | |
| return false; | |
| LOG(INFO) << "Persisted policy to disk, path: " << policy_path.value(); | |
| explicit_update_persist_pending_ = false; | |
| return true; | |
| } | |
| void PolicyStore::Set( | |
| const enterprise_management::PolicyFetchResponse& policy) { | |
| policy_.Clear(); | |
| // This can only fail if |policy| and |policy_| are different types. | |
| policy_.CheckTypeAndMergeFrom(policy); | |
| explicit_update_persist_pending_ = true; | |
| } | |
| } // namespace login_manager |