summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <monty@mashka.mysql.fi>2002-06-12 15:04:18 +0300
committerunknown <monty@mashka.mysql.fi>2002-06-12 15:04:18 +0300
commit0724f98e6771d9e5631cf365f42947ad18f3d09c (patch)
tree8495f49bd4d6cb6596a29d60137462d0563ed9ee /sql
parent70aa7424c41c45a8fb171bbdd9e24d74b70a7765 (diff)
downloadmariadb-git-0724f98e6771d9e5631cf365f42947ad18f3d09c.tar.gz
Added the following new privleges:
SHOW DATABASES CREATE TEMPORARY TABLE LOCK TABLES REPLICATION SLAVE & REPLICATION CLIENT SUPER EXECUTE All scripts & documentation is updated for this change. Added better error messages for global privileges BitKeeper/deleted/.del-mysql_new_fix_privilege_tables.sh~b1664b401375eece: Delete: scripts/mysql_new_fix_privilege_tables.sh Docs/manual.texi: Updated manual for privilege changes. include/mysqld_error.h: new error messages mysql-test/install_test_db.sh: Updated to use new privileges mysql-test/r/grant_cache.result: Updated to use new privileges mysql-test/r/rpl000017.result: Updated to use new privileges mysql-test/t/rpl000017.test: Updated to use new privileges mysys/safemalloc.c: Cleanup scripts/mysql_fix_privilege_tables.sh: Updated to use new privileges scripts/mysql_install_db.sh: Updated to use new privileges sql/field.h: Cleanup sql/item_strfunc.cc: Updated to use new privileges sql/lex.h: Updated to use new privileges sql/log.cc: Updated to use new privileges sql/mysql_priv.h: Updated to use new privileges sql/mysqld.cc: Updated to use new privileges sql/repl_failsafe.cc: Updated to use new privileges sql/share/czech/errmsg.txt: new error messages sql/share/danish/errmsg.txt: new error messages sql/share/dutch/errmsg.txt: new error messages sql/share/english/errmsg.txt: new error messages sql/share/estonian/errmsg.txt: new error messages sql/share/french/errmsg.txt: new error messages sql/share/german/errmsg.txt: new error messages sql/share/greek/errmsg.txt: new error messages sql/share/hungarian/errmsg.txt: new error messages sql/share/italian/errmsg.txt: new error messages sql/share/japanese/errmsg.txt: new error messages sql/share/korean/errmsg.txt: new error messages sql/share/norwegian-ny/errmsg.txt: new error messages sql/share/norwegian/errmsg.txt: new error messages sql/share/polish/errmsg.txt: new error messages sql/share/portuguese/errmsg.txt: new error messages sql/share/romanian/errmsg.txt: new error messages sql/share/russian/errmsg.txt: new error messages sql/share/slovak/errmsg.txt: new error messages sql/share/spanish/errmsg.txt: new error messages sql/share/swedish/errmsg.txt: new error messages sql/share/ukrainian/errmsg.txt: new error messages sql/slave.cc: Portability cleanup sql/sql_acl.cc: Updated to use new privileges sql/sql_acl.h: Updated to use new privileges sql/sql_base.cc: Remove not used include file sql/sql_class.cc: Comment cleanup sql/sql_class.h: Updated to use new privileges Comment cleanups sql/sql_insert.cc: Updated to use new privileges sql/sql_lex.h: Indentation cleanup sql/sql_parse.cc: Updated to use new privileges sql/sql_repl.cc: Updated to use new privileges Comment cleanup sql/sql_show.cc: Updated to use new privileges sql/sql_yacc.yy: Updated to use new privileges Sorted some tockens for easer merge to 4.1 in the future. sql/table.h: Updated to use new privileges tests/grant.pl: Updated to use new privileges tests/grant.res: Updated to use new privileges
Diffstat (limited to 'sql')
-rw-r--r--sql/field.h4
-rw-r--r--sql/item_strfunc.cc2
-rw-r--r--sql/lex.h10
-rw-r--r--sql/log.cc6
-rw-r--r--sql/mysql_priv.h8
-rw-r--r--sql/mysqld.cc2
-rw-r--r--sql/repl_failsafe.cc3
-rw-r--r--sql/share/czech/errmsg.txt5
-rw-r--r--sql/share/danish/errmsg.txt3
-rw-r--r--sql/share/dutch/errmsg.txt5
-rw-r--r--sql/share/english/errmsg.txt3
-rw-r--r--sql/share/estonian/errmsg.txt3
-rw-r--r--sql/share/french/errmsg.txt5
-rw-r--r--sql/share/german/errmsg.txt3
-rw-r--r--sql/share/greek/errmsg.txt3
-rw-r--r--sql/share/hungarian/errmsg.txt5
-rw-r--r--sql/share/italian/errmsg.txt5
-rw-r--r--sql/share/japanese/errmsg.txt5
-rw-r--r--sql/share/korean/errmsg.txt5
-rw-r--r--sql/share/norwegian-ny/errmsg.txt5
-rw-r--r--sql/share/norwegian/errmsg.txt5
-rw-r--r--sql/share/polish/errmsg.txt5
-rw-r--r--sql/share/portuguese/errmsg.txt3
-rw-r--r--sql/share/romanian/errmsg.txt3
-rw-r--r--sql/share/russian/errmsg.txt3
-rw-r--r--sql/share/slovak/errmsg.txt5
-rw-r--r--sql/share/spanish/errmsg.txt5
-rw-r--r--sql/share/swedish/errmsg.txt7
-rw-r--r--sql/share/ukrainian/errmsg.txt3
-rw-r--r--sql/slave.cc25
-rw-r--r--sql/sql_acl.cc463
-rw-r--r--sql/sql_acl.h95
-rw-r--r--sql/sql_base.cc1
-rw-r--r--sql/sql_class.cc37
-rw-r--r--sql/sql_class.h37
-rw-r--r--sql/sql_insert.cc2
-rw-r--r--sql/sql_lex.h36
-rw-r--r--sql/sql_parse.cc172
-rw-r--r--sql/sql_repl.cc17
-rw-r--r--sql/sql_show.cc4
-rw-r--r--sql/sql_yacc.yy277
-rw-r--r--sql/table.h4
42 files changed, 704 insertions, 595 deletions
diff --git a/sql/field.h b/sql/field.h
index df31721186e..c795cbac974 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -923,9 +923,9 @@ public:
:Field_str(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg, table_arg),
packlength(packlength_arg),typelib(typelib_arg)
- {
+ {
flags|=ENUM_FLAG;
- }
+ }
enum_field_types type() const { return FIELD_TYPE_STRING; }
enum Item_result cmp_type () const { return INT_RESULT; }
enum ha_base_keytype key_type() const;
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 22f962b4947..80e50305beb 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -316,7 +316,7 @@ String *Item_func_des_decrypt::val_str(String *str)
{
uint key_number=(uint) (*res)[0] & 127;
// Check if automatic key and that we have privilege to uncompress using it
- if (!(current_thd->master_access & PROCESS_ACL) || key_number > 9)
+ if (!(current_thd->master_access & SUPER_ACL) || key_number > 9)
goto error;
VOID(pthread_mutex_lock(&LOCK_des_key_file));
keyschedule= des_keyschedule[key_number];
diff --git a/sql/lex.h b/sql/lex.h
index e03c4db6479..c6b2cac1dfe 100644
--- a/sql/lex.h
+++ b/sql/lex.h
@@ -30,9 +30,9 @@
#endif
/*
-** Symbols are breaked in to separated arrays to allow fieldnames with
-** same name as functions
-** Theese are kept sorted for human lookup (the symbols are hashed)
+ Symbols are breaked in to separated arrays to allow field names with
+ same name as functions.
+ These are kept sorted for human lookup (the symbols are hashed).
*/
static SYMBOL symbols[] = {
@@ -86,6 +86,7 @@ static SYMBOL symbols[] = {
{ "CHECK", SYM(CHECK_SYM),0,0},
{ "CHECKSUM", SYM(CHECKSUM_SYM),0,0},
{ "CIPHER", SYM(CIPHER_SYM),0,0},
+ { "CLIENT", SYM(CLIENT_SYM),0,0},
{ "CLOSE", SYM(CLOSE_SYM),0,0},
{ "COLUMN", SYM(COLUMN_SYM),0,0},
{ "COLUMNS", SYM(COLUMNS),0,0},
@@ -136,6 +137,7 @@ static SYMBOL symbols[] = {
{ "ENCLOSED", SYM(ENCLOSED),0,0},
{ "ENUM", SYM(ENUM),0,0},
{ "EVENTS", SYM(EVENTS_SYM),0,0},
+ { "EXECUTE", SYM(EXECUTE_SYM),0,0},
{ "EXPLAIN", SYM(DESCRIBE),0,0},
{ "EXISTS", SYM(EXISTS),0,0},
{ "EXTENDED", SYM(EXTENDED_SYM),0,0},
@@ -289,6 +291,7 @@ static SYMBOL symbols[] = {
{ "RENAME", SYM(RENAME),0,0},
{ "REPAIR", SYM(REPAIR),0,0},
{ "REPLACE", SYM(REPLACE),0,0},
+ { "REPLICATION", SYM(REPLICATION),0,0},
{ "REPEATABLE", SYM(REPEATABLE_SYM),0,0},
{ "REQUIRE", SYM(REQUIRE_SYM),0,0},
{ "RESET", SYM(RESET_SYM),0,0},
@@ -344,6 +347,7 @@ static SYMBOL symbols[] = {
{ "STOP", SYM(STOP_SYM),0,0},
{ "STRIPED", SYM(RAID_STRIPED_SYM),0,0},
{ "SUBJECT", SYM(SUBJECT_SYM),0,0},
+ { "SUPER", SYM(SUPER_SYM),0,0},
{ "TABLE", SYM(TABLE_SYM),0,0},
{ "TABLES", SYM(TABLES),0,0},
{ "TEMPORARY", SYM(TEMPORARY),0,0},
diff --git a/sql/log.cc b/sql/log.cc
index 793dfaf6d82..b0483ea4a27 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -826,7 +826,7 @@ bool MYSQL_LOG::write(THD *thd,enum enum_server_command command,
if (thd)
{ // Normal thread
if ((thd->options & OPTION_LOG_OFF) &&
- (thd->master_access & PROCESS_ACL))
+ (thd->master_access & SUPER_ACL))
{
VOID(pthread_mutex_unlock(&LOCK_log));
return 0; // No logging
@@ -907,7 +907,7 @@ bool MYSQL_LOG::write(Log_event* event_info)
IO_CACHE *file = &log_file;
#endif
if ((thd && !(thd->options & OPTION_BIN_LOG) &&
- (thd->master_access & PROCESS_ACL)) ||
+ (thd->master_access & SUPER_ACL)) ||
(db && !db_ok(db, binlog_do_db, binlog_ignore_db)))
{
VOID(pthread_mutex_unlock(&LOCK_log));
@@ -1084,7 +1084,7 @@ bool MYSQL_LOG::write(THD *thd,const char *query, uint query_length,
char buff[80],*end;
end=buff;
if (!(thd->options & OPTION_UPDATE_LOG) &&
- (thd->master_access & PROCESS_ACL))
+ (thd->master_access & SUPER_ACL))
{
VOID(pthread_mutex_unlock(&LOCK_log));
return 0;
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index dae392615ff..1637546e09c 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -82,7 +82,7 @@ char* query_table_status(THD *thd,const char *db,const char *table_name);
#define TEMP_POOL_SIZE 128
/*
The following parameters is to decide when to use an extra cache to
- optimise seeks when reading a big table in sorted order
+ optimise seeks when reading a big table in sorted order
*/
#define MIN_FILE_LENGTH_TO_USE_ROW_CACHE (16L*1024*1024)
#define MIN_ROWS_TO_USE_TABLE_CACHE 100
@@ -321,11 +321,11 @@ void table_cache_free(void);
uint cached_tables(void);
void kill_mysql(void);
void close_connection(NET *net,uint errcode=0,bool lock=1);
-bool check_access(THD *thd,uint access,const char *db=0,uint *save_priv=0,
+bool check_access(THD *thd, ulong access, const char *db=0, ulong *save_priv=0,
bool no_grant=0, bool no_errors=0);
-bool check_table_access(THD *thd,uint want_access, TABLE_LIST *tables,
+bool check_table_access(THD *thd, ulong want_access, TABLE_LIST *tables,
bool no_errors=0);
-bool check_process_priv(THD *thd=0);
+bool check_global_access(THD *thd, ulong want_access);
int mysql_backup_table(THD* thd, TABLE_LIST* table_list);
int mysql_restore_table(THD* thd, TABLE_LIST* table_list);
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 0dc516e6ab2..38b0014e085 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -3146,7 +3146,7 @@ static struct my_option my_long_options[] =
{"safe-mode", OPT_SAFE, "Skip some optimize stages (for testing).",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"safe-show-database", OPT_SAFE_SHOW_DB,
- "Don't show databases for which the user has no privileges",
+ "Depricated option; One should use GRANT SHOW DATABASES instead...",
(gptr*) &opt_safe_show_db, (gptr*) &opt_safe_show_db, 0, GET_BOOL, NO_ARG,
0, 0, 0, 0, 0, 0},
{"safe-user-create", OPT_SAFE_USER_CREATE,
diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc
index 6645f7a1eed..3b63a12c05c 100644
--- a/sql/repl_failsafe.cc
+++ b/sql/repl_failsafe.cc
@@ -24,7 +24,6 @@
#include "mini_client.h"
#include "log_event.h"
#include <mysql.h>
-#include <thr_alarm.h>
#define SLAVE_LIST_CHUNK 128
#define SLAVE_ERRMSG_SIZE (FN_REFLEN+64)
@@ -150,7 +149,7 @@ int register_slave(THD* thd, uchar* packet, uint packet_length)
int res = 1;
uchar* p = packet, *p_end = packet + packet_length;
- if (check_access(thd, FILE_ACL, any_db))
+ if (check_access(thd, REPL_SLAVE_ACL, any_db))
return 1;
if (!(si = (SLAVE_INFO*)my_malloc(sizeof(SLAVE_INFO), MYF(MY_WME))))
diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt
index 11a3063151d..70ec831eaa0 100644
--- a/sql/share/czech/errmsg.txt
+++ b/sql/share/czech/errmsg.txt
@@ -156,7 +156,7 @@
"%-.16s p-Bøíkaz nepøístupný pro u¾ivatele: '%-.32s@%-.64s' pro sloupec '%-.64s' v tabulce '%-.64s'",
"Neplatn-Bý pøíkaz GRANT/REVOKE. Prosím, pøeètìte si v manuálu, jaká privilegia je mo¾né pou¾ít.",
"Argument p-Bøíkazu GRANT u¾ivatel nebo stroj je pøíli¹ dlouhý",
-"Tabulka '%-64s.%s' neexistuje",
+"Tabulka '%-.64s.%s' neexistuje",
"Neexistuje odpov-Bídající grant pro u¾ivatele '%-.32s' na stroji '%-.64s' pro tabulku '%-.64s'",
"Pou-B¾itý pøíkaz není v této verzi MySQL povolen",
"Va-B¹e syntaxe je nìjaká divná",
@@ -236,4 +236,5 @@
"Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled",
"Option '%s' used twice in statement",
-"User '%-64s' has exceeded the '%s' resource (current value: %ld)",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt
index e87f093e7cb..0aba168d398 100644
--- a/sql/share/danish/errmsg.txt
+++ b/sql/share/danish/errmsg.txt
@@ -230,4 +230,5 @@
"Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled",
"Option '%s' used twice in statement",
-"User '%-64s' has exceeded the '%s' resource (current value: %ld)",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt
index 1ae3c78d66b..aaa6a939216 100644
--- a/sql/share/dutch/errmsg.txt
+++ b/sql/share/dutch/errmsg.txt
@@ -155,7 +155,7 @@
"%-.16s commando geweigerd voor gebruiker: '%-.32s@%-.64s' voor kolom '%-.64s' in tabel '%-.64s'",
"Foutief GRANT/REVOKE commando. Raadpleeg de handleiding welke priveleges gebruikt kunnen worden.",
"De host of gebruiker parameter voor GRANT is te lang",
-"Tabel '%-64s.%s' bestaat niet",
+"Tabel '%-.64s.%s' bestaat niet",
"Deze toegang (GRANT) is niet toegekend voor gebruiker '%-.32s' op host '%-.64s' op tabel '%-.64s'",
"Het used commando is niet toegestaan in deze MySQL versie",
"Er is iets fout in de gebruikte syntax",
@@ -235,4 +235,5 @@
"Kan de query niet uitvoeren vanwege een conflicterende read lock",
"Het combineren van transactionele en niet-transactionele tabellen is uitgeschakeld.",
"Optie '%s' tweemaal gebruikt in opdracht",
-"Gebruiker '%-64s' heeft het maximale gebruik van de '%s' faciliteit overschreden (huidige waarde: %ld)",
+"Gebruiker '%-.64s' heeft het maximale gebruik van de '%s' faciliteit overschreden (huidige waarde: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt
index 39f84e4d02f..8845d5fead7 100644
--- a/sql/share/english/errmsg.txt
+++ b/sql/share/english/errmsg.txt
@@ -227,4 +227,5 @@
"Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled",
"Option '%s' used twice in statement",
-"User '%-64s' has exceeded the '%s' resource (current value: %ld)",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt
index e4b27eb5336..3939c50f378 100644
--- a/sql/share/estonian/errmsg.txt
+++ b/sql/share/estonian/errmsg.txt
@@ -232,4 +232,5 @@
"Ei suuda täita päringut konfliktse luku tõttu",
"Transaktsioone toetavate ning mittetoetavate tabelite kooskasutamine ei ole lubatud",
"Määrangut '%s' on lauses kasutatud topelt",
-"User '%-64s' has exceeded the '%s' resource (current value: %ld)",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt
index 09ba354b1d3..97178218826 100644
--- a/sql/share/french/errmsg.txt
+++ b/sql/share/french/errmsg.txt
@@ -147,7 +147,7 @@
"La commande '%-.16s' est interdite à l'utilisateur: '%-.32s@%-.64s' sur la colonne '%-.64s' de la table '%-.64s'",
"Commande GRANT/REVOKE incorrecte. Consultez le manuel.",
"L'hôte ou l'utilisateur donné en argument à GRANT est trop long",
-"La table '%-64s.%s' n'existe pas",
+"La table '%-.64s.%s' n'existe pas",
"Un tel droit n'est pas défini pour l'utilisateur '%-.32s' sur l'hôte '%-.64s' sur la table '%-.64s'",
"Cette commande n'existe pas dans cette version de MySQL",
"Erreur de syntaxe",
@@ -227,4 +227,5 @@
"Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled",
"Option '%s' used twice in statement",
-"User '%-64s' has exceeded the '%s' resource (current value: %ld)",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt
index 58c21ccbdfc..19e981539c2 100644
--- a/sql/share/german/errmsg.txt
+++ b/sql/share/german/errmsg.txt
@@ -230,4 +230,5 @@
"Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled",
"Option '%s' used twice in statement",
-"User '%-64s' has exceeded the '%s' resource (current value: %ld)",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt
index c0387742de0..c3c9f2e010a 100644
--- a/sql/share/greek/errmsg.txt
+++ b/sql/share/greek/errmsg.txt
@@ -227,4 +227,5 @@
"Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled",
"Option '%s' used twice in statement",
-"User '%-64s' has exceeded the '%s' resource (current value: %ld)",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt
index 85563d00f03..5d2589e60f5 100644
--- a/sql/share/hungarian/errmsg.txt
+++ b/sql/share/hungarian/errmsg.txt
@@ -149,7 +149,7 @@
"%-.16s parancs a '%-.32s@%-.64s' felhasznalo szamara nem engedelyezett a '%-.64s' mezo eseten a '%-.64s' tablaban",
"Ervenytelen GRANT/REVOKE parancs. Kerem, nezze meg a kezikonyvben, milyen jogok lehetsegesek",
"A host vagy felhasznalo argumentuma tul hosszu a GRANT parancsban",
-"A '%-64s.%s' tabla nem letezik",
+"A '%-.64s.%s' tabla nem letezik",
"A '%-.32s' felhasznalo szamara a '%-.64s' host '%-.64s' tablajaban ez a parancs nem engedelyezett",
"A hasznalt parancs nem engedelyezett ebben a MySQL verzioban",
"Szintaktikai hiba",
@@ -229,4 +229,5 @@
"Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled",
"Option '%s' used twice in statement",
-"User '%-64s' has exceeded the '%s' resource (current value: %ld)",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt
index 94e9235d590..4a6561c712a 100644
--- a/sql/share/italian/errmsg.txt
+++ b/sql/share/italian/errmsg.txt
@@ -147,7 +147,7 @@
"Comando %-.16s negato per l'utente: '%-.32s@%-.64s' sulla colonna '%-.64s' della tabella '%-.64s'",
"Comando GRANT/REVOKE illegale. Prego consultare il manuale per sapere quali privilegi possono essere usati.",
"L'argomento host o utente per la GRANT e` troppo lungo",
-"La tabella '%-64s.%s' non esiste",
+"La tabella '%-.64s.%s' non esiste",
"GRANT non definita per l'utente '%-.32s' dalla macchina '%-.64s' sulla tabella '%-.64s'",
"Il comando utilizzato non e` supportato in questa versione di MySQL",
"Errore di sintassi nella query SQL",
@@ -227,4 +227,5 @@
"Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled",
"Option '%s' used twice in statement",
-"User '%-64s' has exceeded the '%s' resource (current value: %ld)",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt
index 6ffe5a25bf4..3007bc8b0cb 100644
--- a/sql/share/japanese/errmsg.txt
+++ b/sql/share/japanese/errmsg.txt
@@ -149,7 +149,7 @@
"¥³¥Þ¥ó¥É %-.16s ¤Ï ¥æ¡¼¥¶¡¼ '%-.32s@%-.64s'\n ¥«¥é¥à '%-.64s' ¥Æ¡¼¥Ö¥ë '%-.64s' ¤ËÂФ·¤Æµö²Ä¤µ¤ì¤Æ¤¤¤Þ¤»¤ó",
"Illegal GRANT/REVOKE command. Please consult the manual which privleges can be used.",
"The host or user argument to GRANT is too long",
-"Table '%-64s.%s' doesn't exist",
+"Table '%-.64s.%s' doesn't exist",
"There is no such grant defined for user '%-.32s' on host '%-.64s' on table '%-.64s'",
"The used command is not allowed with this MySQL version",
"Something is wrong in your syntax",
@@ -229,4 +229,5 @@
"Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled",
"Option '%s' used twice in statement",
-"User '%-64s' has exceeded the '%s' resource (current value: %ld)",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt
index fa2a6dc8624..dc44bb25109 100644
--- a/sql/share/korean/errmsg.txt
+++ b/sql/share/korean/errmsg.txt
@@ -147,7 +147,7 @@
"'%-.16s' ¸í·ÉÀº ´ÙÀ½ »ç¿ëÀÚ¿¡°Ô °ÅºÎµÇ¾ú½À´Ï´Ù. : '%-.32s@%-.64s' for Ä®·³ '%-.64s' in Å×À̺í '%-.64s'",
"À߸øµÈ GRANT/REVOKE ¸í·É. ¾î¶² ±Ç¸®¿Í ½ÂÀÎÀÌ »ç¿ëµÇ¾î Áú ¼ö ÀÖ´ÂÁö ¸Þ´º¾óÀ» º¸½Ã¿À.",
"½ÂÀÎ(GRANT)À» À§ÇÏ¿© »ç¿ëÇÑ »ç¿ëÀÚ³ª È£½ºÆ®ÀÇ °ªµéÀÌ ³Ê¹« ±é´Ï´Ù.",
-"Å×À̺í '%-64s.%s' ´Â Á¸ÀçÇÏÁö ¾Ê½À´Ï´Ù.",
+"Å×À̺í '%-.64s.%s' ´Â Á¸ÀçÇÏÁö ¾Ê½À´Ï´Ù.",
"»ç¿ëÀÚ '%-.32s'(È£½ºÆ® '%-.64s')´Â Å×À̺í '%-.64s'¸¦ »ç¿ëÇϱâ À§ÇÏ¿© Á¤ÀÇµÈ ½ÂÀÎÀº ¾ø½À´Ï´Ù. ",
"»ç¿ëµÈ ¸í·ÉÀº ÇöÀçÀÇ MySQL ¹öÁ¯¿¡¼­´Â ÀÌ¿ëµÇÁö ¾Ê½À´Ï´Ù.",
"SQL ±¸¹®¿¡ ¿À·ù°¡ ÀÖ½À´Ï´Ù.",
@@ -227,4 +227,5 @@
"Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled",
"Option '%s' used twice in statement",
-"User '%-64s' has exceeded the '%s' resource (current value: %ld)",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt
index c3dbee47967..89cde7754cd 100644
--- a/sql/share/norwegian-ny/errmsg.txt
+++ b/sql/share/norwegian-ny/errmsg.txt
@@ -149,7 +149,7 @@
"%-.16s command denied to user: '%-.32s@%-.64s' for column '%-.64s' in table '%-.64s'",
"Illegal GRANT/REVOKE command. Please consult the manual which privleges can be used.",
"The host or user argument to GRANT is too long",
-"Table '%-64s.%s' doesn't exist",
+"Table '%-.64s.%s' doesn't exist",
"There is no such grant defined for user '%-.32s' on host '%-.64s' on table '%-.64s'",
"The used command is not allowed with this MySQL version",
"Something is wrong in your syntax",
@@ -229,4 +229,5 @@
"Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled",
"Option '%s' used twice in statement",
-"User '%-64s' has exceeded the '%s' resource (current value: %ld)",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt
index 436b968e3df..e0c8142a939 100644
--- a/sql/share/norwegian/errmsg.txt
+++ b/sql/share/norwegian/errmsg.txt
@@ -149,7 +149,7 @@
"%-.16s command denied to user: '%-.32s@%-.64s' for column '%-.64s' in table '%-.64s'",
"Illegal GRANT/REVOKE command. Please consult the manual which privleges can be used.",
"The host or user argument to GRANT is too long",
-"Table '%-64s.%s' doesn't exist",
+"Table '%-.64s.%s' doesn't exist",
"There is no such grant defined for user '%-.32s' on host '%-.64s' on table '%-.64s'",
"The used command is not allowed with this MySQL version",
"Something is wrong in your syntax",
@@ -229,4 +229,5 @@
"Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled",
"Option '%s' used twice in statement",
-"User '%-64s' has exceeded the '%s' resource (current value: %ld)",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt
index 3883d98f7dd..4b67e5f76ea 100644
--- a/sql/share/polish/errmsg.txt
+++ b/sql/share/polish/errmsg.txt
@@ -151,7 +151,7 @@
"%-.16s command denied to user: '%-.32s@%-.64s' for column '%-.64s' in table '%-.64s'",
"Illegal GRANT/REVOKE command. Please consult the manual which privleges can be used.",
"The host or user argument to GRANT is too long",
-"Table '%-64s.%s' doesn't exist",
+"Table '%-.64s.%s' doesn't exist",
"There is no such grant defined for user '%-.32s' on host '%-.64s' on table '%-.64s'",
"The used command is not allowed with this MySQL version",
"Something is wrong in your syntax",
@@ -231,4 +231,5 @@
"Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled",
"Option '%s' used twice in statement",
-"User '%-64s' has exceeded the '%s' resource (current value: %ld)",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt
index 335d5b96105..8e416e3dcb2 100644
--- a/sql/share/portuguese/errmsg.txt
+++ b/sql/share/portuguese/errmsg.txt
@@ -227,4 +227,5 @@
"Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled",
"Option '%s' used twice in statement",
-"User '%-64s' has exceeded the '%s' resource (current value: %ld)",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt
index a5df91da19a..1bc22fbb360 100644
--- a/sql/share/romanian/errmsg.txt
+++ b/sql/share/romanian/errmsg.txt
@@ -231,4 +231,5 @@
"Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled",
"Option '%s' used twice in statement",
-"User '%-64s' has exceeded the '%s' resource (current value: %ld)",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt
index 36b165bfca2..83747310839 100644
--- a/sql/share/russian/errmsg.txt
+++ b/sql/share/russian/errmsg.txt
@@ -230,4 +230,5 @@
"îÅ×ÏÚÍÏÖÎÏ ×ÙÐÏÌÎÉÔØ ÚÁÐÒÏÓ ÉÚ-ÚÁ ËÏÎÆÌÉËÔÎÏÊ ÂÌÏËÉÒÏ×ËÉ ÞÔÅÎÉÑ",
"ïÄÎÏ×ÒÅÍÅÎÎÏÅ ÉÓÐÏÌØÚÏ×ÁÎÉÅ transactional É non-transactional ÔÁÂÌÉà ÏÔËÌÀÞÅÎÏ",
"ïÐÃÉÑ '%s' ÉÓÐÏÌØÚÏ×ÁÎÁ Ä×ÁÖÄÙ",
-"User '%-64s' has exceeded the '%s' resource (current value: %ld)",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt
index 2b8878fb411..fc23521305c 100644
--- a/sql/share/slovak/errmsg.txt
+++ b/sql/share/slovak/errmsg.txt
@@ -155,7 +155,7 @@
"%-.16s command denied to user: '%-.32s@%-.64s' for column '%-.64s' in table '%-.64s'",
"Illegal GRANT/REVOKE command. Please consult the manual which privleges can be used.",
"The host or user argument to GRANT is too long",
-"Table '%-64s.%s' doesn't exist",
+"Table '%-.64s.%s' doesn't exist",
"There is no such grant defined for user '%-.32s' on host '%-.64s' on table '%-.64s'",
"The used command is not allowed with this MySQL version",
"Something is wrong in your syntax",
@@ -235,4 +235,5 @@
"Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled",
"Option '%s' used twice in statement",
-"User '%-64s' has exceeded the '%s' resource (current value: %ld)",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt
index c69f021db73..b5f1795bf8f 100644
--- a/sql/share/spanish/errmsg.txt
+++ b/sql/share/spanish/errmsg.txt
@@ -148,7 +148,7 @@
"%-.16s comando negado para usuario: '%-.32s@%-.64s' para columna '%-.64s' en la tabla '%-.64s'",
"Ilegal comando GRANT/REVOKE. Por favor consulte el manual para cuales permisos pueden ser usados.",
"El argumento para servidor o usuario para GRANT es demasiado grande",
-"Tabla '%-64s.%s' no existe",
+"Tabla '%-.64s.%s' no existe",
"No existe tal permiso definido para usuario '%-.32s' en el servidor '%-.64s' en la tabla '%-.64s'",
"El comando usado no es permitido con esta versión de MySQL",
"Algo está equivocado en su sintax",
@@ -228,4 +228,5 @@
"Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled",
"Option '%s' used twice in statement",
-"User '%-64s' has exceeded the '%s' resource (current value: %ld)",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt
index 4bb810e1909..5cec38202fa 100644
--- a/sql/share/swedish/errmsg.txt
+++ b/sql/share/swedish/errmsg.txt
@@ -61,7 +61,7 @@
"Kommandot har både sum functions och enkla funktioner",
"Antalet kolumner motsvarar inte antalet värden",
"Kolumn namn '%-.64s' är för långt",
-"Kolumn namn '%-64s finns flera gånger",
+"Kolumn namn '%-.64s finns flera gånger",
"Nyckel namn '%-.64s' finns flera gånger",
"Dubbel nyckel '%-.64s' för nyckel: %d",
"Felaktigt kolumn typ för kolumn: '%-.64s'",
@@ -147,7 +147,7 @@
"%-.16s ej tillåtet för '%-.32s@%-.64s'\n för kolumn '%-.64s' i tabell '%-.64s'",
"Felaktigt GRANT privilegium använt",
"Felaktigt maskinnamn eller användarnamn använt med GRANT",
-"Det finns ingen tabell som heter '%-64s.%s'"
+"Det finns ingen tabell som heter '%-.64s.%s'"
"Det finns inget privilegium definierat för användare '%-.32s' på '%-.64s' för tabell '%-.64s'",
"Du kan inte använda detta kommando med denna MySQL version",
"Du har något fel i din syntax",
@@ -227,4 +227,5 @@
"Kan inte utföra kommandot emedan du har ett READ lås",
"Blandning av transaktionella och icke-transaktionella tabeller är inaktiverat",
"Option '%s' användes två gånger",
-"Användare '%-64s' har överskridit '%s' (nuvarande värde: %ld)",
+"Användare '%-.64s' har överskridit '%s' (nuvarande värde: %ld)",
+"Du har inte privlegiet '%-.128s' som behövs för denna operation",
diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt
index 6777f1230e7..81530dbd03c 100644
--- a/sql/share/ukrainian/errmsg.txt
+++ b/sql/share/ukrainian/errmsg.txt
@@ -232,4 +232,5 @@
"Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled",
"Option '%s' used twice in statement",
-"User '%-64s' has exceeded the '%s' resource (current value: %ld)",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
diff --git a/sql/slave.cc b/sql/slave.cc
index fc51c483131..7791e4151ee 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -388,8 +388,9 @@ int terminate_slave_thread(THD* thd, pthread_mutex_t* term_lock,
}
}
DBUG_ASSERT(thd != 0);
- /* is is criticate to test if the slave is running. Otherwise, we might
- be referening freed memory trying to kick it
+ /*
+ Is is criticate to test if the slave is running. Otherwise, we might
+ be referening freed memory trying to kick it
*/
THD_CHECK_SENTRY(thd);
if (*slave_running)
@@ -398,22 +399,12 @@ int terminate_slave_thread(THD* thd, pthread_mutex_t* term_lock,
}
while (*slave_running)
{
- /* there is a small chance that slave thread might miss the first
- alarm. To protect againts it, resend the signal until it reacts
+ /*
+ There is a small chance that slave thread might miss the first
+ alarm. To protect againts it, resend the signal until it reacts
*/
struct timespec abstime;
-#ifdef HAVE_TIMESPEC_TS_SEC
- abstime.ts_sec=time(NULL)+2;
- abstime.ts_nsec=0;
-#elif defined(__WIN__)
- abstime.tv_sec=time((time_t*) 0)+2;
- abstime.tv_nsec=0;
-#else
- struct timeval tv;
- gettimeofday(&tv,0);
- abstime.tv_sec=tv.tv_sec+2;
- abstime.tv_nsec=tv.tv_usec*1000;
-#endif
+ set_timespec(abstime,2);
DBUG_ASSERT_LOCK(cond_lock);
pthread_cond_timedwait(term_cond, cond_lock, &abstime);
if (*slave_running)
@@ -1881,7 +1872,7 @@ is correct, restart the server with a higher value of max_allowed_packet",
max_allowed_packet);
goto err;
}
-
+
thd->proc_info = "Waiting to reconnect after a failed read";
mc_end_server(mysql);
if (retried_once) // punish repeat offender with sleep
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 7657bdd8133..a664757cb2a 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -31,22 +31,22 @@
#include <m_ctype.h>
#include <stdarg.h>
-/*
- ACL_HOST is used if no host is specified
- */
-
struct acl_host_and_ip
{
char *hostname;
long ip,ip_mask; // Used with masked ip:s
};
+
class ACL_ACCESS {
public:
ulong sort;
- uint access;
+ ulong access;
};
+
+/* ACL_HOST is used if no host is specified */
+
class ACL_HOST :public ACL_ACCESS
{
public:
@@ -54,6 +54,7 @@ public:
char *db;
};
+
class ACL_USER :public ACL_ACCESS
{
public:
@@ -68,6 +69,7 @@ public:
#endif /* HAVE_OPENSSL */
};
+
class ACL_DB :public ACL_ACCESS
{
public:
@@ -75,14 +77,16 @@ public:
char *user,*db;
};
+
class acl_entry :public hash_filo_element
{
public:
- uint access;
+ ulong access;
uint16 length;
char key[1]; // Key will be stored here
};
+
static byte* acl_entry_get_key(acl_entry *entry,uint *length,
my_bool not_used __attribute__((unused)))
{
@@ -100,7 +104,7 @@ static HASH acl_check_hosts, hash_tables;
static DYNAMIC_ARRAY acl_wild_hosts;
static hash_filo *acl_cache;
static uint grant_version=0;
-static uint get_access(TABLE *form,uint fieldnr);
+static ulong get_access(TABLE *form,uint fieldnr);
static int acl_compare(ACL_ACCESS *a,ACL_ACCESS *b);
static ulong get_sort(uint count,...);
static void init_check_host(void);
@@ -195,10 +199,10 @@ int acl_init(bool dont_read_acl_tables)
{
ACL_HOST host;
update_hostname(&host.host,get_field(&mem, table,0));
- host.db=get_field(&mem, table,1);
- host.access=get_access(table,2);
- host.access=fix_rights_for_db(host.access);
- host.sort=get_sort(2,host.host.hostname,host.db);
+ host.db= get_field(&mem, table,1);
+ host.access= get_access(table,2);
+ host.access= fix_rights_for_db(host.access);
+ host.sort= get_sort(2,host.host.hostname,host.db);
#ifndef TO_BE_REMOVED
if (table->fields == 8)
{ // Without grant
@@ -223,6 +227,7 @@ int acl_init(bool dont_read_acl_tables)
protocol_version=9; /* purecov: tested */
}
+ DBUG_PRINT("info",("user table fields: %d",table->fields));
allow_all_hosts=0;
while (!(read_record_info.read_record(&read_record_info)))
{
@@ -231,26 +236,6 @@ int acl_init(bool dont_read_acl_tables)
update_hostname(&user.host,get_field(&mem, table,0));
user.user=get_field(&mem, table,1);
user.password=get_field(&mem, table,2);
-#ifdef HAVE_OPENSSL
- DBUG_PRINT("info",("table->fields=%d",table->fields));
- if (table->fields >= 21) /* From 4.0.0 we have more fields */
- {
- char *ssl_type=get_field(&mem, table,17);
- if (!strcmp(ssl_type, "ANY"))
- user.ssl_type=SSL_TYPE_ANY;
- else if (!strcmp(ssl_type, "X509"))
- user.ssl_type=SSL_TYPE_X509;
- else if (!strcmp(ssl_type, "SPECIFIED"))
- user.ssl_type=SSL_TYPE_SPECIFIED;
- else
- user.ssl_type=SSL_TYPE_NONE;
- user.ssl_cipher=get_field(&mem, table, 18);
- user.x509_issuer=get_field(&mem, table, 19);
- user.x509_subject=get_field(&mem, table, 20);
- }
- else
- user.ssl_type=SSL_TYPE_NONE;
-#endif /* HAVE_OPENSSL */
if (user.password && (length=(uint) strlen(user.password)) == 8 &&
protocol_version == PROTOCOL_VERSION)
{
@@ -264,35 +249,60 @@ int acl_init(bool dont_read_acl_tables)
"Found invalid password for user: '%s@%s'; Ignoring user",
user.user ? user.user : "",
user.host.hostname ? user.host.hostname : ""); /* purecov: tested */
- continue; /* purecov: tested */
+ continue; /* purecov: tested */
}
get_salt_from_password(user.salt,user.password);
user.access=get_access(table,3);
user.sort=get_sort(2,user.host.hostname,user.user);
user.hostname_length= (user.host.hostname ?
(uint) strlen(user.host.hostname) : 0);
- if (table->fields >= 23)
+ if (table->fields >= 31) /* Starting from 4.0.2 we have more fields */
{
- /* Table has new MySQL usage limits */
- char *ptr = get_field(&mem, table, 21);
+#ifdef HAVE_OPENSSL
+ char *ssl_type=get_field(&mem, table, 24);
+ if (!ssl_type)
+ user.ssl_type=SSL_TYPE_NONE;
+ else if (!strcmp(ssl_type, "ANY"))
+ user.ssl_type=SSL_TYPE_ANY;
+ else if (!strcmp(ssl_type, "X509"))
+ user.ssl_type=SSL_TYPE_X509;
+ else /* !strcmp(ssl_type, "SPECIFIED") */
+ user.ssl_type=SSL_TYPE_SPECIFIED;
+
+ user.ssl_cipher= get_field(&mem, table, 25);
+ user.x509_issuer= get_field(&mem, table, 26);
+ user.x509_subject= get_field(&mem, table, 27);
+#endif
+ char *ptr = get_field(&mem, table, 28);
user.user_resource.questions=atoi(ptr);
- ptr = get_field(&mem, table, 22);
+ ptr = get_field(&mem, table, 29);
user.user_resource.updates=atoi(ptr);
- ptr = get_field(&mem, table, 23);
+ ptr = get_field(&mem, table, 30);
user.user_resource.connections=atoi(ptr);
if (user.user_resource.questions || user.user_resource.updates ||
user.user_resource.connections)
mqh_used=1;
}
else
+ {
+#ifdef HAVE_OPENSSL
+ user.ssl_type=SSL_TYPE_NONE;
+#endif
bzero(&(user.user_resource),sizeof(user.user_resource));
#ifndef TO_BE_REMOVED
- if (table->fields <= 13)
- { // Without grant
- if (user.access & CREATE_ACL)
- user.access|=REFERENCES_ACL | INDEX_ACL | ALTER_ACL;
- }
+ if (table->fields <= 13)
+ { // Without grant
+ if (user.access & CREATE_ACL)
+ user.access|=REFERENCES_ACL | INDEX_ACL | ALTER_ACL;
+ }
+ /* Convert old privileges */
+ user.access|= LOCK_TABLES_ACL | CREATE_TMP_ACL | SHOW_DB_ACL;
+ if (user.access & FILE_ACL)
+ user.access|= REPL_CLIENT_ACL | REPL_SLAVE_ACL;
+ if (user.access & PROCESS_ACL)
+ user.access|= SUPER_ACL | EXECUTE_ACL;
#endif
+ }
VOID(push_dynamic(&acl_users,(gptr) &user));
if (!user.host.hostname || user.host.hostname[0] == wild_many &&
!user.host.hostname[1])
@@ -403,31 +413,38 @@ void acl_reload(void)
}
-/* Get all access bits from table after fieldnr */
+/*
+ Get all access bits from table after fieldnr
+ We know that the access privileges ends when there is no more fields
+ or the field is not an enum with two elements.
+*/
-static uint get_access(TABLE *form,uint fieldnr)
+static ulong get_access(TABLE *form, uint fieldnr)
{
- uint access_bits=0,bit;
+ ulong access_bits=0,bit;
char buff[2];
String res(buff,sizeof(buff));
Field **pos;
- for (pos=form->field+fieldnr,bit=1 ; *pos ; pos++ , bit<<=1)
+ for (pos=form->field+fieldnr, bit=1;
+ *pos && (*pos)->real_type() == FIELD_TYPE_ENUM &&
+ ((Field_enum*) (*pos))->typelib->count == 2 ;
+ pos++ , bit<<=1)
{
(*pos)->val_str(&res,&res);
if (toupper(res[0]) == 'Y')
- access_bits|=bit;
+ access_bits|= bit;
}
return access_bits;
}
/*
- return a number which, if sorted 'desc', puts strings in this order:
- no wildcards
- wildcards
- empty string
- */
+ Return a number which, if sorted 'desc', puts strings in this order:
+ no wildcards
+ wildcards
+ empty string
+*/
static ulong get_sort(uint count,...)
{
@@ -472,17 +489,17 @@ static int acl_compare(ACL_ACCESS *a,ACL_ACCESS *b)
Required before connecting to MySQL
*/
-uint acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
- const char *password,const char *message,char **priv_user,
- bool old_ver, USER_RESOURCES *mqh)
+ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
+ const char *password,const char *message,char **priv_user,
+ bool old_ver, USER_RESOURCES *mqh)
{
- uint user_access=NO_ACCESS;
+ ulong user_access=NO_ACCESS;
*priv_user=(char*) user;
char *ptr=0;
bzero(mqh,sizeof(USER_RESOURCES));
if (!initialized)
- return (uint) ~NO_ACCESS; // If no data allow anything /* purecov: tested */
+ return (ulong) ~NO_ACCESS; // If no data allow anything /* purecov: tested */
VOID(pthread_mutex_lock(&acl_cache->lock));
/*
@@ -509,7 +526,7 @@ uint acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
we check if SSL is required, if user is using SSL and
if X509 certificate attributes are OK
*/
- switch(acl_user->ssl_type) {
+ switch (acl_user->ssl_type) {
case SSL_TYPE_NONE: /* SSL is not required to connect */
user_access=acl_user->access;
break;
@@ -581,10 +598,8 @@ uint acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
}
free(ptr);
}
- DBUG_PRINT("info",("checkpoint 5"));
break;
}
- DBUG_PRINT("info",("checkpoint 6"));
#else /* HAVE_OPENSSL */
user_access=acl_user->access;
#endif /* HAVE_OPENSSL */
@@ -623,7 +638,7 @@ static void acl_update_user(const char *user, const char *host,
const char *x509_issuer,
const char *x509_subject,
USER_RESOURCES *mqh,
- uint privileges)
+ ulong privileges)
{
for (uint i=0 ; i < acl_users.elements ; i++)
{
@@ -667,7 +682,7 @@ static void acl_insert_user(const char *user, const char *host,
const char *x509_issuer,
const char *x509_subject,
USER_RESOURCES *mqh,
- uint privileges)
+ ulong privileges)
{
ACL_USER acl_user;
acl_user.user=strdup_root(&mem,user);
@@ -704,7 +719,7 @@ static void acl_insert_user(const char *user, const char *host,
static void acl_update_db(const char *user, const char *host, const char *db,
- uint privileges)
+ ulong privileges)
{
for (uint i=0 ; i < acl_dbs.elements ; i++)
{
@@ -731,7 +746,7 @@ static void acl_update_db(const char *user, const char *host, const char *db,
static void acl_insert_db(const char *user, const char *host, const char *db,
- uint privileges)
+ ulong privileges)
{
ACL_DB acl_db;
/* The acl_cache mutex is locked by mysql_grant */
@@ -750,10 +765,11 @@ static void acl_insert_db(const char *user, const char *host, const char *db,
** Get privilege for a host, user and db combination
*****************************************************************************/
-uint acl_get(const char *host, const char *ip, const char *bin_ip,
+ulong acl_get(const char *host, const char *ip, const char *bin_ip,
const char *user, const char *db)
{
- uint host_access,db_access,i,key_length;
+ ulong host_access,db_access;
+ uint i,key_length;
db_access=0; host_access= ~0;
char key[ACL_KEY_LENGTH],*tmp_db,*end;
acl_entry *entry;
@@ -1104,7 +1120,7 @@ static bool compare_hostname(const acl_host_and_ip *host, const char *hostname,
/****************************************************************************
-** Code to update grants in the user and database privilege tables
+ Code to update grants in the user and database privilege tables
****************************************************************************/
static bool update_user_table(THD *thd, const char *host, const char *user,
@@ -1154,10 +1170,10 @@ static bool test_if_create_new_users(THD *thd)
if (opt_safe_user_create && !(thd->master_access & INSERT_ACL))
{
TABLE_LIST tl;
- uint db_access;
+ ulong db_access;
bzero((char*) &tl,sizeof(tl));
tl.db= (char*) "mysql";
- tl.real_name= (char*) "user";
+ tl.real_name= (char*) "user";
db_access=acl_get(thd->host, thd->ip, (char*) &thd->remote.sin_addr,
thd->priv_user, tl.db);
if (!(db_access & INSERT_ACL))
@@ -1175,12 +1191,13 @@ static bool test_if_create_new_users(THD *thd)
****************************************************************************/
static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
- uint rights, char what, bool create_user)
+ ulong rights, bool revoke_grant,
+ bool create_user)
{
int error = -1;
- uint i,j;
bool old_row_exists=0;
char *password,empty_string[1];
+ char what= (revoke_grant) ? 'N' : 'Y';
DBUG_ENTER("replace_user_table");
password=empty_string;
@@ -1231,55 +1248,58 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
table->field[2]->store(password,(uint) strlen(password));
}
- for (i = 3, j = SELECT_ACL; // starting from reload
- i < table->fields;
- i++, j <<= 1)
+ /* Update table columns with new privileges */
+
+ Field **tmp_field;
+ ulong priv;
+ for (tmp_field= table->field+3, priv = SELECT_ACL;
+ *tmp_field && (*tmp_field)->real_type() == FIELD_TYPE_ENUM &&
+ ((Field_enum*) (*tmp_field))->typelib->count == 2 ;
+ tmp_field++, priv <<= 1)
{
- if (j & rights) // set requested privileges
- table->field[i]->store(&what,1);
+ if (priv & rights) // set requested privileges
+ (*tmp_field)->store(&what,1);
}
rights=get_access(table,3);
-#ifdef HAVE_OPENSSL
- /* We write down SSL related ACL stuff */
DBUG_PRINT("info",("table->fields: %d",table->fields));
- if (table->fields >= 21) /* From 4.0.0 we have more fields */
+ if (table->fields >= 31) /* From 4.0.0 we have more fields */
{
- table->field[18]->store("",0);
- table->field[19]->store("",0);
- table->field[20]->store("",0);
+#ifdef HAVE_OPENSSL
+ /* We write down SSL related ACL stuff */
+ table->field[25]->store("",0);
+ table->field[26]->store("",0);
+ table->field[27]->store("",0);
switch (thd->lex.ssl_type) {
case SSL_TYPE_ANY:
- table->field[17]->store("ANY",3);
+ table->field[24]->store("ANY",3);
break;
case SSL_TYPE_X509:
- table->field[17]->store("X509",4);
+ table->field[24]->store("X509",4);
break;
case SSL_TYPE_SPECIFIED:
- table->field[17]->store("SPECIFIED",9);
+ table->field[24]->store("SPECIFIED",9);
if (thd->lex.ssl_cipher)
- table->field[18]->store(thd->lex.ssl_cipher,
+ table->field[25]->store(thd->lex.ssl_cipher,
strlen(thd->lex.ssl_cipher));
if (thd->lex.x509_issuer)
- table->field[19]->store(thd->lex.x509_issuer,
+ table->field[26]->store(thd->lex.x509_issuer,
strlen(thd->lex.x509_issuer));
if (thd->lex.x509_subject)
- table->field[20]->store(thd->lex.x509_subject,
+ table->field[27]->store(thd->lex.x509_subject,
strlen(thd->lex.x509_subject));
break;
default:
- table->field[17]->store("NONE",4);
+ table->field[24]->store("",0);
}
- }
#endif /* HAVE_OPENSSL */
- if (table->fields >= 23)
- {
+
USER_RESOURCES mqh = thd->lex.mqh;
if (mqh.questions)
- table->field[21]->store((longlong) mqh.questions);
+ table->field[28]->store((longlong) mqh.questions);
if (mqh.updates)
- table->field[22]->store((longlong) mqh.updates);
+ table->field[29]->store((longlong) mqh.updates);
if (mqh.connections)
- table->field[23]->store((longlong) mqh.connections);
+ table->field[30]->store((longlong) mqh.connections);
mqh_used = mqh_used || mqh.questions || mqh.updates || mqh.connections;
}
if (old_row_exists)
@@ -1337,16 +1357,18 @@ end:
/*
-** change grants in the mysql.db table
+ change grants in the mysql.db table
*/
static int replace_db_table(TABLE *table, const char *db,
const LEX_USER &combo,
- uint rights, char what)
+ ulong rights, bool revoke_grant)
{
- uint i,j,store_rights;
+ uint i;
+ ulong priv,store_rights;
bool old_row_exists=0;
int error;
+ char what= (revoke_grant) ? 'N' : 'Y';
DBUG_ENTER("replace_db_table");
// is there such a user in user table in memory ????
@@ -1382,9 +1404,9 @@ static int replace_db_table(TABLE *table, const char *db,
}
store_rights=get_rights_for_db(rights);
- for (i = 3, j = 1; i < table->fields; i++, j <<= 1)
+ for (i= 3, priv= 1; i < table->fields; i++, priv <<= 1)
{
- if (j & store_rights) // do it if priv is chosen
+ if (priv & store_rights) // do it if priv is chosen
table->field [i]->store(&what,1); // set requested privileges
}
rights=get_access(table,3);
@@ -1432,13 +1454,15 @@ class GRANT_COLUMN :public Sql_alloc
{
public:
char *column;
- uint rights, key_length;
- GRANT_COLUMN(String &c, uint y) :rights (y)
+ ulong rights;
+ uint key_length;
+ GRANT_COLUMN(String &c, ulong y) :rights (y)
{
- column= memdup_root(&memex,c.ptr(),key_length=c.length());
+ column= memdup_root(&memex,c.ptr(), key_length=c.length());
}
};
+
static byte* get_key_column(GRANT_COLUMN *buff,uint *length,
my_bool not_used __attribute__((unused)))
{
@@ -1446,14 +1470,16 @@ static byte* get_key_column(GRANT_COLUMN *buff,uint *length,
return (byte*) buff->column;
}
+
class GRANT_TABLE :public Sql_alloc
{
public:
char *host,*db,*user,*tname, *hash_key;
- uint privs, cols, key_length;
+ ulong privs, cols;
+ uint key_length;
HASH hash_columns;
GRANT_TABLE (const char *h, const char *d,const char *u, const char *t,
- uint p,uint c)
+ ulong p, ulong c)
: privs(p), cols(c)
{
host = strdup_root(&memex,h);
@@ -1478,7 +1504,9 @@ public:
host = get_field(&memex,form,0);
db = get_field(&memex,form,1);
- user = get_field(&memex,form,2); if (!user) user=(char*) "";
+ user = get_field(&memex,form,2);
+ if (!user)
+ user=(char*) "";
tname = get_field(&memex,form,3);
if (!host || !db || !tname)
{
@@ -1495,8 +1523,8 @@ public:
(uint) strlen(tname) + 3);
hash_key = (char*) alloc_root(&memex,key_length);
strmov(strmov(strmov(hash_key,user)+1,db)+1,tname);
- privs = (uint) form->field[6]->val_int();
- cols = (uint) form->field[7]->val_int();
+ privs = (ulong) form->field[6]->val_int();
+ cols = (ulong) form->field[7]->val_int();
privs = fix_rights_for_table(privs);
cols = fix_rights_for_column(cols);
@@ -1529,7 +1557,7 @@ public:
GRANT_COLUMN *mem_check;
/* As column name is a string, we don't have to supply a buffer */
res=col_privs->field[4]->val_str(&column_name,&column_name);
- uint priv= (uint) col_privs->field[6]->val_int();
+ ulong priv= (ulong) col_privs->field[6]->val_int();
if (!(mem_check = new GRANT_COLUMN(*res,
fix_rights_for_column(priv))))
{
@@ -1545,6 +1573,7 @@ public:
bool ok() { return privs != 0 || cols != 0; }
};
+
static byte* get_grant_table(GRANT_TABLE *buff,uint *length,
my_bool not_used __attribute__((unused)))
{
@@ -1552,11 +1581,13 @@ static byte* get_grant_table(GRANT_TABLE *buff,uint *length,
return (byte*) buff->hash_key;
}
+
void free_grant_table(GRANT_TABLE *grant_table)
{
hash_free(&grant_table->hash_columns);
}
+
/* Search after a matching grant. Prefer exact grants before not exact ones */
static GRANT_TABLE *table_hash_search(const char *host,const char* ip,
@@ -1593,8 +1624,7 @@ static GRANT_TABLE *table_hash_search(const char *host,const char* ip,
inline GRANT_COLUMN *
-column_hash_search(GRANT_TABLE *t, const char *cname,
- uint length)
+column_hash_search(GRANT_TABLE *t, const char *cname, uint length)
{
return (GRANT_COLUMN*) hash_search(&t->hash_columns, (byte*) cname,length);
}
@@ -1604,7 +1634,7 @@ static int replace_column_table(GRANT_TABLE *g_t,
TABLE *table, const LEX_USER &combo,
List <LEX_COLUMN> &columns,
const char *db, const char *table_name,
- uint rights, bool revoke_grant)
+ ulong rights, bool revoke_grant)
{
int error=0,result=0;
uint key_length;
@@ -1628,7 +1658,7 @@ static int replace_column_table(GRANT_TABLE *g_t,
table->file->index_init(0);
while ((xx=iter++))
{
- uint privileges = xx->rights;
+ ulong privileges = xx->rights;
bool old_row_exists=0;
key_restore(table,key,0,key_length);
table->field[4]->store(xx->column.ptr(),xx->column.length());
@@ -1651,7 +1681,7 @@ static int replace_column_table(GRANT_TABLE *g_t,
}
else
{
- uint tmp= (uint) table->field[6]->val_int();
+ ulong tmp= (ulong) table->field[6]->val_int();
tmp=fix_rights_for_column(tmp);
if (revoke_grant)
@@ -1711,7 +1741,7 @@ static int replace_column_table(GRANT_TABLE *g_t,
// Scan trough all rows with the same host,db,user and table
do
{
- uint privileges = (uint) table->field[6]->val_int();
+ ulong privileges = (ulong) table->field[6]->val_int();
privileges=fix_rights_for_column(privileges);
store_record(table,1);
@@ -1767,18 +1797,21 @@ static int replace_column_table(GRANT_TABLE *g_t,
static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
TABLE *table, const LEX_USER &combo,
const char *db, const char *table_name,
- uint rights, uint kolone, bool revoke_grant)
+ ulong rights, ulong col_rights,
+ bool revoke_grant)
{
char grantor[HOSTNAME_LENGTH+1+USERNAME_LENGTH];
int old_row_exists = 1;
int error=0;
- uint store_table_rights,store_col_rights;
+ ulong store_table_rights, store_col_rights;
DBUG_ENTER("replace_table_table");
strxmov(grantor, thd->user, "@", thd->host_or_ip, NullS);
- // The following should always succeed as new users are created before
- // this function is called!
+ /*
+ The following should always succeed as new users are created before
+ this function is called!
+ */
if (!find_acl_user(combo.host.str,combo.user.str))
{
my_error(ER_PASSWORD_NO_MATCH,MYF(0)); /* purecov: deadcode */
@@ -1813,14 +1846,14 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
restore_record(table,1); // Get saved record
}
- store_table_rights=get_rights_for_table(rights);
- store_col_rights=get_rights_for_column(kolone);
+ store_table_rights= get_rights_for_table(rights);
+ store_col_rights= get_rights_for_column(col_rights);
if (old_row_exists)
{
- uint j,k;
+ ulong j,k;
store_record(table,1);
- j = (uint) table->field[6]->val_int();
- k = (uint) table->field[7]->val_int();
+ j = (ulong) table->field[6]->val_int();
+ k = (ulong) table->field[7]->val_int();
if (revoke_grant)
{
@@ -1829,8 +1862,8 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
}
else
{
- store_table_rights|=j;
- store_col_rights|=k;
+ store_table_rights|= j;
+ store_col_rights|= k;
}
}
@@ -1838,7 +1871,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
table->field[6]->store((longlong) store_table_rights);
table->field[7]->store((longlong) store_col_rights);
rights=fix_rights_for_table(store_table_rights);
- kolone=fix_rights_for_column(store_col_rights);
+ col_rights=fix_rights_for_column(store_col_rights);
if (old_row_exists)
{
@@ -1857,10 +1890,10 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
goto table_error; /* purecov: deadcode */
}
- if (rights | kolone)
+ if (rights | col_rights)
{
- grant_table->privs = rights;
- grant_table->cols = kolone;
+ grant_table->privs= rights;
+ grant_table->cols= col_rights;
}
else
{
@@ -1877,18 +1910,15 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
int mysql_table_grant (THD *thd, TABLE_LIST *table_list,
List <LEX_USER> &user_list,
- List <LEX_COLUMN> &columns, uint rights,
+ List <LEX_COLUMN> &columns, ulong rights,
bool revoke_grant)
{
- uint column_priv = 0;
+ ulong column_priv = 0;
List_iterator <LEX_USER> str_list (user_list);
LEX_USER *Str;
TABLE_LIST tables[3];
bool create_new_users=0;
DBUG_ENTER("mysql_table_grant");
- DBUG_PRINT("info",("ssl_cipher: %s",thd->lex.ssl_cipher));
- DBUG_PRINT("info",("x509_issuer: %s",thd->lex.x509_issuer));
- DBUG_PRINT("info",("x509_subject: %s",thd->lex.x509_subject));
if (!initialized)
{
@@ -1978,12 +2008,8 @@ int mysql_table_grant (THD *thd, TABLE_LIST *table_list,
continue;
}
/* Create user if needed */
- if (replace_user_table(thd,
- tables[0].table,
- *Str,
- 0,
- revoke_grant ? 'N' : 'Y',
- create_new_users))
+ if (replace_user_table(thd, tables[0].table, *Str,
+ 0, revoke_grant, create_new_users))
{
result= -1; // Remember error
continue; // Add next user
@@ -2079,12 +2105,12 @@ int mysql_table_grant (THD *thd, TABLE_LIST *table_list,
}
-int mysql_grant (THD *thd, const char *db, List <LEX_USER> &list, uint rights,
- bool revoke_grant)
+int mysql_grant (THD *thd, const char *db, List <LEX_USER> &list,
+ ulong rights, bool revoke_grant)
{
List_iterator <LEX_USER> str_list (list);
LEX_USER *Str;
- char what,tmp_db[NAME_LEN+1];
+ char tmp_db[NAME_LEN+1];
bool create_new_users=0;
TABLE_LIST tables[2];
DBUG_ENTER("mysql_grant");
@@ -2095,7 +2121,6 @@ int mysql_grant (THD *thd, const char *db, List <LEX_USER> &list, uint rights,
return 1; /* purecov: tested */
}
- what = (revoke_grant) ? 'N' : 'Y';
if (lower_case_table_names && db)
{
strmov(tmp_db,db);
@@ -2144,12 +2169,13 @@ int mysql_grant (THD *thd, const char *db, List <LEX_USER> &list, uint rights,
if ((replace_user_table(thd,
tables[0].table,
*Str,
- (!db ? rights : 0), what, create_new_users)))
+ (!db ? rights : 0), revoke_grant,
+ create_new_users)))
result= -1;
else
{
if (db && replace_db_table(tables[1].table, db, *Str, rights & DB_ACLS,
- what))
+ revoke_grant))
result= -1;
}
}
@@ -2162,7 +2188,8 @@ int mysql_grant (THD *thd, const char *db, List <LEX_USER> &list, uint rights,
DBUG_RETURN(result);
}
- /* Free grant array if possible */
+
+/* Free grant array if possible */
void grant_free(void)
{
@@ -2299,11 +2326,11 @@ void grant_reload(void)
/****************************************************************************
-** Check grants
-** All errors are written directly to the client if command name is given !
+ Check grants
+ All errors are written directly to the client if command name is given !
****************************************************************************/
-bool check_grant(THD *thd, uint want_access, TABLE_LIST *tables,
+bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
uint show_table, bool no_errors)
{
TABLE_LIST *table;
@@ -2389,7 +2416,7 @@ bool check_grant_column (THD *thd,TABLE *table, const char *name,
GRANT_TABLE *grant_table;
GRANT_COLUMN *grant_column;
- uint want_access=table->grant.want_privilege;
+ ulong want_access=table->grant.want_privilege;
if (!want_access)
return 0; // Already checked
@@ -2427,13 +2454,8 @@ bool check_grant_column (THD *thd,TABLE *table, const char *name,
pthread_mutex_unlock(&LOCK_grant);
if (!show_tables)
{
- const char *command="";
- if (want_access & SELECT_ACL)
- command ="select";
- else if (want_access & INSERT_ACL)
- command = "insert";
- else if (want_access & UPDATE_ACL)
- command = "update";
+ char command[128];
+ get_privilege_desc(command, sizeof(command), want_access);
my_printf_error(ER_COLUMNACCESS_DENIED_ERROR,
ER(ER_COLUMNACCESS_DENIED_ERROR),
MYF(0),
@@ -2447,7 +2469,7 @@ bool check_grant_column (THD *thd,TABLE *table, const char *name,
}
-bool check_grant_all_columns(THD *thd,uint want_access, TABLE *table)
+bool check_grant_all_columns(THD *thd, ulong want_access, TABLE *table)
{
GRANT_TABLE *grant_table;
GRANT_COLUMN *grant_column;
@@ -2505,9 +2527,9 @@ bool check_grant_all_columns(THD *thd,uint want_access, TABLE *table)
/****************************************************************************
-** Check if a user has the right to access a database
-** Access is accepted if he has a grant for any table in the database
-** Return 1 if access is denied
+ Check if a user has the right to access a database
+ Access is accepted if he has a grant for any table in the database
+ Return 1 if access is denied
****************************************************************************/
bool check_grant_db(THD *thd,const char *db)
@@ -2536,10 +2558,10 @@ bool check_grant_db(THD *thd,const char *db)
}
/*****************************************************************************
-** Functions to retrieve the grant for a table/column (for SHOW functions)
+ Functions to retrieve the grant for a table/column (for SHOW functions)
*****************************************************************************/
-uint get_table_grant(THD *thd, TABLE_LIST *table)
+ulong get_table_grant(THD *thd, TABLE_LIST *table)
{
char *user = thd->priv_user;
const char *db = table->db ? table->db : thd->db;
@@ -2557,11 +2579,11 @@ uint get_table_grant(THD *thd, TABLE_LIST *table)
}
-uint get_column_grant(THD *thd, TABLE_LIST *table, Field *field)
+ulong get_column_grant(THD *thd, TABLE_LIST *table, Field *field)
{
GRANT_TABLE *grant_table;
GRANT_COLUMN *grant_column;
- uint priv;
+ ulong priv;
pthread_mutex_lock(&LOCK_grant);
// reload table if someone has modified any grants
@@ -2591,18 +2613,27 @@ uint get_column_grant(THD *thd, TABLE_LIST *table, Field *field)
/*****************************************************************************
-** SHOW GRANTS : send to client grant-like strings depicting user@host
-** privileges
+ SHOW GRANTS : send to client grant-like strings depicting user@host
+ privileges
*****************************************************************************/
static const char *command_array[]=
-{"SELECT", "INSERT","UPDATE","DELETE","CREATE", "DROP","RELOAD","SHUTDOWN",
- "PROCESS","FILE","GRANT","REFERENCES","INDEX","ALTER"};
-static int command_lengths[]={6,6,6,6,6,4,6,8,7,4,5,10,5,5};
+{
+ "SELECT", "INSERT","UPDATE","DELETE","CREATE", "DROP", "RELOAD","SHUTDOWN",
+ "PROCESS","FILE","GRANT","REFERENCES","INDEX", "ALTER", "SHOW DATABASES",
+ "SUPER", "CREATE TEMPORARY TABLES", "LOCK TABLES", "EXECUTE",
+ "REPLICATION SLAVE", "REPLICATION CLIENT",
+};
+static uint command_lengths[]=
+{
+ 6,6,6,6,6,4,6,8,7,4,5,10,5,5,14,5,23,11,7,17,18
+};
+
int mysql_show_grants(THD *thd,LEX_USER *lex_user)
{
- uint counter, want_access,index;
+ ulong want_access;
+ uint counter,index;
int error = 0;
ACL_USER *acl_user; ACL_DB *acl_db;
char buff[1024];
@@ -2672,7 +2703,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
else
{
bool found=0;
- uint j,test_access= want_access & ~GRANT_ACL;
+ ulong j,test_access= want_access & ~GRANT_ACL;
for (counter=0, j = SELECT_ACL;j <= GLOBAL_ACLS;counter++,j <<= 1)
{
if (test_access & j)
@@ -2732,28 +2763,34 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
}
}
#endif /* HAVE_OPENSSL */
- if (want_access & GRANT_ACL)
- global.append(" WITH GRANT OPTION",18);
- if (acl_user->user_resource.questions)
- {
- char buff[65], *p; // just as in int2str
- global.append(" WITH MAX_QUERIES_PER_HOUR ",27);
- p=int2str(acl_user->user_resource.questions,buff,10);
- global.append(buff,p-buff);
- }
- if (acl_user->user_resource.updates)
+ if ((want_access & GRANT_ACL) ||
+ (acl_user->user_resource.questions | acl_user->user_resource.updates |
+ acl_user->user_resource.connections))
{
- char buff[65], *p; // just as in int2str
- global.append(" WITH MAX_UPDATES_PER_HOUR ",27);
- p=int2str(acl_user->user_resource.updates,buff,10);
- global.append(buff,p-buff);
- }
- if (acl_user->user_resource.connections)
- {
- char buff[65], *p; // just as in int2str
- global.append(" WITH MAX_CONNECTIONS_PER_HOUR ",31);
- p=int2str(acl_user->user_resource.connections,buff,10);
- global.append(buff,p-buff);
+ global.append(" WITH",5);
+ if (want_access & GRANT_ACL)
+ global.append(" GRANT OPTION",13);
+ if (acl_user->user_resource.questions)
+ {
+ char buff[22], *p; // just as in int2str
+ global.append(" MAX_QUERIES_PER_HOUR ",22);
+ p=int10_to_str(acl_user->user_resource.questions,buff,10);
+ global.append(buff,p-buff);
+ }
+ if (acl_user->user_resource.updates)
+ {
+ char buff[22], *p; // just as in int2str
+ global.append(" MAX_UPDATES_PER_HOUR ",22);
+ p=int10_to_str(acl_user->user_resource.updates,buff,10);
+ global.append(buff,p-buff);
+ }
+ if (acl_user->user_resource.connections)
+ {
+ char buff[22], *p; // just as in int2str
+ global.append(" MAX_CONNECTIONS_PER_HOUR ",26);
+ p=int10_to_str(acl_user->user_resource.connections,buff,10);
+ global.append(buff,p-buff);
+ }
}
thd->packet.length(0);
net_store_data(&thd->packet,global.ptr(),global.length());
@@ -2790,7 +2827,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
else
{
int found=0, cnt;
- uint j,test_access= want_access & ~GRANT_ACL;
+ ulong j,test_access= want_access & ~GRANT_ACL;
for (cnt=0, j = SELECT_ACL; j <= DB_ACLS; cnt++,j <<= 1)
{
if (test_access & j)
@@ -2810,7 +2847,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
db.append(lex_user->host.str, lex_user->host.length);
db.append ('\'');
if (want_access & GRANT_ACL)
- db.append(" WITH GRANT OPTION",18);
+ db.append(" WITH GRANT OPTION",18);
thd->packet.length(0);
net_store_data(&thd->packet,db.ptr(),db.length());
if (my_net_write(&thd->net,(char*) thd->packet.ptr(),
@@ -2849,7 +2886,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
else
{
int found=0;
- uint j,test_access= (want_access | grant_table->cols) & ~GRANT_ACL;
+ ulong j,test_access= (want_access | grant_table->cols) & ~GRANT_ACL;
for (counter=0, j = SELECT_ACL;j <= TABLE_ACLS; counter++,j <<= 1)
{
@@ -2917,6 +2954,34 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
}
+/*
+ Make a clear-text version of the requested privilege.
+*/
+
+void get_privilege_desc(char *to, uint max_length, ulong access)
+{
+ uint pos;
+ char *start=to;
+ DBUG_ASSERT(max_length >= 30); // For end ',' removal
+
+ if (access)
+ {
+ max_length--; // Reserve place for end-zero
+ for (pos=0 ; access ; pos++, access>>=1)
+ {
+ if ((access & 1) &&
+ command_lengths[pos] + (uint) (to-start) < max_length)
+ {
+ to= strmov(to, command_array[pos]);
+ *to++=',';
+ }
+ }
+ to--; // Remove end ','
+ }
+ *to=0;
+}
+
+
void get_mqh(const char *user, const char *host, USER_CONN *uc)
{
ACL_USER *acl_user;
@@ -2929,7 +2994,7 @@ void get_mqh(const char *user, const char *host, USER_CONN *uc)
/*****************************************************************************
-** Instantiate used templates
+ Instantiate used templates
*****************************************************************************/
#ifdef __GNUC__
diff --git a/sql/sql_acl.h b/sql/sql_acl.h
index 9ac3bc6ed74..5d522fa1d7e 100644
--- a/sql/sql_acl.h
+++ b/sql/sql_acl.h
@@ -15,33 +15,49 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#define SELECT_ACL 1
-#define INSERT_ACL 2
-#define UPDATE_ACL 4
-#define DELETE_ACL 8
-#define CREATE_ACL 16
-#define DROP_ACL 32
-#define RELOAD_ACL 64
-#define SHUTDOWN_ACL 128
-#define PROCESS_ACL 256
-#define FILE_ACL 512
-#define GRANT_ACL 1024
-#define REFERENCES_ACL 2048
-#define INDEX_ACL 4096
-#define ALTER_ACL 8192
-#define EXTRA_ACL 16384
-#define DB_ACLS (UPDATE_ACL | SELECT_ACL | INSERT_ACL | \
- DELETE_ACL | CREATE_ACL | DROP_ACL | GRANT_ACL | \
- REFERENCES_ACL | INDEX_ACL | ALTER_ACL)
-#define TABLE_ACLS (SELECT_ACL | INSERT_ACL | UPDATE_ACL | \
- DELETE_ACL | CREATE_ACL | DROP_ACL | GRANT_ACL | \
- REFERENCES_ACL | INDEX_ACL | ALTER_ACL)
-#define COL_ACLS (SELECT_ACL | INSERT_ACL | UPDATE_ACL | REFERENCES_ACL)
-#define GLOBAL_ACLS (SELECT_ACL | INSERT_ACL | UPDATE_ACL | DELETE_ACL |\
- CREATE_ACL | DROP_ACL | RELOAD_ACL | SHUTDOWN_ACL |\
- PROCESS_ACL | FILE_ACL | GRANT_ACL | REFERENCES_ACL |\
- INDEX_ACL | ALTER_ACL)
-#define NO_ACCESS 32768
+#define SELECT_ACL (1L << 0)
+#define INSERT_ACL (1L << 1)
+#define UPDATE_ACL (1L << 2)
+#define DELETE_ACL (1L << 3)
+#define CREATE_ACL (1L << 4)
+#define DROP_ACL (1L << 5)
+#define RELOAD_ACL (1L << 6)
+#define SHUTDOWN_ACL (1L << 7)
+#define PROCESS_ACL (1L << 8)
+#define FILE_ACL (1L << 9)
+#define GRANT_ACL (1L << 10)
+#define REFERENCES_ACL (1L << 11)
+#define INDEX_ACL (1L << 12)
+#define ALTER_ACL (1L << 13)
+#define SHOW_DB_ACL (1L << 14)
+#define SUPER_ACL (1L << 15)
+#define CREATE_TMP_ACL (1L << 16)
+#define LOCK_TABLES_ACL (1L << 17)
+#define EXECUTE_ACL (1L << 18)
+#define REPL_SLAVE_ACL (1L << 19)
+#define REPL_CLIENT_ACL (1L << 20)
+
+
+#define DB_ACLS \
+(UPDATE_ACL | SELECT_ACL | INSERT_ACL | DELETE_ACL | CREATE_ACL | DROP_ACL | \
+ GRANT_ACL | REFERENCES_ACL | INDEX_ACL | ALTER_ACL)
+
+#define TABLE_ACLS \
+(SELECT_ACL | INSERT_ACL | UPDATE_ACL | DELETE_ACL | CREATE_ACL | DROP_ACL | \
+ GRANT_ACL | REFERENCES_ACL | INDEX_ACL | ALTER_ACL)
+
+#define COL_ACLS \
+(SELECT_ACL | INSERT_ACL | UPDATE_ACL | REFERENCES_ACL)
+
+#define GLOBAL_ACLS \
+(SELECT_ACL | INSERT_ACL | UPDATE_ACL | DELETE_ACL | CREATE_ACL | DROP_ACL | \
+ RELOAD_ACL | SHUTDOWN_ACL | PROCESS_ACL | FILE_ACL | GRANT_ACL | \
+ REFERENCES_ACL | INDEX_ACL | ALTER_ACL | SHOW_DB_ACL | SUPER_ACL | \
+ CREATE_TMP_ACL | LOCK_TABLES_ACL | REPL_SLAVE_ACL | REPL_CLIENT_ACL | \
+ EXECUTE_ACL)
+
+#define EXTRA_ACL (1L << 29)
+#define NO_ACCESS (1L << 30)
/* defines to change the above bits to how things are stored in tables */
@@ -57,29 +73,30 @@
int acl_init(bool dont_read_acl_tables);
void acl_reload(void);
void acl_free(bool end=0);
-uint acl_get(const char *host, const char *ip, const char *bin_ip,
- const char *user, const char *db);
-uint acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
- const char *password,const char *scramble,char **priv_user,
- bool old_ver, USER_RESOURCES *max);
+ulong acl_get(const char *host, const char *ip, const char *bin_ip,
+ const char *user, const char *db);
+ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
+ const char *password,const char *scramble,char **priv_user,
+ bool old_ver, USER_RESOURCES *max);
bool acl_check_host(const char *host, const char *ip);
bool change_password(THD *thd, const char *host, const char *user,
char *password);
int mysql_grant(THD *thd, const char *db, List <LEX_USER> &user_list,
- uint rights, bool revoke);
+ ulong rights, bool revoke);
int mysql_table_grant(THD *thd, TABLE_LIST *table, List <LEX_USER> &user_list,
- List <LEX_COLUMN> &column_list, uint rights,
+ List <LEX_COLUMN> &column_list, ulong rights,
bool revoke);
int grant_init(void);
void grant_free(void);
void grant_reload(void);
-bool check_grant(THD *thd, uint want_access, TABLE_LIST *tables,
+bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
uint show_command=0, bool dont_print_error=0);
-bool check_grant_column (THD *thd,TABLE *table, const char *name,uint length,
+bool check_grant_column (THD *thd,TABLE *table, const char *name, uint length,
uint show_command=0);
-bool check_grant_all_columns(THD *thd, uint want_access, TABLE *table);
+bool check_grant_all_columns(THD *thd, ulong want_access, TABLE *table);
bool check_grant_db(THD *thd,const char *db);
-uint get_table_grant(THD *thd, TABLE_LIST *table);
-uint get_column_grant(THD *thd, TABLE_LIST *table, Field *field);
+ulong get_table_grant(THD *thd, TABLE_LIST *table);
+ulong get_column_grant(THD *thd, TABLE_LIST *table, Field *field);
int mysql_show_grants(THD *thd, LEX_USER *user);
+void get_privilege_desc(char *to, uint max_length, ulong access);
void get_mqh(const char *user, const char *host, USER_CONN *uc);
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 8577533fdd6..5741be69032 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -19,7 +19,6 @@
#include "mysql_priv.h"
#include "sql_acl.h"
-#include <thr_alarm.h>
#include <m_ctype.h>
#include <my_dir.h>
#include <hash.h>
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 5099a3c56a7..8d070e35345 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -244,26 +244,30 @@ void THD::awake(bool prepare_to_die)
close_active_vio();
#endif
if (mysys_var)
+ {
+ pthread_mutex_lock(&mysys_var->mutex);
+ if (!system_thread) // Don't abort locks
+ mysys_var->abort=1;
+ /*
+ This broadcast could be up in the air if the victim thread
+ exits the cond in the time between read and broadcast, but that is
+ ok since all we want to do is to make the victim thread get out
+ of waiting on current_cond.
+ */
+ if (mysys_var->current_cond)
{
- pthread_mutex_lock(&mysys_var->mutex);
- if (!system_thread) // Don't abort locks
- mysys_var->abort=1;
- // this broadcast could be up in the air if the victim thread
- // exits the cond in the time between read and broadcast, but that is
- // ok since all we want to do is to make the victim thread get out
- // of waiting on current_cond
- if (mysys_var->current_cond)
- {
- pthread_mutex_lock(mysys_var->current_mutex);
- pthread_cond_broadcast(mysys_var->current_cond);
- pthread_mutex_unlock(mysys_var->current_mutex);
- }
- pthread_mutex_unlock(&mysys_var->mutex);
+ pthread_mutex_lock(mysys_var->current_mutex);
+ pthread_cond_broadcast(mysys_var->current_cond);
+ pthread_mutex_unlock(mysys_var->current_mutex);
}
+ pthread_mutex_unlock(&mysys_var->mutex);
+ }
}
-// remember the location of thread info, the structure needed for
-// sql_alloc() and the structure for the net buffer
+/*
+ Remember the location of thread info, the structure needed for
+ sql_alloc() and the structure for the net buffer
+*/
bool THD::store_globals()
{
@@ -272,6 +276,7 @@ bool THD::store_globals()
my_pthread_setspecific_ptr(THR_NET, &net));
}
+
/* routings to adding tables to list of changed in transaction tables */
inline static void list_include(CHANGED_TABLE_LIST** prev,
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 6608c75a9f5..a9548985479 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -309,34 +309,25 @@ public:
*/
char *host,*user,*priv_user,*db,*ip;
- /* proc_info points to a string that will show in the Info column of
- SHOW PROCESSLIST output
- host_or_ip points to host if host is available, otherwise points to ip
- */
- const char *proc_info, *host_or_ip;
-
- /*
- client_capabilities has flags describing what the client can do
- sql_mode determines if certain non-standard SQL behaviour should be
- enabled
- max_packet_length - supposed to be maximum packet length the client
- can handle, but it currently appears to be assigned but never used
- except for one debugging statement
- */
- uint client_capabilities,sql_mode,max_packet_length;
+ /* Points to info-string that will show in SHOW PROCESSLIST */
+ const char *proc_info;
+ /* points to host if host is available, otherwise points to ip */
+ const char *host_or_ip;
+
+ uint client_capabilities; /* What the client supports */
+ ulong max_packet_length; /* Max packet length for client */
+ /* Determines if which non-standard SQL behaviour should be enabled */
+ uint sql_mode;
+ ulong master_access; /* Global privileges from mysql.user */
+ ulong db_access; /* Privileges for current db */
- /*
- master_access - privillege descriptor mask for system threads
- db_access - privillege descriptor mask for regular threads
- */
- uint master_access,db_access;
/*
open_tables - list of regular tables in use by this thread
temporary_tables - list of temp tables in use by this thread
handler_tables - list of tables that were opened with HANDLER OPEN
and are still in use by this thread
- */
+ */
TABLE *open_tables,*temporary_tables, *handler_tables;
// TODO: document the variables below
MYSQL_LOCK *lock,*locked_tables;
@@ -388,10 +379,10 @@ public:
max_join_size, sent_row_count, examined_row_count;
table_map used_tables;
USER_CONN *user_connect;
- ulong query_id,version, inactive_timeout,options,thread_id;
+ ulong query_id,version, inactive_timeout,options,thread_id, col_access;
long dbug_thread_id;
pthread_t real_id;
- uint current_tablenr,tmp_table,cond_count,col_access;
+ uint current_tablenr,tmp_table,cond_count;
uint server_status,open_options;
uint32 query_length;
uint32 db_length;
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 813af3d92b7..f5b69f1aff9 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -102,7 +102,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
{
int error;
bool log_on= ((thd->options & OPTION_UPDATE_LOG) ||
- !(thd->master_access & PROCESS_ACL));
+ !(thd->master_access & SUPER_ACL));
bool using_transactions, bulk_insert=0;
uint value_count;
uint save_time_stamp;
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 2ec61ff0879..88dadcca5a4 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -63,33 +63,15 @@ enum enum_sql_command {
SQLCOM_END
};
-enum lex_states { STATE_START, STATE_CHAR, STATE_IDENT,
- STATE_IDENT_SEP,
- STATE_IDENT_START,
- STATE_FOUND_IDENT,
- STATE_SIGNED_NUMBER,
- STATE_REAL,
- STATE_HEX_NUMBER,
- STATE_CMP_OP,
- STATE_LONG_CMP_OP,
- STATE_STRING,
- STATE_COMMENT,
- STATE_END,
- STATE_OPERATOR_OR_IDENT,
- STATE_NUMBER_IDENT,
- STATE_INT_OR_REAL,
- STATE_REAL_OR_POINT,
- STATE_BOOL,
- STATE_EOL,
- STATE_ESCAPE,
- STATE_LONG_COMMENT,
- STATE_END_LONG_COMMENT,
- STATE_COLON,
- STATE_SET_VAR,
- STATE_USER_END,
- STATE_HOSTNAME,
- STATE_SKIP,
- STATE_USER_VARIABLE_DELIMITER
+enum lex_states
+{
+ STATE_START, STATE_CHAR, STATE_IDENT, STATE_IDENT_SEP, STATE_IDENT_START,
+ STATE_FOUND_IDENT, STATE_SIGNED_NUMBER, STATE_REAL, STATE_HEX_NUMBER,
+ STATE_CMP_OP, STATE_LONG_CMP_OP, STATE_STRING, STATE_COMMENT, STATE_END,
+ STATE_OPERATOR_OR_IDENT, STATE_NUMBER_IDENT, STATE_INT_OR_REAL,
+ STATE_REAL_OR_POINT, STATE_BOOL, STATE_EOL, STATE_ESCAPE, STATE_LONG_COMMENT,
+ STATE_END_LONG_COMMENT, STATE_COLON, STATE_SET_VAR, STATE_USER_END,
+ STATE_HOSTNAME, STATE_SKIP, STATE_USER_VARIABLE_DELIMITER
};
typedef List<Item> List_item;
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 161077bebae..fc0e558980e 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -24,7 +24,6 @@
#include "sql_repl.h"
#include "repl_failsafe.h"
#include <m_ctype.h>
-#include <thr_alarm.h>
#include <myisam.h>
#include <my_dir.h>
#include <assert.h>
@@ -40,11 +39,11 @@
Maybe it is better to accept flags other than CLIENT_SSL from the
second packet?
*/
-#define SSL_HANDSHAKE_SIZE 2
-#define NORMAL_HANDSHAKE_SIZE 6
-#define MIN_HANDSHAKE_SIZE 2
+#define SSL_HANDSHAKE_SIZE 2
+#define NORMAL_HANDSHAKE_SIZE 6
+#define MIN_HANDSHAKE_SIZE 2
#else
-#define MIN_HANDSHAKE_SIZE 6
+#define MIN_HANDSHAKE_SIZE 6
#endif /* HAVE_OPENSSL */
#define SCRAMBLE_LENGTH 8
@@ -225,7 +224,7 @@ static bool check_user(THD *thd,enum_server_command command, const char *user,
{
VOID(pthread_mutex_lock(&LOCK_thread_count));
bool tmp=(thread_count - delayed_insert_threads >= max_connections &&
- !(thd->master_access & PROCESS_ACL));
+ !(thd->master_access & SUPER_ACL));
VOID(pthread_mutex_unlock(&LOCK_thread_count));
if (tmp)
{ // Too many connections
@@ -1076,7 +1075,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
{
thread_safe_increment(com_other,&LOCK_thread_count);
slow_command = TRUE;
- if (check_access(thd, FILE_ACL, any_db))
+ if (check_global_access(thd, REPL_SLAVE_ACL))
break;
mysql_log.write(thd,command, 0);
@@ -1101,7 +1100,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
{
thread_safe_increment(com_stat[SQLCOM_FLUSH],&LOCK_thread_count);
ulong options= (ulong) (uchar) packet[0];
- if (check_access(thd,RELOAD_ACL,any_db))
+ if (check_global_access(thd,RELOAD_ACL))
break;
mysql_log.write(thd,command,NullS);
if (reload_acl_and_cache(thd, options, (TABLE_LIST*) 0))
@@ -1112,7 +1111,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
}
case COM_SHUTDOWN:
thread_safe_increment(com_other,&LOCK_thread_count);
- if (check_access(thd,SHUTDOWN_ACL,any_db))
+ if (check_global_access(thd,SHUTDOWN_ACL))
break; /* purecov: inspected */
DBUG_PRINT("quit",("Got shutdown command"));
mysql_log.write(thd,command,NullS);
@@ -1158,7 +1157,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
break;
case COM_PROCESS_INFO:
thread_safe_increment(com_stat[SQLCOM_SHOW_PROCESSLIST],&LOCK_thread_count);
- if (!thd->priv_user[0] && check_process_priv(thd))
+ if (!thd->priv_user[0] && check_global_access(thd,PROCESS_ACL))
break;
mysql_log.write(thd,command,NullS);
mysqld_list_processes(thd,thd->master_access & PROCESS_ACL ? NullS :
@@ -1173,7 +1172,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
}
case COM_DEBUG:
thread_safe_increment(com_other,&LOCK_thread_count);
- if (check_process_priv(thd))
+ if (check_global_access(thd, SUPER_ACL))
break; /* purecov: inspected */
mysql_print_status(thd);
mysql_log.write(thd,command,NullS);
@@ -1360,28 +1359,28 @@ mysql_execute_command(void)
case SQLCOM_PURGE:
{
- if (check_process_priv(thd))
+ if (check_global_access(thd, SUPER_ACL))
goto error;
res = purge_master_logs(thd, lex->to_log);
break;
}
case SQLCOM_SHOW_NEW_MASTER:
{
- if (check_access(thd, FILE_ACL, any_db))
+ if (check_global_access(thd, REPL_SLAVE_ACL))
goto error;
res = show_new_master(thd);
break;
}
case SQLCOM_SHOW_SLAVE_HOSTS:
{
- if (check_access(thd, FILE_ACL, any_db))
+ if (check_global_access(thd, REPL_SLAVE_ACL))
goto error;
res = show_slave_hosts(thd);
break;
}
case SQLCOM_SHOW_BINLOG_EVENTS:
{
- if (check_access(thd, FILE_ACL, any_db))
+ if (check_global_access(thd, REPL_SLAVE_ACL))
goto error;
res = show_binlog_events(thd);
break;
@@ -1390,7 +1389,7 @@ mysql_execute_command(void)
{
if (check_db_used(thd,tables) ||
check_table_access(thd,SELECT_ACL, tables) ||
- check_access(thd, FILE_ACL, any_db))
+ check_global_access(thd, FILE_ACL))
goto error; /* purecov: inspected */
res = mysql_backup_table(thd, tables);
@@ -1399,15 +1398,15 @@ mysql_execute_command(void)
case SQLCOM_RESTORE_TABLE:
{
if (check_db_used(thd,tables) ||
- check_table_access(thd,INSERT_ACL, tables) ||
- check_access(thd, FILE_ACL, any_db))
+ check_table_access(thd, INSERT_ACL, tables) ||
+ check_global_access(thd, FILE_ACL))
goto error; /* purecov: inspected */
res = mysql_restore_table(thd, tables);
break;
}
case SQLCOM_CHANGE_MASTER:
{
- if (check_access(thd, PROCESS_ACL, any_db))
+ if (check_global_access(thd, SUPER_ACL))
goto error;
LOCK_ACTIVE_MI;
res = change_master(thd,active_mi);
@@ -1416,7 +1415,7 @@ mysql_execute_command(void)
}
case SQLCOM_SHOW_SLAVE_STAT:
{
- if (check_process_priv(thd))
+ if (check_global_access(thd, SUPER_ACL))
goto error;
LOCK_ACTIVE_MI;
res = show_master_info(thd,active_mi);
@@ -1425,14 +1424,14 @@ mysql_execute_command(void)
}
case SQLCOM_SHOW_MASTER_STAT:
{
- if (check_process_priv(thd))
+ if (check_global_access(thd, SUPER_ACL))
goto error;
res = show_binlog_info(thd);
break;
}
case SQLCOM_LOAD_MASTER_DATA: // sync with master
- if (check_process_priv(thd))
+ if (check_global_access(thd, SUPER_ACL))
goto error;
res = load_master_data(thd);
break;
@@ -1469,9 +1468,12 @@ mysql_execute_command(void)
break;
}
case SQLCOM_CREATE_TABLE:
+ {
+ ulong want_priv= ((lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) ?
+ CREATE_TMP_ACL : CREATE_ACL);
if (!tables->db)
tables->db=thd->db;
- if (check_access(thd,CREATE_ACL,tables->db,&tables->grant.privilege) ||
+ if (check_access(thd,want_priv,tables->db,&tables->grant.privilege) ||
check_merge_table_access(thd, tables->db,
(TABLE_LIST *)
lex->create_info.merge_list.first))
@@ -1553,6 +1555,7 @@ mysql_execute_command(void)
send_ok(&thd->net);
}
break;
+ }
case SQLCOM_CREATE_INDEX:
if (!tables->db)
tables->db=thd->db;
@@ -1586,7 +1589,7 @@ mysql_execute_command(void)
break;
#else
{
- uint priv=0;
+ ulong priv=0;
if (lex->name && strlen(lex->name) > NAME_LEN)
{
net_printf(&thd->net,ER_WRONG_TABLE_NAME,lex->name);
@@ -1676,7 +1679,7 @@ mysql_execute_command(void)
DBUG_VOID_RETURN;
#else
{
- if (check_process_priv(thd))
+ if (check_global_access(thd, SUPER_ACL))
goto error;
res = show_binlogs(thd);
break;
@@ -1778,25 +1781,36 @@ mysql_execute_command(void)
multi_update *result;
uint table_count;
TABLE_LIST *auxi;
+ const char *msg=0;
+
lex->sql_command=SQLCOM_MULTI_UPDATE;
for (auxi=(TABLE_LIST*) tables, table_count=0 ; auxi ; auxi=auxi->next)
{
table_count++;
auxi->lock_type=TL_WRITE;
}
- if (select_lex->order_list.elements || (select_lex->select_limit && select_lex->select_limit < INT_MAX))
+ if (select_lex->order_list.elements)
+ msg="ORDER BY";
+ else if (select_lex->select_limit && select_lex->select_limit !=
+ HA_POS_ERROR)
+ msg="LIMIT";
+
+ if (msg)
{
- send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /// will have to come up with something better eventually
- DBUG_VOID_RETURN;
+ net_printf(&thd->net, ER_WRONG_USAGE, "UPDATE", msg);
+ res= 1;
+ break;
}
tables->grant.want_privilege=(SELECT_ACL & ~tables->grant.privilege);
if ((res=open_and_lock_tables(thd,tables)))
break;
thd->select_limit=HA_POS_ERROR;
if (!setup_fields(thd,tables,select_lex->item_list,1,0,0) &&
- !setup_fields(thd,tables,lex->value_list,0,0,0) && ! thd->fatal_error &&
- (result=new multi_update(thd,tables,select_lex->item_list,lex->duplicates,
- lex->lock_option, table_count)))
+ !setup_fields(thd,tables,lex->value_list,0,0,0) &&
+ ! thd->fatal_error &&
+ (result=new multi_update(thd,tables,select_lex->item_list,
+ lex->duplicates, lex->lock_option,
+ table_count)))
{
List <Item> total_list;
List_iterator <Item> field_list(select_lex->item_list);
@@ -1846,11 +1860,13 @@ mysql_execute_command(void)
case SQLCOM_INSERT_SELECT:
{
- // Check that we have modify privileges for the first table and
- // select privileges for the rest
+ /*
+ Check that we have modify privileges for the first table and
+ select privileges for the rest
+ */
{
- uint privilege= (lex->sql_command == SQLCOM_INSERT_SELECT ?
- INSERT_ACL : INSERT_ACL | UPDATE_ACL | DELETE_ACL);
+ ulong privilege= (lex->sql_command == SQLCOM_INSERT_SELECT ?
+ INSERT_ACL : INSERT_ACL | UPDATE_ACL | DELETE_ACL);
TABLE_LIST *save_next=tables->next;
tables->next=0;
if (check_access(thd, privilege,
@@ -2015,13 +2031,13 @@ mysql_execute_command(void)
DBUG_VOID_RETURN;
#else
if ((specialflag & SPECIAL_SKIP_SHOW_DB) &&
- check_process_priv(thd))
+ check_global_access(thd, SHOW_DB_ACL))
goto error;
res= mysqld_show_dbs(thd, (lex->wild ? lex->wild->ptr() : NullS));
break;
#endif
case SQLCOM_SHOW_PROCESSLIST:
- if (!thd->priv_user[0] && check_process_priv(thd))
+ if (!thd->priv_user[0] && check_global_access(thd,PROCESS_ACL))
break;
mysqld_list_processes(thd,thd->master_access & PROCESS_ACL ? NullS :
thd->priv_user,lex->verbose);
@@ -2034,17 +2050,10 @@ mysql_execute_command(void)
init_vars);
break;
case SQLCOM_SHOW_LOGS:
-#ifdef DONT_ALLOW_SHOW_COMMANDS
- send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
- DBUG_VOID_RETURN;
-#else
- {
- if (grant_option && check_access(thd, FILE_ACL, any_db))
- goto error;
- res= mysqld_show_logs(thd);
- break;
- }
-#endif
+ {
+ res= mysqld_show_logs(thd);
+ break;
+ }
case SQLCOM_SHOW_TABLES:
/* FALL THROUGH */
#ifdef DONT_ALLOW_SHOW_COMMANDS
@@ -2216,8 +2225,7 @@ mysql_execute_command(void)
}
if (check_db_used(thd,tables) || end_active_trans(thd))
goto error;
- if (check_table_access(thd, SELECT_ACL | INSERT_ACL | UPDATE_ACL |
- DELETE_ACL, tables))
+ if (check_table_access(thd, LOCK_TABLES_ACL | SELECT_ACL, tables))
goto error;
thd->in_lock_tables=1;
thd->options|= OPTION_TABLE_LOCK;
@@ -2289,8 +2297,10 @@ mysql_execute_command(void)
tables ? 0 : 1))
goto error;
- /* Check that the user isn't trying to change a password for another
- user if he doesn't have UPDATE privilege to the MySQL database */
+ /*
+ Check that the user isn't trying to change a password for another
+ user if he doesn't have UPDATE privilege to the MySQL database
+ */
if (thd->user) // If not replication
{
@@ -2359,7 +2369,7 @@ mysql_execute_command(void)
}
case SQLCOM_FLUSH:
case SQLCOM_RESET:
- if (check_access(thd,RELOAD_ACL,any_db) || check_db_used(thd, tables))
+ if (check_global_access(thd,RELOAD_ACL) || check_db_used(thd, tables))
goto error;
if (reload_acl_and_cache(thd, lex->type, tables))
send_error(&thd->net,0);
@@ -2461,20 +2471,23 @@ error:
/****************************************************************************
-** Get the user (global) and database privileges for all used tables
-** Returns true (error) if we can't get the privileges and we don't use
-** table/column grants.
-** The idea of EXTRA_ACL is that one will be granted access to the table if
-** one has the asked privilege on any column combination of the table; For
-** example to be able to check a table one needs to have SELECT privilege on
-** any column of the table.
+ Get the user (global) and database privileges for all used tables
+ Returns true (error) if we can't get the privileges and we don't use
+ table/column grants.
+ The idea of EXTRA_ACL is that one will be granted access to the table if
+ one has the asked privilege on any column combination of the table; For
+ example to be able to check a table one needs to have SELECT privilege on
+ any column of the table.
****************************************************************************/
bool
-check_access(THD *thd,uint want_access,const char *db, uint *save_priv,
+check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
bool dont_check_global_grants, bool no_errors)
{
- uint db_access,dummy;
+ DBUG_ENTER("check_access");
+ DBUG_PRINT("enter",("want_access: %lu master_access: %lu", want_access,
+ thd->master_access));
+ ulong db_access,dummy;
if (save_priv)
*save_priv=0;
else
@@ -2484,13 +2497,13 @@ check_access(THD *thd,uint want_access,const char *db, uint *save_priv,
{
if (!no_errors)
send_error(&thd->net,ER_NO_DB_ERROR); /* purecov: tested */
- return TRUE; /* purecov: tested */
+ DBUG_RETURN(TRUE); /* purecov: tested */
}
if ((thd->master_access & want_access) == want_access)
{
*save_priv=thd->master_access;
- return FALSE;
+ DBUG_RETURN(FALSE);
}
if (((want_access & ~thd->master_access) & ~(DB_ACLS | EXTRA_ACL)) ||
! db && dont_check_global_grants)
@@ -2500,11 +2513,11 @@ check_access(THD *thd,uint want_access,const char *db, uint *save_priv,
thd->priv_user,
thd->host_or_ip,
thd->password ? ER(ER_YES) : ER(ER_NO));/* purecov: tested */
- return TRUE; /* purecov: tested */
+ DBUG_RETURN(TRUE); /* purecov: tested */
}
if (db == any_db)
- return FALSE; // Allow select on anything
+ DBUG_RETURN(FALSE); // Allow select on anything
if (db && (!thd->db || strcmp(db,thd->db)))
db_access=acl_get(thd->host, thd->ip, (char*) &thd->remote.sin_addr,
@@ -2519,32 +2532,41 @@ check_access(THD *thd,uint want_access,const char *db, uint *save_priv,
if (db_access == want_access ||
((grant_option && !dont_check_global_grants) &&
!(want_access & ~TABLE_ACLS)))
- return FALSE; /* Ok */
+ DBUG_RETURN(FALSE); /* Ok */
if (!no_errors)
net_printf(&thd->net,ER_DBACCESS_DENIED_ERROR,
thd->priv_user,
thd->host_or_ip,
db ? db : thd->db ? thd->db : "unknown"); /* purecov: tested */
- return TRUE; /* purecov: tested */
+ DBUG_RETURN(TRUE); /* purecov: tested */
}
-bool check_process_priv(THD *thd)
+/* check for global access and give descriptive error message if it fails */
+
+bool check_global_access(THD *thd, ulong want_access)
{
- return (check_access(thd ? thd : current_thd,PROCESS_ACL,any_db));
+ char command[128];
+ if ((thd->master_access & want_access) == want_access)
+ return 0;
+ get_privilege_desc(command, sizeof(command), want_access);
+ net_printf(&thd->net,ER_SPECIFIC_ACCESS_DENIED_ERROR,
+ command);
+ return 1;
}
/*
-** Check the privilege for all used tables. Table privileges are cached
-** in the table list for GRANT checking
+ Check the privilege for all used tables. Table privileges are cached
+ in the table list for GRANT checking
*/
bool
-check_table_access(THD *thd,uint want_access,TABLE_LIST *tables,
+check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables,
bool no_errors)
{
- uint found=0,found_access=0;
+ uint found=0;
+ ulong found_access=0;
TABLE_LIST *org_tables=tables;
for (; tables ; tables=tables->next)
{
@@ -3382,7 +3404,7 @@ void kill_one_thread(THD *thd, ulong id)
{
if (tmp->thread_id == id)
{
- if ((thd->master_access & PROCESS_ACL) ||
+ if ((thd->master_access & SUPER_ACL) ||
!strcmp(thd->user,tmp->user))
{
tmp->awake(1 /*prepare to die*/);
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index fa2a6e2d28a..3b689a2571d 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -21,7 +21,6 @@
#include "sql_acl.h"
#include "log_event.h"
#include "mini_client.h"
-#include <thr_alarm.h>
#include <my_dir.h>
#include <assert.h>
@@ -537,11 +536,13 @@ impossible position";
thd->proc_info = "waiting to finalize termination";
end_io_cache(&log);
pthread_mutex_lock(&LOCK_thread_count);
- // exclude iteration through thread list
- // this is needed for purge_logs() - it will iterate through
- // thread list and update thd->current_linfo->index_file_offset
- // this mutex will make sure that it never tried to update our linfo
- // after we return from this stack frame
+ /*
+ Exclude iteration through thread list
+ this is needed for purge_logs() - it will iterate through
+ thread list and update thd->current_linfo->index_file_offset
+ this mutex will make sure that it never tried to update our linfo
+ after we return from this stack frame
+ */
thd->current_linfo = 0;
pthread_mutex_unlock(&LOCK_thread_count);
if (file >= 0)
@@ -557,7 +558,7 @@ int start_slave(THD* thd , MASTER_INFO* mi, bool net_report)
NET* net = &thd->net;
int thread_mask;
- if (check_access(thd, PROCESS_ACL, any_db))
+ if (check_access(thd, SUPER_ACL, any_db))
return 1;
lock_slave_threads(mi); // this allows us to cleanly read slave_running
init_thread_mask(&thread_mask,mi,1 /* inverse */);
@@ -597,7 +598,7 @@ int stop_slave(THD* thd, MASTER_INFO* mi, bool net_report )
if (!thd) thd = current_thd;
NET* net = &thd->net;
- if (check_access(thd, PROCESS_ACL, any_db))
+ if (check_access(thd, SUPER_ACL, any_db))
return 1;
thd->proc_info = "Killing slave";
int thread_mask;
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index a282c6dde5b..1d117809f44 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -78,11 +78,11 @@ mysqld_show_dbs(THD *thd,const char *wild)
List_iterator_fast<char> it(files);
while ((file_name=it++))
{
- if (!opt_safe_show_db || thd->master_access ||
+ if (thd->master_access & (DB_ACLS | SHOW_DB_ACL) ||
acl_get(thd->host, thd->ip, (char*) &thd->remote.sin_addr,
thd->priv_user, file_name) ||
(grant_option && !check_grant_db(thd, file_name)))
- {
+ {
thd->packet.length(0);
net_store_data(&thd->packet, thd->convert_set, file_name);
if (my_net_write(&thd->net, (char*) thd->packet.ptr(),
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 7b9d1f03dd0..53724c3656b 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -81,7 +81,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token LAST_SYM
%token NEXT_SYM
%token PREV_SYM
-%token SQL_CALC_FOUND_ROWS
%token EQ
%token EQUAL_SYM
@@ -95,50 +94,54 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token SHIFT_RIGHT
%token SET_VAR
-%token AVG_SYM
-%token COUNT_SYM
-%token MAX_SYM
-%token MIN_SYM
-%token SUM_SYM
-%token STD_SYM
-%token ABORT_SYM
+%token ABORT_SYM
%token ADD
-%token ALTER
%token AFTER_SYM
-%token ANALYZE_SYM
-%token BEGIN_SYM
+%token ALTER
+%token ANALYZE_SYM
+%token AVG_SYM
+%token BEGIN_SYM
+%token BINLOG_SYM
%token CHANGE
-%token COMMENT_SYM
-%token COMMIT_SYM
+%token CLIENT_SYM
+%token COMMENT_SYM
+%token COMMIT_SYM
+%token COUNT_SYM
%token CREATE
%token CROSS
%token DELETE_SYM
%token DO_SYM
%token DROP
-%token INSERT
+%token EVENTS_SYM
+%token EXECUTE_SYM
%token FLUSH_SYM
-%token SELECT_SYM
-%token MASTER_SYM
-%token REPAIR
-%token RESET_SYM
-%token PURGE
-%token SLAVE
-%token IO_THREAD
-%token SQL_THREAD
-%token START_SYM
-%token STOP_SYM
-%token TRUNCATE_SYM
-%token ROLLBACK_SYM
-%token OPTIMIZE
-%token SHOW
-%token UPDATE_SYM
+%token INSERT
+%token IO_THREAD
%token KILL_SYM
%token LOAD
-%token LOCK_SYM
%token LOCKS_SYM
+%token LOCK_SYM
+%token MASTER_SYM
+%token MAX_SYM
+%token MIN_SYM
+%token OPTIMIZE
+%token PURGE
+%token REPAIR
+%token REPLICATION
+%token RESET_SYM
+%token ROLLBACK_SYM
+%token SELECT_SYM
+%token SHOW
+%token SLAVE
+%token SQL_THREAD
+%token START_SYM
+%token STD_SYM
+%token STOP_SYM
+%token SUM_SYM
+%token SUPER_SYM
+%token TRUNCATE_SYM
%token UNLOCK_SYM
-%token BINLOG_SYM
-%token EVENTS_SYM
+%token UPDATE_SYM
%token ACTION
%token AGGREGATE_SYM
@@ -149,7 +152,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token AUTO_INC
%token AUTOCOMMIT
%token AVG_ROW_LENGTH
-%token BACKUP_SYM
+%token BACKUP_SYM
%token BERKELEY_DB_SYM
%token BINARY
%token BIT_SYM
@@ -184,7 +187,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token ENABLE_SYM
%token ENCLOSED
%token ESCAPED
-%token DIRECTORY_SYM
+%token DIRECTORY_SYM
%token ESCAPE_SYM
%token EXISTS
%token EXTENDED_SYM
@@ -195,8 +198,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token FOREIGN
%token FROM
%token FULL
-%token FULLTEXT_SYM
-%token GLOBAL_SYM
+%token FULLTEXT_SYM
+%token GLOBAL_SYM
%token GRANT
%token GRANTS
%token GREATEST_SYM
@@ -215,7 +218,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token INNOBASE_SYM
%token INTO
%token IN_SYM
-%token ISOLATION
+%token ISOLATION
%token ISAM_SYM
%token ISSUER
%token JOIN_SYM
@@ -223,7 +226,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token KEY_SYM
%token LEADING
%token LEAST_SYM
-%token LEVEL_SYM
+%token LEVEL_SYM
%token LEX_HOSTNAME
%token LIKE
%token LINES
@@ -232,35 +235,35 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token LONG_NUM
%token LONG_SYM
%token LOW_PRIORITY
-%token MASTER_HOST_SYM
-%token MASTER_USER_SYM
-%token MASTER_LOG_FILE_SYM
-%token MASTER_LOG_POS_SYM
-%token MASTER_LOG_SEQ_SYM
-%token MASTER_PASSWORD_SYM
-%token MASTER_PORT_SYM
-%token MASTER_CONNECT_RETRY_SYM
-%token MASTER_SERVER_ID_SYM
-%token RELAY_LOG_FILE_SYM
-%token RELAY_LOG_POS_SYM
+%token MASTER_HOST_SYM
+%token MASTER_USER_SYM
+%token MASTER_LOG_FILE_SYM
+%token MASTER_LOG_POS_SYM
+%token MASTER_LOG_SEQ_SYM
+%token MASTER_PASSWORD_SYM
+%token MASTER_PORT_SYM
+%token MASTER_CONNECT_RETRY_SYM
+%token MASTER_SERVER_ID_SYM
+%token RELAY_LOG_FILE_SYM
+%token RELAY_LOG_POS_SYM
%token MATCH
%token MAX_ROWS
-%token MAX_CONNECTIONS_PER_HOUR
-%token MAX_QUERIES_PER_HOUR
-%token MAX_UPDATES_PER_HOUR
+%token MAX_CONNECTIONS_PER_HOUR
+%token MAX_QUERIES_PER_HOUR
+%token MAX_UPDATES_PER_HOUR
%token MEDIUM_SYM
%token MERGE_SYM
%token MIN_ROWS
%token MYISAM_SYM
%token NATIONAL_SYM
%token NATURAL
-%token NEW_SYM
+%token NEW_SYM
%token NCHAR_SYM
%token NOT
%token NO_SYM
%token NULL_SYM
%token NUM
-%token OFF
+%token OFF
%token ON
%token OPEN_SYM
%token OPTION
@@ -270,7 +273,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token ORDER_SYM
%token OUTER
%token OUTFILE
-%token DUMPFILE
+%token DUMPFILE
%token PACK_KEYS_SYM
%token PARTIAL
%token PRIMARY_SYM
@@ -291,8 +294,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token RENAME
%token REPEATABLE_SYM
%token REQUIRE_SYM
-%token RESOURCES
-%token RESTORE_SYM
+%token RESOURCES
+%token RESTORE_SYM
%token RESTRICT
%token REVOKE
%token ROWS_SYM
@@ -302,9 +305,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token SERIALIZABLE_SYM
%token SESSION_SYM
%token SHUTDOWN
-%token SQL_CACHE_SYM
-%token SQL_NO_CACHE_SYM
-%token SSL_SYM
+%token SSL_SYM
%token STARTING
%token STATUS_SYM
%token STRAIGHT_JOIN
@@ -325,7 +326,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token UDF_RETURNS_SYM
%token UDF_SONAME_SYM
%token UDF_SYM
-%token UNCOMMITTED_SYM
+%token UNCOMMITTED_SYM
%token UNION_SYM
%token UNIQUE_SYM
%token USAGE
@@ -337,13 +338,13 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token WHERE
%token WITH
%token WRITE_SYM
-%token X509_SYM
-%token COMPRESSED_SYM
+%token X509_SYM
+%token COMPRESSED_SYM
%token BIGINT
%token BLOB_SYM
%token CHAR_SYM
-%token CHANGED
+%token CHANGED
%token COALESCE
%token DATETIME
%token DATE_SYM
@@ -361,7 +362,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token MEDIUMTEXT
%token NUMERIC_SYM
%token PRECISION
-%token QUICK
+%token QUICK
%token REAL
%token SIGNED_SYM
%token SMALLINT
@@ -379,14 +380,14 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token VARYING
%token ZEROFILL
-%token AGAINST
+%token AGAINST
%token ATAN
%token BETWEEN_SYM
%token BIT_AND
%token BIT_OR
%token CASE_SYM
%token CONCAT
-%token CONCAT_WS
+%token CONCAT_WS
%token CURDATE
%token CURTIME
%token DATABASE
@@ -424,7 +425,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token MAKE_SET_SYM
%token MINUTE_SECOND_SYM
%token MINUTE_SYM
-%token MODE_SYM
+%token MODE_SYM
%token MODIFY_SYM
%token MONTH_SYM
%token NOW_SYM
@@ -451,29 +452,32 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token USER
%token WEEK_SYM
%token WHEN_SYM
-%token WORK_SYM
+%token WORK_SYM
%token YEAR_MONTH_SYM
%token YEAR_SYM
%token YEARWEEK
-%token BENCHMARK_SYM
-%token END
-%token THEN_SYM
+%token BENCHMARK_SYM
+%token END
+%token THEN_SYM
-%token SQL_BIG_TABLES
+%token SQL_AUTO_IS_NULL
+%token SQL_BIG_RESULT
%token SQL_BIG_SELECTS
-%token SQL_SELECT_LIMIT
-%token SQL_MAX_JOIN_SIZE
+%token SQL_BIG_TABLES
+%token SQL_CACHE_SYM
+%token SQL_CALC_FOUND_ROWS
%token SQL_LOG_BIN
%token SQL_LOG_OFF
%token SQL_LOG_UPDATE
%token SQL_LOW_PRIORITY_UPDATES
+%token SQL_MAX_JOIN_SIZE
+%token SQL_NO_CACHE_SYM
+%token SQL_QUERY_CACHE_TYPE_SYM
+%token SQL_SAFE_UPDATES
+%token SQL_SELECT_LIMIT
%token SQL_SMALL_RESULT
-%token SQL_BIG_RESULT
-%token SQL_BUFFER_RESULT
%token SQL_WARNINGS
-%token SQL_AUTO_IS_NULL
-%token SQL_SAFE_UPDATES
-%token SQL_QUERY_CACHE_TYPE_SYM
+%token SQL_BUFFER_RESULT
%token SQL_QUOTE_SHOW_CREATE
%token SQL_SLAVE_SKIP_COUNTER
@@ -2990,6 +2994,7 @@ keyword:
| CHECKSUM_SYM {}
| CHECK_SYM {}
| CIPHER_SYM {}
+ | CLIENT_SYM {}
| CLOSE_SYM {}
| COMMENT_SYM {}
| COMMITTED_SYM {}
@@ -3011,6 +3016,7 @@ keyword:
| ENUM {}
| ESCAPE_SYM {}
| EVENTS_SYM {}
+ | EXECUTE_SYM {}
| EXTENDED_SYM {}
| FAST_SYM {}
| DISABLE_SYM {}
@@ -3078,11 +3084,12 @@ keyword:
| RAID_CHUNKSIZE {}
| RAID_STRIPED_SYM {}
| RAID_TYPE {}
- | RELAY_LOG_FILE_SYM {}
- | RELAY_LOG_POS_SYM {}
+ | RELAY_LOG_FILE_SYM {}
+ | RELAY_LOG_POS_SYM {}
| RELOAD {}
| REPAIR {}
| REPEATABLE_SYM {}
+ | REPLICATION {}
| RESET_SYM {}
| RESOURCES {}
| RESTORE_SYM {}
@@ -3100,12 +3107,13 @@ keyword:
| SQL_CACHE_SYM {}
| SQL_NO_CACHE_SYM {}
| SQL_QUERY_CACHE_TYPE_SYM {}
- | SQL_THREAD {}
+ | SQL_THREAD {}
| START_SYM {}
| STATUS_SYM {}
| STOP_SYM {}
| STRING_SYM {}
| SUBJECT_SYM {}
+ | SUPER_SYM {}
| TEMPORARY {}
| TEXT_SYM {}
| TRANSACTION_SYM {}
@@ -3318,7 +3326,7 @@ set_option:
set_isolation:
GLOBAL_SYM tx_isolation
{
- if (check_process_priv())
+ if (check_global_access(current_thd, SUPER_ACL))
YYABORT;
default_tx_isolation= $2;
default_tx_isolation_name=tx_isolation_typelib.type_names[default_tx_isolation];
@@ -3461,76 +3469,79 @@ grant:
grant_privileges:
grant_privilege_list {}
- | ALL PRIVILEGES { Lex->grant = UINT_MAX;}
- | ALL { Lex->grant = UINT_MAX;};
+ | ALL PRIVILEGES { Lex->grant = GLOBAL_ACLS;}
+ | ALL { Lex->grant = GLOBAL_ACLS;};
grant_privilege_list:
grant_privilege
| grant_privilege_list ',' grant_privilege;
grant_privilege:
- SELECT_SYM
- { Lex->which_columns = SELECT_ACL;}
- opt_column_list
- | INSERT
- { Lex->which_columns = INSERT_ACL; }
- opt_column_list
- | UPDATE_SYM
- { Lex->which_columns = UPDATE_ACL; }
- opt_column_list
- | DELETE_SYM { Lex->grant |= DELETE_ACL;}
- | REFERENCES { Lex->which_columns = REFERENCES_ACL;} opt_column_list
- | USAGE {}
+ SELECT_SYM { Lex->which_columns = SELECT_ACL;} opt_column_list
+ | INSERT { Lex->which_columns = INSERT_ACL;} opt_column_list
+ | UPDATE_SYM { Lex->which_columns = UPDATE_ACL; } opt_column_list
+ | REFERENCES { Lex->which_columns = REFERENCES_ACL;} opt_column_list
+ | DELETE_SYM { Lex->grant |= DELETE_ACL;}
+ | USAGE {}
| INDEX { Lex->grant |= INDEX_ACL;}
| ALTER { Lex->grant |= ALTER_ACL;}
| CREATE { Lex->grant |= CREATE_ACL;}
| DROP { Lex->grant |= DROP_ACL;}
+ | EXECUTE_SYM { Lex->grant |= EXECUTE_ACL;}
| RELOAD { Lex->grant |= RELOAD_ACL;}
| SHUTDOWN { Lex->grant |= SHUTDOWN_ACL;}
| PROCESS { Lex->grant |= PROCESS_ACL;}
| FILE_SYM { Lex->grant |= FILE_ACL;}
- | GRANT OPTION { Lex->grant |= GRANT_ACL;};
+ | GRANT OPTION { Lex->grant |= GRANT_ACL;}
+ | SHOW DATABASES { Lex->grant |= SHOW_DB_ACL;}
+ | SUPER_SYM { Lex->grant |= SUPER_ACL;}
+ | CREATE TEMPORARY TABLES { Lex->grant |= CREATE_TMP_ACL;}
+ | LOCK_SYM TABLES { Lex->grant |= LOCK_TABLES_ACL; }
+ | REPLICATION SLAVE { Lex->grant |= REPL_SLAVE_ACL;}
+ | REPLICATION CLIENT_SYM { Lex->grant |= REPL_CLIENT_ACL;}
+ ;
require_list: require_list_element AND require_list
| require_list_element ;
require_list_element: SUBJECT_SYM TEXT_STRING
- {
- LEX *lex=Lex;
- if (lex->x509_subject)
- {
- net_printf(&lex->thd->net,ER_DUP_ARGUMENT, "SUBJECT");
- YYABORT;
- }
- lex->x509_subject=$2.str;
- }
- | ISSUER_SYM TEXT_STRING
- {
- LEX *lex=Lex;
- if (lex->x509_issuer)
- {
- net_printf(&lex->thd->net,ER_DUP_ARGUMENT, "ISSUER");
- YYABORT;
- }
- lex->x509_issuer=$2.str;
- }
- | CIPHER_SYM TEXT_STRING
- {
- LEX *lex=Lex;
- if (lex->ssl_cipher)
- {
- net_printf(&lex->thd->net,ER_DUP_ARGUMENT, "CIPHER");
- YYABORT;
- }
- lex->ssl_cipher=$2.str;
- };
+ {
+ LEX *lex=Lex;
+ if (lex->x509_subject)
+ {
+ net_printf(&lex->thd->net,ER_DUP_ARGUMENT, "SUBJECT");
+ YYABORT;
+ }
+ lex->x509_subject=$2.str;
+ }
+ | ISSUER_SYM TEXT_STRING
+ {
+ LEX *lex=Lex;
+ if (lex->x509_issuer)
+ {
+ net_printf(&lex->thd->net,ER_DUP_ARGUMENT, "ISSUER");
+ YYABORT;
+ }
+ lex->x509_issuer=$2.str;
+ }
+ | CIPHER_SYM TEXT_STRING
+ {
+ LEX *lex=Lex;
+ if (lex->ssl_cipher)
+ {
+ net_printf(&lex->thd->net,ER_DUP_ARGUMENT, "CIPHER");
+ YYABORT;
+ }
+ lex->ssl_cipher=$2.str;
+ }
+ ;
opt_table:
'*'
{
LEX *lex=Lex;
lex->select->db=lex->thd->db;
- if (lex->grant == UINT_MAX)
+ if (lex->grant == GLOBAL_ACLS)
lex->grant = DB_ACLS & ~GRANT_ACL;
else if (lex->columns.elements)
{
@@ -3542,7 +3553,7 @@ opt_table:
{
LEX *lex=Lex;
lex->select->db = $1.str;
- if (lex->grant == UINT_MAX)
+ if (lex->grant == GLOBAL_ACLS)
lex->grant = DB_ACLS & ~GRANT_ACL;
else if (lex->columns.elements)
{
@@ -3554,8 +3565,8 @@ opt_table:
{
LEX *lex=Lex;
lex->select->db = NULL;
- if (lex->grant == UINT_MAX)
- lex->grant = GLOBAL_ACLS & ~GRANT_ACL;
+ if (lex->grant == GLOBAL_ACLS)
+ lex->grant= GLOBAL_ACLS & ~GRANT_ACL;
else if (lex->columns.elements)
{
send_error(&lex->thd->net,ER_ILLEGAL_GRANT_FOR_TABLE);
@@ -3567,7 +3578,7 @@ opt_table:
LEX *lex=Lex;
if (!add_table_to_list($1,NULL,0))
YYABORT;
- if (lex->grant == UINT_MAX)
+ if (lex->grant == GLOBAL_ACLS)
lex->grant = TABLE_ACLS & ~GRANT_ACL;
};
diff --git a/sql/table.h b/sql/table.h
index e8280a7d7e6..b6bc3fa8cf1 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -37,8 +37,8 @@ typedef struct st_grant_info
{
GRANT_TABLE *grant_table;
uint version;
- uint privilege;
- uint want_privilege;
+ ulong privilege;
+ ulong want_privilege;
} GRANT_INFO;
enum tmp_table_type {NO_TMP_TABLE=0, TMP_TABLE=1, TRANSACTIONAL_TMP_TABLE=2};