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