WL#7076: Backporting wl6715 to support both formats in 5.5, 5.6, 5.7

Backporting wl6715 to mysql-5.5
This commit is contained in:
Ashish Agarwal 2013-07-02 11:58:39 +05:30
parent 8723f47391
commit e879caf845
16 changed files with 288 additions and 118 deletions

View file

@ -25,7 +25,7 @@
#define MYSQL_AUDIT_CLASS_MASK_SIZE 1
#define MYSQL_AUDIT_INTERFACE_VERSION 0x0300
#define MYSQL_AUDIT_INTERFACE_VERSION 0x0301
/*************************************************************************
@ -59,6 +59,10 @@ struct mysql_event_general
struct charset_info_st *general_charset;
unsigned long long general_time;
unsigned long long general_rows;
MYSQL_LEX_STRING general_host;
MYSQL_LEX_STRING general_sql_command;
MYSQL_LEX_STRING general_external_user;
MYSQL_LEX_STRING general_ip;
};

View file

@ -210,6 +210,10 @@ struct mysql_event_general
struct charset_info_st *general_charset;
unsigned long long general_time;
unsigned long long general_rows;
MYSQL_LEX_STRING general_host;
MYSQL_LEX_STRING general_sql_command;
MYSQL_LEX_STRING general_external_user;
MYSQL_LEX_STRING general_ip;
};
struct mysql_event_connection
{

View file

@ -699,7 +699,8 @@ int check_embedded_connection(MYSQL *mysql, const char *db)
thd_init_client_charset(thd, mysql->charset->number);
thd->update_charset();
Security_context *sctx= thd->security_ctx;
sctx->host_or_ip= sctx->host= (char*) my_localhost;
sctx->set_phost(my_localhost);
sctx->host_or_ip= sctx->get_host()->ptr();
strmake(sctx->priv_host, (char*) my_localhost, MAX_HOSTNAME-1);
strmake(sctx->priv_user, mysql->user, USERNAME_LENGTH-1);
sctx->user= my_strdup(mysql->user, MYF(0));
@ -727,14 +728,14 @@ int check_embedded_connection(MYSQL *mysql, const char *db)
if (mysql->options.client_ip)
{
sctx->host= my_strdup(mysql->options.client_ip, MYF(0));
sctx->ip= my_strdup(sctx->host, MYF(0));
sctx->set_host(my_strdup(mysql->options.client_ip, MYF(0)));
sctx->set_ip(my_strdup(sctx->host()->ptr(), MYF(0)));
}
else
sctx->host= (char*)my_localhost;
sctx->host_or_ip= sctx->host;
sctx->set_host((char*)my_localhost);
sctx->host_or_ip= sctx->host->ptr();
if (acl_check_host(sctx->host, sctx->ip))
if (acl_check_host(sctx->get_host()->ptr(), sctx->get_ip()->ptr()))
goto err;
/* construct a COM_CHANGE_USER packet */

View file

@ -1218,9 +1218,11 @@ bool LOGGER::slow_log_print(THD *thd, const char *query, uint query_length,
user_host_len= (strxnmov(user_host_buff, MAX_USER_HOST_SIZE,
sctx->priv_user ? sctx->priv_user : "", "[",
sctx->user ? sctx->user : "", "] @ ",
sctx->host ? sctx->host : "", " [",
sctx->ip ? sctx->ip : "", "]", NullS) -
user_host_buff);
sctx->get_host()->length() ?
sctx->get_host()->ptr() : "", " [",
sctx->get_ip()->length() ? sctx->get_ip()->ptr() :
"", "]", NullS) - user_host_buff);
current_time= my_time_possible_from_micro(current_utime);
if (thd->start_utime)

View file

@ -3085,6 +3085,44 @@ SHOW_VAR com_status_vars[]= {
{NullS, NullS, SHOW_LONG}
};
LEX_CSTRING sql_statement_names[(uint) SQLCOM_END + 1];
void init_sql_statement_names()
{
static LEX_CSTRING empty= { C_STRING_WITH_LEN("") };
char *first_com= (char*) offsetof(STATUS_VAR, com_stat[0]);
char *last_com= (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_END]);
int record_size= (char*) offsetof(STATUS_VAR, com_stat[1])
- (char*) offsetof(STATUS_VAR, com_stat[0]);
char *ptr;
uint i;
uint com_index;
for (i= 0; i < ((uint) SQLCOM_END + 1); i++)
sql_statement_names[i]= empty;
SHOW_VAR *var= &com_status_vars[0];
while (var->name != NULL)
{
ptr= var->value;
if ((first_com <= ptr) && (ptr <= last_com))
{
com_index= ((int)(ptr - first_com))/record_size;
DBUG_ASSERT(com_index < (uint) SQLCOM_END);
sql_statement_names[com_index].str= var->name;
/* TODO: Change SHOW_VAR::name to a LEX_STRING, to avoid strlen() */
sql_statement_names[com_index].length= strlen(var->name);
}
var++;
}
DBUG_ASSERT(strcmp(sql_statement_names[(uint) SQLCOM_SELECT].str, "select") == 0);
DBUG_ASSERT(strcmp(sql_statement_names[(uint) SQLCOM_SIGNAL].str, "signal") == 0);
sql_statement_names[(uint) SQLCOM_END].str= "error";
}
/**
Create the name of the default general log file
@ -4274,6 +4312,7 @@ int mysqld_main(int argc, char **argv)
/* Must be initialized early for comparison of options name */
system_charset_info= &my_charset_utf8_general_ci;
init_sql_statement_names();
sys_var_init();
#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
@ -5352,7 +5391,7 @@ void handle_connections_sockets()
continue;
}
if (sock == unix_sock)
thd->security_ctx->host=(char*) my_localhost;
thd->security_ctx->set_host((char*) my_localhost);
create_new_thread(thd);
}

