ret = mysqlnd_switch_to_ssl_if_needed(conn, greet_packet, options, mysql_flags TSRMLS_CC);
if (PASS == ret) {
- zend_bool first_call = TRUE;
+ ret = mysqlnd_run_authentication(conn, user, passwd, passwd_len, db, db_len,
+ greet_packet->auth_plugin_data, greet_packet->auth_plugin_data_len, greet_packet->auth_protocol,
+ greet_packet->charset_no, options, mysql_flags, FALSE /*silent*/, FALSE/*is_change*/ TSRMLS_CC);
+ }
+ DBG_RETURN(ret);
+}
+/* }}} */
- char * switch_to_auth_protocol = NULL;
- size_t switch_to_auth_protocol_len = 0;
- char * requested_protocol = NULL;
- zend_uchar * plugin_data;
- size_t plugin_data_len;
- plugin_data_len = greet_packet->auth_plugin_data_len;
- plugin_data = mnd_emalloc(plugin_data_len + 1);
- if (!plugin_data) {
- ret = FAIL;
- goto end;
- }
- memcpy(plugin_data, greet_packet->auth_plugin_data, plugin_data_len);
- plugin_data[plugin_data_len] = '\0';
+/* {{{ mysqlnd_conn_data::execute_init_commands */
+static enum_func_status
+MYSQLND_METHOD(mysqlnd_conn_data, execute_init_commands)(MYSQLND_CONN_DATA * conn TSRMLS_DC)
+{
+ enum_func_status ret = PASS;
- requested_protocol = mnd_pestrdup(greet_packet->auth_protocol? greet_packet->auth_protocol: "mysql_native_password", FALSE);
- if (!requested_protocol) {
- ret = FAIL;
- goto end;
+ DBG_ENTER("mysqlnd_conn_data::execute_init_commands");
+ if (conn->options->init_commands) {
+ unsigned int current_command = 0;
+ for (; current_command < conn->options->num_commands; ++current_command) {
+ const char * const command = conn->options->init_commands[current_command];
+ if (command) {
+ MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_INIT_COMMAND_EXECUTED_COUNT);
+ if (PASS != conn->m->query(conn, command, strlen(command) TSRMLS_CC)) {
+ MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_INIT_COMMAND_FAILED_COUNT);
+ ret = FAIL;
+ break;
+ }
+ if (conn->last_query_type == QUERY_SELECT) {
+ MYSQLND_RES * result = conn->m->use_result(conn TSRMLS_CC);
+ if (result) {
+ result->m.free_result(result, TRUE TSRMLS_CC);
+ }
+ }
+ }
}
+ }
+ DBG_RETURN(ret);
+}
+/* }}} */
- do {
- struct st_mysqlnd_authentication_plugin * auth_plugin;
- {
- char * plugin_name = NULL;
- mnd_sprintf(&plugin_name, 0, "auth_plugin_%s", requested_protocol);
+/* {{{ mysqlnd_conn_data::get_updated_connect_flags */
+static unsigned int
+MYSQLND_METHOD(mysqlnd_conn_data, get_updated_connect_flags)(MYSQLND_CONN_DATA * conn, unsigned int mysql_flags TSRMLS_DC)
+{
+ MYSQLND_NET * net = conn->net;
- DBG_INF_FMT("looking for %s auth plugin", plugin_name);
- auth_plugin = mysqlnd_plugin_find(plugin_name);
- mnd_sprintf_free(plugin_name);
+ DBG_ENTER("mysqlnd_conn_data::get_updated_connect_flags");
+ /* we allow load data local infile by default */
+ mysql_flags |= MYSQLND_CAPABILITIES;
- if (!auth_plugin) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "The server requested authentication method unknown to the client [%s]", requested_protocol);
- SET_CLIENT_ERROR(*conn->error_info, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE, "The server requested authentication method umknown to the client");
- break;
- }
- }
- DBG_INF("plugin found");
++ mysql_flags |= conn->options.flags; /* use the flags from set_client_option() */
+
- {
- zend_uchar * switch_to_auth_protocol_data = NULL;
- size_t switch_to_auth_protocol_data_len = 0;
- zend_uchar * scrambled_data = NULL;
- size_t scrambled_data_len = 0;
+ if (PG(open_basedir) && strlen(PG(open_basedir))) {
+ mysql_flags ^= CLIENT_LOCAL_FILES;
+ }
+
+#ifndef MYSQLND_COMPRESSION_ENABLED
+ if (mysql_flags & CLIENT_COMPRESS) {
+ mysql_flags &= ~CLIENT_COMPRESS;
+ }
+#else
+ if (net && net->data->options.flags & MYSQLND_NET_FLAG_USE_COMPRESSION) {
+ mysql_flags |= CLIENT_COMPRESS;
+ }
+#endif
+#ifndef MYSQLND_SSL_SUPPORTED
+ if (mysql_flags & CLIENT_SSL) {
+ mysql_flags &= ~CLIENT_SSL;
+ }
+#else
+ if (net && (net->data->options.ssl_key || net->data->options.ssl_cert ||
+ net->data->options.ssl_ca || net->data->options.ssl_capath || net->data->options.ssl_cipher))
+ {
+ mysql_flags |= CLIENT_SSL;
+ }
+#endif
- switch_to_auth_protocol = NULL;
- switch_to_auth_protocol_len = 0;
+ DBG_RETURN(mysql_flags);
+}
+/* }}} */
- if (conn->auth_plugin_data) {
- mnd_pefree(conn->auth_plugin_data, conn->persistent);
- conn->auth_plugin_data = NULL;
- }
- conn->auth_plugin_data_len = plugin_data_len;
- conn->auth_plugin_data = mnd_pemalloc(conn->auth_plugin_data_len, conn->persistent);
- if (!conn->auth_plugin_data) {
- SET_OOM_ERROR(*conn->error_info);
- goto end;
- }
- memcpy(conn->auth_plugin_data, plugin_data, plugin_data_len);
- DBG_INF_FMT("salt=[%*s]", plugin_data_len - 1, plugin_data);
- /* The data should be allocated with malloc() */
- scrambled_data =
- auth_plugin->methods.get_auth_data(NULL, &scrambled_data_len, conn, user, passwd, passwd_len,
- plugin_data, plugin_data_len, options, mysql_flags TSRMLS_CC);
+/* {{{ mysqlnd_conn_data::connect_handshake */
+static enum_func_status
+MYSQLND_METHOD(mysqlnd_conn_data, connect_handshake)(MYSQLND_CONN_DATA * conn,
+ const char * const host, const char * const user,
+ const char * const passwd, const unsigned int passwd_len,
+ const char * const db, const unsigned int db_len,
+ const unsigned int mysql_flags TSRMLS_DC)
+{
+ MYSQLND_PACKET_GREET * greet_packet;
+ MYSQLND_NET * net = conn->net;
+ DBG_ENTER("mysqlnd_conn_data::connect_handshake");
- ret = mysqlnd_auth_handshake(conn, user, passwd, passwd_len, db, db_len, options, mysql_flags,
- greet_packet->charset_no,
- first_call,
- requested_protocol,
- scrambled_data, scrambled_data_len,
- &switch_to_auth_protocol, &switch_to_auth_protocol_len,
- &switch_to_auth_protocol_data, &switch_to_auth_protocol_data_len
- TSRMLS_CC);
- first_call = FALSE;
- free(scrambled_data);
+ greet_packet = conn->protocol->m.get_greet_packet(conn->protocol, FALSE TSRMLS_CC);
+ if (!greet_packet) {
+ SET_OOM_ERROR(*conn->error_info);
+ DBG_RETURN(FAIL); /* OOM */
+ }
- DBG_INF_FMT("switch_to_auth_protocol=%s", switch_to_auth_protocol? switch_to_auth_protocol:"n/a");
- if (requested_protocol && switch_to_auth_protocol) {
- mnd_efree(requested_protocol);
- requested_protocol = switch_to_auth_protocol;
- }
+ if (FAIL == net->data->m.connect_ex(conn->net, conn->scheme, conn->scheme_len, conn->persistent,
+ conn->stats, conn->error_info TSRMLS_CC))
+ {
+ goto err;
+ }
- if (plugin_data) {
- mnd_efree(plugin_data);
- }
- plugin_data_len = switch_to_auth_protocol_data_len;
- plugin_data = switch_to_auth_protocol_data;
- }
- DBG_INF_FMT("conn->error_info->error_no = %d", conn->error_info->error_no);
- } while (ret == FAIL && conn->error_info->error_no == 0 && switch_to_auth_protocol != NULL);
- if (plugin_data) {
- mnd_efree(plugin_data);
- }
-
- if (ret == PASS) {
- DBG_INF_FMT("saving requested_protocol=%s", requested_protocol);
- conn->m->set_client_option(conn, MYSQLND_OPT_AUTH_PROTOCOL, requested_protocol TSRMLS_CC);
- }
+ DBG_INF_FMT("stream=%p", net->data->m.get_stream(net TSRMLS_CC));
- if (requested_protocol) {
- mnd_efree(requested_protocol);
- }
+ if (FAIL == PACKET_READ(greet_packet, conn)) {
+ DBG_ERR("Error while reading greeting packet");
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error while reading greeting packet. PID=%d", getpid());
+ goto err;
+ } else if (greet_packet->error_no) {
+ DBG_ERR_FMT("errorno=%u error=%s", greet_packet->error_no, greet_packet->error);
+ SET_CLIENT_ERROR(*conn->error_info, greet_packet->error_no, greet_packet->sqlstate, greet_packet->error);
+ goto err;
+ } else if (greet_packet->pre41) {
+ DBG_ERR_FMT("Connecting to 3.22, 3.23 & 4.0 is not supported. Server is %-.32s", greet_packet->server_version);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Connecting to 3.22, 3.23 & 4.0 "
+ " is not supported. Server is %-.32s", greet_packet->server_version);
+ SET_CLIENT_ERROR(*conn->error_info, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE,
+ "Connecting to 3.22, 3.23 & 4.0 servers is not supported");
+ goto err;
}
-end:
- DBG_RETURN(ret);
+
+ conn->thread_id = greet_packet->thread_id;
+ conn->protocol_version = greet_packet->protocol_version;
+ conn->server_version = mnd_pestrdup(greet_packet->server_version, conn->persistent);
+
+ conn->greet_charset = mysqlnd_find_charset_nr(greet_packet->charset_no);
+ if (!conn->greet_charset) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ "Server sent charset (%d) unknown to the client. Please, report to the developers", greet_packet->charset_no);
+ SET_CLIENT_ERROR(*conn->error_info, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE,
+ "Server sent charset unknown to the client. Please, report to the developers");
+ goto err;
+ }
+
+ if (FAIL == mysqlnd_connect_run_authentication(conn, user, passwd, db, db_len, (size_t) passwd_len,
+ greet_packet, conn->options, mysql_flags TSRMLS_CC))
+ {
+ goto err;
+ }
+ conn->client_flag = mysql_flags;
+ conn->server_capabilities = greet_packet->server_capabilities;
+ conn->upsert_status->warning_count = 0;
+ conn->upsert_status->server_status = greet_packet->server_status;
+ conn->upsert_status->affected_rows = 0;
+
+ PACKET_FREE(greet_packet);
+ DBG_RETURN(PASS);
+err:
+ PACKET_FREE(greet_packet);
+ DBG_RETURN(FAIL);
}
/* }}} */