mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Added the following new privleges:
SHOW DATABASES CREATE TEMPORARY TABLE LOCK TABLES REPLICATION SLAVE & REPLICATION CLIENT SUPER EXECUTE All scripts & documentation is updated for this change. Added better error messages for global privileges BitKeeper/deleted/.del-mysql_new_fix_privilege_tables.sh~b1664b401375eece: Delete: scripts/mysql_new_fix_privilege_tables.sh Docs/manual.texi: Updated manual for privilege changes. include/mysqld_error.h: new error messages mysql-test/install_test_db.sh: Updated to use new privileges mysql-test/r/grant_cache.result: Updated to use new privileges mysql-test/r/rpl000017.result: Updated to use new privileges mysql-test/t/rpl000017.test: Updated to use new privileges mysys/safemalloc.c: Cleanup scripts/mysql_fix_privilege_tables.sh: Updated to use new privileges scripts/mysql_install_db.sh: Updated to use new privileges sql/field.h: Cleanup sql/item_strfunc.cc: Updated to use new privileges sql/lex.h: Updated to use new privileges sql/log.cc: Updated to use new privileges sql/mysql_priv.h: Updated to use new privileges sql/mysqld.cc: Updated to use new privileges sql/repl_failsafe.cc: Updated to use new privileges sql/share/czech/errmsg.txt: new error messages sql/share/danish/errmsg.txt: new error messages sql/share/dutch/errmsg.txt: new error messages sql/share/english/errmsg.txt: new error messages sql/share/estonian/errmsg.txt: new error messages sql/share/french/errmsg.txt: new error messages sql/share/german/errmsg.txt: new error messages sql/share/greek/errmsg.txt: new error messages sql/share/hungarian/errmsg.txt: new error messages sql/share/italian/errmsg.txt: new error messages sql/share/japanese/errmsg.txt: new error messages sql/share/korean/errmsg.txt: new error messages sql/share/norwegian-ny/errmsg.txt: new error messages sql/share/norwegian/errmsg.txt: new error messages sql/share/polish/errmsg.txt: new error messages sql/share/portuguese/errmsg.txt: new error messages sql/share/romanian/errmsg.txt: new error messages sql/share/russian/errmsg.txt: new error messages sql/share/slovak/errmsg.txt: new error messages sql/share/spanish/errmsg.txt: new error messages sql/share/swedish/errmsg.txt: new error messages sql/share/ukrainian/errmsg.txt: new error messages sql/slave.cc: Portability cleanup sql/sql_acl.cc: Updated to use new privileges sql/sql_acl.h: Updated to use new privileges sql/sql_base.cc: Remove not used include file sql/sql_class.cc: Comment cleanup sql/sql_class.h: Updated to use new privileges Comment cleanups sql/sql_insert.cc: Updated to use new privileges sql/sql_lex.h: Indentation cleanup sql/sql_parse.cc: Updated to use new privileges sql/sql_repl.cc: Updated to use new privileges Comment cleanup sql/sql_show.cc: Updated to use new privileges sql/sql_yacc.yy: Updated to use new privileges Sorted some tockens for easer merge to 4.1 in the future. sql/table.h: Updated to use new privileges tests/grant.pl: Updated to use new privileges tests/grant.res: Updated to use new privileges
This commit is contained in:
463
sql/sql_acl.cc
463
sql/sql_acl.cc
@ -31,22 +31,22 @@
|
||||
#include <m_ctype.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
/*
|
||||
ACL_HOST is used if no host is specified
|
||||
*/
|
||||
|
||||
struct acl_host_and_ip
|
||||
{
|
||||
char *hostname;
|
||||
long ip,ip_mask; // Used with masked ip:s
|
||||
};
|
||||
|
||||
|
||||
class ACL_ACCESS {
|
||||
public:
|
||||
ulong sort;
|
||||
uint access;
|
||||
ulong access;
|
||||
};
|
||||
|
||||
|
||||
/* ACL_HOST is used if no host is specified */
|
||||
|
||||
class ACL_HOST :public ACL_ACCESS
|
||||
{
|
||||
public:
|
||||
@ -54,6 +54,7 @@ public:
|
||||
char *db;
|
||||
};
|
||||
|
||||
|
||||
class ACL_USER :public ACL_ACCESS
|
||||
{
|
||||
public:
|
||||
@ -68,6 +69,7 @@ public:
|
||||
#endif /* HAVE_OPENSSL */
|
||||
};
|
||||
|
||||
|
||||
class ACL_DB :public ACL_ACCESS
|
||||
{
|
||||
public:
|
||||
@ -75,14 +77,16 @@ public:
|
||||
char *user,*db;
|
||||
};
|
||||
|
||||
|
||||
class acl_entry :public hash_filo_element
|
||||
{
|
||||
public:
|
||||
uint access;
|
||||
ulong access;
|
||||
uint16 length;
|
||||
char key[1]; // Key will be stored here
|
||||
};
|
||||
|
||||
|
||||
static byte* acl_entry_get_key(acl_entry *entry,uint *length,
|
||||
my_bool not_used __attribute__((unused)))
|
||||
{
|
||||
@ -100,7 +104,7 @@ static HASH acl_check_hosts, hash_tables;
|
||||
static DYNAMIC_ARRAY acl_wild_hosts;
|
||||
static hash_filo *acl_cache;
|
||||
static uint grant_version=0;
|
||||
static uint get_access(TABLE *form,uint fieldnr);
|
||||
static ulong get_access(TABLE *form,uint fieldnr);
|
||||
static int acl_compare(ACL_ACCESS *a,ACL_ACCESS *b);
|
||||
static ulong get_sort(uint count,...);
|
||||
static void init_check_host(void);
|
||||
@ -195,10 +199,10 @@ int acl_init(bool dont_read_acl_tables)
|
||||
{
|
||||
ACL_HOST host;
|
||||
update_hostname(&host.host,get_field(&mem, table,0));
|
||||
host.db=get_field(&mem, table,1);
|
||||
host.access=get_access(table,2);
|
||||
host.access=fix_rights_for_db(host.access);
|
||||
host.sort=get_sort(2,host.host.hostname,host.db);
|
||||
host.db= get_field(&mem, table,1);
|
||||
host.access= get_access(table,2);
|
||||
host.access= fix_rights_for_db(host.access);
|
||||
host.sort= get_sort(2,host.host.hostname,host.db);
|
||||
#ifndef TO_BE_REMOVED
|
||||
if (table->fields == 8)
|
||||
{ // Without grant
|
||||
@ -223,6 +227,7 @@ int acl_init(bool dont_read_acl_tables)
|
||||
protocol_version=9; /* purecov: tested */
|
||||
}
|
||||
|
||||
DBUG_PRINT("info",("user table fields: %d",table->fields));
|
||||
allow_all_hosts=0;
|
||||
while (!(read_record_info.read_record(&read_record_info)))
|
||||
{
|
||||
@ -231,26 +236,6 @@ int acl_init(bool dont_read_acl_tables)
|
||||
update_hostname(&user.host,get_field(&mem, table,0));
|
||||
user.user=get_field(&mem, table,1);
|
||||
user.password=get_field(&mem, table,2);
|
||||
#ifdef HAVE_OPENSSL
|
||||
DBUG_PRINT("info",("table->fields=%d",table->fields));
|
||||
if (table->fields >= 21) /* From 4.0.0 we have more fields */
|
||||
{
|
||||
char *ssl_type=get_field(&mem, table,17);
|
||||
if (!strcmp(ssl_type, "ANY"))
|
||||
user.ssl_type=SSL_TYPE_ANY;
|
||||
else if (!strcmp(ssl_type, "X509"))
|
||||
user.ssl_type=SSL_TYPE_X509;
|
||||
else if (!strcmp(ssl_type, "SPECIFIED"))
|
||||
user.ssl_type=SSL_TYPE_SPECIFIED;
|
||||
else
|
||||
user.ssl_type=SSL_TYPE_NONE;
|
||||
user.ssl_cipher=get_field(&mem, table, 18);
|
||||
user.x509_issuer=get_field(&mem, table, 19);
|
||||
user.x509_subject=get_field(&mem, table, 20);
|
||||
}
|
||||
else
|
||||
user.ssl_type=SSL_TYPE_NONE;
|
||||
#endif /* HAVE_OPENSSL */
|
||||
if (user.password && (length=(uint) strlen(user.password)) == 8 &&
|
||||
protocol_version == PROTOCOL_VERSION)
|
||||
{
|
||||
@ -264,35 +249,60 @@ int acl_init(bool dont_read_acl_tables)
|
||||
"Found invalid password for user: '%s@%s'; Ignoring user",
|
||||
user.user ? user.user : "",
|
||||
user.host.hostname ? user.host.hostname : ""); /* purecov: tested */
|
||||
continue; /* purecov: tested */
|
||||
continue; /* purecov: tested */
|
||||
}
|
||||
get_salt_from_password(user.salt,user.password);
|
||||
user.access=get_access(table,3);
|
||||
user.sort=get_sort(2,user.host.hostname,user.user);
|
||||
user.hostname_length= (user.host.hostname ?
|
||||
(uint) strlen(user.host.hostname) : 0);
|
||||
if (table->fields >= 23)
|
||||
if (table->fields >= 31) /* Starting from 4.0.2 we have more fields */
|
||||
{
|
||||
/* Table has new MySQL usage limits */
|
||||
char *ptr = get_field(&mem, table, 21);
|
||||
#ifdef HAVE_OPENSSL
|
||||
char *ssl_type=get_field(&mem, table, 24);
|
||||
if (!ssl_type)
|
||||
user.ssl_type=SSL_TYPE_NONE;
|
||||
else if (!strcmp(ssl_type, "ANY"))
|
||||
user.ssl_type=SSL_TYPE_ANY;
|
||||
else if (!strcmp(ssl_type, "X509"))
|
||||
user.ssl_type=SSL_TYPE_X509;
|
||||
else /* !strcmp(ssl_type, "SPECIFIED") */
|
||||
user.ssl_type=SSL_TYPE_SPECIFIED;
|
||||
|
||||
user.ssl_cipher= get_field(&mem, table, 25);
|
||||
user.x509_issuer= get_field(&mem, table, 26);
|
||||
user.x509_subject= get_field(&mem, table, 27);
|
||||
#endif
|
||||
char *ptr = get_field(&mem, table, 28);
|
||||
user.user_resource.questions=atoi(ptr);
|
||||
ptr = get_field(&mem, table, 22);
|
||||
ptr = get_field(&mem, table, 29);
|
||||
user.user_resource.updates=atoi(ptr);
|
||||
ptr = get_field(&mem, table, 23);
|
||||
ptr = get_field(&mem, table, 30);
|
||||
user.user_resource.connections=atoi(ptr);
|
||||
if (user.user_resource.questions || user.user_resource.updates ||
|
||||
user.user_resource.connections)
|
||||
mqh_used=1;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef HAVE_OPENSSL
|
||||
user.ssl_type=SSL_TYPE_NONE;
|
||||
#endif
|
||||
bzero(&(user.user_resource),sizeof(user.user_resource));
|
||||
#ifndef TO_BE_REMOVED
|
||||
if (table->fields <= 13)
|
||||
{ // Without grant
|
||||
if (user.access & CREATE_ACL)
|
||||
user.access|=REFERENCES_ACL | INDEX_ACL | ALTER_ACL;
|
||||
}
|
||||
if (table->fields <= 13)
|
||||
{ // Without grant
|
||||
if (user.access & CREATE_ACL)
|
||||
user.access|=REFERENCES_ACL | INDEX_ACL | ALTER_ACL;
|
||||
}
|
||||
/* Convert old privileges */
|
||||
user.access|= LOCK_TABLES_ACL | CREATE_TMP_ACL | SHOW_DB_ACL;
|
||||
if (user.access & FILE_ACL)
|
||||
user.access|= REPL_CLIENT_ACL | REPL_SLAVE_ACL;
|
||||
if (user.access & PROCESS_ACL)
|
||||
user.access|= SUPER_ACL | EXECUTE_ACL;
|
||||
#endif
|
||||
}
|
||||
VOID(push_dynamic(&acl_users,(gptr) &user));
|
||||
if (!user.host.hostname || user.host.hostname[0] == wild_many &&
|
||||
!user.host.hostname[1])
|
||||
@ -403,31 +413,38 @@ void acl_reload(void)
|
||||
}
|
||||
|
||||
|
||||
/* Get all access bits from table after fieldnr */
|
||||
/*
|
||||
Get all access bits from table after fieldnr
|
||||
We know that the access privileges ends when there is no more fields
|
||||
or the field is not an enum with two elements.
|
||||
*/
|
||||
|
||||
static uint get_access(TABLE *form,uint fieldnr)
|
||||
static ulong get_access(TABLE *form, uint fieldnr)
|
||||
{
|
||||
uint access_bits=0,bit;
|
||||
ulong access_bits=0,bit;
|
||||
char buff[2];
|
||||
String res(buff,sizeof(buff));
|
||||
Field **pos;
|
||||
|
||||
for (pos=form->field+fieldnr,bit=1 ; *pos ; pos++ , bit<<=1)
|
||||
for (pos=form->field+fieldnr, bit=1;
|
||||
*pos && (*pos)->real_type() == FIELD_TYPE_ENUM &&
|
||||
((Field_enum*) (*pos))->typelib->count == 2 ;
|
||||
pos++ , bit<<=1)
|
||||
{
|
||||
(*pos)->val_str(&res,&res);
|
||||
if (toupper(res[0]) == 'Y')
|
||||
access_bits|=bit;
|
||||
access_bits|= bit;
|
||||
}
|
||||
return access_bits;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
return a number which, if sorted 'desc', puts strings in this order:
|
||||
no wildcards
|
||||
wildcards
|
||||
empty string
|
||||
*/
|
||||
Return a number which, if sorted 'desc', puts strings in this order:
|
||||
no wildcards
|
||||
wildcards
|
||||
empty string
|
||||
*/
|
||||
|
||||
static ulong get_sort(uint count,...)
|
||||
{
|
||||
@ -472,17 +489,17 @@ static int acl_compare(ACL_ACCESS *a,ACL_ACCESS *b)
|
||||
Required before connecting to MySQL
|
||||
*/
|
||||
|
||||
uint acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
|
||||
const char *password,const char *message,char **priv_user,
|
||||
bool old_ver, USER_RESOURCES *mqh)
|
||||
ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
|
||||
const char *password,const char *message,char **priv_user,
|
||||
bool old_ver, USER_RESOURCES *mqh)
|
||||
{
|
||||
uint user_access=NO_ACCESS;
|
||||
ulong user_access=NO_ACCESS;
|
||||
*priv_user=(char*) user;
|
||||
char *ptr=0;
|
||||
|
||||
bzero(mqh,sizeof(USER_RESOURCES));
|
||||
if (!initialized)
|
||||
return (uint) ~NO_ACCESS; // If no data allow anything /* purecov: tested */
|
||||
return (ulong) ~NO_ACCESS; // If no data allow anything /* purecov: tested */
|
||||
VOID(pthread_mutex_lock(&acl_cache->lock));
|
||||
|
||||
/*
|
||||
@ -509,7 +526,7 @@ uint acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
|
||||
we check if SSL is required, if user is using SSL and
|
||||
if X509 certificate attributes are OK
|
||||
*/
|
||||
switch(acl_user->ssl_type) {
|
||||
switch (acl_user->ssl_type) {
|
||||
case SSL_TYPE_NONE: /* SSL is not required to connect */
|
||||
user_access=acl_user->access;
|
||||
break;
|
||||
@ -581,10 +598,8 @@ uint acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
|
||||
}
|
||||
free(ptr);
|
||||
}
|
||||
DBUG_PRINT("info",("checkpoint 5"));
|
||||
break;
|
||||
}
|
||||
DBUG_PRINT("info",("checkpoint 6"));
|
||||
#else /* HAVE_OPENSSL */
|
||||
user_access=acl_user->access;
|
||||
#endif /* HAVE_OPENSSL */
|
||||
@ -623,7 +638,7 @@ static void acl_update_user(const char *user, const char *host,
|
||||
const char *x509_issuer,
|
||||
const char *x509_subject,
|
||||
USER_RESOURCES *mqh,
|
||||
uint privileges)
|
||||
ulong privileges)
|
||||
{
|
||||
for (uint i=0 ; i < acl_users.elements ; i++)
|
||||
{
|
||||
@ -667,7 +682,7 @@ static void acl_insert_user(const char *user, const char *host,
|
||||
const char *x509_issuer,
|
||||
const char *x509_subject,
|
||||
USER_RESOURCES *mqh,
|
||||
uint privileges)
|
||||
ulong privileges)
|
||||
{
|
||||
ACL_USER acl_user;
|
||||
acl_user.user=strdup_root(&mem,user);
|
||||
@ -704,7 +719,7 @@ static void acl_insert_user(const char *user, const char *host,
|
||||
|
||||
|
||||
static void acl_update_db(const char *user, const char *host, const char *db,
|
||||
uint privileges)
|
||||
ulong privileges)
|
||||
{
|
||||
for (uint i=0 ; i < acl_dbs.elements ; i++)
|
||||
{
|
||||
@ -731,7 +746,7 @@ static void acl_update_db(const char *user, const char *host, const char *db,
|
||||
|
||||
|
||||
static void acl_insert_db(const char *user, const char *host, const char *db,
|
||||
uint privileges)
|
||||
ulong privileges)
|
||||
{
|
||||
ACL_DB acl_db;
|
||||
/* The acl_cache mutex is locked by mysql_grant */
|
||||
@ -750,10 +765,11 @@ static void acl_insert_db(const char *user, const char *host, const char *db,
|
||||
** Get privilege for a host, user and db combination
|
||||
*****************************************************************************/
|
||||
|
||||
uint acl_get(const char *host, const char *ip, const char *bin_ip,
|
||||
ulong acl_get(const char *host, const char *ip, const char *bin_ip,
|
||||
const char *user, const char *db)
|
||||
{
|
||||
uint host_access,db_access,i,key_length;
|
||||
ulong host_access,db_access;
|
||||
uint i,key_length;
|
||||
db_access=0; host_access= ~0;
|
||||
char key[ACL_KEY_LENGTH],*tmp_db,*end;
|
||||
acl_entry *entry;
|
||||
@ -1104,7 +1120,7 @@ static bool compare_hostname(const acl_host_and_ip *host, const char *hostname,
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
** Code to update grants in the user and database privilege tables
|
||||
Code to update grants in the user and database privilege tables
|
||||
****************************************************************************/
|
||||
|
||||
static bool update_user_table(THD *thd, const char *host, const char *user,
|
||||
@ -1154,10 +1170,10 @@ static bool test_if_create_new_users(THD *thd)
|
||||
if (opt_safe_user_create && !(thd->master_access & INSERT_ACL))
|
||||
{
|
||||
TABLE_LIST tl;
|
||||
uint db_access;
|
||||
ulong db_access;
|
||||
bzero((char*) &tl,sizeof(tl));
|
||||
tl.db= (char*) "mysql";
|
||||
tl.real_name= (char*) "user";
|
||||
tl.real_name= (char*) "user";
|
||||
db_access=acl_get(thd->host, thd->ip, (char*) &thd->remote.sin_addr,
|
||||
thd->priv_user, tl.db);
|
||||
if (!(db_access & INSERT_ACL))
|
||||
@ -1175,12 +1191,13 @@ static bool test_if_create_new_users(THD *thd)
|
||||
****************************************************************************/
|
||||
|
||||
static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
|
||||
uint rights, char what, bool create_user)
|
||||
ulong rights, bool revoke_grant,
|
||||
bool create_user)
|
||||
{
|
||||
int error = -1;
|
||||
uint i,j;
|
||||
bool old_row_exists=0;
|
||||
char *password,empty_string[1];
|
||||
char what= (revoke_grant) ? 'N' : 'Y';
|
||||
DBUG_ENTER("replace_user_table");
|
||||
|
||||
password=empty_string;
|
||||
@ -1231,55 +1248,58 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
|
||||
table->field[2]->store(password,(uint) strlen(password));
|
||||
}
|
||||
|
||||
for (i = 3, j = SELECT_ACL; // starting from reload
|
||||
i < table->fields;
|
||||
i++, j <<= 1)
|
||||
/* Update table columns with new privileges */
|
||||
|
||||
Field **tmp_field;
|
||||
ulong priv;
|
||||
for (tmp_field= table->field+3, priv = SELECT_ACL;
|
||||
*tmp_field && (*tmp_field)->real_type() == FIELD_TYPE_ENUM &&
|
||||
((Field_enum*) (*tmp_field))->typelib->count == 2 ;
|
||||
tmp_field++, priv <<= 1)
|
||||
{
|
||||
if (j & rights) // set requested privileges
|
||||
table->field[i]->store(&what,1);
|
||||
if (priv & rights) // set requested privileges
|
||||
(*tmp_field)->store(&what,1);
|
||||
}
|
||||
rights=get_access(table,3);
|
||||
#ifdef HAVE_OPENSSL
|
||||
/* We write down SSL related ACL stuff */
|
||||
DBUG_PRINT("info",("table->fields: %d",table->fields));
|
||||
if (table->fields >= 21) /* From 4.0.0 we have more fields */
|
||||
if (table->fields >= 31) /* From 4.0.0 we have more fields */
|
||||
{
|
||||
table->field[18]->store("",0);
|
||||
table->field[19]->store("",0);
|
||||
table->field[20]->store("",0);
|
||||
#ifdef HAVE_OPENSSL
|
||||
/* We write down SSL related ACL stuff */
|
||||
table->field[25]->store("",0);
|
||||
table->field[26]->store("",0);
|
||||
table->field[27]->store("",0);
|
||||
switch (thd->lex.ssl_type) {
|
||||
case SSL_TYPE_ANY:
|
||||
table->field[17]->store("ANY",3);
|
||||
table->field[24]->store("ANY",3);
|
||||
break;
|
||||
case SSL_TYPE_X509:
|
||||
table->field[17]->store("X509",4);
|
||||
table->field[24]->store("X509",4);
|
||||
break;
|
||||
case SSL_TYPE_SPECIFIED:
|
||||
table->field[17]->store("SPECIFIED",9);
|
||||
table->field[24]->store("SPECIFIED",9);
|
||||
if (thd->lex.ssl_cipher)
|
||||
table->field[18]->store(thd->lex.ssl_cipher,
|
||||
table->field[25]->store(thd->lex.ssl_cipher,
|
||||
strlen(thd->lex.ssl_cipher));
|
||||
if (thd->lex.x509_issuer)
|
||||
table->field[19]->store(thd->lex.x509_issuer,
|
||||
table->field[26]->store(thd->lex.x509_issuer,
|
||||
strlen(thd->lex.x509_issuer));
|
||||
if (thd->lex.x509_subject)
|
||||
table->field[20]->store(thd->lex.x509_subject,
|
||||
table->field[27]->store(thd->lex.x509_subject,
|
||||
strlen(thd->lex.x509_subject));
|
||||
break;
|
||||
default:
|
||||
table->field[17]->store("NONE",4);
|
||||
table->field[24]->store("",0);
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_OPENSSL */
|
||||
if (table->fields >= 23)
|
||||
{
|
||||
|
||||
USER_RESOURCES mqh = thd->lex.mqh;
|
||||
if (mqh.questions)
|
||||
table->field[21]->store((longlong) mqh.questions);
|
||||
table->field[28]->store((longlong) mqh.questions);
|
||||
if (mqh.updates)
|
||||
table->field[22]->store((longlong) mqh.updates);
|
||||
table->field[29]->store((longlong) mqh.updates);
|
||||
if (mqh.connections)
|
||||
table->field[23]->store((longlong) mqh.connections);
|
||||
table->field[30]->store((longlong) mqh.connections);
|
||||
mqh_used = mqh_used || mqh.questions || mqh.updates || mqh.connections;
|
||||
}
|
||||
if (old_row_exists)
|
||||
@ -1337,16 +1357,18 @@ end:
|
||||
|
||||
|
||||
/*
|
||||
** change grants in the mysql.db table
|
||||
change grants in the mysql.db table
|
||||
*/
|
||||
|
||||
static int replace_db_table(TABLE *table, const char *db,
|
||||
const LEX_USER &combo,
|
||||
uint rights, char what)
|
||||
ulong rights, bool revoke_grant)
|
||||
{
|
||||
uint i,j,store_rights;
|
||||
uint i;
|
||||
ulong priv,store_rights;
|
||||
bool old_row_exists=0;
|
||||
int error;
|
||||
char what= (revoke_grant) ? 'N' : 'Y';
|
||||
DBUG_ENTER("replace_db_table");
|
||||
|
||||
// is there such a user in user table in memory ????
|
||||
@ -1382,9 +1404,9 @@ static int replace_db_table(TABLE *table, const char *db,
|
||||
}
|
||||
|
||||
store_rights=get_rights_for_db(rights);
|
||||
for (i = 3, j = 1; i < table->fields; i++, j <<= 1)
|
||||
for (i= 3, priv= 1; i < table->fields; i++, priv <<= 1)
|
||||
{
|
||||
if (j & store_rights) // do it if priv is chosen
|
||||
if (priv & store_rights) // do it if priv is chosen
|
||||
table->field [i]->store(&what,1); // set requested privileges
|
||||
}
|
||||
rights=get_access(table,3);
|
||||
@ -1432,13 +1454,15 @@ class GRANT_COLUMN :public Sql_alloc
|
||||
{
|
||||
public:
|
||||
char *column;
|
||||
uint rights, key_length;
|
||||
GRANT_COLUMN(String &c, uint y) :rights (y)
|
||||
ulong rights;
|
||||
uint key_length;
|
||||
GRANT_COLUMN(String &c, ulong y) :rights (y)
|
||||
{
|
||||
column= memdup_root(&memex,c.ptr(),key_length=c.length());
|
||||
column= memdup_root(&memex,c.ptr(), key_length=c.length());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static byte* get_key_column(GRANT_COLUMN *buff,uint *length,
|
||||
my_bool not_used __attribute__((unused)))
|
||||
{
|
||||
@ -1446,14 +1470,16 @@ static byte* get_key_column(GRANT_COLUMN *buff,uint *length,
|
||||
return (byte*) buff->column;
|
||||
}
|
||||
|
||||
|
||||
class GRANT_TABLE :public Sql_alloc
|
||||
{
|
||||
public:
|
||||
char *host,*db,*user,*tname, *hash_key;
|
||||
uint privs, cols, key_length;
|
||||
ulong privs, cols;
|
||||
uint key_length;
|
||||
HASH hash_columns;
|
||||
GRANT_TABLE (const char *h, const char *d,const char *u, const char *t,
|
||||
uint p,uint c)
|
||||
ulong p, ulong c)
|
||||
: privs(p), cols(c)
|
||||
{
|
||||
host = strdup_root(&memex,h);
|
||||
@ -1478,7 +1504,9 @@ public:
|
||||
|
||||
host = get_field(&memex,form,0);
|
||||
db = get_field(&memex,form,1);
|
||||
user = get_field(&memex,form,2); if (!user) user=(char*) "";
|
||||
user = get_field(&memex,form,2);
|
||||
if (!user)
|
||||
user=(char*) "";
|
||||
tname = get_field(&memex,form,3);
|
||||
if (!host || !db || !tname)
|
||||
{
|
||||
@ -1495,8 +1523,8 @@ public:
|
||||
(uint) strlen(tname) + 3);
|
||||
hash_key = (char*) alloc_root(&memex,key_length);
|
||||
strmov(strmov(strmov(hash_key,user)+1,db)+1,tname);
|
||||
privs = (uint) form->field[6]->val_int();
|
||||
cols = (uint) form->field[7]->val_int();
|
||||
privs = (ulong) form->field[6]->val_int();
|
||||
cols = (ulong) form->field[7]->val_int();
|
||||
privs = fix_rights_for_table(privs);
|
||||
cols = fix_rights_for_column(cols);
|
||||
|
||||
@ -1529,7 +1557,7 @@ public:
|
||||
GRANT_COLUMN *mem_check;
|
||||
/* As column name is a string, we don't have to supply a buffer */
|
||||
res=col_privs->field[4]->val_str(&column_name,&column_name);
|
||||
uint priv= (uint) col_privs->field[6]->val_int();
|
||||
ulong priv= (ulong) col_privs->field[6]->val_int();
|
||||
if (!(mem_check = new GRANT_COLUMN(*res,
|
||||
fix_rights_for_column(priv))))
|
||||
{
|
||||
@ -1545,6 +1573,7 @@ public:
|
||||
bool ok() { return privs != 0 || cols != 0; }
|
||||
};
|
||||
|
||||
|
||||
static byte* get_grant_table(GRANT_TABLE *buff,uint *length,
|
||||
my_bool not_used __attribute__((unused)))
|
||||
{
|
||||
@ -1552,11 +1581,13 @@ static byte* get_grant_table(GRANT_TABLE *buff,uint *length,
|
||||
return (byte*) buff->hash_key;
|
||||
}
|
||||
|
||||
|
||||
void free_grant_table(GRANT_TABLE *grant_table)
|
||||
{
|
||||
hash_free(&grant_table->hash_columns);
|
||||
}
|
||||
|
||||
|
||||
/* Search after a matching grant. Prefer exact grants before not exact ones */
|
||||
|
||||
static GRANT_TABLE *table_hash_search(const char *host,const char* ip,
|
||||
@ -1593,8 +1624,7 @@ static GRANT_TABLE *table_hash_search(const char *host,const char* ip,
|
||||
|
||||
|
||||
inline GRANT_COLUMN *
|
||||
column_hash_search(GRANT_TABLE *t, const char *cname,
|
||||
uint length)
|
||||
column_hash_search(GRANT_TABLE *t, const char *cname, uint length)
|
||||
{
|
||||
return (GRANT_COLUMN*) hash_search(&t->hash_columns, (byte*) cname,length);
|
||||
}
|
||||
@ -1604,7 +1634,7 @@ static int replace_column_table(GRANT_TABLE *g_t,
|
||||
TABLE *table, const LEX_USER &combo,
|
||||
List <LEX_COLUMN> &columns,
|
||||
const char *db, const char *table_name,
|
||||
uint rights, bool revoke_grant)
|
||||
ulong rights, bool revoke_grant)
|
||||
{
|
||||
int error=0,result=0;
|
||||
uint key_length;
|
||||
@ -1628,7 +1658,7 @@ static int replace_column_table(GRANT_TABLE *g_t,
|
||||
table->file->index_init(0);
|
||||
while ((xx=iter++))
|
||||
{
|
||||
uint privileges = xx->rights;
|
||||
ulong privileges = xx->rights;
|
||||
bool old_row_exists=0;
|
||||
key_restore(table,key,0,key_length);
|
||||
table->field[4]->store(xx->column.ptr(),xx->column.length());
|
||||
@ -1651,7 +1681,7 @@ static int replace_column_table(GRANT_TABLE *g_t,
|
||||
}
|
||||
else
|
||||
{
|
||||
uint tmp= (uint) table->field[6]->val_int();
|
||||
ulong tmp= (ulong) table->field[6]->val_int();
|
||||
tmp=fix_rights_for_column(tmp);
|
||||
|
||||
if (revoke_grant)
|
||||
@ -1711,7 +1741,7 @@ static int replace_column_table(GRANT_TABLE *g_t,
|
||||
// Scan trough all rows with the same host,db,user and table
|
||||
do
|
||||
{
|
||||
uint privileges = (uint) table->field[6]->val_int();
|
||||
ulong privileges = (ulong) table->field[6]->val_int();
|
||||
privileges=fix_rights_for_column(privileges);
|
||||
store_record(table,1);
|
||||
|
||||
@ -1767,18 +1797,21 @@ static int replace_column_table(GRANT_TABLE *g_t,
|
||||
static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
|
||||
TABLE *table, const LEX_USER &combo,
|
||||
const char *db, const char *table_name,
|
||||
uint rights, uint kolone, bool revoke_grant)
|
||||
ulong rights, ulong col_rights,
|
||||
bool revoke_grant)
|
||||
{
|
||||
char grantor[HOSTNAME_LENGTH+1+USERNAME_LENGTH];
|
||||
int old_row_exists = 1;
|
||||
int error=0;
|
||||
uint store_table_rights,store_col_rights;
|
||||
ulong store_table_rights, store_col_rights;
|
||||
DBUG_ENTER("replace_table_table");
|
||||
|
||||
strxmov(grantor, thd->user, "@", thd->host_or_ip, NullS);
|
||||
|
||||
// The following should always succeed as new users are created before
|
||||
// this function is called!
|
||||
/*
|
||||
The following should always succeed as new users are created before
|
||||
this function is called!
|
||||
*/
|
||||
if (!find_acl_user(combo.host.str,combo.user.str))
|
||||
{
|
||||
my_error(ER_PASSWORD_NO_MATCH,MYF(0)); /* purecov: deadcode */
|
||||
@ -1813,14 +1846,14 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
|
||||
restore_record(table,1); // Get saved record
|
||||
}
|
||||
|
||||
store_table_rights=get_rights_for_table(rights);
|
||||
store_col_rights=get_rights_for_column(kolone);
|
||||
store_table_rights= get_rights_for_table(rights);
|
||||
store_col_rights= get_rights_for_column(col_rights);
|
||||
if (old_row_exists)
|
||||
{
|
||||
uint j,k;
|
||||
ulong j,k;
|
||||
store_record(table,1);
|
||||
j = (uint) table->field[6]->val_int();
|
||||
k = (uint) table->field[7]->val_int();
|
||||
j = (ulong) table->field[6]->val_int();
|
||||
k = (ulong) table->field[7]->val_int();
|
||||
|
||||
if (revoke_grant)
|
||||
{
|
||||
@ -1829,8 +1862,8 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
|
||||
}
|
||||
else
|
||||
{
|
||||
store_table_rights|=j;
|
||||
store_col_rights|=k;
|
||||
store_table_rights|= j;
|
||||
store_col_rights|= k;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1838,7 +1871,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
|
||||
table->field[6]->store((longlong) store_table_rights);
|
||||
table->field[7]->store((longlong) store_col_rights);
|
||||
rights=fix_rights_for_table(store_table_rights);
|
||||
kolone=fix_rights_for_column(store_col_rights);
|
||||
col_rights=fix_rights_for_column(store_col_rights);
|
||||
|
||||
if (old_row_exists)
|
||||
{
|
||||
@ -1857,10 +1890,10 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
|
||||
goto table_error; /* purecov: deadcode */
|
||||
}
|
||||
|
||||
if (rights | kolone)
|
||||
if (rights | col_rights)
|
||||
{
|
||||
grant_table->privs = rights;
|
||||
grant_table->cols = kolone;
|
||||
grant_table->privs= rights;
|
||||
grant_table->cols= col_rights;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1877,18 +1910,15 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
|
||||
|
||||
int mysql_table_grant (THD *thd, TABLE_LIST *table_list,
|
||||
List <LEX_USER> &user_list,
|
||||
List <LEX_COLUMN> &columns, uint rights,
|
||||
List <LEX_COLUMN> &columns, ulong rights,
|
||||
bool revoke_grant)
|
||||
{
|
||||
uint column_priv = 0;
|
||||
ulong column_priv = 0;
|
||||
List_iterator <LEX_USER> str_list (user_list);
|
||||
LEX_USER *Str;
|
||||
TABLE_LIST tables[3];
|
||||
bool create_new_users=0;
|
||||
DBUG_ENTER("mysql_table_grant");
|
||||
DBUG_PRINT("info",("ssl_cipher: %s",thd->lex.ssl_cipher));
|
||||
DBUG_PRINT("info",("x509_issuer: %s",thd->lex.x509_issuer));
|
||||
DBUG_PRINT("info",("x509_subject: %s",thd->lex.x509_subject));
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
@ -1978,12 +2008,8 @@ int mysql_table_grant (THD *thd, TABLE_LIST *table_list,
|
||||
continue;
|
||||
}
|
||||
/* Create user if needed */
|
||||
if (replace_user_table(thd,
|
||||
tables[0].table,
|
||||
*Str,
|
||||
0,
|
||||
revoke_grant ? 'N' : 'Y',
|
||||
create_new_users))
|
||||
if (replace_user_table(thd, tables[0].table, *Str,
|
||||
0, revoke_grant, create_new_users))
|
||||
{
|
||||
result= -1; // Remember error
|
||||
continue; // Add next user
|
||||
@ -2079,12 +2105,12 @@ int mysql_table_grant (THD *thd, TABLE_LIST *table_list,
|
||||
}
|
||||
|
||||
|
||||
int mysql_grant (THD *thd, const char *db, List <LEX_USER> &list, uint rights,
|
||||
bool revoke_grant)
|
||||
int mysql_grant (THD *thd, const char *db, List <LEX_USER> &list,
|
||||
ulong rights, bool revoke_grant)
|
||||
{
|
||||
List_iterator <LEX_USER> str_list (list);
|
||||
LEX_USER *Str;
|
||||
char what,tmp_db[NAME_LEN+1];
|
||||
char tmp_db[NAME_LEN+1];
|
||||
bool create_new_users=0;
|
||||
TABLE_LIST tables[2];
|
||||
DBUG_ENTER("mysql_grant");
|
||||
@ -2095,7 +2121,6 @@ int mysql_grant (THD *thd, const char *db, List <LEX_USER> &list, uint rights,
|
||||
return 1; /* purecov: tested */
|
||||
}
|
||||
|
||||
what = (revoke_grant) ? 'N' : 'Y';
|
||||
if (lower_case_table_names && db)
|
||||
{
|
||||
strmov(tmp_db,db);
|
||||
@ -2144,12 +2169,13 @@ int mysql_grant (THD *thd, const char *db, List <LEX_USER> &list, uint rights,
|
||||
if ((replace_user_table(thd,
|
||||
tables[0].table,
|
||||
*Str,
|
||||
(!db ? rights : 0), what, create_new_users)))
|
||||
(!db ? rights : 0), revoke_grant,
|
||||
create_new_users)))
|
||||
result= -1;
|
||||
else
|
||||
{
|
||||
if (db && replace_db_table(tables[1].table, db, *Str, rights & DB_ACLS,
|
||||
what))
|
||||
revoke_grant))
|
||||
result= -1;
|
||||
}
|
||||
}
|
||||
@ -2162,7 +2188,8 @@ int mysql_grant (THD *thd, const char *db, List <LEX_USER> &list, uint rights,
|
||||
DBUG_RETURN(result);
|
||||
}
|
||||
|
||||
/* Free grant array if possible */
|
||||
|
||||
/* Free grant array if possible */
|
||||
|
||||
void grant_free(void)
|
||||
{
|
||||
@ -2299,11 +2326,11 @@ void grant_reload(void)
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
** Check grants
|
||||
** All errors are written directly to the client if command name is given !
|
||||
Check grants
|
||||
All errors are written directly to the client if command name is given !
|
||||
****************************************************************************/
|
||||
|
||||
bool check_grant(THD *thd, uint want_access, TABLE_LIST *tables,
|
||||
bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
|
||||
uint show_table, bool no_errors)
|
||||
{
|
||||
TABLE_LIST *table;
|
||||
@ -2389,7 +2416,7 @@ bool check_grant_column (THD *thd,TABLE *table, const char *name,
|
||||
GRANT_TABLE *grant_table;
|
||||
GRANT_COLUMN *grant_column;
|
||||
|
||||
uint want_access=table->grant.want_privilege;
|
||||
ulong want_access=table->grant.want_privilege;
|
||||
if (!want_access)
|
||||
return 0; // Already checked
|
||||
|
||||
@ -2427,13 +2454,8 @@ bool check_grant_column (THD *thd,TABLE *table, const char *name,
|
||||
pthread_mutex_unlock(&LOCK_grant);
|
||||
if (!show_tables)
|
||||
{
|
||||
const char *command="";
|
||||
if (want_access & SELECT_ACL)
|
||||
command ="select";
|
||||
else if (want_access & INSERT_ACL)
|
||||
command = "insert";
|
||||
else if (want_access & UPDATE_ACL)
|
||||
command = "update";
|
||||
char command[128];
|
||||
get_privilege_desc(command, sizeof(command), want_access);
|
||||
my_printf_error(ER_COLUMNACCESS_DENIED_ERROR,
|
||||
ER(ER_COLUMNACCESS_DENIED_ERROR),
|
||||
MYF(0),
|
||||
@ -2447,7 +2469,7 @@ bool check_grant_column (THD *thd,TABLE *table, const char *name,
|
||||
}
|
||||
|
||||
|
||||
bool check_grant_all_columns(THD *thd,uint want_access, TABLE *table)
|
||||
bool check_grant_all_columns(THD *thd, ulong want_access, TABLE *table)
|
||||
{
|
||||
GRANT_TABLE *grant_table;
|
||||
GRANT_COLUMN *grant_column;
|
||||
@ -2505,9 +2527,9 @@ bool check_grant_all_columns(THD *thd,uint want_access, TABLE *table)
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
** Check if a user has the right to access a database
|
||||
** Access is accepted if he has a grant for any table in the database
|
||||
** Return 1 if access is denied
|
||||
Check if a user has the right to access a database
|
||||
Access is accepted if he has a grant for any table in the database
|
||||
Return 1 if access is denied
|
||||
****************************************************************************/
|
||||
|
||||
bool check_grant_db(THD *thd,const char *db)
|
||||
@ -2536,10 +2558,10 @@ bool check_grant_db(THD *thd,const char *db)
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
** Functions to retrieve the grant for a table/column (for SHOW functions)
|
||||
Functions to retrieve the grant for a table/column (for SHOW functions)
|
||||
*****************************************************************************/
|
||||
|
||||
uint get_table_grant(THD *thd, TABLE_LIST *table)
|
||||
ulong get_table_grant(THD *thd, TABLE_LIST *table)
|
||||
{
|
||||
char *user = thd->priv_user;
|
||||
const char *db = table->db ? table->db : thd->db;
|
||||
@ -2557,11 +2579,11 @@ uint get_table_grant(THD *thd, TABLE_LIST *table)
|
||||
}
|
||||
|
||||
|
||||
uint get_column_grant(THD *thd, TABLE_LIST *table, Field *field)
|
||||
ulong get_column_grant(THD *thd, TABLE_LIST *table, Field *field)
|
||||
{
|
||||
GRANT_TABLE *grant_table;
|
||||
GRANT_COLUMN *grant_column;
|
||||
uint priv;
|
||||
ulong priv;
|
||||
|
||||
pthread_mutex_lock(&LOCK_grant);
|
||||
// reload table if someone has modified any grants
|
||||
@ -2591,18 +2613,27 @@ uint get_column_grant(THD *thd, TABLE_LIST *table, Field *field)
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** SHOW GRANTS : send to client grant-like strings depicting user@host
|
||||
** privileges
|
||||
SHOW GRANTS : send to client grant-like strings depicting user@host
|
||||
privileges
|
||||
*****************************************************************************/
|
||||
|
||||
static const char *command_array[]=
|
||||
{"SELECT", "INSERT","UPDATE","DELETE","CREATE", "DROP","RELOAD","SHUTDOWN",
|
||||
"PROCESS","FILE","GRANT","REFERENCES","INDEX","ALTER"};
|
||||
static int command_lengths[]={6,6,6,6,6,4,6,8,7,4,5,10,5,5};
|
||||
{
|
||||
"SELECT", "INSERT","UPDATE","DELETE","CREATE", "DROP", "RELOAD","SHUTDOWN",
|
||||
"PROCESS","FILE","GRANT","REFERENCES","INDEX", "ALTER", "SHOW DATABASES",
|
||||
"SUPER", "CREATE TEMPORARY TABLES", "LOCK TABLES", "EXECUTE",
|
||||
"REPLICATION SLAVE", "REPLICATION CLIENT",
|
||||
};
|
||||
static uint command_lengths[]=
|
||||
{
|
||||
6,6,6,6,6,4,6,8,7,4,5,10,5,5,14,5,23,11,7,17,18
|
||||
};
|
||||
|
||||
|
||||
int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
||||
{
|
||||
uint counter, want_access,index;
|
||||
ulong want_access;
|
||||
uint counter,index;
|
||||
int error = 0;
|
||||
ACL_USER *acl_user; ACL_DB *acl_db;
|
||||
char buff[1024];
|
||||
@ -2672,7 +2703,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
||||
else
|
||||
{
|
||||
bool found=0;
|
||||
uint j,test_access= want_access & ~GRANT_ACL;
|
||||
ulong j,test_access= want_access & ~GRANT_ACL;
|
||||
for (counter=0, j = SELECT_ACL;j <= GLOBAL_ACLS;counter++,j <<= 1)
|
||||
{
|
||||
if (test_access & j)
|
||||
@ -2732,28 +2763,34 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_OPENSSL */
|
||||
if (want_access & GRANT_ACL)
|
||||
global.append(" WITH GRANT OPTION",18);
|
||||
if (acl_user->user_resource.questions)
|
||||
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__
|
||||
|
Reference in New Issue
Block a user