blob: 1ac2c10acf9d25f4a387d6f0d3d6b2de3fad09e5 [file] [log] [blame]
// 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