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, 2020, 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-1335 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
162 enum 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
190 extern const TABLE_FIELD_DEF mysql_db_table_def;
191 extern bool mysql_user_table_is_in_short_password_format;
192
193 extern LEX_CSTRING host_not_specified;
194 extern LEX_CSTRING current_user;
195 extern LEX_CSTRING current_role;
196 extern LEX_CSTRING current_user_and_current_role;
197
198
access_denied_error_code(int passwd_used)199 static 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
211 bool hostname_requires_resolving(const char *hostname);
212 bool acl_init(bool dont_read_acl_tables);
213 bool acl_reload(THD *thd);
214 void acl_free(bool end=0);
215 ulong acl_get(const char *host, const char *ip,
216 const char *user, const char *db, my_bool db_is_pattern);
217 bool acl_authenticate(THD *thd, uint com_change_user_pkt_len);
218 bool acl_getroot(Security_context *sctx, const char *user, const char *host,
219 const char *ip, const char *db);
220 bool acl_check_host(const char *host, const char *ip);
221 bool check_change_password(THD *thd, LEX_USER *user);
222 bool change_password(THD *thd, LEX_USER *user);
223
224 bool mysql_grant_role(THD *thd, List<LEX_USER> &user_list, bool revoke);
225 bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &user_list,
226 ulong rights, bool revoke, bool is_proxy);
227 int mysql_table_grant(THD *thd, TABLE_LIST *table, List <LEX_USER> &user_list,
228 List <LEX_COLUMN> &column_list, ulong rights,
229 bool revoke);
230 bool 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);
233 bool grant_init();
234 void grant_free(void);
235 bool grant_reload(THD *thd);
236 bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
237 bool any_combination_will_do, uint number, bool no_errors);
238 bool 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);
241 bool check_column_grant_in_table_ref(THD *thd, TABLE_LIST * table_ref,
242 const char *name, size_t length, Field *fld);
243 bool check_grant_all_columns(THD *thd, ulong want_access,
244 Field_iterator_table_ref *fields);
245 bool check_grant_routine(THD *thd, ulong want_access,
246 TABLE_LIST *procs, const Sp_handler *sph,
247 bool no_error);
248 bool check_grant_db(THD *thd,const char *db);
249 bool check_global_access(THD *thd, ulong want_access, bool no_errors= false);
250 bool 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);
253 ulong get_table_grant(THD *thd, TABLE_LIST *table);
254 ulong get_column_grant(THD *thd, GRANT_INFO *grant,
255 const char *db_name, const char *table_name,
256 const char *field_name);
257 bool get_show_user(THD *thd, LEX_USER *lex_user, const char **username,
258 const char **hostname, const char **rolename);
259 void mysql_show_grants_get_fields(THD *thd, List<Item> *fields,
260 const char *name, size_t length);
261 bool mysql_show_grants(THD *thd, LEX_USER *user);
262 bool mysql_show_create_user(THD *thd, LEX_USER *user);
263 int fill_schema_enabled_roles(THD *thd, TABLE_LIST *tables, COND *cond);
264 int fill_schema_applicable_roles(THD *thd, TABLE_LIST *tables, COND *cond);
265 void get_privilege_desc(char *to, uint max_length, ulong access);
266 void get_mqh(const char *user, const char *host, USER_CONN *uc);
267 bool mysql_create_user(THD *thd, List <LEX_USER> &list, bool handle_as_role);
268 bool mysql_drop_user(THD *thd, List <LEX_USER> &list, bool handle_as_role);
269 bool mysql_rename_user(THD *thd, List <LEX_USER> &list);
270 int mysql_alter_user(THD *thd, List <LEX_USER> &list);
271 bool mysql_revoke_all(THD *thd, List <LEX_USER> &list);
272 void fill_effective_table_privileges(THD *thd, GRANT_INFO *grant,
273 const char *db, const char *table);
274 bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name,
275 const Sp_handler *sph);
276 bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name,
277 const Sp_handler *sph);
278 bool check_routine_level_acl(THD *thd, const char *db, const char *name,
279 const Sp_handler *sph);
280 bool is_acl_user(const char *host, const char *user);
281 int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond);
282 int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond);
283 int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond);
284 int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond);
285 int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *wildstr);
286
287 /**
288 Result of an access check for an internal schema or table.
289 Internal ACL checks are always performed *before* using
290 the grant tables.
291 This mechanism enforces that the server implementation has full
292 control on its internal tables.
293 Depending on the internal check result, the server implementation
294 can choose to:
295 - always allow access,
296 - always deny access,
297 - delegate the decision to the database administrator,
298 by using the grant tables.
299 */
300 enum ACL_internal_access_result
301 {
302 /**
303 Access granted for all the requested privileges,
304 do not use the grant tables.
305 This flag is used only for the INFORMATION_SCHEMA privileges,
306 for compatibility reasons.
307 */
308 ACL_INTERNAL_ACCESS_GRANTED,
309 /** Access denied, do not use the grant tables. */
310 ACL_INTERNAL_ACCESS_DENIED,
311 /** No decision yet, use the grant tables. */
312 ACL_INTERNAL_ACCESS_CHECK_GRANT
313 };
314
315 /**
316 Per internal table ACL access rules.
317 This class is an interface.
318 Per table(s) specific access rule should be implemented in a subclass.
319 @sa ACL_internal_schema_access
320 */
321 class ACL_internal_table_access
322 {
323 public:
ACL_internal_table_access()324 ACL_internal_table_access()
325 {}
326
~ACL_internal_table_access()327 virtual ~ACL_internal_table_access()
328 {}
329
330 /**
331 Check access to an internal table.
332 When a privilege is granted, this method add the requested privilege
333 to save_priv.
334 @param want_access the privileges requested
335 @param [in, out] save_priv the privileges granted
336 @return
337 @retval ACL_INTERNAL_ACCESS_GRANTED All the requested privileges
338 are granted, and saved in save_priv.
339 @retval ACL_INTERNAL_ACCESS_DENIED At least one of the requested
340 privileges was denied.
341 @retval ACL_INTERNAL_ACCESS_CHECK_GRANT No requested privilege
342 was denied, and grant should be checked for at least one
343 privilege. Requested privileges that are granted, if any, are saved
344 in save_priv.
345 */
346 virtual ACL_internal_access_result check(ulong want_access,
347 ulong *save_priv) const= 0;
348 };
349
350 /**
351 Per internal schema ACL access rules.
352 This class is an interface.
353 Each per schema specific access rule should be implemented
354 in a different subclass, and registered.
355 Per schema access rules can control:
356 - every schema privileges on schema.*
357 - every table privileges on schema.table
358 @sa ACL_internal_schema_registry
359 */
360 class ACL_internal_schema_access
361 {
362 public:
ACL_internal_schema_access()363 ACL_internal_schema_access()
364 {}
365
~ACL_internal_schema_access()366 virtual ~ACL_internal_schema_access()
367 {}
368
369 /**
370 Check access to an internal schema.
371 @param want_access the privileges requested
372 @param [in, out] save_priv the privileges granted
373 @return
374 @retval ACL_INTERNAL_ACCESS_GRANTED All the requested privileges
375 are granted, and saved in save_priv.
376 @retval ACL_INTERNAL_ACCESS_DENIED At least one of the requested
377 privileges was denied.
378 @retval ACL_INTERNAL_ACCESS_CHECK_GRANT No requested privilege
379 was denied, and grant should be checked for at least one
380 privilege. Requested privileges that are granted, if any, are saved
381 in save_priv.
382 */
383 virtual ACL_internal_access_result check(ulong want_access,
384 ulong *save_priv) const= 0;
385
386 /**
387 Search for per table ACL access rules by table name.
388 @param name the table name
389 @return per table access rules, or NULL
390 */
391 virtual const ACL_internal_table_access *lookup(const char *name) const= 0;
392 };
393
394 /**
395 A registry for per internal schema ACL.
396 An 'internal schema' is a database schema maintained by the
397 server implementation, such as 'performance_schema' and 'INFORMATION_SCHEMA'.
398 */
399 class ACL_internal_schema_registry
400 {
401 public:
402 static void register_schema(const LEX_CSTRING *name,
403 const ACL_internal_schema_access *access);
404 static const ACL_internal_schema_access *lookup(const char *name);
405 };
406
407 const ACL_internal_schema_access *
408 get_cached_schema_access(GRANT_INTERNAL_INFO *grant_internal_info,
409 const char *schema_name);
410
411 const ACL_internal_table_access *
412 get_cached_table_access(GRANT_INTERNAL_INFO *grant_internal_info,
413 const char *schema_name,
414 const char *table_name);
415
416 bool acl_check_proxy_grant_access (THD *thd, const char *host, const char *user,
417 bool with_grant);
418 int acl_setrole(THD *thd, const char *rolename, ulonglong access);
419 int acl_check_setrole(THD *thd, const char *rolename, ulonglong *access);
420 int acl_check_set_default_role(THD *thd, const char *host, const char *user,
421 const char *role);
422 int acl_set_default_role(THD *thd, const char *host, const char *user,
423 const char *rolename);
424
425 extern SHOW_VAR acl_statistics[];
426
427 /* Check if a role is granted to a user/role.
428
429 If hostname == NULL, search for a role as the starting grantee.
430 */
431 bool check_role_is_granted(const char *username,
432 const char *hostname,
433 const char *rolename);
434
435 #ifndef DBUG_OFF
436 extern ulong role_global_merges, role_db_merges, role_table_merges,
437 role_column_merges, role_routine_merges;
438 #endif
439 #endif /* SQL_ACL_INCLUDED */
440