View file

@ -218,6 +218,7 @@ extern I_List<THD> threads;
extern char err_shared_dir[];
extern TYPELIB thread_handling_typelib;
extern my_decimal decimal_zero;
void init_sql_statement_names();
/*
THR_MALLOC is a key which will be used to set/get MEM_ROOT** for a thread,

View file

@ -1309,8 +1309,8 @@ bool acl_getroot(Security_context *sctx, char *user, char *host,
(host ? host : "(NULL)"), (ip ? ip : "(NULL)"),
user, (db ? db : "(NULL)")));
sctx->user= user;
sctx->host= host;
sctx->ip= ip;
sctx->set_host(host);
sctx->set_ip(ip);
sctx->host_or_ip= host ? host : (ip ? ip : "");
if (!initialized)
@ -2205,7 +2205,7 @@ static bool test_if_create_new_users(THD *thd)
C_STRING_WITH_LEN("user"), "user", TL_WRITE);
create_new_users= 1;
db_access=acl_get(sctx->host, sctx->ip,
db_access=acl_get(sctx->get_host()->ptr(), sctx->get_ip()->ptr(),
sctx->priv_user, tl.db, 0);
if (!(db_access & INSERT_ACL))
{
@ -4631,7 +4631,8 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
}
continue;
}
GRANT_TABLE *grant_table= table_hash_search(sctx->host, sctx->ip,
GRANT_TABLE *grant_table= table_hash_search(sctx->get_host()->ptr(),
sctx->get_ip()->ptr(),
tl->get_db_name(),
sctx->priv_user,
tl->get_table_name(),
@ -4721,10 +4722,10 @@ bool check_grant_column(THD *thd, GRANT_INFO *grant,
if (grant->version != grant_version)
{
grant->grant_table=
table_hash_search(sctx->host, sctx->ip, db_name,
sctx->priv_user,
table_hash_search(sctx->get_host()->ptr(), sctx->get_ip()->ptr(),
db_name, sctx->priv_user,
table_name, 0); /* purecov: inspected */
grant->version= grant_version; /* purecov: inspected */
grant->version= grant_version; /* purecov: inspected */
}
if (!(grant_table= grant->grant_table))
goto err; /* purecov: deadcode */
@ -4871,8 +4872,8 @@ bool check_grant_all_columns(THD *thd, ulong want_access_arg,
if (grant->version != grant_version)
{
grant->grant_table=
table_hash_search(sctx->host, sctx->ip, db_name,
sctx->priv_user,
table_hash_search(sctx->get_host()->ptr(), sctx->get_ip()->ptr(),
db_name, sctx->priv_user,
table_name, 0); /* purecov: inspected */
grant->version= grant_version; /* purecov: inspected */
}
@ -4930,7 +4931,8 @@ static bool check_grant_db_routine(THD *thd, const char *db, HASH *hash)
if (strcmp(item->user, sctx->priv_user) == 0 &&
strcmp(item->db, db) == 0 &&
compare_hostname(&item->host, sctx->host, sctx->ip))
compare_hostname(&item->host, sctx->get_host()->ptr(),
sctx->get_ip()->ptr()))
{
return FALSE;
}
@ -4974,7 +4976,8 @@ bool check_grant_db(THD *thd,const char *db)
idx);
if (len < grant_table->key_length &&
!memcmp(grant_table->hash_key,helping,len) &&
compare_hostname(&grant_table->host, sctx->host, sctx->ip))
compare_hostname(&grant_table->host, sctx->get_host()->ptr(),
sctx->get_ip()->ptr()))
{
error= FALSE; /* Found match. */
break;
@ -5025,8 +5028,8 @@ bool check_grant_routine(THD *thd, ulong want_access,
for (table= procs; table; table= table->next_global)
{
GRANT_NAME *grant_proc;
if ((grant_proc= routine_hash_search(host, sctx->ip, table->db, user,
table->table_name, is_proc, 0)))
if ((grant_proc= routine_hash_search(host, sctx->get_ip()->ptr(), table->db,
user, table->table_name, is_proc, 0)))
table->grant.privilege|= grant_proc->privs;
if (want_access & ~table->grant.privilege)
@ -5081,7 +5084,7 @@ bool check_routine_level_acl(THD *thd, const char *db, const char *name,
Security_context *sctx= thd->security_ctx;
mysql_rwlock_rdlock(&LOCK_grant);
if ((grant_proc= routine_hash_search(sctx->priv_host,
sctx->ip, db,
sctx->get_ip()->ptr(), db,
sctx->priv_user,
name, is_proc, 0)))
no_routine_acl= !(grant_proc->privs & SHOW_PROC_ACLS);
@ -5105,8 +5108,8 @@ ulong get_table_grant(THD *thd, TABLE_LIST *table)
#ifdef EMBEDDED_LIBRARY
grant_table= NULL;
#else
grant_table= table_hash_search(sctx->host, sctx->ip, db, sctx->priv_user,
table->table_name, 0);
grant_table= table_hash_search(sctx->get_host()->ptr(), sctx->get_ip()->ptr(),
db, sctx->priv_user, table->table_name, 0);
#endif
table->grant.grant_table=grant_table; // Remember for column test
table->grant.version=grant_version;
@ -5150,7 +5153,7 @@ ulong get_column_grant(THD *thd, GRANT_INFO *grant,
{
Security_context *sctx= thd->security_ctx;
grant->grant_table=
table_hash_search(sctx->host, sctx->ip,
table_hash_search(sctx->get_host()->ptr(), sctx->get_ip()->ptr(),
db_name, sctx->priv_user,
table_name, 0); /* purecov: inspected */
grant->version= grant_version; /* purecov: inspected */
@ -7126,9 +7129,11 @@ bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name,
if ((au= find_acl_user(combo->host.str=(char*)sctx->host_or_ip,combo->user.str,FALSE)))
goto found_acl;
if ((au= find_acl_user(combo->host.str=(char*)sctx->host, combo->user.str,FALSE)))
if ((au= find_acl_user(combo->host.str=(char*)sctx->get_host()->ptr(),
combo->user.str,FALSE)))
goto found_acl;
if ((au= find_acl_user(combo->host.str=(char*)sctx->ip, combo->user.str,FALSE)))
if ((au= find_acl_user(combo->host.str=(char*)sctx->get_ip()->ptr(),
combo->user.str,FALSE)))
goto found_acl;
if((au= find_acl_user(combo->host.str=(char*)"%", combo->user.str, FALSE)))
goto found_acl;
@ -7303,9 +7308,9 @@ acl_check_proxy_grant_access(THD *thd, const char *host, const char *user,
{
ACL_PROXY_USER *proxy= dynamic_element(&acl_proxy_users, i,
ACL_PROXY_USER *);
if (proxy->matches(thd->security_ctx->host,
if (proxy->matches(thd->security_ctx->get_host()->ptr(),
thd->security_ctx->user,
thd->security_ctx->ip,
thd->security_ctx->get_ip()->ptr(),
user) &&
proxy->get_with_grant())
{
@ -7758,7 +7763,8 @@ void fill_effective_table_privileges(THD *thd, GRANT_INFO *grant,
Security_context *sctx= thd->security_ctx;
DBUG_ENTER("fill_effective_table_privileges");
DBUG_PRINT("enter", ("Host: '%s', Ip: '%s', User: '%s', table: `%s`.`%s`",
sctx->priv_host, (sctx->ip ? sctx->ip : "(NULL)"),
sctx->priv_host, (sctx->get_ip()->length() ?
sctx->get_ip()->ptr() : "(NULL)"),
(sctx->priv_user ? sctx->priv_user : "(NULL)"),
db, table));
/* --skip-grants */
@ -7780,14 +7786,15 @@ void fill_effective_table_privileges(THD *thd, GRANT_INFO *grant,
}
/* db privileges */
grant->privilege|= acl_get(sctx->host, sctx->ip, sctx->priv_user, db, 0);
grant->privilege|= acl_get(sctx->get_host()->ptr(), sctx->get_ip()->ptr(),
sctx->priv_user, db, 0);
/* table privileges */
mysql_rwlock_rdlock(&LOCK_grant);
if (grant->version != grant_version)
{
grant->grant_table=
table_hash_search(sctx->host, sctx->ip, db,
table_hash_search(sctx->get_host()->ptr(), sctx->get_ip()->ptr(), db,
sctx->priv_user,
table, 0); /* purecov: inspected */
grant->version= grant_version; /* purecov: inspected */
@ -9374,8 +9381,8 @@ server_mpvio_initialize(THD *thd, MPVIO_EXT *mpvio, uint connect_errors,
mpvio->thread_id= thd->thread_id;
mpvio->server_status= &thd->server_status;
mpvio->net= &thd->net;
mpvio->ip= thd->security_ctx->ip;
mpvio->host= thd->security_ctx->host;
mpvio->ip= (char *) thd->security_ctx->get_ip()->ptr();
mpvio->host= (char *) thd->security_ctx->get_host()->ptr();
mpvio->charset_adapter= charset_adapter;
}
@ -9524,9 +9531,10 @@ acl_authenticate(THD *thd, uint connect_errors, uint com_change_user_pkt_len)
const char *auth_user = acl_user->user ? acl_user->user : "";
ACL_PROXY_USER *proxy_user;
/* check if the user is allowed to proxy as another user */
proxy_user= acl_find_proxy_user(auth_user, sctx->host, sctx->ip,
proxy_user= acl_find_proxy_user(auth_user, sctx->get_host()->ptr(),
sctx->get_ip()->ptr(),
mpvio.auth_info.authenticated_as,
&is_proxy_user);
&is_proxy_user);
if (is_proxy_user)
{
ACL_USER *acl_proxy_user;
@ -9651,7 +9659,7 @@ acl_authenticate(THD *thd, uint connect_errors, uint com_change_user_pkt_len)
}
if (mpvio.auth_info.external_user[0])
sctx->external_user= my_strdup(mpvio.auth_info.external_user, MYF(0));
sctx->set_external_user(my_strdup(mpvio.auth_info.external_user, MYF(0)));
if (res == CR_OK_HANDSHAKE_COMPLETE)
thd->stmt_da->disable_status();

View file

@ -83,6 +83,10 @@ static void general_class_handler(THD *thd, uint event_subtype, va_list ap)
event.general_query_length= va_arg(ap, unsigned int);
event.general_charset= va_arg(ap, struct charset_info_st *);
event.general_rows= (unsigned long long) va_arg(ap, ha_rows);
event.general_sql_command= va_arg(ap, MYSQL_LEX_STRING);
event.general_host= va_arg(ap, MYSQL_LEX_STRING);
event.general_external_user= va_arg(ap, MYSQL_LEX_STRING);
event.general_ip= va_arg(ap, MYSQL_LEX_STRING);
event_class_dispatch(thd, MYSQL_AUDIT_GENERAL_CLASS, &event);
}

View file

@ -49,8 +49,9 @@ static inline uint make_user_name(THD *thd, char *buf)
return strxnmov(buf, MAX_USER_HOST_SIZE,
sctx->priv_user[0] ? sctx->priv_user : "", "[",
sctx->user ? sctx->user : "", "] @ ",
sctx->host ? sctx->host : "", " [",
sctx->ip ? sctx->ip : "", "]", NullS) - buf;
sctx->get_host()->length() ? sctx->get_host()->ptr() :
"", " [", sctx->get_ip()->length() ? sctx->get_ip()->ptr() :
"", "]", NullS) - buf;
}
/**
@ -75,16 +76,38 @@ void mysql_audit_general_log(THD *thd, time_t time,
#ifndef EMBEDDED_LIBRARY
if (mysql_global_audit_mask[0] & MYSQL_AUDIT_GENERAL_CLASSMASK)
{
CHARSET_INFO *clientcs= thd ? thd->variables.character_set_client
: global_system_variables.character_set_client;
MYSQL_LEX_STRING sql_command, ip, host, external_user;
static MYSQL_LEX_STRING empty= { C_STRING_WITH_LEN("") };
if (thd)
{
ip.str= (char *) thd->security_ctx->get_ip()->ptr();
ip.length= thd->security_ctx->get_ip()->length();
host.str= (char *) thd->security_ctx->get_host()->ptr();
host.length= thd->security_ctx->get_host()->length();
external_user.str= (char *) thd->security_ctx->get_external_user()->ptr();
external_user.length= thd->security_ctx->get_external_user()->length();
sql_command.str= (char *) sql_statement_names[thd->lex->sql_command].str;
sql_command.length= sql_statement_names[thd->lex->sql_command].length;
}
else
{
ip= empty;
host= empty;
external_user= empty;
sql_command= empty;
}
const CHARSET_INFO *clientcs= thd ? thd->variables.character_set_client
: global_system_variables.character_set_client;
mysql_audit_notify(thd, MYSQL_AUDIT_GENERAL_CLASS, MYSQL_AUDIT_GENERAL_LOG,
0, time, user, userlen, cmd, cmdlen,
query, querylen, clientcs, 0);
0, time, user, userlen, cmd, cmdlen, query, querylen,
clientcs, 0, sql_command, host, external_user, ip);
}
#endif
}
/**
Call audit plugins of GENERAL audit class.
event_subtype should be set to one of:
@ -106,11 +129,13 @@ void mysql_audit_general(THD *thd, uint event_subtype,
{
time_t time= my_time(0);
uint msglen= msg ? strlen(msg) : 0;
const char *user;
uint userlen;
const char *user;
char user_buff[MAX_USER_HOST_SIZE];
CSET_STRING query;
MYSQL_LEX_STRING ip, host, external_user, sql_command;
ha_rows rows;
static MYSQL_LEX_STRING empty= { C_STRING_WITH_LEN("") };
if (thd)
{
@ -118,17 +143,30 @@ void mysql_audit_general(THD *thd, uint event_subtype,
user= user_buff;
userlen= make_user_name(thd, user_buff);
rows= thd->warning_info->current_row_for_warning();
ip.str= (char *) thd->security_ctx->get_ip()->ptr();
ip.length= thd->security_ctx->get_ip()->length();
host.str= (char *) thd->security_ctx->get_host()->ptr();
host.length= thd->security_ctx->get_host()->length();
external_user.str= (char *) thd->security_ctx->get_external_user()->ptr();
external_user.length= thd->security_ctx->get_external_user()->length();
sql_command.str= (char *) sql_statement_names[thd->lex->sql_command].str;
sql_command.length= sql_statement_names[thd->lex->sql_command].length;
}
else
{
user= 0;
userlen= 0;
ip= empty;
host= empty;
external_user= empty;
sql_command= empty;
rows= 0;
}
mysql_audit_notify(thd, MYSQL_AUDIT_GENERAL_CLASS, event_subtype,
error_code, time, user, userlen, msg, msglen,
query.str(), query.length(), query.charset(), rows);
query.str(), query.length(), query.charset(), rows,
sql_command, host, external_user, ip);
}
#endif
}
@ -139,14 +177,13 @@ void mysql_audit_general(THD *thd, uint event_subtype,
(thd)->thread_id, (thd)->security_ctx->user,\
(thd)->security_ctx->user ? strlen((thd)->security_ctx->user) : 0,\
(thd)->security_ctx->priv_user, strlen((thd)->security_ctx->priv_user),\
(thd)->security_ctx->external_user,\
(thd)->security_ctx->external_user ?\
strlen((thd)->security_ctx->external_user) : 0,\
(thd)->security_ctx->get_external_user()->ptr(),\
(thd)->security_ctx->get_external_user()->length(),\
(thd)->security_ctx->proxy_user, strlen((thd)->security_ctx->proxy_user),\
(thd)->security_ctx->host,\
(thd)->security_ctx->host ? strlen((thd)->security_ctx->host) : 0,\
(thd)->security_ctx->ip,\
(thd)->security_ctx->ip ? strlen((thd)->security_ctx->ip) : 0,\
(thd)->security_ctx->get_host()->ptr(),\
(thd)->security_ctx->get_host()->length(),\
(thd)->security_ctx->get_ip()->ptr(),\
(thd)->security_ctx->get_ip()->length(),\
(thd)->db, (thd)->db ? strlen((thd)->db) : 0)
#define MYSQL_AUDIT_NOTIFY_CONNECTION_DISCONNECT(thd, errcode)\
@ -160,14 +197,13 @@ void mysql_audit_general(THD *thd, uint event_subtype,
(thd)->thread_id, (thd)->security_ctx->user,\
(thd)->security_ctx->user ? strlen((thd)->security_ctx->user) : 0,\
(thd)->security_ctx->priv_user, strlen((thd)->security_ctx->priv_user),\
(thd)->security_ctx->external_user,\
(thd)->security_ctx->external_user ?\
strlen((thd)->security_ctx->external_user) : 0,\
(thd)->security_ctx->get_external_user()->ptr(),\
(thd)->security_ctx->get_external_user()->length(),\
(thd)->security_ctx->proxy_user, strlen((thd)->security_ctx->proxy_user),\
(thd)->security_ctx->host,\
(thd)->security_ctx->host ? strlen((thd)->security_ctx->host) : 0,\
(thd)->security_ctx->ip,\
(thd)->security_ctx->ip ? strlen((thd)->security_ctx->ip) : 0,\
(thd)->security_ctx->get_host()->ptr(),\
(thd)->security_ctx->get_host()->length(),\
(thd)->security_ctx->get_ip()->ptr(),\
(thd)->security_ctx->get_ip()->length(),\
(thd)->db, (thd)->db ? strlen((thd)->db) : 0)
#endif /* SQL_AUDIT_INCLUDED */

View file

@ -675,7 +675,7 @@ char *thd_security_context(THD *thd, char *buffer, unsigned int length,
unsigned int max_query_len)
{
String str(buffer, length, &my_charset_latin1);
const Security_context *sctx= &thd->main_security_ctx;
Security_context *sctx= &thd->main_security_ctx;
char header[256];
int len;
/*
@ -695,16 +695,16 @@ char *thd_security_context(THD *thd, char *buffer, unsigned int length,
str.length(0);
str.append(header, len);
if (sctx->host)
if (sctx->get_host()->length())
{
str.append(' ');
str.append(sctx->host);
str.append(sctx->get_host()->ptr());
}
if (sctx->ip)
if (sctx->get_ip()->length())
{
str.append(' ');
str.append(sctx->ip);
str.append(sctx->get_ip()->ptr());
}
if (sctx->user)
@ -3341,7 +3341,10 @@ void THD::set_status_var_init()
void Security_context::init()
{
host= user= ip= external_user= 0;
user= 0;
ip.set("", 0, system_charset_info);
host.set("", 0, system_charset_info);
external_user.set("", 0, system_charset_info);
host_or_ip= "connecting host";
priv_user[0]= priv_host[0]= proxy_user[0]= '\0';
master_access= 0;
@ -3350,29 +3353,35 @@ void Security_context::init()
#endif
}
void Security_context::destroy()
{
// If not pointer to constant
if (host != my_localhost)
if (host.ptr() != my_localhost && host.length())
{
my_free(host);
host= NULL;
char *c= (char *) host.ptr();
host.set("", 0, system_charset_info);
my_free(c);
}
if (user != delayed_user)
if (user)
{
my_free(user);
user= NULL;
}
if (external_user)
if (external_user.length())
{
my_free(external_user);
user= NULL;
char *c= (char *) external_user.ptr();
external_user.set("", 0, system_charset_info);
my_free(c);
}
if (ip.length())
{
char *c= (char *) ip.ptr();
ip.set("", 0, system_charset_info);
my_free(c);
}
my_free(ip);
ip= NULL;
}
@ -3392,6 +3401,45 @@ bool Security_context::set_user(char *user_arg)
return user == 0;
}
String *Security_context::get_host()
{
return (&host);
}
String *Security_context::get_ip()
{
return (&ip);
}
String *Security_context::get_external_user()
{
return (&external_user);
}
void Security_context::set_host(const char *str)
{
uint len= str ? strlen(str) : 0;
host.set(str, len, system_charset_info);
}
void Security_context::set_ip(const char *str)
{
uint len= str ? strlen(str) : 0;
ip.set(str, len, system_charset_info);
}
void Security_context::set_external_user(const char *str)
{
uint len= str ? strlen(str) : 0;
external_user.set(str, len, system_charset_info);
}
void Security_context::set_host(const char * str, size_t len)
{
host.set(str, len, system_charset_info);
host.c_ptr_quick();
}
#ifndef NO_EMBEDDED_ACCESS_CHECKS
/**
Initialize this security context from the passed in credentials

View file

@ -388,6 +388,7 @@ extern const LEX_STRING Diag_condition_item_names[];
#include "sql_lex.h" /* Must be here */
extern LEX_CSTRING sql_statement_names[(uint) SQLCOM_END + 1];
class Delayed_insert;
class select_result;
class Time_zone;
@ -895,6 +896,11 @@ void xid_cache_delete(XID_STATE *xid_state);
*/
class Security_context {
private:
String host;
String ip;
String external_user;
public:
Security_context() {} /* Remove gcc warning */
/*
@ -904,13 +910,11 @@ public:
priv_user - The user privilege we are using. May be "" for anonymous user.
ip - client IP
*/
char *host, *user, *ip;
char *user;
char priv_user[USERNAME_LENGTH];
char proxy_user[USERNAME_LENGTH + MAX_HOSTNAME + 5];
/* The host privilege we are using */
char priv_host[MAX_HOSTNAME];
/* The external user (if available) */
char *external_user;
/* points to host if host is available, otherwise points to ip */
const char *host_or_ip;
ulong master_access; /* Global privileges from mysql.user */
@ -925,7 +929,13 @@ public:
}
bool set_user(char *user_arg);
String *get_host();
String *get_ip();
String *get_external_user();
void set_host(const char *p);
void set_ip(const char *p);
void set_external_user(const char *p);
void set_host(const char *str, size_t len);
#ifndef NO_EMBEDDED_ACCESS_CHECKS
bool
change_security_context(THD *thd,

View file

@ -38,6 +38,7 @@
#include "sql_acl.h" // acl_getroot, NO_ACCESS, SUPER_ACL
#include "sql_callback.h"
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
/*
Without SSL the handshake consists of one packet. This packet
@ -490,7 +491,7 @@ static int check_connection(THD *thd)
thd->set_active_vio(net->vio);
#endif
if (!thd->main_security_ctx.host) // If TCP/IP connection
if (!thd->main_security_ctx.get_host()->length()) // If TCP/IP connection
{
char ip[NI_MAXHOST];
@ -512,25 +513,30 @@ static int check_connection(THD *thd)
};);
/* END : DEBUG */
if (!(thd->main_security_ctx.ip= my_strdup(ip,MYF(MY_WME))))
thd->main_security_ctx.set_ip(my_strdup(ip, MYF(MY_WME)));
if (!(thd->main_security_ctx.get_ip()->length()))
return 1; /* The error is set by my_strdup(). */
thd->main_security_ctx.host_or_ip= thd->main_security_ctx.ip;
thd->main_security_ctx.host_or_ip= thd->main_security_ctx.get_ip()->ptr();
if (!(specialflag & SPECIAL_NO_RESOLVE))
{
if (ip_to_hostname(&net->vio->remote, thd->main_security_ctx.ip,
&thd->main_security_ctx.host, &connect_errors))
char *host= (char *) thd->main_security_ctx.get_host()->ptr();
if (ip_to_hostname(&net->vio->remote,
thd->main_security_ctx.get_ip()->ptr(),
&host, &connect_errors))
{
my_error(ER_BAD_HOST_ERROR, MYF(0));
return 1;
}
/* Cut very long hostnames to avoid possible overflows */
if (thd->main_security_ctx.host)
if (thd->main_security_ctx.get_host()->length())
{
if (thd->main_security_ctx.host != my_localhost)
thd->main_security_ctx.host[min(strlen(thd->main_security_ctx.host),
HOSTNAME_LENGTH)]= 0;
thd->main_security_ctx.host_or_ip= thd->main_security_ctx.host;
if (thd->main_security_ctx.get_host()->ptr() != my_localhost)
thd->main_security_ctx.set_host(thd->main_security_ctx.get_host()->ptr(),
min(thd->main_security_ctx.get_host()->length(),
HOSTNAME_LENGTH));
thd->main_security_ctx.host_or_ip=
thd->main_security_ctx.get_host()->ptr();
}
if (connect_errors > max_connect_errors)
{
@ -539,11 +545,14 @@ static int check_connection(THD *thd)
}
}
DBUG_PRINT("info",("Host: %s ip: %s",
(thd->main_security_ctx.host ?
thd->main_security_ctx.host : "unknown host"),
(thd->main_security_ctx.ip ?
thd->main_security_ctx.ip : "unknown ip")));
if (acl_check_host(thd->main_security_ctx.host, thd->main_security_ctx.ip))
(thd->main_security_ctx.get_host()->length() ?
thd->main_security_ctx.get_host()->ptr() :
"unknown host"),
(thd->main_security_ctx.get_ip()->length() ?
thd->main_security_ctx.get_ip()->ptr()
: "unknown ip")));
if (acl_check_host(thd->main_security_ctx.get_host()->ptr(),
thd->main_security_ctx.get_ip()->ptr()))
{
my_error(ER_HOST_NOT_PRIVILEGED, MYF(0),
thd->main_security_ctx.host_or_ip);
@ -552,9 +561,9 @@ static int check_connection(THD *thd)
}
else /* Hostname given means that the connection was on a socket */
{
DBUG_PRINT("info",("Host: %s", thd->main_security_ctx.host));
thd->main_security_ctx.host_or_ip= thd->main_security_ctx.host;
thd->main_security_ctx.ip= 0;
DBUG_PRINT("info",("Host: %s", thd->main_security_ctx.get_host()->ptr()));
thd->main_security_ctx.host_or_ip= thd->main_security_ctx.get_host()->ptr();
thd->main_security_ctx.set_ip("");
/* Reset sin_addr */
bzero((char*) &net->vio->remote, sizeof(net->vio->remote));
}

View file

@ -1529,8 +1529,8 @@ bool mysql_change_db(THD *thd, const LEX_STRING *new_db_name, bool force_switch)
db_access=
test_all_bits(sctx->master_access, DB_ACLS) ?
DB_ACLS :
acl_get(sctx->host,
sctx->ip,
acl_get(sctx->get_host()->ptr(),
sctx->get_ip()->ptr(),
sctx->priv_user,
new_db_file_name.str,
FALSE) | sctx->master_access;

View file

@ -1893,7 +1893,7 @@ public:
{
DBUG_ENTER("Delayed_insert constructor");
thd.security_ctx->user=(char*) delayed_user;
thd.security_ctx->host=(char*) my_localhost;
thd.security_ctx->set_host(my_localhost);
strmake(thd.security_ctx->priv_user, thd.security_ctx->user,
USERNAME_LENGTH);
thd.current_tablenr=0;
@ -1939,7 +1939,8 @@ public:
mysql_cond_destroy(&cond_client);
thd.unlink(); // Must be unlinked under lock
my_free(thd.query());
thd.security_ctx->user= thd.security_ctx->host=0;
thd.security_ctx->set_host("");
thd.security_ctx->user= (char *) thd.security_ctx->get_host()->ptr();
thread_count--;
delayed_insert_threads--;
mysql_mutex_unlock(&LOCK_thread_count);

View file

@ -4806,8 +4806,8 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
if (!(sctx->master_access & SELECT_ACL))
{
if (db && (!thd->db || db_is_pattern || strcmp(db, thd->db)))
db_access= acl_get(sctx->host, sctx->ip, sctx->priv_user, db,
db_is_pattern);
db_access= acl_get(sctx->get_host()->ptr(), sctx->get_ip()->ptr(),
sctx->priv_user, db, db_is_pattern);
else
{
/* get access for current db */
@ -4855,8 +4855,8 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
}
if (db && (!thd->db || db_is_pattern || strcmp(db,thd->db)))
db_access= acl_get(sctx->host, sctx->ip, sctx->priv_user, db,
db_is_pattern);
db_access= acl_get(sctx->get_host()->ptr(), sctx->get_ip()->ptr(),
sctx->priv_user, db, db_is_pattern);
else
db_access= sctx->db_access;
DBUG_PRINT("info",("db_access: %lu want_access: %lu",

View file

@ -795,8 +795,8 @@ bool mysqld_show_create_db(THD *thd, char *dbname,
if (test_all_bits(sctx->master_access, DB_ACLS))
db_access=DB_ACLS;
else
db_access= (acl_get(sctx->host, sctx->ip, sctx->priv_user, dbname, 0) |
sctx->master_access);
db_access= (acl_get(sctx->get_host()->ptr(), sctx->get_ip()->ptr(),
sctx->priv_user, dbname, 0) | sctx->master_access);
if (!(db_access & DB_ACLS) && check_grant_db(thd,dbname))
{
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
@ -1832,8 +1832,8 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
thd_info->user= thd->strdup(tmp_sctx->user ? tmp_sctx->user :
(tmp->system_thread ?
"system user" : "unauthenticated user"));
if (tmp->peer_port && (tmp_sctx->host || tmp_sctx->ip) &&
thd->security_ctx->host_or_ip[0])
if (tmp->peer_port && (tmp_sctx->get_host()->length() ||
tmp_sctx->get_ip()->length()) && thd->security_ctx->host_or_ip[0])
{
if ((thd_info->host= (char*) thd->alloc(LIST_PROCESS_HOST_LEN+1)))
my_snprintf((char *) thd_info->host, LIST_PROCESS_HOST_LEN,
@ -1842,7 +1842,8 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
else
thd_info->host= thd->strdup(tmp_sctx->host_or_ip[0] ?
tmp_sctx->host_or_ip :
tmp_sctx->host ? tmp_sctx->host : "");
tmp_sctx->get_host()->length() ?
tmp_sctx->get_host()->ptr() : "");
if ((thd_info->db=tmp->db)) // Safe test
thd_info->db=thd->strdup(thd_info->db);
thd_info->command=(int) tmp->command;
@ -1934,8 +1935,8 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
(tmp->system_thread ? "system user" : "unauthenticated user");
table->field[1]->store(val, strlen(val), cs);
/* HOST */
if (tmp->peer_port && (tmp_sctx->host || tmp_sctx->ip) &&
thd->security_ctx->host_or_ip[0])
if (tmp->peer_port && (tmp_sctx->get_host()->length() ||
tmp_sctx->get_ip()->length()) && thd->security_ctx->host_or_ip[0])
{
char host[LIST_PROCESS_HOST_LEN + 1];
my_snprintf(host, LIST_PROCESS_HOST_LEN, "%s:%u",
@ -3746,7 +3747,8 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
&thd->col_access, NULL, 0, 1) ||
(!thd->col_access && check_grant_db(thd, db_name->str))) ||
sctx->master_access & (DB_ACLS | SHOW_DB_ACL) ||
acl_get(sctx->host, sctx->ip, sctx->priv_user, db_name->str, 0))
acl_get(sctx->get_host()->ptr(), sctx->get_ip()->ptr(),
sctx->priv_user, db_name->str, 0))
#endif
{
List<LEX_STRING> table_names;
@ -3917,7 +3919,8 @@ int fill_schema_schemata(THD *thd, TABLE_LIST *tables, COND *cond)
}
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (sctx->master_access & (DB_ACLS | SHOW_DB_ACL) ||
acl_get(sctx->host, sctx->ip, sctx->priv_user, db_name->str, 0) ||
acl_get(sctx->get_host()->ptr(), sctx->get_ip()->ptr(),
sctx->priv_user, db_name->str, 0) ||
!check_grant_db(thd, db_name->str))
#endif
{