1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-27 18:02:13 +03:00
WL#604 Privileges in embedded library
code added to check privileges in embedded library
NO_EMBEDDED_ACCESS_CHECKS macros inserted in code so we can exclude
access-checking parts. Actually we now can exclude these parts from
standalone server as well. Do we need it?
Access checks are disabled in embedded server by default. One should
edit libmysqld/Makefile manually to get this working.
We definitely need the separate configure for embedded server
This commit is contained in:
hf@deer.(none)
2003-09-26 15:33:13 +05:00
parent 7dd4cb58d6
commit ba8fa76fa2
24 changed files with 447 additions and 286 deletions

View File

@ -142,7 +142,7 @@ enum mysql_option
MYSQL_OPT_PROTOCOL, MYSQL_SHARED_MEMORY_BASE_NAME, MYSQL_OPT_READ_TIMEOUT, MYSQL_OPT_PROTOCOL, MYSQL_SHARED_MEMORY_BASE_NAME, MYSQL_OPT_READ_TIMEOUT,
MYSQL_OPT_WRITE_TIMEOUT, MYSQL_OPT_USE_RESULT, MYSQL_OPT_WRITE_TIMEOUT, MYSQL_OPT_USE_RESULT,
MYSQL_OPT_USE_REMOTE_CONNECTION, MYSQL_OPT_USE_EMBEDDED_CONNECTION, MYSQL_OPT_USE_REMOTE_CONNECTION, MYSQL_OPT_USE_EMBEDDED_CONNECTION,
MYSQL_OPT_GUESS_CONNECTION MYSQL_OPT_GUESS_CONNECTION, MYSQL_SET_CLIENT_IP
}; };
struct st_mysql_options { struct st_mysql_options {
@ -180,6 +180,7 @@ struct st_mysql_options {
my_bool separate_thread; my_bool separate_thread;
#endif #endif
enum mysql_option methods_to_use; enum mysql_option methods_to_use;
char *client_ip;
}; };
enum mysql_status enum mysql_status

View File

@ -22,6 +22,7 @@ MYSQLSHAREdir = $(pkgdatadir)
MYSQLBASEdir= $(prefix) MYSQLBASEdir= $(prefix)
DEFS = -DEMBEDDED_LIBRARY -DMYSQL_SERVER \ DEFS = -DEMBEDDED_LIBRARY -DMYSQL_SERVER \
-DNO_EMBEDDED_ACCESS_CHECKS \
-DDEFAULT_MYSQL_HOME="\"$(MYSQLBASEdir)\"" \ -DDEFAULT_MYSQL_HOME="\"$(MYSQLBASEdir)\"" \
-DDATADIR="\"$(MYSQLDATAdir)\"" \ -DDATADIR="\"$(MYSQLDATAdir)\"" \
-DSHAREDIR="\"$(MYSQLSHAREdir)\"" -DSHAREDIR="\"$(MYSQLSHAREdir)\""

View File

@ -33,6 +33,9 @@ static const char *fake_groups[] = { "server", "embedded", 0 };
#include "../sql/mysqld.cc" #include "../sql/mysqld.cc"
#endif #endif
int check_user(THD *thd, enum enum_server_command command,
const char *passwd, uint passwd_len, const char *db,
bool check_count);
C_MODE_START C_MODE_START
#include <mysql.h> #include <mysql.h>
#undef ER #undef ER
@ -42,14 +45,6 @@ C_MODE_START
static my_bool org_my_init_done; static my_bool org_my_init_done;
my_bool server_inited; my_bool server_inited;
static int check_connections1(THD * thd);
static int check_connections2(THD * thd);
static bool check_user(THD *thd, enum_server_command command,
const char *user, const char *passwd, const char *db,
bool check_count);
char * get_mysql_home(){ return mysql_home;};
char * get_mysql_real_data_home(){ return mysql_real_data_home;};
static my_bool STDCALL static my_bool STDCALL
emb_advanced_command(MYSQL *mysql, enum enum_server_command command, emb_advanced_command(MYSQL *mysql, enum enum_server_command command,
const char *header, ulong header_length, const char *header, ulong header_length,
@ -217,34 +212,6 @@ void THD::clear_error()
net.report_error= 0; net.report_error= 0;
} }
static bool check_user(THD *thd,enum_server_command command, const char *user,
const char *passwd, const char *db, bool check_count)
{
thd->db=0;
if (!(thd->user = my_strdup(user, MYF(0))))
{
send_error(thd,ER_OUT_OF_RESOURCES);
return 1;
}
thd->master_access= ~0L; // No user checking
thd->priv_user= thd->user;
mysql_log.write(thd,command,
(thd->priv_user == thd->user ?
(char*) "%s@%s on %s" :
(char*) "%s@%s as anonymous on %s"),
user,
thd->host_or_ip,
db ? db : (char*) "");
thd->db_access=0;
if (db && db[0])
return test(mysql_change_db(thd,db));
else
send_ok(thd); // Ready to handle questions
return 0; // ok
}
/* /*
Make a copy of array and the strings array points to Make a copy of array and the strings array points to
*/ */
@ -339,7 +306,7 @@ int STDCALL mysql_server_init(int argc, char **argv, char **groups)
error_handler_hook = my_message_sql; error_handler_hook = my_message_sql;
opt_noacl = 1; // No permissions #ifndef NO_EMBEDDED_ACCESS_CHECKS
if (acl_init((THD *)0, opt_noacl)) if (acl_init((THD *)0, opt_noacl))
{ {
mysql_server_end(); mysql_server_end();
@ -347,11 +314,16 @@ int STDCALL mysql_server_init(int argc, char **argv, char **groups)
} }
if (!opt_noacl) if (!opt_noacl)
(void) grant_init((THD *)0); (void) grant_init((THD *)0);
#endif
init_max_user_conn(); init_max_user_conn();
init_update_queries(); init_update_queries();
#ifdef HAVE_DLOPEN #ifdef HAVE_DLOPEN
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (!opt_noacl) if (!opt_noacl)
#endif
udf_init(); udf_init();
#endif #endif
@ -444,8 +416,10 @@ void *create_embedded_thd(int client_flag, char *db)
thd->db= db; thd->db= db;
thd->db_length= db ? strip_sp(db) : 0; thd->db_length= db ? strip_sp(db) : 0;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
thd->db_access= DB_ACLS; thd->db_access= DB_ACLS;
thd->master_access= ~NO_ACCESS; thd->master_access= ~NO_ACCESS;
#endif
thd->net.query_cache_query= 0; thd->net.query_cache_query= 0;
thd->data= 0; thd->data= 0;
@ -453,6 +427,51 @@ void *create_embedded_thd(int client_flag, char *db)
return thd; return thd;
} }
#ifndef NO_EMBEDDED_ACCESS_CHECKS
int check_embedded_connection(MYSQL *mysql)
{
THD *thd= (THD*)mysql->thd;
int result;
char scramble_buff[SCRAMBLE_LENGTH];
int passwd_len;
thd->host= mysql->options.client_ip ?
mysql->options.client_ip : (char*)my_localhost;
thd->ip= thd->host;
thd->host_or_ip= thd->host;
if (acl_check_host(thd->host,thd->ip))
{
result= ER_HOST_NOT_PRIVILEGED;
goto err;
}
thd->user= mysql->user;
if (mysql->passwd && mysql->passwd[0])
{
memset(thd->scramble, 55, SCRAMBLE_LENGTH); // dummy scramble
thd->scramble[SCRAMBLE_LENGTH]= 0;
scramble(scramble_buff, thd->scramble, mysql->passwd);
passwd_len= SCRAMBLE_LENGTH;
}
else
passwd_len= 0;
if((result= check_user(thd, COM_CONNECT,
scramble_buff, passwd_len, thd->db, true)))
goto err;
return 0;
err:
{
NET *net= &mysql->net;
memcpy(net->last_error, thd->net.last_error, sizeof(net->last_error));
memcpy(net->sqlstate, thd->net.sqlstate, sizeof(net->sqlstate));
}
return result;
}
#endif
C_MODE_END C_MODE_END
bool Protocol::send_fields(List<Item> *list, uint flag) bool Protocol::send_fields(List<Item> *list, uint flag)

View File

