1 #ifndef AUTH_COMMON_INCLUDED
2 #define AUTH_COMMON_INCLUDED
3 
4 /* Copyright (c) 2000, 2020, Oracle and/or its affiliates.
5 
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License, version 2.0,
8    as published by the Free Software Foundation.
9 
10    This program is also distributed with certain software (including
11    but not limited to OpenSSL) that is licensed under separate terms,
12    as designated in a particular file or component or in included license
13    documentation.  The authors of MySQL hereby grant you an additional
14    permission to link the program and your derivative works with the
15    separately licensed software that they have included with MySQL.
16 
17    This program is distributed in the hope that it will be useful,
18    but WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20    GNU General Public License, version 2.0, for more details.
21 
22    You should have received a copy of the GNU General Public License
23    along with this program; if not, write to the Free Software Foundation,
24    51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
25 
26 #include "my_global.h"                          /* NO_EMBEDDED_ACCESS_CHECKS */
27 #include "auth_acls.h"                          /* ACL information */
28 #include "sql_string.h"                         /* String */
29 #include "table.h"                              /* TABLE_LIST */
30 #include "field.h"
31 #include <set>
32 
33 /* Forward Declarations */
34 class LEX_COLUMN;
35 class THD;
36 struct GRANT_INFO;
37 struct LEX;
38 typedef struct user_conn USER_CONN;
39 
40 /* Classes */
41 
42 enum ACL_internal_access_result
43 {
44   /**
45     Access granted for all the requested privileges,
46     do not use the grant tables.
47     This flag is used only for the INFORMATION_SCHEMA privileges,
48     for compatibility reasons.
49   */
50   ACL_INTERNAL_ACCESS_GRANTED,
51   /** Access denied, do not use the grant tables. */
52   ACL_INTERNAL_ACCESS_DENIED,
53   /** No decision yet, use the grant tables. */
54   ACL_INTERNAL_ACCESS_CHECK_GRANT
55 };
56 
57 /**
58   Per internal table ACL access rules.
59   This class is an interface.
60   Per table(s) specific access rule should be implemented in a subclass.
61   @sa ACL_internal_schema_access
62 */
63 class ACL_internal_table_access
64 {
65 public:
ACL_internal_table_access()66   ACL_internal_table_access()
67   {}
68 
~ACL_internal_table_access()69   virtual ~ACL_internal_table_access()
70   {}
71 
72   /**
73     Check access to an internal table.
74     When a privilege is granted, this method add the requested privilege
75     to save_priv.
76     @param want_access the privileges requested
77     @param [in, out] save_priv the privileges granted
78     @return
79       @retval ACL_INTERNAL_ACCESS_GRANTED All the requested privileges
80       are granted, and saved in save_priv.
81       @retval ACL_INTERNAL_ACCESS_DENIED At least one of the requested
82       privileges was denied.
83       @retval ACL_INTERNAL_ACCESS_CHECK_GRANT No requested privilege
84       was denied, and grant should be checked for at least one
85       privilege. Requested privileges that are granted, if any, are saved
86       in save_priv.
87   */
88   virtual ACL_internal_access_result check(ulong want_access,
89                                            ulong *save_priv) const= 0;
90 };
91 
92 /**
93   Per internal schema ACL access rules.
94   This class is an interface.
95   Each per schema specific access rule should be implemented
96   in a different subclass, and registered.
97   Per schema access rules can control:
98   - every schema privileges on schema.*
99   - every table privileges on schema.table
100   @sa ACL_internal_schema_registry
101 */
102 class ACL_internal_schema_access
103 {
104 public:
ACL_internal_schema_access()105   ACL_internal_schema_access()
106   {}
107 
~ACL_internal_schema_access()108   virtual ~ACL_internal_schema_access()
109   {}
110 
111   /**
112     Check access to an internal schema.
113     @param want_access the privileges requested
114     @param [in, out] save_priv the privileges granted
115     @return
116       @retval ACL_INTERNAL_ACCESS_GRANTED All the requested privileges
117       are granted, and saved in save_priv.
118       @retval ACL_INTERNAL_ACCESS_DENIED At least one of the requested
119       privileges was denied.
120       @retval ACL_INTERNAL_ACCESS_CHECK_GRANT No requested privilege
121       was denied, and grant should be checked for at least one
122       privilege. Requested privileges that are granted, if any, are saved
123       in save_priv.
124   */
125   virtual ACL_internal_access_result check(ulong want_access,
126                                            ulong *save_priv) const= 0;
127 
128   /**
129     Search for per table ACL access rules by table name.
130     @param name the table name
131     @return per table access rules, or NULL
132   */
133   virtual const ACL_internal_table_access *lookup(const char *name) const= 0;
134 };
135 
136 /**
137   A registry for per internal schema ACL.
138   An 'internal schema' is a database schema maintained by the
139   server implementation, such as 'performance_schema' and 'INFORMATION_SCHEMA'.
140 */
141 class ACL_internal_schema_registry
142 {
143 public:
144   static void register_schema(const LEX_STRING &name,
145                               const ACL_internal_schema_access *access);
146   static const ACL_internal_schema_access *lookup(const char *name);
147 };
148 
149 /**
150   Extension of ACL_internal_schema_access for Information Schema
151 */
152 class IS_internal_schema_access : public ACL_internal_schema_access
153 {
154 public:
IS_internal_schema_access()155   IS_internal_schema_access()
156   {}
157 
~IS_internal_schema_access()158   ~IS_internal_schema_access()
159   {}
160 
161   ACL_internal_access_result check(ulong want_access,
162                                    ulong *save_priv) const;
163 
164   const ACL_internal_table_access *lookup(const char *name) const;
165 };
166 
167 /* Data Structures */
168 
169 extern const char *command_array[];
170 extern uint        command_lengths[];
171 
172 enum mysql_db_table_field
173 {
174   MYSQL_DB_FIELD_HOST = 0,
175   MYSQL_DB_FIELD_DB,
176   MYSQL_DB_FIELD_USER,
177   MYSQL_DB_FIELD_SELECT_PRIV,
178   MYSQL_DB_FIELD_INSERT_PRIV,
179   MYSQL_DB_FIELD_UPDATE_PRIV,
180   MYSQL_DB_FIELD_DELETE_PRIV,
181   MYSQL_DB_FIELD_CREATE_PRIV,
182   MYSQL_DB_FIELD_DROP_PRIV,
183   MYSQL_DB_FIELD_GRANT_PRIV,
184   MYSQL_DB_FIELD_REFERENCES_PRIV,
185   MYSQL_DB_FIELD_INDEX_PRIV,
186   MYSQL_DB_FIELD_ALTER_PRIV,
187   MYSQL_DB_FIELD_CREATE_TMP_TABLE_PRIV,
188   MYSQL_DB_FIELD_LOCK_TABLES_PRIV,
189   MYSQL_DB_FIELD_CREATE_VIEW_PRIV,
190   MYSQL_DB_FIELD_SHOW_VIEW_PRIV,
191   MYSQL_DB_FIELD_CREATE_ROUTINE_PRIV,
192   MYSQL_DB_FIELD_ALTER_ROUTINE_PRIV,
193   MYSQL_DB_FIELD_EXECUTE_PRIV,
194   MYSQL_DB_FIELD_EVENT_PRIV,
195   MYSQL_DB_FIELD_TRIGGER_PRIV,
196   MYSQL_DB_FIELD_COUNT
197 };
198 
199 enum mysql_user_table_field
200 {
201   MYSQL_USER_FIELD_HOST= 0,
202   MYSQL_USER_FIELD_USER,
203   MYSQL_USER_FIELD_SELECT_PRIV,
204   MYSQL_USER_FIELD_INSERT_PRIV,
205   MYSQL_USER_FIELD_UPDATE_PRIV,
206   MYSQL_USER_FIELD_DELETE_PRIV,
207   MYSQL_USER_FIELD_CREATE_PRIV,
208   MYSQL_USER_FIELD_DROP_PRIV,
209   MYSQL_USER_FIELD_RELOAD_PRIV,
210   MYSQL_USER_FIELD_SHUTDOWN_PRIV,
211   MYSQL_USER_FIELD_PROCESS_PRIV,
212   MYSQL_USER_FIELD_FILE_PRIV,
213   MYSQL_USER_FIELD_GRANT_PRIV,
214   MYSQL_USER_FIELD_REFERENCES_PRIV,
215   MYSQL_USER_FIELD_INDEX_PRIV,
216   MYSQL_USER_FIELD_ALTER_PRIV,
217   MYSQL_USER_FIELD_SHOW_DB_PRIV,
218   MYSQL_USER_FIELD_SUPER_PRIV,
219   MYSQL_USER_FIELD_CREATE_TMP_TABLE_PRIV,
220   MYSQL_USER_FIELD_LOCK_TABLES_PRIV,
221   MYSQL_USER_FIELD_EXECUTE_PRIV,
222   MYSQL_USER_FIELD_REPL_SLAVE_PRIV,
223   MYSQL_USER_FIELD_REPL_CLIENT_PRIV,
224   MYSQL_USER_FIELD_CREATE_VIEW_PRIV,
225   MYSQL_USER_FIELD_SHOW_VIEW_PRIV,
226   MYSQL_USER_FIELD_CREATE_ROUTINE_PRIV,
227   MYSQL_USER_FIELD_ALTER_ROUTINE_PRIV,
228   MYSQL_USER_FIELD_CREATE_USER_PRIV,
229   MYSQL_USER_FIELD_EVENT_PRIV,
230   MYSQL_USER_FIELD_TRIGGER_PRIV,
231   MYSQL_USER_FIELD_CREATE_TABLESPACE_PRIV,
232   MYSQL_USER_FIELD_SSL_TYPE,
233   MYSQL_USER_FIELD_SSL_CIPHER,
234   MYSQL_USER_FIELD_X509_ISSUER,
235   MYSQL_USER_FIELD_X509_SUBJECT,
236   MYSQL_USER_FIELD_MAX_QUESTIONS,
237   MYSQL_USER_FIELD_MAX_UPDATES,
238   MYSQL_USER_FIELD_MAX_CONNECTIONS,
239   MYSQL_USER_FIELD_MAX_USER_CONNECTIONS,
240   MYSQL_USER_FIELD_PLUGIN,
241   MYSQL_USER_FIELD_AUTHENTICATION_STRING,
242   MYSQL_USER_FIELD_PASSWORD_EXPIRED,
243   MYSQL_USER_FIELD_PASSWORD_LAST_CHANGED,
244   MYSQL_USER_FIELD_PASSWORD_LIFETIME,
245   MYSQL_USER_FIELD_ACCOUNT_LOCKED,
246   MYSQL_USER_FIELD_COUNT
247 };
248 
249 enum mysql_proxies_priv_table_feild
250 {
251   MYSQL_PROXIES_PRIV_FIELD_HOST = 0,
252   MYSQL_PROXIES_PRIV_FIELD_USER,
253   MYSQL_PROXIES_PRIV_FIELD_PROXIED_HOST,
254   MYSQL_PROXIES_PRIV_FIELD_PROXIED_USER,
255   MYSQL_PROXIES_PRIV_FIELD_WITH_GRANT,
256   MYSQL_PROXIES_PRIV_FIELD_GRANTOR,
257   MYSQL_PROXIES_PRIV_FIELD_TIMESTAMP,
258   MYSQL_PROXIES_PRIV_FIELD_COUNT
259 };
260 
261 enum mysql_procs_priv_table_field
262 {
263   MYSQL_PROCS_PRIV_FIELD_HOST = 0,
264   MYSQL_PROCS_PRIV_FIELD_DB,
265   MYSQL_PROCS_PRIV_FIELD_USER,
266   MYSQL_PROCS_PRIV_FIELD_ROUTINE_NAME,
267   MYSQL_PROCS_PRIV_FIELD_ROUTINE_TYPE,
268   MYSQL_PROCS_PRIV_FIELD_GRANTOR,
269   MYSQL_PROCS_PRIV_FIELD_PROC_PRIV,
270   MYSQL_PROCS_PRIV_FIELD_TIMESTAMP,
271   MYSQL_PROCS_PRIV_FIELD_COUNT
272 };
273 
274 enum mysql_columns_priv_table_field
275 {
276   MYSQL_COLUMNS_PRIV_FIELD_HOST = 0,
277   MYSQL_COLUMNS_PRIV_FIELD_DB,
278   MYSQL_COLUMNS_PRIV_FIELD_USER,
279   MYSQL_COLUMNS_PRIV_FIELD_TABLE_NAME,
280   MYSQL_COLUMNS_PRIV_FIELD_COLUMN_NAME,
281   MYSQL_COLUMNS_PRIV_FIELD_TIMESTAMP,
282   MYSQL_COLUMNS_PRIV_FIELD_COLUMN_PRIV,
283   MYSQL_COLUMNS_PRIV_FIELD_COUNT
284 };
285 
286 enum mysql_tables_priv_table_field
287 {
288   MYSQL_TABLES_PRIV_FIELD_HOST = 0,
289   MYSQL_TABLES_PRIV_FIELD_DB,
290   MYSQL_TABLES_PRIV_FIELD_USER,
291   MYSQL_TABLES_PRIV_FIELD_TABLE_NAME,
292   MYSQL_TABLES_PRIV_FIELD_GRANTOR,
293   MYSQL_TABLES_PRIV_FIELD_TIMESTAMP,
294   MYSQL_TABLES_PRIV_FIELD_TABLE_PRIV,
295   MYSQL_TABLES_PRIV_FIELD_COLUMN_PRIV,
296   MYSQL_TABLES_PRIV_FIELD_COUNT
297 };
298 
299 /* When we run mysql_upgrade we must make sure that the server can be run
300    using previous mysql.user table schema during acl_load.
301 
302    Acl_load_user_table_schema is a common interface for the current and the
303                               previous mysql.user table schema.
304  */
305 class Acl_load_user_table_schema
306 {
307 public:
308   virtual uint host_idx()= 0;
309   virtual uint user_idx()= 0;
310   virtual uint password_idx()= 0;
311   virtual uint select_priv_idx()= 0;
312   virtual uint insert_priv_idx()= 0;
313   virtual uint update_priv_idx()= 0;
314   virtual uint delete_priv_idx()= 0;
315   virtual uint create_priv_idx()= 0;
316   virtual uint drop_priv_idx()= 0;
317   virtual uint reload_priv_idx()= 0;
318   virtual uint shutdown_priv_idx()= 0;
319   virtual uint process_priv_idx()= 0;
320   virtual uint file_priv_idx()= 0;
321   virtual uint grant_priv_idx()= 0;
322   virtual uint references_priv_idx()= 0;
323   virtual uint index_priv_idx()= 0;
324   virtual uint alter_priv_idx()= 0;
325   virtual uint show_db_priv_idx()= 0;
326   virtual uint super_priv_idx()= 0;
327   virtual uint create_tmp_table_priv_idx()= 0;
328   virtual uint lock_tables_priv_idx()= 0;
329   virtual uint execute_priv_idx()= 0;
330   virtual uint repl_slave_priv_idx()= 0;
331   virtual uint repl_client_priv_idx()= 0;
332   virtual uint create_view_priv_idx()= 0;
333   virtual uint show_view_priv_idx()= 0;
334   virtual uint create_routine_priv_idx()= 0;
335   virtual uint alter_routine_priv_idx()= 0;
336   virtual uint create_user_priv_idx()= 0;
337   virtual uint event_priv_idx()= 0;
338   virtual uint trigger_priv_idx()= 0;
339   virtual uint create_tablespace_priv_idx()= 0;
340   virtual uint ssl_type_idx()= 0;
341   virtual uint ssl_cipher_idx()= 0;
342   virtual uint x509_issuer_idx()= 0;
343   virtual uint x509_subject_idx()= 0;
344   virtual uint max_questions_idx()= 0;
345   virtual uint max_updates_idx()= 0;
346   virtual uint max_connections_idx()= 0;
347   virtual uint max_user_connections_idx()= 0;
348   virtual uint plugin_idx()= 0;
349   virtual uint authentication_string_idx()= 0;
350   virtual uint password_expired_idx()= 0;
351   virtual uint password_last_changed_idx()= 0;
352   virtual uint password_lifetime_idx()= 0;
353   virtual uint account_locked_idx()= 0;
354 
~Acl_load_user_table_schema()355   virtual ~Acl_load_user_table_schema() {}
356 };
357 
358 /*
359   This class describes indices for the current mysql.user table schema.
360  */
361 class Acl_load_user_table_current_schema : public Acl_load_user_table_schema
362 {
363 public:
host_idx()364   uint host_idx() { return MYSQL_USER_FIELD_HOST; }
user_idx()365   uint user_idx() { return MYSQL_USER_FIELD_USER; }
366   //not available
password_idx()367   uint password_idx() { DBUG_ASSERT(0); return MYSQL_USER_FIELD_COUNT; }
select_priv_idx()368   uint select_priv_idx() { return MYSQL_USER_FIELD_SELECT_PRIV; }
insert_priv_idx()369   uint insert_priv_idx() { return MYSQL_USER_FIELD_INSERT_PRIV; }
update_priv_idx()370   uint update_priv_idx() { return MYSQL_USER_FIELD_UPDATE_PRIV; }
delete_priv_idx()371   uint delete_priv_idx() { return MYSQL_USER_FIELD_DELETE_PRIV; }
create_priv_idx()372   uint create_priv_idx() { return MYSQL_USER_FIELD_CREATE_PRIV; }
drop_priv_idx()373   uint drop_priv_idx() { return MYSQL_USER_FIELD_DROP_PRIV; }
reload_priv_idx()374   uint reload_priv_idx() { return MYSQL_USER_FIELD_RELOAD_PRIV; }
shutdown_priv_idx()375   uint shutdown_priv_idx() { return MYSQL_USER_FIELD_SHUTDOWN_PRIV; }
process_priv_idx()376   uint process_priv_idx() { return MYSQL_USER_FIELD_PROCESS_PRIV; }
file_priv_idx()377   uint file_priv_idx() { return MYSQL_USER_FIELD_FILE_PRIV; }
grant_priv_idx()378   uint grant_priv_idx() { return MYSQL_USER_FIELD_GRANT_PRIV; }
references_priv_idx()379   uint references_priv_idx() { return MYSQL_USER_FIELD_REFERENCES_PRIV; }
index_priv_idx()380   uint index_priv_idx() { return MYSQL_USER_FIELD_INDEX_PRIV; }
alter_priv_idx()381   uint alter_priv_idx() { return MYSQL_USER_FIELD_ALTER_PRIV; }
show_db_priv_idx()382   uint show_db_priv_idx() { return MYSQL_USER_FIELD_SHOW_DB_PRIV; }
super_priv_idx()383   uint super_priv_idx() { return MYSQL_USER_FIELD_SUPER_PRIV; }
create_tmp_table_priv_idx()384   uint create_tmp_table_priv_idx()
385   {
386     return MYSQL_USER_FIELD_CREATE_TMP_TABLE_PRIV;
387   }
lock_tables_priv_idx()388   uint lock_tables_priv_idx() { return MYSQL_USER_FIELD_LOCK_TABLES_PRIV; }
execute_priv_idx()389   uint execute_priv_idx() { return MYSQL_USER_FIELD_EXECUTE_PRIV; }
repl_slave_priv_idx()390   uint repl_slave_priv_idx() { return MYSQL_USER_FIELD_REPL_SLAVE_PRIV; }
repl_client_priv_idx()391   uint repl_client_priv_idx() { return MYSQL_USER_FIELD_REPL_CLIENT_PRIV; }
create_view_priv_idx()392   uint create_view_priv_idx() { return MYSQL_USER_FIELD_CREATE_VIEW_PRIV; }
show_view_priv_idx()393   uint show_view_priv_idx() { return MYSQL_USER_FIELD_SHOW_VIEW_PRIV; }
create_routine_priv_idx()394   uint create_routine_priv_idx()
395   {
396     return MYSQL_USER_FIELD_CREATE_ROUTINE_PRIV;
397   }
alter_routine_priv_idx()398   uint alter_routine_priv_idx() { return MYSQL_USER_FIELD_ALTER_ROUTINE_PRIV; }
create_user_priv_idx()399   uint create_user_priv_idx() { return MYSQL_USER_FIELD_CREATE_USER_PRIV; }
event_priv_idx()400   uint event_priv_idx() { return MYSQL_USER_FIELD_EVENT_PRIV; }
trigger_priv_idx()401   uint trigger_priv_idx() { return MYSQL_USER_FIELD_TRIGGER_PRIV; }
create_tablespace_priv_idx()402   uint create_tablespace_priv_idx()
403   {
404     return MYSQL_USER_FIELD_CREATE_TABLESPACE_PRIV;
405   }
ssl_type_idx()406   uint ssl_type_idx() { return MYSQL_USER_FIELD_SSL_TYPE; }
ssl_cipher_idx()407   uint ssl_cipher_idx() { return MYSQL_USER_FIELD_SSL_CIPHER; }
x509_issuer_idx()408   uint x509_issuer_idx() { return MYSQL_USER_FIELD_X509_ISSUER; }
x509_subject_idx()409   uint x509_subject_idx() { return MYSQL_USER_FIELD_X509_SUBJECT; }
max_questions_idx()410   uint max_questions_idx() { return MYSQL_USER_FIELD_MAX_QUESTIONS; }
max_updates_idx()411   uint max_updates_idx() { return MYSQL_USER_FIELD_MAX_UPDATES; }
max_connections_idx()412   uint max_connections_idx() { return MYSQL_USER_FIELD_MAX_CONNECTIONS; }
max_user_connections_idx()413   uint max_user_connections_idx()
414   {
415     return MYSQL_USER_FIELD_MAX_USER_CONNECTIONS;
416   }
plugin_idx()417   uint plugin_idx() { return MYSQL_USER_FIELD_PLUGIN; }
authentication_string_idx()418   uint authentication_string_idx()
419   {
420     return MYSQL_USER_FIELD_AUTHENTICATION_STRING;
421   }
password_expired_idx()422   uint password_expired_idx() { return MYSQL_USER_FIELD_PASSWORD_EXPIRED; }
password_last_changed_idx()423   uint password_last_changed_idx()
424   {
425     return MYSQL_USER_FIELD_PASSWORD_LAST_CHANGED;
426   }
password_lifetime_idx()427   uint password_lifetime_idx() { return MYSQL_USER_FIELD_PASSWORD_LIFETIME; }
account_locked_idx()428   uint account_locked_idx() { return MYSQL_USER_FIELD_ACCOUNT_LOCKED; }
429 };
430 
431 /*
432   This class describes indices for the old mysql.user table schema.
433  */
434 class Acl_load_user_table_old_schema : public Acl_load_user_table_schema
435 {
436 public:
437   enum mysql_user_table_field_56
438   {
439     MYSQL_USER_FIELD_HOST_56= 0,
440     MYSQL_USER_FIELD_USER_56,
441     MYSQL_USER_FIELD_PASSWORD_56,
442     MYSQL_USER_FIELD_SELECT_PRIV_56,
443     MYSQL_USER_FIELD_INSERT_PRIV_56,
444     MYSQL_USER_FIELD_UPDATE_PRIV_56,
445     MYSQL_USER_FIELD_DELETE_PRIV_56,
446     MYSQL_USER_FIELD_CREATE_PRIV_56,
447     MYSQL_USER_FIELD_DROP_PRIV_56,
448     MYSQL_USER_FIELD_RELOAD_PRIV_56,
449     MYSQL_USER_FIELD_SHUTDOWN_PRIV_56,
450     MYSQL_USER_FIELD_PROCESS_PRIV_56,
451     MYSQL_USER_FIELD_FILE_PRIV_56,
452     MYSQL_USER_FIELD_GRANT_PRIV_56,
453     MYSQL_USER_FIELD_REFERENCES_PRIV_56,
454     MYSQL_USER_FIELD_INDEX_PRIV_56,
455     MYSQL_USER_FIELD_ALTER_PRIV_56,
456     MYSQL_USER_FIELD_SHOW_DB_PRIV_56,
457     MYSQL_USER_FIELD_SUPER_PRIV_56,
458     MYSQL_USER_FIELD_CREATE_TMP_TABLE_PRIV_56,
459     MYSQL_USER_FIELD_LOCK_TABLES_PRIV_56,
460     MYSQL_USER_FIELD_EXECUTE_PRIV_56,
461     MYSQL_USER_FIELD_REPL_SLAVE_PRIV_56,
462     MYSQL_USER_FIELD_REPL_CLIENT_PRIV_56,
463     MYSQL_USER_FIELD_CREATE_VIEW_PRIV_56,
464     MYSQL_USER_FIELD_SHOW_VIEW_PRIV_56,
465     MYSQL_USER_FIELD_CREATE_ROUTINE_PRIV_56,
466     MYSQL_USER_FIELD_ALTER_ROUTINE_PRIV_56,
467     MYSQL_USER_FIELD_CREATE_USER_PRIV_56,
468     MYSQL_USER_FIELD_EVENT_PRIV_56,
469     MYSQL_USER_FIELD_TRIGGER_PRIV_56,
470     MYSQL_USER_FIELD_CREATE_TABLESPACE_PRIV_56,
471     MYSQL_USER_FIELD_SSL_TYPE_56,
472     MYSQL_USER_FIELD_SSL_CIPHER_56,
473     MYSQL_USER_FIELD_X509_ISSUER_56,
474     MYSQL_USER_FIELD_X509_SUBJECT_56,
475     MYSQL_USER_FIELD_MAX_QUESTIONS_56,
476     MYSQL_USER_FIELD_MAX_UPDATES_56,
477     MYSQL_USER_FIELD_MAX_CONNECTIONS_56,
478     MYSQL_USER_FIELD_MAX_USER_CONNECTIONS_56,
479     MYSQL_USER_FIELD_PLUGIN_56,
480     MYSQL_USER_FIELD_AUTHENTICATION_STRING_56,
481     MYSQL_USER_FIELD_PASSWORD_EXPIRED_56,
482     MYSQL_USER_FIELD_COUNT_56
483   };
484 
host_idx()485   uint host_idx() { return MYSQL_USER_FIELD_HOST_56; }
user_idx()486   uint user_idx() { return MYSQL_USER_FIELD_USER_56; }
password_idx()487   uint password_idx() { return MYSQL_USER_FIELD_PASSWORD_56; }
select_priv_idx()488   uint select_priv_idx() { return MYSQL_USER_FIELD_SELECT_PRIV_56; }
insert_priv_idx()489   uint insert_priv_idx() { return MYSQL_USER_FIELD_INSERT_PRIV_56; }
update_priv_idx()490   uint update_priv_idx() { return MYSQL_USER_FIELD_UPDATE_PRIV_56; }
delete_priv_idx()491   uint delete_priv_idx() { return MYSQL_USER_FIELD_DELETE_PRIV_56; }
create_priv_idx()492   uint create_priv_idx() { return MYSQL_USER_FIELD_CREATE_PRIV_56; }
drop_priv_idx()493   uint drop_priv_idx() { return MYSQL_USER_FIELD_DROP_PRIV_56; }
reload_priv_idx()494   uint reload_priv_idx() { return MYSQL_USER_FIELD_RELOAD_PRIV_56; }
shutdown_priv_idx()495   uint shutdown_priv_idx() { return MYSQL_USER_FIELD_SHUTDOWN_PRIV_56; }
process_priv_idx()496   uint process_priv_idx() { return MYSQL_USER_FIELD_PROCESS_PRIV_56; }
file_priv_idx()497   uint file_priv_idx() { return MYSQL_USER_FIELD_FILE_PRIV_56; }
grant_priv_idx()498   uint grant_priv_idx() { return MYSQL_USER_FIELD_GRANT_PRIV_56; }
references_priv_idx()499   uint references_priv_idx() { return MYSQL_USER_FIELD_REFERENCES_PRIV_56; }
index_priv_idx()500   uint index_priv_idx() { return MYSQL_USER_FIELD_INDEX_PRIV_56; }
alter_priv_idx()501   uint alter_priv_idx() { return MYSQL_USER_FIELD_ALTER_PRIV_56; }
show_db_priv_idx()502   uint show_db_priv_idx() { return MYSQL_USER_FIELD_SHOW_DB_PRIV_56; }
super_priv_idx()503   uint super_priv_idx() { return MYSQL_USER_FIELD_SUPER_PRIV_56; }
create_tmp_table_priv_idx()504   uint create_tmp_table_priv_idx()
505   {
506     return MYSQL_USER_FIELD_CREATE_TMP_TABLE_PRIV_56;
507   }
lock_tables_priv_idx()508   uint lock_tables_priv_idx() { return MYSQL_USER_FIELD_LOCK_TABLES_PRIV_56; }
execute_priv_idx()509   uint execute_priv_idx() { return MYSQL_USER_FIELD_EXECUTE_PRIV_56; }
repl_slave_priv_idx()510   uint repl_slave_priv_idx() { return MYSQL_USER_FIELD_REPL_SLAVE_PRIV_56; }
repl_client_priv_idx()511   uint repl_client_priv_idx() { return MYSQL_USER_FIELD_REPL_CLIENT_PRIV_56; }
create_view_priv_idx()512   uint create_view_priv_idx() { return MYSQL_USER_FIELD_CREATE_VIEW_PRIV_56; }
show_view_priv_idx()513   uint show_view_priv_idx() { return MYSQL_USER_FIELD_SHOW_VIEW_PRIV_56; }
create_routine_priv_idx()514   uint create_routine_priv_idx()
515   {
516     return MYSQL_USER_FIELD_CREATE_ROUTINE_PRIV_56;
517   }
alter_routine_priv_idx()518   uint alter_routine_priv_idx()
519   {
520     return MYSQL_USER_FIELD_ALTER_ROUTINE_PRIV_56;
521   }
create_user_priv_idx()522   uint create_user_priv_idx() { return MYSQL_USER_FIELD_CREATE_USER_PRIV_56; }
event_priv_idx()523   uint event_priv_idx() { return MYSQL_USER_FIELD_EVENT_PRIV_56; }
trigger_priv_idx()524   uint trigger_priv_idx() { return MYSQL_USER_FIELD_TRIGGER_PRIV_56; }
create_tablespace_priv_idx()525   uint create_tablespace_priv_idx()
526   {
527     return MYSQL_USER_FIELD_CREATE_TABLESPACE_PRIV_56;
528   }
ssl_type_idx()529   uint ssl_type_idx() { return MYSQL_USER_FIELD_SSL_TYPE_56; }
ssl_cipher_idx()530   uint ssl_cipher_idx() { return MYSQL_USER_FIELD_SSL_CIPHER_56; }
x509_issuer_idx()531   uint x509_issuer_idx() { return MYSQL_USER_FIELD_X509_ISSUER_56; }
x509_subject_idx()532   uint x509_subject_idx() { return MYSQL_USER_FIELD_X509_SUBJECT_56; }
max_questions_idx()533   uint max_questions_idx() { return MYSQL_USER_FIELD_MAX_QUESTIONS_56; }
max_updates_idx()534   uint max_updates_idx() { return MYSQL_USER_FIELD_MAX_UPDATES_56; }
max_connections_idx()535   uint max_connections_idx() { return MYSQL_USER_FIELD_MAX_CONNECTIONS_56; }
max_user_connections_idx()536   uint max_user_connections_idx()
537   {
538     return MYSQL_USER_FIELD_MAX_USER_CONNECTIONS_56;
539   }
plugin_idx()540   uint plugin_idx() { return MYSQL_USER_FIELD_PLUGIN_56; }
authentication_string_idx()541   uint authentication_string_idx()
542   {
543     return MYSQL_USER_FIELD_AUTHENTICATION_STRING_56;
544   }
password_expired_idx()545   uint password_expired_idx() { return MYSQL_USER_FIELD_PASSWORD_EXPIRED_56; }
546 
547   //those fields are not available in 5.6 db schema
password_last_changed_idx()548   uint password_last_changed_idx() { return MYSQL_USER_FIELD_COUNT_56; }
password_lifetime_idx()549   uint password_lifetime_idx() { return MYSQL_USER_FIELD_COUNT_56; }
account_locked_idx()550   uint account_locked_idx() { return MYSQL_USER_FIELD_COUNT_56; }
551 };
552 
553 
554 class Acl_load_user_table_schema_factory
555 {
556 public:
get_user_table_schema(TABLE * table)557   virtual Acl_load_user_table_schema* get_user_table_schema(TABLE *table)
558   {
559     return is_old_user_table_schema(table) ?
560       (Acl_load_user_table_schema*) new Acl_load_user_table_old_schema():
561       (Acl_load_user_table_schema*) new Acl_load_user_table_current_schema();
562   }
563 
is_old_user_table_schema(TABLE * table)564   virtual bool is_old_user_table_schema(TABLE* table)
565   {
566     Field *password_field=
567       table->field[Acl_load_user_table_old_schema::MYSQL_USER_FIELD_PASSWORD_56];
568     return strncmp(password_field->field_name, "Password", 8) == 0;
569   }
570 
user_table_schema_check(TABLE * table)571   virtual bool user_table_schema_check(TABLE* table)
572   {
573     return table->s->fields >
574            Acl_load_user_table_old_schema::MYSQL_USER_FIELD_PASSWORD_56;
575   }
576 
~Acl_load_user_table_schema_factory()577   virtual ~Acl_load_user_table_schema_factory() {}
578 };
579 
580 extern const TABLE_FIELD_DEF mysql_db_table_def;
581 extern bool mysql_user_table_is_in_short_password_format;
582 extern my_bool disconnect_on_expired_password;
583 extern const char *any_db;	// Special symbol for check_access
584 /** controls the extra checks on plugin availability for mysql.user records */
585 
586 #ifndef NO_EMBEDDED_ACCESS_CHECKS
587 extern my_bool validate_user_plugins;
588 #endif /* NO_EMBEDDED_ACCESS_CHECKS */
589 
590 /* Function Declarations */
591 
592 /* sql_authentication */
593 
594 int set_default_auth_plugin(char *plugin_name, size_t plugin_name_length);
595 void acl_log_connect(const char *user, const char *host, const char *auth_as,
596 	const char *db, THD *thd,
597 enum enum_server_command command);
598 int acl_authenticate(THD *thd, enum_server_command command);
599 bool acl_check_host(const char *host, const char *ip);
600 
601 /*
602   User Attributes are the once which are defined during CREATE/ALTER/GRANT
603   statement. These attributes are divided into following catagories.
604 */
605 
606 #define NONE_ATTR               0L
607 #define DEFAULT_AUTH_ATTR       (1L << 0)    /* update defaults auth */
608 #define PLUGIN_ATTR             (1L << 1)    /* update plugin */
609                                              /* authentication_string */
610 #define SSL_ATTR                (1L << 2)    /* ex: SUBJECT,CIPHER.. */
611 #define RESOURCE_ATTR           (1L << 3)    /* ex: MAX_QUERIES_PER_HOUR.. */
612 #define PASSWORD_EXPIRE_ATTR    (1L << 4)    /* update password expire col */
613 #define ACCESS_RIGHTS_ATTR      (1L << 5)    /* update privileges */
614 #define ACCOUNT_LOCK_ATTR       (1L << 6)    /* update account lock status */
615 
616 /* rewrite CREATE/ALTER/GRANT user */
617 void mysql_rewrite_create_alter_user(THD *thd, String *rlb,
618                                      std::set<LEX_USER *> *extra_users= NULL,
619                                      bool hide_password_hash= false);
620 void mysql_rewrite_grant(THD *thd, String *rlb);
621 
622 /* sql_user */
623 void append_user(THD *thd, String *str, LEX_USER *user,
624                  bool comma, bool ident);
625 void append_user_new(THD *thd, String *str, LEX_USER *user, bool comma= true,
626                      bool hide_password_hash= false);
627 int check_change_password(THD *thd, const char *host, const char *user,
628                           const char *password, size_t password_len);
629 bool change_password(THD *thd, const char *host, const char *user,
630                      char *password);
631 bool mysql_create_user(THD *thd, List <LEX_USER> &list, bool if_not_exists);
632 bool mysql_alter_user(THD *thd, List <LEX_USER> &list, bool if_exists);
633 bool mysql_drop_user(THD *thd, List <LEX_USER> &list, bool if_exists);
634 bool mysql_rename_user(THD *thd, List <LEX_USER> &list);
635 
636 bool set_and_validate_user_attributes(THD *thd,
637                                       LEX_USER *Str,
638                                       ulong &what_to_set,
639                                       bool is_privileged_user,
640                                       const char * cmd);
641 
642 /* sql_auth_cache */
643 int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *wildstr);
644 bool hostname_requires_resolving(const char *hostname);
645 my_bool acl_init(bool dont_read_acl_tables);
646 void acl_free(bool end=0);
647 my_bool acl_reload(THD *thd);
648 bool grant_init(bool skip_grant_tables);
649 void grant_free(void);
650 my_bool grant_reload(THD *thd);
651 ulong acl_get(const char *host, const char *ip,
652               const char *user, const char *db, my_bool db_is_pattern);
653 bool is_acl_user(const char *host, const char *user);
654 bool acl_getroot(Security_context *sctx, char *user,
655                  char *host, char *ip, const char *db);
656 
657 /* sql_authorization */
658 bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &user_list,
659                  ulong rights, bool revoke, bool is_proxy);
660 bool mysql_routine_grant(THD *thd, TABLE_LIST *table, bool is_proc,
661                          List <LEX_USER> &user_list, ulong rights,
662                          bool revoke, bool write_to_binlog);
663 int mysql_table_grant(THD *thd, TABLE_LIST *table, List <LEX_USER> &user_list,
664                        List <LEX_COLUMN> &column_list, ulong rights,
665                        bool revoke);
666 bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
667                  bool any_combination_will_do, uint number, bool no_errors);
668 bool check_grant_column (THD *thd, GRANT_INFO *grant,
669                          const char *db_name, const char *table_name,
670                          const char *name, size_t length,
671                          Security_context *sctx, ulong want_privilege);
672 bool check_column_grant_in_table_ref(THD *thd, TABLE_LIST * table_ref,
673                                      const char *name, size_t length,
674                                      ulong want_privilege);
675 bool check_grant_all_columns(THD *thd, ulong want_access,
676                              Field_iterator_table_ref *fields);
677 bool check_grant_routine(THD *thd, ulong want_access,
678                          TABLE_LIST *procs, bool is_proc, bool no_error);
679 bool check_routine_level_acl(THD *thd, const char *db, const char *name,
680                              bool is_proc);
681 bool check_grant_db(THD *thd,const char *db);
682 bool acl_check_proxy_grant_access(THD *thd, const char *host, const char *user,
683                                   bool with_grant);
684 void get_privilege_desc(char *to, uint max_length, ulong access);
685 void get_mqh(const char *user, const char *host, USER_CONN *uc);
686 ulong get_table_grant(THD *thd, TABLE_LIST *table);
687 ulong get_column_grant(THD *thd, GRANT_INFO *grant,
688                        const char *db_name, const char *table_name,
689                        const char *field_name);
690 bool mysql_show_grants(THD *thd, LEX_USER *user);
691 bool mysql_show_create_user(THD *thd, LEX_USER *user, bool are_both_users_same);
692 bool mysql_revoke_all(THD *thd, List <LEX_USER> &list);
693 bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name,
694                           bool is_proc);
695 bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name,
696                          bool is_proc);
697 void fill_effective_table_privileges(THD *thd, GRANT_INFO *grant,
698                                      const char *db, const char *table);
699 int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, Item *cond);
700 int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, Item *cond);
701 int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, Item *cond);
702 int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, Item *cond);
703 const ACL_internal_schema_access *
704 get_cached_schema_access(GRANT_INTERNAL_INFO *grant_internal_info,
705                          const char *schema_name);
706 
707 bool select_precheck(THD *thd, LEX *lex, TABLE_LIST *tables,
708                      TABLE_LIST *first_table);
709 bool multi_delete_precheck(THD *thd, TABLE_LIST *tables);
710 bool delete_precheck(THD *thd, TABLE_LIST *tables);
711 bool lock_tables_precheck(THD *thd, TABLE_LIST *tables);
712 bool create_table_precheck(THD *thd, TABLE_LIST *tables,
713                            TABLE_LIST *create_table);
714 bool check_fk_parent_table_access(THD *thd,
715                                   const char *child_table_db,
716                                   HA_CREATE_INFO *create_info,
717                                   Alter_info *alter_info);
718 bool check_lock_view_underlying_table_access(THD *thd, TABLE_LIST *tbl,
719                                              bool *fake_lock_tables_acl);
720 bool check_readonly(THD *thd, bool err_if_readonly);
721 void err_readonly(THD *thd);
722 
723 bool is_secure_transport(int vio_type);
724 
725 #ifndef NO_EMBEDDED_ACCESS_CHECKS
726 
727 bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *tables);
728 bool check_single_table_access(THD *thd, ulong privilege,
729 			   TABLE_LIST *tables, bool no_errors);
730 bool check_routine_access(THD *thd, ulong want_access, const char *db,
731                           char *name, bool is_proc, bool no_errors);
732 bool check_some_access(THD *thd, ulong want_access, TABLE_LIST *table);
733 bool check_some_routine_access(THD *thd, const char *db, const char *name, bool is_proc);
734 bool check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
735                   GRANT_INTERNAL_INFO *grant_internal_info,
736                   bool dont_check_global_grants, bool no_errors);
737 bool check_table_access(THD *thd, ulong requirements,TABLE_LIST *tables,
738                         bool any_combination_of_privileges_will_do,
739                         uint number,
740                         bool no_errors);
741 #else
check_one_table_access(THD * thd,ulong privilege,TABLE_LIST * tables)742 inline bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *tables)
743 { return false; }
check_single_table_access(THD * thd,ulong privilege,TABLE_LIST * tables,bool no_errors)744 inline bool check_single_table_access(THD *thd, ulong privilege,
745 			   TABLE_LIST *tables, bool no_errors)
746 { return false; }
check_routine_access(THD * thd,ulong want_access,const char * db,char * name,bool is_proc,bool no_errors)747 inline bool check_routine_access(THD *thd,ulong want_access,const char *db,
748                                  char *name, bool is_proc, bool no_errors)
749 { return false; }
check_some_access(THD * thd,ulong want_access,TABLE_LIST * table)750 inline bool check_some_access(THD *thd, ulong want_access, TABLE_LIST *table)
751 {
752   table->grant.privilege= want_access;
753   return false;
754 }
check_some_routine_access(THD * thd,const char * db,const char * name,bool is_proc)755 inline bool check_some_routine_access(THD *thd, const char *db,
756                                       const char *name, bool is_proc)
757 { return false; }
check_access(THD *,ulong,const char *,ulong * save_priv,GRANT_INTERNAL_INFO *,bool,bool)758 inline bool check_access(THD *, ulong, const char *, ulong *save_priv,
759                          GRANT_INTERNAL_INFO *, bool, bool)
760 {
761   if (save_priv)
762     *save_priv= GLOBAL_ACLS;
763   return false;
764 }
765 inline bool
check_table_access(THD * thd,ulong requirements,TABLE_LIST * tables,bool any_combination_of_privileges_will_do,uint number,bool no_errors)766 check_table_access(THD *thd, ulong requirements,TABLE_LIST *tables,
767                    bool any_combination_of_privileges_will_do,
768                    uint number,
769                    bool no_errors)
770 { return false; }
771 #endif /*NO_EMBEDDED_ACCESS_CHECKS*/
772 
773 /* These was under the INNODB_COMPATIBILITY_HOOKS */
774 
775 bool check_global_access(THD *thd, ulong want_access);
776 
777 #ifdef NO_EMBEDDED_ACCESS_CHECKS
778 #define check_grant(A,B,C,D,E,F) 0
779 #define check_grant_db(A,B) 0
780 #endif
781 
782 /* sql_user_table */
783 void close_acl_tables(THD *thd);
784 
785 #if !defined(EMBEDDED_LIBRARY) || defined(XTRABACKUP)
786 typedef enum ssl_artifacts_status
787 {
788   SSL_ARTIFACTS_NOT_FOUND= 0,
789   SSL_ARTIFACTS_VIA_OPTIONS,
790   SSL_ARTIFACT_TRACES_FOUND,
791   SSL_ARTIFACTS_AUTO_DETECTED
792 } ssl_artifacts_status;
793 
794 #endif /* !EMBEDDED_LIBRARY || XTRABACKUP */
795 
796 #if defined(HAVE_OPENSSL)
797 extern my_bool opt_auto_generate_certs;
798 bool do_auto_cert_generation(ssl_artifacts_status auto_detection_status);
799 #endif /* HAVE_OPENSSL */
800 #endif /* AUTH_COMMON_INCLUDED */
801