GRANT
and REVOKE
Syntax
GRANT
and REVOKE
SyntaxGRANT priv_type [(column_list)] [, priv_type [(column_list)] ...] ON {tbl_name | * | *.* | db_name.*} TO user_name [IDENTIFIED BY [PASSWORD] 'password'] [, user_name [IDENTIFIED BY [PASSWORD] 'password'] ...] [REQUIRE NONE | [{SSL| X509}] [CIPHER cipher [AND]] [ISSUER issuer [AND]] [SUBJECT subject]] [WITH [GRANT OPTION | MAX_QUERIES_PER_HOUR # | MAX_UPDATES_PER_HOUR # | MAX_CONNECTIONS_PER_HOUR #]] REVOKE priv_type [(column_list)] [, priv_type [(column_list)] ...] ON {tbl_name | * | *.* | db_name.*} FROM user_name [, user_name ...]
GRANT
is implemented in MySQL Version 3.22.11 or later. For
earlier MySQL versions, the GRANT
statement does nothing.
The GRANT
and REVOKE
commands allow system administrators
to create users and grant and revoke rights to MySQL users at
four privilege levels:
mysql.user
table.
REVOKE ALL ON *.*
will revoke only global privileges.
mysql.db
and mysql.host
tables.
REVOKE ALL ON db.*
will revoke only database privileges.
mysql.tables_priv
table.
REVOKE ALL ON db.table
will revoke only table privileges.
mysql.columns_priv
table.
When using REVOKE
you must specify the same columns that were granted.
For the GRANT
and REVOKE
statements, priv_type
may be
specified as any of the following:
ALL [PRIVILEGES] | Sets all simple privileges except WITH GRANT OPTION
|
ALTER | Allows usage of ALTER TABLE
|
CREATE | Allows usage of CREATE TABLE
|
CREATE TEMPORARY TABLES | Allows usage of CREATE TEMPORARY TABLE
|
DELETE | Allows usage of DELETE
|
DROP | Allows usage of DROP TABLE .
|
EXECUTE | Allows the user to run stored procedures (MySQL 5.0) |
FILE | Allows usage of SELECT ... INTO OUTFILE and LOAD DATA INFILE .
|
INDEX | Allows usage of CREATE INDEX and DROP INDEX
|
INSERT | Allows usage of INSERT
|
LOCK TABLES | Allows usage of LOCK TABLES on tables for which one has the SELECT privilege.
|
PROCESS | Allows usage of SHOW FULL PROCESSLIST
|
REFERENCES | For the future |
RELOAD | Allows usage of FLUSH
|
REPLICATION CLIENT | Gives the right to the user to ask where the slaves/masters are. |
REPLICATION SLAVE | Needed for the replication slaves (to read binlogs from master). |
SELECT | Allows usage of SELECT
|
SHOW DATABASES | SHOW DATABASES shows all databases.
|
SHUTDOWN | Allows usage of mysqladmin shutdown
|
SUPER | Allows one connect (once) even if
max_connections is reached and execute commands CHANGE MASTER ,
KILL thread , mysqladmin debug , PURGE MASTER LOGS and SET GLOBAL
|
UPDATE | Allows usage of UPDATE
|
USAGE | Synonym for ``no privileges.'' |
GRANT OPTION | Synonym for WITH GRANT OPTION
|
USAGE
can be used when you want to create a user that has no privileges.
The privileges CREATE TEMPORARY TABLES
, EXECUTE
,
LOCK TABLES
, REPLICATION ...
, SHOW DATABASES
and
SUPER
are new for in version 4.0.2. To use these new privileges
after upgrading to 4.0.2, you have to run the
mysql_fix_privilege_tables
script.
In older MySQL versions, the PROCESS
privilege gives the same
rights as the new SUPER
privilege.
To revoke the GRANT
privilege from a user, use a priv_type
value of GRANT OPTION
:
mysql> REVOKE GRANT OPTION ON ... FROM ...;
The only priv_type
values you can specify for a table are SELECT
,
INSERT
, UPDATE
, DELETE
, CREATE
, DROP
,
GRANT OPTION
, INDEX
, and ALTER
.
The only priv_type
values you can specify for a column (that is, when
you use a column_list
clause) are SELECT
, INSERT
, and
UPDATE
.
MySQL allows you to create database level privileges even if the database doesn't exist, to make it easy to prepare for database usage. Currently MySQL does however not allow one to create table level grants if the table doesn't exist. MySQL will not automatically revoke any privileges even if you drop a table or drop a database.
You can set global privileges by using ON *.*
syntax. You can set
database privileges by using ON db_name.*
syntax. If you specify
ON *
and you have a current database, you will set the privileges for
that database. (Warning: if you specify ON *
and you
don't have a current database, you will affect the global privileges!)
Please note: the `_' and `%' wildcards are allowed when
specifying database names in GRANT
commands. This means that if you
wish to use for instance a `_' character as part of a database name,
you should specify it as `\_' in the GRANT
command, to prevent
the user from being able to access additional databases matching the
wildcard pattern, for example, GRANT ... ON `foo\_bar`.* TO ...
.
In order to accommodate granting rights to users from arbitrary hosts,
MySQL supports specifying the user_name
value in the form
user@host
. If you want to specify a user
string
containing special characters (such as `-'), or a host
string
containing special characters or wildcard characters (such as `%'), you
can quote the user or host name (for example, 'test-user'@'test-hostname'
).
You can specify wildcards in the hostname. For example,
user@'%.loc.gov'
applies to user
for any host in the
loc.gov
domain, and user@'144.155.166.%'
applies to user
for any host in the 144.155.166
class C subnet.
The simple form user
is a synonym for user@"%"
.
MySQL doesn't support wildcards in user names. Anonymous users are
defined by inserting entries with User=''
into the
mysql.user
table or creating an user with an empty name with the
GRANT
command.
Note: if you allow anonymous users to connect to the MySQL
server, you should also grant privileges to all local users as
user@localhost
because otherwise the anonymous user entry for
the local host in the mysql.user
table will be used when the user
tries to log into the MySQL server from the local machine!
You can verify if this applies to you by executing this query:
mysql> SELECT Host,User FROM mysql.user WHERE User='';
For the moment, GRANT
only supports host, table, database, and
column names up to 60 characters long. A user name can be up to 16
characters.
The privileges for a table or column are formed from the
logical OR of the privileges at each of the four privilege
levels. For example, if the mysql.user
table specifies that a
user has a global SELECT
privilege, this can't be denied by an
entry at the database, table, or column level.
The privileges for a column can be calculated as follows:
global privileges OR (database privileges AND host privileges) OR table privileges OR column privileges
In most cases, you grant rights to a user at only one of the privilege levels, so life isn't normally as complicated as above. The details of the privilege-checking procedure are presented in section 4.2 General Security Issues and the MySQL Access Privilege System.
If you grant privileges for a user/hostname combination that does not exist
in the mysql.user
table, an entry is added and remains there until
deleted with a DELETE
command. In other words, GRANT
may
create user
table entries, but REVOKE
will not remove them;
you must do that explicitly using DELETE
.
In MySQL Version 3.22.12 or later,
if a new user is created or if you have global grant privileges, the user's
password will be set to the password specified by the IDENTIFIED BY
clause, if one is given. If the user already had a password, it is replaced
by the new one.
If you don't want to send the password in clear text you can use the
PASSWORD
option followed by a scrambled password from SQL
function PASSWORD()
or the C API function
make_scrambled_password(char *to, const char *password)
.
Warning: if you create a new user but do not specify an
IDENTIFIED BY
clause, the user has no password. This is insecure.
Passwords can also be set with the SET PASSWORD
command.
See section 5.5.6 SET
Syntax.
If you grant privileges for a database, an entry in the mysql.db
table is created if needed. When all privileges for the database have been
removed with REVOKE
, this entry is deleted.
If a user doesn't have any privileges on a table, the table is not displayed
when the user requests a list of tables (for example, with a SHOW TABLES
statement). The same is true for SHOW DATABASES
.
The WITH GRANT OPTION
clause gives the user the ability to give
to other users any privileges the user has at the specified privilege level.
You should be careful to whom you give the GRANT
privilege, as two
users with different privileges may be able to join privileges!
MAX_QUERIES_PER_HOUR #
, MAX_UPDATES_PER_HOUR #
and
MAX_CONNECTIONS_PER_HOUR #
are new in MySQL version 4.0.2.
These options limit the number of queries/updates and logins the user can
do during one hour. If #
is 0 (default), then this means that there
are no limitations for that user. See section 4.3.6 Limiting user resources.
Note: to specify any of these options for an existing user without adding
other additional privileges, use GRANT USAGE ON *.* ... WITH MAX_...
.
You cannot grant another user a privilege you don't have yourself;
the GRANT
privilege allows you to give away only those privileges
you possess.
Be aware that when you grant a user the GRANT
privilege at a
particular privilege level, any privileges the user already possesses (or
is given in the future!) at that level are also grantable by that user.
Suppose you grant a user the INSERT
privilege on a database. If
you then grant the SELECT
privilege on the database and specify
WITH GRANT OPTION
, the user can give away not only the SELECT
privilege, but also INSERT
. If you then grant the UPDATE
privilege to the user on the database, the user can give away the
INSERT
, SELECT
and UPDATE
.
You should not grant ALTER
privileges to a normal user. If you
do that, the user can try to subvert the privilege system by renaming
tables!
Note that if you are using table or column privileges for even one user, the server examines table and column privileges for all users and this will slow down MySQL a bit.
When mysqld
starts, all privileges are read into memory.
Database, table, and column privileges take effect at once, and
user-level privileges take effect the next time the user connects.
Modifications to the grant tables that you perform using GRANT
or
REVOKE
are noticed by the server immediately.
If you modify the grant tables manually (using INSERT
, UPDATE
,
etc.), you should execute a FLUSH PRIVILEGES
statement or run
mysqladmin flush-privileges
to tell the server to reload the grant
tables.
See section 4.3.3 When Privilege Changes Take Effect.
The biggest differences between the SQL standard and MySQL versions of
GRANT
are:
TRIGGER
or UNDER
privileges.
INSERT
privilege on only some of the
columns in a table, you can execute INSERT
statements on the
table; the columns for which you don't have the INSERT
privilege
will be set to their default values. SQL-99 requires you to have the
INSERT
privilege on all columns.
REVOKE
commands or by manipulating the
MySQL grant tables.
For a description of using REQUIRE
, see section 4.3.9 Using Secure Connections.
Posted by Frank Wortner on Saturday February 16 2002, @10:21pm | [Delete] [Edit] |
I had no problems with ld. DEC (Compaq) might
have fixed ld in a patch kit. You might want to
install the latest patch kit for your Digital Unix
(Tru64 Unix) before building MySQL. Patch kits
are available at
<a
href=http://ftp.support.compaq.com/public/unix/>
http://ftp.support.compaq.com/public/unix/</a>
Posted by rochlin on Saturday February 16 2002, @10:21pm | [Delete] [Edit] |
For source installations, these instructions refer to the directory structure presuming "usr/local" was used (default) with configure. But the preceding page's instructions (for compilation/installation) suggest you use:
./configure --prefix=/usr/local/mysql
To be consistent (and this is causing me some hassles with Perl, so it's not purely semantic), the instructions on this page should presume /usr/local/mysql was specified as the installation directory with configure.
Posted by Linda Wright on Saturday February 16 2002, @10:21pm | [Delete] [Edit] |
This is probably the most important and least
appreciated sections of all of the mySQL
documentation for first time mySQL users. IMHO,
reading this page in conjunction with
http://www.mysql.com/doc/P/r/Privileges.html is a
must for anyone planning secure database systems
of any real sophistication.
Posted by Christopher Raymond on Saturday February 16 2002, @10:21pm | [Delete] [Edit] |
I am trying to install MySQL under OS X Public Beta. When I run the mysql_install_db script, I get an error message:
dyld: ./bin/mysqld can't open library: /usr/lib/libpthread.A.dylib (No such file or directory, errno = 2)
Installation of grant tables failed!
I am assuming that the script is looking for a directory that doesn't exist because Apple has a little bit different directory naming structure. Maybe this script needs to be modified for the OS X distribution.
Can anyone help?
Posted by Mark Zieg on Saturday February 16 2002, @10:21pm | [Delete] [Edit] |
It would be nice if there was an option to log connections, but not queries.
Posted by Bennett Haselton on Saturday February 16 2002, @10:21pm | [Delete] [Edit] |
If you're logged on as the mysql root user, without a current database selected, and you try to
grant all privileges to a user with the command:
GRANT ALL PRIVILEGES ON * TO bhaselto
then the RELOAD, SHUTDOWN, PROCESS, FILE and GRANT will not be granted, as can be
verified by checking the "user" table of the "mysql" database. (This is presumably by design,
since these privileges can make a user "too powerful".)
Posted by DC Hill on Saturday February 16 2002, @10:21pm | [Delete] [Edit] |
NOTE: If you have granted privileges to a user on a particular database, or at any lower level than that, invoking "REVOKE ALL ON *.* FROM user@host;" will NOT revoke privileges at those levels. The *.* in the above statement means 'global', not 'all (individual) tables on all (individual) databases. That statment will ONLY revoke global privileges, as stored in the mysql.user table. You MUST revoke any more specific privileges in the same manner as they were granted, if you wish them to be removed from the privilege tables. (i.e. - GRANT ALL ON foo.* TO user@host; => REVOKE ALL ON foo.* FROM user@host;) I hope this saves some of you a little time and frustration.
Posted by Cris Perdue on Saturday February 16 2002, @10:21pm | [Delete] [Edit] |
REVOKE ALL on *.* from user@localhost does not revoke the privilege to connect to the database
server. To prohibit connections altogether it appears you have to use an SQL delete statement
then "flush privileges". This situation includes connection rights for the anonymous user
(""@localhost) automatically granted by some RPM distributions of MySQL. This usage of REVOKE
does remove all global privileges to do operations such as SELECT, INSERT, etc., leaving only the
privilege to connect.
Posted by Ken Maupin on Saturday February 16 2002, @10:21pm | [Delete] [Edit] |
The documentation doesn't emphasize this point,
but it appears tables_priv doesn't allow CIDR
notation in the Host column. If you use CIDR
notation in the other privilege tables, you need
to use wildcard notation in tables_priv. This
also affects the way GRANT and REVOKE work: if you
grant table-specific privileges to a user using
CIDR notation, you'll need to manually adjust the
Host column in tables_priv.
Posted by Antonius Jacobs on Saturday February 16 2002, @10:21pm | [Delete] [Edit] |
I just chanced my password in mysql now I can't
login anymore. I have used the mysql usermanuel.
I hope someone can help my with this problem.
Posted by Sania Prokopyuk on Saturday February 16 2002, @10:21pm | [Delete] [Edit] |
To enable REPLACE command you have to set the
user DELETE privilegy!
Posted by William Janoch on Saturday February 16 2002, @10:21pm | [Delete] [Edit] |
For detailed exples of how to use GRANT, check out the GRANT OPTIONS section of the documentation.
Here's a pretty standard GRANT to give a use control of a whole (single) database:
GRANT ALL ON database.* TO user IDENTIFIED BY "password"
Posted by William Janoch on Wednesday December 18 2002, @5:27pm | [Delete] [Edit] |
Common General GRANT examples to give "user" total control of a single database:
from localhost:GRANT ALL ON database.* TO user@localhost IDENTIFIED BY "password"
from remote host: GRANT ALL ON database.* TO user@example.com IDENTIFIED BY "password"
Posted by Joel Dare on Saturday February 16 2002, @10:21pm | [Delete] [Edit] |
Don't forget to "flush privileges"! I just spent
a couple hours trying to figure out why I
couldn't load a file after granting the
appropriate permissions...
Posted by ute.diestel on Saturday February 16 2002, @10:21pm | [Delete] [Edit] |
!!! Process_priv=N does not generally mean NOT,
also:
4.5.6.6 SHOW PROCESSLIST
http://www.mysql.com/doc/S/H/SHOW_PROCESSLIST.html
"If you have the process privilege, you can see
all threads.
Otherwise, you can see only your own threads."
Posted by FreeBSD Forums on Saturday February 16 2002, @10:21pm | [Delete] [Edit] |
You can use phpMyAdmin web based tool to do a lot
of mySQL admin functions. <a
href="http://www.freebsdforums.org"
>FreeBSD forums</a>
Posted by [name withheld] on Monday February 25 2002, @6:03am | [Delete] [Edit] |
Verified on MySQL 3.23.36 on Red Hat Linux 7.1:
Note that if you type
use a_c;
grant select on * to user@host;
you will have given user@host access to any
database matching 'a_c' where the underscore is a
wildcard. (Rarely a problem, I suppose).
Rectify with
update mysql.db set db='a\_c' where db='a_c';
Posted by jan behrens on Tuesday July 9 2002, @1:31am | [Delete] [Edit] |
the aformentioned bug from DAN ELIN in x.x.41 is
apperently still valid in x.x.51,i cannot logon to a
database after GRANTing privileges and given a
password to a new user(yes, i flushed
privileges)...................only root access is possible
Posted by Dan Egli on Thursday April 4 2002, @8:33pm | [Delete] [Edit] |
There seems to be a bug in 3.23.41 using Grant.
Only root can access the mysql database, even
after using Grant to grant privs on whatever
database/table/column/ect.. you always get
permission denied, regardless.
Posted by Lars Aronsson on Saturday June 8 2002, @11:16am | [Delete] [Edit] |
The normal response from a grant or revoke
statement is "Query OK, 0 rows affected". The
message that zero rows were affected is a common
source of confusion, but should just be ignored by
the user. Trying to revoke grants that were never
granted yields an "ERROR 1147: There is no such
grant defined for user...".
Posted by Marcio Merlone on Monday June 10 2002, @2:08pm | [Delete] [Edit] |
Where can I find information on how to revoke the
rights to 'show databases' command for ordinary
users? I donīt want my users to know wich
databases exists on server...
Posted by Eric Anderson on Tuesday June 11 2002, @9:40am | [Delete] [Edit] |
I'm attempting to delete two users, one called
webmaster@"localhost" and the other
webmaster@"%". When I try to delete them I'm told
error: 1066: not unique table/alias and when I
try to specify by their ip mask I get a syntax
error. Any suggestions?
Posted by Philip Mak on Wednesday December 18 2002, @5:27pm | [Delete] [Edit] |
Eric Anderson wrote:
> I'm attempting to delete two users, one called webmaster@"localhost" and the other webmaster@"%".
Try this:
<tt>DELETE FROM user WHERE user='webmaster' AND host='localhost';
DELETE FROM user WHERE user='webmaster' AND host='%';
FLUSH PRIVILEGES;
Posted by Melvyn Sopacua on Monday August 19 2002, @5:15am | [Delete] [Edit] |
For 4.0.2, the privilege system has changed with
some backwards compatibility concerns, even when
the mysql_fix_privileges script has been run.
If you have a user, with all privileges for a
certian database, but no global privileges, the
CREATE TEMPORARY TABLE privilege on that database
is denied.
You have to give global CREATE __and__ global
CREATE TEMPORARY TABLES to the user. IOW:
GRANT CREATE, CREATE TEMPORARY TABLES ON *.* TO
user@host;
Needless to say, this affects security grately.
Posted by [name withheld] on Sunday August 25 2002, @9:17am | [Delete] [Edit] |
Temporary files are a great idea but even with
Create and Create Temproary File rights in the
user (global rights) file it still doesn't work.
This appears to be badly designed.
Posted by Brad Bulger on Monday September 2 2002, @4:09am | [Delete] [Edit] |
It should be noted that WITH GRANT OPTION only
allows the user to pass on privileges to users who
already exist. The automagical creation of user
records does not apply - you get an error saying
that the user with the GRANT OPTION privilege does
not have access to the 'mysql' database. This is
probably a good thing, but it needs to be documented.
Posted by Michael Babcock on Friday November 8 2002, @1:00pm | [Delete] [Edit] |
SHOW MASTER STATUS requires PROCESS privileges.
Other such odd combinations should be documented.
Posted by Dee Kintaudi on Thursday November 21 2002, @12:42pm | [Delete] [Edit] |
Okay I got a question and a problem with Mysql and
passwords:). I tried to use several of the options
and most of them have not worked. However one
soloution did work and I tested it out twice and it
was solid. Of course I lost the little piece of paper I
wrote it out on and I can't seem to find this
soloution anywhere, as if it did not exist or maybe I
imagined it. The soloution that worked for me,
before I lost the little slip of paper I wrote it down on
goes something like this..... Insert into user root
Password "my password" and then something
with 'Y', 'Y', 'Y', (about a dozen or 15 times or so)
However, I can not find this soloution anywhere can
someone help me out here?
I think it would be so nice if they just put this
throughout their documentation instead of trying to
hide it. I think this would solve many problems. Just
put password = 'Y', 'Y', 'Y', its like their ashamed of it
or something.
Posted by AJIT DIXIT on Monday November 25 2002, @6:56am | [Delete] [Edit] |
When I work on multi-table update with root user
it works fine
When I work with non-root user I get error
Sql : update Stockists, areas set a_nm = aname
where acd = area
Error : update command denied to user:
'aldixit@localhost' for table 'areas'
What previledges are required for multi-table update ?
Posted by Martin Francis on Thursday March 27 2003, @8:49am | [Delete] [Edit] |
Version 3.23.38 for Windows: Hyphens in database names
If the database you are granting access to has a hyphen in the name, use backticks around the database name or the command will fail:
GRANT Select, Insert, Update, Delete, Index, Alter, Create, Drop, References
ON `test-1`.*
TO 'user-1'@'%'
IDENTIFIED BY 'secret'
Posted by lee chau on Wednesday March 12 2003, @10:05am | [Delete] [Edit] |
Is it possible to create an user account with say all privileges on all database EXCEPT mysql database, and no need to further update this acount's privileges even a new database is created later on ?
Posted by Rizwan Omer on Sunday April 13 2003, @1:26am | [Delete] [Edit] |
A simple example to Create a user with Administriative right will be:
mysql> GRANT ALL PRIVILEGES ON *.* TO myNewAdminUser@localhost
-> IDENTIFIED BY 'myAdminPassword' WITH GRANT OPTION;
where myNewAdminUser is the name of the new User to be created and
myAdminPassword is the password for the new Admin User.
Hope it helps...Cheers!
Posted by ratha grimes on Wednesday June 25 2003, @7:20pm | [Delete] [Edit] |
If you create a database with a mixed case name (e.g. "MySqlTestDatabase") and then try to assign rights to a user for that database ("grant all on MySqlTestDatabase.* to user@localhost"), your user will not be able to access the db. That's because the create database statement will ignore the lettercase and name your database with lowercase letters, but the grant statement will respect the case and insert into the "mysql.db" privilege table with the case as given. Then when your user tries to access the database, they won't be allowed, because the privilege doesn't match the actual database name. To fix it, rectify the db table: "update db set database = 'mysqltestdatabase' where database = 'MySqlTestDatabase'." (Don't forget to "flush privileges.")
Posted by [name withheld] on Saturday July 19 2003, @1:39am | [Delete] [Edit] |
I tried to 'grant' all priveleges for a new user (in fact creating this user with all rights already given) with the following statement:
mysql> INSERT INTO user VALUES ('localhost', 'thenewuser', PASSWORD('newuserspwd'),
-> 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y',
-> 'Y');
And it all worked. I guess you must be very confident about someone when giving him/her access to the 'user' table because it means that a new user can be added with ALL the priveleges!