diff options
author | unknown <monty@mashka.mysql.fi> | 2002-06-12 15:04:18 +0300 |
---|---|---|
committer | unknown <monty@mashka.mysql.fi> | 2002-06-12 15:04:18 +0300 |
commit | 0724f98e6771d9e5631cf365f42947ad18f3d09c (patch) | |
tree | 8495f49bd4d6cb6596a29d60137462d0563ed9ee /sql | |
parent | 70aa7424c41c45a8fb171bbdd9e24d74b70a7765 (diff) | |
download | mariadb-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')
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}; |