mirror of
https://github.com/scylladb/scylladb.git
synced 2026-04-20 00:20:47 +00:00
156 lines
4.8 KiB
C++
156 lines
4.8 KiB
C++
/*
|
|
* Copyright (C) 2017 ScyllaDB
|
|
*/
|
|
|
|
/*
|
|
* SPDX-License-Identifier: LicenseRef-ScyllaDB-Source-Available-1.1
|
|
*/
|
|
#pragma once
|
|
|
|
#include "seastarx.hh"
|
|
#include "utils/log.hh"
|
|
#include "utils/observable.hh"
|
|
#include "db/consistency_level.hh"
|
|
#include "locator/token_metadata_fwd.hh"
|
|
#include <seastar/core/sharded.hh>
|
|
#include <seastar/util/log.hh>
|
|
|
|
#include "enum_set.hh"
|
|
|
|
#include <memory>
|
|
|
|
namespace db {
|
|
|
|
class config;
|
|
|
|
}
|
|
|
|
namespace cql3 {
|
|
|
|
class cql_statement;
|
|
class query_processor;
|
|
class query_options;
|
|
|
|
}
|
|
|
|
namespace service {
|
|
|
|
class migration_manager;
|
|
class query_state;
|
|
|
|
}
|
|
|
|
namespace locator {
|
|
|
|
class shared_token_metadata;
|
|
|
|
}
|
|
|
|
namespace audit {
|
|
|
|
extern logging::logger logger;
|
|
|
|
class audit_exception : public std::exception {
|
|
sstring _what;
|
|
public:
|
|
explicit audit_exception(sstring&& what) : _what(std::move(what)) { }
|
|
const char* what() const noexcept override {
|
|
return _what.c_str();
|
|
}
|
|
};
|
|
|
|
enum class statement_category {
|
|
QUERY, DML, DDL, DCL, AUTH, ADMIN
|
|
};
|
|
|
|
using category_set = enum_set<super_enum<statement_category, statement_category::QUERY,
|
|
statement_category::DML,
|
|
statement_category::DDL,
|
|
statement_category::DCL,
|
|
statement_category::AUTH,
|
|
statement_category::ADMIN>>;
|
|
|
|
class audit_info final {
|
|
statement_category _category;
|
|
sstring _keyspace;
|
|
sstring _table;
|
|
sstring _query;
|
|
bool _batch;
|
|
public:
|
|
audit_info(statement_category cat, sstring keyspace, sstring table, bool batch)
|
|
: _category(cat)
|
|
, _keyspace(std::move(keyspace))
|
|
, _table(std::move(table))
|
|
, _batch(batch)
|
|
{ }
|
|
void set_query_string(const std::string_view& query_string) {
|
|
_query = sstring(query_string);
|
|
}
|
|
const sstring& keyspace() const { return _keyspace; }
|
|
const sstring& table() const { return _table; }
|
|
const sstring& query() const { return _query; }
|
|
sstring category_string() const;
|
|
statement_category category() const { return _category; }
|
|
bool batch() const { return _batch; }
|
|
};
|
|
|
|
using audit_info_ptr = std::unique_ptr<audit_info>;
|
|
|
|
class storage_helper;
|
|
|
|
class audit final : public seastar::async_sharded_service<audit> {
|
|
locator::shared_token_metadata& _token_metadata;
|
|
std::set<sstring> _audited_keyspaces;
|
|
// Maps keyspace name to set of table names in that keyspace
|
|
std::map<sstring, std::set<sstring>> _audited_tables;
|
|
category_set _audited_categories;
|
|
|
|
std::unique_ptr<storage_helper> _storage_helper_ptr;
|
|
|
|
const db::config& _cfg;
|
|
utils::observer<sstring> _cfg_keyspaces_observer;
|
|
utils::observer<sstring> _cfg_tables_observer;
|
|
utils::observer<sstring> _cfg_categories_observer;
|
|
|
|
template<class T>
|
|
void update_config(const sstring & new_value, std::function<T(const sstring&)> parse_func, T& cfg_parameter);
|
|
|
|
bool should_log_table(const sstring& keyspace, const sstring& name) const;
|
|
public:
|
|
static seastar::sharded<audit>& audit_instance() {
|
|
// FIXME: leaked intentionally to avoid shutdown problems, see #293
|
|
static seastar::sharded<audit>* audit_inst = new seastar::sharded<audit>();
|
|
|
|
return *audit_inst;
|
|
}
|
|
|
|
static audit& local_audit_instance() {
|
|
return audit_instance().local();
|
|
}
|
|
static future<> start_audit(const db::config& cfg, sharded<locator::shared_token_metadata>& stm, sharded<cql3::query_processor>& qp, sharded<service::migration_manager>& mm);
|
|
static future<> stop_audit();
|
|
static audit_info_ptr create_audit_info(statement_category cat, const sstring& keyspace, const sstring& table, bool batch = false);
|
|
audit(locator::shared_token_metadata& stm,
|
|
cql3::query_processor& qp,
|
|
service::migration_manager& mm,
|
|
std::set<sstring>&& audit_modes,
|
|
std::set<sstring>&& audited_keyspaces,
|
|
std::map<sstring, std::set<sstring>>&& audited_tables,
|
|
category_set&& audited_categories,
|
|
const db::config& cfg);
|
|
~audit();
|
|
future<> start(const db::config& cfg);
|
|
future<> stop();
|
|
future<> shutdown();
|
|
bool should_log(const audit_info* audit_info) const;
|
|
bool should_log_login() const { return _audited_categories.contains(statement_category::AUTH); }
|
|
future<> log(const audit_info* audit_info, service::query_state& query_state, const cql3::query_options& options, bool error);
|
|
future<> log_login(const sstring& username, socket_address client_ip, bool error) noexcept;
|
|
};
|
|
|
|
future<> inspect(shared_ptr<cql3::cql_statement> statement, service::query_state& query_state, const cql3::query_options& options, bool error);
|
|
|
|
future<> inspect_login(const sstring& username, socket_address client_ip, bool error);
|
|
|
|
}
|