new object iteration logic including fix for crash reported in issue #31
parent
f717564993
commit
bc92825963
|
@ -79,14 +79,35 @@ public:
|
|||
|
||||
class ThdSesData {
|
||||
public:
|
||||
|
||||
//enum indicating from where the object list came from
|
||||
enum ObjectIterType {OBJ_NONE, OBJ_DB, OBJ_QUERY_CACHE, OBJ_TABLE_LIST};
|
||||
ThdSesData(THD *pTHD);
|
||||
THD* getTHD () { return m_pThd;}
|
||||
const char * getCmdName () { return m_CmdName; }
|
||||
const char * getUserName () { return m_UserName; }
|
||||
/**
|
||||
* Start fetching objects. Return true if there are objects available.
|
||||
*/
|
||||
bool startGetObjects();
|
||||
/**
|
||||
* Get next object. Return true if populated. False if there isn't an object available.
|
||||
* Will point the passed pointers to point to db, name and type.
|
||||
* obj_type is optional and may be null.
|
||||
*/
|
||||
bool getNextObject(const char ** db_name, const char ** obj_name, const char ** obj_type);
|
||||
private:
|
||||
THD *m_pThd;
|
||||
const char *m_CmdName;
|
||||
const char *m_UserName;
|
||||
enum ObjectIterType m_objIterType;
|
||||
//pointer for iterating tables
|
||||
TABLE_LIST * m_tables;
|
||||
//indicator if we are at the first table
|
||||
bool m_firstTable;
|
||||
//used for query cache iter
|
||||
QueryTableInf * m_tableInf;
|
||||
int m_index;
|
||||
protected:
|
||||
ThdSesData (const ThdSesData& );
|
||||
ThdSesData &operator =(const ThdSesData& );
|
||||
|
|
|
@ -414,71 +414,25 @@ ssize_t Audit_json_formatter::event_format(ThdSesData* pThdData, IWriter * write
|
|||
yajl_add_string_val(gen, "host", sctx->host);
|
||||
yajl_add_string_val(gen, "ip", sctx->ip);
|
||||
const char *cmd = pThdData->getCmdName();
|
||||
//only print tables if lex is not null and it is not a quit command
|
||||
LEX * pLex = Audit_formatter::thd_lex(pThdData->getTHD());
|
||||
QueryTableInf *pQuery_cache_table_list = getQueryCacheTableList1 (pThdData->getTHD());
|
||||
if (pLex && command != COM_QUIT && pLex->query_tables == NULL && pQuery_cache_table_list)
|
||||
{
|
||||
yajl_add_string_val(gen, "cmd", "select");
|
||||
yajl_add_string(gen, "objects");
|
||||
yajl_gen_array_open(gen);
|
||||
for (int i=0;i<pQuery_cache_table_list->num_of_elem && i < MAX_NUM_QUERY_TABLE_ELEM && pQuery_cache_table_list->num_of_elem >=0;i++)
|
||||
{
|
||||
yajl_gen_map_open(gen);
|
||||
yajl_add_obj (gen, pQuery_cache_table_list->db[i],pQuery_cache_table_list->object_type[i],pQuery_cache_table_list->table_name[i] );
|
||||
yajl_gen_map_close(gen);
|
||||
|
||||
}
|
||||
yajl_gen_array_close(gen);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
yajl_add_string_val(gen, "cmd", cmd);
|
||||
}
|
||||
|
||||
|
||||
if (strcmp (cmd,"Init DB") ==0 || strcmp (cmd, "SHOW TABLES")== 0 || strcmp (cmd, "SHOW TABLE")==0)
|
||||
{
|
||||
if ((pThdData->getTHD())->db !=0)
|
||||
{
|
||||
yajl_add_string(gen, "objects");
|
||||
yajl_gen_array_open(gen);
|
||||
yajl_add_obj (gen,(pThdData->getTHD())->db,"database", NULL);
|
||||
yajl_gen_array_close(gen);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (pLex && command != COM_QUIT && pLex->query_tables)
|
||||
yajl_add_string_val(gen, "cmd", cmd);
|
||||
//get objects
|
||||
if(pThdData->startGetObjects())
|
||||
{
|
||||
yajl_add_string(gen, "objects");
|
||||
yajl_gen_array_open(gen);
|
||||
TABLE_LIST * table = pLex->query_tables;
|
||||
bool isFirstElementInView = true;
|
||||
|
||||
while (table)
|
||||
const char * db_name = NULL;
|
||||
const char * obj_name = NULL;
|
||||
const char * obj_type = NULL;
|
||||
while(pThdData->getNextObject(&db_name, &obj_name, &obj_type))
|
||||
{
|
||||
yajl_gen_map_open(gen);
|
||||
if (isFirstElementInView && strstr (cmd,"_view")!=NULL )
|
||||
{
|
||||
yajl_add_obj (gen,table->get_db_name(), "view",table->get_table_name());
|
||||
isFirstElementInView = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
yajl_add_obj (gen,table->get_db_name(), retrive_object_type(table),table->get_table_name());
|
||||
}
|
||||
yajl_add_obj (gen, db_name, obj_type, obj_name );
|
||||
yajl_gen_map_close(gen);
|
||||
table = table->next_global;
|
||||
}
|
||||
yajl_gen_array_close(gen);
|
||||
}
|
||||
|
||||
|
||||
size_t qlen = 0;
|
||||
|
||||
const char * query = thd_query_str(pThdData->getTHD(), &qlen);
|
||||
if (query && qlen > 0)
|
||||
{
|
||||
|
@ -527,9 +481,116 @@ ssize_t Audit_json_formatter::event_format(ThdSesData* pThdData, IWriter * write
|
|||
|
||||
|
||||
|
||||
|
||||
ThdSesData::ThdSesData (THD *pTHD) : m_pThd (pTHD), m_CmdName(NULL), m_UserName(NULL)
|
||||
ThdSesData::ThdSesData (THD *pTHD) :
|
||||
m_pThd (pTHD), m_CmdName(NULL), m_UserName(NULL),
|
||||
m_objIterType(OBJ_NONE), m_tables(NULL), m_firstTable(true),
|
||||
m_tableInf(NULL), m_index(0)
|
||||
{
|
||||
m_CmdName = retrieve_command (m_pThd);
|
||||
m_UserName = retrieve_user (m_pThd);
|
||||
}
|
||||
|
||||
bool ThdSesData::startGetObjects()
|
||||
{
|
||||
//reset vars as this may be called multiple times
|
||||
m_objIterType = OBJ_NONE;
|
||||
m_tables = NULL;
|
||||
m_firstTable = true;
|
||||
m_index = 0;
|
||||
m_tableInf = Audit_formatter::getQueryCacheTableList1(getTHD());
|
||||
int command = Audit_formatter::thd_inst_command(getTHD());
|
||||
LEX * pLex = Audit_formatter::thd_lex(getTHD());
|
||||
//query cache case
|
||||
if(pLex && command == COM_QUERY && m_tableInf && m_tableInf->num_of_elem > 0)
|
||||
{
|
||||
m_objIterType = OBJ_QUERY_CACHE;
|
||||
return true;
|
||||
}
|
||||
const char *cmd = getCmdName();
|
||||
//commands which have single database object
|
||||
if (strcmp (cmd,"Init DB") ==0 || strcmp (cmd, "SHOW TABLES")== 0 || strcmp (cmd, "SHOW TABLE")==0)
|
||||
{
|
||||
if(getTHD()->db)
|
||||
{
|
||||
m_objIterType = OBJ_DB;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//only return query tabls if command is COM_QUERY
|
||||
//TODO: check if other commands can also generate query tables such as "show fields"
|
||||
if (pLex && command == COM_QUERY && pLex->query_tables)
|
||||
{
|
||||
m_tables = pLex->query_tables;
|
||||
m_objIterType = OBJ_TABLE_LIST;
|
||||
return true;
|
||||
}
|
||||
//no objects
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ThdSesData::getNextObject(const char ** db_name, const char ** obj_name, const char ** obj_type)
|
||||
{
|
||||
switch(m_objIterType)
|
||||
{
|
||||
case OBJ_DB:
|
||||
{
|
||||
if(m_firstTable)
|
||||
{
|
||||
*db_name = getTHD()->db;
|
||||
*obj_name = NULL;
|
||||
if(obj_type)
|
||||
{
|
||||
*obj_type = "DATABASE";
|
||||
}
|
||||
m_firstTable = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
case OBJ_QUERY_CACHE:
|
||||
{
|
||||
if(m_index < m_tableInf->num_of_elem &&
|
||||
m_index< MAX_NUM_QUERY_TABLE_ELEM)
|
||||
{
|
||||
*db_name = m_tableInf->db[m_index];
|
||||
*obj_name = m_tableInf->table_name[m_index];
|
||||
if(obj_type)
|
||||
{
|
||||
*obj_type = m_tableInf->object_type[m_index];
|
||||
}
|
||||
m_index++;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
case OBJ_TABLE_LIST:
|
||||
{
|
||||
if(m_tables)
|
||||
{
|
||||
*db_name = m_tables->get_db_name();
|
||||
*obj_name = m_tables->get_table_name();
|
||||
if(obj_type)
|
||||
{
|
||||
//object is a view if it view command (alter_view, drop_view ..)
|
||||
//and first object or view field is populated
|
||||
if((m_firstTable && strstr(getCmdName(), "_view") != NULL) ||
|
||||
m_tables->view)
|
||||
{
|
||||
*obj_type = "VIEW";
|
||||
m_firstTable = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
*obj_type = "TABLE";
|
||||
}
|
||||
}
|
||||
m_tables = m_tables->next_global;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
default :
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -680,35 +680,22 @@ static void audit(ThdSesData *pThdData)
|
|||
}
|
||||
}
|
||||
if (num_record_objs > 0) {
|
||||
LEX *pLex = Audit_formatter::thd_lex(pThdData->getTHD());
|
||||
TABLE_LIST * table = pLex->query_tables;
|
||||
//when statement is returned from query cache, objects will be included in pQueryTableInf
|
||||
QueryTableInf * pQueryTableInf = (QueryTableInf*)THDVAR(pThdData->getTHD(), query_cache_table_list);
|
||||
int matched = 0;
|
||||
if(strcmp(pThdData->getCmdName(),"Quit") == 0 || (!table && (!pQueryTableInf || pQueryTableInf->num_of_elem <= 0))) //empty list of objects
|
||||
bool matched = false;
|
||||
if(pThdData->startGetObjects())
|
||||
{
|
||||
matched = record_empty_objs_set;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(pQueryTableInf) //query cache case
|
||||
const char * db_name = NULL;
|
||||
const char * obj_name = NULL;
|
||||
while(!matched && pThdData->getNextObject(&db_name, &obj_name, NULL))
|
||||
{
|
||||
for (int i=0; i < pQueryTableInf->num_of_elem && i < MAX_NUM_QUERY_TABLE_ELEM && !matched ; i++)
|
||||
{
|
||||
matched = check_db_obj(pQueryTableInf->db[i], pQueryTableInf->table_name[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (table && !matched)
|
||||
{
|
||||
matched = check_db_obj(table->get_db_name(), table->get_table_name());
|
||||
table = table->next_global;
|
||||
}
|
||||
matched = check_db_obj(db_name, obj_name);
|
||||
}
|
||||
}
|
||||
else //no objects
|
||||
{
|
||||
matched = record_empty_objs_set;
|
||||
}
|
||||
if (!matched) {
|
||||
return;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (pThdPrintedList && pThdPrintedList->cur_index < MAX_NUM_QUEUE_ELEM)
|
||||
|
@ -1327,6 +1314,11 @@ const char * retrieve_command (THD * thd)
|
|||
{
|
||||
command = COM_END;
|
||||
}
|
||||
//check if from query cache. If so set to select and return
|
||||
if(THDVAR(thd, query_cache_table_list) != 0)
|
||||
{
|
||||
return "select";
|
||||
}
|
||||
const int sql_command = thd_sql_command(thd);
|
||||
if (sql_command >=0 && sql_command <= (MAX_COM_STATUS_VARS_RECORDS -1) )
|
||||
{
|
||||
|
@ -1337,7 +1329,7 @@ const char * retrieve_command (THD * thd)
|
|||
cmd = command_name[command].str;
|
||||
}
|
||||
Security_context * sctx = Audit_formatter::thd_inst_main_security_ctx(thd);
|
||||
if (strcmp (cmd, "Connect") ==0 && (sctx->priv_user == NULL || *sctx->priv_user == 0x0))
|
||||
if (strcmp (cmd, "Connect") ==0 && ((sctx->user && strcmp(sctx->user, "event_scheduler") != 0) && (sctx->priv_user == NULL || *sctx->priv_user == 0x0)))
|
||||
{
|
||||
cmd = "Failed Login";
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue