~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];
179
    server_capabilites= CLIENT_BASIC_FLAGS;
180
181
    if (opt_using_transactions)
182
      server_capabilites|= CLIENT_TRANSACTIONS;
183
#ifdef HAVE_COMPRESS
184
    server_capabilites|= CLIENT_COMPRESS;
185
#endif /* HAVE_COMPRESS */
186
741.1.1 by Eric Day
Reworked server version packing in handshake, was writing max length instead of just string length + NULL.
187
    end= buff + strlen(server_version);
188
    if ((end - buff) >= SERVER_VERSION_LENGTH)
189
      end= buff + (SERVER_VERSION_LENGTH - 1);
190
    memcpy(buff, server_version, end - buff);
191
    *end= 0;
192
    end++;
670.3.1 by Toru Maesaka
Replaced MySQL's my_stpncpy() with libc and c++ calls
193
520.1.22 by Brian Aker
Second pass of thd cleanup
194
    int4store((unsigned char*) end, session->thread_id);
1 by brian
clean slate
195
    end+= 4;
196
    /*
197
      So as check_connection is the only entry point to authorization
198
      procedure, scramble is set here. This gives us new scramble for
199
      each handshake.
200
    */
840.1.20 by Monty Taylor
Renamed non-prefixed things from libdrizzleclient to drizzleclient.
201
    drizzleclient_create_random_string(session->scramble, SCRAMBLE_LENGTH, &session->rand);
1 by brian
clean slate
202
    /*
203
      Old clients does not understand long scrambles, but can ignore packet
204
      tail: that's why first part of the scramble is placed here, and second
205
      part at the end of packet.
206
    */
629.5.3 by Toru Maesaka
Third pass of replacing MySQL's strmake() with libc calls
207
    end= strncpy(end, session->scramble, SCRAMBLE_LENGTH_323);
208
    end+= SCRAMBLE_LENGTH_323 + 1;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
209
1 by brian
clean slate
210
    int2store(end, server_capabilites);
211
    /* write server characteristics: up to 16 bytes allowed */
212
    end[2]=(char) default_charset_info->number;
520.1.22 by Brian Aker
Second pass of thd cleanup
213
    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.
214
    memset(end+5, 0, 13);
1 by brian
clean slate
215
    end+= 18;
216
    /* write scramble tail */
629.5.3 by Toru Maesaka
Third pass of replacing MySQL's strmake() with libc calls
217
    size_t scramble_len= SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323;
218
    end= strncpy(end, session->scramble + SCRAMBLE_LENGTH_323, scramble_len);
219
    end+= scramble_len + 1;
1 by brian
clean slate
220
221
    /* At this point we write connection message and read reply */
840.1.20 by Monty Taylor
Renamed non-prefixed things from libdrizzleclient to drizzleclient.
222
    if (drizzleclient_net_write_command(net, (unsigned char) protocol_version, (unsigned char*) "", 0,
481 by Brian Aker
Remove all of uchar.
223
                          (unsigned char*) buff, (size_t) (end-buff)) ||
840.1.17 by Monty Taylor
Renamed my_net_* to drizzleclient_net_* to help with namespace issues.
224
	(pkt_len= drizzleclient_net_read(net)) == packet_error ||
1 by brian
clean slate
225
	pkt_len < MIN_HANDSHAKE_SIZE)
226
    {
227
      my_error(ER_HANDSHAKE_ERROR, MYF(0),
694 by Brian Aker
Refactor out char* strdup for string class in user.
228
               session->security_ctx.ip.c_str());
1 by brian
clean slate
229
      return 1;
230
    }
231
  }
520.1.22 by Brian Aker
Second pass of thd cleanup
232
  if (session->packet.alloc(session->variables.net_buffer_length))
1 by brian
clean slate
233
    return 1; /* The error is set by alloc(). */
234
520.1.22 by Brian Aker
Second pass of thd cleanup
235
  session->client_capabilities= uint2korr(net->read_pos);
236
237
238
  session->client_capabilities|= ((uint32_t) uint2korr(net->read_pos+2)) << 16;
239
  session->max_client_packet_length= uint4korr(net->read_pos+4);
240
  session->update_charset();
264.2.4 by Andrey Hristov
Remove support for the old, pre-4.1, protocol
241
  end= (char*) net->read_pos+32;
242
1 by brian
clean slate
243
  /*
244
    Disable those bits which are not supported by the server.
245
    This is a precautionary measure, if the client lies. See Bug#27944.
246
  */
520.1.22 by Brian Aker
Second pass of thd cleanup
247
  session->client_capabilities&= server_capabilites;
1 by brian
clean slate
248
249
  if (end >= (char*) net->read_pos+ pkt_len +2)
250
  {
251
694 by Brian Aker
Refactor out char* strdup for string class in user.
252
    my_error(ER_HANDSHAKE_ERROR, MYF(0), session->security_ctx.ip.c_str());
1 by brian
clean slate
253
    return 1;
254
  }
