From 72d8b533cc102aad6be5046a0fe8b8e63ec1e218 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 18 Oct 2013 08:10:51 -0700 Subject: Fixes for mysql-test failures mysql-test/r/acl_roles_show_grants.result: one can do SHOW GRANTS for himself mysql-test/t/acl_roles_set_role-table-column-priv.test: correct error message mysql-test/t/acl_roles_show_grants.test: one can SHOW GRANTS for himself sql/sql_acl.cc: bugfixing: * don't assign with && - it can shortcut and the second assignment won't be executed * correct the test in check_grant_all_columns() - want_access should not be modified * sql/sql_cmd.h.OTHER: add new commands at the end sql/sql_db.cc: don't call acl_get() if all privileges are already satisfied (crashes when run with --skip-grants, because acl data stuctures aren't initialized) sql/sql_parse.cc: * test for current_user in get_current_user() * map explicitly specified user@host to current_user --- sql/sql_acl.cc | 38 +++++++++++++++++++------------------- sql/sql_db.cc | 21 ++++++++++----------- sql/sql_lex.h | 4 ++-- sql/sql_parse.cc | 7 ++++++- 4 files changed, 37 insertions(+), 33 deletions(-) (limited to 'sql') diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 9716f7c251c..d1146a99113 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -6057,9 +6057,12 @@ bool check_grant_column(THD *thd, GRANT_INFO *grant, table_name, TRUE) : NULL; grant->version= grant_version; /* purecov: inspected */ } - if (!(grant_table= grant->grant_table_user) && - !(grant_table_role= grant->grant_table_role)) - goto err; /* purecov: deadcode */ + + grant_table= grant->grant_table_user; + grant_table_role= grant->grant_table_role; + + if (!grant_table && !grant_table_role) + goto err; if (grant_table) { @@ -6187,14 +6190,12 @@ bool check_grant_all_columns(THD *thd, ulong want_access_arg, Field_iterator_table_ref *fields) { Security_context *sctx= thd->security_ctx; - ulong want_access= want_access_arg; + ulong UNINIT_VAR(want_access); const char *table_name= NULL; - const char* db_name; GRANT_INFO *grant; - /* Initialized only to make gcc happy */ - GRANT_TABLE *grant_table= NULL; - GRANT_TABLE *grant_table_role= NULL; + GRANT_TABLE *UNINIT_VAR(grant_table); + GRANT_TABLE *UNINIT_VAR(grant_table_role); /* Flag that gets set if privilege checking has to be performed on column level. @@ -6238,16 +6239,14 @@ bool check_grant_all_columns(THD *thd, ulong want_access_arg, if (want_access) { + ulong have_access= 0; if (grant_table) { GRANT_COLUMN *grant_column= column_hash_search(grant_table, field_name, (uint) strlen(field_name)); if (grant_column) - { - using_column_privileges= TRUE; - want_access&= ~grant_column->rights; - } + have_access= grant_column->rights; } if (grant_table_role) { @@ -6255,13 +6254,12 @@ bool check_grant_all_columns(THD *thd, ulong want_access_arg, column_hash_search(grant_table_role, field_name, (uint) strlen(field_name)); if (grant_column) - { - using_column_privileges= TRUE; - want_access&= ~grant_column->rights; - } + have_access|= grant_column->rights; } - if (!want_access) + if (have_access) + using_column_privileges= TRUE; + if (want_access & ~have_access) goto err; } } @@ -6580,8 +6578,10 @@ ulong get_column_grant(THD *thd, GRANT_INFO *grant, grant->version= grant_version; /* purecov: inspected */ } - if (!(grant_table= grant->grant_table_user) && - !(grant_table_role= grant->grant_table_role)) + grant_table= grant->grant_table_user; + grant_table_role= grant->grant_table_role; + + if (!grant_table && !grant_table_role) priv= grant->privilege; else { diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 47c2e3bd406..7cc2caaa881 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -1470,18 +1470,17 @@ bool mysql_change_db(THD *thd, const LEX_STRING *new_db_name, bool force_switch) DBUG_PRINT("info",("Use database: %s", new_db_file_name.str)); #ifndef NO_EMBEDDED_ACCESS_CHECKS - db_access= - test_all_bits(sctx->master_access, DB_ACLS) ? - DB_ACLS : - acl_get(sctx->host, - sctx->ip, - sctx->priv_user, - new_db_file_name.str, - FALSE) | sctx->master_access; - if (sctx->priv_role[0]) + if (test_all_bits(sctx->master_access, DB_ACLS)) + db_access= DB_ACLS; + else { - /* include a possible currently set role for access */ - db_access|= acl_get("", "", sctx->priv_role, new_db_file_name.str, FALSE); + db_access= acl_get(sctx->host, sctx->ip, sctx->priv_user, + new_db_file_name.str, FALSE) | sctx->master_access; + if (sctx->priv_role[0]) + { + /* include a possible currently set role for access */ + db_access|= acl_get("", "", sctx->priv_role, new_db_file_name.str, FALSE); + } } if (!force_switch && diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 293081c21db..281ca26b64f 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -148,7 +148,7 @@ enum enum_sql_command { SQLCOM_SHOW_TRIGGERS, SQLCOM_LOAD,SQLCOM_SET_OPTION,SQLCOM_LOCK_TABLES,SQLCOM_UNLOCK_TABLES, - SQLCOM_GRANT, SQLCOM_GRANT_ROLE, + SQLCOM_GRANT, SQLCOM_CHANGE_DB, SQLCOM_CREATE_DB, SQLCOM_DROP_DB, SQLCOM_ALTER_DB, SQLCOM_REPAIR, SQLCOM_REPLACE, SQLCOM_REPLACE_SELECT, SQLCOM_CREATE_FUNCTION, SQLCOM_DROP_FUNCTION, @@ -169,7 +169,6 @@ enum enum_sql_command { SQLCOM_SHOW_WARNS, SQLCOM_EMPTY_QUERY, SQLCOM_SHOW_ERRORS, SQLCOM_SHOW_STORAGE_ENGINES, SQLCOM_SHOW_PRIVILEGES, SQLCOM_HELP, SQLCOM_CREATE_USER, SQLCOM_DROP_USER, SQLCOM_RENAME_USER, - SQLCOM_CREATE_ROLE, SQLCOM_DROP_ROLE, SQLCOM_REVOKE_ROLE, SQLCOM_REVOKE_ALL, SQLCOM_CHECKSUM, SQLCOM_CREATE_PROCEDURE, SQLCOM_CREATE_SPFUNCTION, SQLCOM_CALL, SQLCOM_DROP_PROCEDURE, SQLCOM_ALTER_PROCEDURE,SQLCOM_ALTER_FUNCTION, @@ -197,6 +196,7 @@ enum enum_sql_command { SQLCOM_SHOW_USER_STATS, SQLCOM_SHOW_TABLE_STATS, SQLCOM_SHOW_INDEX_STATS, SQLCOM_SHOW_CLIENT_STATS, SQLCOM_SHOW_EXPLAIN, SQLCOM_SHUTDOWN, + SQLCOM_CREATE_ROLE, SQLCOM_DROP_ROLE, SQLCOM_GRANT_ROLE, SQLCOM_REVOKE_ROLE, /* When a command is added here, be sure it's also added in mysqld.cc diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 9d17d9c3e31..997ba7f97ea 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4001,6 +4001,11 @@ end_with_restore_list: LEX_USER *grant_user= lex->grant_user; if (!grant_user) goto error; + + if (grant_user->user.str && + !strcmp(thd->security_ctx->priv_user, grant_user->user.str)) + grant_user= ¤t_user; + if (grant_user == ¤t_user || grant_user == ¤t_role || grant_user == ¤t_user_and_current_role || @@ -7752,7 +7757,7 @@ LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name) LEX_USER *get_current_user(THD *thd, LEX_USER *user) { - if (!user->user.str) // current_user + if (user == ¤t_user) // current_user return create_default_definer(thd); return user; -- cgit v1.2.1