@ -146,12 +146,17 @@ static inline int mysql_init_charset(MYSQL *mysql)
return 0; return 0;
} }
int check_embedded_connection(MYSQL *mysql);
MYSQL * STDCALL MYSQL * STDCALL
mysql_real_connect(MYSQL *mysql,const char *host, const char *user, mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
const char *passwd, const char *db, const char *passwd, const char *db,
uint port, const char *unix_socket,ulong client_flag) uint port, const char *unix_socket,ulong client_flag)
{ {
char *db_name; char *db_name;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
char name_buff[USERNAME_LENGTH];
#endif
DBUG_ENTER("mysql_real_connect"); DBUG_ENTER("mysql_real_connect");
DBUG_PRINT("enter",("host: %s db: %s user: %s", DBUG_PRINT("enter",("host: %s db: %s user: %s",
host ? host : "(Null)", host ? host : "(Null)",
@ -190,6 +195,29 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
if (!db || !db[0]) if (!db || !db[0])
db=mysql->options.db; db=mysql->options.db;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (!user || !user[0])
user=mysql->options.user;
if (!passwd)
{
passwd=mysql->options.password;
#if !defined(DONT_USE_MYSQL_PWD)
if (!passwd)
passwd=getenv("MYSQL_PWD"); /* get it from environment */
#endif
}
if (!user || !user[0])
{
read_user_name(name_buff);
if (!name_buff[0])
user= name_buff;
}
mysql->user=my_strdup(user,MYF(0));
mysql->passwd= passwd ? my_strdup(passwd,MYF(0)) : NULL;
#endif /*!NO_EMBEDDED_ACCESS_CHECKS*/
port=0; port=0;
unix_socket=0; unix_socket=0;
db_name = db ? my_strdup(db,MYF(MY_WME)) : NULL; db_name = db ? my_strdup(db,MYF(MY_WME)) : NULL;
@ -198,6 +226,11 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
init_embedded_mysql(mysql, client_flag, db_name); init_embedded_mysql(mysql, client_flag, db_name);
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (check_embedded_connection(mysql))
goto error;
#endif
if (mysql_init_charset(mysql)) if (mysql_init_charset(mysql))
goto error; goto error;
@ -245,51 +278,3 @@ error:
DBUG_RETURN(0); DBUG_RETURN(0);
} }
/*************************************************************************
** Send a QUIT to the server and close the connection
** If handle is alloced by mysql connect free it.
*************************************************************************/
void STDCALL mysql_close(MYSQL *mysql)
{
DBUG_ENTER("mysql_close");
if (mysql) /* Some simple safety */
{
if (mysql->methods != &embedded_methods)
{
cli_mysql_close(mysql);
DBUG_VOID_RETURN;
}
my_free(mysql->options.user,MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->options.host,MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->options.password,MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->options.unix_socket,MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->options.db,MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->options.my_cnf_file,MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->options.my_cnf_group,MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->options.charset_dir,MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->options.charset_name,MYF(MY_ALLOW_ZERO_PTR));
if (mysql->options.init_commands)
{
DYNAMIC_ARRAY *init_commands= mysql->options.init_commands;
char **ptr= (char**)init_commands->buffer;
char **end= ptr + init_commands->elements;
for (; ptr<end; ptr++)
my_free(*ptr,MYF(MY_WME));
delete_dynamic(init_commands);
my_free((char*)init_commands,MYF(MY_WME));
}
/* Clear pointers for better safety */
bzero((char*) &mysql->options,sizeof(mysql->options));
#ifdef HAVE_OPENSSL
((VioConnectorFd*)(mysql->connector_fd))->delete();
mysql->connector_fd = 0;
#endif /* HAVE_OPENSSL */
if (mysql->free_me)
my_free((gptr) mysql,MYF(0));
}
DBUG_VOID_RETURN;
}

View File

@ -48,14 +48,12 @@
#endif #endif
#define CLI_MYSQL_REAL_CONNECT cli_mysql_real_connect #define CLI_MYSQL_REAL_CONNECT cli_mysql_real_connect
#define CLI_MYSQL_CLOSE cli_mysql_close
#undef net_flush #undef net_flush
my_bool net_flush(NET *net); my_bool net_flush(NET *net);
#else /*EMBEDDED_LIBRARY*/ #else /*EMBEDDED_LIBRARY*/
#define CLI_MYSQL_REAL_CONNECT mysql_real_connect #define CLI_MYSQL_REAL_CONNECT mysql_real_connect
#define CLI_MYSQL_CLOSE mysql_close
#endif /*EMBEDDED_LIBRARY*/ #endif /*EMBEDDED_LIBRARY*/
#if !defined(MYSQL_SERVER) && (defined(__WIN__) || defined(_WIN32) || defined(_WIN64)) #if !defined(MYSQL_SERVER) && (defined(__WIN__) || defined(_WIN32) || defined(_WIN64))
@ -2127,6 +2125,7 @@ static void mysql_close_free_options(MYSQL *mysql)
my_free(mysql->options.my_cnf_group,MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->options.my_cnf_group,MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->options.charset_dir,MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->options.charset_dir,MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->options.charset_name,MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->options.charset_name,MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->options.client_ip,MYF(MY_ALLOW_ZERO_PTR));
if (mysql->options.init_commands) if (mysql->options.init_commands)
{ {
DYNAMIC_ARRAY *init_commands= mysql->options.init_commands; DYNAMIC_ARRAY *init_commands= mysql->options.init_commands;
@ -2159,7 +2158,7 @@ static void mysql_close_free(MYSQL *mysql)
} }
void STDCALL CLI_MYSQL_CLOSE(MYSQL *mysql) void STDCALL mysql_close(MYSQL *mysql)
{ {
DBUG_ENTER("mysql_close"); DBUG_ENTER("mysql_close");
if (mysql) /* Some simple safety */ if (mysql) /* Some simple safety */
@ -2529,6 +2528,8 @@ mysql_options(MYSQL *mysql,enum mysql_option option, const char *arg)
case MYSQL_OPT_GUESS_CONNECTION: case MYSQL_OPT_GUESS_CONNECTION:
mysql->options.methods_to_use= option; mysql->options.methods_to_use= option;
break; break;
case MYSQL_SET_CLIENT_IP:
mysql->options.client_ip= my_strdup(arg, MYF(MY_WME));
default: default:
DBUG_RETURN(1); DBUG_RETURN(1);
} }

View File

@ -2277,7 +2277,9 @@ String *Item_load_file::val_str(String *str)
DBUG_ENTER("load_file"); DBUG_ENTER("load_file");
if (!(file_name= args[0]->val_str(str)) || if (!(file_name= args[0]->val_str(str)) ||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
!(current_thd->master_access & FILE_ACL) || !(current_thd->master_access & FILE_ACL) ||
#endif
!my_stat(file_name->c_ptr(), &stat_info, MYF(MY_WME))) !my_stat(file_name->c_ptr(), &stat_info, MYF(MY_WME)))
goto err; goto err;
if (!(stat_info.st_mode & S_IROTH)) if (!(stat_info.st_mode & S_IROTH))

View File

@ -1093,8 +1093,11 @@ bool MYSQL_LOG::write(THD *thd,enum enum_server_command command,
if (thd) if (thd)
{ // Normal thread { // Normal thread
if ((thd->options & OPTION_LOG_OFF) && if ((thd->options & OPTION_LOG_OFF)
(thd->master_access & SUPER_ACL)) #ifndef NO_EMBEDDED_ACCESS_CHECKS
&& (thd->master_access & SUPER_ACL)
#endif
)
{ {
VOID(pthread_mutex_unlock(&LOCK_log)); VOID(pthread_mutex_unlock(&LOCK_log));
return 0; // No logging return 0; // No logging
@ -1553,8 +1556,11 @@ bool MYSQL_LOG::write(THD *thd,const char *query, uint query_length,
int tmp_errno=0; int tmp_errno=0;
char buff[80],*end; char buff[80],*end;
end=buff; end=buff;
if (!(thd->options & OPTION_UPDATE_LOG) && if (!(thd->options & OPTION_UPDATE_LOG)
(thd->master_access & SUPER_ACL)) #ifndef NO_EMBEDDED_ACCESS_CHECKS
&& (thd->master_access & SUPER_ACL)
#endif
)
{ {
VOID(pthread_mutex_unlock(&LOCK_log)); VOID(pthread_mutex_unlock(&LOCK_log));
return 0; return 0;

View File

@ -393,18 +393,24 @@ bool check_stack_overrun(THD *thd,char *dummy);
#define check_stack_overrun(A, B) 0 #define check_stack_overrun(A, B) 0
#endif #endif
bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
bool *write_to_binlog);
void table_cache_init(void); void table_cache_init(void);
void table_cache_free(void); void table_cache_free(void);
uint cached_tables(void); uint cached_tables(void);
void kill_mysql(void); void kill_mysql(void);
void close_connection(THD *thd, uint errcode, bool lock); void close_connection(THD *thd, uint errcode, bool lock);
bool check_access(THD *thd, ulong access, const char *db=0, ulong *save_priv=0, #ifndef NO_EMBEDDED_ACCESS_CHECKS
bool no_grant=0, bool no_errors=0); bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
bool *write_to_binlog);
bool check_access(THD *thd, ulong access, const char *db, ulong *save_priv,
bool no_grant, bool no_errors);
bool check_table_access(THD *thd, ulong want_access, TABLE_LIST *tables, bool check_table_access(THD *thd, ulong want_access, TABLE_LIST *tables,
bool no_errors=0); bool no_errors);
bool check_global_access(THD *thd, ulong want_access); bool check_global_access(THD *thd, ulong want_access);
#else
#define check_access(thd, access, db, save_priv, no_grant, no_errors) false
#define check_table_access(thd, want_access, tables, no_errors) false
#define check_global_access(thd, want_access) false
#endif
int mysql_backup_table(THD* thd, TABLE_LIST* table_list); int mysql_backup_table(THD* thd, TABLE_LIST* table_list);
int mysql_restore_table(THD* thd, TABLE_LIST* table_list); int mysql_restore_table(THD* thd, TABLE_LIST* table_list);
@ -717,7 +723,7 @@ extern char *mysql_data_home,server_version[SERVER_VERSION_LENGTH],
#define mysql_tmpdir (my_tmpdir(&mysql_tmpdir_list)) #define mysql_tmpdir (my_tmpdir(&mysql_tmpdir_list))
extern MY_TMPDIR mysql_tmpdir_list; extern MY_TMPDIR mysql_tmpdir_list;
extern const char *command_name[]; extern const char *command_name[];
extern const char *first_keyword, *localhost, *delayed_user, *binary_keyword; extern const char *first_keyword, *my_localhost, *delayed_user, *binary_keyword;
extern const char **errmesg; /* Error messages */ extern const char **errmesg; /* Error messages */
extern const char *myisam_recover_options_str; extern const char *myisam_recover_options_str;
extern const char *in_left_expr_name, *in_additional_cond; extern const char *in_left_expr_name, *in_additional_cond;

View File

@ -218,7 +218,7 @@ const char *sql_mode_names[] =
TYPELIB sql_mode_typelib= { array_elements(sql_mode_names)-1,"", TYPELIB sql_mode_typelib= { array_elements(sql_mode_names)-1,"",
sql_mode_names }; sql_mode_names };
const char *first_keyword= "first", *binary_keyword= "BINARY"; const char *first_keyword= "first", *binary_keyword= "BINARY";
const char *localhost= "localhost", *delayed_user= "DELAYED"; const char *my_localhost= "localhost", *delayed_user= "DELAYED";
#if SIZEOF_OFF_T > 4 && defined(BIG_TABLES) #if SIZEOF_OFF_T > 4 && defined(BIG_TABLES)
#define GET_HA_ROWS GET_ULL #define GET_HA_ROWS GET_ULL
#else #else
@ -875,8 +875,10 @@ void clean_up(bool print_message)
if (use_slave_mask) if (use_slave_mask)
bitmap_free(&slave_error_mask); bitmap_free(&slave_error_mask);
#endif #endif
#ifndef NO_EMBEDDED_ACCESS_CHECKS
acl_free(1); acl_free(1);
grant_free(); grant_free();
#endif
query_cache_destroy(); query_cache_destroy();
table_cache_free(); table_cache_free();
hostname_cache_free(); hostname_cache_free();
@ -1672,6 +1674,7 @@ static void init_signals(void)
} }
#ifndef EMBEDDED_LIBRARY
static void start_signal_handler(void) static void start_signal_handler(void)
{ {
int error; int error;
@ -1834,6 +1837,7 @@ extern "C" void *signal_hand(void *arg __attribute__((unused)))
} }
return(0); /* purecov: deadcode */ return(0); /* purecov: deadcode */
} }
#endif /*!EMBEDDED_LIBRARY*/
static void check_data_home(const char *path) static void check_data_home(const char *path)
{} {}
@ -3111,7 +3115,7 @@ extern "C" pthread_handler_decl(handle_connections_sockets,
continue; continue;
} }
if (sock == unix_sock) if (sock == unix_sock)
thd->host=(char*) localhost; thd->host=(char*) my_localhost;
#ifdef __WIN__ #ifdef __WIN__
/* Set default wait_timeout */ /* Set default wait_timeout */
ulong wait_timeout= global_system_variables.net_wait_timeout * 1000; ulong wait_timeout= global_system_variables.net_wait_timeout * 1000;
@ -3201,7 +3205,7 @@ extern "C" pthread_handler_decl(handle_connections_namedpipes,arg)
continue; continue;
} }
/* host name is unknown */ /* host name is unknown */
thd->host = my_strdup(localhost,MYF(0)); /* Host is unknown */ thd->host = my_strdup(my_localhost,MYF(0)); /* Host is unknown */
create_new_thread(thd); create_new_thread(thd);
} }
@ -3410,7 +3414,7 @@ errorconn:
if (!event_client_read) CloseHandle(event_client_read); if (!event_client_read) CloseHandle(event_client_read);
continue; continue;
} }
thd->host = my_strdup(localhost,MYF(0)); /* Host is unknown */ thd->host = my_strdup(my_localhost,MYF(0)); /* Host is unknown */
create_new_thread(thd); create_new_thread(thd);
uint4korr(connect_number++); uint4korr(connect_number++);
} }

View File

@ -154,9 +154,8 @@ int register_slave(THD* thd, uchar* packet, uint packet_length)
SLAVE_INFO *si; SLAVE_INFO *si;
uchar *p= packet, *p_end= packet + packet_length; uchar *p= packet, *p_end= packet + packet_length;
if (check_access(thd, REPL_SLAVE_ACL, any_db)) if (check_access(thd, REPL_SLAVE_ACL, any_db,0,0,0))
return 1; return 1;
if (!(si = (SLAVE_INFO*)my_malloc(sizeof(SLAVE_INFO), MYF(MY_WME)))) if (!(si = (SLAVE_INFO*)my_malloc(sizeof(SLAVE_INFO), MYF(MY_WME))))
goto err2; goto err2;

View File

@ -1723,6 +1723,7 @@ byte *sys_var_insert_id::value_ptr(THD *thd, enum_var_type type,
bool sys_var_pseudo_thread_id::check(THD *thd, set_var *var) bool sys_var_pseudo_thread_id::check(THD *thd, set_var *var)
{ {
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (thd->master_access & SUPER_ACL) if (thd->master_access & SUPER_ACL)
return 0; return 0;
else else
@ -1730,6 +1731,9 @@ bool sys_var_pseudo_thread_id::check(THD *thd, set_var *var)
my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER"); my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
return 1; return 1;
} }
#else
return 0;
#endif
} }
@ -2028,7 +2032,6 @@ int set_var::check(THD *thd)
} }
if ((type == OPT_GLOBAL && check_global_access(thd, SUPER_ACL))) if ((type == OPT_GLOBAL && check_global_access(thd, SUPER_ACL)))
return 1; return 1;
/* value is a NULL pointer if we are using SET ... = DEFAULT */ /* value is a NULL pointer if we are using SET ... = DEFAULT */
if (!value) if (!value)
{ {
@ -2091,17 +2094,25 @@ int set_var_user::update(THD *thd)
int set_var_password::check(THD *thd) int set_var_password::check(THD *thd)
{ {
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (!user->host.str) if (!user->host.str)
user->host.str= (char*) thd->host_or_ip; user->host.str= (char*) thd->host_or_ip;
/* Returns 1 as the function sends error to client */ /* Returns 1 as the function sends error to client */
return check_change_password(thd, user->host.str, user->user.str) ? 1 : 0; return check_change_password(thd, user->host.str, user->user.str) ? 1 : 0;
#else
return 0;
#endif
} }
int set_var_password::update(THD *thd) int set_var_password::update(THD *thd)
{ {
#ifndef NO_EMBEDDED_ACCESS_CHECKS
/* Returns 1 as the function sends error to client */ /* Returns 1 as the function sends error to client */
return (change_password(thd, user->host.str, user->user.str, password) ? return (change_password(thd, user->host.str, user->user.str, password) ?
1 : 0); 1 : 0);
#else
return 0;
#endif
} }
/**************************************************************************** /****************************************************************************

View File

@ -34,6 +34,7 @@
#include <m_ctype.h> #include <m_ctype.h>
#include <stdarg.h> #include <stdarg.h>
#ifndef NO_EMBEDDED_ACCESS_CHECKS
class acl_entry :public hash_filo_element class acl_entry :public hash_filo_element
{ {
@ -985,51 +986,6 @@ exit:
return (db_access & host_access); return (db_access & host_access);
} }
int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *wildstr)
{
reg3 int flag;
DBUG_ENTER("wild_case_compare");
DBUG_PRINT("enter",("str: '%s' wildstr: '%s'",str,wildstr));
while (*wildstr)
{
while (*wildstr && *wildstr != wild_many && *wildstr != wild_one)
{
if (*wildstr == wild_prefix && wildstr[1])
wildstr++;
if (my_toupper(cs, *wildstr++) !=
my_toupper(cs, *str++)) DBUG_RETURN(1);
}
if (! *wildstr ) DBUG_RETURN (*str != 0);
if (*wildstr++ == wild_one)
{
if (! *str++) DBUG_RETURN (1); /* One char; skip */
}
else
{ /* Found '*' */
if (!*wildstr) DBUG_RETURN(0); /* '*' as last char: OK */
flag=(*wildstr != wild_many && *wildstr != wild_one);
do
{
if (flag)
{
char cmp;
if ((cmp= *wildstr) == wild_prefix && wildstr[1])
cmp=wildstr[1];
cmp=my_toupper(cs, cmp);
while (*str && my_toupper(cs, *str) != cmp)
str++;
if (!*str) DBUG_RETURN (1);
}
if (wild_case_compare(cs, str,wildstr) == 0) DBUG_RETURN (0);
} while (*str++);
DBUG_RETURN(1);
}
}
DBUG_RETURN (*str != '\0');
}
/* /*
Check if there are any possible matching entries for this host Check if there are any possible matching entries for this host
@ -1136,7 +1092,7 @@ bool check_change_password(THD *thd, const char *host, const char *user)
(strcmp(thd->user,user) || (strcmp(thd->user,user) ||
my_strcasecmp(&my_charset_latin1, host, thd->host_or_ip))) my_strcasecmp(&my_charset_latin1, host, thd->host_or_ip)))
{ {
if (check_access(thd, UPDATE_ACL, "mysql",0,1)) if (check_access(thd, UPDATE_ACL, "mysql",0,1,0))
return(1); return(1);
} }
if (!thd->slave_thread && !thd->user[0]) if (!thd->slave_thread && !thd->user[0])
@ -3605,3 +3561,50 @@ template class List_iterator<LEX_USER>;
template class List<LEX_COLUMN>; template class List<LEX_COLUMN>;
template class List<LEX_USER>; template class List<LEX_USER>;
#endif #endif
#endif /*NO_EMBEDDED_ACCESS_CHECKS */
int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *wildstr)
{
reg3 int flag;
DBUG_ENTER("wild_case_compare");
DBUG_PRINT("enter",("str: '%s' wildstr: '%s'",str,wildstr));
while (*wildstr)
{
while (*wildstr && *wildstr != wild_many && *wildstr != wild_one)
{
if (*wildstr == wild_prefix && wildstr[1])
wildstr++;
if (my_toupper(cs, *wildstr++) !=
my_toupper(cs, *str++)) DBUG_RETURN(1);
}
if (! *wildstr ) DBUG_RETURN (*str != 0);
if (*wildstr++ == wild_one)
{
if (! *str++) DBUG_RETURN (1); /* One char; skip */
}
else
{ /* Found '*' */
if (!*wildstr) DBUG_RETURN(0); /* '*' as last char: OK */
flag=(*wildstr != wild_many && *wildstr != wild_one);
do
{
if (flag)
{
char cmp;
if ((cmp= *wildstr) == wild_prefix && wildstr[1])
cmp=wildstr[1];
cmp=my_toupper(cs, cmp);
while (*str && my_toupper(cs, *str) != cmp)
str++;
if (!*str) DBUG_RETURN (1);
}
if (wild_case_compare(cs, str,wildstr) == 0) DBUG_RETURN (0);
} while (*str++);
DBUG_RETURN(1);
}
}
DBUG_RETURN (*str != '\0');
}

