//------------------------------------------------------------------------------
// File: UuidStore.cc
// Author: Georgios Bitzes - CERN
//------------------------------------------------------------------------------
/************************************************************************
* EOS - the CERN Disk Storage System *
* Copyright (C) 2018 CERN/Switzerland *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see .*
************************************************************************/
#include "UuidStore.hh"
#include "DirectoryIterator.hh"
#include "Utils.hh"
#include "common/SymKeys.hh"
#include "common/Logging.hh"
#include
#include
//----------------------------------------------------------------------------
//! Constructor. Provide the repository, that is the directory to use
//! on the physical filesystem.
//----------------------------------------------------------------------------
UuidStore::UuidStore(const std::string& repository_)
: repository(chopTrailingSlashes(repository_))
{
struct stat repostat;
if (::stat(repository.c_str(), &repostat) != 0) {
THROW("Cannot stat uuid-store repository: " << repository);
}
if (!S_ISDIR(repostat.st_mode)) {
THROW("Repository path is not a directory: " << repository);
}
initialCleanup();
}
//------------------------------------------------------------------------------
//! Unlink leftover credential files from previous runs - if eosxd crashes,
//! this can happen. Only unlink files matching our prefix, so that in case
//! of misconfiguration we don't wipe out important files.
//------------------------------------------------------------------------------
void UuidStore::initialCleanup()
{
DirectoryIterator iterator(repository);
struct dirent* current = nullptr;
while ((current = iterator.next())) {
if (startsWith(current->d_name, "eos-fusex-uuid-store-")) {
if (unlink(SSTR(repository << "/" << current->d_name).c_str()) != 0) {
eos_static_crit("UuidStore:: Could not delete %s during initial cleanup, errno %d",
current->d_name, errno);
}
} else {
eos_static_crit("Found file in credential store with suspicious filename, should not be there: %s. Not unlinking.",
current->d_name);
}
}
if (!iterator.ok()) {
eos_static_crit("UuidStore:: Cleanup thread encountered an error while iterating over the repository: %s",
iterator.err().c_str());
}
}
//------------------------------------------------------------------------------
//! Store the given contents inside the store. Returns the full filesystem
//! path on which the contents were stored.
//------------------------------------------------------------------------------
std::string UuidStore::put(const std::string& contents)
{
std::string path = SSTR(repository << "/" << "eos-fusex-uuid-store-"
<< generateUuid());
if (!writeFile600(path, contents)) {
eos_static_crit("UuidStore: Could not write path: %s", path.c_str());
return "";
}
return path;
}
//------------------------------------------------------------------------------
//! Make uuid
//------------------------------------------------------------------------------
std::string UuidStore::generateUuid()
{
char buffer[64];
uuid_t uuid;
uuid_generate_random(uuid);
uuid_unparse(uuid, buffer);
return std::string(buffer);
}