255
520.1.22 by Brian Aker
Second pass of thd cleanup
256
  if (session->client_capabilities & CLIENT_INTERACTIVE)
257
    session->variables.net_wait_timeout= session->variables.net_interactive_timeout;
258
  if ((session->client_capabilities & CLIENT_TRANSACTIONS) &&
1 by brian
clean slate
259
      opt_using_transactions)
520.1.22 by Brian Aker
Second pass of thd cleanup
260
    net->return_status= &session->server_status;
1 by brian
clean slate
261
262
  char *user= end;
376 by Brian Aker
strend remove
263
  char *passwd= strchr(user, '\0')+1;
482 by Brian Aker
Remove uint.
264
  uint32_t user_len= passwd - user - 1;
1 by brian
clean slate
265
  char *db= passwd;
266
  char db_buff[NAME_LEN + 1];           // buffer to store db in utf8
267
  char user_buff[USERNAME_LENGTH + 1];	// buffer to store user in utf8
482 by Brian Aker
Remove uint.
268
  uint32_t dummy_errors;
1 by brian
clean slate
269
270
  /*
271
    Old clients send null-terminated string as password; new clients send
272
    the size (1 byte) + string (not null-terminated). Hence in case of empty
273
    password both send '\0'.
274
275
    This strlen() can't be easily deleted without changing protocol.
276
277
    Cast *passwd to an unsigned char, so that it doesn't extend the sign for
278
    *passwd > 127 and become 2**32-127+ after casting to uint.
279
  */
520.1.22 by Brian Aker
Second pass of thd cleanup
280
  uint32_t passwd_len= session->client_capabilities & CLIENT_SECURE_CONNECTION ?
481 by Brian Aker
Remove all of uchar.
281
    (unsigned char)(*passwd++) : strlen(passwd);
520.1.22 by Brian Aker
Second pass of thd cleanup
282
  db= session->client_capabilities & CLIENT_CONNECT_WITH_DB ?
1 by brian
clean slate
283
    db + passwd_len + 1 : 0;
284
  /* strlen() can't be easily deleted without changing protocol */
482 by Brian Aker
Remove uint.
285
  uint32_t db_len= db ? strlen(db) : 0;
1 by brian
clean slate
286
287
  if (passwd + passwd_len + db_len > (char *)net->read_pos + pkt_len)
288
  {
694 by Brian Aker
Refactor out char* strdup for string class in user.
289
    my_error(ER_HANDSHAKE_ERROR, MYF(0), session->security_ctx.ip.c_str());
1 by brian
clean slate
290
    return 1;
291
  }
292
293
  /* Since 4.1 all database names are stored in utf8 */
294
  if (db)
295
  {
296
    db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1,
297
                             system_charset_info,
298
                             db, db_len,
520.1.22 by Brian Aker
Second pass of thd cleanup
299
                             session->charset(), &dummy_errors)]= 0;
1 by brian
clean slate
300
    db= db_buff;
301
  }
302
303
  user_buff[user_len= copy_and_convert(user_buff, sizeof(user_buff)-1,
304
                                       system_charset_info, user, user_len,
520.1.22 by Brian Aker
Second pass of thd cleanup
305
                                       session->charset(), &dummy_errors)]= '\0';
1 by brian
clean slate
306
  user= user_buff;
307
308
  /* If username starts and ends in "'", chop them off */
309
  if (user_len > 1 && user[0] == '\'' && user[user_len - 1] == '\'')
310
  {
311
    user[user_len-1]= 0;
312
    user++;
313
    user_len-= 2;
314
  }
315
694 by Brian Aker
Refactor out char* strdup for string class in user.
316
  session->security_ctx.user.assign(user);
317
832.2.9 by Mark Atwood
remove unused parameter to check_user() related to max_connections
318
  return check_user(session, passwd, passwd_len, db);
