1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

WL#1365: Implement definer's rights execution of stored procedures.

(Also put the hostpart back in the definer column.)


mysql-test/r/sp-error.result:
  Moved error test from sp.test
mysql-test/r/sp.result:
  Moved error test to sp-error.test.
  Put hostpart back into definer column in mysql.proc.
mysql-test/t/sp-error.test:
  Moved error test from sp.test
mysql-test/t/sp.test:
  Moved error test to sp-error.test.
  Put hostpart back into definer column in mysql.proc.
sql/item_func.cc:
  (Maybe) switch security context before invoking a stored function.
sql/sp.cc:
  Renamed creator into definer, for more consistent terminology, and put the
  hostpart back.
sql/sp_head.cc:
  Some fixes in the way things are allocated, and moved set_info() definition
  here from sp_head.h. creator is now called definer, and is split into a
  user and host part.
  Added functions for (possible) change and restore of privileges, for sql security
  definer calls.
sql/sp_head.h:
  Moved set_info() definition here from sp_head.h.
  creator is now called definer, and is split into a user and host part.
  Added functions for (possible) change and restore of privileges, for sql security
  definer calls.
sql/sql_acl.cc:
  New function acl_getroot_no_password() for getting the privileges used when
  calling an SP with sql security definer.
sql/sql_acl.h:
  New function acl_getroot_no_password() for getting the privileges used when
  calling an SP with sql security definer.
sql/sql_parse.cc:
  (Maybe) switch security context before invoking a stored procedure.
sql/sql_yacc.yy:
  Fixed typo.
This commit is contained in:
unknown
2003-12-13 16:40:52 +01:00
parent 8630ca9a09
commit a6f85eeac1
14 changed files with 392 additions and 67 deletions

View File

@@ -19,6 +19,7 @@
#endif
#include "mysql_priv.h"
#include "sql_acl.h"
#include "sp_head.h"
#include "sp.h"
#include "sp_pcontext.h"
@@ -183,9 +184,10 @@ sp_head::init_strings(LEX_STRING *name, LEX *lex)
DBUG_PRINT("info", ("name: %*s", name->length, name->str));
m_name.length= name->length;
m_name.str= lex->thd->strmake(name->str, name->length);
m_name.str= strmake_root(&m_mem_root, name->str, name->length);
m_params.length= m_param_end- m_param_begin;
m_params.str= lex->thd->strmake((char *)m_param_begin, m_params.length);
m_params.str= strmake_root(&m_mem_root,
(char *)m_param_begin, m_params.length);
if (m_returns_begin && m_returns_end)
{
/* QQ KLUDGE: We can't seem to cut out just the type in the parser
@@ -202,12 +204,13 @@ sp_head::init_strings(LEX_STRING *name, LEX *lex)
p-= 1;
m_returns_end= (uchar *)p+1;
m_retstr.length= m_returns_end - m_returns_begin;
m_retstr.str= lex->thd->strmake((char *)m_returns_begin, m_retstr.length);
m_retstr.str= strmake_root(&m_mem_root,
(char *)m_returns_begin, m_retstr.length);
}
m_body.length= lex->end_of_query - m_body_begin;
m_body.str= lex->thd->strmake((char *)m_body_begin, m_body.length);
m_body.str= strmake_root(&m_mem_root, (char *)m_body_begin, m_body.length);
m_defstr.length= lex->end_of_query - lex->buf;
m_defstr.str= lex->thd->strmake((char *)lex->buf, m_defstr.length);
m_defstr.str= strmake_root(&m_mem_root, (char *)lex->buf, m_defstr.length);
DBUG_VOID_RETURN;
}
@@ -664,6 +667,34 @@ sp_head::backpatch(sp_label_t *lab)
}
}
void
sp_head::set_info(char *definer, uint definerlen,
longlong created, longlong modified,
st_sp_chistics *chistics)
{
char *p= strchr(definer, '@');
uint len;
if (! p)
p= definer; // Weird...
len= p-definer;
m_definer_user.str= strmake_root(&m_mem_root, definer, len);
m_definer_user.length= len;
len= definerlen-len-1;
m_definer_host.str= strmake_root(&m_mem_root, p+1, len);
m_definer_host.length= len;
m_created= created;
m_modified= modified;
m_chistics= (st_sp_chistics *)alloc_root(&m_mem_root, sizeof(st_sp_chistics));
memcpy(m_chistics, chistics, sizeof(st_sp_chistics));
if (m_chistics->comment.length == 0)
m_chistics->comment.str= 0;
else
m_chistics->comment.str= strmake_root(&m_mem_root,
m_chistics->comment.str,
m_chistics->comment.length);
}
int
sp_head::show_create_procedure(THD *thd)
{
@@ -1041,3 +1072,64 @@ sp_instr_cfetch::execute(THD *thd, uint *nextp)
*nextp= m_ip+1;
DBUG_RETURN(res);
}
//
// Security context swapping
//
void
sp_change_security_context(THD *thd, sp_head *sp, st_sp_security_context *ctxp)
{
ctxp->changed= (sp->m_chistics->suid != IS_NOT_SUID &&
(strcmp(sp->m_definer_user.str, thd->priv_user) ||
strcmp(sp->m_definer_host.str, thd->priv_host)));
if (ctxp->changed)
{
ctxp->master_access= thd->master_access;
ctxp->db_access= thd->db_access;
ctxp->db= thd->db;
ctxp->db_length= thd->db_length;
ctxp->priv_user= thd->priv_user;
strncpy(ctxp->priv_host, thd->priv_host, sizeof(ctxp->priv_host));
ctxp->user= thd->user;
ctxp->host= thd->host;
ctxp->ip= thd->ip;
/* Change thise just to do the acl_getroot_no_password */
thd->user= sp->m_definer_user.str;
thd->host= thd->ip = sp->m_definer_host.str;
if (acl_getroot_no_password(thd))
{ // Failed, run as invoker for now
ctxp->changed= FALSE;
thd->master_access= ctxp->master_access;
thd->db_access= ctxp->db_access;
thd->db= ctxp->db;
thd->db_length= ctxp->db_length;
thd->priv_user= ctxp->priv_user;
strncpy(thd->priv_host, ctxp->priv_host, sizeof(thd->priv_host));
}
/* Restore these immiediately */
thd->user= ctxp->user;
thd->host= ctxp->host;
thd->ip= ctxp->ip;
}
}
void
sp_restore_security_context(THD *thd, sp_head *sp, st_sp_security_context *ctxp)
{
if (ctxp->changed)
{
ctxp->changed= FALSE;
thd->master_access= ctxp->master_access;
thd->db_access= ctxp->db_access;
thd->db= ctxp->db;
thd->db_length= ctxp->db_length;
thd->priv_user= ctxp->priv_user;
strncpy(thd->priv_host, ctxp->priv_host, sizeof(thd->priv_host));
}
}