blob: 441266ad9fcee714ae9be7ad720e64b84884d515 [file] [log] [blame]
// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
// 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 <policy/policy_util.h>
#include "login_manager/system_utils_impl.h"
namespace login_manager {
namespace {
const char kPrefsFileName[] = "preferences";
} // namespace
PolicyStore::PolicyStore(const base::FilePath& policy_path)
: policy_path_(policy_path) {}
PolicyStore::~PolicyStore() {}
bool PolicyStore::DefunctPrefsFilePresent() {
return base::PathExists(policy_path_.DirName().Append(kPrefsFileName));
}
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) {
std::string polstr;
cached_policy_data_.clear();
policy::LoadPolicyResult result =
policy::LoadPolicyFromPath(policy_path, &polstr, &policy_);
switch (result) {
case policy::LoadPolicyResult::kSuccess:
cached_policy_data_ = polstr;
return true;
case policy::LoadPolicyResult::kFileNotFound:
return true;
case policy::LoadPolicyResult::kFailedToReadFile:
case policy::LoadPolicyResult::kEmptyFile:
return false;
case policy::LoadPolicyResult::kInvalidPolicyData:
base::DeleteFile(policy_path);
policy_.Clear();
return false;
}
NOTREACHED();
}
bool PolicyStore::PersistToPath(const base::FilePath& policy_path) {
SystemUtilsImpl utils;
std::string policy_blob;
if (!policy_.SerializeToString(&policy_blob)) {
LOG(ERROR) << "Could not serialize policy!";
return false;
}
// Skip writing to the file if the contents of policy data haven't been
// changed.
if (cached_policy_data_ == policy_blob)
return true;
if (!utils.AtomicFileWrite(policy_path, policy_blob))
return false;
LOG(INFO) << "Persisted policy to disk, path: " << policy_path.value();
cached_policy_data_ = policy_blob;
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);
}
bool PolicyStore::Delete() {
if (!base::DeleteFile(policy_path_))
return false;
policy_.Clear();
return true;
}
} // namespace login_manager