static bool InternalSecureSaveToFile()

in src/common/commonutils/FileUtils.c [189:284]


static bool InternalSecureSaveToFile(const char* fileName, const char* mode, const char* payload, const int payloadSizeBytes, OsConfigLogHandle log)
{
    const char* tempFileNameTemplate = "%s/~OSConfig%u";
    char* fileDirectory = NULL;
    char* fileNameCopy = NULL;
    char* tempFileName = NULL;
    char* fileContents = NULL;
    unsigned int ownerId = 0;
    unsigned int groupId = 0;
    unsigned int access = 0644;
    int status = 0;
    bool result = false;

    if ((NULL == fileName) || (NULL == payload) || (0 >= payloadSizeBytes))
    {
        OsConfigLogError(log, "InternalSecureSaveToFile: invalid arguments");
        return false;
    }
    else if (NULL == (fileNameCopy = DuplicateString(fileName)))
    {
        OsConfigLogError(log, "InternalSecureSaveToFile: out of memory");
        return false;
    }

    if (NULL == (fileDirectory = dirname(fileNameCopy)))
    {
        OsConfigLogInfo(log, "InternalSecureSaveToFile: no directory name for '%s' (%d)", fileNameCopy, errno);
    }

    if (DirectoryExists(fileDirectory))
    {
        if (0 == GetDirectoryAccess(fileDirectory, &ownerId, &groupId, &access, log))
        {
            OsConfigLogInfo(log, "InternalSecureSaveToFile: directory '%s' exists, is owned by user (%u, %u) and has access mode %03o",
                fileDirectory, ownerId, groupId, access);
        }
    }

    if (NULL != (tempFileName = FormatAllocateString(tempFileNameTemplate, fileDirectory ? fileDirectory : "/tmp", rand())))
    {
        if ((0 == strcmp(mode, "a") && FileExists(fileName)))
        {
            if (NULL != (fileContents = LoadStringFromFile(fileName, false, log)))
            {
                if (true == (result = SaveToFile(tempFileName, "a", fileContents, strlen(fileContents), log)))
                {
                    // If there is no EOL at the end of file, add one before the append
                    if (EOL != fileContents[strlen(fileContents) - 1])
                    {
                        SaveToFile(tempFileName, "w", "\n", 1, log);
                    }

                    result = SaveToFile(tempFileName, "a", payload, payloadSizeBytes, log);
                }

                FREE_MEMORY(fileContents);
            }
            else
            {
                OsConfigLogInfo(log, "InternalSecureSaveToFile: cannot read from '%s' (%d)", fileName, errno);
                result = false;
            }
        }
        else
        {
            result = SaveToFile(tempFileName, "w", payload, payloadSizeBytes, log);
        }
    }
    else
    {
        OsConfigLogError(log, "InternalSecureSaveToFile: out of memory");
        result = false;
    }

    if (result && (false == FileExists(tempFileName)))
    {
        OsConfigLogInfo(log, "InternalSecureSaveToFile: cannot create temporary file (%d)", errno);
        result = false;
    }

    if (result)
    {
        if (0 != (status = RenameFileWithOwnerAndAccess(tempFileName, fileName, log)))
        {
            OsConfigLogInfo(log, "InternalSecureSaveToFile: RenameFileWithOwnerAndAccess('%s' to '%s') returned %d", tempFileName, fileName, status);
            result = false;
        }

        remove(tempFileName);
    }

    FREE_MEMORY(tempFileName);
    FREE_MEMORY(fileNameCopy);

    return result;
}