1#ifndef SQL_ACL_INCLUDED
2#define SQL_ACL_INCLUDED
3
4/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
5 Copyright (c) 2017, MariaDB Corporation.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; version 2 of the License.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
19
20#include "violite.h" /* SSL_type */
21#include "sql_class.h" /* LEX_COLUMN */
22
23#define SELECT_ACL (1UL << 0)
24#define INSERT_ACL (1UL << 1)
25#define UPDATE_ACL (1UL << 2)
26#define DELETE_ACL (1UL << 3)
27#define CREATE_ACL (1UL << 4)
28#define DROP_ACL (1UL << 5)
29#define RELOAD_ACL (1UL << 6)
30#define SHUTDOWN_ACL (1UL << 7)
31#define PROCESS_ACL (1UL << 8)
32#define FILE_ACL (1UL << 9)
33#define GRANT_ACL (1UL << 10)
34#define REFERENCES_ACL (1UL << 11)
35#define INDEX_ACL (1UL << 12)
36#define ALTER_ACL (1UL << 13)
37#define SHOW_DB_ACL (1UL << 14)
38#define SUPER_ACL (1UL << 15)
39#define CREATE_TMP_ACL (1UL << 16)
40#define LOCK_TABLES_ACL (1UL << 17)
41#define EXECUTE_ACL (1UL << 18)
42#define REPL_SLAVE_ACL (1UL << 19)
43#define REPL_CLIENT_ACL (1UL << 20)
44#define CREATE_VIEW_ACL (1UL << 21)
45#define SHOW_VIEW_ACL (1UL << 22)
46#define CREATE_PROC_ACL (1UL << 23)
47#define ALTER_PROC_ACL (1UL << 24)
48#define CREATE_USER_ACL (1UL << 25)
49#define EVENT_ACL (1UL << 26)
50#define TRIGGER_ACL (1UL << 27)
51#define CREATE_TABLESPACE_ACL (1UL << 28)
52#define DELETE_HISTORY_ACL (1UL << 29)
53/*
54 don't forget to update
55 1. static struct show_privileges_st sys_privileges[]
56 2. static const char *command_array[] and static uint command_lengths[]
57 3. mysql_system_tables.sql and mysql_system_tables_fix.sql
58 4. acl_init() or whatever - to define behaviour for old privilege tables
59 5. sql_yacc.yy - for GRANT/REVOKE to work
60*/
61#define NO_ACCESS (1UL << 30)
62#define DB_ACLS \
63(UPDATE_ACL | SELECT_ACL | INSERT_ACL | DELETE_ACL | CREATE_ACL | DROP_ACL | \
64 GRANT_ACL | REFERENCES_ACL | INDEX_ACL | ALTER_ACL | CREATE_TMP_ACL | \
65 LOCK_TABLES_ACL | EXECUTE_ACL | CREATE_VIEW_ACL | SHOW_VIEW_ACL | \
66 CREATE_PROC_ACL | ALTER_PROC_ACL | EVENT_ACL | TRIGGER_ACL | \
67 DELETE_HISTORY_ACL)
68
69#define TABLE_ACLS \
70(SELECT_ACL | INSERT_ACL | UPDATE_ACL | DELETE_ACL | CREATE_ACL | DROP_ACL | \
71 GRANT_ACL | REFERENCES_ACL | INDEX_ACL | ALTER_ACL | CREATE_VIEW_ACL | \
72 SHOW_VIEW_ACL | TRIGGER_ACL | DELETE_HISTORY_ACL)
73
74#define COL_ACLS \
75(SELECT_ACL | INSERT_ACL | UPDATE_ACL | REFERENCES_ACL)
76
77#define PROC_ACLS \
78(ALTER_PROC_ACL | EXECUTE_ACL | GRANT_ACL)
79
80#define SHOW_PROC_ACLS \
81(ALTER_PROC_ACL | EXECUTE_ACL | CREATE_PROC_ACL)
82
83#define GLOBAL_ACLS \
84(SELECT_ACL | INSERT_ACL | UPDATE_ACL | DELETE_ACL | CREATE_ACL | DROP_ACL | \
85 RELOAD_ACL | SHUTDOWN_ACL | PROCESS_ACL | FILE_ACL | GRANT_ACL | \
86 REFERENCES_ACL | INDEX_ACL | ALTER_ACL | SHOW_DB_ACL | SUPER_ACL | \
87 CREATE_TMP_ACL | LOCK_TABLES_ACL | REPL_SLAVE_ACL | REPL_CLIENT_ACL | \
88 EXECUTE_ACL | CREATE_VIEW_ACL | SHOW_VIEW_ACL | CREATE_PROC_ACL | \
89 ALTER_PROC_ACL | CREATE_USER_ACL | EVENT_ACL | TRIGGER_ACL | \
90 CREATE_TABLESPACE_ACL | DELETE_HISTORY_ACL)
91
92#define DEFAULT_CREATE_PROC_ACLS \
93(ALTER_PROC_ACL | EXECUTE_ACL)
94
95#define SHOW_CREATE_TABLE_ACLS \
96(SELECT_ACL | INSERT_ACL | UPDATE_ACL | DELETE_ACL | \
97 CREATE_ACL | DROP_ACL | ALTER_ACL | INDEX_ACL | \
98 TRIGGER_ACL | REFERENCES_ACL | GRANT_ACL | CREATE_VIEW_ACL | SHOW_VIEW_ACL)
99
100/**
101 Table-level privileges which are automatically "granted" to everyone on
102 existing temporary tables (CREATE_ACL is necessary for ALTER ... RENAME).
103*/
104#define TMP_TABLE_ACLS \
105(SELECT_ACL | INSERT_ACL | UPDATE_ACL | DELETE_ACL | CREATE_ACL | DROP_ACL | \
106 INDEX_ACL | ALTER_ACL)
107
108/*
109 Defines to change the above bits to how things are stored in tables
110 This is needed as the 'host' and 'db' table is missing a few privileges
111*/
112
113/* Privileges that needs to be reallocated (in continous chunks) */
114#define DB_CHUNK0 (SELECT_ACL | INSERT_ACL | UPDATE_ACL | DELETE_ACL | \
115 CREATE_ACL | DROP_ACL)
116#define DB_CHUNK1 (GRANT_ACL | REFERENCES_ACL | INDEX_ACL | ALTER_ACL)
117#define DB_CHUNK2 (CREATE_TMP_ACL | LOCK_TABLES_ACL)
118#define DB_CHUNK3 (CREATE_VIEW_ACL | SHOW_VIEW_ACL | \
119 CREATE_PROC_ACL | ALTER_PROC_ACL )
120#define DB_CHUNK4 (EXECUTE_ACL)
121#define DB_CHUNK5 (EVENT_ACL | TRIGGER_ACL)
122#define DB_CHUNK6 (DELETE_HISTORY_ACL)
123
124#define fix_rights_for_db(A) (((A) & DB_CHUNK0) | \
125 (((A) << 4) & DB_CHUNK1) | \
126 (((A) << 6) & DB_CHUNK2) | \
127 (((A) << 9) & DB_CHUNK3) | \
128 (((A) << 2) & DB_CHUNK4) | \
129 (((A) << 9) & DB_CHUNK5) | \
130 (((A) << 10) & DB_CHUNK6))
131#define get_rights_for_db(A) (((A) & DB_CHUNK0) | \
132 (((A) & DB_CHUNK1) >> 4) | \
133 (((A) & DB_CHUNK2) >> 6) | \
134 (((A) & DB_CHUNK3) >> 9) | \
135 (((A) & DB_CHUNK4) >> 2) | \
136 (((A) & DB_CHUNK5) >> 9) | \
137 (((A) & DB_CHUNK6) >> 10))
138#define TBL_CHUNK0 DB_CHUNK0
139#define TBL_CHUNK1 DB_CHUNK1
140#define TBL_CHUNK2 (CREATE_VIEW_ACL | SHOW_VIEW_ACL)
141#define TBL_CHUNK3 TRIGGER_ACL
142#define TBL_CHUNK4 (DELETE_HISTORY_ACL)
143#define fix_rights_for_table(A) (((A) & TBL_CHUNK0) | \
144 (((A) << 4) & TBL_CHUNK1) | \
145 (((A) << 11) & TBL_CHUNK2) | \
146 (((A) << 15) & TBL_CHUNK3) | \
147 (((A) << 16) & TBL_CHUNK4))
148#define get_rights_for_table(A) (((A) & TBL_CHUNK0) | \
149 (((A) & TBL_CHUNK1) >> 4) | \
150 (((A) & TBL_CHUNK2) >> 11) | \
151 (((A) & TBL_CHUNK3) >> 15) | \
152 (((A) & TBL_CHUNK4) >> 16))
153#define fix_rights_for_column(A) (((A) & 7) | (((A) & ~7) << 8))
154#define get_rights_for_column(A) (((A) & 7) | ((A) >> 8))
155#define fix_rights_for_procedure(A) ((((A) << 18) & EXECUTE_ACL) | \
156 (((A) << 23) & ALTER_PROC_ACL) | \
157 (((A) << 8) & GRANT_ACL))
158#define get_rights_for_procedure(A) ((((A) & EXECUTE_ACL) >> 18) | \
159 (((A) & ALTER_PROC_ACL) >> 23) | \
160 (((A) & GRANT_ACL) >> 8))
161
162enum mysql_db_table_field
163{
164 MYSQL_DB_FIELD_HOST = 0,
165 MYSQL_DB_FIELD_DB,
166 MYSQL_DB_FIELD_USER,
167 MYSQL_DB_FIELD_SELECT_PRIV,
168 MYSQL_DB_FIELD_INSERT_PRIV,
169 MYSQL_DB_FIELD_UPDATE_PRIV,
170 MYSQL_DB_FIELD_DELETE_PRIV,
171 MYSQL_DB_FIELD_CREATE_PRIV,
172 MYSQL_DB_FIELD_DROP_PRIV,
173 MYSQL_DB_FIELD_GRANT_PRIV,
174 MYSQL_DB_FIELD_REFERENCES_PRIV,
175 MYSQL_DB_FIELD_INDEX_PRIV,
176 MYSQL_DB_FIELD_ALTER_PRIV,
177 MYSQL_DB_FIELD_CREATE_TMP_TABLE_PRIV,
178 MYSQL_DB_FIELD_LOCK_TABLES_PRIV,
179 MYSQL_DB_FIELD_CREATE_VIEW_PRIV,
180 MYSQL_DB_FIELD_SHOW_VIEW_PRIV,
181 MYSQL_DB_FIELD_CREATE_ROUTINE_PRIV,
182 MYSQL_DB_FIELD_ALTER_ROUTINE_PRIV,
183 MYSQL_DB_FIELD_EXECUTE_PRIV,
184 MYSQL_DB_FIELD_EVENT_PRIV,
185 MYSQL_DB_FIELD_TRIGGER_PRIV,
186 MYSQL_DB_FIELD_DELETE_VERSIONING_ROWS_PRIV,
187 MYSQL_DB_FIELD_COUNT
188};
189
190extern const TABLE_FIELD_DEF mysql_db_table_def;
191extern bool mysql_user_table_is_in_short_password_format;
192
193extern LEX_CSTRING host_not_specified;
194extern LEX_CSTRING current_user;
195extern LEX_CSTRING current_role;
196extern LEX_CSTRING current_user_and_current_role;
197
198
199static inline int access_denied_error_code(int passwd_used)
200{
201#ifdef mysqld_error_find_printf_error_used
202 return 0;
203#else
204 return passwd_used == 2 ? ER_ACCESS_DENIED_NO_PASSWORD_ERROR
205 : ER_ACCESS_DENIED_ERROR;
206#endif
207}
208
209/* prototypes */
210
211bool hostname_requires_resolving(const char *hostname);
212bool acl_init(bool dont_read_acl_tables);
213bool acl_reload(THD *thd);
214void acl_free(bool end=0);
215ulong acl_get(const char *host, const char *ip,
216 const char *user, const char *db, my_bool db_is_pattern);
217bool acl_authenticate(THD *thd, uint com_change_user_pkt_len);
218bool acl_getroot(Security_context *sctx, const char *user, const char *host,
219 const char *ip, const char *db);
220bool acl_check_host(const char *host, const char *ip);
221bool check_change_password(THD *thd, LEX_USER *user);
222bool change_password(THD *thd, LEX_USER *user);
223
224bool mysql_grant_role(THD *thd, List<LEX_USER> &user_list, bool revoke);
225bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &user_list,
226 ulong rights, bool revoke, bool is_proxy);
227int mysql_table_grant(THD *thd, TABLE_LIST *table, List <LEX_USER> &user_list,
228 List <LEX_COLUMN> &column_list, ulong rights,
229 bool revoke);
230bool mysql_routine_grant(THD *thd, TABLE_LIST *table, const Sp_handler *sph,
231 List <LEX_USER> &user_list, ulong rights,
232 bool revoke, bool write_to_binlog);
233bool grant_init();
234void grant_free(void);
235bool grant_reload(THD *thd);
236bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
237 bool any_combination_will_do, uint number, bool no_errors);
238bool check_grant_column (THD *thd, GRANT_INFO *grant,
239 const char *db_name, const char *table_name,
240 const char *name, size_t length, Security_context *sctx);
241bool check_column_grant_in_table_ref(THD *thd, TABLE_LIST * table_ref,
242 const char *name, size_t length, Field *fld);
243bool check_grant_all_columns(THD *thd, ulong want_access,
244 Field_iterator_table_ref *fields);
245bool check_grant_routine(THD *thd, ulong want_access,
246 TABLE_LIST *procs, const Sp_handler *sph,
247 bool no_error);
248bool check_grant_db(THD *thd,const char *db);
249bool check_global_access(THD *thd, ulong want_access, bool no_errors= false);
250bool check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
251 GRANT_INTERNAL_INFO *grant_internal_info,
252 bool dont_check_global_grants, bool no_errors);
253ulong get_table_grant(THD *thd, TABLE_LIST *table);
254ulong get_column_grant(THD *thd, GRANT_INFO *grant,
255 const char *db_name, const char *table_name,
256 const char *field_name);
257void mysql_show_grants_get_fields(THD *thd, List<Item> *fields,
258 const char *name, size_t length);
259bool mysql_show_grants(THD *thd, LEX_USER *user);
260bool mysql_show_create_user(THD *thd, LEX_USER *user);
261int fill_schema_enabled_roles(THD *thd, TABLE_LIST *tables, COND *cond);
262int fill_schema_applicable_roles(THD *thd, TABLE_LIST *tables, COND *cond);
263void get_privilege_desc(char *to, uint max_length, ulong access);
264void get_mqh(const char *user, const char *host, USER_CONN *uc);
265bool mysql_create_user(THD *thd, List <LEX_USER> &list, bool handle_as_role);
266bool mysql_drop_user(THD *thd, List <LEX_USER> &list, bool handle_as_role);
267bool mysql_rename_user(THD *thd, List <LEX_USER> &list);
268int mysql_alter_user(THD *thd, List <LEX_USER> &list);
269bool mysql_revoke_all(THD *thd, List <LEX_USER> &list);
270void fill_effective_table_privileges(THD *thd, GRANT_INFO *grant,
271 const char *db, const char *table);
272bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name,
273 const Sp_handler *sph);
274bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name,
275 const Sp_handler *sph);
276bool check_routine_level_acl(THD *thd, const char *db, const char *name,
277 const Sp_handler *sph);
278bool is_acl_user(const char *host, const char *user);
279int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond);
280int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond);
281int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond);
282int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond);
283int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *wildstr);
284
285/**
286 Result of an access check for an internal schema or table.
287 Internal ACL checks are always performed *before* using
288 the grant tables.
289 This mechanism enforces that the server implementation has full
290 control on its internal tables.
291 Depending on the internal check result, the server implementation
292 can choose to:
293 - always allow access,
294 - always deny access,
295 - delegate the decision to the database administrator,
296 by using the grant tables.
297*/
298enum ACL_internal_access_result
299{
300 /**
301 Access granted for all the requested privileges,
302 do not use the grant tables.
303 This flag is used only for the INFORMATION_SCHEMA privileges,
304 for compatibility reasons.
305 */
306 ACL_INTERNAL_ACCESS_GRANTED,
307 /** Access denied, do not use the grant tables. */
308 ACL_INTERNAL_ACCESS_DENIED,
309 /** No decision yet, use the grant tables. */
310 ACL_INTERNAL_ACCESS_CHECK_GRANT
311};
312
313/**
314 Per internal table ACL access rules.
315 This class is an interface.
316 Per table(s) specific access rule should be implemented in a subclass.
317 @sa ACL_internal_schema_access
318*/
319class ACL_internal_table_access
320{
321public:
322 ACL_internal_table_access()
323 {}
324
325 virtual ~ACL_internal_table_access()
326 {}
327
328 /**
329 Check access to an internal table.
330 When a privilege is granted, this method add the requested privilege
331 to save_priv.
332 @param want_access the privileges requested
333 @param [in, out] save_priv the privileges granted
334 @return
335 @retval ACL_INTERNAL_ACCESS_GRANTED All the requested privileges
336 are granted, and saved in save_priv.
337 @retval ACL_INTERNAL_ACCESS_DENIED At least one of the requested
338 privileges was denied.
339 @retval ACL_INTERNAL_ACCESS_CHECK_GRANT No requested privilege
340 was denied, and grant should be checked for at least one
341 privilege. Requested privileges that are granted, if any, are saved
342 in save_priv.
343 */
344 virtual ACL_internal_access_result check(ulong want_access,
345 ulong *save_priv) const= 0;
346};
347
348/**
349 Per internal schema ACL access rules.
350 This class is an interface.
351 Each per schema specific access rule should be implemented
352 in a different subclass, and registered.
353 Per schema access rules can control:
354 - every schema privileges on schema.*
355 - every table privileges on schema.table
356 @sa ACL_internal_schema_registry
357*/
358class ACL_internal_schema_access
359{
360public:
361 ACL_internal_schema_access()
362 {}
363
364 virtual ~ACL_internal_schema_access()
365 {}
366
367 /**
368 Check access to an internal schema.
369 @param want_access the privileges requested
370 @param [in, out] save_priv the privileges granted
371 @return
372 @retval ACL_INTERNAL_ACCESS_GRANTED All the requested privileges
373 are granted, and saved in save_priv.
374 @retval ACL_INTERNAL_ACCESS_DENIED At least one of the requested
375 privileges was denied.
376 @retval ACL_INTERNAL_ACCESS_CHECK_GRANT No requested privilege
377 was denied, and grant should be checked for at least one
378 privilege. Requested privileges that are granted, if any, are saved
379 in save_priv.
380 */
381 virtual ACL_internal_access_result check(ulong want_access,
382 ulong *save_priv) const= 0;
383
384 /**
385 Search for per table ACL access rules by table name.
386 @param name the table name
387 @return per table access rules, or NULL
388 */
389 virtual const ACL_internal_table_access *lookup(const char *name) const= 0;
390};
391
392/**
393 A registry for per internal schema ACL.
394 An 'internal schema' is a database schema maintained by the
395 server implementation, such as 'performance_schema' and 'INFORMATION_SCHEMA'.
396*/
397class ACL_internal_schema_registry
398{
399public:
400 static void register_schema(const LEX_CSTRING *name,
401 const ACL_internal_schema_access *access);
402 static const ACL_internal_schema_access *lookup(const char *name);
403};
404
405const ACL_internal_schema_access *
406get_cached_schema_access(GRANT_INTERNAL_INFO *grant_internal_info,
407 const char *schema_name);
408
409const ACL_internal_table_access *
410get_cached_table_access(GRANT_INTERNAL_INFO *grant_internal_info,
411 const char *schema_name,
412 const char *table_name);
413
414bool acl_check_proxy_grant_access (THD *thd, const char *host, const char *user,
415 bool with_grant);
416int acl_setrole(THD *thd, const char *rolename, ulonglong access);
417int acl_check_setrole(THD *thd, const char *rolename, ulonglong *access);
418int acl_check_set_default_role(THD *thd, const char *host, const char *user);
419int acl_set_default_role(THD *thd, const char *host, const char *user,
420 const char *rolename);
421
422extern SHOW_VAR acl_statistics[];
423
424/* Check if a role is granted to a user/role.
425
426 If hostname == NULL, search for a role as the starting grantee.
427*/
428bool check_role_is_granted(const char *username,
429 const char *hostname,
430 const char *rolename);
431
432#ifndef DBUG_OFF
433extern ulong role_global_merges, role_db_merges, role_table_merges,
434 role_column_merges, role_routine_merges;
435#endif
436#endif /* SQL_ACL_INCLUDED */
437