diff --git a/include/ClickHouse_Authentication.hpp b/include/ClickHouse_Authentication.hpp index 31d396515..62b9a31c3 100644 --- a/include/ClickHouse_Authentication.hpp +++ b/include/ClickHouse_Authentication.hpp @@ -67,6 +67,7 @@ class ClickHouse_Authentication { bool set_lock = true); bool reset(); void print_version(); + bool exists(char *username); char *lookup(char *username, enum cred_username_type usertype, bool *use_ssl, int *default_hostgroup, char **default_schema, bool *schema_locked, bool *transaction_persistent, diff --git a/include/MySQL_Authentication.hpp b/include/MySQL_Authentication.hpp index d8dd5cb25..dfb0523b0 100644 --- a/include/MySQL_Authentication.hpp +++ b/include/MySQL_Authentication.hpp @@ -65,6 +65,7 @@ class MySQL_Authentication { bool del(char *username, enum cred_username_type usertype, bool set_lock=true); bool reset(); void print_version(); + bool exists(char *username); char * lookup(char *username, enum cred_username_type usertype, bool *use_ssl, int *default_hostgroup, char **default_schema, bool *schema_locked, bool *transaction_persistent, bool *fast_forward, int *max_connections, void **sha1_pass); int dump_all_users(account_details_t ***, bool _complete=true); int increase_frontend_user_connections(char *username, int *mc=NULL); diff --git a/include/MySQL_Data_Stream.h b/include/MySQL_Data_Stream.h index f0ed5a5a1..d0bb7d7c0 100644 --- a/include/MySQL_Data_Stream.h +++ b/include/MySQL_Data_Stream.h @@ -128,6 +128,10 @@ class MySQL_Data_Stream int active; // data stream is active. If not, shutdown+close needs to be called int status; // status . FIXME: make it a ORable variable + int switching_auth_stage; + int switching_auth_type; + uint8_t tmp_charset; + short revents; char kill_type; diff --git a/include/MySQL_Thread.h b/include/MySQL_Thread.h index fd494bcd7..6b08175ef 100644 --- a/include/MySQL_Thread.h +++ b/include/MySQL_Thread.h @@ -418,6 +418,7 @@ class MySQL_Threads_Handler int hostgroup_manager_verbose; int binlog_reader_connect_retry_msec; char *init_connect; + char *add_ldap_user_comment; char *default_sql_mode; char *default_time_zone; #ifdef DEBUG diff --git a/include/proxysql_structs.h b/include/proxysql_structs.h index 992070e8a..c390b6934 100644 --- a/include/proxysql_structs.h +++ b/include/proxysql_structs.h @@ -693,6 +693,8 @@ __thread char * mysql_thread___monitor_username; __thread char * mysql_thread___monitor_password; __thread char * mysql_thread___monitor_replication_lag_use_percona_heartbeat; +__thread char * mysql_thread___add_ldap_user_comment; + #ifdef DEBUG __thread bool mysql_thread___session_debug; #endif /* DEBUG */ @@ -809,6 +811,8 @@ extern __thread char * mysql_thread___monitor_username; extern __thread char * mysql_thread___monitor_password; extern __thread char * mysql_thread___monitor_replication_lag_use_percona_heartbeat; +extern __thread char * mysql_thread___add_ldap_user_comment; + #ifdef DEBUG extern __thread bool mysql_thread___session_debug; #endif /* DEBUG */ diff --git a/lib/ClickHouse_Authentication.cpp b/lib/ClickHouse_Authentication.cpp index 0b8c18462..e127ce72c 100644 --- a/lib/ClickHouse_Authentication.cpp +++ b/lib/ClickHouse_Authentication.cpp @@ -353,6 +353,25 @@ bool ClickHouse_Authentication::set_SHA1(char * username, enum cred_username_typ return ret; }; +bool ClickHouse_Authentication::exists(char * username) { + bool ret = false; + uint64_t hash1, hash2; + SpookyHash myhash; + myhash.Init(1,2); + myhash.Update(username,strlen(username)); + myhash.Final(&hash1,&hash2); + + creds_group_t &cg = creds_frontends ; + pthread_rwlock_rdlock(&cg.lock); + std::map::iterator lookup; + lookup = cg.bt_map.find(hash1); + if (lookup != cg.bt_map.end()) { + ret = true; + } + pthread_rwlock_unlock(&cg.lock); + return ret; +} + char * ClickHouse_Authentication::lookup(char * username, enum cred_username_type usertype, bool *use_ssl, int *default_hostgroup, char **default_schema, bool *schema_locked, bool *transaction_persistent, bool *fast_forward, int *max_connections, void **sha1_pass) { char *ret=NULL; uint64_t hash1, hash2; diff --git a/lib/MySQL_Authentication.cpp b/lib/MySQL_Authentication.cpp index cfdb4fac6..fd75a3337 100644 --- a/lib/MySQL_Authentication.cpp +++ b/lib/MySQL_Authentication.cpp @@ -406,6 +406,25 @@ bool MySQL_Authentication::set_SHA1(char * username, enum cred_username_type use return ret; }; +bool MySQL_Authentication::exists(char * username) { + bool ret = false; + uint64_t hash1, hash2; + SpookyHash myhash; + myhash.Init(1,2); + myhash.Update(username,strlen(username)); + myhash.Final(&hash1,&hash2); + + creds_group_t &cg = creds_frontends ; + pthread_rwlock_rdlock(&cg.lock); + std::map::iterator lookup; + lookup = cg.bt_map.find(hash1); + if (lookup != cg.bt_map.end()) { + ret = true; + } + pthread_rwlock_unlock(&cg.lock); + return ret; +} + char * MySQL_Authentication::lookup(char * username, enum cred_username_type usertype, bool *use_ssl, int *default_hostgroup, char **default_schema, bool *schema_locked, bool *transaction_persistent, bool *fast_forward, int *max_connections, void **sha1_pass) { char *ret=NULL; uint64_t hash1, hash2; diff --git a/lib/MySQL_Protocol.cpp b/lib/MySQL_Protocol.cpp index 7a54c96bb..b77740a49 100644 --- a/lib/MySQL_Protocol.cpp +++ b/lib/MySQL_Protocol.cpp @@ -21,6 +21,9 @@ typedef uint8_t uchar; //#define RESULTSET_BUFLEN 16300 +#ifndef CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA +#define CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA 0x00200000 +#endif #ifdef DEBUG static void __dump_pkt(const char *func, unsigned char *_ptr, unsigned int len) { @@ -994,11 +997,28 @@ uint8_t MySQL_Protocol::generate_pkt_row3(MySQL_ResultSet *myrs, unsigned int *l bool MySQL_Protocol::generate_pkt_auth_switch_request(bool send, void **ptr, unsigned int *len) { proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 7, "Generating auth switch request pkt\n"); mysql_hdr myhdr; - myhdr.pkt_id=1; - myhdr.pkt_length=1 // fe - + (strlen("mysql_native_password")+1) - + 20 // scramble - + 1; // 00 + myhdr.pkt_id=2; + if ((*myds)->encrypted) { + myhdr.pkt_id++; + } + + switch((*myds)->switching_auth_type) { + case 1: + myhdr.pkt_length=1 // fe + + (strlen("mysql_native_password")+1) + + 20 // scramble + + 1; // 00 + break; + case 2: + myhdr.pkt_length=1 // fe + + (strlen("mysql_clear_password")+1) + + 1; // 00 + break; + default: + assert(0); + break; + } + unsigned int size=myhdr.pkt_length+sizeof(mysql_hdr); unsigned char *_ptr=(unsigned char *)malloc(size); memset(_ptr,0,size); @@ -1007,10 +1027,22 @@ bool MySQL_Protocol::generate_pkt_auth_switch_request(bool send, void **ptr, uns l=sizeof(mysql_hdr); _ptr[l]=0xfe; l++; //0xfe - memcpy(_ptr+l,"mysql_native_password",strlen("mysql_native_password")); - l+=strlen("mysql_native_password"); - _ptr[l]=0x00; l++; - memcpy(_ptr+l, (*myds)->myconn->scramble_buff+0, 20); l+=20; + switch((*myds)->switching_auth_type) { + case 1: + memcpy(_ptr+l,"mysql_native_password",strlen("mysql_native_password")); + l+=strlen("mysql_native_password"); + _ptr[l]=0x00; l++; + memcpy(_ptr+l, (*myds)->myconn->scramble_buff+0, 20); l+=20; + break; + case 2: + memcpy(_ptr+l,"mysql_clear_password",strlen("mysql_clear_password")); + l+=strlen("mysql_clear_password"); + _ptr[l]=0x00; l++; + break; + default: + assert(0); + break; + } _ptr[l]=0x00; //l+=1; //0x00 if (send==true) { (*myds)->PSarrayOUT->add((void *)_ptr,size); @@ -1393,23 +1425,40 @@ bool MySQL_Protocol::process_pkt_handshake_response(unsigned char *pkt, unsigned memcpy(&hdr,pkt,sizeof(mysql_hdr)); //Copy4B(&hdr,pkt); pkt += sizeof(mysql_hdr); + + if ((*myds)->myconn->userinfo->username) { + pass_len=strlen((char *)pkt); + pass = (unsigned char *)malloc(pass_len+1); + memcpy(pass, pkt, pass_len); + pass[pass_len] = 0; + user = (unsigned char *)(*myds)->myconn->userinfo->username; + db = (*myds)->myconn->userinfo->schemaname; + (*myds)->switching_auth_stage=2; + auth_plugin_id = (*myds)->switching_auth_type; + charset=(*myds)->tmp_charset; + proxy_debug(PROXY_DEBUG_MYSQL_PROTOCOL,2,"Encrypted: %d , switching_auth: %d, auth_plugin_id: %d\n", (*myds)->encrypted, (*myds)->switching_auth_stage, auth_plugin_id); + goto __do_auth; + } + capabilities = CPY4(pkt); (*myds)->myconn->options.client_flag = capabilities; pkt += sizeof(uint32_t); max_pkt = CPY4(pkt); pkt += sizeof(uint32_t); charset = *(uint8_t *)pkt; - // see bug #810 if ( (*myds)->encrypted == false ) { // client wants to use SSL if (len == sizeof(mysql_hdr)+32) { (*myds)->encrypted = true; use_ssl = true; - return false; + ret = false; + goto __exit_process_pkt_handshake_response; } } + // see bug #810 if (charset==0) { charset=mysql_thread___default_charset; } + (*myds)->tmp_charset=charset; pkt += 24; // if (len==sizeof(mysql_hdr)+32) { // (*myds)->encrypted=true; @@ -1418,10 +1467,21 @@ bool MySQL_Protocol::process_pkt_handshake_response(unsigned char *pkt, unsigned user = pkt; pkt += strlen((char *)user) + 1; - pass_len = (capabilities & CLIENT_SECURE_CONNECTION ? *pkt++ : strlen((char *)pkt)); - if (pass_len > (len - (pkt - _ptr))) { - ret = false; - goto __exit_process_pkt_handshake_response; + if (capabilities & CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA) { + uint64_t passlen64; + int pass_len_enc=mysql_decode_length(pkt,&passlen64); + pass_len = passlen64; + pkt += pass_len_enc; + if (pass_len > (len - (pkt - _ptr))) { + ret = false; + goto __exit_process_pkt_handshake_response; + } + } else { + pass_len = (capabilities & CLIENT_SECURE_CONNECTION ? *pkt++ : strlen((char *)pkt)); + if (pass_len > (len - (pkt - _ptr))) { + ret = false; + goto __exit_process_pkt_handshake_response; + } } pass = (unsigned char *)malloc(pass_len+1); memcpy(pass, pkt, pass_len); @@ -1464,8 +1524,68 @@ bool MySQL_Protocol::process_pkt_handshake_response(unsigned char *pkt, unsigned auth_plugin_id = 2; } } +__switch_auth_plugin: + if (auth_plugin_id == 0) { + if ((*myds)->switching_auth_stage == 0) { + (*myds)->switching_auth_stage = 1; + // check if user exists + bool user_exists = true; + if (GloMyLdapAuth) { // we check if user exists only if GloMyLdapAuth is enabled +#ifdef PROXYSQLCLICKHOUSE + if (session_type == PROXYSQL_SESSION_CLICKHOUSE) { + user_exists = GloClickHouseAuth->exists((char *)user); + // for clickhouse, we currently do not support clear text or LDAP + user_exists = true; + } else { +#endif /* PROXYSQLCLICKHOUSE */ + user_exists = GloMyAuth->exists((char *)user); + //password=GloMyAuth->lookup((char *)user, USERNAME_FRONTEND, &_ret_use_ssl, &default_hostgroup, &default_schema, &schema_locked, &transaction_persistent, &fast_forward, &max_connections, &sha1_pass); +#ifdef PROXYSQLCLICKHOUSE + } +#endif /* PROXYSQLCLICKHOUSE */ + } + if (user_exists) { + (*myds)->switching_auth_type = 1; // mysql_native_password + } else { + (*myds)->switching_auth_type = 2; // mysql_clear_password + } + generate_pkt_auth_switch_request(true, NULL, NULL); + (*myds)->myconn->userinfo->set((char *)user, NULL, db, NULL); + ret = false; + goto __exit_process_pkt_handshake_response; + } + } else { + if (auth_plugin_id == 1) { + if (GloMyLdapAuth) { + if ((*myds)->switching_auth_stage == 0) { + bool user_exists = true; +#ifdef PROXYSQLCLICKHOUSE + if (session_type == PROXYSQL_SESSION_CLICKHOUSE) { + user_exists = GloClickHouseAuth->exists((char *)user); + // for clickhouse, we currently do not support clear text or LDAP + user_exists = true; + } else { +#endif /* PROXYSQLCLICKHOUSE */ + user_exists = GloMyAuth->exists((char *)user); + //password=GloMyAuth->lookup((char *)user, USERNAME_FRONTEND, &_ret_use_ssl, &default_hostgroup, &default_schema, &schema_locked, &transaction_persistent, &fast_forward, &max_connections, &sha1_pass); +#ifdef PROXYSQLCLICKHOUSE + } +#endif /* PROXYSQLCLICKHOUSE */ + if (user_exists == false) { + (*myds)->switching_auth_type = 2; // mysql_clear_password + (*myds)->switching_auth_stage = 1; + generate_pkt_auth_switch_request(true, NULL, NULL); + (*myds)->myconn->userinfo->set((char *)user, NULL, db, NULL); + ret = false; + goto __exit_process_pkt_handshake_response; + } + } + } + } + } if (auth_plugin_id == 0) { // unknown plugin - return false; + ret = false; + goto __exit_process_pkt_handshake_response; } //char reply[SHA_DIGEST_LENGTH+1]; //reply[SHA_DIGEST_LENGTH]='\0'; @@ -1476,6 +1596,9 @@ bool MySQL_Protocol::process_pkt_handshake_response(unsigned char *pkt, unsigned //bool fast_forward = false; //int max_connections; //enum proxysql_session_type session_type = (*myds)->sess->session_type; + +__do_auth: + if (session_type == PROXYSQL_SESSION_CLICKHOUSE) { #ifdef PROXYSQLCLICKHOUSE password=GloClickHouseAuth->lookup((char *)user, USERNAME_FRONTEND, &_ret_use_ssl, &default_hostgroup, &default_schema, &schema_locked, &transaction_persistent, &fast_forward, &max_connections, &sha1_pass); @@ -1541,6 +1664,7 @@ bool MySQL_Protocol::process_pkt_handshake_response(unsigned char *pkt, unsigned (*myds)->sess->transaction_persistent=transaction_persistent; (*myds)->sess->session_fast_forward=fast_forward; (*myds)->sess->user_max_connections=max_connections; + char *tmp_user=strdup((const char *)user); userinfo->set(backend_username, NULL, NULL, NULL); if (sha1_pass==NULL) { // currently proxysql doesn't know any sha1_pass for that specific user, let's set it! @@ -1548,7 +1672,8 @@ bool MySQL_Protocol::process_pkt_handshake_response(unsigned char *pkt, unsigned } if (userinfo->sha1_pass) free(userinfo->sha1_pass); userinfo->sha1_pass=sha1_pass_hex(reply); - userinfo->fe_username=strdup((const char *)user); + userinfo->fe_username=strdup((const char *)tmp_user); + free(tmp_user); ret=true; } } else { diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index c59e4e388..00f679cc6 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -2344,7 +2344,9 @@ __get_pkts_from_client: mybe->server_myds->kill_type=0; if (GloMyLdapAuth) { if (session_type==PROXYSQL_SESSION_MYSQL) { - add_ldap_comment_to_pkt(&pkt); + if (mysql_thread___add_ldap_user_comment && strlen(mysql_thread___add_ldap_user_comment)) { + add_ldap_comment_to_pkt(&pkt); + } } } mybe->server_myds->mysql_real_query.init(&pkt); @@ -3512,6 +3514,12 @@ void MySQL_Session::handler___status_CHANGING_USER_CLIENT___STATE_CLIENT_HANDSHA void MySQL_Session::handler___status_CONNECTING_CLIENT___STATE_SERVER_HANDSHAKE(PtrSize_t *pkt, bool *wrong_pass) { bool is_encrypted = client_myds->encrypted; bool handshake_response_return = client_myds->myprot.process_pkt_handshake_response((unsigned char *)pkt->ptr,pkt->size); + + if ( + (handshake_response_return == false) && (client_myds->switching_auth_stage == 1) + ) { + return; + } if ( (is_encrypted == false) && // the connection was encrypted @@ -3630,9 +3638,11 @@ void MySQL_Session::handler___status_CONNECTING_CLIENT___STATE_SERVER_HANDSHAKE( client_authenticated=false; *wrong_pass=true; client_myds->setDSS_STATE_QUERY_SENT_NET(); + uint8_t _pid = 2; + if (client_myds->switching_auth_stage) _pid+=2; if (max_connections_reached==true) { proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 5, "Too many connections\n"); - client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,2,1040,(char *)"08004", (char *)"Too many connections", true); + client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,_pid,1040,(char *)"08004", (char *)"Too many connections", true); } else { // see issue #794 proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 5, "User '%s' has exceeded the 'max_user_connections' resource (current value: %d)\n", client_myds->myconn->userinfo->username, used_users); char *a=(char *)"User '%s' has exceeded the 'max_user_connections' resource (current value: %d)"; @@ -3683,6 +3693,9 @@ void MySQL_Session::handler___status_CONNECTING_CLIENT___STATE_SERVER_HANDSHAKE( } else { client_addr = strdup((char *)""); } + uint8_t _pid = 2; + if (client_myds->switching_auth_stage) _pid+=2; + if (is_encrypted) _pid++; if ( (strcmp(client_addr,(char *)"127.0.0.1")==0) || @@ -3691,30 +3704,37 @@ void MySQL_Session::handler___status_CONNECTING_CLIENT___STATE_SERVER_HANDSHAKE( (strcmp(client_addr,(char *)"::1")==0) ) { // we are good! - client_myds->myprot.generate_pkt_OK(true,NULL,NULL, (is_encrypted ? 3 : 2), 0,0,0,0,NULL); + //client_myds->myprot.generate_pkt_OK(true,NULL,NULL, (is_encrypted ? 3 : 2), 0,0,0,0,NULL); + client_myds->myprot.generate_pkt_OK(true,NULL,NULL, _pid, 0,0,0,0,NULL); status=WAITING_CLIENT_DATA; client_myds->DSS=STATE_CLIENT_AUTH_OK; } else { char *a=(char *)"User '%s' can only connect locally"; char *b=(char *)malloc(strlen(a)+strlen(client_myds->myconn->userinfo->username)); sprintf(b,a,client_myds->myconn->userinfo->username); - client_myds->myprot.generate_pkt_ERR(true,NULL,NULL, (is_encrypted ? 3 : 2), 1040,(char *)"42000", b, true); + //client_myds->myprot.generate_pkt_ERR(true,NULL,NULL, (is_encrypted ? 3 : 2), 1040,(char *)"42000", b, true); + client_myds->myprot.generate_pkt_ERR(true,NULL,NULL, _pid, 1040,(char *)"42000", b, true); free(b); } free(addr); free(client_addr); } else { + uint8_t _pid = 2; + if (client_myds->switching_auth_stage) _pid+=2; + if (is_encrypted) _pid++; if (use_ssl == true && is_encrypted == false) { *wrong_pass=true; char *_a=(char *)"ProxySQL Error: Access denied for user '%s' (using password: %s). SSL is required"; char *_s=(char *)malloc(strlen(_a)+strlen(client_myds->myconn->userinfo->username)+32); sprintf(_s, _a, client_myds->myconn->userinfo->username, (client_myds->myconn->userinfo->password ? "YES" : "NO")); - client_myds->myprot.generate_pkt_ERR(true,NULL,NULL, (is_encrypted ? 3 : 2), 1045,(char *)"28000", _s, true); + //client_myds->myprot.generate_pkt_ERR(true,NULL,NULL, (is_encrypted ? 3 : 2), 1045,(char *)"28000", _s, true); + client_myds->myprot.generate_pkt_ERR(true,NULL,NULL, _pid, 1045,(char *)"28000", _s, true); __sync_add_and_fetch(&MyHGM->status.client_connections_aborted,1); free(_s); } else { // we are good! - client_myds->myprot.generate_pkt_OK(true,NULL,NULL, (is_encrypted ? 3 : 2), 0,0,0,0,NULL); + //client_myds->myprot.generate_pkt_OK(true,NULL,NULL, (is_encrypted ? 3 : 2), 0,0,0,0,NULL); + client_myds->myprot.generate_pkt_OK(true,NULL,NULL, _pid, 0,0,0,0,NULL); status=WAITING_CLIENT_DATA; client_myds->DSS=STATE_CLIENT_AUTH_OK; } @@ -3768,8 +3788,12 @@ void MySQL_Session::handler___status_CONNECTING_CLIENT___STATE_SERVER_HANDSHAKE( } if (client_myds->myconn->userinfo->username) { char *_s=(char *)malloc(strlen(client_myds->myconn->userinfo->username)+100+strlen(client_addr)); + uint8_t _pid = 2; + if (client_myds->switching_auth_stage) _pid+=2; + if (is_encrypted) _pid++; sprintf(_s,"ProxySQL Error: Access denied for user '%s'@'%s' (using password: %s)", client_myds->myconn->userinfo->username, client_addr, (client_myds->myconn->userinfo->password ? "YES" : "NO")); - client_myds->myprot.generate_pkt_ERR(true,NULL,NULL, (is_encrypted ? 3 : 2), 1045,(char *)"28000", _s, true); + //client_myds->myprot.generate_pkt_ERR(true,NULL,NULL, (is_encrypted ? 3 : 2), 1045,(char *)"28000", _s, true); + client_myds->myprot.generate_pkt_ERR(true,NULL,NULL, _pid, 1045,(char *)"28000", _s, true); free(_s); } __sync_add_and_fetch(&MyHGM->status.client_connections_aborted,1); @@ -4924,9 +4948,9 @@ void MySQL_Session::add_ldap_comment_to_pkt(PtrSize_t *_pkt) { if (client_myds->myconn->userinfo->fe_username==NULL) return; char *fe=client_myds->myconn->userinfo->fe_username; - char *a = (char *)" /* proxysql-ldap-user=%s */"; - char *b = (char *)malloc(strlen(a)+strlen(fe)); - sprintf(b,a,fe); + char *a = (char *)" /* %s=%s */"; + char *b = (char *)malloc(strlen(a)+strlen(fe)+strlen(mysql_thread___add_ldap_user_comment)); + sprintf(b,a,mysql_thread___add_ldap_user_comment,fe); PtrSize_t _new_pkt; _new_pkt.ptr = malloc(strlen(b) + _pkt->size); memcpy(_new_pkt.ptr , _pkt->ptr, 5); diff --git a/lib/MySQL_Thread.cpp b/lib/MySQL_Thread.cpp index d4a093e84..415a56e50 100644 --- a/lib/MySQL_Thread.cpp +++ b/lib/MySQL_Thread.cpp @@ -314,6 +314,7 @@ static char * mysql_thread_variables_names[]= { (char *)"stacksize", (char *)"threads", (char *)"init_connect", + (char *)"add_ldap_user_comment", (char *)"default_sql_mode", (char *)"default_time_zone", (char *)"connpoll_reset_queue_length", @@ -405,6 +406,7 @@ MySQL_Threads_Handler::MySQL_Threads_Handler() { variables.long_query_time=1000; variables.query_cache_size_MB=256; variables.init_connect=NULL; + variables.add_ldap_user_comment=NULL; variables.default_sql_mode=strdup((char *)MYSQL_DEFAULT_SQL_MODE); variables.default_time_zone=strdup((char *)MYSQL_DEFAULT_TIME_ZONE); variables.ping_interval_server_msec=10000; @@ -572,6 +574,13 @@ char * MySQL_Threads_Handler::get_variable_string(char *name) { return strdup(variables.init_connect); } } + if (!strcasecmp(name,"add_ldap_user_comment")) { + if (variables.add_ldap_user_comment==NULL || strlen(variables.add_ldap_user_comment)==0) { + return NULL; + } else { + return strdup(variables.add_ldap_user_comment); + } + } if (!strcasecmp(name,"default_sql_mode")) { if (variables.default_sql_mode==NULL) { variables.default_sql_mode=strdup((char *)MYSQL_DEFAULT_SQL_MODE); @@ -764,6 +773,13 @@ VALGRIND_DISABLE_ERROR_REPORTING; return strdup(variables.init_connect); } } + if (!strcasecmp(name,"add_ldap_user_comment")) { + if (variables.add_ldap_user_comment==NULL || strlen(variables.add_ldap_user_comment)==0) { + return NULL; + } else { + return strdup(variables.add_ldap_user_comment); + } + } if (!strcasecmp(name,"default_sql_mode")) { if (variables.default_sql_mode==NULL) { variables.default_sql_mode=strdup((char *)MYSQL_DEFAULT_SQL_MODE); @@ -1861,6 +1877,15 @@ bool MySQL_Threads_Handler::set_variable(char *name, char *value) { // this is t } return true; } + if (!strcasecmp(name,"add_ldap_user_comment")) { + if (variables.init_connect) free(variables.add_ldap_user_comment); + variables.add_ldap_user_comment=NULL; + if (vallen) { + if (strcmp(value,"(null)")) + variables.add_ldap_user_comment=strdup(value); + } + return true; + } if (!strcasecmp(name,"default_sql_mode")) { if (variables.default_sql_mode) free(variables.default_sql_mode); @@ -2397,6 +2422,7 @@ MySQL_Threads_Handler::~MySQL_Threads_Handler() { if (variables.interfaces) free(variables.interfaces); if (variables.server_version) free(variables.server_version); if (variables.init_connect) free(variables.init_connect); + if (variables.add_ldap_user_comment) free(variables.add_ldap_user_comment); if (variables.default_sql_mode) free(variables.default_sql_mode); if (variables.default_time_zone) free(variables.default_time_zone); if (variables.eventslog_filename) free(variables.eventslog_filename); @@ -2511,6 +2537,7 @@ MySQL_Thread::~MySQL_Thread() { if (mysql_thread___default_schema) { free(mysql_thread___default_schema); mysql_thread___default_schema=NULL; } if (mysql_thread___server_version) { free(mysql_thread___server_version); mysql_thread___server_version=NULL; } if (mysql_thread___init_connect) { free(mysql_thread___init_connect); mysql_thread___init_connect=NULL; } + if (mysql_thread___add_ldap_user_comment) { free(mysql_thread___add_ldap_user_comment); mysql_thread___add_ldap_user_comment=NULL; } if (mysql_thread___default_sql_mode) { free(mysql_thread___default_sql_mode); mysql_thread___default_sql_mode=NULL; } if (mysql_thread___default_time_zone) { free(mysql_thread___default_time_zone); mysql_thread___default_time_zone=NULL; } if (mysql_thread___eventslog_filename) { free(mysql_thread___eventslog_filename); mysql_thread___eventslog_filename=NULL; } @@ -3593,6 +3620,8 @@ void MySQL_Thread::refresh_variables() { if (mysql_thread___init_connect) free(mysql_thread___init_connect); mysql_thread___init_connect=GloMTH->get_variable_string((char *)"init_connect"); + if (mysql_thread___add_ldap_user_comment) free(mysql_thread___add_ldap_user_comment); + mysql_thread___add_ldap_user_comment=GloMTH->get_variable_string((char *)"add_ldap_user_comment"); if (mysql_thread___default_sql_mode) free(mysql_thread___default_sql_mode); mysql_thread___default_sql_mode=GloMTH->get_variable_string((char *)"default_sql_mode"); if (mysql_thread___default_time_zone) free(mysql_thread___default_time_zone); @@ -3659,6 +3688,7 @@ MySQL_Thread::MySQL_Thread() { __thread_MySQL_Thread_Variables_version=0; mysql_thread___server_version=NULL; mysql_thread___init_connect=NULL; + mysql_thread___add_ldap_user_comment=NULL; mysql_thread___eventslog_filename=NULL; // SSL proxy to server diff --git a/lib/mysql_data_stream.cpp b/lib/mysql_data_stream.cpp index 094e75e65..b33e423b9 100644 --- a/lib/mysql_data_stream.cpp +++ b/lib/mysql_data_stream.cpp @@ -197,6 +197,8 @@ MySQL_Data_Stream::MySQL_Data_Stream() { myconn=NULL; // 20141011 DSS=STATE_NOT_CONNECTED; encrypted=false; + switching_auth_stage = 0; + switching_auth_type = 0; ssl=NULL; rbio_ssl = NULL; wbio_ssl = NULL;