1 by brian
clean slate
319
}
320
321
322
/*
323
  Setup thread to be used with the current thread
324
325
  SYNOPSIS
326
    bool setup_connection_thread_globals()
520.1.22 by Brian Aker
Second pass of thd cleanup
327
    session    Thread/connection handler
1 by brian
clean slate
328
329
  RETURN
330
    0   ok
331
    1   Error (out of memory)
332
        In this case we will close the connection and increment status
333
*/
334
520.1.22 by Brian Aker
Second pass of thd cleanup
335
bool setup_connection_thread_globals(Session *session)
1 by brian
clean slate
336
{
520.1.22 by Brian Aker
Second pass of thd cleanup
337
  if (session->store_globals())
1 by brian
clean slate
338
  {
693 by Brian Aker
Cleaning up session class.
339
    session->close_connection(ER_OUT_OF_RESOURCES, true);
1 by brian
clean slate
340
    statistic_increment(aborted_connects,&LOCK_status);
520.1.22 by Brian Aker
Second pass of thd cleanup
341
    thread_scheduler.end_thread(session, 0);
1 by brian
clean slate
342
    return 1;                                   // Error
343
  }
344
  return 0;
345
}
346
347
348
/*
349
  Autenticate user, with error reporting
350
351
  SYNOPSIS
352
   login_connection()
520.1.22 by Brian Aker
Second pass of thd cleanup
353
   session        Thread handler
1 by brian
clean slate
354
355
  NOTES
356
    Connection is not closed in case of errors
357
358
  RETURN
359
    0    ok
360
    1    error
361
*/
362
363
520.1.22 by Brian Aker
Second pass of thd cleanup
364
bool login_connection(Session *session)
1 by brian
clean slate
365
{
520.1.22 by Brian Aker
Second pass of thd cleanup
366
  NET *net= &session->net;
1 by brian
clean slate
367
  int error;
368
369
  /* Use "connect_timeout" value during connection phase */
840.1.17 by Monty Taylor
Renamed my_net_* to drizzleclient_net_* to help with namespace issues.
370
  drizzleclient_net_set_read_timeout(net, connect_timeout);
371
  drizzleclient_net_set_write_timeout(net, connect_timeout);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
372
520.1.22 by Brian Aker
Second pass of thd cleanup
373
  lex_start(session);
1 by brian
clean slate
374
520.1.22 by Brian Aker
Second pass of thd cleanup
375
  error= check_connection(session);
840.1.20 by Monty Taylor
Renamed non-prefixed things from libdrizzleclient to drizzleclient.
376
  drizzleclient_net_end_statement(session);
1 by brian
clean slate
377
378
  if (error)
379
  {						// Wrong permissions
380
    statistic_increment(aborted_connects,&LOCK_status);
51.1.50 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
381
    return(1);
1 by brian
clean slate
382
  }
383
  /* 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.
384
  drizzleclient_net_set_read_timeout(net, session->variables.net_read_timeout);
385
  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
386
  return(0);
1 by brian
clean slate
387
}
388
389
390
/*
391
  Close an established connection
392
393
  NOTES
394
    This mainly updates status variables
395
*/
396
520.1.22 by Brian Aker
Second pass of thd cleanup
397
void end_connection(Session *session)
1 by brian
clean slate
398
{
520.1.22 by Brian Aker
Second pass of thd cleanup
399
  NET *net= &session->net;
400
  plugin_sessionvar_cleanup(session);
1 by brian
clean slate
401
520.1.22 by Brian Aker
Second pass of thd cleanup
402
  if (session->killed || (net->error && net->vio != 0))
1 by brian
clean slate
403
  {
404
    statistic_increment(aborted_threads,&LOCK_status);
405
  }
406
407
  if (net->error && net->vio != 0)
408
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
409
    if (!session->killed && session->variables.log_warnings > 1)
1 by brian
clean slate
410
    {
694 by Brian Aker
Refactor out char* strdup for string class in user.
411
      Security_context *sctx= &session->security_ctx;
1 by brian
clean slate
412
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
413
      errmsg_printf(ERRMSG_LVL_WARN, ER(ER_NEW_ABORTING_CONNECTION),
520.1.22 by Brian Aker
Second pass of thd cleanup
414
                        session->thread_id,(session->db ? session->db : "unconnected"),
694 by Brian Aker
Refactor out char* strdup for string class in user.
415
                        sctx->user.empty() == false ? sctx->user.c_str() : "unauthenticated",
416
                        sctx->ip.c_str(),
520.1.22 by Brian Aker
Second pass of thd cleanup
417
                        (session->main_da.is_error() ? session->main_da.message() :
1 by brian
clean slate
418
                         ER(ER_UNKNOWN_ERROR)));
419
    }
420
  }
421
}
422
423
424
/*
520.1.21 by Brian Aker
THD -> Session rename
425
  Initialize Session to handle queries
1 by brian
clean slate
426
*/
427
520.1.22 by Brian Aker
Second pass of thd cleanup
428
void prepare_new_connection_state(Session* session)
1 by brian
clean slate
429
{
694 by Brian Aker
Refactor out char* strdup for string class in user.
430
  Security_context *sctx= &session->security_ctx;
1 by brian
clean slate
431
520.1.22 by Brian Aker
Second pass of thd cleanup
432
  if (session->variables.max_join_size == HA_POS_ERROR)
433
    session->options |= OPTION_BIG_SELECTS;
434
  if (session->client_capabilities & CLIENT_COMPRESS)
435
    session->net.compress=1;				// Use compression
1 by brian
clean slate
436
437
  /*
520.1.22 by Brian Aker
Second pass of thd cleanup
438
    Much of this is duplicated in create_embedded_session() for the
1 by brian
clean slate
439
    embedded server library.
440
    TODO: refactor this to avoid code duplication there
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
}