70
72
should be done with this in mind; 'thd' is INOUT, all other params
75
@retval 0 OK; thd->security_ctx->user/master_access/priv_user/db_access and
76
thd->db are updated; OK is sent to the client.
74
77
@retval 1 error, e.g. access denied or handshake error, not sent to
75
78
the client. A message is pushed into the error stack.
79
check_user(THD *thd, const char *passwd,
80
uint32_t passwd_len, const char *db,
82
check_user(THD *thd, enum enum_server_command command,
83
const char *passwd, uint passwd_len, const char *db,
86
DBUG_ENTER("check_user");
83
87
LEX_STRING db_str= { (char *) db, db ? strlen(db) : 0 };
84
bool is_authenticated;
87
90
Clear thd->db as it points to something, that will be freed when
92
95
thd->reset_db(NULL, 0);
94
if (passwd_len != 0 && passwd_len != SCRAMBLE_LENGTH)
96
my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.ip);
100
is_authenticated= authenticate_user(thd, passwd);
102
if (is_authenticated != true)
104
my_error(ER_ACCESS_DENIED_ERROR, MYF(0),
105
thd->main_security_ctx.user,
106
thd->main_security_ctx.ip,
107
passwd_len ? ER(ER_YES) : ER(ER_NO));
97
my_bool opt_secure_auth_local;
98
pthread_mutex_lock(&LOCK_global_system_variables);
99
opt_secure_auth_local= opt_secure_auth;
100
pthread_mutex_unlock(&LOCK_global_system_variables);
103
If the server is running in secure auth mode, short scrambles are
106
if (opt_secure_auth_local && passwd_len == SCRAMBLE_LENGTH_323)
108
my_error(ER_NOT_SUPPORTED_AUTH_MODE, MYF(0));
109
general_log_print(thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE));
112
if (passwd_len != 0 &&
113
passwd_len != SCRAMBLE_LENGTH &&
114
passwd_len != SCRAMBLE_LENGTH_323)
116
my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
113
120
USER_RESOURCES ur;
114
121
thd->security_ctx->skip_grants();
115
122
memset(&ur, 0, sizeof(USER_RESOURCES));
125
("Capabilities: %lu packet_length: %ld Host: '%s' "
126
"Login user: '%s' Priv_user: '%s' Using password: %s "
128
thd->client_capabilities,
129
thd->max_client_packet_length,
130
thd->main_security_ctx.host_or_ip,
131
thd->main_security_ctx.user,
132
thd->main_security_ctx.priv_user,
133
passwd_len ? "yes": "no",
134
(thd->db ? thd->db : "*none*")));
119
138
pthread_mutex_lock(&LOCK_connection_count);
120
139
bool count_ok= connection_count <= max_connections;
121
pthread_mutex_unlock(&LOCK_connection_count);
140
VOID(pthread_mutex_unlock(&LOCK_connection_count));
124
143
{ // too many connections
125
144
my_error(ER_CON_COUNT_ERROR, MYF(0));
150
Log the command before authentication checks, so that the user can
151
check the log for the tried login tried and also to detect
154
general_log_print(thd, command,
155
(thd->main_security_ctx.priv_user ==
156
thd->main_security_ctx.user ?
157
(char*) "%s@%s on %s" :
158
(char*) "%s@%s as anonymous on %s"),
159
thd->main_security_ctx.user,
160
thd->main_security_ctx.host_or_ip,
161
db ? db : (char*) "");
164
This is the default access rights for the current database. It's
165
set to 0 here because we don't have an active database yet (and we
166
may not have an active database to set.
168
thd->main_security_ctx.db_access=0;
130
170
/* Change database if necessary */
133
if (mysql_change_db(thd, &db_str, false))
173
if (mysql_change_db(thd, &db_str, FALSE))
135
175
/* mysql_change_db() has pushed the error message. */
140
180
thd->password= test(passwd_len); // remember for error messages
141
181
/* Ready to handle queries */
148
188
started with corresponding variable that is greater then 0.
151
extern "C" unsigned char *get_key_conn(user_conn *buff, size_t *length,
152
bool not_used __attribute__((unused)))
191
extern "C" uchar *get_key_conn(user_conn *buff, size_t *length,
192
my_bool not_used __attribute__((unused)))
154
194
*length= buff->len;
155
return (unsigned char*) buff->user;
195
return (uchar*) buff->user;
159
199
extern "C" void free_user(struct user_conn *uc)
201
my_free((char*) uc,MYF(0));
164
void thd_init_client_charset(THD *thd, uint32_t cs_number)
204
void thd_init_client_charset(THD *thd, uint cs_number)
167
207
Use server character set and collation if
221
261
static int check_connection(THD *thd)
223
263
NET *net= &thd->net;
268
("New connection received on %s", vio_description(net->vio)));
269
#ifdef SIGNAL_WITH_VIO_CLOSE
270
thd->set_active_vio(net->vio);
273
if (!thd->main_security_ctx.host) // If TCP/IP connection
229
275
char ip[NI_MAXHOST];
231
if (net_peer_addr(net, ip, &thd->peer_port, NI_MAXHOST))
277
if (vio_peer_addr(net->vio, ip, &thd->peer_port, NI_MAXHOST))
233
my_error(ER_BAD_HOST_ERROR, MYF(0), thd->main_security_ctx.ip);
279
my_error(ER_BAD_HOST_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
236
282
if (!(thd->main_security_ctx.ip= my_strdup(ip,MYF(MY_WME))))
237
283
return 1; /* The error is set by my_strdup(). */
239
net_keepalive(net, true);
284
thd->main_security_ctx.host_or_ip= thd->main_security_ctx.ip;
285
thd->main_security_ctx.host= ip_to_hostname(&net->vio->remote,
287
thd->main_security_ctx.host_or_ip= thd->main_security_ctx.host;
288
DBUG_PRINT("info",("Host: %s ip: %s",
289
(thd->main_security_ctx.host ?
290
thd->main_security_ctx.host : "unknown host"),
291
(thd->main_security_ctx.ip ?
292
thd->main_security_ctx.ip : "unknown ip")));
294
else /* Hostname given means that the connection was on a socket */
296
DBUG_PRINT("info",("Host: %s", thd->main_security_ctx.host));
297
thd->main_security_ctx.host_or_ip= thd->main_security_ctx.host;
298
thd->main_security_ctx.ip= 0;
300
bzero((char*) &net->vio->remote, sizeof(net->vio->remote));
302
vio_keepalive(net->vio, TRUE);
241
uint32_t server_capabilites;
304
ulong server_capabilites;
243
306
/* buff[] needs to big enough to hold the server_version variable */
244
307
char buff[SERVER_VERSION_LENGTH + SCRAMBLE_LENGTH + 64];
270
333
/* write server characteristics: up to 16 bytes allowed */
271
334
end[2]=(char) default_charset_info->number;
272
335
int2store(end+3, thd->server_status);
273
memset(end+5, 0, 13);
275
338
/* write scramble tail */
276
339
end= strmake(end, thd->scramble + SCRAMBLE_LENGTH_323,
277
340
SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323) + 1;
279
342
/* At this point we write connection message and read reply */
280
if (net_write_command(net, (unsigned char) protocol_version, (unsigned char*) "", 0,
281
(unsigned char*) buff, (size_t) (end-buff)) ||
343
if (net_write_command(net, (uchar) protocol_version, (uchar*) "", 0,
344
(uchar*) buff, (size_t) (end-buff)) ||
282
345
(pkt_len= my_net_read(net)) == packet_error ||
283
346
pkt_len < MIN_HANDSHAKE_SIZE)
285
348
my_error(ER_HANDSHAKE_ERROR, MYF(0),
286
thd->main_security_ctx.ip);
349
thd->main_security_ctx.host_or_ip);
353
#ifdef _CUSTOMCONFIG_
354
#include "_cust_sql_parse.h"
290
356
if (thd->packet.alloc(thd->variables.net_buffer_length))
291
357
return 1; /* The error is set by alloc(). */
293
359
thd->client_capabilities= uint2korr(net->read_pos);
296
thd->client_capabilities|= ((uint32_t) uint2korr(net->read_pos+2)) << 16;
297
thd->max_client_packet_length= uint4korr(net->read_pos+4);
298
thd_init_client_charset(thd, (uint) net->read_pos[8]);
299
thd->update_charset();
300
end= (char*) net->read_pos+32;
360
if (thd->client_capabilities & CLIENT_PROTOCOL_41)
362
thd->client_capabilities|= ((ulong) uint2korr(net->read_pos+2)) << 16;
363
thd->max_client_packet_length= uint4korr(net->read_pos+4);
364
DBUG_PRINT("info", ("client_character_set: %d", (uint) net->read_pos[8]));
365
thd_init_client_charset(thd, (uint) net->read_pos[8]);
366
thd->update_charset();
367
end= (char*) net->read_pos+32;
371
thd->max_client_packet_length= uint3korr(net->read_pos+2);
372
end= (char*) net->read_pos+5;
303
375
Disable those bits which are not supported by the server.
304
376
This is a precautionary measure, if the client lies. See Bug#27944.
306
378
thd->client_capabilities&= server_capabilites;
380
if (thd->client_capabilities & CLIENT_IGNORE_SPACE)
381
thd->variables.sql_mode|= MODE_IGNORE_SPACE;
308
383
if (end >= (char*) net->read_pos+ pkt_len +2)
311
my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.ip);
386
my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
336
411
Cast *passwd to an unsigned char, so that it doesn't extend the sign for
337
412
*passwd > 127 and become 2**32-127+ after casting to uint.
339
uint32_t passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
340
(unsigned char)(*passwd++) : strlen(passwd);
414
uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
415
(uchar)(*passwd++) : strlen(passwd);
341
416
db= thd->client_capabilities & CLIENT_CONNECT_WITH_DB ?
342
417
db + passwd_len + 1 : 0;
343
418
/* strlen() can't be easily deleted without changing protocol */
344
uint32_t db_len= db ? strlen(db) : 0;
419
uint db_len= db ? strlen(db) : 0;
346
421
if (passwd + passwd_len + db_len > (char *)net->read_pos + pkt_len)
348
my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.ip);
423
my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
375
450
if (thd->main_security_ctx.user)
376
if (thd->main_security_ctx.user)
377
free(thd->main_security_ctx.user);
451
x_free(thd->main_security_ctx.user);
378
452
if (!(thd->main_security_ctx.user= my_strdup(user, MYF(MY_WME))))
379
453
return 1; /* The error is set by my_strdup(). */
380
return check_user(thd, passwd, passwd_len, db, true);
454
return check_user(thd, COM_CONNECT, passwd, passwd_len, db, TRUE);