1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 7 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2006-2018 The PHP Group |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
15 | Authors: Andrey Hristov <andrey@php.net> |
16 | Ulf Wendel <uw@php.net> |
17 +----------------------------------------------------------------------+
18 */
19
20 #include "php.h"
21 #include "mysqlnd.h"
22 #include "mysqlnd_connection.h"
23 #include "mysqlnd_priv.h"
24 #include "mysqlnd_auth.h"
25 #include "mysqlnd_wireprotocol.h"
26 #include "mysqlnd_statistics.h"
27 #include "mysqlnd_debug.h"
28
29
30 struct st_mysqlnd_protocol_no_params_command
31 {
32 struct st_mysqlnd_protocol_no_params_command_context
33 {
34 MYSQLND_CONN_DATA * conn;
35 } context;
36 };
37
38
39 /************************** COM_SET_OPTION ******************************************/
40 struct st_mysqlnd_protocol_com_set_option_command
41 {
42 struct st_mysqlnd_com_set_option_context
43 {
44 MYSQLND_CONN_DATA * conn;
45 enum_mysqlnd_server_option option;
46 } context;
47 };
48
49
50 /* {{{ mysqlnd_com_set_option_run */
51 static enum_func_status
mysqlnd_com_set_option_run(void * cmd)52 mysqlnd_com_set_option_run(void *cmd)
53 {
54 struct st_mysqlnd_protocol_com_set_option_command * command = (struct st_mysqlnd_protocol_com_set_option_command *) cmd;
55 zend_uchar buffer[2];
56 enum_func_status ret = FAIL;
57 MYSQLND_CONN_DATA * conn = command->context.conn;
58 enum_mysqlnd_server_option option = command->context.option;
59 func_mysqlnd_protocol_payload_decoder_factory__send_command send_command = conn->payload_decoder_factory->m.send_command;
60 func_mysqlnd_protocol_payload_decoder_factory__send_command_handle_response send_command_handle_response = conn->payload_decoder_factory->m.send_command_handle_response;
61
62 DBG_ENTER("mysqlnd_com_set_option_run");
63 int2store(buffer, (unsigned int) option);
64
65 ret = send_command(conn->payload_decoder_factory, COM_SET_OPTION, buffer, sizeof(buffer), FALSE,
66 &conn->state,
67 conn->error_info,
68 conn->upsert_status,
69 conn->stats,
70 conn->m->send_close,
71 conn);
72 if (PASS == ret) {
73 ret = send_command_handle_response(conn->payload_decoder_factory, PROT_EOF_PACKET, FALSE, COM_SET_OPTION, TRUE,
74 conn->error_info, conn->upsert_status, &conn->last_message);
75 }
76 DBG_RETURN(ret);
77 }
78 /* }}} */
79
80
81 /* {{{ mysqlnd_com_set_option_run_command */
82 static enum_func_status
mysqlnd_com_set_option_run_command(va_list args)83 mysqlnd_com_set_option_run_command(va_list args)
84 {
85 struct st_mysqlnd_protocol_com_set_option_command command;
86 enum_func_status ret;
87
88 DBG_ENTER("mysqlnd_com_set_option_run_command");
89 command.context.conn = va_arg(args, MYSQLND_CONN_DATA *);
90 command.context.option = va_arg(args, enum_mysqlnd_server_option);
91
92 ret = mysqlnd_com_set_option_run(&command);
93
94 DBG_RETURN(ret);
95 }
96 /* }}} */
97
98
99 /************************** COM_DEBUG ******************************************/
100 /* {{{ mysqlnd_com_debug_run */
101 static enum_func_status
mysqlnd_com_debug_run(void * cmd)102 mysqlnd_com_debug_run(void *cmd)
103 {
104 struct st_mysqlnd_protocol_no_params_command * command = (struct st_mysqlnd_protocol_no_params_command *) cmd;
105 enum_func_status ret = FAIL;
106 MYSQLND_CONN_DATA * conn = command->context.conn;
107 func_mysqlnd_protocol_payload_decoder_factory__send_command send_command = conn->payload_decoder_factory->m.send_command;
108 func_mysqlnd_protocol_payload_decoder_factory__send_command_handle_response send_command_handle_response = conn->payload_decoder_factory->m.send_command_handle_response;
109
110 DBG_ENTER("mysqlnd_com_debug_run");
111
112 ret = send_command(conn->payload_decoder_factory, COM_DEBUG, NULL, 0, FALSE,
113 &conn->state,
114 conn->error_info,
115 conn->upsert_status,
116 conn->stats,
117 conn->m->send_close,
118 conn);
119 if (PASS == ret) {
120 ret = send_command_handle_response(conn->payload_decoder_factory, PROT_EOF_PACKET, FALSE, COM_DEBUG, TRUE,
121 conn->error_info, conn->upsert_status, &conn->last_message);
122 }
123
124 DBG_RETURN(ret);
125 }
126 /* }}} */
127
128
129 /* {{{ mysqlnd_com_debug_run_command */
130 static enum_func_status
mysqlnd_com_debug_run_command(va_list args)131 mysqlnd_com_debug_run_command(va_list args)
132 {
133 struct st_mysqlnd_protocol_no_params_command command;
134 enum_func_status ret;
135
136 DBG_ENTER("mysqlnd_com_debug_run_command");
137 command.context.conn = va_arg(args, MYSQLND_CONN_DATA *);
138
139 ret = mysqlnd_com_debug_run(&command);
140
141 DBG_RETURN(ret);
142 }
143 /* }}} */
144
145
146 /************************** COM_INIT_DB ******************************************/
147 struct st_mysqlnd_protocol_com_init_db_command
148 {
149 struct st_mysqlnd_com_init_db_context
150 {
151 MYSQLND_CONN_DATA * conn;
152 MYSQLND_CSTRING db;
153 } context;
154 };
155
156
157 /* {{{ mysqlnd_com_init_db_run */
158 static enum_func_status
mysqlnd_com_init_db_run(void * cmd)159 mysqlnd_com_init_db_run(void *cmd)
160 {
161 struct st_mysqlnd_protocol_com_init_db_command * command = (struct st_mysqlnd_protocol_com_init_db_command *) cmd;
162 enum_func_status ret = FAIL;
163 MYSQLND_CONN_DATA * conn = command->context.conn;
164 const MYSQLND_CSTRING db = command->context.db;
165 func_mysqlnd_protocol_payload_decoder_factory__send_command send_command = conn->payload_decoder_factory->m.send_command;
166 func_mysqlnd_protocol_payload_decoder_factory__send_command_handle_response send_command_handle_response = conn->payload_decoder_factory->m.send_command_handle_response;
167
168 DBG_ENTER("mysqlnd_com_init_db_run");
169
170 ret = send_command(conn->payload_decoder_factory, COM_INIT_DB, (zend_uchar*) command->context.db.s, command->context.db.l, FALSE,
171 &conn->state,
172 conn->error_info,
173 conn->upsert_status,
174 conn->stats,
175 conn->m->send_close,
176 conn);
177 if (PASS == ret) {
178 ret = send_command_handle_response(conn->payload_decoder_factory, PROT_OK_PACKET, FALSE, COM_INIT_DB, TRUE,
179 conn->error_info, conn->upsert_status, &conn->last_message);
180 }
181
182 /*
183 The server sends 0 but libmysql doesn't read it and has established
184 a protocol of giving back -1. Thus we have to follow it :(
185 */
186 UPSERT_STATUS_SET_AFFECTED_ROWS_TO_ERROR(conn->upsert_status);
187 if (ret == PASS) {
188 if (conn->connect_or_select_db.s) {
189 mnd_pefree(conn->connect_or_select_db.s, conn->persistent);
190 }
191 conn->connect_or_select_db.s = mnd_pestrndup(db.s, db.l, conn->persistent);
192 conn->connect_or_select_db.l = db.l;
193 if (!conn->connect_or_select_db.s) {
194 /* OOM */
195 SET_OOM_ERROR(conn->error_info);
196 ret = FAIL;
197 }
198 }
199
200 DBG_RETURN(ret);
201 }
202 /* }}} */
203
204
205 /* {{{ mysqlnd_com_init_db_run_command */
206 static enum_func_status
mysqlnd_com_init_db_run_command(va_list args)207 mysqlnd_com_init_db_run_command(va_list args)
208 {
209 struct st_mysqlnd_protocol_com_init_db_command command;
210 enum_func_status ret;
211
212 DBG_ENTER("mysqlnd_com_init_db_run_command");
213 command.context.conn = va_arg(args, MYSQLND_CONN_DATA *);
214 command.context.db = va_arg(args, MYSQLND_CSTRING);
215
216 ret = mysqlnd_com_init_db_run(&command);
217
218 DBG_RETURN(ret);
219 }
220 /* }}} */
221
222
223 /************************** COM_PING ******************************************/
224 /* {{{ mysqlnd_com_ping_run */
225 static enum_func_status
mysqlnd_com_ping_run(void * cmd)226 mysqlnd_com_ping_run(void *cmd)
227 {
228 struct st_mysqlnd_protocol_no_params_command * command = (struct st_mysqlnd_protocol_no_params_command *) cmd;
229 enum_func_status ret = FAIL;
230 MYSQLND_CONN_DATA * conn = command->context.conn;
231 func_mysqlnd_protocol_payload_decoder_factory__send_command send_command = conn->payload_decoder_factory->m.send_command;
232 func_mysqlnd_protocol_payload_decoder_factory__send_command_handle_response send_command_handle_response = conn->payload_decoder_factory->m.send_command_handle_response;
233
234 DBG_ENTER("mysqlnd_com_ping_run");
235
236 ret = send_command(conn->payload_decoder_factory, COM_PING, NULL, 0, TRUE,
237 &conn->state,
238 conn->error_info,
239 conn->upsert_status,
240 conn->stats,
241 conn->m->send_close,
242 conn);
243 if (PASS == ret) {
244 ret = send_command_handle_response(conn->payload_decoder_factory, PROT_OK_PACKET, TRUE, COM_PING, TRUE,
245 conn->error_info, conn->upsert_status, &conn->last_message);
246 }
247 /*
248 The server sends 0 but libmysql doesn't read it and has established
249 a protocol of giving back -1. Thus we have to follow it :(
250 */
251 UPSERT_STATUS_SET_AFFECTED_ROWS_TO_ERROR(conn->upsert_status);
252
253 DBG_RETURN(ret);
254 }
255 /* }}} */
256
257
258 /* {{{ mysqlnd_com_ping_run_command */
259 static enum_func_status
mysqlnd_com_ping_run_command(va_list args)260 mysqlnd_com_ping_run_command(va_list args)
261 {
262 struct st_mysqlnd_protocol_no_params_command command;
263 enum_func_status ret;
264
265 DBG_ENTER("mysqlnd_com_ping_run_command");
266 command.context.conn = va_arg(args, MYSQLND_CONN_DATA *);
267
268 ret = mysqlnd_com_ping_run(&command);
269
270 DBG_RETURN(ret);
271 }
272 /* }}} */
273
274
275 /************************** COM_STATISTICS ******************************************/
276 struct st_mysqlnd_protocol_com_statistics_command
277 {
278 struct st_mysqlnd_com_statistics_context
279 {
280 MYSQLND_CONN_DATA * conn;
281 zend_string ** message;
282 } context;
283 };
284
285
286 /* {{{ mysqlnd_com_statistics_run */
287 static enum_func_status
mysqlnd_com_statistics_run(void * cmd)288 mysqlnd_com_statistics_run(void *cmd)
289 {
290 struct st_mysqlnd_protocol_com_statistics_command * command = (struct st_mysqlnd_protocol_com_statistics_command *) cmd;
291 enum_func_status ret = FAIL;
292 MYSQLND_CONN_DATA * conn = command->context.conn;
293 zend_string **message = command->context.message;
294 func_mysqlnd_protocol_payload_decoder_factory__send_command send_command = conn->payload_decoder_factory->m.send_command;
295
296 DBG_ENTER("mysqlnd_com_statistics_run");
297
298 ret = send_command(conn->payload_decoder_factory, COM_STATISTICS, NULL, 0, FALSE,
299 &conn->state,
300 conn->error_info,
301 conn->upsert_status,
302 conn->stats,
303 conn->m->send_close,
304 conn);
305
306 if (PASS == ret) {
307 MYSQLND_PACKET_STATS stats_header;
308
309 conn->payload_decoder_factory->m.init_stats_packet(&stats_header);
310 if (PASS == (ret = PACKET_READ(conn, &stats_header))) {
311 /* will be freed by Zend, thus don't use the mnd_ allocator */
312 *message = zend_string_init(stats_header.message.s, stats_header.message.l, 0);
313 DBG_INF(ZSTR_VAL(*message));
314 }
315 PACKET_FREE(&stats_header);
316 }
317
318 DBG_RETURN(ret);
319 }
320 /* }}} */
321
322
323 /* {{{ mysqlnd_com_statistics_run_command */
324 static enum_func_status
mysqlnd_com_statistics_run_command(va_list args)325 mysqlnd_com_statistics_run_command(va_list args)
326 {
327 struct st_mysqlnd_protocol_com_statistics_command command;
328 enum_func_status ret;
329
330 DBG_ENTER("mysqlnd_com_statistics_run_command");
331 command.context.conn = va_arg(args, MYSQLND_CONN_DATA *);
332 command.context.message = va_arg(args, zend_string **);
333
334 ret = mysqlnd_com_statistics_run(&command);
335
336 DBG_RETURN(ret);
337 }
338 /* }}} */
339
340 /************************** COM_PROCESS_KILL ******************************************/
341 struct st_mysqlnd_protocol_com_process_kill_command
342 {
343 struct st_mysqlnd_com_process_kill_context
344 {
345 MYSQLND_CONN_DATA * conn;
346 unsigned int process_id;
347 zend_bool read_response;
348 } context;
349 };
350
351
352 /* {{{ mysqlnd_com_process_kill_run */
353 enum_func_status
mysqlnd_com_process_kill_run(void * cmd)354 mysqlnd_com_process_kill_run(void *cmd)
355 {
356 struct st_mysqlnd_protocol_com_process_kill_command * command = (struct st_mysqlnd_protocol_com_process_kill_command *) cmd;
357 zend_uchar buff[4];
358 enum_func_status ret = FAIL;
359 MYSQLND_CONN_DATA * conn = command->context.conn;
360 zend_bool read_response = command->context.read_response;
361 func_mysqlnd_protocol_payload_decoder_factory__send_command send_command = conn->payload_decoder_factory->m.send_command;
362 func_mysqlnd_protocol_payload_decoder_factory__send_command_handle_response send_command_handle_response = conn->payload_decoder_factory->m.send_command_handle_response;
363
364 DBG_ENTER("mysqlnd_com_process_kill_run");
365 int4store(buff, command->context.process_id);
366
367 ret = send_command(conn->payload_decoder_factory, COM_PROCESS_KILL, buff, 4, FALSE,
368 &conn->state,
369 conn->error_info,
370 conn->upsert_status,
371 conn->stats,
372 conn->m->send_close,
373 conn);
374 if (PASS == ret && read_response) {
375 ret = send_command_handle_response(conn->payload_decoder_factory, PROT_OK_PACKET, FALSE, COM_PROCESS_KILL, TRUE,
376 conn->error_info, conn->upsert_status, &conn->last_message);
377 }
378
379 if (read_response) {
380 /*
381 The server sends 0 but libmysql doesn't read it and has established
382 a protocol of giving back -1. Thus we have to follow it :(
383 */
384 UPSERT_STATUS_SET_AFFECTED_ROWS_TO_ERROR(conn->upsert_status);
385 } else if (PASS == ret) {
386 SET_CONNECTION_STATE(&conn->state, CONN_QUIT_SENT);
387 conn->m->send_close(conn);
388 }
389
390 DBG_RETURN(ret);
391 }
392 /* }}} */
393
394
395 /* {{{ mysqlnd_com_process_kill_run_command */
396 static enum_func_status
mysqlnd_com_process_kill_run_command(va_list args)397 mysqlnd_com_process_kill_run_command(va_list args)
398 {
399 struct st_mysqlnd_protocol_com_process_kill_command command;
400 enum_func_status ret;
401
402 DBG_ENTER("mysqlnd_com_process_kill_run_command");
403 command.context.conn = va_arg(args, MYSQLND_CONN_DATA *);
404 command.context.process_id = va_arg(args, unsigned int);
405 command.context.read_response = va_arg(args, unsigned int)? TRUE:FALSE;
406
407 ret = mysqlnd_com_process_kill_run(&command);
408
409 DBG_RETURN(ret);
410 }
411 /* }}} */
412
413 /************************** COM_REFRESH ******************************************/
414 struct st_mysqlnd_protocol_com_refresh_command
415 {
416 struct st_mysqlnd_com_refresh_context
417 {
418 MYSQLND_CONN_DATA * conn;
419 uint8_t options;
420 } context;
421 };
422
423
424 /* {{{ mysqlnd_com_refresh_run */
425 enum_func_status
mysqlnd_com_refresh_run(void * cmd)426 mysqlnd_com_refresh_run(void *cmd)
427 {
428 struct st_mysqlnd_protocol_com_refresh_command * command = (struct st_mysqlnd_protocol_com_refresh_command *) cmd;
429 zend_uchar bits[1];
430 enum_func_status ret = FAIL;
431 MYSQLND_CONN_DATA * conn = command->context.conn;
432 func_mysqlnd_protocol_payload_decoder_factory__send_command send_command = conn->payload_decoder_factory->m.send_command;
433 func_mysqlnd_protocol_payload_decoder_factory__send_command_handle_response send_command_handle_response = conn->payload_decoder_factory->m.send_command_handle_response;
434
435 DBG_ENTER("mysqlnd_com_refresh_run");
436 int1store(bits, command->context.options);
437
438 ret = send_command(conn->payload_decoder_factory, COM_REFRESH, bits, 1, FALSE,
439 &conn->state,
440 conn->error_info,
441 conn->upsert_status,
442 conn->stats,
443 conn->m->send_close,
444 conn);
445 if (PASS == ret) {
446 ret = send_command_handle_response(conn->payload_decoder_factory, PROT_OK_PACKET, FALSE, COM_REFRESH, TRUE,
447 conn->error_info, conn->upsert_status, &conn->last_message);
448 }
449
450 DBG_RETURN(ret);
451 }
452 /* }}} */
453
454
455 /* {{{ mysqlnd_com_refresh_run_command */
456 static enum_func_status
mysqlnd_com_refresh_run_command(va_list args)457 mysqlnd_com_refresh_run_command(va_list args)
458 {
459 struct st_mysqlnd_protocol_com_refresh_command command;
460 enum_func_status ret;
461
462 DBG_ENTER("mysqlnd_com_refresh_run_command");
463 command.context.conn = va_arg(args, MYSQLND_CONN_DATA *);
464 command.context.options = va_arg(args, unsigned int);
465
466 ret = mysqlnd_com_refresh_run(&command);
467
468 DBG_RETURN(ret);
469 }
470 /* }}} */
471
472
473 /************************** COM_SHUTDOWN ******************************************/
474 struct st_mysqlnd_protocol_com_shutdown_command
475 {
476 struct st_mysqlnd_com_shutdown_context
477 {
478 MYSQLND_CONN_DATA * conn;
479 uint8_t level;
480 } context;
481 };
482
483
484 /* {{{ mysqlnd_com_shutdown_run */
485 enum_func_status
mysqlnd_com_shutdown_run(void * cmd)486 mysqlnd_com_shutdown_run(void *cmd)
487 {
488 struct st_mysqlnd_protocol_com_shutdown_command * command = (struct st_mysqlnd_protocol_com_shutdown_command *) cmd;
489 zend_uchar bits[1];
490 enum_func_status ret = FAIL;
491 MYSQLND_CONN_DATA * conn = command->context.conn;
492 func_mysqlnd_protocol_payload_decoder_factory__send_command send_command = conn->payload_decoder_factory->m.send_command;
493 func_mysqlnd_protocol_payload_decoder_factory__send_command_handle_response send_command_handle_response = conn->payload_decoder_factory->m.send_command_handle_response;
494
495 DBG_ENTER("mysqlnd_com_shutdown_run");
496 int1store(bits, command->context.level);
497
498 ret = send_command(conn->payload_decoder_factory, COM_SHUTDOWN, bits, 1, FALSE,
499 &conn->state,
500 conn->error_info,
501 conn->upsert_status,
502 conn->stats,
503 conn->m->send_close,
504 conn);
505 if (PASS == ret) {
506 ret = send_command_handle_response(conn->payload_decoder_factory, PROT_OK_PACKET, FALSE, COM_SHUTDOWN, TRUE,
507 conn->error_info, conn->upsert_status, &conn->last_message);
508 }
509
510 DBG_RETURN(ret);
511 }
512 /* }}} */
513
514
515 /* {{{ mysqlnd_com_shutdown_run_command */
516 static enum_func_status
mysqlnd_com_shutdown_run_command(va_list args)517 mysqlnd_com_shutdown_run_command(va_list args)
518 {
519 struct st_mysqlnd_protocol_com_shutdown_command command;
520 enum_func_status ret;
521
522 DBG_ENTER("mysqlnd_com_shutdown_run_command");
523 command.context.conn = va_arg(args, MYSQLND_CONN_DATA *);
524 command.context.level = va_arg(args, unsigned int);
525
526 ret = mysqlnd_com_shutdown_run(&command);
527
528 DBG_RETURN(ret);
529 }
530 /* }}} */
531
532
533 /************************** COM_QUIT ******************************************/
534 struct st_mysqlnd_protocol_com_quit_command
535 {
536 struct st_mysqlnd_com_quit_context
537 {
538 MYSQLND_CONN_DATA * conn;
539 } context;
540 };
541
542
543 /* {{{ mysqlnd_com_quit_run */
544 enum_func_status
mysqlnd_com_quit_run(void * cmd)545 mysqlnd_com_quit_run(void *cmd)
546 {
547 struct st_mysqlnd_protocol_com_quit_command * command = (struct st_mysqlnd_protocol_com_quit_command *) cmd;
548 enum_func_status ret = FAIL;
549 MYSQLND_CONN_DATA * conn = command->context.conn;
550 func_mysqlnd_protocol_payload_decoder_factory__send_command send_command = conn->payload_decoder_factory->m.send_command;
551
552 DBG_ENTER("mysqlnd_com_quit_run");
553
554 ret = send_command(conn->payload_decoder_factory, COM_QUIT, NULL, 0, TRUE,
555 &conn->state,
556 conn->error_info,
557 conn->upsert_status,
558 conn->stats,
559 conn->m->send_close,
560 conn);
561
562 DBG_RETURN(ret);
563 }
564 /* }}} */
565
566
567 /* {{{ mysqlnd_com_quit_run_command */
568 static enum_func_status
mysqlnd_com_quit_run_command(va_list args)569 mysqlnd_com_quit_run_command(va_list args)
570 {
571 struct st_mysqlnd_protocol_com_quit_command command;
572 enum_func_status ret;
573
574 DBG_ENTER("mysqlnd_com_quit_run_command");
575 command.context.conn = va_arg(args, MYSQLND_CONN_DATA *);
576
577 ret = mysqlnd_com_quit_run(&command);
578
579 DBG_RETURN(ret);
580 }
581 /* }}} */
582
583 /************************** COM_QUERY ******************************************/
584 struct st_mysqlnd_protocol_com_query_command
585 {
586 struct st_mysqlnd_com_query_context
587 {
588 MYSQLND_CONN_DATA * conn;
589 MYSQLND_CSTRING query;
590 } context;
591 };
592
593
594 /* {{{ mysqlnd_com_query_run */
595 static enum_func_status
mysqlnd_com_query_run(void * cmd)596 mysqlnd_com_query_run(void *cmd)
597 {
598 struct st_mysqlnd_protocol_com_query_command * command = (struct st_mysqlnd_protocol_com_query_command *) cmd;
599 enum_func_status ret = FAIL;
600 MYSQLND_CONN_DATA * conn = command->context.conn;
601 func_mysqlnd_protocol_payload_decoder_factory__send_command send_command = conn->payload_decoder_factory->m.send_command;
602
603 DBG_ENTER("mysqlnd_com_query_run");
604
605 ret = send_command(conn->payload_decoder_factory, COM_QUERY, (zend_uchar*) command->context.query.s, command->context.query.l, FALSE,
606 &conn->state,
607 conn->error_info,
608 conn->upsert_status,
609 conn->stats,
610 conn->m->send_close,
611 conn);
612
613 if (PASS == ret) {
614 SET_CONNECTION_STATE(&conn->state, CONN_QUERY_SENT);
615 }
616
617 DBG_RETURN(ret);
618 }
619 /* }}} */
620
621
622 /* {{{ mysqlnd_com_query_run_command */
623 static enum_func_status
mysqlnd_com_query_run_command(va_list args)624 mysqlnd_com_query_run_command(va_list args)
625 {
626 struct st_mysqlnd_protocol_com_query_command command;
627 enum_func_status ret;
628
629 DBG_ENTER("mysqlnd_com_query_run_command");
630 command.context.conn = va_arg(args, MYSQLND_CONN_DATA *);
631 command.context.query = va_arg(args, MYSQLND_CSTRING);
632
633 ret = mysqlnd_com_query_run(&command);
634
635 DBG_RETURN(ret);
636 }
637 /* }}} */
638
639 /************************** COM_CHANGE_USER ******************************************/
640 struct st_mysqlnd_protocol_com_change_user_command
641 {
642 struct st_mysqlnd_com_change_user_context
643 {
644 MYSQLND_CONN_DATA * conn;
645 MYSQLND_CSTRING payload;
646 zend_bool silent;
647 } context;
648 };
649
650
651 /* {{{ mysqlnd_com_change_user_run */
652 static enum_func_status
mysqlnd_com_change_user_run(void * cmd)653 mysqlnd_com_change_user_run(void *cmd)
654 {
655 struct st_mysqlnd_protocol_com_change_user_command * command = (struct st_mysqlnd_protocol_com_change_user_command *) cmd;
656 enum_func_status ret = FAIL;
657 MYSQLND_CONN_DATA * conn = command->context.conn;
658 func_mysqlnd_protocol_payload_decoder_factory__send_command send_command = conn->payload_decoder_factory->m.send_command;
659
660 DBG_ENTER("mysqlnd_com_change_user_run");
661
662 ret = send_command(conn->payload_decoder_factory, COM_CHANGE_USER, (zend_uchar*) command->context.payload.s, command->context.payload.l, command->context.silent,
663 &conn->state,
664 conn->error_info,
665 conn->upsert_status,
666 conn->stats,
667 conn->m->send_close,
668 conn);
669
670 DBG_RETURN(ret);
671 }
672 /* }}} */
673
674
675 /* {{{ mysqlnd_com_change_user_run_command */
676 static enum_func_status
mysqlnd_com_change_user_run_command(va_list args)677 mysqlnd_com_change_user_run_command(va_list args)
678 {
679 struct st_mysqlnd_protocol_com_change_user_command command;
680 enum_func_status ret;
681
682 DBG_ENTER("mysqlnd_com_change_user_run_command");
683 command.context.conn = va_arg(args, MYSQLND_CONN_DATA *);
684 command.context.payload = va_arg(args, MYSQLND_CSTRING);
685 command.context.silent = va_arg(args, unsigned int);
686
687 ret = mysqlnd_com_change_user_run(&command);
688
689 DBG_RETURN(ret);
690 }
691 /* }}} */
692
693
694 /************************** COM_REAP_RESULT ******************************************/
695 struct st_mysqlnd_protocol_com_reap_result_command
696 {
697 struct st_mysqlnd_com_reap_result_context
698 {
699 MYSQLND_CONN_DATA * conn;
700 } context;
701 };
702
703
704 /* {{{ mysqlnd_com_reap_result_run */
705 static enum_func_status
mysqlnd_com_reap_result_run(void * cmd)706 mysqlnd_com_reap_result_run(void *cmd)
707 {
708 struct st_mysqlnd_protocol_com_reap_result_command * command = (struct st_mysqlnd_protocol_com_reap_result_command *) cmd;
709 enum_func_status ret = FAIL;
710 MYSQLND_CONN_DATA * conn = command->context.conn;
711 const enum_mysqlnd_connection_state state = GET_CONNECTION_STATE(&conn->state);
712
713 DBG_ENTER("mysqlnd_com_reap_result_run");
714 if (state <= CONN_READY || state == CONN_QUIT_SENT) {
715 php_error_docref(NULL, E_WARNING, "Connection not opened, clear or has been closed");
716 DBG_ERR_FMT("Connection not opened, clear or has been closed. State=%u", state);
717 DBG_RETURN(ret);
718 }
719 ret = conn->m->query_read_result_set_header(conn, NULL);
720
721 DBG_RETURN(ret);
722 }
723 /* }}} */
724
725
726 /* {{{ mysqlnd_com_reap_result_run_command */
727 static enum_func_status
mysqlnd_com_reap_result_run_command(va_list args)728 mysqlnd_com_reap_result_run_command(va_list args)
729 {
730 struct st_mysqlnd_protocol_com_reap_result_command command;
731 enum_func_status ret;
732
733 DBG_ENTER("mysqlnd_com_reap_result_run_command");
734 command.context.conn = va_arg(args, MYSQLND_CONN_DATA *);
735
736 ret = mysqlnd_com_reap_result_run(&command);
737
738 DBG_RETURN(ret);
739 }
740 /* }}} */
741
742
743 /************************** COM_STMT_PREPARE ******************************************/
744 struct st_mysqlnd_protocol_com_stmt_prepare_command
745 {
746 struct st_mysqlnd_com_stmt_prepare_context
747 {
748 MYSQLND_CONN_DATA * conn;
749 MYSQLND_CSTRING query;
750 } context;
751 };
752
753
754 /* {{{ mysqlnd_com_stmt_prepare_run */
755 static enum_func_status
mysqlnd_com_stmt_prepare_run(void * cmd)756 mysqlnd_com_stmt_prepare_run(void *cmd)
757 {
758 struct st_mysqlnd_protocol_com_stmt_prepare_command * command = (struct st_mysqlnd_protocol_com_stmt_prepare_command *) cmd;
759 enum_func_status ret = FAIL;
760 MYSQLND_CONN_DATA * conn = command->context.conn;
761 func_mysqlnd_protocol_payload_decoder_factory__send_command send_command = conn->payload_decoder_factory->m.send_command;
762
763 DBG_ENTER("mysqlnd_com_stmt_prepare_run");
764
765 ret = send_command(conn->payload_decoder_factory, COM_STMT_PREPARE, (zend_uchar*) command->context.query.s, command->context.query.l, FALSE,
766 &conn->state,
767 conn->error_info,
768 conn->upsert_status,
769 conn->stats,
770 conn->m->send_close,
771 conn);
772
773 DBG_RETURN(ret);
774 }
775 /* }}} */
776
777
778 /* {{{ mysqlnd_com_stmt_prepare_run_command */
779 static enum_func_status
mysqlnd_com_stmt_prepare_run_command(va_list args)780 mysqlnd_com_stmt_prepare_run_command(va_list args)
781 {
782 struct st_mysqlnd_protocol_com_stmt_prepare_command command;
783 enum_func_status ret;
784
785 DBG_ENTER("mysqlnd_com_stmt_prepare_run_command");
786 command.context.conn = va_arg(args, MYSQLND_CONN_DATA *);
787 command.context.query = va_arg(args, MYSQLND_CSTRING);
788
789 ret = mysqlnd_com_stmt_prepare_run(&command);
790
791 DBG_RETURN(ret);
792 }
793 /* }}} */
794
795
796 /************************** COM_STMT_EXECUTE ******************************************/
797 struct st_mysqlnd_protocol_com_stmt_execute_command
798 {
799 struct st_mysqlnd_com_stmt_execute_context
800 {
801 MYSQLND_CONN_DATA * conn;
802 MYSQLND_CSTRING payload;
803 } context;
804 };
805
806
807 /* {{{ mysqlnd_com_stmt_execute_run */
808 static enum_func_status
mysqlnd_com_stmt_execute_run(void * cmd)809 mysqlnd_com_stmt_execute_run(void *cmd)
810 {
811 struct st_mysqlnd_protocol_com_stmt_execute_command * command = (struct st_mysqlnd_protocol_com_stmt_execute_command *) cmd;
812 enum_func_status ret = FAIL;
813 MYSQLND_CONN_DATA * conn = command->context.conn;
814 func_mysqlnd_protocol_payload_decoder_factory__send_command send_command = conn->payload_decoder_factory->m.send_command;
815
816 DBG_ENTER("mysqlnd_com_stmt_execute_run");
817
818 ret = send_command(conn->payload_decoder_factory, COM_STMT_EXECUTE, (zend_uchar*) command->context.payload.s, command->context.payload.l, FALSE,
819 &conn->state,
820 conn->error_info,
821 conn->upsert_status,
822 conn->stats,
823 conn->m->send_close,
824 conn);
825
826 DBG_RETURN(ret);
827 }
828 /* }}} */
829
830
831 /* {{{ mysqlnd_com_stmt_execute_run_command */
832 static enum_func_status
mysqlnd_com_stmt_execute_run_command(va_list args)833 mysqlnd_com_stmt_execute_run_command(va_list args)
834 {
835 struct st_mysqlnd_protocol_com_stmt_execute_command command;
836 enum_func_status ret;
837
838 DBG_ENTER("mysqlnd_com_stmt_execute_run_command");
839 command.context.conn = va_arg(args, MYSQLND_CONN_DATA *);
840 command.context.payload = va_arg(args, MYSQLND_CSTRING);
841
842 ret = mysqlnd_com_stmt_execute_run(&command);
843
844 DBG_RETURN(ret);
845 }
846 /* }}} */
847
848
849 /************************** COM_STMT_FETCH ******************************************/
850 struct st_mysqlnd_protocol_com_stmt_fetch_command
851 {
852 struct st_mysqlnd_com_stmt_fetch_context
853 {
854 MYSQLND_CONN_DATA * conn;
855 MYSQLND_CSTRING payload;
856 } context;
857 };
858
859
860 /* {{{ mysqlnd_com_stmt_fetch_run */
861 static enum_func_status
mysqlnd_com_stmt_fetch_run(void * cmd)862 mysqlnd_com_stmt_fetch_run(void *cmd)
863 {
864 struct st_mysqlnd_protocol_com_stmt_fetch_command * command = (struct st_mysqlnd_protocol_com_stmt_fetch_command *) cmd;
865 enum_func_status ret = FAIL;
866 MYSQLND_CONN_DATA * conn = command->context.conn;
867 func_mysqlnd_protocol_payload_decoder_factory__send_command send_command = conn->payload_decoder_factory->m.send_command;
868
869 DBG_ENTER("mysqlnd_com_stmt_fetch_run");
870
871 ret = send_command(conn->payload_decoder_factory, COM_STMT_FETCH, (zend_uchar*) command->context.payload.s, command->context.payload.l, FALSE,
872 &conn->state,
873 conn->error_info,
874 conn->upsert_status,
875 conn->stats,
876 conn->m->send_close,
877 conn);
878
879 DBG_RETURN(ret);
880 }
881 /* }}} */
882
883
884 /* {{{ mysqlnd_com_stmt_fetch_run_command */
885 static enum_func_status
mysqlnd_com_stmt_fetch_run_command(va_list args)886 mysqlnd_com_stmt_fetch_run_command(va_list args)
887 {
888 struct st_mysqlnd_protocol_com_stmt_fetch_command command;
889 enum_func_status ret;
890
891 DBG_ENTER("mysqlnd_com_stmt_fetch_run_command");
892 command.context.conn = va_arg(args, MYSQLND_CONN_DATA *);
893 command.context.payload = va_arg(args, MYSQLND_CSTRING);
894
895 ret = mysqlnd_com_stmt_fetch_run(&command);
896
897 DBG_RETURN(ret);
898 }
899 /* }}} */
900
901
902 /************************** COM_STMT_RESET ******************************************/
903 struct st_mysqlnd_protocol_com_stmt_reset_command
904 {
905 struct st_mysqlnd_com_stmt_reset_context
906 {
907 MYSQLND_CONN_DATA * conn;
908 zend_ulong stmt_id;
909 } context;
910 };
911
912
913 /* {{{ mysqlnd_com_stmt_reset_run */
914 static enum_func_status
mysqlnd_com_stmt_reset_run(void * cmd)915 mysqlnd_com_stmt_reset_run(void *cmd)
916 {
917 zend_uchar cmd_buf[MYSQLND_STMT_ID_LENGTH /* statement id */];
918 struct st_mysqlnd_protocol_com_stmt_reset_command * command = (struct st_mysqlnd_protocol_com_stmt_reset_command *) cmd;
919 enum_func_status ret = FAIL;
920 MYSQLND_CONN_DATA * conn = command->context.conn;
921 func_mysqlnd_protocol_payload_decoder_factory__send_command send_command = conn->payload_decoder_factory->m.send_command;
922 func_mysqlnd_protocol_payload_decoder_factory__send_command_handle_response send_command_handle_response = conn->payload_decoder_factory->m.send_command_handle_response;
923
924 DBG_ENTER("mysqlnd_com_stmt_reset_run");
925
926 int4store(cmd_buf, command->context.stmt_id);
927 ret = send_command(conn->payload_decoder_factory, COM_STMT_RESET, cmd_buf, sizeof(cmd_buf), FALSE,
928 &conn->state,
929 conn->error_info,
930 conn->upsert_status,
931 conn->stats,
932 conn->m->send_close,
933 conn);
934 if (PASS == ret) {
935 ret = send_command_handle_response(conn->payload_decoder_factory, PROT_OK_PACKET, FALSE, COM_STMT_RESET, TRUE,
936 conn->error_info, conn->upsert_status, &conn->last_message);
937 }
938
939 DBG_RETURN(ret);
940 }
941 /* }}} */
942
943
944 /* {{{ mysqlnd_com_stmt_reset_run_command */
945 static enum_func_status
mysqlnd_com_stmt_reset_run_command(va_list args)946 mysqlnd_com_stmt_reset_run_command(va_list args)
947 {
948 struct st_mysqlnd_protocol_com_stmt_reset_command command;
949 enum_func_status ret;
950
951 DBG_ENTER("mysqlnd_com_stmt_reset_run_command");
952 command.context.conn = va_arg(args, MYSQLND_CONN_DATA *);
953 command.context.stmt_id = va_arg(args, size_t);
954
955 ret = mysqlnd_com_stmt_reset_run(&command);
956
957 DBG_RETURN(ret);
958 }
959 /* }}} */
960
961
962 /************************** COM_STMT_SEND_LONG_DATA ******************************************/
963 struct st_mysqlnd_protocol_com_stmt_send_long_data_command
964 {
965 struct st_mysqlnd_com_stmt_send_long_data_context
966 {
967 MYSQLND_CONN_DATA * conn;
968 MYSQLND_CSTRING payload;
969 } context;
970 };
971
972
973 /* {{{ mysqlnd_com_stmt_send_long_data_run */
974 static enum_func_status
mysqlnd_com_stmt_send_long_data_run(void * cmd)975 mysqlnd_com_stmt_send_long_data_run(void *cmd)
976 {
977 struct st_mysqlnd_protocol_com_stmt_send_long_data_command * command = (struct st_mysqlnd_protocol_com_stmt_send_long_data_command *) cmd;
978 enum_func_status ret = FAIL;
979 MYSQLND_CONN_DATA * conn = command->context.conn;
980 func_mysqlnd_protocol_payload_decoder_factory__send_command send_command = conn->payload_decoder_factory->m.send_command;
981
982 DBG_ENTER("mysqlnd_com_stmt_send_long_data_run");
983
984 ret = send_command(conn->payload_decoder_factory, COM_STMT_SEND_LONG_DATA, (zend_uchar*) command->context.payload.s, command->context.payload.l, FALSE,
985 &conn->state,
986 conn->error_info,
987 conn->upsert_status,
988 conn->stats,
989 conn->m->send_close,
990 conn);
991
992 DBG_RETURN(ret);
993 }
994 /* }}} */
995
996
997 /* {{{ mysqlnd_com_stmt_send_long_data_run_command */
998 static enum_func_status
mysqlnd_com_stmt_send_long_data_run_command(va_list args)999 mysqlnd_com_stmt_send_long_data_run_command(va_list args)
1000 {
1001 struct st_mysqlnd_protocol_com_stmt_send_long_data_command command;
1002 enum_func_status ret;
1003
1004 DBG_ENTER("mysqlnd_com_stmt_send_long_data_run_command");
1005 command.context.conn = va_arg(args, MYSQLND_CONN_DATA *);
1006 command.context.payload = va_arg(args, MYSQLND_CSTRING);
1007
1008 ret = mysqlnd_com_stmt_send_long_data_run(&command);
1009
1010 DBG_RETURN(ret);
1011 }
1012 /* }}} */
1013
1014
1015 /************************** COM_STMT_CLOSE ******************************************/
1016 struct st_mysqlnd_protocol_com_stmt_close_command
1017 {
1018 struct st_mysqlnd_com_stmt_close_context
1019 {
1020 MYSQLND_CONN_DATA * conn;
1021 zend_ulong stmt_id;
1022 } context;
1023 };
1024
1025
1026 /* {{{ mysqlnd_com_stmt_close_run */
1027 static enum_func_status
mysqlnd_com_stmt_close_run(void * cmd)1028 mysqlnd_com_stmt_close_run(void *cmd)
1029 {
1030 zend_uchar cmd_buf[MYSQLND_STMT_ID_LENGTH /* statement id */];
1031 struct st_mysqlnd_protocol_com_stmt_close_command * command = (struct st_mysqlnd_protocol_com_stmt_close_command *) cmd;
1032 enum_func_status ret = FAIL;
1033 MYSQLND_CONN_DATA * conn = command->context.conn;
1034 func_mysqlnd_protocol_payload_decoder_factory__send_command send_command = conn->payload_decoder_factory->m.send_command;
1035
1036 DBG_ENTER("mysqlnd_com_stmt_close_run");
1037
1038 int4store(cmd_buf, command->context.stmt_id);
1039 ret = send_command(conn->payload_decoder_factory, COM_STMT_CLOSE, cmd_buf, sizeof(cmd_buf), FALSE,
1040 &conn->state,
1041 conn->error_info,
1042 conn->upsert_status,
1043 conn->stats,
1044 conn->m->send_close,
1045 conn);
1046
1047 DBG_RETURN(ret);
1048 }
1049 /* }}} */
1050
1051
1052 /* {{{ mysqlnd_com_stmt_close_run_command */
1053 static enum_func_status
mysqlnd_com_stmt_close_run_command(va_list args)1054 mysqlnd_com_stmt_close_run_command(va_list args)
1055 {
1056 struct st_mysqlnd_protocol_com_stmt_close_command command;
1057 enum_func_status ret;
1058
1059 DBG_ENTER("mysqlnd_com_stmt_close_run_command");
1060 command.context.conn = va_arg(args, MYSQLND_CONN_DATA *);
1061 command.context.stmt_id = va_arg(args, size_t);
1062
1063 ret = mysqlnd_com_stmt_close_run(&command);
1064
1065 DBG_RETURN(ret);
1066 }
1067 /* }}} */
1068
1069
1070
1071 /************************** COM_ENABLE_SSL ******************************************/
1072 struct st_mysqlnd_protocol_com_enable_ssl_command
1073 {
1074 struct st_mysqlnd_com_enable_ssl_context
1075 {
1076 MYSQLND_CONN_DATA * conn;
1077 size_t client_capabilities;
1078 size_t server_capabilities;
1079 unsigned int charset_no;
1080 } context;
1081 };
1082
1083
1084 /* {{{ mysqlnd_com_enable_ssl_run */
1085 static enum_func_status
mysqlnd_com_enable_ssl_run(void * cmd)1086 mysqlnd_com_enable_ssl_run(void *cmd)
1087 {
1088 struct st_mysqlnd_protocol_com_enable_ssl_command * command = (struct st_mysqlnd_protocol_com_enable_ssl_command *) cmd;
1089 enum_func_status ret = FAIL;
1090 MYSQLND_CONN_DATA * conn = command->context.conn;
1091 MYSQLND_PACKET_AUTH auth_packet;
1092 size_t client_capabilities = command->context.client_capabilities;
1093 size_t server_capabilities = command->context.server_capabilities;
1094
1095 DBG_ENTER("mysqlnd_com_enable_ssl_run");
1096 DBG_INF_FMT("client_capability_flags=%lu", client_capabilities);
1097 DBG_INF_FMT("CLIENT_LONG_PASSWORD= %d", client_capabilities & CLIENT_LONG_PASSWORD? 1:0);
1098 DBG_INF_FMT("CLIENT_FOUND_ROWS= %d", client_capabilities & CLIENT_FOUND_ROWS? 1:0);
1099 DBG_INF_FMT("CLIENT_LONG_FLAG= %d", client_capabilities & CLIENT_LONG_FLAG? 1:0);
1100 DBG_INF_FMT("CLIENT_NO_SCHEMA= %d", client_capabilities & CLIENT_NO_SCHEMA? 1:0);
1101 DBG_INF_FMT("CLIENT_COMPRESS= %d", client_capabilities & CLIENT_COMPRESS? 1:0);
1102 DBG_INF_FMT("CLIENT_ODBC= %d", client_capabilities & CLIENT_ODBC? 1:0);
1103 DBG_INF_FMT("CLIENT_LOCAL_FILES= %d", client_capabilities & CLIENT_LOCAL_FILES? 1:0);
1104 DBG_INF_FMT("CLIENT_IGNORE_SPACE= %d", client_capabilities & CLIENT_IGNORE_SPACE? 1:0);
1105 DBG_INF_FMT("CLIENT_PROTOCOL_41= %d", client_capabilities & CLIENT_PROTOCOL_41? 1:0);
1106 DBG_INF_FMT("CLIENT_INTERACTIVE= %d", client_capabilities & CLIENT_INTERACTIVE? 1:0);
1107 DBG_INF_FMT("CLIENT_SSL= %d", client_capabilities & CLIENT_SSL? 1:0);
1108 DBG_INF_FMT("CLIENT_IGNORE_SIGPIPE= %d", client_capabilities & CLIENT_IGNORE_SIGPIPE? 1:0);
1109 DBG_INF_FMT("CLIENT_TRANSACTIONS= %d", client_capabilities & CLIENT_TRANSACTIONS? 1:0);
1110 DBG_INF_FMT("CLIENT_RESERVED= %d", client_capabilities & CLIENT_RESERVED? 1:0);
1111 DBG_INF_FMT("CLIENT_SECURE_CONNECTION=%d", client_capabilities & CLIENT_SECURE_CONNECTION? 1:0);
1112 DBG_INF_FMT("CLIENT_MULTI_STATEMENTS=%d", client_capabilities & CLIENT_MULTI_STATEMENTS? 1:0);
1113 DBG_INF_FMT("CLIENT_MULTI_RESULTS= %d", client_capabilities & CLIENT_MULTI_RESULTS? 1:0);
1114 DBG_INF_FMT("CLIENT_PS_MULTI_RESULTS=%d", client_capabilities & CLIENT_PS_MULTI_RESULTS? 1:0);
1115 DBG_INF_FMT("CLIENT_CONNECT_ATTRS= %d", client_capabilities & CLIENT_PLUGIN_AUTH? 1:0);
1116 DBG_INF_FMT("CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA= %d", client_capabilities & CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA? 1:0);
1117 DBG_INF_FMT("CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS= %d", client_capabilities & CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS? 1:0);
1118 DBG_INF_FMT("CLIENT_SESSION_TRACK= %d", client_capabilities & CLIENT_SESSION_TRACK? 1:0);
1119 DBG_INF_FMT("CLIENT_SSL_VERIFY_SERVER_CERT= %d", client_capabilities & CLIENT_SSL_VERIFY_SERVER_CERT? 1:0);
1120 DBG_INF_FMT("CLIENT_REMEMBER_OPTIONS= %d", client_capabilities & CLIENT_REMEMBER_OPTIONS? 1:0);
1121
1122 conn->payload_decoder_factory->m.init_auth_packet(&auth_packet);
1123 auth_packet.client_flags = client_capabilities;
1124 auth_packet.max_packet_size = MYSQLND_ASSEMBLED_PACKET_MAX_SIZE;
1125
1126 auth_packet.charset_no = command->context.charset_no;
1127
1128 #ifdef MYSQLND_SSL_SUPPORTED
1129 if (client_capabilities & CLIENT_SSL) {
1130 const zend_bool server_has_ssl = (server_capabilities & CLIENT_SSL)? TRUE:FALSE;
1131 if (server_has_ssl == FALSE) {
1132 goto close_conn;
1133 } else {
1134 enum mysqlnd_ssl_peer verify = client_capabilities & CLIENT_SSL_VERIFY_SERVER_CERT?
1135 MYSQLND_SSL_PEER_VERIFY:
1136 (client_capabilities & CLIENT_SSL_DONT_VERIFY_SERVER_CERT?
1137 MYSQLND_SSL_PEER_DONT_VERIFY:
1138 MYSQLND_SSL_PEER_DEFAULT);
1139 DBG_INF("Switching to SSL");
1140 if (!PACKET_WRITE(conn, &auth_packet)) {
1141 goto close_conn;
1142 }
1143
1144 conn->vio->data->m.set_client_option(conn->vio, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, (const char *) &verify);
1145
1146 if (FAIL == conn->vio->data->m.enable_ssl(conn->vio)) {
1147 goto end;
1148 }
1149 }
1150 }
1151 #else
1152 auth_packet.client_flags &= ~CLIENT_SSL;
1153 if (!PACKET_WRITE(conn, &auth_packet)) {
1154 goto close_conn;
1155 }
1156 #endif
1157 ret = PASS;
1158 end:
1159 PACKET_FREE(&auth_packet);
1160 DBG_RETURN(ret);
1161
1162 close_conn:
1163 SET_CONNECTION_STATE(&conn->state, CONN_QUIT_SENT);
1164 conn->m->send_close(conn);
1165 SET_CLIENT_ERROR(conn->error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone);
1166 PACKET_FREE(&auth_packet);
1167 DBG_RETURN(ret);
1168 }
1169 /* }}} */
1170
1171
1172 /* {{{ mysqlnd_com_enable_ssl_run_command */
1173 static enum_func_status
mysqlnd_com_enable_ssl_run_command(va_list args)1174 mysqlnd_com_enable_ssl_run_command(va_list args)
1175 {
1176 struct st_mysqlnd_protocol_com_enable_ssl_command command;
1177 enum_func_status ret;
1178
1179 DBG_ENTER("mysqlnd_com_enable_ssl_run_command");
1180 command.context.conn = va_arg(args, MYSQLND_CONN_DATA *);
1181 command.context.client_capabilities = va_arg(args, size_t);
1182 command.context.server_capabilities = va_arg(args, size_t);
1183 command.context.charset_no = va_arg(args, unsigned int);
1184
1185 ret = mysqlnd_com_enable_ssl_run(&command);
1186
1187 DBG_RETURN(ret);
1188 }
1189 /* }}} */
1190
1191 /************************** COM_READ_HANDSHAKE ******************************************/
1192 struct st_mysqlnd_protocol_com_handshake_command
1193 {
1194 struct st_mysqlnd_com_handshake_context
1195 {
1196 MYSQLND_CONN_DATA * conn;
1197 MYSQLND_CSTRING user;
1198 MYSQLND_CSTRING passwd;
1199 MYSQLND_CSTRING database;
1200 size_t client_flags;
1201 } context;
1202 };
1203
1204
1205 /* {{{ mysqlnd_com_handshake_run */
1206 static enum_func_status
mysqlnd_com_handshake_run(void * cmd)1207 mysqlnd_com_handshake_run(void *cmd)
1208 {
1209 struct st_mysqlnd_protocol_com_handshake_command * command = (struct st_mysqlnd_protocol_com_handshake_command *) cmd;
1210 const char * user = command->context.user.s;
1211
1212 const char * passwd = command->context.passwd.s;
1213 size_t passwd_len = command->context.passwd.l;
1214
1215 const char * db = command->context.database.s;
1216 size_t db_len = command->context.database.l;
1217
1218 size_t mysql_flags = command->context.client_flags;
1219
1220 MYSQLND_CONN_DATA * conn = command->context.conn;
1221 MYSQLND_PACKET_GREET greet_packet;
1222
1223 DBG_ENTER("mysqlnd_conn_data::connect_handshake");
1224 DBG_INF_FMT("stream=%p", conn->vio->data->m.get_stream(conn->vio));
1225 DBG_INF_FMT("[user=%s] [db=%s:%d] [flags=%llu]", user, db, db_len, mysql_flags);
1226
1227 conn->payload_decoder_factory->m.init_greet_packet(&greet_packet);
1228
1229 if (FAIL == PACKET_READ(conn, &greet_packet)) {
1230 DBG_ERR("Error while reading greeting packet");
1231 php_error_docref(NULL, E_WARNING, "Error while reading greeting packet. PID=%d", getpid());
1232 goto err;
1233 } else if (greet_packet.error_no) {
1234 DBG_ERR_FMT("errorno=%u error=%s", greet_packet.error_no, greet_packet.error);
1235 SET_CLIENT_ERROR(conn->error_info, greet_packet.error_no, greet_packet.sqlstate, greet_packet.error);
1236 goto err;
1237 } else if (greet_packet.pre41) {
1238 DBG_ERR_FMT("Connecting to 3.22, 3.23 & 4.0 is not supported. Server is %-.32s", greet_packet.server_version);
1239 php_error_docref(NULL, E_WARNING, "Connecting to 3.22, 3.23 & 4.0 "
1240 " is not supported. Server is %-.32s", greet_packet.server_version);
1241 SET_CLIENT_ERROR(conn->error_info, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE,
1242 "Connecting to 3.22, 3.23 & 4.0 servers is not supported");
1243 goto err;
1244 }
1245
1246 conn->thread_id = greet_packet.thread_id;
1247 conn->protocol_version = greet_packet.protocol_version;
1248 conn->server_version = mnd_pestrdup(greet_packet.server_version, conn->persistent);
1249
1250 conn->greet_charset = mysqlnd_find_charset_nr(greet_packet.charset_no);
1251 if (!conn->greet_charset) {
1252 php_error_docref(NULL, E_WARNING,
1253 "Server sent charset (%d) unknown to the client. Please, report to the developers", greet_packet.charset_no);
1254 SET_CLIENT_ERROR(conn->error_info, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE,
1255 "Server sent charset unknown to the client. Please, report to the developers");
1256 goto err;
1257 }
1258
1259 conn->server_capabilities = greet_packet.server_capabilities;
1260
1261 if (FAIL == mysqlnd_connect_run_authentication(conn, user, passwd, db, db_len, (size_t) passwd_len,
1262 greet_packet.authentication_plugin_data, greet_packet.auth_protocol,
1263 greet_packet.charset_no, greet_packet.server_capabilities,
1264 conn->options, mysql_flags))
1265 {
1266 goto err;
1267 }
1268
1269 UPSERT_STATUS_RESET(conn->upsert_status);
1270 UPSERT_STATUS_SET_SERVER_STATUS(conn->upsert_status, greet_packet.server_status);
1271
1272 PACKET_FREE(&greet_packet);
1273 DBG_RETURN(PASS);
1274 err:
1275 conn->server_capabilities = 0;
1276 PACKET_FREE(&greet_packet);
1277 DBG_RETURN(FAIL);
1278 }
1279 /* }}} */
1280
1281
1282 /* {{{ mysqlnd_com_handshake_run_command */
1283 static enum_func_status
mysqlnd_com_handshake_run_command(va_list args)1284 mysqlnd_com_handshake_run_command(va_list args)
1285 {
1286 struct st_mysqlnd_protocol_com_handshake_command command;
1287 enum_func_status ret;
1288
1289 DBG_ENTER("mysqlnd_com_handshake_run_command");
1290 command.context.conn = va_arg(args, MYSQLND_CONN_DATA *);
1291 command.context.user = *va_arg(args, const MYSQLND_CSTRING *);
1292 command.context.passwd = *va_arg(args, const MYSQLND_CSTRING *);
1293 command.context.database = *va_arg(args, const MYSQLND_CSTRING *);
1294 command.context.client_flags = va_arg(args, size_t);
1295
1296 ret = mysqlnd_com_handshake_run(&command);
1297
1298 DBG_RETURN(ret);
1299 }
1300 /* }}} */
1301
1302
1303
1304 /* {{{ _mysqlnd_run_command */
1305 static enum_func_status
_mysqlnd_run_command(enum php_mysqlnd_server_command command,...)1306 _mysqlnd_run_command(enum php_mysqlnd_server_command command, ...)
1307 {
1308 enum_func_status ret = FAIL;
1309 va_list args;
1310 DBG_ENTER("_mysqlnd_run_command");
1311
1312 va_start(args, command);
1313 switch (command) {
1314 case COM_SET_OPTION:
1315 ret = mysqlnd_com_set_option_run_command(args);
1316 break;
1317 case COM_DEBUG:
1318 ret = mysqlnd_com_debug_run_command(args);
1319 break;
1320 case COM_INIT_DB:
1321 ret = mysqlnd_com_init_db_run_command(args);
1322 break;
1323 case COM_PING:
1324 ret = mysqlnd_com_ping_run_command(args);
1325 break;
1326 case COM_STATISTICS:
1327 ret = mysqlnd_com_statistics_run_command(args);
1328 break;
1329 case COM_PROCESS_KILL:
1330 ret = mysqlnd_com_process_kill_run_command(args);
1331 break;
1332 case COM_REFRESH:
1333 ret = mysqlnd_com_refresh_run_command(args);
1334 break;
1335 case COM_SHUTDOWN:
1336 ret = mysqlnd_com_shutdown_run_command(args);
1337 break;
1338 case COM_QUIT:
1339 ret = mysqlnd_com_quit_run_command(args);
1340 break;
1341 case COM_QUERY:
1342 ret = mysqlnd_com_query_run_command(args);
1343 break;
1344 case COM_REAP_RESULT:
1345 ret = mysqlnd_com_reap_result_run_command(args);
1346 break;
1347 case COM_CHANGE_USER:
1348 ret = mysqlnd_com_change_user_run_command(args);
1349 break;
1350 case COM_STMT_PREPARE:
1351 ret = mysqlnd_com_stmt_prepare_run_command(args);
1352 break;
1353 case COM_STMT_EXECUTE:
1354 ret = mysqlnd_com_stmt_execute_run_command(args);
1355 break;
1356 case COM_STMT_FETCH:
1357 ret = mysqlnd_com_stmt_fetch_run_command(args);
1358 break;
1359 case COM_STMT_RESET:
1360 ret = mysqlnd_com_stmt_reset_run_command(args);
1361 break;
1362 case COM_STMT_SEND_LONG_DATA:
1363 ret = mysqlnd_com_stmt_send_long_data_run_command(args);
1364 break;
1365 case COM_STMT_CLOSE:
1366 ret = mysqlnd_com_stmt_close_run_command(args);
1367 break;
1368 case COM_ENABLE_SSL:
1369 ret = mysqlnd_com_enable_ssl_run_command(args);
1370 break;
1371 case COM_HANDSHAKE:
1372 ret = mysqlnd_com_handshake_run_command(args);
1373 break;
1374 default:
1375 break;
1376 }
1377 va_end(args);
1378 DBG_RETURN(ret);
1379 }
1380 /* }}} */
1381
1382 func_mysqlnd__run_command mysqlnd_run_command = _mysqlnd_run_command;
1383
1384 /*
1385 * Local variables:
1386 * tab-width: 4
1387 * c-basic-offset: 4
1388 * End:
1389 * vim600: noet sw=4 ts=4 fdm=marker
1390 * vim<600: noet sw=4 ts=4
1391 */
1392