[Commits] f953315: MDEV-5313 Improving audit api.

Alexey Botchkov holyfoot at askmonty.org
Mon Jan 14 18:23:31 EET 2019


revision-id: f953315f68e21c9a994c9c30d02589631e4778a7 (mariadb-10.4.1-75-gf953315)
parent(s): 301bd62b2536f85a8ce418dcd5e705796d8c5763
committer: Alexey Botchkov
timestamp: 2019-01-14 20:17:55 +0400
message:

MDEV-5313 Improving audit api.

The 'run query from plugin' proposal interface.
Consists of a single function 'run_plugin_proc', that
gets the 'stored function with no args returning TEXT' in plain string
format, runs it and returns the TEXT result.

---
 plugin/server_audit/server_audit.c |  18 ++++++
 sql/sp.cc                          | 120 +++++++++++++++++++++++++++++++++++++
 2 files changed, 138 insertions(+)

diff --git a/plugin/server_audit/server_audit.c b/plugin/server_audit/server_audit.c
index a9b4ff2..968d8b5 100644
--- a/plugin/server_audit/server_audit.c
+++ b/plugin/server_audit/server_audit.c
@@ -2325,6 +2325,23 @@ typedef struct loc_system_variables
 
 static int init_done= 0;
 
+extern int run_plugin_proc(const char *proc, size_t proc_len,
+    char *result, size_t result_buf_len, size_t *result_len);
+
+static const char *sel0=
+  "CREATE DEFINER=`root`@`localhost` FUNCTION `lipi`() RETURNS TEXT\n"
+  "begin declare v TEXT; select concat('Value: ', s1) from lipi_t into v; return v; end";
+
+int runselect()
+{
+  char buf[1024];
+  size_t res_len;
+  int res;
+
+  res= run_plugin_proc(sel0, strlen(sel0), buf, sizeof(buf), &res_len);
+  return res;
+}
+
 static int server_audit_init(void *p __attribute__((unused)))
 {
   if (!serv_ver)
@@ -2433,6 +2450,7 @@ static int server_audit_init(void *p __attribute__((unused)))
   if (logging)
     start_logging();
 
+  runselect();
   init_done= 1;
   return 0;
 }
diff --git a/sql/sp.cc b/sql/sp.cc
index 6b38a0d..647f201 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -273,6 +273,7 @@ class Stored_routine_creation_ctx : public Stored_program_creation_ctx,
     : Stored_program_creation_ctx(thd)
   { }
 
+public:
   Stored_routine_creation_ctx(CHARSET_INFO *client_cs,
                               CHARSET_INFO *connection_cl,
                               CHARSET_INFO *db_cl)
@@ -3056,3 +3057,122 @@ LEX_CSTRING Sp_handler_function::empty_body_lex_cstring(sql_mode_t mode) const
   static LEX_CSTRING m_empty_body_ora= {STRING_WITH_LEN("AS BEGIN RETURN NULL; END")};
   return mode & MODE_ORACLE ? m_empty_body_ora : m_empty_body_std;
 }
