Merge work:/home/bk/mysql-4.0 into mashka.mysql.fi:/my/mysql-4.0

Docs/manual.texi:
  Auto merged
sql/sql_parse.cc:
  Auto merged
This commit is contained in:
unknown 2002-06-12 15:08:22 +03:00
commit e91d0d898b
54 changed files with 1035 additions and 744 deletions

View file

@ -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{reload} @tab @code{Reload_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{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{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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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;

View file

@ -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)

View file

@ -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

View file

@ -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!"

View file

@ -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

View file

@ -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;

View file

@ -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];

View file

@ -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},

View file

@ -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;

View file

@ -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);

View file

@ -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,

View file

@ -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))))

View file

@ -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",

View file

@ -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",

View file

@ -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",

View file

@ -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",

View file

@ -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",

View file

@ -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",

View file

@ -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",

View file

@ -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",

View file

@ -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",

View file

@ -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",

View file

@ -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",

View file

@ -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",

View file

@ -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",

View file

@ -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",

View file

@ -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",

View file

@ -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",

View file

@ -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",

View file

@ -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",

View file

@ -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",

View file

@ -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",

View file

@ -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",

View file

@ -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",

View file

@ -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

View file

@ -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)
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_QUERIES_PER_HOUR ",27);
p=int2str(acl_user->user_resource.questions,buff,10);
global.append(buff,p-buff);
}
if (acl_user->user_resource.updates)
{
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__

View file

@ -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);

View file

@ -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>

View file

@ -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,

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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,
@ -2019,13 +2035,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);
@ -2038,17 +2054,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
@ -2220,8 +2229,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;
@ -2293,8 +2301,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
{
@ -2363,7 +2373,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);
@ -2465,20 +2475,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
@ -2488,13 +2501,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)
@ -2504,11 +2517,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,
@ -2523,32 +2536,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)
{
@ -3386,7 +3408,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*/);

View file

@ -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;

View file

@ -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(),

View file

@ -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_SMALL_RESULT
%token SQL_BIG_RESULT
%token SQL_BUFFER_RESULT
%token SQL_WARNINGS
%token SQL_AUTO_IS_NULL
%token SQL_SAFE_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_WARNINGS
%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;
};

View file

@ -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};

View file

@ -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

View file

@ -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'