~drizzle-trunk/drizzle/development

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