+
+
+static Stored_routine_creation_ctx rs_ctx(&my_charset_bin,
+                                          &my_charset_bin,
+                                          &my_charset_bin);
+
+#include "sp_rcontext.h" //sp_rcontext declaration
+
+extern "C" int run_plugin_proc(const char *proc, size_t proc_len,
+    char *result, size_t result_buf_len, size_t *result_len)
+{
+  THD *thd= current_thd;
+  LEX *old_lex= thd->lex, newlex;
+  TABLE *dummy_table;
+  MEM_ROOT sp_mem_root;
+  String defstr(proc, proc_len, system_charset_info);
+  sql_mode_t sql_mode;
+  Sp_chistics chistics;
+  Query_arena *sp_query_arena;
+  Field *sp_result_field;
+  uchar result_buf[10];
+  uchar null_buf[1];
+  //Stored_program_creation_ctx *creation_ctx;
+  Sub_statement_state statement_state;
+  sp_rcontext *func_ctx= NULL;
+  String buf;
+  int err_status= 1;
+
+  thd->lex= &newlex;
+  newlex.current_select= NULL;
+
+  sql_mode= thd->variables.sql_mode;
+
+  sp_head *pi= sp_compile(thd, &defstr, sql_mode, NULL, &rs_ctx);
+  {
+    /* Set current user as a definer. */
+    CHARSET_INFO *cs= system_charset_info;
+    const char *user= thd->security_ctx->user;
+    const char *host= thd->security_ctx->host;
+    size_t res_length= (strlen(user)+strlen(host)+2) * cs->mbmaxlen;
+    if (buf.alloc((uint) res_length))
+      goto error;
+    res_length= cs->cset->snprintf(cs, (char*)buf.ptr(), (uint) res_length,
+                                       "%s@%s", user, host);
+    buf.length(res_length);
+    pi->set_definer(buf.ptr(), buf.length());
+  }
+  chistics.suid= SP_IS_SUID;
+  chistics.daccess= SP_CONTAINS_SQL;
+  chistics.agg_type= NOT_AGGREGATE;
+  pi->set_info(0, 0, chistics, sql_mode);
+  pi->set_creation_ctx(&rs_ctx);
+  pi->optimize();
+
+  newlex.set_trg_event_type_for_tables();
+  thd->lex->sphead= NULL;
+  lex_end(thd->lex);
+  thd->lex= old_lex;
+
+  /* Item_sp::Item_sp > */
+  dummy_table= (TABLE*) thd->calloc(sizeof(TABLE) + sizeof(TABLE_SHARE) +
+                                    sizeof(Query_arena));
+  dummy_table->s= (TABLE_SHARE*) (dummy_table + 1);
+  sp_query_arena= (Query_arena *) (dummy_table->s + 1);
+  memset(&sp_mem_root, 0, sizeof(sp_mem_root));
+  /* < Item_sp::Item_sp */
+  /* Item_sp::init_result_field > */
+  /*
+     A Field needs to be attached to a Table.
+     Below we "create" a dummy table by initializing
+     the needed pointers.
+   */
+  dummy_table->alias.set("", 0, table_alias_charset);
+  dummy_table->in_use= thd;
+  dummy_table->copy_blobs= TRUE;
+  dummy_table->s->table_cache_key= empty_clex_str;
+  dummy_table->s->table_name= empty_clex_str;
+  dummy_table->maybe_null= 1;
+
+  if (!(sp_result_field= new (thd->mem_root)
+        Field_blob(result_buf, null_buf, 1,
+          Field::NONE, &empty_clex_str,
+          dummy_table->s, 2, &my_charset_latin1)))
+    goto error;
+  sp_result_field->init(dummy_table);
+  sp_result_field->null_bit= 1; //????
+
+  /* < Item_sp::init_result_field */
+
+  /* Item_sp::execute >*/
+  thd->reset_sub_statement_state(&statement_state, SUB_STMT_FUNCTION);
+  init_sql_alloc(&sp_mem_root, "ap_query", MEM_ROOT_BLOCK_SIZE, 0, MYF(0)); 
+  *sp_query_arena= Query_arena(&sp_mem_root,
+                               Query_arena::STMT_INITIALIZED_FOR_SP);
+
+  err_status= pi->execute_function(thd, NULL, 0, sp_result_field,
+                                   &func_ctx, sp_query_arena);
+
+  delete func_ctx;
+  sp_query_arena->free_items();
+  free_root(&sp_mem_root, MYF(0));
+
+  thd->restore_sub_statement_state(&statement_state);
+  sp_result_field->val_str(&buf);
+  *result_len= buf.length();
+  if (buf.length() < result_buf_len)
+    result_buf_len= buf.length();
+
+  memcpy(result, buf.ptr(), result_buf_len);
+
+  thd->lex->sphead= NULL;
+  lex_end(thd->lex);
+  thd->lex= old_lex;
+
+  /* < Item_sp::execute */
+error:
+  return err_status;
+}
+


More information about the commits mailing list