1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2024-12-14 10:13:05 +02:00

Allow storageInfo() to operate outside the base storage path.

It is occasionally useful to get information about a file outside of the base storage path.  storageLocal() can be used in some cases but when the storage is remote is doesn't seem worth creating a separate storage object for adhoc info requests.

storageInfo() is a read-only operation so this seems pretty safe.  The noPathEnforce parameter will make auditing exceptions easy.
This commit is contained in:
David Steele 2019-11-21 10:55:03 -05:00
parent d3b1897625
commit 9f71a019c8
3 changed files with 13 additions and 1 deletions

View File

@ -240,6 +240,7 @@ storageInfo(const Storage *this, const String *fileExp, StorageInfoParam param)
FUNCTION_LOG_PARAM(STRING, fileExp);
FUNCTION_LOG_PARAM(BOOL, param.ignoreMissing);
FUNCTION_LOG_PARAM(BOOL, param.followLink);
FUNCTION_LOG_PARAM(BOOL, param.noPathEnforce);
FUNCTION_LOG_END();
ASSERT(this != NULL);
@ -250,7 +251,7 @@ storageInfo(const Storage *this, const String *fileExp, StorageInfoParam param)
MEM_CONTEXT_TEMP_BEGIN()
{
// Build the path
String *file = storagePathP(this, fileExp);
String *file = storagePathP(this, fileExp, .noEnforce = param.noPathEnforce);
// Call driver function
result = storageInterfaceInfoP(this->driver, file, .followLink = param.followLink);

View File

@ -84,6 +84,7 @@ typedef struct StorageInfoParam
VAR_PARAM_HEADER;
bool ignoreMissing;
bool followLink;
bool noPathEnforce;
} StorageInfoParam;
#define storageInfoP(this, fileExp, ...) \

View File

@ -161,6 +161,16 @@ testRun(void)
TEST_ASSIGN(info, storageInfoP(storageTest, fileName, .ignoreMissing = true), "get file info (missing)");
TEST_RESULT_BOOL(info.exists, false, " check not exists");
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("info outside of base path");
TEST_ERROR(
storageInfoP(storageTest, STRDEF("/etc"), .ignoreMissing = true), AssertError,
hrnReplaceKey("absolute path '/etc' is not in base path '{[path]}'"));
TEST_RESULT_BOOL(
storageInfoP(storageTest, STRDEF("/etc"), .ignoreMissing = true, .noPathEnforce = true).exists, true,
"path not enforced");
// -------------------------------------------------------------------------------------------------------------------------
struct utimbuf utimeTest = {.actime = 1000000000, .modtime = 1555160000};
THROW_ON_SYS_ERROR_FMT(utime(testPath(), &utimeTest) != 0, FileWriteError, "unable to set time for '%s'", testPath());