summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Docs/manual.texi186
-rw-r--r--include/mysqld_error.h3
-rw-r--r--mysql-test/install_test_db.sh35
-rw-r--r--mysql-test/r/grant_cache.result4
-rw-r--r--mysql-test/r/rpl000017.result4
-rw-r--r--mysql-test/t/rpl000017.test4
-rw-r--r--mysys/safemalloc.c11
-rw-r--r--scripts/mysql_fix_privilege_tables.sh70
-rw-r--r--scripts/mysql_install_db.sh25
-rw-r--r--scripts/mysql_new_fix_privilege_tables.sh25
-rw-r--r--sql/field.h4
-rw-r--r--sql/item_strfunc.cc2
-rw-r--r--sql/lex.h10
-rw-r--r--sql/log.cc6
-rw-r--r--sql/mysql_priv.h8
-rw-r--r--sql/mysqld.cc2
-rw-r--r--sql/repl_failsafe.cc3
-rw-r--r--sql/share/czech/errmsg.txt5
-rw-r--r--sql/share/danish/errmsg.txt3
-rw-r--r--sql/share/dutch/errmsg.txt5
-rw-r--r--sql/share/english/errmsg.txt3
-rw-r--r--sql/share/estonian/errmsg.txt3
-rw-r--r--sql/share/french/errmsg.txt5
-rw-r--r--sql/share/german/errmsg.txt3
-rw-r--r--sql/share/greek/errmsg.txt3
-rw-r--r--sql/share/hungarian/errmsg.txt5
-rw-r--r--sql/share/italian/errmsg.txt5
-rw-r--r--sql/share/japanese/errmsg.txt5
-rw-r--r--sql/share/korean/errmsg.txt5
-rw-r--r--sql/share/norwegian-ny/errmsg.txt5
-rw-r--r--sql/share/norwegian/errmsg.txt5
-rw-r--r--sql/share/polish/errmsg.txt5
-rw-r--r--sql/share/portuguese/errmsg.txt3
-rw-r--r--sql/share/romanian/errmsg.txt3
-rw-r--r--sql/share/russian/errmsg.txt3
-rw-r--r--sql/share/slovak/errmsg.txt5
-rw-r--r--sql/share/spanish/errmsg.txt5
-rw-r--r--sql/share/swedish/errmsg.txt7
-rw-r--r--sql/share/ukrainian/errmsg.txt3
-rw-r--r--sql/slave.cc25
-rw-r--r--sql/sql_acl.cc463
-rw-r--r--sql/sql_acl.h95
-rw-r--r--sql/sql_base.cc1
-rw-r--r--sql/sql_class.cc37
-rw-r--r--sql/sql_class.h37
-rw-r--r--sql/sql_insert.cc2
-rw-r--r--sql/sql_lex.h36
-rw-r--r--sql/sql_parse.cc172
-rw-r--r--sql/sql_repl.cc17
-rw-r--r--sql/sql_show.cc4
-rw-r--r--sql/sql_yacc.yy277
-rw-r--r--sql/table.h4
-rw-r--r--tests/grant.pl48
-rw-r--r--tests/grant.res61
54 files changed, 1033 insertions, 742 deletions
diff --git a/Docs/manual.texi b/Docs/manual.texi
index 563b130fc4d..266c245e9e7 100644
--- a/Docs/manual.texi
+++ b/Docs/manual.texi
@@ -8149,6 +8149,29 @@ version 4.0;
@itemize @bullet
@item
+MySQL 4.0 has a lot of new privileges in the @code{mysql.user} table.
+@xref{GRANT}.
+
+To get these new privileges to work, one must run the
+@code{mysql_fix_privilege_tables} scripts. Until this script is run all
+users have the @code{SHOW DATABASES}, @code{CREATE TEMPORARY TABLES},
+and @code{LOCK TABLES} privileges. @code{SUPER} and @code{EXECUTE}
+privileges takes their value from @code{PROCESS}. @code{REPLICATION
+SLAVE} and @code{REPLICATION CLIENT} takes their values from
+@code{FILE}.
+
+If you have any scripts that creates new users, you may want to change
+them to use the new privileges. If you are not using @code{GRANT}
+commands in the scripits, this is a good time to change the scripts...
+
+In 4.0.2 the option @code{--safe-show-database} doesn't do anything and
+should not be used. @xref{Privileges options}.
+
+If you get access denied errors for new users with MySQL 4.0.2, you
+should check if you need some of the new grants that you didn't need
+before. In particular, you will need @code{REPLICATION SLAVE} (instead
+of @code{FILE}) for new slaves.
+@item
@code{DOUBLE} and @code{FLOAT} columns are now honoring the
@code{UNSIGNED} flag on storage (before, @code{UNSIGNED} was ignored for
these columns).
@@ -11886,6 +11909,9 @@ The list of databases is probably different on your machine, but the
privileges. The @code{test} database is often provided as a workspace for
users to try things out.
+Note that you may not see all databases if you don't have the @code{SHOW
+DATABASES} privilege. @xref{GRANT}.
+
If the @code{test} database exists, try to access it:
@example
@@ -14336,8 +14362,9 @@ freeing. As this checking is very slow, you can avoid this, when you don't
need memory checking, by using this option.
@item --skip-show-database
-Don't allow 'SHOW DATABASE' commands, unless the user has @strong{process}
-privilege.
+Don't allow 'SHOW DATABASE' commands, unless the user has the
+@strong{SHOW DATABASE} privilege. In 4.0.2 this command should not be
+need anymore.
@item --skip-stack-trace
Don't write stack traces. This option is useful when you are running
@@ -15112,9 +15139,10 @@ If one uses @code{--local-infile=0} then one can't use @code{LOAD DATA LOCAL
INFILE}.
@item --safe-show-database
-With this option,
-@code{SHOW DATABASES} returns only those databases for which the user has
-some kind of privilege.
+With this option, @code{SHOW DATABASES} returns only those databases for
+which the user has some kind of privilege. In 4.0.2 this command doesn't
+do anything (the option is enabled by default) as we now have the
+@code{SHOWS DATABASES} privilege. @xref{GRANT}.
@item --safe-user-create
If this is enabled, an user can't create new users with the @code{GRANT}
@@ -15433,26 +15461,33 @@ MySQL server reads the contents of these tables when it starts up
and under the circumstances indicated in @ref{Privilege changes}.
The names used in this manual to refer to the privileges provided by
-MySQL are shown here, along with the table column name associated
+MySQL 4.0.2 are shown here, along with the table column name associated
with each privilege in the grant tables and the context in which the
privilege applies:
@multitable @columnfractions .15 .20 .35
@item @strong{Privilege} @tab @strong{Column} @tab @strong{Context}
-@item @strong{select} @tab @code{Select_priv} @tab tables
-@item @strong{insert} @tab @code{Insert_priv} @tab tables
-@item @strong{update} @tab @code{Update_priv} @tab tables
+@item @strong{alter} @tab @code{Alter_priv} @tab tables
@item @strong{delete} @tab @code{Delete_priv} @tab tables
@item @strong{index} @tab @code{Index_priv} @tab tables
-@item @strong{alter} @tab @code{Alter_priv} @tab tables
+@item @strong{insert} @tab @code{Insert_priv} @tab tables
+@item @strong{select} @tab @code{Select_priv} @tab tables
+@item @strong{update} @tab @code{Update_priv} @tab tables
@item @strong{create} @tab @code{Create_priv} @tab databases, tables, or indexes
@item @strong{drop} @tab @code{Drop_priv} @tab databases or tables
@item @strong{grant} @tab @code{Grant_priv} @tab databases or tables
@item @strong{references} @tab @code{References_priv} @tab databases or tables
+@item @strong{create temporary tables} @tab @code{create_tmp_table_priv} @tab server administration
+@item @strong{execute} @tab @code{execute_priv} @tab server administration
+@item @strong{file} @tab @code{File_priv} @tab file access on server
+@item @strong{lock tables} @tab @code{Lock_tables_priv} @tab server administration
+@item @strong{process} @tab @code{Process_priv} @tab server administration
@item @strong{reload} @tab @code{Reload_priv} @tab server administration
+@item @strong{replication client} @tab @code{Repl_client_priv} @tab server administration
+@item @strong{replication slave} @tab @code{Repl_slave_priv} @tab server administration
+@item @strong{show databases} @tab @code{Show_db_priv} @tab server administration
@item @strong{shutdown} @tab @code{Shutdown_priv} @tab server administration
-@item @strong{process} @tab @code{Process_priv} @tab server administration
-@item @strong{file} @tab @code{File_priv} @tab file access on server
+@item @strong{super} @tab @code{Super_priv} @tab server administration
@end multitable
The @strong{select}, @strong{insert}, @strong{update}, and @strong{delete}
@@ -15500,7 +15535,8 @@ execute:
@code{flush-privileges}, @code{flush-hosts}, @code{flush-logs}, and
@code{flush-tables}
@item @strong{shutdown} @tab @code{shutdown}
-@item @strong{process} @tab @code{processlist}, @code{kill}
+@item @strong{process} @tab @code{processlist}
+@item @strong{super} @tab @code{kill}
@end multitable
The @code{reload} command tells the server to re-read the grant tables. The
@@ -15514,10 +15550,10 @@ than @code{refresh}.
The @code{shutdown} command shuts down the server.
The @code{processlist} command displays information about the threads
-executing within the server. The @code{kill} command kills server threads.
-You can always display or kill your own threads, but you need the
-@strong{process} privilege to display or kill threads initiated by other
-users. @xref{KILL}.
+executing within the server. The @code{kill} command kills server
+threads. You can always display or kill your own threads, but you need
+the @strong{PROCESS} privilege to display and @code{SUPER} privilege to
+kill threads initiated by other users. @xref{KILL}.
It is a good idea in general to grant privileges only to those users who need
them, but you should exercise particular caution in granting certain
@@ -16465,17 +16501,40 @@ For examples of how @code{GRANT} works, see @ref{Adding users}.
For the @code{GRANT} and @code{REVOKE} statements, @code{priv_type} may be
specified as any of the following:
-@example
-ALL PRIVILEGES FILE RELOAD
-ALTER INDEX SELECT
-CREATE INSERT SHUTDOWN
-DELETE PROCESS UPDATE
-DROP REFERENCES USAGE
-@end example
+@multitable @columnfractions .30 .70
+@item @code{ALL [PRIVILEGES]} @tab Sets all simple privileges except @code{WITH GRANT OPTION}
+@item @code{ALTER} @tab Allows usage of @code{ALTER TABLE}
+@item @code{CREATE} @tab Allows usage of @code{CREATE TABLE}
+@item @code{CREATE TEMPORARY TABLE} @tab Allows usage of @code{CREATE TEMPORARY TABLE}
+@item @code{DELETE} @tab Allows usage of @code{DELETE}
+@item @code{DROP} @tab Allows usage of @code{DROP TABLE}.
+@item @code{EXECUTE} @tab Allows the user to run stored procedures (for MySQL 5.0)
+@item @code{FILE} @tab Allows usage of @code{SELECT ... INTO OUTFILE} and @code{LOAD DATA INFILE}.
+@item @code{INDEX} @tab Allows usage of @code{CREATE INDEX} and @code{DROP INDEX}
+@item @code{INSERT} @tab Allows usage of @code{INSERT}
+@item @code{LOCK TABLES} @tab Allows usage of @code{LOCK TABLES} on tables for which on has the @code{SELECT} privilege.
+@item @code{PROCESS} @tab Allows usage of @code{SHOW FULL PROCESSLIST}
+@item @code{REFERENCES} @tab For the future
+@item @code{RELOAD} @tab Allows usage of @code{FLUSH}
+@item @code{REPLICATION CLIENT} @tab Gives the right to the user to ask where the slaves/masters are.
+@item @code{REPLICATION SLAVE} @tab Needed for the replication slaves (to read binlogs from master).
+@item @code{SELECT} @tab Allows usage of @code{SELECT}
+@item @code{SHOW DATABASES} @tab @code{SHOW DATABASES} shows all databases.
+@item @code{SHUTDOWN} @tab Allows usage of @code{mysqladmin shutdown}
+@item @code{SUPER} @tab Allows one connect (once) even if max_connections is reached and execute commands @code{CHANGE MASTER}, @code{KILL thread}, @code{mysqladmin debug}, @code{PURGE MASTER LOGS} and @code{SET GLOBAL}
+@item @code{UPDATE} @tab Allows usage of @code{UPDATE}
+@item @code{USAGE} @tab Synonym for ``no privileges.''
+@end multitable
-@code{ALL} is a synonym for @code{ALL PRIVILEGES}. @code{REFERENCES} is not
-yet implemented. @code{USAGE} is currently a synonym for ``no privileges.''
-It can be used when you want to create a user that has no privileges.
+@code{USAGE} can be used when you want to create a user that has no privileges.
+
+The privileges @code{CREATE TEMPORARY TABLE}, @code{EXECUTE},
+@code{LOCK TABLES}, @code{REPLICATION ...}, @code{SHOW DATABASES} and
+@code{SUPER} are new for MySQL 4.0.2. To use these, after upgrading to
+4.0.2, one has to run the @code{mysql_fix_privilege_tables} script.
+
+In older MySQL versions, the @code{PROCESS} privilege gave the same rights
+as the new @code{SUPER} privilege.
To revoke the @strong{grant} privilege from a user, use a @code{priv_type}
value of @code{GRANT OPTION}:
@@ -16591,10 +16650,10 @@ You should be careful to whom you give the @strong{grant} privilege, as two
users with different privileges may be able to join privileges!
@code{MAX_QUERIES_PER_HOUR #}, @code{MAX_UPDATES_PER_HOUR #} and
-@code{MAX_CONNECTIONS_PER_HOUR #} limit the number of
-queries/updates and logins the user can do during one hour.
-If @code{#} is 0 (default), then this means that there is no limitations
-for the user. @xref{User resources}.
+@code{MAX_CONNECTIONS_PER_HOUR #} are new in MySQL 4.0.2. They limit
+the number of queries/updates and logins the user can do during one
+hour. If @code{#} is 0 (default), then this means that there is no
+limitations for the user. @xref{User resources}.
You cannot grant another user a privilege you don't have yourself;
the @strong{grant} privilege allows you to give away only those privileges
@@ -16939,7 +16998,7 @@ earlier in the @code{user} table sort order.
@item admin
A user who can connect from @code{localhost} without a password and who is
-granted the @strong{reload} and @strong{process} administrative privileges.
+granted the @strong{reload} and @strong{PROCESS} administrative privileges.
This allows the user to execute the @code{mysqladmin reload},
@code{mysqladmin refresh}, and @code{mysqladmin flush-*} commands, as well as
@code{mysqladmin processlist} . No database-related privileges are granted.
@@ -19152,7 +19211,8 @@ Each connection to @code{mysqld} runs in a separate thread. You can see
which threads are running with the @code{SHOW PROCESSLIST} command and kill
a thread with the @code{KILL thread_id} command.
-If you have the @strong{process} privilege, you can see and kill all threads.
+If you have the @strong{PROCESS} privilege, you can see all threads.
+If you have the @code{SUPER} privilege you can kill all threads.
Otherwise, you can see and kill only your own threads.
You can also use the @code{mysqladmin processlist} and @code{mysqladmin kill}
@@ -19260,8 +19320,10 @@ mysql> SHOW INDEX FROM mytable FROM mydb;
mysql> SHOW INDEX FROM mydb.mytable;
@end example
-@code{SHOW DATABASES} lists the databases on the MySQL server
-host. You can also get this list using the @code{mysqlshow} command.
+@code{SHOW DATABASES} lists the databases on the MySQL server host. You
+can also get this list using the @code{mysqlshow} command. In MySQL
+4.0.2 you will only see those databases for which you have some kind of
+privilege, if you don't have the global @code{SHOW DATABASES} privilege.
@code{SHOW TABLES} lists the tables in a given database. You can also
get this list using the @code{mysqlshow db_name} command.
@@ -20058,7 +20120,7 @@ Is ON if we only allow local (socket) connections.
@item @code{skip_show_database}
This prevents people from doing @code{SHOW DATABASES} if they don't have
-the @strong{process} privilege. This can improve security if you're
+the @strong{PROCESS} privilege. This can improve security if you're
concerned about people being able to see what databases other users
have. See also @code{safe_show_database}.
@@ -20168,14 +20230,14 @@ subsystem)
@code{SHOW [FULL] PROCESSLIST} shows you which threads are running. You can
also get this information using the @code{mysqladmin processlist}
-command. If you have the @strong{process} privilege, you can see all
+command. If you have the @strong{SUPER} privilege, you can see all
threads. Otherwise, you can see only your own threads. @xref{KILL, ,
@code{KILL}}. If you don't use the @code{FULL} option, then only
the first 100 characters of each query will be shown.
This command is very useful if you get the 'too many connections' error
message and want to find out what's going on. MySQL reserves
-one extra connection for a client with the @strong{process} privilege
+one extra connection for a client with the @strong{SUPER} privilege
to ensure that you should always be able to login and check the system
(assuming you are not giving this privilege to all your users).
@@ -23531,10 +23593,11 @@ do not report bugs until you have verified that the problem is present
in the latest release.
@item
-Set up special a replication user on the master with the @code{FILE}
-privilege and permission to connect from all the slaves. If the user is
-only doing replication (which is recommended), you don't need to grant any
-additional privileges.
+Set up special a replication user on the master with the @code{FILE} (in
+MySQL versions older than 4.0.2) or @code{REPLICATION SLAVE} privilege
+in newer MySQL versions. You must also gived permission to connect from
+all the slaves. If the user is only doing replication (which is
+recommended), you don't need to grant any additional privileges.
For example, to create a user named @code{repl} which can access your
master from any host, you might use this command:
@@ -23749,8 +23812,9 @@ a database that was excluded from replication.
@item
Starting in Version 3.23.16, @code{SET SQL_LOG_BIN = 0} will turn off
replication (binary) logging on the master, and @code{SET SQL_LOG_BIN =
-1} will turn it back on -- you must have the @strong{process} privilege to do
-this.
+1} will turn it back on -- you must have the @strong{SUPER} (in MySQL
+4.0.2 and above) or @strong{PROCESS} (in older MySQL versions) privilege
+to do this.
@item
Starting in Version 3.23.19, you can clean up stale replication leftovers when
something goes wrong and you want a clean start with @code{FLUSH MASTER}
@@ -24088,11 +24152,11 @@ summary of commands:
@tab Stops the slave thread. (Slave)
@item @code{SET SQL_LOG_BIN=0}
- @tab Disables update logging if the user has the @strong{process} privilege.
+@tab Disables update logging if the user has the @strong{SUPER} privilege.
Ignored otherwise. (Master)
@item @code{SET SQL_LOG_BIN=1}
- @tab Re-enables update logging if the user has the @strong{process} privilege.
+ @tab Re-enables update logging if the user has the @strong{SUPER} privilege.
Ignored otherwise. (Master)
@item @code{SET SQL_SLAVE_SKIP_COUNTER=n}
@@ -27599,12 +27663,12 @@ can be restored by using a @code{SQL_SELECT_LIMIT} value of @code{DEFAULT}.
@item SQL_LOG_OFF = 0 | 1
If set to @code{1}, no logging will be done to the standard log for this
-client, if the client has the @strong{process} privilege. This does not
+client, if the client has the @strong{SUPER} privilege. This does not
affect the update log!
@item SQL_LOG_UPDATE = 0 | 1
If set to @code{0}, no logging will be done to the update log for the client,
-if the client has the @strong{process} privilege. This does not affect the
+if the client has the @strong{SUPER} privilege. This does not affect the
standard log!
@item SQL_QUOTE_SHOW_CREATE = 0 | 1
@@ -32935,7 +32999,7 @@ If no @code{key_string} argument is given, @code{DES_DECRYPT()} examines
the first byte of the encrypted string to determine the DES key number
that was used to encrypt the original string, then reads the key
from the @code{des-key-file} to decrypt the message. For this to work
-the user must have the @strong{process} privilege.
+the user must have the @strong{SUPER} privilege.
If you pass this function a @code{key_string} argument, that string
is used as the key for decrypting the message.
@@ -35156,7 +35220,9 @@ you create a table. A temporary table will automatically be deleted if a
connection dies and the name is per connection. This means that two different
connections can both use the same temporary table name without conflicting
with each other or with an existing table of the same name. (The existing table
-is hidden until the temporary table is deleted.)
+is hidden until the temporary table is deleted.). In MySQL 4.0.2 one must
+have the @code{CREATE TEMPORARY TABLE} privilege to be able to create
+temporary tables.
In MySQL Version 3.23 or later, you can use the keywords
@code{IF NOT EXISTS} so that an error does not occur if the table already
@@ -36179,6 +36245,11 @@ are locked by the current thread are automatically unlocked when the
thread issues another @code{LOCK TABLES}, or when the connection to the
server is closed.
+To use @code{LOCK TABLES} in MySQL 4.0.2 you need the global @code{LOCK
+TABLES} privilege and a @code{SELECT} privilege on the involved tables.
+In MySQL 3.23 you need to have @code{SELECT}, @code{INSERT},
+@code{DELETE} and @code{UPDATE} privileges for the tables.
+
The main reasons to use @code{LOCK TABLES} are for emulating transactions
or getting more speed when updating tables. This is explained in more
detail later.
@@ -36315,7 +36386,7 @@ the next transaction.
The default behavior is to set the isolation level for the next (not
started) transaction. If you use the @code{GLOBAL} keyword, the statement
sets the default transaction level globally for all new connections
-created from that point on. You will need the @strong{process}
+created from that point on. You will need the @strong{SUPER}
privilege to do do this. Using the @code{SESSION} keyword sets the
default transaction level for all future transactions performed on the
current connection.
@@ -42266,7 +42337,7 @@ if(mysql_drop_db(&mysql, "my_database"))
@subsubheading Description
Instructs the server to write some debug information to the log. The
-connected user must have the @strong{process} privilege for this to work.
+connected user must have the @strong{SUPER} privilege for this to work.
@subsubheading Return Values
@@ -46405,7 +46476,7 @@ If you need more connections than the default (100), then you should restart
Note that @code{mysqld} actually allows (@code{max_connections}+1)
clients to connect. The last connection is reserved for a user with the
-@strong{process} privilege. By not giving this privilege to normal
+@strong{SUPER} privilege. By not giving this privilege to normal
users (they shouldn't need this), an administrator with this privilege
can log in and use @code{SHOW PROCESSLIST} to find out what could be
wrong. @xref{SHOW}.
@@ -49343,6 +49414,11 @@ Our TODO section contains what we plan to have in 4.0. @xref{TODO MySQL 4.0}.
@itemize @bullet
@item
+Added privileges @code{CREATE TEMPORARY TABLE}, @code{LOCK TABLES},
+@code{REPLICATION CLIENT}, @code{REPLICATION SLAVE}, @code{SHOW
+DATABASES} and @code{SUPER}. To use these, one must run the
+@code{mysql_fix_privilege_tables}.
+@item
Fixed query cache align data bug.
@item
Fixed mutex bug in replication when reading from master fails.
@@ -53424,8 +53500,8 @@ Changed optimiser to make it better at deciding when to do a full join
and when using keys.
@item
You can now use @code{mysqladmin proc} to display information about your own
-threads. Only users with the @strong{process} privilege can get
-information about all threads.
+threads. Only users with the @strong{PROCESS} privilege can get
+information about all threads. (In 4.0.2 one need the @strong{SUPER} privilege for this.)
@item
Added handling of formats @code{YYMMDD}, @code{YYYYMMDD},
@code{YYMMDDHHMMSS} for numbers when using @code{DATETIME} and
diff --git a/include/mysqld_error.h b/include/mysqld_error.h
index 06378fa60c0..fa7ab07b046 100644
--- a/include/mysqld_error.h
+++ b/include/mysqld_error.h
@@ -243,4 +243,5 @@
#define ER_MIXING_NOT_ALLOWED 1224
#define ER_DUP_ARGUMENT 1225
#define ER_USER_LIMIT_REACHED 1226
-#define ER_ERROR_MESSAGES 227
+#define ER_SPECIFIC_ACCESS_DENIED_ERROR 1227
+#define ER_ERROR_MESSAGES 228
diff --git a/mysql-test/install_test_db.sh b/mysql-test/install_test_db.sh
index b105609693c..104242cc3b1 100644
--- a/mysql-test/install_test_db.sh
+++ b/mysql-test/install_test_db.sh
@@ -117,9 +117,9 @@ fi
if test ! -f $mdata/user.frm
then
c_u="$c_u CREATE TABLE user ("
- c_u="$c_u Host char(60) DEFAULT '' NOT NULL,"
- c_u="$c_u User char(16) DEFAULT '' NOT NULL,"
- c_u="$c_u Password char(16) DEFAULT '' NOT NULL,"
+ c_u="$c_u Host char(60) binary DEFAULT '' NOT NULL,"
+ c_u="$c_u User char(16) binary DEFAULT '' NOT NULL,"
+ c_u="$c_u Password char(16) binary DEFAULT '' NOT NULL,"
c_u="$c_u Select_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
c_u="$c_u Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
c_u="$c_u Update_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
@@ -134,20 +134,29 @@ then
c_u="$c_u References_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
c_u="$c_u Index_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
c_u="$c_u Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_u="$c_u ssl_type enum('NONE','ANY', 'X509', 'SPECIFIED') NOT NULL,"
- c_u="$c_u ssl_cipher char(60) NULL,"
- c_u="$c_u x509_issuer blob NULL,"
- c_u="$c_u x509_subject blob NULL,"
+ c_u="$c_u Show_db_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Super_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Execute_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Repl_slave_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Repl_client_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u ssl_type enum('','ANY','X509', 'SPECIFIED') DEFAULT '' NOT NULL,"
+ c_u="$c_u ssl_cipher BLOB NOT NULL,"
+ c_u="$c_u x509_issuer BLOB NOT NULL,"
+ c_u="$c_u x509_subject BLOB NOT NULL,"
+ c_u="$c_u max_questions int(11) unsigned DEFAULT 0 NOT NULL,"
+ c_u="$c_u max_updates int(11) unsigned DEFAULT 0 NOT NULL,"
+ c_u="$c_u max_connections int(11) unsigned DEFAULT 0 NOT NULL,"
c_u="$c_u PRIMARY KEY Host (Host,User)"
c_u="$c_u )"
c_u="$c_u comment='Users and global privileges';"
- i_u="INSERT INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','none',NULL,NULL,NULL);
- INSERT INTO user VALUES ('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','none',NULL,NULL,NULL);
- REPLACE INTO user VALUES ('127.0.0.1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','none',NULL,NULL,NULL);
-
- INSERT INTO user VALUES ('localhost','','','N','N','N','N','N','N','N','N','N','N','N','N','N','N','none',NULL,NULL,NULL);
- INSERT INTO user VALUES ('$hostname','','','N','N','N','N','N','N','N','N','N','N','N','N','N','N','none',NULL,NULL,NULL);"
+ i_u="INSERT INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
+ INSERT INTO user VALUES ('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
+ REPLACE INTO user VALUES ('127.0.0.1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
+ INSERT INTO user (host,user) values ('localhost','');
+ INSERT INTO user (host,user) values ('$hostname','');"
fi
if test ! -f $mdata/func.frm
diff --git a/mysql-test/r/grant_cache.result b/mysql-test/r/grant_cache.result
index d236c26d71a..3892765f587 100644
--- a/mysql-test/r/grant_cache.result
+++ b/mysql-test/r/grant_cache.result
@@ -104,11 +104,11 @@ a
1
2
select c from t1;
-select command denied to user: 'mysqltest_3@localhost' for column 'c' in table 't1'
+SELECT command denied to user: 'mysqltest_3@localhost' for column 'c' in table 't1'
select * from t2;
select command denied to user: 'mysqltest_3@localhost' for table 't2'
select mysqltest.t1.c from test.t1,mysqltest.t1;
-select command denied to user: 'mysqltest_3@localhost' for column 'c' in table 't1'
+SELECT command denied to user: 'mysqltest_3@localhost' for column 'c' in table 't1'
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 6
diff --git a/mysql-test/r/rpl000017.result b/mysql-test/r/rpl000017.result
index e2c3c089378..bac0573165d 100644
--- a/mysql-test/r/rpl000017.result
+++ b/mysql-test/r/rpl000017.result
@@ -1,6 +1,6 @@
reset master;
-grant file on *.* to replicate@localhost identified by 'aaaaaaaaaaaaaaab';
-grant file on *.* to replicate@127.0.0.1 identified by 'aaaaaaaaaaaaaaab';
+grant replication slave on *.* to replicate@localhost identified by 'aaaaaaaaaaaaaaab';
+grant replication slave on *.* to replicate@127.0.0.1 identified by 'aaaaaaaaaaaaaaab';
slave start;
drop table if exists t1;
create table t1(n int);
diff --git a/mysql-test/t/rpl000017.test b/mysql-test/t/rpl000017.test
index 011b6507e49..f346ca39ca0 100644
--- a/mysql-test/t/rpl000017.test
+++ b/mysql-test/t/rpl000017.test
@@ -2,8 +2,8 @@ connect (master,localhost,root,,test,0,master.sock);
connect (slave,localhost,root,,test,0,slave.sock);
connection master;
reset master;
-grant file on *.* to replicate@localhost identified by 'aaaaaaaaaaaaaaab';
-grant file on *.* to replicate@127.0.0.1 identified by 'aaaaaaaaaaaaaaab';
+grant replication slave on *.* to replicate@localhost identified by 'aaaaaaaaaaaaaaab';
+grant replication slave on *.* to replicate@127.0.0.1 identified by 'aaaaaaaaaaaaaaab';
connection slave;
slave start;
connection master;
diff --git a/mysys/safemalloc.c b/mysys/safemalloc.c
index 961d49f042e..768edc9f11e 100644
--- a/mysys/safemalloc.c
+++ b/mysys/safemalloc.c
@@ -374,19 +374,16 @@ static int check_ptr(const char *where, byte *ptr, const char *sFile,
return 0;
}
-#ifdef THREAD
+
+#if !defined(PEDANTIC_SAFEMALLOC) && defined(THREAD)
static int legal_leak(struct remember* pPtr)
{
/* TODO: This code needs to be made more general */
return (pthread_self() == pPtr->thread_id || main_th == pPtr->thread_id ||
shutdown_th == pPtr->thread_id || signal_th == pPtr->thread_id);
}
-#else
-static int legal_leak(struct remember* pPtr)
-{
- return 1;
-}
-#endif
+#endif /* THREAD */
+
/*
TERMINATE(FILE *file)
diff --git a/scripts/mysql_fix_privilege_tables.sh b/scripts/mysql_fix_privilege_tables.sh
index 7226840b475..ead0350093a 100644
--- a/scripts/mysql_fix_privilege_tables.sh
+++ b/scripts/mysql_fix_privilege_tables.sh
@@ -12,6 +12,17 @@ echo "and give the MySQL root user password as a argument!"
root_password="$1"
host="localhost"
+echo "Converting all privilege tables to MyISAM format"
+@bindir@/mysql -f --user=root --password="$root_password" --host="$host" mysql <<END_OF_DATA
+ALTER TABLE user type=MyISAM;
+ALTER TABLE db type=MyISAM;
+ALTER TABLE host type=MyISAM;
+ALTER TABLE func type=MyISAM;
+ALTER TABLE columns_priv type=MyISAM;
+ALTER TABLE tables_priv type=MyISAM;
+END_OF_DATA
+
+
# Fix old password format, add File_priv and func table
echo ""
echo "If your tables are already up to date or partially up to date you will"
@@ -56,10 +67,18 @@ END_OF_DATA
echo ""
fi
+#
+# The second alter changes ssl_type to new 4.0.2 format
+
echo "Adding columns needed by GRANT .. REQUIRE (openssl)"
echo "You can ignore any Duplicate column errors"
-@bindir@/mysql --user=root --password="$root_password" --host="$host" mysql <<END_OF_DATA
-ALTER TABLE user ADD ssl_type enum('NONE','ANY','X509', 'SPECIFIED') DEFAULT 'NONE' NOT NULL, ADD ssl_cipher BLOB NOT NULL, ADD x509_issuer BLOB NOT NULL, ADD x509_subject BLOB NOT NULL
+@bindir@/mysql -f --user=root --password="$root_password" --host="$host" mysql <<END_OF_DATA
+ALTER TABLE user
+ADD ssl_type enum('','ANY','X509', 'SPECIFIED') NOT NULL,
+ADD ssl_cipher BLOB NOT NULL,
+ADD x509_issuer BLOB NOT NULL,
+ADD x509_subject BLOB NOT NULL;
+ALTER TABLE user MODIFY ssl_type enum('','ANY','X509', 'SPECIFIED') NOT NULL;
END_OF_DATA
echo ""
@@ -98,7 +117,7 @@ END_OF_DATA
#
echo "Changing name of columns_priv.Type -> columns_priv.Column_priv"
-echo "You can ignore any errors from this"
+echo "You can ignore any Unknown column errors from this"
@bindir@/mysql -f --user=root --password="$root_password" --host="$host" mysql <<END_OF_DATA
ALTER TABLE columns_priv change Type Column_priv set('Select','Insert','Update','References') DEFAULT '' NOT NULL;
@@ -117,12 +136,41 @@ alter table func add type enum ('function','aggregate') NOT NULL;
EOF
echo ""
-echo "Converting all privilege tables to MyISAM format"
-@bindir@/mysql -f --user=root --password="$root_password" --host="$host" mysql <<END_OF_DATA
-ALTER TABLE user type=MyISAM;
-ALTER TABLE db type=MyISAM;
-ALTER TABLE host type=MyISAM;
-ALTER TABLE func type=MyISAM;
-ALTER TABLE columns_priv type=MyISAM;
-ALTER TABLE tables_priv type=MyISAM;
+#
+# Change the user table to MySQL 4.0 format
+#
+
+echo "Adding new fields used by MySQL 4.02 to the privilege tables"
+echo "You can ignore any Duplicate column errors"
+
+@bindir@/mysql --user=root --password="$root_password" --host="$host" mysql <<END_OF_DATA
+alter table user
+add Show_db_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER alter_priv,
+add Super_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Show_db_priv,
+add Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Super_priv,
+add Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Create_tmp_table_priv,
+add Execute_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Lock_tables_priv,
+add Repl_slave_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Execute_priv,
+add Repl_client_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Repl_slave_priv
+END_OF_DATA
+
+if test $? -eq "0"
+then
+ # Convert privileges so that users have similar privileges as before
+ echo ""
+ echo "Updating new privileges in MySQL 4.0.2 from old ones"
+ @bindir@/mysql --user=root --password="$root_password" --host="$host" mysql <<END_OF_DATA
+ update user set show_db_priv= select_priv, super_priv=process_priv, execute_priv=process_priv, create_tmp_table_priv='Y', Lock_tables_priv='Y', Repl_slave_priv=file_priv, Repl_client_priv=file_priv
+END_OF_DATA
+ echo ""
+fi
+
+# Add fields that can be used to limit number of questions and connections
+# for some users.
+
+@bindir@/mysql -f --user=root --password="$root_password" --host="$host" mysql <<END_OF_DATA
+alter table user
+add max_questions int(11) NOT NULL AFTER x509_subject,
+add max_updates int(11) unsigned NOT NULL AFTER max_questions,
+add max_connections int(11) unsigned NOT NULL AFTER max_updates;
END_OF_DATA
diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh
index 473b182de25..6ac54256124 100644
--- a/scripts/mysql_install_db.sh
+++ b/scripts/mysql_install_db.sh
@@ -1,5 +1,5 @@
#!/bin/sh
-# Copyright (C) 1997, 1998, 1999 TCX DataKonsult AB & Monty Program KB & Detron HB
+# Copyright (C) 2002 MySQL AB
# For a more info consult the file COPYRIGHT distributed with this file.
# This scripts creates the privilege tables db, host, user, tables_priv,
@@ -224,7 +224,14 @@ then
c_u="$c_u References_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
c_u="$c_u Index_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
c_u="$c_u Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_u="$c_u ssl_type enum('NONE','ANY','X509', 'SPECIFIED') DEFAULT 'NONE' NOT NULL,"
+ c_u="$c_u Show_db_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Super_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Execute_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Repl_slave_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Repl_client_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u ssl_type enum('','ANY','X509', 'SPECIFIED') DEFAULT '' NOT NULL,"
c_u="$c_u ssl_cipher BLOB NOT NULL,"
c_u="$c_u x509_issuer BLOB NOT NULL,"
c_u="$c_u x509_subject BLOB NOT NULL,"
@@ -235,14 +242,14 @@ then
c_u="$c_u )"
c_u="$c_u comment='Users and global privileges';"
- i_u="INSERT INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','NONE','','','',0,0,0);
- INSERT INTO user VALUES ('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','NONE','','','',0,0,0);
+ i_u="INSERT INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
+ INSERT INTO user VALUES ('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
- REPLACE INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','NONE','','','',0,0,0);
- REPLACE INTO user VALUES ('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','NONE','','','',0,0,0);
+ REPLACE INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
+ REPLACE INTO user VALUES ('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
- INSERT INTO user VALUES ('localhost','','','N','N','N','N','N','N','N','N','N','N','N','N','N','N','NONE','','','',0,0,0);
- INSERT INTO user VALUES ('$hostname','','','N','N','N','N','N','N','N','N','N','N','N','N','N','N','NONE','','','',0,0,0);"
+ INSERT INTO user (host,user) values ('localhost','');
+ INSERT INTO user (host,user) values ('$hostname','');"
fi
if test ! -f $mdata/func.frm
@@ -343,7 +350,7 @@ then
echo "cd @prefix@ ; $bindir/mysqld_safe &"
echo
echo "You can test the MySQL daemon with the benchmarks in the 'sql-bench' directory:"
- echo "cd sql-bench ; run-all-tests"
+ echo "cd sql-bench ; perl run-all-tests"
echo
fi
echo "Please report any problems with the @scriptdir@/mysqlbug script!"
diff --git a/scripts/mysql_new_fix_privilege_tables.sh b/scripts/mysql_new_fix_privilege_tables.sh
deleted file mode 100644
index ce10ed0b412..00000000000
--- a/scripts/mysql_new_fix_privilege_tables.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/sh
-
-echo "This scripts updates the mysql.user, mysql.db, mysql.host and the"
-echo "mysql.func table to MySQL 3.22.14 and above."
-echo ""
-echo "This is needed if you want to use the new GRANT functions,"
-echo "CREATE AGGREAGATE FUNCTION or want to use the more secure passwords in 3.23"
-echo ""
-echo "If you get Access denied errors, you should run this script again"
-echo "and give the MySQL root user password as a argument!"
-
-root_password="$1"
-host="localhost"
-
-# Fix old password format, add File_priv and func table
-echo ""
-echo "If your tables are already up to date or partially up to date you will"
-echo "get some warnings about 'Duplicated column name'. You can safely ignore these!"
-
-# Add fields that can be used to limit number of questions and connections
-# for some users.
-
-@bindir@/mysql -f --user=root --password="$root_password" --host="$host" mysql <<END_OF_DATA
-alter table user add max_questions int(11) NOT NULL, add max_updates int(11) unsigned NOT NULL, add max_connections int(11) unsigned NOT NULL;
-END_OF_DATA
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};
diff --git a/tests/grant.pl b/tests/grant.pl
index 4e627737174..6da4326d465 100644
--- a/tests/grant.pl
+++ b/tests/grant.pl
@@ -36,7 +36,8 @@ $|=1;
$tables_cols="Host, Db, User, Table_name, Grantor, Table_priv, Column_priv";
$columns_cols="Host, Db, User, Table_name, Column_name, Column_priv";
-$tmp_table="/tmp/grant-$$.test";
+$tmp_table="/tmp/mysql-grant.test"; # Can't use $$ as we are logging result
+unlink($tmp_table);
#
# clear grant tables
@@ -74,6 +75,7 @@ user_connect(0);
user_query("select * from mysql.user where user = '$opt_user'");
user_query("select * from mysql.db where user = '$opt_user'");
safe_query("grant select on *.* to $user,$user");
+safe_query("show grants for $user");
# The following should fail
user_query("insert into mysql.user (host,user) values ('error','$opt_user')",1);
@@ -384,7 +386,9 @@ safe_query("select $columns_cols from mysql.columns_priv where user = '$opt_user
# Clear up privileges to make future tests easier
safe_query("delete from user where user='$opt_user'");
+safe_query("delete from db where user='$opt_user'");
safe_query("flush privileges");
+safe_query("show grants for $user",1);
#
# Test IDENTIFIED BY
@@ -394,7 +398,9 @@ safe_query("grant ALL PRIVILEGES on $opt_database.test to $user identified by 'd
user_connect(0,"dummy");
safe_query("grant SELECT on $opt_database.* to $user identified by ''");
user_connect(0);
-safe_query("revoke SELECT on $opt_database.* from $user identified by ''");
+safe_query("revoke ALL PRIVILEGES on $opt_database.test from $user identified by ''");
+safe_query("revoke ALL PRIVILEGES on $opt_database.* from $user identified by ''");
+safe_query("show grants for $user");
#
# Test bug reported in SELECT INTO OUTFILE
@@ -407,7 +413,7 @@ safe_query("insert into $opt_database.test3 values (1)");
user_connect(0);
user_query("select * into outfile '$tmp_table' from $opt_database.test3");
safe_query("revoke SELECT on $opt_database.test3 from $user");
-safe_query("revoke FILE from *.* from $user");
+safe_query("revoke FILE on *.* from $user");
safe_query("drop table $opt_database.test3");
#
@@ -415,24 +421,36 @@ safe_query("drop table $opt_database.test3");
#
safe_query("create table $opt_database.test3 (a int)");
+user_connect(1);
+safe_query("grant INSERT on $opt_database.test3 to $user");
user_connect(0);
user_query("select * into outfile '$tmp_table' from $opt_database.test3",1);
safe_query("grant SELECT on $opt_database.test3 to $user");
user_connect(0);
-user_query("LOCK TABLES $opt_database.test3",1);
-safe_query("grant INSERT,UPDATE,DELETE on $opt_database.test3 to $user");
+user_query("LOCK TABLES $opt_database.test3 READ",1);
+safe_query("grant LOCK TABLES on *.* to $user");
+safe_query("show grants for $user");
+safe_query("select * from mysql.user where user='$opt_user'");
user_connect(0);
-user_query("LOCK TABLES $opt_database.test3");
-safe_query("revoke SELECT, INSERT,UPDATE,DELETE on $opt_database.test3 from $user");
-safe_query("grant SELECT,INSERT,UPDATE,DELETE on $opt_database.* to $user");
-user_connect(0);
-user_query("LOCK TABLES $opt_database.test3");
-safe_query("revoke SELECT, INSERT,UPDATE,DELETE on $opt_database.* from $user");
-safe_query("grant SELECT,INSERT,UPDATE,DELETE on *.* to $user");
-user_connect(0);
-user_query("LOCK TABLES $opt_database.test3");
+user_query("LOCK TABLES $opt_database.test3 READ");
user_query("UNLOCK TABLES");
-safe_query("revoke SELECT, INSERT,UPDATE,DELETE on *.* from $user");
+safe_query("revoke SELECT,INSERT,UPDATE,DELETE on $opt_database.test3 from $user");
+user_connect(1);
+safe_query("revoke LOCK TABLES on *.* from $user");
+safe_query("drop table $opt_database.test3");
+
+#
+# test new privileges in 4.0.2
+#
+
+safe_query("show grants for $user");
+safe_query("grant all on *.* to $user WITH MAX_QUERIES_PER_HOUR 1 MAX_UPDATES_PER_HOUR 2 MAX_CONNECTIONS_PER_HOUR 3");
+safe_query("show grants for $user");
+safe_query("revoke LOCK TABLES on *.* from $user");
+safe_query("flush privileges");
+safe_query("show grants for $user");
+safe_query("revoke ALL PRIVILEGES on *.* from $user");
+safe_query("show grants for $user");
#
# Clean up things
diff --git a/tests/grant.res b/tests/grant.res
index 0c5fd220868..b54fec94514 100644
--- a/tests/grant.res
+++ b/tests/grant.res
@@ -19,10 +19,13 @@ Access denied for user: 'grant_user@localhost' (Using password: NO)
set password FOR grant_user=''
Connecting grant_user
select * from mysql.user where user = 'grant_user'
-localhost grant_user Y N N N N N N N N N N N N N NONE
+localhost grant_user Y N N N N N N N N N N N N N N N N N N N N 0 0 0
select * from mysql.db where user = 'grant_user'
grant select on *.* to grant_user@localhost,grant_user@localhost
+show grants for grant_user@localhost
+GRANT SELECT ON *.* TO 'grant_user'@'localhost'
+
insert into mysql.user (host,user) values ('error','grant_user')
Error in execute: Access denied for user: 'grant_user@localhost' to database 'mysql'
update mysql.user set host='error' WHERE user='grant_user'
@@ -93,7 +96,7 @@ delete from user where user='grant_user'
flush privileges
grant select on grant_test.* to grant_user@localhost
select * from mysql.user where user = 'grant_user'
-localhost grant_user N N N N N N N N N N N N N N NONE
+localhost grant_user N N N N N N N N N N N N N N N N N N N N N 0 0 0
select * from mysql.db where user = 'grant_user'
localhost grant_test grant_user Y N N N N N N N N N
@@ -152,7 +155,7 @@ insert into mysql.user (host,user) values ('error','grant_user',0)
Error in execute: Access denied for user: 'grant_user@localhost' to database 'mysql'
revoke ALL PRIVILEGES on grant_test.* from grant_user@localhost
select * from mysql.user where user = 'grant_user'
-localhost grant_user N N N N N N N N N N N N N N NONE
+localhost grant_user N N N N N N N N N N N N N N N N N N N N N 0 0 0
select * from mysql.db where user = 'grant_user'
Connecting grant_user
@@ -432,18 +435,66 @@ localhost grant_test grant_user N Y N N N N N N N N
select Host, Db, User, Table_name, Grantor, Table_priv, Column_priv from mysql.tables_priv where user = 'grant_user'
select Host, Db, User, Table_name, Column_name, Column_priv from mysql.columns_priv where user = 'grant_user'
delete from user where user='grant_user'
+delete from db where user='grant_user'
flush privileges
+show grants for grant_user@localhost
+Error in execute: There is no such grant defined for user 'grant_user' on host 'localhost'
grant ALL PRIVILEGES on grant_test.test to grant_user@localhost identified by 'dummy', grant_user@127.0.0.1 identified by 'dummy2'
Connecting grant_user
grant SELECT on grant_test.* to grant_user@localhost identified by ''
Connecting grant_user
-revoke SELECT on grant_test.* from grant_user@localhost identified by ''
+revoke ALL PRIVILEGES on grant_test.test from grant_user@localhost identified by ''
+revoke ALL PRIVILEGES on grant_test.* from grant_user@localhost identified by ''
+show grants for grant_user@localhost
create table grant_test.test3 (a int)
grant SELECT on grant_test.test3 to grant_user@localhost
grant FILE on *.* to grant_user@localhost
insert into grant_test.test3 values (1)
Connecting grant_user
-select * into outfile '/tmp/grant-11047.test' from grant_test.test3
+select * into outfile '/tmp/mysql-grant.test' from grant_test.test3
+revoke SELECT on grant_test.test3 from grant_user@localhost
+revoke FILE on *.* from grant_user@localhost
+drop table grant_test.test3
+create table grant_test.test3 (a int)
+Connecting grant_user
+Access denied for user: 'grant_user@localhost' to database 'grant_test'
+grant INSERT on grant_test.test3 to grant_user@localhost
+Connecting grant_user
+select * into outfile '/tmp/mysql-grant.test' from grant_test.test3
+Error in execute: Access denied for user: 'grant_user@localhost' (Using password: NO)
+grant SELECT on grant_test.test3 to grant_user@localhost
+Connecting grant_user
+LOCK TABLES grant_test.test3 READ
+Error in execute: Access denied for user: 'grant_user@localhost' (Using password: NO)
+grant LOCK TABLES on *.* to grant_user@localhost
+show grants for grant_user@localhost
+GRANT LOCK TABLES ON *.* TO 'grant_user'@'localhost'
+GRANT SELECT, INSERT ON grant_test.test3 TO 'grant_user'@'localhost'
+
+select * from mysql.user where user='grant_user'
+127.0.0.1 grant_user 7f70e8b858ee6782 N N N N N N N N N N N N N N N N N N N N N 0 0 0
+localhost grant_user N N N N N N N N N N N N N N N N N Y N N N 0 0 0
+
+Connecting grant_user
+LOCK TABLES grant_test.test3 READ
+UNLOCK TABLES
+revoke SELECT,INSERT,UPDATE,DELETE on grant_test.test3 from grant_user@localhost
+Connecting grant_user
+Access denied for user: 'grant_user@localhost' to database 'grant_test'
+revoke LOCK TABLES on *.* from grant_user@localhost
+drop table grant_test.test3
+show grants for grant_user@localhost
+grant all on *.* to grant_user@localhost WITH MAX_QUERIES_PER_HOUR 1 MAX_UPDATES_PER_HOUR 2 MAX_CONNECTIONS_PER_HOUR 3
+show grants for grant_user@localhost
+GRANT ALL PRIVILEGES ON *.* TO 'grant_user'@'localhost' WITH MAX_QUERIES_PER_HOUR 1 MAX_UPDATES_PER_HOUR 2 MAX_CONNECTIONS_PER_HOUR 3
+
+revoke LOCK TABLES on *.* from grant_user@localhost
+flush privileges
+show grants for grant_user@localhost
+GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'grant_user'@'localhost' WITH MAX_QUERIES_PER_HOUR 1 MAX_UPDATES_PER_HOUR 2 MAX_CONNECTIONS_PER_HOUR 3
+
+revoke ALL PRIVILEGES on *.* from grant_user@localhost
+show grants for grant_user@localhost
drop database grant_test
delete from user where user='grant_user'
delete from db where user='grant_user'