View File

@ -14,7 +14,6 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define SELECT_ACL (1L << 0) #define SELECT_ACL (1L << 0)
#define INSERT_ACL (1L << 1) #define INSERT_ACL (1L << 1)
#define UPDATE_ACL (1L << 2) #define UPDATE_ACL (1L << 2)
@ -59,6 +58,8 @@
#define EXTRA_ACL (1L << 29) #define EXTRA_ACL (1L << 29)
#define NO_ACCESS (1L << 30) #define NO_ACCESS (1L << 30)
#ifndef NO_EMBEDDED_ACCESS_CHECKS
/* /*
Defines to change the above bits to how things are stored in tables Defines to change the above bits to how things are stored in tables
This is needed as the 'host' and 'db' table is missing a few privileges This is needed as the 'host' and 'db' table is missing a few privileges
@ -162,3 +163,6 @@ void get_privilege_desc(char *to, uint max_length, ulong access);
void get_mqh(const char *user, const char *host, USER_CONN *uc); void get_mqh(const char *user, const char *host, USER_CONN *uc);
int mysql_drop_user(THD *thd, List <LEX_USER> &list); int mysql_drop_user(THD *thd, List <LEX_USER> &list);
int mysql_revoke_all(THD *thd, List <LEX_USER> &list); int mysql_revoke_all(THD *thd, List <LEX_USER> &list);
#endif /*!NO_EMBEDDED_ACCESS_CHECKS*/

View File

@ -158,7 +158,6 @@ OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *wild)
table_list.grant.privilege=0; table_list.grant.privilege=0;
if (check_table_access(thd,SELECT_ACL | EXTRA_ACL,&table_list,1)) if (check_table_access(thd,SELECT_ACL | EXTRA_ACL,&table_list,1))
continue; continue;
/* need to check if we haven't already listed it */ /* need to check if we haven't already listed it */
for (table= open_list ; table ; table=table->next) for (table= open_list ; table ; table=table->next)
{ {
@ -1696,8 +1695,10 @@ Field *find_field_in_table(THD *thd,TABLE *table,const char *name,uint length,
else else
thd->dupp_field=field; thd->dupp_field=field;
} }
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (check_grants && check_grant_column(thd,table,name,length)) if (check_grants && check_grant_column(thd,table,name,length))
return WRONG_GRANT; return WRONG_GRANT;
#endif
return field; return field;
} }
@ -2099,11 +2100,12 @@ insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name,
tables->alias) && tables->alias) &&
(!db_name || !strcmp(tables->db,db_name)))) (!db_name || !strcmp(tables->db,db_name))))
{ {
#ifndef NO_EMBEDDED_ACCESS_CHECKS
/* Ensure that we have access right to all columns */ /* Ensure that we have access right to all columns */
if (!(table->grant.privilege & SELECT_ACL) && if (!(table->grant.privilege & SELECT_ACL) &&
check_grant_all_columns(thd,SELECT_ACL,table)) check_grant_all_columns(thd,SELECT_ACL,table))
DBUG_RETURN(-1); DBUG_RETURN(-1);
#endif
Field **ptr=table->field,*field; Field **ptr=table->field,*field;
thd->used_tables|=table->map; thd->used_tables|=table->map;
while ((field = *ptr++)) while ((field = *ptr++))

View File

@ -1002,6 +1002,7 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
Query_cache_table *table = block_table->parent; Query_cache_table *table = block_table->parent;
table_list.db = table->db(); table_list.db = table->db();
table_list.alias= table_list.real_name= table->table(); table_list.alias= table_list.real_name= table->table();
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (check_table_access(thd,SELECT_ACL,&table_list,1)) if (check_table_access(thd,SELECT_ACL,&table_list,1))
{ {
DBUG_PRINT("qcache", DBUG_PRINT("qcache",
@ -1021,6 +1022,7 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
thd->lex.safe_to_cache_query= 0; // Don't try to cache this thd->lex.safe_to_cache_query= 0; // Don't try to cache this
goto err_unlock; // Parse query goto err_unlock; // Parse query
} }
#endif /*!NO_EMBEDDED_ACCESS_CHECKS*/
if (check_tables && !handler::caching_allowed(thd, table->db(), if (check_tables && !handler::caching_allowed(thd, table->db(),
table->key_length(), table->key_length(),
table->type())) table->type()))

View File

@ -135,7 +135,9 @@ THD::THD():user_time(0), is_fatal_error(0),
slave_net = 0; slave_net = 0;
command=COM_CONNECT; command=COM_CONNECT;
set_query_id=1; set_query_id=1;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
db_access=NO_ACCESS; db_access=NO_ACCESS;
#endif
version=refresh_version; // For boot version=refresh_version; // For boot
*scramble= '\0'; *scramble= '\0';
@ -316,7 +318,7 @@ THD::~THD()
#endif #endif
DBUG_PRINT("info", ("freeing host")); DBUG_PRINT("info", ("freeing host"));
if (host != localhost) // If not pointer to constant if (host != my_localhost) // If not pointer to constant
safeFree(host); safeFree(host);
if (user != delayed_user) if (user != delayed_user)
safeFree(user); safeFree(user);

View File

@ -592,6 +592,7 @@ bool mysql_change_db(THD *thd, const char *name)
DBUG_RETURN(1); DBUG_RETURN(1);
} }
DBUG_PRINT("info",("Use database: %s", dbname)); DBUG_PRINT("info",("Use database: %s", dbname));
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (test_all_bits(thd->master_access,DB_ACLS)) if (test_all_bits(thd->master_access,DB_ACLS))
db_access=DB_ACLS; db_access=DB_ACLS;
else else
@ -611,7 +612,7 @@ bool mysql_change_db(THD *thd, const char *name)
my_free(dbname,MYF(0)); my_free(dbname,MYF(0));
DBUG_RETURN(1); DBUG_RETURN(1);
} }
#endif
(void) sprintf(path,"%s/%s",mysql_data_home,dbname); (void) sprintf(path,"%s/%s",mysql_data_home,dbname);
length=unpack_dirname(path,path); // Convert if not unix length=unpack_dirname(path,path); // Convert if not unix
if (length && path[length-1] == FN_LIBCHAR) if (length && path[length-1] == FN_LIBCHAR)
@ -626,8 +627,9 @@ bool mysql_change_db(THD *thd, const char *name)
x_free(thd->db); x_free(thd->db);
thd->db=dbname; // THD::~THD will free this thd->db=dbname; // THD::~THD will free this
thd->db_length=db_length; thd->db_length=db_length;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
thd->db_access=db_access; thd->db_access=db_access;
#endif
strmov(path+unpack_dirname(path,path), MY_DB_OPT_FILE); strmov(path+unpack_dirname(path,path), MY_DB_OPT_FILE);
load_db_opt(thd, path, &create); load_db_opt(thd, path, &create);
thd->db_charset= create.table_charset ? thd->db_charset= create.table_charset ?
@ -656,6 +658,7 @@ int mysqld_show_create_db(THD *thd, char *dbname,
DBUG_RETURN(1); DBUG_RETURN(1);
} }
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (test_all_bits(thd->master_access,DB_ACLS)) if (test_all_bits(thd->master_access,DB_ACLS))
db_access=DB_ACLS; db_access=DB_ACLS;
else else
@ -674,6 +677,7 @@ int mysqld_show_create_db(THD *thd, char *dbname,
dbname); dbname);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
#endif
(void) sprintf(path,"%s/%s",mysql_data_home, dbname); (void) sprintf(path,"%s/%s",mysql_data_home, dbname);
length=unpack_dirname(path,path); // Convert if not unix length=unpack_dirname(path,path); // Convert if not unix

View File

