2019-12-09 11:44:51 +03:00
/*
* auditd - plugin - clickhouse is an auditd plugin for sending auditd data
* to clickhouse DB .
2020-01-10 14:15:59 +03:00
* Copyright ( C ) 2019 - 2020 Aleksei Nikiforov < darktemplar @ basealt . ru >
2019-12-09 11:44:51 +03:00
*
* 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 < https : //www.gnu.org/licenses/>.
*
*/
# ifndef AUDITD_PLUGIN_CLICKHOUSE_RECORD_HPP
# define AUDITD_PLUGIN_CLICKHOUSE_RECORD_HPP
# include <memory>
# include <map>
# include <functional>
# include <string>
2019-12-11 17:16:28 +03:00
# include <list>
2019-12-09 11:44:51 +03:00
# include <stdint.h>
# include <boost/optional.hpp>
2020-01-14 17:16:01 +03:00
# include <boost/property_tree/ptree.hpp>
2019-12-09 11:44:51 +03:00
# include <auparse.h>
# include <libaudit.h>
# include <clickhouse-cpp/columns/column.h>
2020-01-14 17:16:01 +03:00
struct AuditRecord ;
2019-12-12 15:01:59 +03:00
bool check_field_type ( auparse_type_t field_type , const std : : string & database_type , const std : : string & database_field_name ) ;
2020-01-10 14:15:59 +03:00
std : : string field_type_to_string ( auparse_type_t field_type ) ;
2020-01-14 17:16:01 +03:00
std : : string generate_name_for_audit_record ( const AuditRecord & record ) ;
2019-12-09 11:44:51 +03:00
class AbstractRecordField
{
public :
enum class Type
{
Int ,
String ,
2019-12-11 17:16:28 +03:00
InterpretedString ,
InterpretedStringArray
2019-12-09 11:44:51 +03:00
} ;
2019-12-12 17:53:14 +03:00
struct Column
{
std : : string name ;
clickhouse : : ColumnRef value ;
Column ( const std : : string & l_name , const clickhouse : : ColumnRef & l_value )
: name ( l_name ) ,
value ( l_value )
{
}
} ;
2019-12-09 11:44:51 +03:00
virtual ~ AbstractRecordField ( ) = default ;
2019-12-11 17:16:28 +03:00
virtual void addOrUpdateValue ( auparse_state_t * record ) = 0 ;
2019-12-12 17:53:14 +03:00
virtual std : : vector < Column > generateColumnsAndNames ( ) const = 0 ;
virtual void addToColumn ( const std : : vector < Column > & columns ) const = 0 ;
2019-12-09 11:44:51 +03:00
virtual Type getType ( ) const = 0 ;
std : : string getName ( ) const { return m_name ; }
protected :
explicit AbstractRecordField ( const std : : string & name ) ;
AbstractRecordField ( const AbstractRecordField & other ) = default ;
AbstractRecordField & operator = ( const AbstractRecordField & other ) = default ;
std : : string m_name ;
} ;
2019-12-12 15:01:59 +03:00
struct AuditRecord
2019-12-09 11:44:51 +03:00
{
2019-12-12 15:01:59 +03:00
time_t time ;
uint64_t milliseconds ;
uint64_t serial ;
std : : string node ; // skip processing node from record fields
2019-12-09 11:44:51 +03:00
2019-12-12 15:01:59 +03:00
std : : map < std : : string , std : : shared_ptr < AbstractRecordField > > fields ;
2020-01-14 17:16:01 +03:00
2020-01-15 15:26:53 +03:00
std : : string filename ; // filename of file where data is stored; empty if no such file exists
2020-01-14 17:16:01 +03:00
boost : : property_tree : : ptree toPtree ( ) const ;
2020-01-14 17:53:22 +03:00
static AuditRecord fromPtree ( const boost : : property_tree : : ptree & data ) ;
2020-01-15 14:41:46 +03:00
bool operator < ( const AuditRecord & other ) const ;
2019-12-09 11:44:51 +03:00
} ;
class CommonStringRecordField : public AbstractRecordField
{
public :
2019-12-12 17:53:14 +03:00
virtual std : : vector < Column > generateColumnsAndNames ( ) const override ;
virtual void addToColumn ( const std : : vector < Column > & columns ) const override ;
2019-12-09 11:44:51 +03:00
2020-01-14 17:16:01 +03:00
const boost : : optional < std : : string > & getStringValue ( ) const ;
void setStringValue ( const boost : : optional < std : : string > & value ) ;
2019-12-09 11:44:51 +03:00
protected :
explicit CommonStringRecordField ( const std : : string & name ) ;
boost : : optional < std : : string > m_value ;
} ;
class StringRecordField : public CommonStringRecordField
{
public :
2019-12-11 17:16:28 +03:00
static std : : shared_ptr < AbstractRecordField > createRecord ( const std : : string & name ) ;
2019-12-09 11:44:51 +03:00
2019-12-11 17:16:28 +03:00
virtual void addOrUpdateValue ( auparse_state_t * record ) override ;
2019-12-09 11:44:51 +03:00
virtual Type getType ( ) const override ;
protected :
2019-12-11 17:16:28 +03:00
explicit StringRecordField ( const std : : string & name ) ;
2019-12-09 11:44:51 +03:00
} ;
class InterpretedStringRecordField : public CommonStringRecordField
{
public :
2019-12-11 17:16:28 +03:00
static std : : shared_ptr < AbstractRecordField > createRecord ( const std : : string & name ) ;
2019-12-09 11:44:51 +03:00
2019-12-11 17:16:28 +03:00
virtual void addOrUpdateValue ( auparse_state_t * record ) override ;
2019-12-09 11:44:51 +03:00
virtual Type getType ( ) const override ;
protected :
2019-12-11 17:16:28 +03:00
explicit InterpretedStringRecordField ( const std : : string & name ) ;
2019-12-09 11:44:51 +03:00
} ;
2019-12-09 12:19:58 +03:00
class IntegerRecordField : public InterpretedStringRecordField
{
public :
2019-12-11 17:16:28 +03:00
static std : : shared_ptr < AbstractRecordField > createRecord ( const std : : string & name ) ;
2019-12-09 12:19:58 +03:00
2019-12-11 17:16:28 +03:00
virtual void addOrUpdateValue ( auparse_state_t * record ) override ;
2019-12-12 17:53:14 +03:00
virtual std : : vector < Column > generateColumnsAndNames ( ) const override ;
virtual void addToColumn ( const std : : vector < Column > & columns ) const override ;
2019-12-09 12:19:58 +03:00
virtual Type getType ( ) const override ;
2020-01-14 17:16:01 +03:00
const boost : : optional < int > & getIntValue ( ) const ;
void setIntValue ( const boost : : optional < int > & value ) ;
2019-12-09 12:19:58 +03:00
protected :
2019-12-11 17:16:28 +03:00
explicit IntegerRecordField ( const std : : string & name ) ;
2019-12-09 12:19:58 +03:00
boost : : optional < int > m_int_value ;
} ;
2019-12-11 17:16:28 +03:00
class InterpretedStringArrayRecordField : public AbstractRecordField
{
public :
static std : : shared_ptr < AbstractRecordField > createRecord ( const std : : string & name ) ;
virtual void addOrUpdateValue ( auparse_state_t * record ) override ;
2019-12-12 17:53:14 +03:00
virtual std : : vector < Column > generateColumnsAndNames ( ) const override ;
virtual void addToColumn ( const std : : vector < Column > & columns ) const override ;
2019-12-11 17:16:28 +03:00
virtual Type getType ( ) const override ;
2020-01-14 17:16:01 +03:00
const std : : list < std : : string > & getNamesArray ( ) const ;
const std : : list < std : : string > & getValuesArray ( ) const ;
void setArrays ( std : : list < std : : string > names_array , std : : list < std : : string > values_array ) ;
2019-12-11 17:16:28 +03:00
protected :
explicit InterpretedStringArrayRecordField ( const std : : string & name ) ;
2019-12-12 17:01:12 +03:00
std : : list < std : : string > m_names_array ;
std : : list < std : : string > m_values_array ;
2019-12-11 17:16:28 +03:00
} ;
2019-12-09 11:44:51 +03:00
# endif /* AUDITD_PLUGIN_CLICKHOUSE_RECORD_HPP */