diff options
author | unknown <acurtis@xiphis.org> | 2005-05-17 19:54:20 +0100 |
---|---|---|
committer | unknown <acurtis@xiphis.org> | 2005-05-17 19:54:20 +0100 |
commit | 55171821d238704a8b43a7ba4d150384f9ea70e1 (patch) | |
tree | 09011cb747c8c1ed831bf8ca66668d0aa4f2610a /sql/sql_acl.cc | |
parent | 9b07cafe1e7a1230218c06f85b88f68b5741c9ef (diff) | |
download | mariadb-git-55171821d238704a8b43a7ba4d150384f9ea70e1.tar.gz |
Bug#10246 - Parser: bad syntax for GRANT EXECUTE
Rename some functions
more fine-grained sp privileges
make grant/revoke sp grammar less ambigious
mysql-test/r/sp-security.result:
change test for new syntax
mysql-test/r/system_mysql_db.result:
change test for new syntax
mysql-test/t/sp-security.test:
change test for new syntax
scripts/mysql_create_system_tables.sh:
now store routine_type for procs_priv
scripts/mysql_fix_privilege_tables.sql:
now store routine_type for procs_priv
sql/item_func.cc:
rename of function
sql/mysql_priv.h:
rename of function
sql/sp_head.cc:
extra arg for check_some_routine_access
sql/sql_acl.cc:
rename of function. now handle func/proc acls seperately
sql/sql_acl.h:
rename of function
sql/sql_parse.cc:
rename of function
grants for procs handled distinctly from funcs
sql/sql_show.cc:
check_some_routine_access extra arg
sql/sql_base.cc:
fix for build
sql/sql_yacc.yy:
fix for build
Diffstat (limited to 'sql/sql_acl.cc')
-rw-r--r-- | sql/sql_acl.cc | 198 |
1 files changed, 131 insertions, 67 deletions
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index ca9ba7611e6..92a482193f5 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -60,7 +60,7 @@ static DYNAMIC_ARRAY acl_hosts,acl_users,acl_dbs; static MEM_ROOT mem, memex; static bool initialized=0; static bool allow_all_hosts=1; -static HASH acl_check_hosts, column_priv_hash, proc_priv_hash; +static HASH acl_check_hosts, column_priv_hash, proc_priv_hash, func_priv_hash; static DYNAMIC_ARRAY acl_wild_hosts; static hash_filo *acl_cache; static uint grant_version=0; /* Version of priv tables. incremented by acl_init */ @@ -2136,11 +2136,12 @@ static GRANT_NAME *name_hash_search(HASH *name_hash, inline GRANT_NAME * -proc_hash_search(const char *host, const char *ip, const char *db, - const char *user, const char *tname, bool exact) +routine_hash_search(const char *host, const char *ip, const char *db, + const char *user, const char *tname, bool proc, bool exact) { - return (GRANT_TABLE*) name_hash_search(&proc_priv_hash, host, ip, db, - user, tname, exact); + return (GRANT_TABLE*) + name_hash_search(proc ? &proc_priv_hash : &func_priv_hash, + host, ip, db, user, tname, exact); } @@ -2466,16 +2467,17 @@ table_error: } -static int replace_proc_table(THD *thd, GRANT_NAME *grant_name, +static int replace_routine_table(THD *thd, GRANT_NAME *grant_name, TABLE *table, const LEX_USER &combo, - const char *db, const char *proc_name, - ulong rights, bool revoke_grant) + const char *db, const char *routine_name, + bool is_proc, ulong rights, bool revoke_grant) { char grantor[HOSTNAME_LENGTH+USERNAME_LENGTH+2]; int old_row_exists= 1; int error=0; ulong store_proc_rights; - DBUG_ENTER("replace_proc_table"); + byte *key; + DBUG_ENTER("replace_routine_table"); if (!initialized) { @@ -2499,7 +2501,10 @@ static int replace_proc_table(THD *thd, GRANT_NAME *grant_name, table->field[0]->store(combo.host.str,combo.host.length, &my_charset_latin1); table->field[1]->store(db,(uint) strlen(db), &my_charset_latin1); table->field[2]->store(combo.user.str,combo.user.length, &my_charset_latin1); - table->field[3]->store(proc_name,(uint) strlen(proc_name), &my_charset_latin1); + table->field[3]->store(routine_name,(uint) strlen(routine_name), + &my_charset_latin1); + table->field[4]->store((longlong)(is_proc ? + TYPE_ENUM_PROCEDURE : TYPE_ENUM_FUNCTION)); store_record(table,record[1]); // store at pos 1 if (table->file->index_read_idx(table->record[0],0, @@ -2514,7 +2519,7 @@ static int replace_proc_table(THD *thd, GRANT_NAME *grant_name, if (revoke_grant) { // no row, no revoke my_error(ER_NONEXISTING_PROC_GRANT, MYF(0), - combo.user.str, combo.host.str, proc_name); + combo.user.str, combo.host.str, routine_name); DBUG_RETURN(-1); } old_row_exists= 0; @@ -2539,7 +2544,7 @@ static int replace_proc_table(THD *thd, GRANT_NAME *grant_name, } } - table->field[4]->store(grantor,(uint) strlen(grantor), &my_charset_latin1); + table->field[5]->store(grantor,(uint) strlen(grantor), &my_charset_latin1); table->field[6]->store((longlong) store_proc_rights); rights=fix_rights_for_procedure(store_proc_rights); @@ -2566,7 +2571,7 @@ static int replace_proc_table(THD *thd, GRANT_NAME *grant_name, } else { - hash_delete(&proc_priv_hash,(byte*) grant_name); + hash_delete(is_proc ? &proc_priv_hash : &func_priv_hash,(byte*) grant_name); } DBUG_RETURN(0); @@ -2841,12 +2846,13 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list, /* - Store procedure level grants in the privilege tables + Store routine level grants in the privilege tables SYNOPSIS - mysql_procedure_grant() + mysql_routine_grant() thd Thread handle - table_list List of procedures to give grant + table_list List of routines to give grant + is_proc true indicates routine list are procedures user_list List of users to give grant rights Table level grant revoke_grant Set to 1 if this is a REVOKE command @@ -2856,16 +2862,16 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list, 1 error */ -bool mysql_procedure_grant(THD *thd, TABLE_LIST *table_list, - List <LEX_USER> &user_list, ulong rights, - bool revoke_grant, bool no_error) +bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc, + List <LEX_USER> &user_list, ulong rights, + bool revoke_grant, bool no_error) { List_iterator <LEX_USER> str_list (user_list); LEX_USER *Str; TABLE_LIST tables[2]; bool create_new_users=0, result=0; char *db_name, *table_name; - DBUG_ENTER("mysql_procedure_grant"); + DBUG_ENTER("mysql_routine_grant"); if (!initialized) { @@ -2884,7 +2890,7 @@ bool mysql_procedure_grant(THD *thd, TABLE_LIST *table_list, if (!revoke_grant) { - if (sp_exists_routine(thd, table_list, 0, no_error)<0) + if (sp_exists_routine(thd, table_list, is_proc, no_error)<0) DBUG_RETURN(TRUE); } @@ -2957,8 +2963,8 @@ bool mysql_procedure_grant(THD *thd, TABLE_LIST *table_list, db_name= table_list->db; table_name= table_list->table_name; - grant_name= proc_hash_search(Str->host.str, NullS, db_name, - Str->user.str, table_name, 1); + grant_name= routine_hash_search(Str->host.str, NullS, db_name, + Str->user.str, table_name, is_proc, 1); if (!grant_name) { if (revoke_grant) @@ -2977,11 +2983,11 @@ bool mysql_procedure_grant(THD *thd, TABLE_LIST *table_list, result= TRUE; continue; } - my_hash_insert(&proc_priv_hash,(byte*) grant_name); + my_hash_insert(is_proc ? &proc_priv_hash : &func_priv_hash,(byte*) grant_name); } - if (replace_proc_table(thd, grant_name, tables[1].table, *Str, - db_name, table_name, rights, revoke_grant)) + if (replace_routine_table(thd, grant_name, tables[1].table, *Str, + db_name, table_name, is_proc, rights, revoke_grant)) { result= TRUE; continue; @@ -3133,6 +3139,9 @@ my_bool grant_init(THD *org_thd) (void) hash_init(&proc_priv_hash,system_charset_info, 0,0,0, (hash_get_key) get_grant_table, 0,0); + (void) hash_init(&func_priv_hash,system_charset_info, + 0,0,0, (hash_get_key) get_grant_table, + 0,0); init_sql_alloc(&memex, ACL_ALLOC_BLOCK_SIZE, 0); /* Don't do anything if running with --skip-grant */ @@ -3206,6 +3215,8 @@ my_bool grant_init(THD *org_thd) do { GRANT_NAME *mem_check; + longlong proc_type; + HASH *hash; if (!(mem_check=new GRANT_NAME(p_table))) { /* This could only happen if we are out memory */ @@ -3224,11 +3235,27 @@ my_bool grant_init(THD *org_thd) continue; } } + if (p_table->field[4]->val_int() == TYPE_ENUM_PROCEDURE) + { + hash= &proc_priv_hash; + } + else + if (p_table->field[4]->val_int() == TYPE_ENUM_FUNCTION) + { + hash= &func_priv_hash; + } + else + { + sql_print_warning("'procs_priv' entry '%s' " + "ignored, bad routine type", + mem_check->tname); + continue; + } mem_check->privs= fix_rights_for_procedure(mem_check->privs); if (! mem_check->ok()) delete mem_check; - else if (my_hash_insert(&proc_priv_hash,(byte*) mem_check)) + else if (my_hash_insert(hash, (byte*) mem_check)) { delete mem_check; grant_option= FALSE; @@ -3272,7 +3299,7 @@ end: void grant_reload(THD *thd) { - HASH old_column_priv_hash, old_proc_priv_hash; + HASH old_column_priv_hash, old_proc_priv_hash, old_func_priv_hash; bool old_grant_option; MEM_ROOT old_mem; DBUG_ENTER("grant_reload"); @@ -3281,6 +3308,7 @@ void grant_reload(THD *thd) grant_version++; old_column_priv_hash= column_priv_hash; old_proc_priv_hash= proc_priv_hash; + old_func_priv_hash= func_priv_hash; old_grant_option= grant_option; old_mem= memex; @@ -3290,6 +3318,7 @@ void grant_reload(THD *thd) grant_free(); /* purecov: deadcode */ column_priv_hash= old_column_priv_hash; /* purecov: deadcode */ proc_priv_hash= old_proc_priv_hash; + func_priv_hash= old_func_priv_hash; grant_option= old_grant_option; /* purecov: deadcode */ memex= old_mem; /* purecov: deadcode */ } @@ -3297,6 +3326,7 @@ void grant_reload(THD *thd) { hash_free(&old_column_priv_hash); hash_free(&old_proc_priv_hash); + hash_free(&old_func_priv_hash); free_root(&old_mem,MYF(0)); } rw_unlock(&LOCK_grant); @@ -3540,13 +3570,14 @@ bool check_grant_db(THD *thd,const char *db) /**************************************************************************** - Check procedure level grants + Check routine level grants SYNPOSIS - bool check_grant_procedure() + bool check_grant_routine() thd Thread handler want_access Bits of privileges user needs to have - procs List of procedures to check. The user should have 'want_access' + procs List of routines to check. The user should have 'want_access' + is_proc True if the list is all procedures, else functions no_errors If 0 then we write an error. The error is sent directly to the client @@ -3555,13 +3586,13 @@ bool check_grant_db(THD *thd,const char *db) 1 Error: User did not have the requested privielges ****************************************************************************/ -bool check_grant_procedure(THD *thd, ulong want_access, - TABLE_LIST *procs, bool no_errors) +bool check_grant_routine(THD *thd, ulong want_access, + TABLE_LIST *procs, bool is_proc, bool no_errors) { TABLE_LIST *table; char *user= thd->priv_user; char *host= thd->priv_host; - DBUG_ENTER("check_grant_procedure"); + DBUG_ENTER("check_grant_routine"); want_access&= ~thd->master_access; if (!want_access) @@ -3571,8 +3602,8 @@ bool check_grant_procedure(THD *thd, ulong want_access, for (table= procs; table; table= table->next_global) { GRANT_NAME *grant_proc; - if ((grant_proc= proc_hash_search(host,thd->ip, - table->db, user, table->table_name, 0))) + if ((grant_proc= routine_hash_search(host,thd->ip, table->db, user, + table->table_name, is_proc, 0))) table->grant.privilege|= grant_proc->privs; if (want_access & ~table->grant.privilege) @@ -3594,7 +3625,7 @@ err: if (want_access & EXECUTE_ACL) command= "execute"; else if (want_access & ALTER_PROC_ACL) - command= "alter procedure"; + command= "alter routine"; else if (want_access & GRANT_ACL) command= "grant"; my_error(ER_PROCACCESS_DENIED_ERROR, MYF(0), @@ -3606,7 +3637,7 @@ err: /* Check if routine has any of the - procedure level grants + routine level grants SYNPOSIS bool check_routine_level_acl() @@ -3619,15 +3650,15 @@ err: 1 error */ -bool check_routine_level_acl(THD *thd, const char *db, const char *name) +bool check_routine_level_acl(THD *thd, const char *db, const char *name, bool is_proc) { bool no_routine_acl= 1; if (grant_option) { GRANT_NAME *grant_proc; rw_rdlock(&LOCK_grant); - if ((grant_proc= proc_hash_search(thd->priv_host, thd->ip, db, - thd->priv_user, name, 0))) + if ((grant_proc= routine_hash_search(thd->priv_host, thd->ip, db, + thd->priv_user, name, is_proc, 0))) no_routine_acl= !(grant_proc->privs & SHOW_PROC_ACLS); rw_unlock(&LOCK_grant); } @@ -3730,6 +3761,11 @@ static uint command_lengths[]= }; +static int show_routine_grants(THD *thd, LEX_USER *lex_user, HASH *hash, + const char *type, int typelen, + char *buff, int buffsize); + + /* SHOW GRANTS; Send grants for a user to the client @@ -4076,12 +4112,40 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user) } } - /* Add procedure access */ - for (index=0 ; index < proc_priv_hash.records ; index++) + if (show_routine_grants(thd, lex_user, &proc_priv_hash, + "PROCEDURE", 9, buff, sizeof(buff))) + { + error= -1; + goto end; + } + + if (show_routine_grants(thd, lex_user, &func_priv_hash, + "FUNCTION", 8, buff, sizeof(buff))) + { + error= -1; + goto end; + } + +end: + VOID(pthread_mutex_unlock(&acl_cache->lock)); + rw_unlock(&LOCK_grant); + + send_eof(thd); + DBUG_RETURN(error); +} + +static int show_routine_grants(THD* thd, LEX_USER *lex_user, HASH *hash, + const char *type, int typelen, + char *buff, int buffsize) +{ + uint counter, index; + int error= 0; + Protocol *protocol= thd->protocol; + /* Add routine access */ + for (index=0 ; index < hash->records ; index++) { const char *user; - GRANT_NAME *grant_proc= (GRANT_NAME*) hash_element(&proc_priv_hash, - index); + GRANT_NAME *grant_proc= (GRANT_NAME*) hash_element(hash, index); if (!(user=grant_proc->user)) user= ""; @@ -4093,7 +4157,7 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user) ulong proc_access= grant_proc->privs; if (proc_access != 0) { - String global(buff, sizeof(buff), system_charset_info); + String global(buff, buffsize, system_charset_info); ulong test_access= proc_access & ~GRANT_ACL; global.length(0); @@ -4119,6 +4183,8 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user) } } global.append(" ON ",4); + global.append(type,typelen); + global.append(' '); append_identifier(thd, &global, grant_proc->db, strlen(grant_proc->db)); global.append('.'); @@ -4143,15 +4209,9 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user) } } } -end: - VOID(pthread_mutex_unlock(&acl_cache->lock)); - rw_unlock(&LOCK_grant); - - send_eof(thd); - DBUG_RETURN(error); + return error; } - /* Make a clear-text version of the requested privilege. */ @@ -4977,7 +5037,7 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list) bool mysql_revoke_all(THD *thd, List <LEX_USER> &list) { - uint counter, revoked; + uint counter, revoked, is_proc; int result; ACL_DB *acl_db; TABLE_LIST tables[GRANT_TABLES]; @@ -5092,12 +5152,12 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list) } while (revoked); /* Remove procedure access */ - do { - for (counter= 0, revoked= 0 ; counter < proc_priv_hash.records ; ) + for (is_proc=0; is_proc<2; is_proc++) do { + HASH *hash= is_proc ? &proc_priv_hash : &func_priv_hash; + for (counter= 0, revoked= 0 ; counter < hash->records ; ) { const char *user,*host; - GRANT_NAME *grant_proc= (GRANT_NAME*) hash_element(&proc_priv_hash, - counter); + GRANT_NAME *grant_proc= (GRANT_NAME*) hash_element(hash, counter); if (!(user=grant_proc->user)) user= ""; if (!(host=grant_proc->host.hostname)) @@ -5106,9 +5166,10 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list) if (!strcmp(lex_user->user.str,user) && !my_strcasecmp(system_charset_info, lex_user->host.str, host)) { - if (!replace_proc_table(thd,grant_proc,tables[4].table,*lex_user, + if (!replace_routine_table(thd,grant_proc,tables[4].table,*lex_user, grant_proc->db, grant_proc->tname, + is_proc, ~0, 1)) { revoked= 1; @@ -5146,11 +5207,13 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list) < 0 Error. Error message not yet sent. */ -bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name) +bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name, + bool is_proc) { uint counter, revoked; int result; TABLE_LIST tables[GRANT_TABLES]; + HASH *hash= is_proc ? &proc_priv_hash : &func_priv_hash; DBUG_ENTER("sp_revoke_privileges"); if ((result= open_grant_tables(thd, tables))) @@ -5162,10 +5225,9 @@ bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name) /* Remove procedure access */ do { - for (counter= 0, revoked= 0 ; counter < proc_priv_hash.records ; ) + for (counter= 0, revoked= 0 ; counter < hash->records ; ) { - GRANT_NAME *grant_proc= (GRANT_NAME*) hash_element(&proc_priv_hash, - counter); + GRANT_NAME *grant_proc= (GRANT_NAME*) hash_element(hash, counter); if (!my_strcasecmp(system_charset_info, grant_proc->db, sp_db) && !my_strcasecmp(system_charset_info, grant_proc->tname, sp_name)) { @@ -5174,8 +5236,9 @@ bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name) lex_user.user.length= strlen(grant_proc->user); lex_user.host.str= grant_proc->host.hostname; lex_user.host.length= strlen(grant_proc->host.hostname); - if (!replace_proc_table(thd,grant_proc,tables[4].table,lex_user, - grant_proc->db, grant_proc->tname, ~0, 1)) + if (!replace_routine_table(thd,grant_proc,tables[4].table,lex_user, + grant_proc->db, grant_proc->tname, + is_proc, ~0, 1)) { revoked= 1; continue; @@ -5211,7 +5274,8 @@ bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name) < 0 Error. Error message not yet sent. */ -bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name) +bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name, + bool is_proc) { LEX_USER *combo; TABLE_LIST tables[1]; @@ -5249,7 +5313,7 @@ bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name) thd->lex->ssl_type= SSL_TYPE_NOT_SPECIFIED; bzero((char*) &thd->lex->mqh, sizeof(thd->lex->mqh)); - result= mysql_procedure_grant(thd, tables, user_list, + result= mysql_routine_grant(thd, tables, is_proc, user_list, DEFAULT_CREATE_PROC_ACLS, 0, 1); DBUG_RETURN(result); } |