SHOW GRANTS hided real grants when grants on both column and table (Bug 654)
mysql-test/r/grant.result: Test of grant BUG mysql-test/t/grant.test: Test of grant BUG sql/sql_acl.cc: SHOW GRANTS hided real grants when grants on both column and table (Bug 654) Code cleanup (Bigger than intended because of editor problem) sql/sql_acl.h: Fixed grant bug
This commit is contained in:
parent
16d6c8eb1f
commit
35c2b9df75
@ -1,3 +1,4 @@
|
|||||||
|
drop table if exists t1;
|
||||||
delete from mysql.user where user='mysqltest_1';
|
delete from mysql.user where user='mysqltest_1';
|
||||||
delete from mysql.db where user='mysqltest_1';
|
delete from mysql.db where user='mysqltest_1';
|
||||||
flush privileges;
|
flush privileges;
|
||||||
@ -64,8 +65,44 @@ GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, CREATE TE
|
|||||||
revoke all privileges on mysqltest.* from mysqltest_1@localhost;
|
revoke all privileges on mysqltest.* from mysqltest_1@localhost;
|
||||||
delete from mysql.user where user='mysqltest_1';
|
delete from mysql.user where user='mysqltest_1';
|
||||||
flush privileges;
|
flush privileges;
|
||||||
grant usage on test.* to user@localhost with grant option;
|
grant usage on test.* to mysqltest_1@localhost with grant option;
|
||||||
show grants for user@localhost;
|
show grants for mysqltest_1@localhost;
|
||||||
Grants for user@localhost
|
Grants for mysqltest_1@localhost
|
||||||
GRANT USAGE ON *.* TO 'user'@'localhost'
|
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
|
||||||
GRANT USAGE ON `test`.* TO 'user'@'localhost' WITH GRANT OPTION
|
GRANT USAGE ON `mysqltest`.* TO 'mysqltest_1'@'localhost' WITH GRANT OPTION
|
||||||
|
GRANT USAGE ON `test`.* TO 'mysqltest_1'@'localhost' WITH GRANT OPTION
|
||||||
|
delete from mysql.user where user='mysqltest_1';
|
||||||
|
delete from mysql.db where user='mysqltest_1';
|
||||||
|
delete from mysql.tables_priv where user='mysqltest_1';
|
||||||
|
delete from mysql.columns_priv where user='mysqltest_1';
|
||||||
|
flush privileges;
|
||||||
|
create table t1 (a int);
|
||||||
|
GRANT select,update,insert on t1 to mysqltest_1@localhost;
|
||||||
|
GRANT select (a), update (a),insert(a), references(a) on t1 to mysqltest_1@localhost;
|
||||||
|
show grants for mysqltest_1@localhost;
|
||||||
|
Grants for mysqltest_1@localhost
|
||||||
|
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
|
||||||
|
GRANT SELECT, SELECT (a), INSERT, INSERT (a), UPDATE, UPDATE (a), REFERENCES (a) ON `test`.`t1` TO 'mysqltest_1'@'localhost'
|
||||||
|
select table_priv,column_priv from mysql.tables_priv where user="mysqltest_1";
|
||||||
|
table_priv column_priv
|
||||||
|
Select,Insert,Update Select,Insert,Update,References
|
||||||
|
REVOKE select (a), update on t1 from mysqltest_1@localhost;
|
||||||
|
show grants for mysqltest_1@localhost;
|
||||||
|
Grants for mysqltest_1@localhost
|
||||||
|
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
|
||||||
|
GRANT SELECT, INSERT, INSERT (a), REFERENCES (a) ON `test`.`t1` TO 'mysqltest_1'@'localhost'
|
||||||
|
REVOKE insert,insert (a) on t1 from mysqltest_1@localhost;
|
||||||
|
GRANT references on t1 to mysqltest_1@localhost;
|
||||||
|
show grants for mysqltest_1@localhost;
|
||||||
|
Grants for mysqltest_1@localhost
|
||||||
|
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
|
||||||
|
GRANT SELECT, REFERENCES, REFERENCES (a) ON `test`.`t1` TO 'mysqltest_1'@'localhost'
|
||||||
|
select table_priv,column_priv from mysql.tables_priv where user="mysqltest_1";
|
||||||
|
table_priv column_priv
|
||||||
|
Select,References References
|
||||||
|
delete from mysql.user where user='mysqltest_1';
|
||||||
|
delete from mysql.db where user='mysqltest_1';
|
||||||
|
delete from mysql.tables_priv where user='mysqltest_1';
|
||||||
|
delete from mysql.columns_priv where user='mysqltest_1';
|
||||||
|
flush privileges;
|
||||||
|
drop table t1;
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
--disable_warnings
|
||||||
|
drop table if exists t1;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
#
|
#
|
||||||
# Test that SSL options works properly
|
# Test that SSL options works properly
|
||||||
#
|
#
|
||||||
@ -39,6 +43,32 @@ show grants for mysqltest_1@localhost;
|
|||||||
revoke all privileges on mysqltest.* from mysqltest_1@localhost;
|
revoke all privileges on mysqltest.* from mysqltest_1@localhost;
|
||||||
delete from mysql.user where user='mysqltest_1';
|
delete from mysql.user where user='mysqltest_1';
|
||||||
flush privileges;
|
flush privileges;
|
||||||
grant usage on test.* to user@localhost with grant option;
|
grant usage on test.* to mysqltest_1@localhost with grant option;
|
||||||
show grants for user@localhost;
|
show grants for mysqltest_1@localhost;
|
||||||
|
delete from mysql.user where user='mysqltest_1';
|
||||||
|
delete from mysql.db where user='mysqltest_1';
|
||||||
|
delete from mysql.tables_priv where user='mysqltest_1';
|
||||||
|
delete from mysql.columns_priv where user='mysqltest_1';
|
||||||
|
flush privileges;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test what happens when you have same table and colum level grants
|
||||||
|
#
|
||||||
|
|
||||||
|
create table t1 (a int);
|
||||||
|
GRANT select,update,insert on t1 to mysqltest_1@localhost;
|
||||||
|
GRANT select (a), update (a),insert(a), references(a) on t1 to mysqltest_1@localhost;
|
||||||
|
show grants for mysqltest_1@localhost;
|
||||||
|
select table_priv,column_priv from mysql.tables_priv where user="mysqltest_1";
|
||||||
|
REVOKE select (a), update on t1 from mysqltest_1@localhost;
|
||||||
|
show grants for mysqltest_1@localhost;
|
||||||
|
REVOKE insert,insert (a) on t1 from mysqltest_1@localhost;
|
||||||
|
GRANT references on t1 to mysqltest_1@localhost;
|
||||||
|
show grants for mysqltest_1@localhost;
|
||||||
|
select table_priv,column_priv from mysql.tables_priv where user="mysqltest_1";
|
||||||
|
delete from mysql.user where user='mysqltest_1';
|
||||||
|
delete from mysql.db where user='mysqltest_1';
|
||||||
|
delete from mysql.tables_priv where user='mysqltest_1';
|
||||||
|
delete from mysql.columns_priv where user='mysqltest_1';
|
||||||
|
flush privileges;
|
||||||
|
drop table t1;
|
||||||
|
361
sql/sql_acl.cc
361
sql/sql_acl.cc
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (C) 2000 MySQL AB
|
/* Copyright (C) 2000-2003 MySQL AB
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -193,7 +193,7 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables)
|
|||||||
host.db= get_field(&mem, table,1);
|
host.db= get_field(&mem, table,1);
|
||||||
host.access= get_access(table,2);
|
host.access= get_access(table,2);
|
||||||
host.access= fix_rights_for_db(host.access);
|
host.access= fix_rights_for_db(host.access);
|
||||||
host.sort= get_sort(2,host.host.hostname,host.db);
|
host.sort= get_sort(2,host.host.hostname,host.db);
|
||||||
#ifndef TO_BE_REMOVED
|
#ifndef TO_BE_REMOVED
|
||||||
if (table->fields == 8)
|
if (table->fields == 8)
|
||||||
{ // Without grant
|
{ // Without grant
|
||||||
@ -213,8 +213,7 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables)
|
|||||||
if (table->field[2]->field_length == 8 &&
|
if (table->field[2]->field_length == 8 &&
|
||||||
protocol_version == PROTOCOL_VERSION)
|
protocol_version == PROTOCOL_VERSION)
|
||||||
{
|
{
|
||||||
sql_print_error(
|
sql_print_error("Old 'user' table. (Check README or the Reference manual). Continuing --old-protocol"); /* purecov: tested */
|
||||||
"Old 'user' table. (Check README or the Reference manual). Continuing --old-protocol"); /* purecov: tested */
|
|
||||||
protocol_version=9; /* purecov: tested */
|
protocol_version=9; /* purecov: tested */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,7 +246,7 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables)
|
|||||||
user.sort=get_sort(2,user.host.hostname,user.user);
|
user.sort=get_sort(2,user.host.hostname,user.user);
|
||||||
user.hostname_length= (user.host.hostname ?
|
user.hostname_length= (user.host.hostname ?
|
||||||
(uint) strlen(user.host.hostname) : 0);
|
(uint) strlen(user.host.hostname) : 0);
|
||||||
if (table->fields >= 31) /* Starting from 4.0.2 we have more fields */
|
if (table->fields >= 31) /* Starting from 4.0.2 we have more fields */
|
||||||
{
|
{
|
||||||
char *ssl_type=get_field(&mem, table, 24);
|
char *ssl_type=get_field(&mem, table, 24);
|
||||||
if (!ssl_type)
|
if (!ssl_type)
|
||||||
@ -259,7 +258,7 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables)
|
|||||||
else /* !strcmp(ssl_type, "SPECIFIED") */
|
else /* !strcmp(ssl_type, "SPECIFIED") */
|
||||||
user.ssl_type=SSL_TYPE_SPECIFIED;
|
user.ssl_type=SSL_TYPE_SPECIFIED;
|
||||||
|
|
||||||
user.ssl_cipher= get_field(&mem, table, 25);
|
user.ssl_cipher= get_field(&mem, table, 25);
|
||||||
user.x509_issuer= get_field(&mem, table, 26);
|
user.x509_issuer= get_field(&mem, table, 26);
|
||||||
user.x509_subject= get_field(&mem, table, 27);
|
user.x509_subject= get_field(&mem, table, 27);
|
||||||
|
|
||||||
@ -368,7 +367,14 @@ void acl_free(bool end)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reload acl list if possible */
|
|
||||||
|
/*
|
||||||
|
Forget current privileges and read new privileges from the privilege tables
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
acl_reload()
|
||||||
|
thd Thread handle
|
||||||
|
*/
|
||||||
|
|
||||||
void acl_reload(THD *thd)
|
void acl_reload(THD *thd)
|
||||||
{
|
{
|
||||||
@ -493,8 +499,8 @@ static int acl_compare(ACL_ACCESS *a,ACL_ACCESS *b)
|
|||||||
|
|
||||||
ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
|
ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
|
||||||
const char *password,const char *message,
|
const char *password,const char *message,
|
||||||
char **priv_user, char *priv_host,
|
char **priv_user, char *priv_host,
|
||||||
bool old_ver, USER_RESOURCES *mqh)
|
bool old_ver, USER_RESOURCES *mqh)
|
||||||
{
|
{
|
||||||
ulong user_access=NO_ACCESS;
|
ulong user_access=NO_ACCESS;
|
||||||
*priv_user=(char*) user;
|
*priv_user=(char*) user;
|
||||||
@ -526,15 +532,15 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
|
|||||||
{
|
{
|
||||||
#ifdef HAVE_OPENSSL
|
#ifdef HAVE_OPENSSL
|
||||||
Vio *vio=thd->net.vio;
|
Vio *vio=thd->net.vio;
|
||||||
/*
|
/*
|
||||||
In this point we know that user is allowed to connect
|
In this point we know that user is allowed to connect
|
||||||
from given host by given username/password pair. Now
|
from given host by given username/password pair. Now
|
||||||
we check if SSL is required, if user is using SSL and
|
we check if SSL is required, if user is using SSL and
|
||||||
if X509 certificate attributes are OK
|
if X509 certificate attributes are OK
|
||||||
*/
|
*/
|
||||||
switch (acl_user->ssl_type) {
|
switch (acl_user->ssl_type) {
|
||||||
case SSL_TYPE_NOT_SPECIFIED: // Impossible
|
case SSL_TYPE_NOT_SPECIFIED: // Impossible
|
||||||
case SSL_TYPE_NONE: /* SSL is not required to connect */
|
case SSL_TYPE_NONE: /* SSL is not required to connect */
|
||||||
user_access=acl_user->access;
|
user_access=acl_user->access;
|
||||||
break;
|
break;
|
||||||
case SSL_TYPE_ANY: /* Any kind of SSL is good enough */
|
case SSL_TYPE_ANY: /* Any kind of SSL is good enough */
|
||||||
@ -544,7 +550,7 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
|
|||||||
case SSL_TYPE_X509: /* Client should have any valid certificate. */
|
case SSL_TYPE_X509: /* Client should have any valid certificate. */
|
||||||
/*
|
/*
|
||||||
We need to check for absence of SSL because without SSL
|
We need to check for absence of SSL because without SSL
|
||||||
we should reject connection.
|
we should reject connection.
|
||||||
*/
|
*/
|
||||||
if (vio_type(vio) == VIO_TYPE_SSL && SSL_get_peer_certificate(vio->ssl_))
|
if (vio_type(vio) == VIO_TYPE_SSL && SSL_get_peer_certificate(vio->ssl_))
|
||||||
user_access=acl_user->access;
|
user_access=acl_user->access;
|
||||||
@ -653,12 +659,12 @@ static byte* check_get_key(ACL_USER *buff,uint *length,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void acl_update_user(const char *user, const char *host,
|
static void acl_update_user(const char *user, const char *host,
|
||||||
const char *password,
|
const char *password,
|
||||||
enum SSL_type ssl_type,
|
enum SSL_type ssl_type,
|
||||||
const char *ssl_cipher,
|
const char *ssl_cipher,
|
||||||
const char *x509_issuer,
|
const char *x509_issuer,
|
||||||
const char *x509_subject,
|
const char *x509_subject,
|
||||||
USER_RESOURCES *mqh,
|
USER_RESOURCES *mqh,
|
||||||
ulong privileges)
|
ulong privileges)
|
||||||
{
|
{
|
||||||
for (uint i=0 ; i < acl_users.elements ; i++)
|
for (uint i=0 ; i < acl_users.elements ; i++)
|
||||||
@ -707,7 +713,7 @@ static void acl_update_user(const char *user, const char *host,
|
|||||||
|
|
||||||
|
|
||||||
static void acl_insert_user(const char *user, const char *host,
|
static void acl_insert_user(const char *user, const char *host,
|
||||||
const char *password,
|
const char *password,
|
||||||
enum SSL_type ssl_type,
|
enum SSL_type ssl_type,
|
||||||
const char *ssl_cipher,
|
const char *ssl_cipher,
|
||||||
const char *x509_issuer,
|
const char *x509_issuer,
|
||||||
@ -805,9 +811,10 @@ static void acl_insert_db(const char *user, const char *host, const char *db,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
** Get privilege for a host, user and db combination
|
/*
|
||||||
*****************************************************************************/
|
Get privilege for a host, user and db combination
|
||||||
|
*/
|
||||||
|
|
||||||
ulong 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)
|
const char *user, const char *db)
|
||||||
@ -929,11 +936,14 @@ int wild_case_compare(const char *str,const char *wildstr)
|
|||||||
DBUG_RETURN (*str != '\0');
|
DBUG_RETURN (*str != '\0');
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
** check if there are any possible matching entries for this host
|
/*
|
||||||
** All host names without wild cards are stored in a hash table,
|
Check if there are any possible matching entries for this host
|
||||||
** entries with wildcards are stored in a dynamic array
|
|
||||||
*****************************************************************************/
|
NOTES
|
||||||
|
All host names without wild cards are stored in a hash table,
|
||||||
|
entries with wildcards are stored in a dynamic array
|
||||||
|
*/
|
||||||
|
|
||||||
static void init_check_host(void)
|
static void init_check_host(void)
|
||||||
{
|
{
|
||||||
@ -1006,10 +1016,6 @@ bool acl_check_host(const char *host, const char *ip)
|
|||||||
return 1; // Host is not allowed
|
return 1; // Host is not allowed
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
Change password for the user if it's not an anonymous user
|
|
||||||
Note: This should write the error directly to the client!
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Check if the user is allowed to change password
|
Check if the user is allowed to change password
|
||||||
@ -1021,8 +1027,8 @@ bool acl_check_host(const char *host, const char *ip)
|
|||||||
user user name
|
user user name
|
||||||
|
|
||||||
RETURN VALUE
|
RETURN VALUE
|
||||||
0 OK
|
0 OK
|
||||||
1 ERROR ; In this case the error is sent to the client.
|
1 ERROR ; In this case the error is sent to the client.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool check_change_password(THD *thd, const char *host, const char *user)
|
bool check_change_password(THD *thd, const char *host, const char *user)
|
||||||
@ -1061,7 +1067,7 @@ bool check_change_password(THD *thd, const char *host, const char *user)
|
|||||||
RETURN VALUES
|
RETURN VALUES
|
||||||
0 ok
|
0 ok
|
||||||
1 ERROR; In this case the error is sent to the client.
|
1 ERROR; In this case the error is sent to the client.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool change_password(THD *thd, const char *host, const char *user,
|
bool change_password(THD *thd, const char *host, const char *user,
|
||||||
char *new_password)
|
char *new_password)
|
||||||
@ -1127,7 +1133,7 @@ find_acl_user(const char *host, const char *user)
|
|||||||
{
|
{
|
||||||
ACL_USER *acl_user=dynamic_element(&acl_users,i,ACL_USER*);
|
ACL_USER *acl_user=dynamic_element(&acl_users,i,ACL_USER*);
|
||||||
DBUG_PRINT("info",("strcmp('%s','%s'), compare_hostname('%s','%s'),",
|
DBUG_PRINT("info",("strcmp('%s','%s'), compare_hostname('%s','%s'),",
|
||||||
user,acl_user->user,(host),(acl_user->host)));
|
user,acl_user->user,(host),(acl_user->host)));
|
||||||
if (!acl_user->user && !user[0] ||
|
if (!acl_user->user && !user[0] ||
|
||||||
acl_user->user && !strcmp(user,acl_user->user))
|
acl_user->user && !strcmp(user,acl_user->user))
|
||||||
{
|
{
|
||||||
@ -1140,15 +1146,18 @@ find_acl_user(const char *host, const char *user)
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
Handle comparing of hostname
|
|
||||||
A hostname may be of type:
|
|
||||||
hostname (May include wildcards); monty.pp.sci.fi
|
|
||||||
ip (May include wildcards); 192.168.0.0
|
|
||||||
ip/netmask 192.168.0.0/255.255.255.0
|
|
||||||
|
|
||||||
A net mask of 0.0.0.0 is not allowed.
|
/*
|
||||||
*****************************************************************************/
|
Comparing of hostnames
|
||||||
|
|
||||||
|
NOTES
|
||||||
|
A hostname may be of type:
|
||||||
|
hostname (May include wildcards); monty.pp.sci.fi
|
||||||
|
ip (May include wildcards); 192.168.0.0
|
||||||
|
ip/netmask 192.168.0.0/255.255.255.0
|
||||||
|
|
||||||
|
A net mask of 0.0.0.0 is not allowed.
|
||||||
|
*/
|
||||||
|
|
||||||
static const char *calc_ip(const char *ip, long *val, char end)
|
static const char *calc_ip(const char *ip, long *val, char end)
|
||||||
{
|
{
|
||||||
@ -1195,9 +1204,9 @@ static bool compare_hostname(const acl_host_and_ip *host, const char *hostname,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/*
|
||||||
Code to update grants in the user and database privilege tables
|
Update grants in the user and database privilege tables
|
||||||
****************************************************************************/
|
*/
|
||||||
|
|
||||||
static bool update_user_table(THD *thd, const char *host, const char *user,
|
static bool update_user_table(THD *thd, const char *host, const char *user,
|
||||||
const char *new_password)
|
const char *new_password)
|
||||||
@ -1263,7 +1272,7 @@ static bool test_if_create_new_users(THD *thd)
|
|||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
** Handle GRANT commands
|
Handle GRANT commands
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
|
static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
|
||||||
@ -1285,8 +1294,8 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
|
|||||||
if (combo.password.length != HASH_PASSWORD_LENGTH)
|
if (combo.password.length != HASH_PASSWORD_LENGTH)
|
||||||
{
|
{
|
||||||
my_printf_error(ER_PASSWORD_NO_MATCH,
|
my_printf_error(ER_PASSWORD_NO_MATCH,
|
||||||
"Password hash should be a %d-digit hexadecimal number",
|
"Password hash should be a %d-digit hexadecimal number",
|
||||||
MYF(0),HASH_PASSWORD_LENGTH);
|
MYF(0),HASH_PASSWORD_LENGTH);
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
}
|
}
|
||||||
password=combo.password.str;
|
password=combo.password.str;
|
||||||
@ -1459,7 +1468,7 @@ static int replace_db_table(TABLE *table, const char *db,
|
|||||||
char what= (revoke_grant) ? 'N' : 'Y';
|
char what= (revoke_grant) ? 'N' : 'Y';
|
||||||
DBUG_ENTER("replace_db_table");
|
DBUG_ENTER("replace_db_table");
|
||||||
|
|
||||||
// is there such a user in user table in memory ????
|
/* Check if there is such a user in user table in memory? */
|
||||||
if (!initialized || !find_acl_user(combo.host.str,combo.user.str))
|
if (!initialized || !find_acl_user(combo.host.str,combo.user.str))
|
||||||
{
|
{
|
||||||
my_error(ER_PASSWORD_NO_MATCH,MYF(0));
|
my_error(ER_PASSWORD_NO_MATCH,MYF(0));
|
||||||
@ -1471,7 +1480,7 @@ static int replace_db_table(TABLE *table, const char *db,
|
|||||||
table->field[2]->store(combo.user.str,combo.user.length);
|
table->field[2]->store(combo.user.str,combo.user.length);
|
||||||
table->file->index_init(0);
|
table->file->index_init(0);
|
||||||
if (table->file->index_read(table->record[0],(byte*) table->field[0]->ptr,0,
|
if (table->file->index_read(table->record[0],(byte*) table->field[0]->ptr,0,
|
||||||
HA_READ_KEY_EXACT))
|
HA_READ_KEY_EXACT))
|
||||||
{
|
{
|
||||||
if (what == 'N')
|
if (what == 'N')
|
||||||
{ // no row, no revoke
|
{ // no row, no revoke
|
||||||
@ -1502,7 +1511,7 @@ static int replace_db_table(TABLE *table, const char *db,
|
|||||||
|
|
||||||
if (old_row_exists)
|
if (old_row_exists)
|
||||||
{
|
{
|
||||||
// update old existing row
|
/* update old existing row */
|
||||||
if (rights)
|
if (rights)
|
||||||
{
|
{
|
||||||
if ((error=table->file->update_row(table->record[1],table->record[0])))
|
if ((error=table->file->update_row(table->record[1],table->record[0])))
|
||||||
@ -1529,11 +1538,11 @@ static int replace_db_table(TABLE *table, const char *db,
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
/* This could only happen if the grant tables got corrupted */
|
/* This could only happen if the grant tables got corrupted */
|
||||||
table_error:
|
table_error:
|
||||||
table->file->print_error(error,MYF(0)); /* purecov: deadcode */
|
table->file->print_error(error,MYF(0)); /* purecov: deadcode */
|
||||||
table->file->index_end();
|
table->file->index_end();
|
||||||
|
|
||||||
abort:
|
abort:
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1649,7 +1658,7 @@ public:
|
|||||||
if (!(mem_check = new GRANT_COLUMN(*res,
|
if (!(mem_check = new GRANT_COLUMN(*res,
|
||||||
fix_rights_for_column(priv))))
|
fix_rights_for_column(priv))))
|
||||||
{
|
{
|
||||||
// Don't use this entry
|
/* Don't use this entry */
|
||||||
privs = cols = 0; /* purecov: deadcode */
|
privs = cols = 0; /* purecov: deadcode */
|
||||||
return; /* purecov: deadcode */
|
return; /* purecov: deadcode */
|
||||||
}
|
}
|
||||||
@ -1827,7 +1836,7 @@ static int replace_column_table(GRANT_TABLE *g_t,
|
|||||||
key_length, HA_READ_KEY_EXACT))
|
key_length, HA_READ_KEY_EXACT))
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
// Scan trough all rows with the same host,db,user and table
|
/* Scan through all rows with the same host,db,user and table */
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
ulong privileges = (ulong) table->field[6]->val_int();
|
ulong privileges = (ulong) table->field[6]->val_int();
|
||||||
@ -1877,7 +1886,7 @@ static int replace_column_table(GRANT_TABLE *g_t,
|
|||||||
!key_cmp(table,key,0,key_length));
|
!key_cmp(table,key,0,key_length));
|
||||||
}
|
}
|
||||||
|
|
||||||
end:
|
end:
|
||||||
table->file->index_end();
|
table->file->index_end();
|
||||||
DBUG_RETURN(result);
|
DBUG_RETURN(result);
|
||||||
}
|
}
|
||||||
@ -1947,7 +1956,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
|
|||||||
|
|
||||||
if (revoke_grant)
|
if (revoke_grant)
|
||||||
{
|
{
|
||||||
// column rights are already fixed in mysql_table_grant !
|
/* column rights are already fixed in mysql_table_grant */
|
||||||
store_table_rights=j & ~store_table_rights;
|
store_table_rights=j & ~store_table_rights;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1983,7 +1992,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
|
|||||||
if (rights | col_rights)
|
if (rights | col_rights)
|
||||||
{
|
{
|
||||||
grant_table->privs= rights;
|
grant_table->privs= rights;
|
||||||
grant_table->cols= col_rights;
|
grant_table->cols= col_rights;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1991,19 +2000,36 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
|
|||||||
}
|
}
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
/* This should never happen */
|
/* This should never happen */
|
||||||
table_error:
|
table_error:
|
||||||
table->file->print_error(error,MYF(0)); /* purecov: deadcode */
|
table->file->print_error(error,MYF(0)); /* purecov: deadcode */
|
||||||
DBUG_RETURN(-1); /* purecov: deadcode */
|
DBUG_RETURN(-1); /* purecov: deadcode */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Store table level and column level grants in the privilege tables
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
mysql_table_grant()
|
||||||
|
thd Thread handle
|
||||||
|
table_list List of tables to give grant
|
||||||
|
user_list List of users to give grant
|
||||||
|
columns List of columns to give grant
|
||||||
|
rights Table level grant
|
||||||
|
revoke_grant Set to 1 if this is a REVOKE command
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
0 ok
|
||||||
|
1 error
|
||||||
|
*/
|
||||||
|
|
||||||
int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
|
int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
|
||||||
List <LEX_USER> &user_list,
|
List <LEX_USER> &user_list,
|
||||||
List <LEX_COLUMN> &columns, ulong rights,
|
List <LEX_COLUMN> &columns, ulong rights,
|
||||||
bool revoke_grant)
|
bool revoke_grant)
|
||||||
{
|
{
|
||||||
ulong column_priv = 0;
|
ulong column_priv= 0;
|
||||||
List_iterator <LEX_USER> str_list (user_list);
|
List_iterator <LEX_USER> str_list (user_list);
|
||||||
LEX_USER *Str;
|
LEX_USER *Str;
|
||||||
TABLE_LIST tables[3];
|
TABLE_LIST tables[3];
|
||||||
@ -2024,21 +2050,21 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
|
|||||||
if (columns.elements && !revoke_grant)
|
if (columns.elements && !revoke_grant)
|
||||||
{
|
{
|
||||||
TABLE *table;
|
TABLE *table;
|
||||||
class LEX_COLUMN *check;
|
class LEX_COLUMN *column;
|
||||||
List_iterator <LEX_COLUMN> iter(columns);
|
List_iterator <LEX_COLUMN> column_iter(columns);
|
||||||
|
|
||||||
if (!(table=open_ltable(thd,table_list,TL_READ)))
|
if (!(table=open_ltable(thd,table_list,TL_READ)))
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
while ((check = iter++))
|
while ((column = column_iter++))
|
||||||
{
|
{
|
||||||
if (!find_field_in_table(thd,table,check->column.ptr(),
|
if (!find_field_in_table(thd,table,column->column.ptr(),
|
||||||
check->column.length(),0,0))
|
column->column.length(),0,0))
|
||||||
{
|
{
|
||||||
my_printf_error(ER_BAD_FIELD_ERROR,ER(ER_BAD_FIELD_ERROR),MYF(0),
|
my_printf_error(ER_BAD_FIELD_ERROR,ER(ER_BAD_FIELD_ERROR),MYF(0),
|
||||||
check->column.c_ptr(), table_list->alias);
|
column->column.c_ptr(), table_list->alias);
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
}
|
}
|
||||||
column_priv |= check->rights | (rights & COL_ACLS);
|
column_priv|= column->rights;
|
||||||
}
|
}
|
||||||
close_thread_tables(thd);
|
close_thread_tables(thd);
|
||||||
}
|
}
|
||||||
@ -2148,21 +2174,21 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
|
|||||||
/* If revoke_grant, calculate the new column privilege for tables_priv */
|
/* If revoke_grant, calculate the new column privilege for tables_priv */
|
||||||
if (revoke_grant)
|
if (revoke_grant)
|
||||||
{
|
{
|
||||||
class LEX_COLUMN *check;
|
class LEX_COLUMN *column;
|
||||||
List_iterator <LEX_COLUMN> iter(columns);
|
List_iterator <LEX_COLUMN> column_iter(columns);
|
||||||
GRANT_COLUMN *grant_column;
|
GRANT_COLUMN *grant_column;
|
||||||
|
|
||||||
/* Fix old grants */
|
/* Fix old grants */
|
||||||
while ((check = iter++))
|
while ((column = column_iter++))
|
||||||
{
|
{
|
||||||
grant_column = column_hash_search(grant_table,
|
grant_column = column_hash_search(grant_table,
|
||||||
check->column.ptr(),
|
column->column.ptr(),
|
||||||
check->column.length());
|
column->column.length());
|
||||||
if (grant_column)
|
if (grant_column)
|
||||||
grant_column->rights&= ~(check->rights | rights);
|
grant_column->rights&= ~(column->rights | rights);
|
||||||
}
|
}
|
||||||
/* scan trough all columns to get new column grant */
|
/* scan trough all columns to get new column grant */
|
||||||
column_priv=0;
|
column_priv= 0;
|
||||||
for (uint idx=0 ; idx < grant_table->hash_columns.records ; idx++)
|
for (uint idx=0 ; idx < grant_table->hash_columns.records ; idx++)
|
||||||
{
|
{
|
||||||
grant_column= (GRANT_COLUMN*) hash_element(&grant_table->hash_columns,
|
grant_column= (GRANT_COLUMN*) hash_element(&grant_table->hash_columns,
|
||||||
@ -2259,7 +2285,7 @@ int mysql_grant (THD *thd, const char *db, List <LEX_USER> &list,
|
|||||||
if (!revoke_grant)
|
if (!revoke_grant)
|
||||||
create_new_users= test_if_create_new_users(thd);
|
create_new_users= test_if_create_new_users(thd);
|
||||||
|
|
||||||
// go through users in user_list
|
/* go through users in user_list */
|
||||||
pthread_mutex_lock(&LOCK_grant);
|
pthread_mutex_lock(&LOCK_grant);
|
||||||
VOID(pthread_mutex_lock(&acl_cache->lock));
|
VOID(pthread_mutex_lock(&acl_cache->lock));
|
||||||
grant_version++;
|
grant_version++;
|
||||||
@ -2280,7 +2306,7 @@ int mysql_grant (THD *thd, const char *db, List <LEX_USER> &list,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ((replace_user_table(thd,
|
if ((replace_user_table(thd,
|
||||||
tables[0].table,
|
tables[0].table,
|
||||||
*Str,
|
*Str,
|
||||||
(!db ? rights : 0), revoke_grant,
|
(!db ? rights : 0), revoke_grant,
|
||||||
create_new_users)))
|
create_new_users)))
|
||||||
@ -2401,7 +2427,16 @@ end:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Reload grant array if possible */
|
/*
|
||||||
|
Reload grant array if possible
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
grant_reload()
|
||||||
|
thd Thread handler
|
||||||
|
|
||||||
|
NOTES
|
||||||
|
Locked tables are checked by acl_init and doesn't have to be checked here
|
||||||
|
*/
|
||||||
|
|
||||||
void grant_reload(THD *thd)
|
void grant_reload(THD *thd)
|
||||||
{
|
{
|
||||||
@ -2410,8 +2445,6 @@ void grant_reload(THD *thd)
|
|||||||
MEM_ROOT old_mem;
|
MEM_ROOT old_mem;
|
||||||
DBUG_ENTER("grant_reload");
|
DBUG_ENTER("grant_reload");
|
||||||
|
|
||||||
// Locked tables are checked by acl_init and doesn't have to be checked here
|
|
||||||
|
|
||||||
pthread_mutex_lock(&LOCK_grant);
|
pthread_mutex_lock(&LOCK_grant);
|
||||||
grant_version++;
|
grant_version++;
|
||||||
old_hash_tables=hash_tables;
|
old_hash_tables=hash_tables;
|
||||||
@ -2487,13 +2520,13 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
|
|||||||
pthread_mutex_unlock(&LOCK_grant);
|
pthread_mutex_unlock(&LOCK_grant);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
pthread_mutex_unlock(&LOCK_grant);
|
pthread_mutex_unlock(&LOCK_grant);
|
||||||
if (!no_errors) // Not a silent skip of table
|
if (!no_errors) // Not a silent skip of table
|
||||||
{
|
{
|
||||||
const char *command="";
|
const char *command="";
|
||||||
if (want_access & SELECT_ACL)
|
if (want_access & SELECT_ACL)
|
||||||
command ="select";
|
command ="select";
|
||||||
else if (want_access & INSERT_ACL)
|
else if (want_access & INSERT_ACL)
|
||||||
command = "insert";
|
command = "insert";
|
||||||
else if (want_access & UPDATE_ACL)
|
else if (want_access & UPDATE_ACL)
|
||||||
@ -2534,7 +2567,7 @@ bool check_grant_column(THD *thd,TABLE *table, const char *name,
|
|||||||
|
|
||||||
pthread_mutex_lock(&LOCK_grant);
|
pthread_mutex_lock(&LOCK_grant);
|
||||||
|
|
||||||
// reload table if someone has modified any grants
|
/* reload table if someone has modified any grants */
|
||||||
|
|
||||||
if (table->grant.version != grant_version)
|
if (table->grant.version != grant_version)
|
||||||
{
|
{
|
||||||
@ -2594,7 +2627,7 @@ bool check_grant_all_columns(THD *thd, ulong want_access, TABLE *table)
|
|||||||
|
|
||||||
pthread_mutex_lock(&LOCK_grant);
|
pthread_mutex_lock(&LOCK_grant);
|
||||||
|
|
||||||
// reload table if someone has modified any grants
|
/* reload table if someone has modified any grants */
|
||||||
|
|
||||||
if (table->grant.version != grant_version)
|
if (table->grant.version != grant_version)
|
||||||
{
|
{
|
||||||
@ -2604,7 +2637,7 @@ bool check_grant_all_columns(THD *thd, ulong want_access, TABLE *table)
|
|||||||
table->real_name,0); /* purecov: inspected */
|
table->real_name,0); /* purecov: inspected */
|
||||||
table->grant.version=grant_version; /* purecov: inspected */
|
table->grant.version=grant_version; /* purecov: inspected */
|
||||||
}
|
}
|
||||||
// The following should always be true
|
/* The following should always be true */
|
||||||
if (!(grant_table=table->grant.grant_table))
|
if (!(grant_table=table->grant.grant_table))
|
||||||
goto err; /* purecov: inspected */
|
goto err; /* purecov: inspected */
|
||||||
|
|
||||||
@ -2619,7 +2652,7 @@ bool check_grant_all_columns(THD *thd, ulong want_access, TABLE *table)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* We must use my_printf_error() here! */
|
/* We must use my_printf_error() here! */
|
||||||
err:
|
err:
|
||||||
pthread_mutex_unlock(&LOCK_grant);
|
pthread_mutex_unlock(&LOCK_grant);
|
||||||
|
|
||||||
const char *command="";
|
const char *command="";
|
||||||
@ -2639,11 +2672,11 @@ bool check_grant_all_columns(THD *thd, ulong want_access, TABLE *table)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/*
|
||||||
Check if a user has the right to access a database
|
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
|
Access is accepted if he has a grant for any table in the database
|
||||||
Return 1 if access is denied
|
Return 1 if access is denied
|
||||||
****************************************************************************/
|
*/
|
||||||
|
|
||||||
bool check_grant_db(THD *thd,const char *db)
|
bool check_grant_db(THD *thd,const char *db)
|
||||||
{
|
{
|
||||||
@ -2683,7 +2716,7 @@ ulong get_table_grant(THD *thd, TABLE_LIST *table)
|
|||||||
|
|
||||||
pthread_mutex_lock(&LOCK_grant);
|
pthread_mutex_lock(&LOCK_grant);
|
||||||
grant_table = table_hash_search(thd->host,thd->ip,db,user,
|
grant_table = table_hash_search(thd->host,thd->ip,db,user,
|
||||||
table->real_name,0);
|
table->real_name, 0);
|
||||||
table->grant.grant_table=grant_table; // Remember for column test
|
table->grant.grant_table=grant_table; // Remember for column test
|
||||||
table->grant.version=grant_version;
|
table->grant.version=grant_version;
|
||||||
if (grant_table)
|
if (grant_table)
|
||||||
@ -2701,7 +2734,7 @@ ulong get_column_grant(THD *thd, TABLE_LIST *table, Field *field)
|
|||||||
ulong priv;
|
ulong priv;
|
||||||
|
|
||||||
pthread_mutex_lock(&LOCK_grant);
|
pthread_mutex_lock(&LOCK_grant);
|
||||||
// reload table if someone has modified any grants
|
/* reload table if someone has modified any grants */
|
||||||
if (table->grant.version != grant_version)
|
if (table->grant.version != grant_version)
|
||||||
{
|
{
|
||||||
table->grant.grant_table=
|
table->grant.grant_table=
|
||||||
@ -2726,11 +2759,20 @@ ulong get_column_grant(THD *thd, TABLE_LIST *table, Field *field)
|
|||||||
return priv;
|
return priv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Help function for mysql_show_grants */
|
||||||
|
|
||||||
/*****************************************************************************
|
static void add_user_option(String *grant, ulong value, const char *name)
|
||||||
SHOW GRANTS : send to client grant-like strings depicting user@host
|
{
|
||||||
privileges
|
if (value)
|
||||||
*****************************************************************************/
|
{
|
||||||
|
char buff[22], *p; // just as in int2str
|
||||||
|
grant->append(' ');
|
||||||
|
grant->append(name, strlen(name));
|
||||||
|
grant->append(' ');
|
||||||
|
p=int10_to_str(value, buff, 10);
|
||||||
|
grant->append(buff,p-buff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const char *command_array[]=
|
static const char *command_array[]=
|
||||||
{
|
{
|
||||||
@ -2739,13 +2781,21 @@ static const char *command_array[]=
|
|||||||
"SUPER", "CREATE TEMPORARY TABLES", "LOCK TABLES", "EXECUTE",
|
"SUPER", "CREATE TEMPORARY TABLES", "LOCK TABLES", "EXECUTE",
|
||||||
"REPLICATION SLAVE", "REPLICATION CLIENT",
|
"REPLICATION SLAVE", "REPLICATION CLIENT",
|
||||||
};
|
};
|
||||||
|
|
||||||
static uint command_lengths[]=
|
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
|
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)
|
/*
|
||||||
|
SHOW GRANTS; Send grants for a user to the client
|
||||||
|
|
||||||
|
IMPLEMENTATION
|
||||||
|
Send to client grant-like strings depicting user@host privileges
|
||||||
|
*/
|
||||||
|
|
||||||
|
int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
||||||
{
|
{
|
||||||
ulong want_access;
|
ulong want_access;
|
||||||
uint counter,index;
|
uint counter,index;
|
||||||
@ -2784,7 +2834,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
|||||||
!my_strcasecmp(lex_user->host.str,host))
|
!my_strcasecmp(lex_user->host.str,host))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (counter == acl_users.elements)
|
if (counter == acl_users.elements)
|
||||||
{
|
{
|
||||||
my_printf_error(ER_NONEXISTING_GRANT,ER(ER_NONEXISTING_GRANT),
|
my_printf_error(ER_NONEXISTING_GRANT,ER(ER_NONEXISTING_GRANT),
|
||||||
MYF(0),lex_user->user.str,lex_user->host.str);
|
MYF(0),lex_user->user.str,lex_user->host.str);
|
||||||
@ -2815,13 +2865,13 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
|||||||
global.append("ALL PRIVILEGES",14);
|
global.append("ALL PRIVILEGES",14);
|
||||||
else if (!(want_access & ~GRANT_ACL))
|
else if (!(want_access & ~GRANT_ACL))
|
||||||
global.append("USAGE",5);
|
global.append("USAGE",5);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool found=0;
|
bool found=0;
|
||||||
ulong 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)
|
for (counter=0, j = SELECT_ACL;j <= GLOBAL_ACLS;counter++,j <<= 1)
|
||||||
{
|
{
|
||||||
if (test_access & j)
|
if (test_access & j)
|
||||||
{
|
{
|
||||||
if (found)
|
if (found)
|
||||||
global.append(", ",2);
|
global.append(", ",2);
|
||||||
@ -2831,7 +2881,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
global.append (" ON *.* TO '",12);
|
global.append (" ON *.* TO '",12);
|
||||||
global.append(lex_user->user.str,lex_user->user.length);
|
global.append(lex_user->user.str,lex_user->user.length);
|
||||||
global.append ("'@'",3);
|
global.append ("'@'",3);
|
||||||
global.append(lex_user->host.str,lex_user->host.length);
|
global.append(lex_user->host.str,lex_user->host.length);
|
||||||
global.append ('\'');
|
global.append ('\'');
|
||||||
@ -2854,25 +2904,25 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
|||||||
global.append(" REQUIRE ",9);
|
global.append(" REQUIRE ",9);
|
||||||
if (acl_user->x509_issuer)
|
if (acl_user->x509_issuer)
|
||||||
{
|
{
|
||||||
ssl_options++;
|
ssl_options++;
|
||||||
global.append("ISSUER \'",8);
|
global.append("ISSUER \'",8);
|
||||||
global.append(acl_user->x509_issuer,strlen(acl_user->x509_issuer));
|
global.append(acl_user->x509_issuer,strlen(acl_user->x509_issuer));
|
||||||
global.append('\'');
|
global.append('\'');
|
||||||
}
|
}
|
||||||
if (acl_user->x509_subject)
|
if (acl_user->x509_subject)
|
||||||
{
|
{
|
||||||
if (ssl_options++)
|
if (ssl_options++)
|
||||||
global.append(' ');
|
global.append(' ');
|
||||||
global.append("SUBJECT \'",9);
|
global.append("SUBJECT \'",9);
|
||||||
global.append(acl_user->x509_subject,strlen(acl_user->x509_subject));
|
global.append(acl_user->x509_subject,strlen(acl_user->x509_subject));
|
||||||
global.append('\'');
|
global.append('\'');
|
||||||
}
|
}
|
||||||
if (acl_user->ssl_cipher)
|
if (acl_user->ssl_cipher)
|
||||||
{
|
{
|
||||||
if (ssl_options++)
|
if (ssl_options++)
|
||||||
global.append(' ');
|
global.append(' ');
|
||||||
global.append("CIPHER '",8);
|
global.append("CIPHER '",8);
|
||||||
global.append(acl_user->ssl_cipher,strlen(acl_user->ssl_cipher));
|
global.append(acl_user->ssl_cipher,strlen(acl_user->ssl_cipher));
|
||||||
global.append('\'');
|
global.append('\'');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2880,30 +2930,15 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
|||||||
(acl_user->user_resource.questions | acl_user->user_resource.updates |
|
(acl_user->user_resource.questions | acl_user->user_resource.updates |
|
||||||
acl_user->user_resource.connections))
|
acl_user->user_resource.connections))
|
||||||
{
|
{
|
||||||
global.append(" WITH",5);
|
global.append(" WITH",5);
|
||||||
if (want_access & GRANT_ACL)
|
if (want_access & GRANT_ACL)
|
||||||
global.append(" GRANT OPTION",13);
|
global.append(" GRANT OPTION",13);
|
||||||
if (acl_user->user_resource.questions)
|
add_user_option(&global, acl_user->user_resource.questions,
|
||||||
{
|
"MAX_QUERIES_PER_HOUR");
|
||||||
char buff[22], *p; // just as in int2str
|
add_user_option(&global, acl_user->user_resource.updates,
|
||||||
global.append(" MAX_QUERIES_PER_HOUR ",22);
|
"MAX_UPDATES_PER_HOUR");
|
||||||
p=int10_to_str(acl_user->user_resource.questions,buff,10);
|
add_user_option(&global, acl_user->user_resource.connections,
|
||||||
global.append(buff,p-buff);
|
"MAX_CONNECTIONS_PER_HOUR");
|
||||||
}
|
|
||||||
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);
|
thd->packet.length(0);
|
||||||
net_store_data(&thd->packet,global.ptr(),global.length());
|
net_store_data(&thd->packet,global.ptr(),global.length());
|
||||||
@ -2929,7 +2964,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
|||||||
!my_strcasecmp(lex_user->host.str,host))
|
!my_strcasecmp(lex_user->host.str,host))
|
||||||
{
|
{
|
||||||
want_access=acl_db->access;
|
want_access=acl_db->access;
|
||||||
if (want_access)
|
if (want_access)
|
||||||
{
|
{
|
||||||
String db(buff,sizeof(buff));
|
String db(buff,sizeof(buff));
|
||||||
db.length(0);
|
db.length(0);
|
||||||
@ -2938,7 +2973,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
|||||||
if (test_all_bits(want_access,(DB_ACLS & ~GRANT_ACL)))
|
if (test_all_bits(want_access,(DB_ACLS & ~GRANT_ACL)))
|
||||||
db.append("ALL PRIVILEGES",14);
|
db.append("ALL PRIVILEGES",14);
|
||||||
else if (!(want_access & ~GRANT_ACL))
|
else if (!(want_access & ~GRANT_ACL))
|
||||||
db.append("USAGE",5);
|
db.append("USAGE",5);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int found=0, cnt;
|
int found=0, cnt;
|
||||||
@ -2954,13 +2989,13 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
db.append (" ON `",5);
|
db.append(" ON `",5);
|
||||||
db.append(acl_db->db);
|
db.append(acl_db->db);
|
||||||
db.append ("`.* TO '",8);
|
db.append("`.* TO '",8);
|
||||||
db.append(lex_user->user.str,lex_user->user.length);
|
db.append(lex_user->user.str,lex_user->user.length);
|
||||||
db.append ("'@'",3);
|
db.append("'@'",3);
|
||||||
db.append(lex_user->host.str, lex_user->host.length);
|
db.append(lex_user->host.str, lex_user->host.length);
|
||||||
db.append ('\'');
|
db.append('\'');
|
||||||
if (want_access & GRANT_ACL)
|
if (want_access & GRANT_ACL)
|
||||||
db.append(" WITH GRANT OPTION",18);
|
db.append(" WITH GRANT OPTION",18);
|
||||||
thd->packet.length(0);
|
thd->packet.length(0);
|
||||||
@ -2979,7 +3014,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
|||||||
for (index=0 ; index < hash_tables.records ; index++)
|
for (index=0 ; index < hash_tables.records ; index++)
|
||||||
{
|
{
|
||||||
const char *user,*host;
|
const char *user,*host;
|
||||||
GRANT_TABLE *grant_table= (GRANT_TABLE*) hash_element(&hash_tables,index);
|
GRANT_TABLE *grant_table= (GRANT_TABLE*) hash_element(&hash_tables,index);
|
||||||
|
|
||||||
if (!(user=grant_table->user))
|
if (!(user=grant_table->user))
|
||||||
user="";
|
user="";
|
||||||
@ -2989,44 +3024,54 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
|||||||
if (!strcmp(lex_user->user.str,user) &&
|
if (!strcmp(lex_user->user.str,user) &&
|
||||||
!my_strcasecmp(lex_user->host.str,host))
|
!my_strcasecmp(lex_user->host.str,host))
|
||||||
{
|
{
|
||||||
want_access=grant_table->privs;
|
ulong table_access= grant_table->privs;
|
||||||
if ((want_access | grant_table->cols) != 0)
|
if ((table_access | grant_table->cols) != 0)
|
||||||
{
|
{
|
||||||
String global(buff,sizeof(buff));
|
String global(buff,sizeof(buff));
|
||||||
global.length(0);
|
global.length(0);
|
||||||
global.append("GRANT ",6);
|
global.append("GRANT ",6);
|
||||||
|
|
||||||
if (test_all_bits(grant_table->privs,(TABLE_ACLS & ~GRANT_ACL)))
|
if (test_all_bits(table_access, (TABLE_ACLS & ~GRANT_ACL)))
|
||||||
global.append("ALL PRIVILEGES",14);
|
global.append("ALL PRIVILEGES",14);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int found=0;
|
int found= 0;
|
||||||
ulong j,test_access= (want_access | grant_table->cols) & ~GRANT_ACL;
|
ulong j,test_access= (table_access | grant_table->cols) & ~GRANT_ACL;
|
||||||
|
|
||||||
for (counter=0, j = SELECT_ACL;j <= TABLE_ACLS; counter++,j <<= 1)
|
for (counter= 0, j= SELECT_ACL; j <= TABLE_ACLS; counter++, j<<= 1)
|
||||||
{
|
{
|
||||||
if (test_access & j)
|
if (test_access & j)
|
||||||
{
|
{
|
||||||
if (found)
|
if (found)
|
||||||
global.append(", ",2);
|
global.append(", ",2);
|
||||||
found = 1;
|
found= 1;
|
||||||
global.append(command_array[counter],command_lengths[counter]);
|
global.append(command_array[counter],command_lengths[counter]);
|
||||||
|
|
||||||
if (grant_table->cols)
|
if (grant_table->cols)
|
||||||
{
|
{
|
||||||
uint found_col=0;
|
uint found_col= 0;
|
||||||
for (uint col_index=0 ;
|
for (uint col_index=0 ;
|
||||||
col_index < grant_table->hash_columns.records ;
|
col_index < grant_table->hash_columns.records ;
|
||||||
col_index++)
|
col_index++)
|
||||||
{
|
{
|
||||||
GRANT_COLUMN *grant_column = (GRANT_COLUMN*)
|
GRANT_COLUMN *grant_column = (GRANT_COLUMN*)
|
||||||
hash_element(&grant_table->hash_columns,col_index);
|
hash_element(&grant_table->hash_columns,col_index);
|
||||||
if (grant_column->rights & j)
|
if (grant_column->rights & j)
|
||||||
{
|
{
|
||||||
if (!found_col)
|
if (!found_col)
|
||||||
{
|
{
|
||||||
|
found_col= 1;
|
||||||
|
/*
|
||||||
|
If we have a duplicated table level privilege, we
|
||||||
|
must write the access privilege name again.
|
||||||
|
*/
|
||||||
|
if (table_access & j)
|
||||||
|
{
|
||||||
|
global.append(", ", 2);
|
||||||
|
global.append(command_array[counter],
|
||||||
|
command_lengths[counter]);
|
||||||
|
}
|
||||||
global.append(" (",2);
|
global.append(" (",2);
|
||||||
found_col=1;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
global.append(", ",2);
|
global.append(", ",2);
|
||||||
@ -3045,12 +3090,12 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
|||||||
global.append("`.`",3);
|
global.append("`.`",3);
|
||||||
global.append(grant_table->tname);
|
global.append(grant_table->tname);
|
||||||
global.append("` TO '",6);
|
global.append("` TO '",6);
|
||||||
global.append(lex_user->user.str,lex_user->user.length);
|
global.append(lex_user->user.str,lex_user->user.length);
|
||||||
global.append("'@'",3);
|
global.append("'@'",3);
|
||||||
global.append(lex_user->host.str,lex_user->host.length);
|
global.append(lex_user->host.str,lex_user->host.length);
|
||||||
global.append('\'');
|
global.append('\'');
|
||||||
if (want_access & GRANT_ACL)
|
if (table_access & GRANT_ACL)
|
||||||
global.append(" WITH GRANT OPTION",18);
|
global.append(" WITH GRANT OPTION",18);
|
||||||
thd->packet.length(0);
|
thd->packet.length(0);
|
||||||
net_store_data(&thd->packet,global.ptr(),global.length());
|
net_store_data(&thd->packet,global.ptr(),global.length());
|
||||||
if (my_net_write(&thd->net,(char*) thd->packet.ptr(),
|
if (my_net_write(&thd->net,(char*) thd->packet.ptr(),
|
||||||
@ -3063,7 +3108,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
end:
|
end:
|
||||||
VOID(pthread_mutex_unlock(&acl_cache->lock));
|
VOID(pthread_mutex_unlock(&acl_cache->lock));
|
||||||
pthread_mutex_unlock(&LOCK_grant);
|
pthread_mutex_unlock(&LOCK_grant);
|
||||||
|
|
||||||
|
@ -76,8 +76,8 @@
|
|||||||
#define get_rights_for_db(A) (((A) & 63) | (((A) & DB_CHUNK1) >> 4) | (((A) & DB_CHUNK2) >> 6))
|
#define get_rights_for_db(A) (((A) & 63) | (((A) & DB_CHUNK1) >> 4) | (((A) & DB_CHUNK2) >> 6))
|
||||||
#define fix_rights_for_table(A) (((A) & 63) | (((A) & ~63) << 4))
|
#define fix_rights_for_table(A) (((A) & 63) | (((A) & ~63) << 4))
|
||||||
#define get_rights_for_table(A) (((A) & 63) | (((A) & ~63) >> 4))
|
#define get_rights_for_table(A) (((A) & 63) | (((A) & ~63) >> 4))
|
||||||
#define fix_rights_for_column(A) (((A) & 7) | (((A) & ~7) << 7))
|
#define fix_rights_for_column(A) (((A) & 7) | (((A) & ~7) << 8))
|
||||||
#define get_rights_for_column(A) (((A) & 7) | (((A) & ~7) >> 7))
|
#define get_rights_for_column(A) (((A) & 7) | ((A) >> 8))
|
||||||
|
|
||||||
/* prototypes */
|
/* prototypes */
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user