@ -91,13 +91,15 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit,
We have to do access checks here as this code is executed before any We have to do access checks here as this code is executed before any
sql command is started to execute. sql command is started to execute.
*/ */
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (tables) if (tables)
res= check_table_access(thd,SELECT_ACL, tables); res= check_table_access(thd,SELECT_ACL, tables,0);
else else
res= check_access(thd, SELECT_ACL, any_db); res= check_access(thd, SELECT_ACL, any_db,0,0,0);
if (res) if (res)
DBUG_RETURN(1); DBUG_RETURN(1);
#endif
if (!(res=open_and_lock_tables(thd,tables))) if (!(res=open_and_lock_tables(thd,tables)))
{ {
if (is_union || is_subsel) if (is_union || is_subsel)
@ -203,7 +205,9 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit,
org_table_list->table=table; org_table_list->table=table;
table->derived_select_number= select_cursor->select_number; table->derived_select_number= select_cursor->select_number;
table->tmp_table= TMP_TABLE; table->tmp_table= TMP_TABLE;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
org_table_list->grant.privilege= SELECT_ACL; org_table_list->grant.privilege= SELECT_ACL;
#endif
if (lex->describe) if (lex->describe)
{ {
// to fix a problem in EXPLAIN // to fix a problem in EXPLAIN

View File

@ -60,9 +60,11 @@ check_insert_fields(THD *thd,TABLE *table,List<Item> &fields,
MYF(0),counter); MYF(0),counter);
return -1; return -1;
} }
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (grant_option && if (grant_option &&
check_grant_all_columns(thd,INSERT_ACL,table)) check_grant_all_columns(thd,INSERT_ACL,table))
return -1; return -1;
#endif
table->time_stamp=0; // This is saved by caller table->time_stamp=0; // This is saved by caller
} }
else else
@ -96,7 +98,9 @@ check_insert_fields(THD *thd,TABLE *table,List<Item> &fields,
table->time_stamp= table->timestamp_field->offset()+1; table->time_stamp= table->timestamp_field->offset()+1;
} }
// For the values we need select_priv // For the values we need select_priv
#ifndef NO_EMBEDDED_ACCESS_CHECKS
table->grant.want_privilege=(SELECT_ACL & ~table->grant.privilege); table->grant.want_privilege=(SELECT_ACL & ~table->grant.privilege);
#endif
return 0; return 0;
} }
@ -130,14 +134,15 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
thd->lex.select_lex.table_list.first; thd->lex.select_lex.table_list.first;
DBUG_ENTER("mysql_insert"); DBUG_ENTER("mysql_insert");
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (thd->master_access & SUPER_ACL) if (thd->master_access & SUPER_ACL)
#endif
{ {
if (!(thd->options & OPTION_UPDATE_LOG)) if (!(thd->options & OPTION_UPDATE_LOG))
log_on&= ~(int) DELAYED_LOG_UPDATE; log_on&= ~(int) DELAYED_LOG_UPDATE;
if (!(thd->options & OPTION_BIN_LOG)) if (!(thd->options & OPTION_BIN_LOG))
log_on&= ~(int) DELAYED_LOG_BIN; log_on&= ~(int) DELAYED_LOG_BIN;
} }
/* /*
in safe mode or with skip-new change delayed insert to be regular in safe mode or with skip-new change delayed insert to be regular
if we are told to replace duplicates, the insert cannot be concurrent if we are told to replace duplicates, the insert cannot be concurrent
@ -626,7 +631,7 @@ public:
group_count(0) group_count(0)
{ {
thd.user=thd.priv_user=(char*) delayed_user; thd.user=thd.priv_user=(char*) delayed_user;
thd.host=(char*) localhost; thd.host=(char*) my_localhost;
thd.current_tablenr=0; thd.current_tablenr=0;
thd.version=refresh_version; thd.version=refresh_version;
thd.command=COM_DELAYED_INSERT; thd.command=COM_DELAYED_INSERT;

View File

@ -53,15 +53,19 @@ extern "C" int gethostname(char *name, int namelen);
static int check_for_max_user_connections(THD *thd, USER_CONN *uc); static int check_for_max_user_connections(THD *thd, USER_CONN *uc);
static void decrease_user_connections(USER_CONN *uc); static void decrease_user_connections(USER_CONN *uc);
static bool check_db_used(THD *thd,TABLE_LIST *tables); static bool check_db_used(THD *thd,TABLE_LIST *tables);
#ifndef NO_EMBEDDED_ACCESS_CHECKS
static bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *tables); static bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *tables);
static bool single_table_command_access(THD *thd, ulong privilege,
TABLE_LIST *tables, int *res);
#else
#define check_merge_table_access(thd, db, tables) false
#define single_table_command_access(thd, privilege, tables, res) false
#endif
static void remove_escape(char *name); static void remove_escape(char *name);
static void refresh_status(void); static void refresh_status(void);
static bool append_file_to_dir(THD *thd, char **filename_ptr, static bool append_file_to_dir(THD *thd, char **filename_ptr,
char *table_name); char *table_name);
static bool single_table_command_access(THD *thd, ulong privilege,
TABLE_LIST *tables, int *res);
const char *any_db="*any*"; // Special symbol for check_access const char *any_db="*any*"; // Special symbol for check_access
const char *command_name[]={ const char *command_name[]={
@ -176,7 +180,7 @@ end:
} }
#ifndef EMBEDDED_LIBRARY #ifndef NO_EMBEDDED_ACCESS_CHECKS
/* /*
Check if user exist and password supplied is correct. Check if user exist and password supplied is correct.
@ -203,9 +207,9 @@ end:
>0 error, not sent to client >0 error, not sent to client
*/ */
static int check_user(THD *thd, enum enum_server_command command, int check_user(THD *thd, enum enum_server_command command,
const char *passwd, uint passwd_len, const char *db, const char *passwd, uint passwd_len, const char *db,
bool check_count) bool check_count)
{ {
DBUG_ENTER("check_user"); DBUG_ENTER("check_user");
@ -240,6 +244,7 @@ static int check_user(THD *thd, enum enum_server_command command,
USER_RESOURCES ur; USER_RESOURCES ur;
int res= acl_getroot(thd, &ur, passwd, passwd_len); int res= acl_getroot(thd, &ur, passwd, passwd_len);
#ifndef EMBEDDED_LIBRARY
if (res == -1) if (res == -1)
{ {
/* /*
@ -267,6 +272,7 @@ static int check_user(THD *thd, enum enum_server_command command,
/* So as passwd is short, errcode is always >= 0 */ /* So as passwd is short, errcode is always >= 0 */
res= acl_getroot(thd, &ur, (char *) net->read_pos, SCRAMBLE_LENGTH_323); res= acl_getroot(thd, &ur, (char *) net->read_pos, SCRAMBLE_LENGTH_323);
} }
#endif /*EMBEDDED_LIBRARY*/
/* here res is always >= 0 */ /* here res is always >= 0 */
if (res == 0) if (res == 0)
{ {
@ -352,7 +358,7 @@ static int check_user(THD *thd, enum enum_server_command command,
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
#endif // EMBEDDED_LIBRARY #endif /*!NO_EMBEDDED_ACCESS_CHECKS*/
/* /*
@ -463,6 +469,7 @@ bool is_update_query(enum enum_sql_command command)
return uc_update_queries[command]; return uc_update_queries[command];
} }
#ifndef NO_EMBEDDED_ACCESS_CHECKS
/* /*
Check if maximum queries per hour limit has been reached Check if maximum queries per hour limit has been reached
returns 0 if OK. returns 0 if OK.
@ -553,7 +560,7 @@ static void reset_mqh(THD *thd, LEX_USER *lu, bool get_them= 0)
} }
(void) pthread_mutex_unlock(&LOCK_user_conn); (void) pthread_mutex_unlock(&LOCK_user_conn);
} }
#endif /*!NO_EMBEDDED_ACCESS_CHECKS*/
/* /*
Perform handshake, authorize client and update thd ACL variables. Perform handshake, authorize client and update thd ACL variables.
@ -567,9 +574,8 @@ static void reset_mqh(THD *thd, LEX_USER *lu, bool get_them= 0)
> 0 error code (not sent to user) > 0 error code (not sent to user)
*/ */
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
static int static int check_connection(THD *thd)
check_connection(THD *thd)
{ {
uint connect_errors= 0; uint connect_errors= 0;
NET *net= &thd->net; NET *net= &thd->net;
@ -590,8 +596,8 @@ check_connection(THD *thd)
/* Fast local hostname resolve for Win32 */ /* Fast local hostname resolve for Win32 */
if (!strcmp(thd->ip,"127.0.0.1")) if (!strcmp(thd->ip,"127.0.0.1"))
{ {
thd->host= (char*) localhost; thd->host= (char*) my_localhost;
thd->host_or_ip= localhost; thd->host_or_ip= my_localhost;
} }
else else
#endif #endif
@ -624,7 +630,6 @@ check_connection(THD *thd)
bzero((char*) &thd->remote, sizeof(struct sockaddr)); bzero((char*) &thd->remote, sizeof(struct sockaddr));
} }
vio_keepalive(net->vio, TRUE); vio_keepalive(net->vio, TRUE);
ulong pkt_len= 0; ulong pkt_len= 0;
char *end; char *end;
{ {
@ -814,7 +819,6 @@ check_connection(THD *thd)
return check_user(thd, COM_CONNECT, passwd, passwd_len, db, true); return check_user(thd, COM_CONNECT, passwd, passwd_len, db, true);
} }
pthread_handler_decl(handle_one_connection,arg) pthread_handler_decl(handle_one_connection,arg)
{ {
THD *thd=(THD*) arg; THD *thd=(THD*) arg;
@ -1040,11 +1044,12 @@ int mysql_table_dump(THD* thd, char* db, char* tbl_name, int fd)
if (!(table=open_ltable(thd, table_list, TL_READ_NO_INSERT))) if (!(table=open_ltable(thd, table_list, TL_READ_NO_INSERT)))
DBUG_RETURN(1); DBUG_RETURN(1);
if (check_access(thd, SELECT_ACL, db, &table_list->grant.privilege)) #ifndef NO_EMBEDDED_ACCESS_CHECKS
if (check_access(thd, SELECT_ACL, db, &table_list->grant.privilege,0,0))
goto err; goto err;
if (grant_option && check_grant(thd, SELECT_ACL, table_list)) if (grant_option && check_grant(thd, SELECT_ACL, table_list))
goto err; goto err;
#endif
thd->free_list = 0; thd->free_list = 0;
thd->query_length=(uint) strlen(tbl_name); thd->query_length=(uint) strlen(tbl_name);
thd->query = tbl_name; thd->query = tbl_name;
@ -1344,11 +1349,13 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
my_casedn_str(files_charset_info, table_list.real_name); my_casedn_str(files_charset_info, table_list.real_name);
remove_escape(table_list.real_name); // This can't have wildcards remove_escape(table_list.real_name); // This can't have wildcards
if (check_access(thd,SELECT_ACL,table_list.db,&thd->col_access)) #ifndef NO_EMBEDDED_ACCESS_CHECKS
if (check_access(thd,SELECT_ACL,table_list.db,&thd->col_access,0,0))
break; break;
table_list.grant.privilege=thd->col_access; table_list.grant.privilege=thd->col_access;
if (grant_option && check_grant(thd,SELECT_ACL,&table_list,2)) if (grant_option && check_grant(thd,SELECT_ACL,&table_list,2))
break; break;
#endif /*DONT_ALLOW_SHOW_COMMANDS*/
mysqld_list_fields(thd,&table_list,fields); mysqld_list_fields(thd,&table_list,fields);
free_items(thd->free_list); free_items(thd->free_list);
break; break;
@ -1371,7 +1378,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
net_printf(thd,ER_WRONG_DB_NAME, db ? db : "NULL"); net_printf(thd,ER_WRONG_DB_NAME, db ? db : "NULL");
break; break;
} }
if (check_access(thd,CREATE_ACL,db,0,1)) if (check_access(thd,CREATE_ACL,db,0,1,0))
break; break;
mysql_log.write(thd,command,packet); mysql_log.write(thd,command,packet);
mysql_create_db(thd,db,0,0); mysql_create_db(thd,db,0,0);
@ -1387,7 +1394,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
net_printf(thd,ER_WRONG_DB_NAME, db ? db : "NULL"); net_printf(thd,ER_WRONG_DB_NAME, db ? db : "NULL");
break; break;
} }
if (check_access(thd,DROP_ACL,db,0,1)) if (check_access(thd,DROP_ACL,db,0,1,0))
break; break;
if (thd->locked_tables || thd->active_transaction()) if (thd->locked_tables || thd->active_transaction())
{ {
@ -1425,6 +1432,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
break; break;
} }
#endif #endif
#ifndef NO_EMBEDDED_ACCESS_CHECKS
case COM_REFRESH: case COM_REFRESH:
{ {
statistic_increment(com_stat[SQLCOM_FLUSH],&LOCK_status); statistic_increment(com_stat[SQLCOM_FLUSH],&LOCK_status);
@ -1438,6 +1446,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
send_ok(thd); send_ok(thd);
break; break;
} }
#endif
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
case COM_SHUTDOWN: case COM_SHUTDOWN:
statistic_increment(com_other,&LOCK_status); statistic_increment(com_other,&LOCK_status);
@ -1490,11 +1499,19 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
break; break;
case COM_PROCESS_INFO: case COM_PROCESS_INFO:
statistic_increment(com_stat[SQLCOM_SHOW_PROCESSLIST],&LOCK_status); statistic_increment(com_stat[SQLCOM_SHOW_PROCESSLIST],&LOCK_status);
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (!thd->priv_user[0] && check_global_access(thd,PROCESS_ACL)) if (!thd->priv_user[0] && check_global_access(thd,PROCESS_ACL))
break; break;
#endif
mysql_log.write(thd,command,NullS); mysql_log.write(thd,command,NullS);
mysqld_list_processes(thd,thd->master_access & PROCESS_ACL ? NullS : mysqld_list_processes(thd,
thd->priv_user,0); #ifndef NO_EMBEDDED_ACCESS_CHECKS
thd->master_access & PROCESS_ACL ?
NullS : thd->priv_user
#else
NullS
#endif
,0);
break; break;
case COM_PROCESS_KILL: case COM_PROCESS_KILL:
{ {
@ -1634,7 +1651,7 @@ mysql_execute_command(THD *thd)
*/ */
thd->old_total_warn_count= thd->total_warn_count; thd->old_total_warn_count= thd->total_warn_count;
#ifndef EMBEDDED_LIBRARY #ifdef HAVE_REPLICATON
if (thd->slave_thread) if (thd->slave_thread)
{ {
/* /*
@ -1660,7 +1677,7 @@ mysql_execute_command(THD *thd)
} }
#endif #endif
} }
#endif /* !EMBEDDED_LIBRARY */ #endif /* !HAVE_REPLICATION */
/* /*
TODO: make derived tables processing 'inside' SELECT processing. TODO: make derived tables processing 'inside' SELECT processing.
TODO: solve problem with depended derived tables in subselects TODO: solve problem with depended derived tables in subselects
@ -1695,7 +1712,11 @@ mysql_execute_command(THD *thd)
Except for the replication thread and the 'super' users. Except for the replication thread and the 'super' users.
*/ */
if (opt_readonly && if (opt_readonly &&
!(thd->slave_thread || (thd->master_access & SUPER_ACL)) && !(thd->slave_thread
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|| (thd->master_access & SUPER_ACL)
#endif
) &&
(uc_update_queries[lex->sql_command] > 0)) (uc_update_queries[lex->sql_command] > 0))
{ {
send_error(thd, ER_CANT_UPDATE_WITH_READLOCK); send_error(thd, ER_CANT_UPDATE_WITH_READLOCK);
@ -1707,22 +1728,23 @@ mysql_execute_command(THD *thd)
case SQLCOM_SELECT: case SQLCOM_SELECT:
{ {
select_result *result=lex->result; select_result *result=lex->result;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (tables) if (tables)
{ {
res=check_table_access(thd, res=check_table_access(thd,
lex->exchange ? SELECT_ACL | FILE_ACL : lex->exchange ? SELECT_ACL | FILE_ACL :
SELECT_ACL, SELECT_ACL,
tables); tables,0);
} }
else else
res=check_access(thd, lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL, res=check_access(thd, lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL,
any_db); any_db,0,0,0);
if (res) if (res)
{ {
res=0; res=0;
break; // Error message is given break; // Error message is given
} }
#endif
unit->offset_limit_cnt= (ha_rows) unit->global_parameters->offset_limit; unit->offset_limit_cnt= (ha_rows) unit->global_parameters->offset_limit;
unit->select_limit_cnt= (ha_rows) (unit->global_parameters->select_limit+ unit->select_limit_cnt= (ha_rows) (unit->global_parameters->select_limit+
unit->global_parameters->offset_limit); unit->global_parameters->offset_limit);
@ -1770,8 +1792,9 @@ mysql_execute_command(THD *thd)
} }
break; break;
} }
case SQLCOM_DO: case SQLCOM_DO:
if (tables && ((res= check_table_access(thd, SELECT_ACL, tables)) || if (tables && ((res= check_table_access(thd, SELECT_ACL, tables,0)) ||
(res= open_and_lock_tables(thd,tables)))) (res= open_and_lock_tables(thd,tables))))
break; break;
@ -1807,7 +1830,6 @@ mysql_execute_command(THD *thd)
break; break;
} }
#endif #endif
case SQLCOM_SHOW_WARNS: case SQLCOM_SHOW_WARNS:
{ {
res= mysqld_show_warnings(thd, (ulong) res= mysqld_show_warnings(thd, (ulong)
@ -1857,7 +1879,7 @@ mysql_execute_command(THD *thd)
case SQLCOM_BACKUP_TABLE: case SQLCOM_BACKUP_TABLE:
{ {
if (check_db_used(thd,tables) || if (check_db_used(thd,tables) ||
check_table_access(thd,SELECT_ACL, tables) || check_table_access(thd,SELECT_ACL, tables,0) ||
check_global_access(thd, FILE_ACL)) check_global_access(thd, FILE_ACL))
goto error; /* purecov: inspected */ goto error; /* purecov: inspected */
res = mysql_backup_table(thd, tables); res = mysql_backup_table(thd, tables);
@ -1867,7 +1889,7 @@ mysql_execute_command(THD *thd)
case SQLCOM_RESTORE_TABLE: case SQLCOM_RESTORE_TABLE:
{ {
if (check_db_used(thd,tables) || if (check_db_used(thd,tables) ||
check_table_access(thd, INSERT_ACL, tables) || check_table_access(thd, INSERT_ACL, tables,0) ||
check_global_access(thd, FILE_ACL)) check_global_access(thd, FILE_ACL))
goto error; /* purecov: inspected */ goto error; /* purecov: inspected */
res = mysql_restore_table(thd, tables); res = mysql_restore_table(thd, tables);
@ -1876,7 +1898,7 @@ mysql_execute_command(THD *thd)
case SQLCOM_PRELOAD_KEYS: case SQLCOM_PRELOAD_KEYS:
{ {
if (check_db_used(thd, tables) || if (check_db_used(thd, tables) ||
check_access(thd, INDEX_ACL, tables->db, &tables->grant.privilege)) check_access(thd, INDEX_ACL, tables->db, &tables->grant.privilege,0,0))
goto error; goto error;
res = mysql_preload_keys(thd, tables); res = mysql_preload_keys(thd, tables);
break; break;
@ -1933,7 +1955,8 @@ mysql_execute_command(THD *thd)
{ {
if (!tables->db) if (!tables->db)
tables->db=thd->db; tables->db=thd->db;
if (check_access(thd,CREATE_ACL,tables->db,&tables->grant.privilege)) #ifndef NO_EMBEDDED_ACCESS_CHECKS
if (check_access(thd,CREATE_ACL,tables->db,&tables->grant.privilege,0,0))
goto error; /* purecov: inspected */ goto error; /* purecov: inspected */
if (grant_option) if (grant_option)
{ {
@ -1945,6 +1968,7 @@ mysql_execute_command(THD *thd)
if (error) if (error)
goto error; goto error;
} }
#endif
if (strlen(tables->real_name) > NAME_LEN) if (strlen(tables->real_name) > NAME_LEN)
{ {
net_printf(thd,ER_WRONG_TABLE_NAME,tables->real_name); net_printf(thd,ER_WRONG_TABLE_NAME,tables->real_name);
@ -1964,11 +1988,14 @@ mysql_execute_command(THD *thd)
case SQLCOM_CREATE_TABLE: case SQLCOM_CREATE_TABLE:
{ {
#ifndef NO_EMBEDDED_ACCESS_CHECKS
ulong want_priv= ((lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) ? ulong want_priv= ((lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) ?
CREATE_TMP_ACL : CREATE_ACL); CREATE_TMP_ACL : CREATE_ACL);
#endif
if (!tables->db) if (!tables->db)
tables->db=thd->db; tables->db=thd->db;
if (check_access(thd,want_priv,tables->db,&tables->grant.privilege) || #ifndef NO_EMBEDDED_ACCESS_CHECKS
if (check_access(thd,want_priv,tables->db,&tables->grant.privilege,0,0) ||
check_merge_table_access(thd, tables->db, check_merge_table_access(thd, tables->db,
(TABLE_LIST *) (TABLE_LIST *)
lex->create_info.merge_list.first)) lex->create_info.merge_list.first))
@ -1983,6 +2010,7 @@ mysql_execute_command(THD *thd)
if (error) if (error)
goto error; goto error;
} }
#endif
if (strlen(tables->real_name) > NAME_LEN) if (strlen(tables->real_name) > NAME_LEN)
{ {
net_printf(thd, ER_WRONG_TABLE_NAME, tables->alias); net_printf(thd, ER_WRONG_TABLE_NAME, tables->alias);
@ -2012,11 +2040,13 @@ mysql_execute_command(THD *thd)
net_printf(thd,ER_UPDATE_TABLE_USED,tables->real_name); net_printf(thd,ER_UPDATE_TABLE_USED,tables->real_name);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (tables->next) if (tables->next)
{ {
if (check_table_access(thd, SELECT_ACL, tables->next)) if (check_table_access(thd, SELECT_ACL, tables->next,0))
goto error; // Error message is given goto error; // Error message is given
} }
#endif
select_lex->options|= SELECT_NO_UNLOCK; select_lex->options|= SELECT_NO_UNLOCK;
unit->offset_limit_cnt= select_lex->offset_limit; unit->offset_limit_cnt= select_lex->offset_limit;
unit->select_limit_cnt= select_lex->select_limit+ unit->select_limit_cnt= select_lex->select_limit+
@ -2059,10 +2089,12 @@ mysql_execute_command(THD *thd)
case SQLCOM_CREATE_INDEX: case SQLCOM_CREATE_INDEX:
if (!tables->db) if (!tables->db)
tables->db=thd->db; tables->db=thd->db;
if (check_access(thd,INDEX_ACL,tables->db,&tables->grant.privilege)) #ifndef NO_EMBEDDED_ACCESS_CHECKS
if (check_access(thd,INDEX_ACL,tables->db,&tables->grant.privilege,0,0))
goto error; /* purecov: inspected */ goto error; /* purecov: inspected */
if (grant_option && check_grant(thd,INDEX_ACL,tables)) if (grant_option && check_grant(thd,INDEX_ACL,tables))
goto error; goto error;
#endif
if (end_active_trans(thd)) if (end_active_trans(thd))
res= -1; res= -1;
else else
@ -2121,14 +2153,15 @@ mysql_execute_command(THD *thd)
tables->db=thd->db; tables->db=thd->db;
if (!select_lex->db) if (!select_lex->db)
select_lex->db=tables->db; select_lex->db=tables->db;
if (check_access(thd,ALTER_ACL,tables->db,&tables->grant.privilege) || if (check_access(thd,ALTER_ACL,tables->db,&tables->grant.privilege,0,0) ||
check_access(thd,INSERT_ACL | CREATE_ACL,select_lex->db,&priv) || check_access(thd,INSERT_ACL | CREATE_ACL,select_lex->db,&priv,0,0)||
check_merge_table_access(thd, tables->db, check_merge_table_access(thd, tables->db,
(TABLE_LIST *) (TABLE_LIST *)
lex->create_info.merge_list.first)) lex->create_info.merge_list.first))
goto error; /* purecov: inspected */ goto error; /* purecov: inspected */
if (!tables->db) if (!tables->db)
tables->db=thd->db; tables->db=thd->db;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (grant_option) if (grant_option)
{ {
if (check_grant(thd,ALTER_ACL,tables)) if (check_grant(thd,ALTER_ACL,tables))
@ -2144,6 +2177,7 @@ mysql_execute_command(THD *thd)
goto error; goto error;
} }
} }
#endif
/* Don't yet allow changing of symlinks with ALTER TABLE */ /* Don't yet allow changing of symlinks with ALTER TABLE */
lex->create_info.data_file_name=lex->create_info.index_file_name=0; lex->create_info.data_file_name=lex->create_info.index_file_name=0;
/* ALTER TABLE ends previous transaction */ /* ALTER TABLE ends previous transaction */
@ -2162,18 +2196,19 @@ mysql_execute_command(THD *thd)
} }
break; break;
} }
#endif #endif /*DONT_ALLOW_SHOW_COMMANDS*/
case SQLCOM_RENAME_TABLE: case SQLCOM_RENAME_TABLE:
{ {
TABLE_LIST *table; TABLE_LIST *table;
if (check_db_used(thd,tables)) if (check_db_used(thd,tables))
goto error; goto error;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
for (table=tables ; table ; table=table->next->next) for (table=tables ; table ; table=table->next->next)
{ {
if (check_access(thd, ALTER_ACL | DROP_ACL, table->db, if (check_access(thd, ALTER_ACL | DROP_ACL, table->db,
&table->grant.privilege) || &table->grant.privilege,0,0) ||
check_access(thd, INSERT_ACL | CREATE_ACL, table->next->db, check_access(thd, INSERT_ACL | CREATE_ACL, table->next->db,
&table->next->grant.privilege)) &table->next->grant.privilege,0,0))
goto error; goto error;
if (grant_option) if (grant_option)
{ {
@ -2188,6 +2223,7 @@ mysql_execute_command(THD *thd)
goto error; goto error;
} }
} }
#endif
query_cache_invalidate3(thd, tables, 0); query_cache_invalidate3(thd, tables, 0);
if (end_active_trans(thd)) if (end_active_trans(thd))
res= -1; res= -1;
@ -2217,7 +2253,7 @@ mysql_execute_command(THD *thd)
{ {
if (check_db_used(thd, tables) || if (check_db_used(thd, tables) ||
check_access(thd, SELECT_ACL | EXTRA_ACL, tables->db, check_access(thd, SELECT_ACL | EXTRA_ACL, tables->db,
&tables->grant.privilege)) &tables->grant.privilege,0,0))
goto error; goto error;
res = mysqld_show_create(thd, tables); res = mysqld_show_create(thd, tables);
break; break;
@ -2226,7 +2262,7 @@ mysql_execute_command(THD *thd)
case SQLCOM_CHECKSUM: case SQLCOM_CHECKSUM:
{ {
if (check_db_used(thd,tables) || if (check_db_used(thd,tables) ||
check_table_access(thd, SELECT_ACL | EXTRA_ACL , tables)) check_table_access(thd, SELECT_ACL | EXTRA_ACL , tables,0))
goto error; /* purecov: inspected */ goto error; /* purecov: inspected */
res = mysql_checksum_table(thd, tables, &lex->check_opt); res = mysql_checksum_table(thd, tables, &lex->check_opt);
break; break;
@ -2234,7 +2270,7 @@ mysql_execute_command(THD *thd)
case SQLCOM_REPAIR: case SQLCOM_REPAIR:
{ {
if (check_db_used(thd,tables) || if (check_db_used(thd,tables) ||
check_table_access(thd,SELECT_ACL | INSERT_ACL, tables)) check_table_access(thd,SELECT_ACL | INSERT_ACL, tables,0))
goto error; /* purecov: inspected */ goto error; /* purecov: inspected */
res = mysql_repair_table(thd, tables, &lex->check_opt); res = mysql_repair_table(thd, tables, &lex->check_opt);
/* ! we write after unlocking the table */ /* ! we write after unlocking the table */
@ -2252,7 +2288,7 @@ mysql_execute_command(THD *thd)
case SQLCOM_CHECK: case SQLCOM_CHECK:
{ {
if (check_db_used(thd,tables) || if (check_db_used(thd,tables) ||
check_table_access(thd, SELECT_ACL | EXTRA_ACL , tables)) check_table_access(thd, SELECT_ACL | EXTRA_ACL , tables,0))
goto error; /* purecov: inspected */ goto error; /* purecov: inspected */
res = mysql_check_table(thd, tables, &lex->check_opt); res = mysql_check_table(thd, tables, &lex->check_opt);
break; break;
@ -2260,7 +2296,7 @@ mysql_execute_command(THD *thd)
case SQLCOM_ANALYZE: case SQLCOM_ANALYZE:
{ {
if (check_db_used(thd,tables) || if (check_db_used(thd,tables) ||
check_table_access(thd,SELECT_ACL | INSERT_ACL, tables)) check_table_access(thd,SELECT_ACL | INSERT_ACL, tables,0))
goto error; /* purecov: inspected */ goto error; /* purecov: inspected */
res = mysql_analyze_table(thd, tables, &lex->check_opt); res = mysql_analyze_table(thd, tables, &lex->check_opt);
/* ! we write after unlocking the table */ /* ! we write after unlocking the table */
@ -2280,7 +2316,7 @@ mysql_execute_command(THD *thd)
{ {
HA_CREATE_INFO create_info; HA_CREATE_INFO create_info;
if (check_db_used(thd,tables) || if (check_db_used(thd,tables) ||
check_table_access(thd,SELECT_ACL | INSERT_ACL, tables)) check_table_access(thd,SELECT_ACL | INSERT_ACL, tables,0))
goto error; /* purecov: inspected */ goto error; /* purecov: inspected */
if (specialflag & (SPECIAL_SAFE_MODE | SPECIAL_NO_NEW_FUNC)) if (specialflag & (SPECIAL_SAFE_MODE | SPECIAL_NO_NEW_FUNC))
{ {
@ -2320,7 +2356,6 @@ mysql_execute_command(THD *thd)
if (single_table_command_access(thd, UPDATE_ACL, tables, &res)) if (single_table_command_access(thd, UPDATE_ACL, tables, &res))
goto error; goto error;
if (select_lex->item_list.elements != lex->value_list.elements) if (select_lex->item_list.elements != lex->value_list.elements)
{ {
send_error(thd,ER_WRONG_VALUE_COUNT); send_error(thd,ER_WRONG_VALUE_COUNT);
@ -2338,10 +2373,12 @@ mysql_execute_command(THD *thd)
res= -1; res= -1;
break; break;
case SQLCOM_UPDATE_MULTI: case SQLCOM_UPDATE_MULTI:
if (check_access(thd,UPDATE_ACL,tables->db,&tables->grant.privilege)) #ifndef NO_EMBEDDED_ACCESS_CHECKS
if (check_access(thd,UPDATE_ACL,tables->db,&tables->grant.privilege,0,0))
goto error; goto error;
if (grant_option && check_grant(thd,UPDATE_ACL,tables)) if (grant_option && check_grant(thd,UPDATE_ACL,tables))
goto error; goto error;
#endif
if (select_lex->item_list.elements != lex->value_list.elements) if (select_lex->item_list.elements != lex->value_list.elements)
{ {
send_error(thd,ER_WRONG_VALUE_COUNT); send_error(thd,ER_WRONG_VALUE_COUNT);
@ -2371,13 +2408,14 @@ mysql_execute_command(THD *thd)
case SQLCOM_REPLACE: case SQLCOM_REPLACE:
case SQLCOM_INSERT: case SQLCOM_INSERT:
{ {
#ifndef NO_EMBEDDED_ACCESS_CHECKS
my_bool update=(lex->value_list.elements ? UPDATE_ACL : 0); my_bool update=(lex->value_list.elements ? UPDATE_ACL : 0);
ulong privilege= (lex->duplicates == DUP_REPLACE ? ulong privilege= (lex->duplicates == DUP_REPLACE ?
INSERT_ACL | DELETE_ACL : INSERT_ACL | update); INSERT_ACL | DELETE_ACL : INSERT_ACL | update);
if (single_table_command_access(thd, privilege, tables, &res)) if (single_table_command_access(thd, privilege, tables, &res))
goto error; goto error;
#endif
if (select_lex->item_list.elements != lex->value_list.elements) if (select_lex->item_list.elements != lex->value_list.elements)
{ {
send_error(thd,ER_WRONG_VALUE_COUNT); send_error(thd,ER_WRONG_VALUE_COUNT);
@ -2385,7 +2423,12 @@ mysql_execute_command(THD *thd)
} }
res = mysql_insert(thd,tables,lex->field_list,lex->many_values, res = mysql_insert(thd,tables,lex->field_list,lex->many_values,
select_lex->item_list, lex->value_list, select_lex->item_list, lex->value_list,
(update ? DUP_UPDATE : lex->duplicates)); #ifndef NO_EMBEDDED_ACCESS_CHECKS
(update ? DUP_UPDATE : lex->duplicates)
#else
DUP_UPDATE
#endif
);
if (thd->net.report_error) if (thd->net.report_error)
res= -1; res= -1;
break; break;
@ -2398,19 +2441,22 @@ mysql_execute_command(THD *thd)
Check that we have modify privileges for the first table and Check that we have modify privileges for the first table and
select privileges for the rest select privileges for the rest
*/ */
#ifndef NO_EMBEDDED_ACCESS_CHECKS
{ {
ulong privilege= (lex->duplicates == DUP_REPLACE ? ulong privilege= (lex->duplicates == DUP_REPLACE ?
INSERT_ACL | DELETE_ACL : INSERT_ACL); INSERT_ACL | DELETE_ACL : INSERT_ACL);
TABLE_LIST *save_next=tables->next; TABLE_LIST *save_next=tables->next;
tables->next=0; tables->next=0;
if (check_access(thd, privilege, if (check_access(thd, privilege,
tables->db,&tables->grant.privilege) || tables->db,&tables->grant.privilege,0,0) ||
(grant_option && check_grant(thd, privilege, tables))) (grant_option && check_grant(thd, privilege, tables)))
goto error; goto error;
tables->next=save_next; tables->next=save_next;
if ((res=check_table_access(thd, SELECT_ACL, save_next))) if ((res=check_table_access(thd, SELECT_ACL, save_next,0)))
goto error; goto error;
} }
#endif
/* Don't unlock tables until command is written to binary log */ /* Don't unlock tables until command is written to binary log */
select_lex->options|= SELECT_NO_UNLOCK; select_lex->options|= SELECT_NO_UNLOCK;
@ -2444,10 +2490,12 @@ mysql_execute_command(THD *thd)
break; break;
} }
case SQLCOM_TRUNCATE: case SQLCOM_TRUNCATE:
if (check_access(thd,DELETE_ACL,tables->db,&tables->grant.privilege)) #ifndef NO_EMBEDDED_ACCESS_CHECKS
if (check_access(thd,DELETE_ACL,tables->db,&tables->grant.privilege,0,0))
goto error; /* purecov: inspected */ goto error; /* purecov: inspected */
if (grant_option && check_grant(thd,DELETE_ACL,tables)) if (grant_option && check_grant(thd,DELETE_ACL,tables))
goto error; goto error;
#endif
/* /*
Don't allow this within a transaction because we want to use Don't allow this within a transaction because we want to use
re-generate table re-generate table
@ -2461,11 +2509,12 @@ mysql_execute_command(THD *thd)
break; break;
case SQLCOM_DELETE: case SQLCOM_DELETE:
{ {
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (single_table_command_access(thd, DELETE_ACL, tables, &res)) if (single_table_command_access(thd, DELETE_ACL, tables, &res))
goto error; goto error;
// Set privilege for the WHERE clause // Set privilege for the WHERE clause
tables->grant.want_privilege=(SELECT_ACL & ~tables->grant.privilege); tables->grant.want_privilege=(SELECT_ACL & ~tables->grant.privilege);
#endif
res = mysql_delete(thd,tables, select_lex->where, res = mysql_delete(thd,tables, select_lex->where,
(ORDER*) select_lex->order_list.first, (ORDER*) select_lex->order_list.first,
select_lex->select_limit, select_lex->options); select_lex->select_limit, select_lex->options);
@ -2482,8 +2531,8 @@ mysql_execute_command(THD *thd)
/* sql_yacc guarantees that tables and aux_tables are not zero */ /* sql_yacc guarantees that tables and aux_tables are not zero */
if (check_db_used(thd, tables) || check_db_used(thd,aux_tables) || if (check_db_used(thd, tables) || check_db_used(thd,aux_tables) ||
check_table_access(thd,SELECT_ACL, tables) || check_table_access(thd,SELECT_ACL, tables,0) ||
check_table_access(thd,DELETE_ACL, aux_tables)) check_table_access(thd,DELETE_ACL, aux_tables,0))
goto error; goto error;
if ((thd->options & OPTION_SAFE_UPDATES) && !select_lex->where) if ((thd->options & OPTION_SAFE_UPDATES) && !select_lex->where)
{ {
@ -2560,7 +2609,7 @@ mysql_execute_command(THD *thd)
{ {
if (!lex->drop_temporary) if (!lex->drop_temporary)
{ {
if (check_table_access(thd,DROP_ACL,tables)) if (check_table_access(thd,DROP_ACL,tables,0))
goto error; /* purecov: inspected */ goto error; /* purecov: inspected */
if (end_active_trans(thd)) if (end_active_trans(thd))
{ {
@ -2587,10 +2636,12 @@ mysql_execute_command(THD *thd)
case SQLCOM_DROP_INDEX: case SQLCOM_DROP_INDEX:
if (!tables->db) if (!tables->db)
tables->db=thd->db; tables->db=thd->db;
if (check_access(thd,INDEX_ACL,tables->db,&tables->grant.privilege)) #ifndef NO_EMBEDDED_ACCESS_CHECKS
if (check_access(thd,INDEX_ACL,tables->db,&tables->grant.privilege,0,0))
goto error; /* purecov: inspected */ goto error; /* purecov: inspected */
if (grant_option && check_grant(thd,INDEX_ACL,tables)) if (grant_option && check_grant(thd,INDEX_ACL,tables))
goto error; goto error;
#endif
if (end_active_trans(thd)) if (end_active_trans(thd))
res= -1; res= -1;
else else
@ -2608,12 +2659,18 @@ mysql_execute_command(THD *thd)
break; break;
#endif #endif
case SQLCOM_SHOW_PROCESSLIST: case SQLCOM_SHOW_PROCESSLIST:
#ifndef EMBEDDED_LIBRARY #ifndef NO_EMBEDDED_ACCESS_CHECKS
if (!thd->priv_user[0] && check_global_access(thd,PROCESS_ACL)) if (!thd->priv_user[0] && check_global_access(thd,PROCESS_ACL))
break; break;
#endif #endif
mysqld_list_processes(thd,thd->master_access & PROCESS_ACL ? NullS : mysqld_list_processes(thd,
thd->priv_user,lex->verbose); #ifndef NO_EMBEDDED_ACCESS_CHECKS
thd->master_access & PROCESS_ACL ? NullS :
thd->priv_user
#else
NullS
#endif
,lex->verbose);
break; break;
case SQLCOM_SHOW_TABLE_TYPES: case SQLCOM_SHOW_TABLE_TYPES:
res= mysqld_show_table_types(thd); res= mysqld_show_table_types(thd);
@ -2639,8 +2696,10 @@ mysql_execute_command(THD *thd)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
#else #else
{ {
if (grant_option && check_access(thd, FILE_ACL, any_db)) #ifndef NO_EMBEDDED_ACCESS_CHECKS
if (grant_option && check_access(thd, FILE_ACL, any_db,0,0,0))
goto error; goto error;
#endif
res= mysqld_show_logs(thd); res= mysqld_show_logs(thd);
break; break;
} }
@ -2664,7 +2723,8 @@ mysql_execute_command(THD *thd)
net_printf(thd,ER_WRONG_DB_NAME, db); net_printf(thd,ER_WRONG_DB_NAME, db);
goto error; goto error;
} }
if (check_access(thd,SELECT_ACL,db,&thd->col_access)) #ifndef NO_EMBEDDED_ACCESS_CHECKS
if (check_access(thd,SELECT_ACL,db,&thd->col_access,0,0))
goto error; /* purecov: inspected */ goto error; /* purecov: inspected */
if (!thd->col_access && check_grant_db(thd,db)) if (!thd->col_access && check_grant_db(thd,db))
{ {
@ -2674,6 +2734,7 @@ mysql_execute_command(THD *thd)
db); db);
goto error; goto error;
} }
#endif
/* grant is checked in mysqld_show_tables */ /* grant is checked in mysqld_show_tables */
if (select_lex->options & SELECT_DESCRIBE) if (select_lex->options & SELECT_DESCRIBE)
res= mysqld_extend_show_tables(thd,db, res= mysqld_extend_show_tables(thd,db,
@ -2707,11 +2768,13 @@ mysql_execute_command(THD *thd)
} }
remove_escape(db); // Fix escaped '_' remove_escape(db); // Fix escaped '_'
remove_escape(tables->real_name); remove_escape(tables->real_name);
if (check_access(thd,SELECT_ACL | EXTRA_ACL,db,&thd->col_access)) #ifndef NO_EMBEDDED_ACCESS_CHECKS
if (check_access(thd,SELECT_ACL | EXTRA_ACL,db,&thd->col_access,0,0))
goto error; /* purecov: inspected */ goto error; /* purecov: inspected */
tables->grant.privilege=thd->col_access; tables->grant.privilege=thd->col_access;
if (grant_option && check_grant(thd,SELECT_ACL,tables,2)) if (grant_option && check_grant(thd,SELECT_ACL,tables,2))
goto error; goto error;
#endif
res= mysqld_show_fields(thd,tables, res= mysqld_show_fields(thd,tables,
(lex->wild ? lex->wild->ptr() : NullS), (lex->wild ? lex->wild->ptr() : NullS),
lex->verbose); lex->verbose);
@ -2734,11 +2797,13 @@ mysql_execute_command(THD *thd)
remove_escape(tables->real_name); remove_escape(tables->real_name);
if (!tables->db) if (!tables->db)
tables->db=thd->db; tables->db=thd->db;
if (check_access(thd,SELECT_ACL,db,&thd->col_access)) #ifndef NO_EMBEDDED_ACCESS_CHECKS
if (check_access(thd,SELECT_ACL,db,&thd->col_access,0,0))
goto error; /* purecov: inspected */ goto error; /* purecov: inspected */
tables->grant.privilege=thd->col_access; tables->grant.privilege=thd->col_access;
if (grant_option && check_grant(thd,SELECT_ACL,tables,2)) if (grant_option && check_grant(thd,SELECT_ACL,tables,2))
goto error; goto error;
#endif
res= mysqld_show_keys(thd,tables); res= mysqld_show_keys(thd,tables);
break; break;
} }
@ -2749,12 +2814,13 @@ mysql_execute_command(THD *thd)
case SQLCOM_LOAD: case SQLCOM_LOAD:
{ {
#ifndef NO_EMBEDDED_ACCESS_CHECKS
uint privilege= (lex->duplicates == DUP_REPLACE ? uint privilege= (lex->duplicates == DUP_REPLACE ?
INSERT_ACL | DELETE_ACL : INSERT_ACL); INSERT_ACL | DELETE_ACL : INSERT_ACL);
if (!lex->local_file) if (!lex->local_file)
{ {
if (check_access(thd,privilege | FILE_ACL,tables->db)) if (check_access(thd,privilege | FILE_ACL,tables->db,0,0,0))
goto error; goto error;
} }
else else
@ -2765,17 +2831,18 @@ mysql_execute_command(THD *thd)
send_error(thd,ER_NOT_ALLOWED_COMMAND); send_error(thd,ER_NOT_ALLOWED_COMMAND);
goto error; goto error;
} }
if (check_access(thd,privilege,tables->db,&tables->grant.privilege) || if (check_access(thd,privilege,tables->db,&tables->grant.privilege,0,0) ||
grant_option && check_grant(thd,privilege,tables)) grant_option && check_grant(thd,privilege,tables))
goto error; goto error;
} }
#endif /*NO_EMBEDDED_ACCESS_CHECKS*/
res=mysql_load(thd, lex->exchange, tables, lex->field_list, res=mysql_load(thd, lex->exchange, tables, lex->field_list,
lex->duplicates, (bool) lex->local_file, lex->lock_option); lex->duplicates, (bool) lex->local_file, lex->lock_option);
break; break;
} }
case SQLCOM_SET_OPTION: case SQLCOM_SET_OPTION:
if (tables && ((res= check_table_access(thd, SELECT_ACL, tables)) || if (tables && ((res= check_table_access(thd, SELECT_ACL, tables,0)) ||
(res= open_and_lock_tables(thd,tables)))) (res= open_and_lock_tables(thd,tables))))
break; break;
fix_tables_pointers(lex->all_selects_list); fix_tables_pointers(lex->all_selects_list);
@ -2800,7 +2867,7 @@ mysql_execute_command(THD *thd)
unlock_locked_tables(thd); unlock_locked_tables(thd);
if (check_db_used(thd,tables) || end_active_trans(thd)) if (check_db_used(thd,tables) || end_active_trans(thd))
goto error; goto error;
if (check_table_access(thd, LOCK_TABLES_ACL | SELECT_ACL, tables)) if (check_table_access(thd, LOCK_TABLES_ACL | SELECT_ACL, tables,0))
goto error; goto error;
thd->in_lock_tables=1; thd->in_lock_tables=1;
thd->options|= OPTION_TABLE_LOCK; thd->options|= OPTION_TABLE_LOCK;
@ -2837,7 +2904,7 @@ mysql_execute_command(THD *thd)
break; break;
} }
#endif #endif
if (check_access(thd,CREATE_ACL,lex->name,0,1)) if (check_access(thd,CREATE_ACL,lex->name,0,1,0))
break; break;
res=mysql_create_db(thd,lex->name,&lex->create_info,0); res=mysql_create_db(thd,lex->name,&lex->create_info,0);
break; break;
@ -2865,7 +2932,7 @@ mysql_execute_command(THD *thd)
break; break;
} }
#endif #endif
if (check_access(thd,DROP_ACL,lex->name,0,1)) if (check_access(thd,DROP_ACL,lex->name,0,1,0))
break; break;
if (thd->locked_tables || thd->active_transaction()) if (thd->locked_tables || thd->active_transaction())
{ {
@ -2882,7 +2949,7 @@ mysql_execute_command(THD *thd)
net_printf(thd,ER_WRONG_DB_NAME, lex->name); net_printf(thd,ER_WRONG_DB_NAME, lex->name);
break; break;
} }
if (check_access(thd,ALTER_ACL,lex->name,0,1)) if (check_access(thd,ALTER_ACL,lex->name,0,1,0))
break; break;
if (thd->locked_tables || thd->active_transaction()) if (thd->locked_tables || thd->active_transaction())
{ {
@ -2899,7 +2966,7 @@ mysql_execute_command(THD *thd)
net_printf(thd,ER_WRONG_DB_NAME, lex->name); net_printf(thd,ER_WRONG_DB_NAME, lex->name);
break; break;
} }
if (check_access(thd,DROP_ACL,lex->name,0,1)) if (check_access(thd,DROP_ACL,lex->name,0,1,0))
break; break;
if (thd->locked_tables || thd->active_transaction()) if (thd->locked_tables || thd->active_transaction())
{ {
@ -2910,7 +2977,7 @@ mysql_execute_command(THD *thd)
break; break;
} }
case SQLCOM_CREATE_FUNCTION: case SQLCOM_CREATE_FUNCTION:
if (check_access(thd,INSERT_ACL,"mysql",0,1)) if (check_access(thd,INSERT_ACL,"mysql",0,1,0))
break; break;
#ifdef HAVE_DLOPEN #ifdef HAVE_DLOPEN
if (!(res = mysql_create_function(thd,&lex->udf))) if (!(res = mysql_create_function(thd,&lex->udf)))
@ -2920,7 +2987,7 @@ mysql_execute_command(THD *thd)
#endif #endif
break; break;
case SQLCOM_DROP_FUNCTION: case SQLCOM_DROP_FUNCTION:
if (check_access(thd,DELETE_ACL,"mysql",0,1)) if (check_access(thd,DELETE_ACL,"mysql",0,1,0))
break; break;
#ifdef HAVE_DLOPEN #ifdef HAVE_DLOPEN
if (!(res = mysql_drop_function(thd,&lex->udf.name))) if (!(res = mysql_drop_function(thd,&lex->udf.name)))
@ -2929,9 +2996,10 @@ mysql_execute_command(THD *thd)
res= -1; res= -1;
#endif #endif
break; break;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
case SQLCOM_DROP_USER: case SQLCOM_DROP_USER:
{ {
if (check_access(thd, GRANT_ACL,"mysql",0,1)) if (check_access(thd, GRANT_ACL,"mysql",0,1,0))
break; break;
if (!(res= mysql_drop_user(thd, lex->users_list))) if (!(res= mysql_drop_user(thd, lex->users_list)))
{ {
@ -2947,7 +3015,7 @@ mysql_execute_command(THD *thd)
} }
case SQLCOM_REVOKE_ALL: case SQLCOM_REVOKE_ALL:
{ {
if (check_access(thd, GRANT_ACL ,"mysql",0,1)) if (check_access(thd, GRANT_ACL ,"mysql",0,1,0))
break; break;
if (!(res = mysql_revoke_all(thd, lex->users_list))) if (!(res = mysql_revoke_all(thd, lex->users_list)))
{ {
@ -2967,7 +3035,7 @@ mysql_execute_command(THD *thd)
if (check_access(thd, lex->grant | lex->grant_tot_col | GRANT_ACL, if (check_access(thd, lex->grant | lex->grant_tot_col | GRANT_ACL,
tables && tables->db ? tables->db : select_lex->db, tables && tables->db ? tables->db : select_lex->db,
tables ? &tables->grant.privilege : 0, tables ? &tables->grant.privilege : 0,
tables ? 0 : 1)) tables ? 0 : 1,0))
goto error; goto error;
/* /*
@ -2987,7 +3055,7 @@ mysql_execute_command(THD *thd)
my_strcasecmp(&my_charset_latin1, my_strcasecmp(&my_charset_latin1,
user->host.str, thd->host_or_ip))) user->host.str, thd->host_or_ip)))
{ {
if (check_access(thd, UPDATE_ACL, "mysql",0,1)) if (check_access(thd, UPDATE_ACL, "mysql",0,1,0))
goto error; goto error;
break; // We are allowed to do changes break; // We are allowed to do changes
} }
@ -3077,21 +3145,24 @@ mysql_execute_command(THD *thd)
} }
break; break;
} }
#endif /*!NO_EMBEDDED_ACCESS_CHECKS*/
case SQLCOM_KILL: case SQLCOM_KILL:
kill_one_thread(thd,lex->thread_id); kill_one_thread(thd,lex->thread_id);
break; break;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
case SQLCOM_SHOW_GRANTS: case SQLCOM_SHOW_GRANTS:
res=0; res=0;
if ((thd->priv_user && if ((thd->priv_user &&
!strcmp(thd->priv_user,lex->grant_user->user.str)) || !strcmp(thd->priv_user,lex->grant_user->user.str)) ||
!check_access(thd, SELECT_ACL, "mysql",0,1)) !check_access(thd, SELECT_ACL, "mysql",0,1,0))
{ {
res = mysql_show_grants(thd,lex->grant_user); res = mysql_show_grants(thd,lex->grant_user);
} }
break; break;
#endif
case SQLCOM_HA_OPEN: case SQLCOM_HA_OPEN:
if (check_db_used(thd,tables) || if (check_db_used(thd,tables) ||
check_table_access(thd,SELECT_ACL, tables)) check_table_access(thd,SELECT_ACL, tables,0))
goto error; goto error;
res = mysql_ha_open(thd, tables); res = mysql_ha_open(thd, tables);
break; break;
@ -3201,6 +3272,7 @@ error:
} }
#ifndef NO_EMBEDDED_ACCESS_CHECKS
/* /*
Check grants for commands which work only with one table and all other Check grants for commands which work only with one table and all other
tables belong to subselects. tables belong to subselects.
@ -3221,7 +3293,7 @@ static bool single_table_command_access(THD *thd, ulong privilege,
TABLE_LIST *tables, int *res) TABLE_LIST *tables, int *res)
{ {
if (check_access(thd, privilege, tables->db, &tables->grant.privilege)) if (check_access(thd, privilege, tables->db, &tables->grant.privilege,0,0))
return 1; return 1;
// Show only 1 table for check_grant // Show only 1 table for check_grant
@ -3234,7 +3306,7 @@ static bool single_table_command_access(THD *thd, ulong privilege,
if (subselects_tables) if (subselects_tables)
{ {
tables->next= subselects_tables; tables->next= subselects_tables;
if ((*res= check_table_access(thd, SELECT_ACL, subselects_tables))) if ((*res= check_table_access(thd, SELECT_ACL, subselects_tables,0)))
return 1; return 1;
} }
return 0; return 0;
@ -3405,6 +3477,26 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables,
return FALSE; return FALSE;
} }
static bool check_merge_table_access(THD *thd, char *db,
TABLE_LIST *table_list)
{
int error=0;
if (table_list)
{
/* Check that all tables use the current database */
TABLE_LIST *tmp;
for (tmp=table_list; tmp ; tmp=tmp->next)
{
if (!tmp->db || !tmp->db[0])
tmp->db=db;
}
error=check_table_access(thd, SELECT_ACL | UPDATE_ACL | DELETE_ACL,
table_list,0);
}
return error;
}
#endif /*!NO_EMBEDDED_ACCESS_CHECKS*/
static bool check_db_used(THD *thd,TABLE_LIST *tables) static bool check_db_used(THD *thd,TABLE_LIST *tables)
{ {
@ -3422,27 +3514,6 @@ static bool check_db_used(THD *thd,TABLE_LIST *tables)
return FALSE; return FALSE;
} }
static bool check_merge_table_access(THD *thd, char *db,
TABLE_LIST *table_list)
{
int error=0;
if (table_list)
{
/* Check that all tables use the current database */
TABLE_LIST *tmp;
for (tmp=table_list; tmp ; tmp=tmp->next)
{
if (!tmp->db || !tmp->db[0])
tmp->db=db;
}
error=check_table_access(thd, SELECT_ACL | UPDATE_ACL | DELETE_ACL,
table_list);
}
return error;
}
/**************************************************************************** /****************************************************************************
Check stack size; Send error if there isn't enough stack to continue Check stack size; Send error if there isn't enough stack to continue
****************************************************************************/ ****************************************************************************/
@ -3667,12 +3738,14 @@ mysql_parse(THD *thd, char *inBuf, uint length)
LEX *lex=lex_start(thd, (uchar*) inBuf, length); LEX *lex=lex_start(thd, (uchar*) inBuf, length);
if (!yyparse((void *)thd) && ! thd->is_fatal_error) if (!yyparse((void *)thd) && ! thd->is_fatal_error)
{ {
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (mqh_used && thd->user_connect && if (mqh_used && thd->user_connect &&
check_mqh(thd, lex->sql_command)) check_mqh(thd, lex->sql_command))
{ {
thd->net.error = 0; thd->net.error = 0;
} }
else else
#endif
{ {
if (thd->net.report_error) if (thd->net.report_error)
send_error(thd, 0, NullS); send_error(thd, 0, NullS);
@ -4277,7 +4350,7 @@ void add_join_natural(TABLE_LIST *a,TABLE_LIST *b)
b->natural_join=a; b->natural_join=a;
} }
#ifndef NO_EMBEDDED_ACCESS_CHECKS
/* /*
Reload/resets privileges and the different caches. Reload/resets privileges and the different caches.
@ -4407,6 +4480,7 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
*write_to_binlog= tmp_write_to_binlog; *write_to_binlog= tmp_write_to_binlog;
return result; return result;
} }
#endif /*!NO_EMBEDDED_ACCESS_CHECKS*/
/* /*
@ -4438,14 +4512,18 @@ void kill_one_thread(THD *thd, ulong id)
VOID(pthread_mutex_unlock(&LOCK_thread_count)); VOID(pthread_mutex_unlock(&LOCK_thread_count));
if (tmp) if (tmp)
{ {
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if ((thd->master_access & SUPER_ACL) || if ((thd->master_access & SUPER_ACL) ||
!strcmp(thd->user,tmp->user)) !strcmp(thd->user,tmp->user))
#endif
{ {
tmp->awake(1 /*prepare to die*/); tmp->awake(1 /*prepare to die*/);
error=0; error=0;
} }
#ifndef NO_EMBEDDED_ACCESS_CHECKS
else else
error=ER_KILL_DENIED_ERROR; error=ER_KILL_DENIED_ERROR;
#endif
pthread_mutex_unlock(&tmp->LOCK_delete); pthread_mutex_unlock(&tmp->LOCK_delete);
} }

View File

@ -524,16 +524,18 @@ static bool mysql_test_insert_fields(PREP_STMT *stmt,
List_item *values; List_item *values;
DBUG_ENTER("mysql_test_insert_fields"); DBUG_ENTER("mysql_test_insert_fields");
#ifndef NO_EMBEDDED_ACCESS_CHECKS
my_bool update=(thd->lex.value_list.elements ? UPDATE_ACL : 0); my_bool update=(thd->lex.value_list.elements ? UPDATE_ACL : 0);
ulong privilege= (thd->lex.duplicates == DUP_REPLACE ? ulong privilege= (thd->lex.duplicates == DUP_REPLACE ?
INSERT_ACL | DELETE_ACL : INSERT_ACL | update); INSERT_ACL | DELETE_ACL : INSERT_ACL | update);
if (check_access(thd,privilege,table_list->db, if (check_access(thd,privilege,table_list->db,
&table_list->grant.privilege) || &table_list->grant.privilege,0,0) ||
(grant_option && check_grant(thd,privilege,table_list)) || (grant_option && check_grant(thd,privilege,table_list)))
open_and_lock_tables(thd, table_list)) DBUG_RETURN(1);
#endif
if (open_and_lock_tables(thd, table_list))
DBUG_RETURN(1); DBUG_RETURN(1);
table= table_list->table; table= table_list->table;
if ((values= its++)) if ((values= its++))
@ -581,12 +583,14 @@ static bool mysql_test_upd_fields(PREP_STMT *stmt, TABLE_LIST *table_list,
THD *thd= stmt->thd; THD *thd= stmt->thd;
DBUG_ENTER("mysql_test_upd_fields"); DBUG_ENTER("mysql_test_upd_fields");
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (check_access(thd,UPDATE_ACL,table_list->db, if (check_access(thd,UPDATE_ACL,table_list->db,
&table_list->grant.privilege) || &table_list->grant.privilege,0,0) ||
(grant_option && check_grant(thd,UPDATE_ACL,table_list)) || (grant_option && check_grant(thd,UPDATE_ACL,table_list)))
open_and_lock_tables(thd, table_list)) DBUG_RETURN(1);
#endif
if (open_and_lock_tables(thd, table_list))
DBUG_RETURN(1); DBUG_RETURN(1);
if (setup_tables(table_list) || if (setup_tables(table_list) ||
setup_fields(thd, 0, table_list, fields, 1, 0, 0) || setup_fields(thd, 0, table_list, fields, 1, 0, 0) ||
setup_conds(thd, table_list, &conds) || thd->net.report_error) setup_conds(thd, table_list, &conds) || thd->net.report_error)
@ -627,15 +631,16 @@ static bool mysql_test_select_fields(PREP_STMT *stmt, TABLE_LIST *tables,
select_result *result= thd->lex.result; select_result *result= thd->lex.result;
DBUG_ENTER("mysql_test_select_fields"); DBUG_ENTER("mysql_test_select_fields");
#ifndef NO_EMBEDDED_ACCESS_CHECKS
ulong privilege= lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL; ulong privilege= lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL;
if (tables) if (tables)
{ {
if (check_table_access(thd, privilege, tables)) if (check_table_access(thd, privilege, tables,0))
DBUG_RETURN(1); DBUG_RETURN(1);
} }
else if (check_access(thd, privilege, "*any*")) else if (check_access(thd, privilege, "*any*",0,0,0))
DBUG_RETURN(1); DBUG_RETURN(1);
#endif
if ((&lex->select_lex != lex->all_selects_list && if ((&lex->select_lex != lex->all_selects_list &&
lex->unit.create_total_list(thd, lex, &tables, 0))) lex->unit.create_total_list(thd, lex, &tables, 0)))
DBUG_RETURN(1); DBUG_RETURN(1);

View File

@ -669,7 +669,7 @@ int start_slave(THD* thd , MASTER_INFO* mi, bool net_report)
int thread_mask; int thread_mask;
DBUG_ENTER("start_slave"); DBUG_ENTER("start_slave");
if (check_access(thd, SUPER_ACL, any_db)) if (check_access(thd, SUPER_ACL, any_db,0,0,0))
DBUG_RETURN(1); DBUG_RETURN(1);
lock_slave_threads(mi); // this allows us to cleanly read slave_running lock_slave_threads(mi); // this allows us to cleanly read slave_running
// Get a mask of _stopped_ threads // Get a mask of _stopped_ threads
@ -791,7 +791,7 @@ int stop_slave(THD* thd, MASTER_INFO* mi, bool net_report )
if (!thd) if (!thd)
thd = current_thd; thd = current_thd;
if (check_access(thd, SUPER_ACL, any_db)) if (check_access(thd, SUPER_ACL, any_db,0,0,0))
return 1; return 1;
thd->proc_info = "Killing slave"; thd->proc_info = "Killing slave";
int thread_mask; int thread_mask;

View File

@ -73,10 +73,12 @@ mysqld_show_dbs(THD *thd,const char *wild)
while ((file_name=it++)) while ((file_name=it++))
{ {
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (thd->master_access & (DB_ACLS | SHOW_DB_ACL) || if (thd->master_access & (DB_ACLS | SHOW_DB_ACL) ||
acl_get(thd->host, thd->ip, (char*) &thd->remote.sin_addr, acl_get(thd->host, thd->ip, (char*) &thd->remote.sin_addr,
thd->priv_user, file_name,0) || thd->priv_user, file_name,0) ||
(grant_option && !check_grant_db(thd, file_name))) (grant_option && !check_grant_db(thd, file_name)))
#endif
{ {
protocol->prepare_for_resend(); protocol->prepare_for_resend();
protocol->store(file_name, system_charset_info); protocol->store(file_name, system_charset_info);
@ -437,6 +439,7 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path,
continue; continue;
} }
} }
#ifndef NO_EMBEDDED_ACCESS_CHECKS
/* Don't show tables where we don't have any privileges */ /* Don't show tables where we don't have any privileges */
if (db && !(col_access & TABLE_ACLS)) if (db && !(col_access & TABLE_ACLS))
{ {
@ -446,6 +449,7 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path,
if (check_grant(thd,TABLE_ACLS,&table_list,1,1)) if (check_grant(thd,TABLE_ACLS,&table_list,1,1))
continue; continue;
} }
#endif
if (files->push_back(thd->strdup(file->name))) if (files->push_back(thd->strdup(file->name)))
{ {
my_dirend(dirp); my_dirend(dirp);
@ -674,8 +678,9 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild,
} }
file=table->file; file=table->file;
file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
#ifndef NO_EMBEDDED_ACCESS_CHECKS
(void) get_table_grant(thd, table_list); (void) get_table_grant(thd, table_list);
#endif
List<Item> field_list; List<Item> field_list;
field_list.push_back(new Item_empty_string("Field",NAME_LEN)); field_list.push_back(new Item_empty_string("Field",NAME_LEN));
field_list.push_back(new Item_empty_string("Type",40)); field_list.push_back(new Item_empty_string("Type",40));
@ -755,6 +760,7 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild,
{ {
/* Add grant options & comments */ /* Add grant options & comments */
end=tmp; end=tmp;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
col_access= get_column_grant(thd,table_list,field) & COL_ACLS; col_access= get_column_grant(thd,table_list,field) & COL_ACLS;
for (uint bitnr=0; col_access ; col_access>>=1,bitnr++) for (uint bitnr=0; col_access ; col_access>>=1,bitnr++)
{ {
@ -764,6 +770,9 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild,
end=strmov(end,grant_types.type_names[bitnr]); end=strmov(end,grant_types.type_names[bitnr]);
} }
} }
#else
end=strmov(end,"");
#endif
protocol->store(tmp+1,end == tmp ? 0 : (uint) (end-tmp-1), protocol->store(tmp+1,end == tmp ? 0 : (uint) (end-tmp-1),
system_charset_info); system_charset_info);
protocol->store(field->comment.str, field->comment.length, protocol->store(field->comment.str, field->comment.length,

View File

@ -86,8 +86,10 @@ int mysql_update(THD *thd,
/* Calculate "table->used_keys" based on the WHERE */ /* Calculate "table->used_keys" based on the WHERE */
table->used_keys=table->keys_in_use; table->used_keys=table->keys_in_use;
table->quick_keys=0; table->quick_keys=0;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
want_privilege=table->grant.want_privilege; want_privilege=table->grant.want_privilege;
table->grant.want_privilege=(SELECT_ACL & ~table->grant.privilege); table->grant.want_privilege=(SELECT_ACL & ~table->grant.privilege);
#endif
bzero((char*) &tables,sizeof(tables)); // For ORDER BY bzero((char*) &tables,sizeof(tables)); // For ORDER BY
tables.table= table; tables.table= table;
@ -122,7 +124,9 @@ int mysql_update(THD *thd,
} }
/* Check the fields we are going to modify */ /* Check the fields we are going to modify */
#ifndef NO_EMBEDDED_ACCESS_CHECKS
table->grant.want_privilege=want_privilege; table->grant.want_privilege=want_privilege;
#endif
if (setup_fields(thd, 0, update_table_list, fields, 1, 0, 0)) if (setup_fields(thd, 0, update_table_list, fields, 1, 0, 0))
DBUG_RETURN(-1); /* purecov: inspected */ DBUG_RETURN(-1); /* purecov: inspected */
if (table->timestamp_field) if (table->timestamp_field)
@ -134,8 +138,10 @@ int mysql_update(THD *thd,
table->timestamp_field->query_id=timestamp_query_id; table->timestamp_field->query_id=timestamp_query_id;
} }
#ifndef NO_EMBEDDED_ACCESS_CHECKS
/* Check values */ /* Check values */
table->grant.want_privilege=(SELECT_ACL & ~table->grant.privilege); table->grant.want_privilege=(SELECT_ACL & ~table->grant.privilege);
#endif
if (setup_fields(thd, 0, update_table_list, values, 0, 0, 0)) if (setup_fields(thd, 0, update_table_list, values, 0, 0, 0))
{ {
free_underlaid_joins(thd, &thd->lex.select_lex); free_underlaid_joins(thd, &thd->lex.select_lex);
@ -418,7 +424,9 @@ int mysql_multi_update(THD *thd,
TABLE_LIST *tl; TABLE_LIST *tl;
DBUG_ENTER("mysql_multi_update"); DBUG_ENTER("mysql_multi_update");
#ifndef NO_EMBEDDED_ACCESS_CHECKS
table_list->grant.want_privilege=(SELECT_ACL & ~table_list->grant.privilege); table_list->grant.want_privilege=(SELECT_ACL & ~table_list->grant.privilege);
#endif
if ((res=open_and_lock_tables(thd,table_list))) if ((res=open_and_lock_tables(thd,table_list)))
DBUG_RETURN(res); DBUG_RETURN(res);
fix_tables_pointers(thd->lex.all_selects_list); fix_tables_pointers(thd->lex.all_selects_list);