Skip to content
Permalink
Browse files
MDEV-21689 Add Sql_cmd for GRANT/REVOKE statements
Rewriting GRANT/REVOKE grammar to use more bison stack and use Sql_cmd_ style

1. Removing a few members from LEX:
   - uint grant, grant_to_col, which_columns
   - List<LEX_COLUMN> columns
   - bool all_privileges
2. Adding classes Grand_object_name, Lex_grant_object_name
3. Adding classes Grand_privilege, Lex_grand_privilege
4. Adding struct Lex_column_list_privilege_st, class Lex_column_list_privilege
5. Rewriting the GRANT/REVOKE grammar to use new classes and pass them through
   bison stack (rather than directly access LEX members)
6. Adding classes Sql_cmd_grant* and Sql_cmd_revoke*,
   changing GRANT/REVOKE to use LEX::m_sql_cmd.
7. Adding the "sp_handler" grammar rule and removing some duplicate grammar
   for GRANT/REVOKE for different kinds of SP objects.
8. Adding a new rule comma_separated_ident_list, reusing it in:
   - with_column_list
   - colum_list_privilege
  • Loading branch information
abarkov committed Feb 8, 2020
1 parent 06b0623 commit 77c6382
Show file tree
Hide file tree
Showing 13 changed files with 813 additions and 317 deletions.
@@ -47,7 +47,8 @@ SET(SQL_EMBEDDED_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc
../sql/password.c ../sql/discover.cc ../sql/derror.cc
../sql/field.cc ../sql/field_conv.cc ../sql/field_comp.cc
../sql/filesort_utils.cc ../sql/sql_digest.cc
../sql/filesort.cc ../sql/gstream.cc ../sql/slave.cc
../sql/filesort.cc ../sql/grant.cc
../sql/gstream.cc ../sql/slave.cc
../sql/signal_handler.cc
../sql/handler.cc ../sql/hash_filo.cc ../sql/hostname.cc
../sql/init.cc ../sql/item_buff.cc ../sql/item_cmpfunc.cc
@@ -129,6 +129,7 @@ SET (SQL_SOURCE
sql_reload.cc

# added in MariaDB:
grant.cc
sql_explain.cc
sql_analyze_stmt.cc
sql_join_cache.cc
@@ -0,0 +1,108 @@
/*
Copyright (c) 2009, 2020, MariaDB Corporation
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; version 2 of the License.
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, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */

#include "mariadb.h"
#include "sql_acl.h"


bool Grant_privilege::add_column_privilege(THD *thd,
const Lex_ident_sys &name,
uint which_grant)
{
String *new_str= new (thd->mem_root) String((const char*) name.str,
name.length,
system_charset_info);
if (unlikely(new_str == NULL))
return true;
List_iterator <LEX_COLUMN> iter(m_columns);
class LEX_COLUMN *point;
while ((point=iter++))
{
if (!my_strcasecmp(system_charset_info,
point->column.c_ptr(), new_str->c_ptr()))
break;
}
m_column_privilege_total|= which_grant;
if (point)
{
point->rights |= which_grant;
return false;
}

LEX_COLUMN *col= new (thd->mem_root) LEX_COLUMN(*new_str, which_grant);
if (unlikely(col == NULL))
return true;
return m_columns.push_back(col, thd->mem_root);
}


bool Grant_privilege::add_column_list_privilege(THD *thd,
List<Lex_ident_sys> &list,
uint privilege)
{
Lex_ident_sys *col;
List_iterator<Lex_ident_sys> it(list);
while ((col= it++))
{
if (add_column_privilege(thd, *col, privilege))
return true;
}
return false;
}


uint Grant_object_name::all_privileges_by_type() const
{
switch (m_type) {
case STAR: return DB_ACLS & ~GRANT_ACL;
case IDENT_STAR: return DB_ACLS & ~GRANT_ACL;
case STAR_STAR: return GLOBAL_ACLS & ~GRANT_ACL;
case TABLE_IDENT: return TABLE_ACLS & ~GRANT_ACL;
}
return 0;
}


bool Grant_privilege::set_object_name(THD *thd,
const Grant_object_name &ident,
SELECT_LEX *sel,
uint with_grant_option)
{
DBUG_ASSERT(!m_all_privileges || !m_columns.elements);

m_db= ident.m_db;
if (m_all_privileges)
m_object_privilege= ident.all_privileges_by_type();
m_object_privilege|= with_grant_option;
switch (ident.m_type)
{
case Lex_grant_object_name::STAR:
case Lex_grant_object_name::IDENT_STAR:
case Lex_grant_object_name::STAR_STAR:
if (!m_all_privileges && m_columns.elements)
{
// e.g. GRANT SELECT (a) ON db.*
my_error(ER_ILLEGAL_GRANT_FOR_TABLE, MYF(0));
return true;
}
return false;
case Lex_grant_object_name::TABLE_IDENT:
m_db= ident.m_table_ident->db;
return !sel->add_table_to_list(thd, ident.m_table_ident,
NULL, TL_OPTION_UPDATING);
}
return false; // Make gcc happy
}
@@ -0,0 +1,96 @@
/*
Copyright (c) 2020, MariaDB Corporation.
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; version 2 of the License.
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, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */

#ifndef SQL_GRANT_INCLUDED
#define SQL_GRANT_INCLUDED

#include "lex_string.h"

class LEX_COLUMN;
class Lex_ident_sys;
class Table_ident;

/*
Represents the object name in this standard SQL grammar:
GRANT <object privileges> ON <object name>
*/
class Grant_object_name
{
public:
enum Type
{
STAR, // ON *
IDENT_STAR, // ON db.*
STAR_STAR, // ON *.*
TABLE_IDENT // ON db.name
};
Lex_cstring m_db;
Table_ident *m_table_ident;
Type m_type;
public:
Grant_object_name(Table_ident *table_ident)
:m_table_ident(table_ident),
m_type(TABLE_IDENT)
{ }
Grant_object_name(const LEX_CSTRING &db, Type type)
:m_db(db),
m_table_ident(NULL),
m_type(type)
{ }
uint all_privileges_by_type() const;
};



/*
Represents standard SQL statements described by:
- <grant privilege statement>
- <revoke privilege statement>
*/
class Grant_privilege
{
protected:
List<LEX_COLUMN> m_columns;
Lex_cstring m_db;
uint m_object_privilege;
uint m_column_privilege_total;
bool m_all_privileges;
public:
Grant_privilege()
:m_object_privilege(0), m_column_privilege_total(0), m_all_privileges(false)
{ }
Grant_privilege(uint privilege, bool all_privileges)
:m_object_privilege(privilege),
m_column_privilege_total(0),
m_all_privileges(all_privileges)
{ }
void add_object_privilege(uint privilege)
{
m_object_privilege|= privilege;
}
bool add_column_privilege(THD *thd, const Lex_ident_sys &col,
uint privilege);
bool add_column_list_privilege(THD *thd, List<Lex_ident_sys> &list,
uint privilege);
bool set_object_name(THD *thd,
const Grant_object_name &ident,
SELECT_LEX *sel,
uint with_grant_option);
const List<LEX_COLUMN> & columns() const { return m_columns; }
};


#endif // SQL_GRANT_INCLUDED
@@ -30,6 +30,10 @@ class Lex_cstring : public LEX_CSTRING
str= NULL;
length= 0;
}
Lex_cstring(const LEX_CSTRING &str)
{
LEX_CSTRING::operator=(str);
}
Lex_cstring(const char *_str, size_t _len)
{
str= _str;

0 comments on commit 77c6382

Please sign in to comment.