520.6.3
by Monty Taylor
Moved scheduler.h out of common_includes. |
1 |
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
|
2 |
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
|
|
3 |
*
|
|
4 |
* Copyright (C) 2008 Sun Microsystems
|
|
5 |
*
|
|
6 |
* This program is free software; you can redistribute it and/or modify
|
|
7 |
* it under the terms of the GNU General Public License as published by
|
|
8 |
* the Free Software Foundation; version 2 of the License.
|
|
9 |
*
|
|
10 |
* This program is distributed in the hope that it will be useful,
|
|
11 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13 |
* GNU General Public License for more details.
|
|
14 |
*
|
|
15 |
* You should have received a copy of the GNU General Public License
|
|
16 |
* along with this program; if not, write to the Free Software
|
|
17 |
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
18 |
*/
|
|
1
by brian
clean slate |
19 |
|
20 |
||
21 |
/*
|
|
22 |
Functions to autenticate and handle reqests for a connection
|
|
23 |
*/
|
|
243.1.17
by Jay Pipes
FINAL PHASE removal of mysql_priv.h (Bye, bye my friend.) |
24 |
#include <drizzled/server_includes.h> |
575.4.7
by Monty Taylor
More header cleanup. |
25 |
#include <netdb.h> |
26 |
||
259
by Brian Aker
First pass on PAM auth |
27 |
#include <drizzled/authentication.h> |
575.4.6
by Monty Taylor
Removed my_getwd. |
28 |
#include <drizzled/db.h> |
549
by Monty Taylor
Took gettext.h out of header files. |
29 |
#include <drizzled/error.h> |
575.4.7
by Monty Taylor
More header cleanup. |
30 |
#include <drizzled/sql_parse.h> |
809
by Brian Aker
Refactor of scheduler plugin code to simplify around one structure. Also |
31 |
#include <drizzled/plugin_scheduling.h> |
584.1.15
by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes. |
32 |
#include <drizzled/session.h> |
798.2.26
by Brian Aker
Remove log_event.h from session.h |
33 |
#include <drizzled/data_home.h> |
1
by brian
clean slate |
34 |
|
809
by Brian Aker
Refactor of scheduler plugin code to simplify around one structure. Also |
35 |
extern scheduling_st thread_scheduler; |
520.6.3
by Monty Taylor
Moved scheduler.h out of common_includes. |
36 |
|
1
by brian
clean slate |
37 |
#define MIN_HANDSHAKE_SIZE 6
|
38 |
||
39 |
/**
|
|
40 |
Check if user exist and password supplied is correct.
|
|
41 |
||
520.1.22
by Brian Aker
Second pass of thd cleanup |
42 |
@param session thread handle, session->security_ctx->{host,user,ip} are used
|
1
by brian
clean slate |
43 |
@param command originator of the check: now check_user is called
|
44 |
during connect and change user procedures; used for
|
|
45 |
logging.
|
|
46 |
@param passwd scrambled password received from client
|
|
47 |
@param passwd_len length of scrambled password
|
|
48 |
@param db database name to connect to, may be NULL
|
|
51.1.50
by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE |
49 |
@param check_count true if establishing a new connection. In this case
|
1
by brian
clean slate |
50 |
check that we have not exceeded the global
|
51 |
max_connections limist
|
|
52 |
||
53 |
@note Host, user and passwd may point to communication buffer.
|
|
54 |
Current implementation does not depend on that, but future changes
|
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
55 |
should be done with this in mind; 'session' is INOUT, all other params
|
1
by brian
clean slate |
56 |
are 'IN'.
|
57 |
||
265
by brian
First pass through cleaning up security context. |
58 |
@retval 0 OK
|
1
by brian
clean slate |
59 |
@retval 1 error, e.g. access denied or handshake error, not sent to
|
60 |
the client. A message is pushed into the error stack.
|
|
61 |
*/
|
|
62 |
||
63 |
int
|
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
64 |
check_user(Session *session, const char *passwd, |
482
by Brian Aker
Remove uint. |
65 |
uint32_t passwd_len, const char *db, |
77.1.45
by Monty Taylor
Warning fixes. |
66 |
bool check_count) |
1
by brian
clean slate |
67 |
{
|
68 |
LEX_STRING db_str= { (char *) db, db ? strlen(db) : 0 }; |
|
259
by Brian Aker
First pass on PAM auth |
69 |
bool is_authenticated; |
1
by brian
clean slate |
70 |
|
71 |
/*
|
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
72 |
Clear session->db as it points to something, that will be freed when
|
1
by brian
clean slate |
73 |
connection is closed. We don't want to accidentally free a wrong
|
74 |
pointer if connect failed. Also in case of 'CHANGE USER' failure,
|
|
75 |
current database will be switched to 'no database selected'.
|
|
76 |
*/
|
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
77 |
session->reset_db(NULL, 0); |
1
by brian
clean slate |
78 |
|
259
by Brian Aker
First pass on PAM auth |
79 |
if (passwd_len != 0 && passwd_len != SCRAMBLE_LENGTH) |
1
by brian
clean slate |
80 |
{
|
694
by Brian Aker
Refactor out char* strdup for string class in user. |
81 |
my_error(ER_HANDSHAKE_ERROR, MYF(0), session->security_ctx.ip.c_str()); |
51.1.50
by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE |
82 |
return(1); |
1
by brian
clean slate |
83 |
}
|
84 |
||
520.1.22
by Brian Aker
Second pass of thd cleanup |
85 |
is_authenticated= authenticate_user(session, passwd); |
259
by Brian Aker
First pass on PAM auth |
86 |
|
87 |
if (is_authenticated != true) |
|
88 |
{
|
|
89 |
my_error(ER_ACCESS_DENIED_ERROR, MYF(0), |
|
694
by Brian Aker
Refactor out char* strdup for string class in user. |
90 |
session->security_ctx.user.c_str(), |
91 |
session->security_ctx.ip.c_str(), |
|
259
by Brian Aker
First pass on PAM auth |
92 |
passwd_len ? ER(ER_YES) : ER(ER_NO)); |
93 |
||
94 |
return 1; |
|
95 |
}
|
|
96 |
||
97 |
||
694
by Brian Aker
Refactor out char* strdup for string class in user. |
98 |
session->security_ctx.skip_grants(); |
1
by brian
clean slate |
99 |
|
100 |
if (check_count) |
|
101 |
{
|
|
102 |
pthread_mutex_lock(&LOCK_connection_count); |
|
103 |
bool count_ok= connection_count <= max_connections; |
|
398.1.10
by Monty Taylor
Actually removed VOID() this time. |
104 |
pthread_mutex_unlock(&LOCK_connection_count); |
1
by brian
clean slate |
105 |
|
106 |
if (!count_ok) |
|
107 |
{ // too many connections |
|
108 |
my_error(ER_CON_COUNT_ERROR, MYF(0)); |
|
51.1.50
by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE |
109 |
return(1); |
1
by brian
clean slate |
110 |
}
|
111 |
}
|
|
112 |
||
113 |
/* Change database if necessary */
|
|
114 |
if (db && db[0]) |
|
115 |
{
|
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
116 |
if (mysql_change_db(session, &db_str, false)) |
1
by brian
clean slate |
117 |
{
|
118 |
/* mysql_change_db() has pushed the error message. */
|
|
51.1.50
by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE |
119 |
return(1); |
1
by brian
clean slate |
120 |
}
|
121 |
}
|
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
122 |
my_ok(session); |
660.1.3
by Eric Herman
removed trailing whitespace with simple script: |
123 |
session->password= test(passwd_len); // remember for error messages |
1
by brian
clean slate |
124 |
/* Ready to handle queries */
|
51.1.50
by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE |
125 |
return(0); |
1
by brian
clean slate |
126 |
}
|
127 |
||
128 |
||
129 |
/*
|
|
130 |
Check for maximum allowable user connections, if the mysqld server is
|
|
131 |
started with corresponding variable that is greater then 0.
|
|
132 |
*/
|
|
133 |
||
481
by Brian Aker
Remove all of uchar. |
134 |
extern "C" unsigned char *get_key_conn(user_conn *buff, size_t *length, |
779.1.27
by Monty Taylor
Got rid of __attribute__((unused)) and the like from the .cc files. |
135 |
bool ) |
1
by brian
clean slate |
136 |
{
|
137 |
*length= buff->len; |
|
481
by Brian Aker
Remove all of uchar. |
138 |
return (unsigned char*) buff->user; |
1
by brian
clean slate |
139 |
}
|
140 |
||
141 |
||
142 |
extern "C" void free_user(struct user_conn *uc) |
|
143 |
{
|
|
477
by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that. |
144 |
free((char*) uc); |
1
by brian
clean slate |
145 |
}
|
146 |
||
147 |
/*
|
|
148 |
Initialize connection threads
|
|
149 |
*/
|
|
150 |
||
151 |
bool init_new_connection_handler_thread() |
|
152 |
{
|
|
153 |
pthread_detach_this_thread(); |
|
154 |
/* Win32 calls this in pthread_create */
|
|
155 |
if (my_thread_init()) |
|
156 |
return 1; |
|
157 |
return 0; |
|
158 |
}
|
|
159 |
||
160 |
/*
|
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
161 |
Perform handshake, authorize client and update session ACL variables.
|
1
by brian
clean slate |
162 |
|
163 |
SYNOPSIS
|
|
164 |
check_connection()
|
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
165 |
session thread handle
|
1
by brian
clean slate |
166 |
|
167 |
RETURN
|
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
168 |
0 success, OK is sent to user, session is updated.
|
1
by brian
clean slate |
169 |
-1 error, which is sent to user
|
170 |
> 0 error code (not sent to user)
|
|
171 |
*/
|
|
172 |
||
520.1.22
by Brian Aker
Second pass of thd cleanup |
173 |
static int check_connection(Session *session) |
1
by brian
clean slate |
174 |
{
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
175 |
NET *net= &session->net; |
307
by Brian Aker
Minor cleanups around ulong in kernel. |
176 |
uint32_t pkt_len= 0; |
1
by brian
clean slate |
177 |
char *end; |
178 |
||
265
by brian
First pass through cleaning up security context. |
179 |
// TCP/IP connection
|
1
by brian
clean slate |
180 |
{
|
181 |
char ip[NI_MAXHOST]; |
|
182 |
||
520.1.22
by Brian Aker
Second pass of thd cleanup |
183 |
if (net_peer_addr(net, ip, &session->peer_port, NI_MAXHOST)) |
1
by brian
clean slate |
184 |
{
|
694
by Brian Aker
Refactor out char* strdup for string class in user. |
185 |
my_error(ER_BAD_HOST_ERROR, MYF(0), session->security_ctx.ip.c_str()); |
1
by brian
clean slate |
186 |
return 1; |
187 |
}
|
|
694
by Brian Aker
Refactor out char* strdup for string class in user. |
188 |
|
189 |
session->security_ctx.ip.assign(ip); |
|
1
by brian
clean slate |
190 |
}
|
383.1.54
by Monty Taylor
More violite refactoring/removal. |
191 |
net_keepalive(net, true); |
660.1.3
by Eric Herman
removed trailing whitespace with simple script: |
192 |
|
307
by Brian Aker
Minor cleanups around ulong in kernel. |
193 |
uint32_t server_capabilites; |
1
by brian
clean slate |
194 |
{
|
195 |
/* buff[] needs to big enough to hold the server_version variable */
|
|
196 |
char buff[SERVER_VERSION_LENGTH + SCRAMBLE_LENGTH + 64]; |
|
197 |
server_capabilites= CLIENT_BASIC_FLAGS; |
|
198 |
||
199 |
if (opt_using_transactions) |
|
200 |
server_capabilites|= CLIENT_TRANSACTIONS; |
|
201 |
#ifdef HAVE_COMPRESS
|
|
202 |
server_capabilites|= CLIENT_COMPRESS; |
|
203 |
#endif /* HAVE_COMPRESS */ |
|
204 |
||
741.1.1
by Eric Day
Reworked server version packing in handshake, was writing max length instead of just string length + NULL. |
205 |
end= buff + strlen(server_version); |
206 |
if ((end - buff) >= SERVER_VERSION_LENGTH) |
|
207 |
end= buff + (SERVER_VERSION_LENGTH - 1); |
|
208 |
memcpy(buff, server_version, end - buff); |
|
209 |
*end= 0; |
|
210 |
end++; |
|
670.3.1
by Toru Maesaka
Replaced MySQL's my_stpncpy() with libc and c++ calls |
211 |
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
212 |
int4store((unsigned char*) end, session->thread_id); |
1
by brian
clean slate |
213 |
end+= 4; |
214 |
/*
|
|
215 |
So as check_connection is the only entry point to authorization
|
|
216 |
procedure, scramble is set here. This gives us new scramble for
|
|
217 |
each handshake.
|
|
218 |
*/
|
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
219 |
create_random_string(session->scramble, SCRAMBLE_LENGTH, &session->rand); |
1
by brian
clean slate |
220 |
/*
|
221 |
Old clients does not understand long scrambles, but can ignore packet
|
|
222 |
tail: that's why first part of the scramble is placed here, and second
|
|
223 |
part at the end of packet.
|
|
224 |
*/
|
|
629.5.3
by Toru Maesaka
Third pass of replacing MySQL's strmake() with libc calls |
225 |
end= strncpy(end, session->scramble, SCRAMBLE_LENGTH_323); |
226 |
end+= SCRAMBLE_LENGTH_323 + 1; |
|
660.1.3
by Eric Herman
removed trailing whitespace with simple script: |
227 |
|
1
by brian
clean slate |
228 |
int2store(end, server_capabilites); |
229 |
/* write server characteristics: up to 16 bytes allowed */
|
|
230 |
end[2]=(char) default_charset_info->number; |
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
231 |
int2store(end+3, session->server_status); |
212.6.1
by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file. |
232 |
memset(end+5, 0, 13); |
1
by brian
clean slate |
233 |
end+= 18; |
234 |
/* write scramble tail */
|
|
629.5.3
by Toru Maesaka
Third pass of replacing MySQL's strmake() with libc calls |
235 |
size_t scramble_len= SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323; |
236 |
end= strncpy(end, session->scramble + SCRAMBLE_LENGTH_323, scramble_len); |
|
237 |
end+= scramble_len + 1; |
|
1
by brian
clean slate |
238 |
|
239 |
/* At this point we write connection message and read reply */
|
|
481
by Brian Aker
Remove all of uchar. |
240 |
if (net_write_command(net, (unsigned char) protocol_version, (unsigned char*) "", 0, |
241 |
(unsigned char*) buff, (size_t) (end-buff)) || |
|
1
by brian
clean slate |
242 |
(pkt_len= my_net_read(net)) == packet_error || |
243 |
pkt_len < MIN_HANDSHAKE_SIZE) |
|
244 |
{
|
|
245 |
my_error(ER_HANDSHAKE_ERROR, MYF(0), |
|
694
by Brian Aker
Refactor out char* strdup for string class in user. |
246 |
session->security_ctx.ip.c_str()); |
1
by brian
clean slate |
247 |
return 1; |
248 |
}
|
|
249 |
}
|
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
250 |
if (session->packet.alloc(session->variables.net_buffer_length)) |
1
by brian
clean slate |
251 |
return 1; /* The error is set by alloc(). */ |
252 |
||
520.1.22
by Brian Aker
Second pass of thd cleanup |
253 |
session->client_capabilities= uint2korr(net->read_pos); |
254 |
||
255 |
||
256 |
session->client_capabilities|= ((uint32_t) uint2korr(net->read_pos+2)) << 16; |
|
257 |
session->max_client_packet_length= uint4korr(net->read_pos+4); |
|
258 |
session->update_charset(); |
|
264.2.4
by Andrey Hristov
Remove support for the old, pre-4.1, protocol |
259 |
end= (char*) net->read_pos+32; |
260 |
||
1
by brian
clean slate |
261 |
/*
|
262 |
Disable those bits which are not supported by the server.
|
|
263 |
This is a precautionary measure, if the client lies. See Bug#27944.
|
|
264 |
*/
|
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
265 |
session->client_capabilities&= server_capabilites; |
1
by brian
clean slate |
266 |
|
267 |
if (end >= (char*) net->read_pos+ pkt_len +2) |
|
268 |
{
|
|
269 |
||
694
by Brian Aker
Refactor out char* strdup for string class in user. |
270 |
my_error(ER_HANDSHAKE_ERROR, MYF(0), session->security_ctx.ip.c_str()); |
1
by brian
clean slate |
271 |
return 1; |
272 |
}
|
|
273 |
||
520.1.22
by Brian Aker
Second pass of thd cleanup |
274 |
if (session->client_capabilities & CLIENT_INTERACTIVE) |
275 |
session->variables.net_wait_timeout= session->variables.net_interactive_timeout; |
|
276 |
if ((session->client_capabilities & CLIENT_TRANSACTIONS) && |
|
1
by brian
clean slate |
277 |
opt_using_transactions) |
520.1.22
by Brian Aker
Second pass of thd cleanup |
278 |
net->return_status= &session->server_status; |
1
by brian
clean slate |
279 |
|
280 |
char *user= end; |
|
376
by Brian Aker
strend remove |
281 |
char *passwd= strchr(user, '\0')+1; |
482
by Brian Aker
Remove uint. |
282 |
uint32_t user_len= passwd - user - 1; |
1
by brian
clean slate |
283 |
char *db= passwd; |
284 |
char db_buff[NAME_LEN + 1]; // buffer to store db in utf8 |
|
285 |
char user_buff[USERNAME_LENGTH + 1]; // buffer to store user in utf8 |
|
482
by Brian Aker
Remove uint. |
286 |
uint32_t dummy_errors; |
1
by brian
clean slate |
287 |
|
288 |
/*
|
|
289 |
Old clients send null-terminated string as password; new clients send
|
|
290 |
the size (1 byte) + string (not null-terminated). Hence in case of empty
|
|
291 |
password both send '\0'.
|
|
292 |
||
293 |
This strlen() can't be easily deleted without changing protocol.
|
|
294 |
||
295 |
Cast *passwd to an unsigned char, so that it doesn't extend the sign for
|
|
296 |
*passwd > 127 and become 2**32-127+ after casting to uint.
|
|
297 |
*/
|
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
298 |
uint32_t passwd_len= session->client_capabilities & CLIENT_SECURE_CONNECTION ? |
481
by Brian Aker
Remove all of uchar. |
299 |
(unsigned char)(*passwd++) : strlen(passwd); |
520.1.22
by Brian Aker
Second pass of thd cleanup |
300 |
db= session->client_capabilities & CLIENT_CONNECT_WITH_DB ? |
1
by brian
clean slate |
301 |
db + passwd_len + 1 : 0; |
302 |
/* strlen() can't be easily deleted without changing protocol */
|
|
482
by Brian Aker
Remove uint. |
303 |
uint32_t db_len= db ? strlen(db) : 0; |
1
by brian
clean slate |
304 |
|
305 |
if (passwd + passwd_len + db_len > (char *)net->read_pos + pkt_len) |
|
306 |
{
|
|
694
by Brian Aker
Refactor out char* strdup for string class in user. |
307 |
my_error(ER_HANDSHAKE_ERROR, MYF(0), session->security_ctx.ip.c_str()); |
1
by brian
clean slate |
308 |
return 1; |
309 |
}
|
|
310 |
||
311 |
/* Since 4.1 all database names are stored in utf8 */
|
|
312 |
if (db) |
|
313 |
{
|
|
314 |
db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1, |
|
315 |
system_charset_info, |
|
316 |
db, db_len, |
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
317 |
session->charset(), &dummy_errors)]= 0; |
1
by brian
clean slate |
318 |
db= db_buff; |
319 |
}
|
|
320 |
||
321 |
user_buff[user_len= copy_and_convert(user_buff, sizeof(user_buff)-1, |
|
322 |
system_charset_info, user, user_len, |
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
323 |
session->charset(), &dummy_errors)]= '\0'; |
1
by brian
clean slate |
324 |
user= user_buff; |
325 |
||
326 |
/* If username starts and ends in "'", chop them off */
|
|
327 |
if (user_len > 1 && user[0] == '\'' && user[user_len - 1] == '\'') |
|
328 |
{
|
|
329 |
user[user_len-1]= 0; |
|
330 |
user++; |
|
331 |
user_len-= 2; |
|
332 |
}
|
|
333 |
||
694
by Brian Aker
Refactor out char* strdup for string class in user. |
334 |
session->security_ctx.user.assign(user); |
335 |
||
520.1.22
by Brian Aker
Second pass of thd cleanup |
336 |
return check_user(session, passwd, passwd_len, db, true); |
1
by brian
clean slate |
337 |
}
|
338 |
||
339 |
||
340 |
/*
|
|
341 |
Setup thread to be used with the current thread
|
|
342 |
||
343 |
SYNOPSIS
|
|
344 |
bool setup_connection_thread_globals()
|
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
345 |
session Thread/connection handler
|
1
by brian
clean slate |
346 |
|
347 |
RETURN
|
|
348 |
0 ok
|
|
349 |
1 Error (out of memory)
|
|
350 |
In this case we will close the connection and increment status
|
|
351 |
*/
|
|
352 |
||
520.1.22
by Brian Aker
Second pass of thd cleanup |
353 |
bool setup_connection_thread_globals(Session *session) |
1
by brian
clean slate |
354 |
{
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
355 |
if (session->store_globals()) |
1
by brian
clean slate |
356 |
{
|
693
by Brian Aker
Cleaning up session class. |
357 |
session->close_connection(ER_OUT_OF_RESOURCES, true); |
1
by brian
clean slate |
358 |
statistic_increment(aborted_connects,&LOCK_status); |
520.1.22
by Brian Aker
Second pass of thd cleanup |
359 |
thread_scheduler.end_thread(session, 0); |
1
by brian
clean slate |
360 |
return 1; // Error |
361 |
}
|
|
362 |
return 0; |
|
363 |
}
|
|
364 |
||
365 |
||
366 |
/*
|
|
367 |
Autenticate user, with error reporting
|
|
368 |
||
369 |
SYNOPSIS
|
|
370 |
login_connection()
|
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
371 |
session Thread handler
|
1
by brian
clean slate |
372 |
|
373 |
NOTES
|
|
374 |
Connection is not closed in case of errors
|
|
375 |
||
376 |
RETURN
|
|
377 |
0 ok
|
|
378 |
1 error
|
|
379 |
*/
|
|
380 |
||
381 |
||
520.1.22
by Brian Aker
Second pass of thd cleanup |
382 |
bool login_connection(Session *session) |
1
by brian
clean slate |
383 |
{
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
384 |
NET *net= &session->net; |
1
by brian
clean slate |
385 |
int error; |
386 |
||
387 |
/* Use "connect_timeout" value during connection phase */
|
|
388 |
my_net_set_read_timeout(net, connect_timeout); |
|
389 |
my_net_set_write_timeout(net, connect_timeout); |
|
660.1.3
by Eric Herman
removed trailing whitespace with simple script: |
390 |
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
391 |
lex_start(session); |
1
by brian
clean slate |
392 |
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
393 |
error= check_connection(session); |
394 |
net_end_statement(session); |
|
1
by brian
clean slate |
395 |
|
396 |
if (error) |
|
397 |
{ // Wrong permissions |
|
398 |
statistic_increment(aborted_connects,&LOCK_status); |
|
51.1.50
by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE |
399 |
return(1); |
1
by brian
clean slate |
400 |
}
|
401 |
/* Connect completed, set read/write timeouts back to default */
|
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
402 |
my_net_set_read_timeout(net, session->variables.net_read_timeout); |
403 |
my_net_set_write_timeout(net, session->variables.net_write_timeout); |
|
51.1.50
by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE |
404 |
return(0); |
1
by brian
clean slate |
405 |
}
|
406 |
||
407 |
||
408 |
/*
|
|
409 |
Close an established connection
|
|
410 |
||
411 |
NOTES
|
|
412 |
This mainly updates status variables
|
|
413 |
*/
|
|
414 |
||
520.1.22
by Brian Aker
Second pass of thd cleanup |
415 |
void end_connection(Session *session) |
1
by brian
clean slate |
416 |
{
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
417 |
NET *net= &session->net; |
418 |
plugin_sessionvar_cleanup(session); |
|
1
by brian
clean slate |
419 |
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
420 |
if (session->killed || (net->error && net->vio != 0)) |
1
by brian
clean slate |
421 |
{
|
422 |
statistic_increment(aborted_threads,&LOCK_status); |
|
423 |
}
|
|
424 |
||
425 |
if (net->error && net->vio != 0) |
|
426 |
{
|
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
427 |
if (!session->killed && session->variables.log_warnings > 1) |
1
by brian
clean slate |
428 |
{
|
694
by Brian Aker
Refactor out char* strdup for string class in user. |
429 |
Security_context *sctx= &session->security_ctx; |
1
by brian
clean slate |
430 |
|
755.2.1
by Mark Atwood
replace sql_print_error etc with errmsg_print |
431 |
errmsg_printf(ERRMSG_LVL_WARN, ER(ER_NEW_ABORTING_CONNECTION), |
520.1.22
by Brian Aker
Second pass of thd cleanup |
432 |
session->thread_id,(session->db ? session->db : "unconnected"), |
694
by Brian Aker
Refactor out char* strdup for string class in user. |
433 |
sctx->user.empty() == false ? sctx->user.c_str() : "unauthenticated", |
434 |
sctx->ip.c_str(), |
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
435 |
(session->main_da.is_error() ? session->main_da.message() : |
1
by brian
clean slate |
436 |
ER(ER_UNKNOWN_ERROR))); |
437 |
}
|
|
438 |
}
|
|
439 |
}
|
|
440 |
||
441 |
||
442 |
/*
|
|
520.1.21
by Brian Aker
THD -> Session rename |
443 |
Initialize Session to handle queries
|
1
by brian
clean slate |
444 |
*/
|
445 |
||
520.1.22
by Brian Aker
Second pass of thd cleanup |
446 |
void prepare_new_connection_state(Session* session) |
1
by brian
clean slate |
447 |
{
|
694
by Brian Aker
Refactor out char* strdup for string class in user. |
448 |
Security_context *sctx= &session->security_ctx; |
1
by brian
clean slate |
449 |
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
450 |
if (session->variables.max_join_size == HA_POS_ERROR) |
451 |
session->options |= OPTION_BIG_SELECTS; |
|
452 |
if (session->client_capabilities & CLIENT_COMPRESS) |
|
453 |
session->net.compress=1; // Use compression |
|
1
by brian
clean slate |
454 |
|
455 |
/*
|
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
456 |
Much of this is duplicated in create_embedded_session() for the
|
1
by brian
clean slate |
457 |
embedded server library.
|
458 |
TODO: refactor this to avoid code duplication there
|
|
459 |
*/
|
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
460 |
session->version= refresh_version; |
461 |
session->set_proc_info(0); |
|
462 |
session->command= COM_SLEEP; |
|
463 |
session->set_time(); |
|
464 |
session->init_for_queries(); |
|
1
by brian
clean slate |
465 |
|
466 |
/* In the past this would only run of the user did not have SUPER_ACL */
|
|
467 |
if (sys_init_connect.value_length) |
|
468 |
{
|
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
469 |
execute_init_command(session, &sys_init_connect, &LOCK_sys_init_connect); |
470 |
if (session->is_error()) |
|
1
by brian
clean slate |
471 |
{
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
472 |
session->killed= Session::KILL_CONNECTION; |
755.2.1
by Mark Atwood
replace sql_print_error etc with errmsg_print |
473 |
errmsg_printf(ERRMSG_LVL_WARN, ER(ER_NEW_ABORTING_CONNECTION), |
520.1.22
by Brian Aker
Second pass of thd cleanup |
474 |
session->thread_id,(session->db ? session->db : "unconnected"), |
694
by Brian Aker
Refactor out char* strdup for string class in user. |
475 |
sctx->user.empty() == false ? sctx->user.c_str() : "unauthenticated", |
476 |
sctx->ip.c_str(), "init_connect command failed"); |
|
755.2.1
by Mark Atwood
replace sql_print_error etc with errmsg_print |
477 |
errmsg_printf(ERRMSG_LVL_WARN, "%s", session->main_da.message()); |
1
by brian
clean slate |
478 |
}
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
479 |
session->set_proc_info(0); |
480 |
session->set_time(); |
|
481 |
session->init_for_queries(); |
|
1
by brian
clean slate |
482 |
}
|
483 |
}
|
|
484 |
||
485 |
||
486 |
/*
|
|
487 |
Thread handler for a connection
|
|
488 |
||
489 |
SYNOPSIS
|
|
490 |
handle_one_connection()
|
|
520.1.21
by Brian Aker
THD -> Session rename |
491 |
arg Connection object (Session)
|
1
by brian
clean slate |
492 |
|
493 |
IMPLEMENTATION
|
|
494 |
This function (normally) does the following:
|
|
495 |
- Initialize thread
|
|
520.1.21
by Brian Aker
THD -> Session rename |
496 |
- Initialize Session to be used with this thread
|
1
by brian
clean slate |
497 |
- Authenticate user
|
498 |
- Execute all queries sent on the connection
|
|
499 |
- Take connection down
|
|
500 |
- End thread / Handle next connection using thread from thread cache
|
|
501 |
*/
|
|
502 |
||
503 |
pthread_handler_t handle_one_connection(void *arg) |
|
504 |
{
|
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
505 |
Session *session= (Session*) arg; |
506 |
uint32_t launch_time= (uint32_t) ((session->thr_create_utime= my_micro_time()) - |
|
507 |
session->connect_utime); |
|
1
by brian
clean slate |
508 |
|
509 |
if (thread_scheduler.init_new_connection_thread()) |
|
510 |
{
|
|
693
by Brian Aker
Cleaning up session class. |
511 |
session->close_connection(ER_OUT_OF_RESOURCES, true); |
1
by brian
clean slate |
512 |
statistic_increment(aborted_connects,&LOCK_status); |
520.1.22
by Brian Aker
Second pass of thd cleanup |
513 |
thread_scheduler.end_thread(session,0); |
1
by brian
clean slate |
514 |
return 0; |
515 |
}
|
|
516 |
if (launch_time >= slow_launch_time*1000000L) |
|
517 |
statistic_increment(slow_launch_threads,&LOCK_status); |
|
518 |
||
519 |
/*
|
|
520 |
handle_one_connection() is normally the only way a thread would
|
|
521 |
start and would always be on the very high end of the stack ,
|
|
522 |
therefore, the thread stack always starts at the address of the
|
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
523 |
first local variable of handle_one_connection, which is session. We
|
1
by brian
clean slate |
524 |
need to know the start of the stack so that we could check for
|
525 |
stack overruns.
|
|
526 |
*/
|
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
527 |
session->thread_stack= (char*) &session; |
528 |
if (setup_connection_thread_globals(session)) |
|
1
by brian
clean slate |
529 |
return 0; |
530 |
||
531 |
for (;;) |
|
532 |
{
|
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
533 |
NET *net= &session->net; |
1
by brian
clean slate |
534 |
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
535 |
if (login_connection(session)) |
1
by brian
clean slate |
536 |
goto end_thread; |
537 |
||
520.1.22
by Brian Aker
Second pass of thd cleanup |
538 |
prepare_new_connection_state(session); |
1
by brian
clean slate |
539 |
|
540 |
while (!net->error && net->vio != 0 && |
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
541 |
!(session->killed == Session::KILL_CONNECTION)) |
1
by brian
clean slate |
542 |
{
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
543 |
if (do_command(session)) |
1
by brian
clean slate |
544 |
break; |
545 |
}
|
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
546 |
end_connection(session); |
660.1.3
by Eric Herman
removed trailing whitespace with simple script: |
547 |
|
1
by brian
clean slate |
548 |
end_thread: |
813.4.1
by Stewart Smith
gcc 4.2.1 fixes |
549 |
session->close_connection(0, true); |
693
by Brian Aker
Cleaning up session class. |
550 |
if (thread_scheduler.end_thread(session, 1)) |
1
by brian
clean slate |
551 |
return 0; // Probably no-threads |
552 |
||
553 |
/*
|
|
554 |
If end_thread() returns, we are either running with
|
|
555 |
thread-handler=no-threads or this thread has been schedule to
|
|
556 |
handle the next connection.
|
|
557 |
*/
|
|
520.1.22
by Brian Aker
Second pass of thd cleanup |
558 |
session= current_session; |
559 |
session->thread_stack= (char*) &session; |
|
1
by brian
clean slate |
560 |
}
|
561 |
}
|