Update copyCertificate function to preserve file metadata
Cert Manager currently creates a new file with the same content
during Certificate::copyCertificate function but doesn’t
preserve the file metadata(uid,gid,rwx etc.) from the original
file. It's a nice to have feature if both content and file
metadata are preserved during the copy. This would be useful for
security software running later on to validate the file's
integrity and authenticity.
This is achievable by utilizing the cp command. PCM will issue a
std::system call to ask the underlying host environment's command
processor to execute the cp -fp call.
This PR doesn't change any current business logic to any existing
code that depends on PCM.
Change-Id: I53907253857b04629914290a77b140c338344d05
Signed-off-by: Zac Tang <zactang1024@gmail.com>
diff --git a/certificate.cpp b/certificate.cpp
index 428b252..0387921 100644
--- a/certificate.cpp
+++ b/certificate.cpp
@@ -116,31 +116,23 @@
const std::string& certFilePath)
{
// Copy the certificate to the installation path
- // During boot up will be parsing existing file so no need to
+ // During bootup will be parsing existing file so no need to
// copy it.
if (certSrcFilePath != certFilePath)
{
- std::ifstream inputCertFileStream;
- std::ofstream outputCertFileStream;
- inputCertFileStream.exceptions(
- std::ifstream::failbit | std::ifstream::badbit |
- std::ifstream::eofbit);
- outputCertFileStream.exceptions(
- std::ofstream::failbit | std::ofstream::badbit |
- std::ofstream::eofbit);
- try
- {
- inputCertFileStream.open(certSrcFilePath);
- outputCertFileStream.open(certFilePath, std::ios::out);
- outputCertFileStream << inputCertFileStream.rdbuf() << std::flush;
- inputCertFileStream.close();
- outputCertFileStream.close();
- }
- catch (const std::exception& e)
+ // -p flag preserves the file metadata when copying
+ // -f flag forces the copy
+ const std::string command =
+ std::format("cp -fp {} {}", certSrcFilePath, certFilePath);
+ int statusCode = std::system(command.c_str());
+
+ // Non-zero `status_code` indicates something went wrong with issuing
+ // the copy command.
+ if (statusCode != 0)
{
lg2::error(
"Failed to copy certificate, ERR:{ERR}, SRC:{SRC}, DST:{DST}",
- "ERR", e, "SRC", certSrcFilePath, "DST", certFilePath);
+ "ERR", statusCode, "SRC", certSrcFilePath, "DST", certFilePath);
elog<InternalFailure>();
}
}