diff --git a/include/MySQL_Authentication.hpp b/include/MySQL_Authentication.hpp index dfb0523b0..519b49ebe 100644 --- a/include/MySQL_Authentication.hpp +++ b/include/MySQL_Authentication.hpp @@ -23,6 +23,7 @@ typedef struct _account_details_t { bool __frontend; // this is used only during the dump bool __backend; // this is used only during the dump bool __active; + char *attributes; char *comment; } account_details_t; @@ -61,7 +62,7 @@ class MySQL_Authentication { public: MySQL_Authentication(); ~MySQL_Authentication(); - bool add(char *username, char *password, 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, char *comment); + bool add(char *username, char *password, 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, char* attributes, char *comment); bool del(char *username, enum cred_username_type usertype, bool set_lock=true); bool reset(); void print_version(); diff --git a/lib/MySQL_Authentication.cpp b/lib/MySQL_Authentication.cpp index 71b0de9ef..7e6a9313c 100644 --- a/lib/MySQL_Authentication.cpp +++ b/lib/MySQL_Authentication.cpp @@ -79,7 +79,7 @@ __loop_remove_inactives: #endif } -bool MySQL_Authentication::add(char * username, char * password, 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, char *comment) { +bool MySQL_Authentication::add(char * username, char * password, 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, char* attributes, char *comment) { uint64_t hash1, hash2; SpookyHash myhash; myhash.Init(1,2); @@ -116,12 +116,17 @@ bool MySQL_Authentication::add(char * username, char * password, enum cred_usern free(ad->comment); ad->comment=strdup(comment); } + if (strcasecmp(ad->attributes, attributes)) { + free(ad->attributes); + ad->attributes=strdup(attributes); + } } else { ad=(account_details_t *)malloc(sizeof(account_details_t)); ad->username=strdup(username); ad->default_schema=strdup(default_schema); ad->comment=strdup(comment); ad->password=strdup(password); + ad->attributes=strdup(attributes); new_ad=true; ad->sha1_pass=NULL; ad->num_connections_used=0; @@ -165,6 +170,7 @@ unsigned int MySQL_Authentication::memory_usage() { if (ado->sha1_pass) ret += SHA_DIGEST_LENGTH; if (ado->default_schema) ret += strlen(ado->default_schema) + 1; if (ado->comment) ret += strlen(ado->comment) + 1; + if (ado->attributes) ret += strlen(ado->attributes) + 1; } ret += sizeof(creds_group_t); ret += sizeof(PtrArray); @@ -177,6 +183,7 @@ unsigned int MySQL_Authentication::memory_usage() { if (ado->sha1_pass) ret += SHA_DIGEST_LENGTH; if (ado->default_schema) ret += strlen(ado->default_schema) + 1; if (ado->comment) ret += strlen(ado->comment) + 1; + if (ado->attributes) ret += strlen(ado->attributes) + 1; } ret += sizeof(creds_group_t); ret += sizeof(PtrArray); @@ -218,6 +225,7 @@ int MySQL_Authentication::dump_all_users(account_details_t ***ads, bool _complet if (_complete==false) { ad->password=NULL; ad->default_schema=NULL; + ad->attributes=NULL; ad->comment=NULL; ad->num_connections_used=ado->num_connections_used; } else { @@ -227,6 +235,7 @@ int MySQL_Authentication::dump_all_users(account_details_t ***ads, bool _complet ad->sha1_pass=NULL; ad->use_ssl=ado->use_ssl; ad->default_schema=strdup(ado->default_schema); + ad->attributes=strdup(ado->attributes); ad->comment=strdup(ado->comment); ad->schema_locked=ado->schema_locked; ad->transaction_persistent=ado->transaction_persistent; @@ -248,6 +257,7 @@ int MySQL_Authentication::dump_all_users(account_details_t ***ads, bool _complet ad->use_ssl=ado->use_ssl; ad->default_hostgroup=ado->default_hostgroup; ad->default_schema=strdup(ado->default_schema); + ad->attributes=strdup(ado->attributes); ad->comment=strdup(ado->comment); ad->schema_locked=ado->schema_locked; ad->transaction_persistent=ado->transaction_persistent; @@ -361,6 +371,7 @@ bool MySQL_Authentication::del(char * username, enum cred_username_type usertype free(ad->password); if (ad->sha1_pass) { free(ad->sha1_pass); ad->sha1_pass=NULL; } free(ad->default_schema); + free(ad->attributes); free(ad->comment); free(ad); ret=true; @@ -491,6 +502,7 @@ bool MySQL_Authentication::_reset(enum cred_username_type usertype) { if (ad->sha1_pass) { free(ad->sha1_pass); ad->sha1_pass=NULL; } free(ad->default_schema); free(ad->comment); + free(ad->attributes); free(ad); } } @@ -537,6 +549,9 @@ uint64_t MySQL_Authentication::_get_runtime_checksum(enum cred_username_type use myhash.Update(ad->default_schema,strlen(ad->default_schema)); if (ad->comment) myhash.Update(ad->comment,strlen(ad->comment)); + if (ad->attributes) { + myhash.Update(ad->attributes,strlen(ad->attributes)); + } } it++; } diff --git a/lib/ProxySQL_Admin.cpp b/lib/ProxySQL_Admin.cpp index 84a614a92..f8a629456 100644 --- a/lib/ProxySQL_Admin.cpp +++ b/lib/ProxySQL_Admin.cpp @@ -301,9 +301,10 @@ static int http_handler(void *cls, struct MHD_Connection *connection, const char #define ADMIN_SQLITE_TABLE_MYSQL_USERS_V1_3_0 "CREATE TABLE mysql_users (username VARCHAR NOT NULL , password VARCHAR , active INT CHECK (active IN (0,1)) NOT NULL DEFAULT 1 , use_ssl INT CHECK (use_ssl IN (0,1)) NOT NULL DEFAULT 0 , default_hostgroup INT NOT NULL DEFAULT 0 , default_schema VARCHAR , schema_locked INT CHECK (schema_locked IN (0,1)) NOT NULL DEFAULT 0 , transaction_persistent INT CHECK (transaction_persistent IN (0,1)) NOT NULL DEFAULT 0 , fast_forward INT CHECK (fast_forward IN (0,1)) NOT NULL DEFAULT 0 , backend INT CHECK (backend IN (0,1)) NOT NULL DEFAULT 1 , frontend INT CHECK (frontend IN (0,1)) NOT NULL DEFAULT 1 , max_connections INT CHECK (max_connections >=0) NOT NULL DEFAULT 10000 , PRIMARY KEY (username, backend) , UNIQUE (username, frontend))" #define ADMIN_SQLITE_TABLE_MYSQL_USERS_V1_4_0 "CREATE TABLE mysql_users (username VARCHAR NOT NULL , password VARCHAR , active INT CHECK (active IN (0,1)) NOT NULL DEFAULT 1 , use_ssl INT CHECK (use_ssl IN (0,1)) NOT NULL DEFAULT 0 , default_hostgroup INT NOT NULL DEFAULT 0 , default_schema VARCHAR , schema_locked INT CHECK (schema_locked IN (0,1)) NOT NULL DEFAULT 0 , transaction_persistent INT CHECK (transaction_persistent IN (0,1)) NOT NULL DEFAULT 1 , fast_forward INT CHECK (fast_forward IN (0,1)) NOT NULL DEFAULT 0 , backend INT CHECK (backend IN (0,1)) NOT NULL DEFAULT 1 , frontend INT CHECK (frontend IN (0,1)) NOT NULL DEFAULT 1 , max_connections INT CHECK (max_connections >=0) NOT NULL DEFAULT 10000 , PRIMARY KEY (username, backend) , UNIQUE (username, frontend))" #define ADMIN_SQLITE_TABLE_MYSQL_USERS_V2_0_0 "CREATE TABLE mysql_users (username VARCHAR NOT NULL , password VARCHAR , active INT CHECK (active IN (0,1)) NOT NULL DEFAULT 1 , use_ssl INT CHECK (use_ssl IN (0,1)) NOT NULL DEFAULT 0 , default_hostgroup INT NOT NULL DEFAULT 0 , default_schema VARCHAR , schema_locked INT CHECK (schema_locked IN (0,1)) NOT NULL DEFAULT 0 , transaction_persistent INT CHECK (transaction_persistent IN (0,1)) NOT NULL DEFAULT 1 , fast_forward INT CHECK (fast_forward IN (0,1)) NOT NULL DEFAULT 0 , backend INT CHECK (backend IN (0,1)) NOT NULL DEFAULT 1 , frontend INT CHECK (frontend IN (0,1)) NOT NULL DEFAULT 1 , max_connections INT CHECK (max_connections >=0) NOT NULL DEFAULT 10000 , comment VARCHAR NOT NULL DEFAULT '' , PRIMARY KEY (username, backend) , UNIQUE (username, frontend))" -#define ADMIN_SQLITE_TABLE_MYSQL_USERS ADMIN_SQLITE_TABLE_MYSQL_USERS_V2_0_0 +#define ADMIN_SQLITE_TABLE_MYSQL_USERS_V2_1_0 "CREATE TABLE mysql_users (username VARCHAR NOT NULL , password VARCHAR , active INT CHECK (active IN (0,1)) NOT NULL DEFAULT 1 , use_ssl INT CHECK (use_ssl IN (0,1)) NOT NULL DEFAULT 0 , default_hostgroup INT NOT NULL DEFAULT 0 , default_schema VARCHAR , schema_locked INT CHECK (schema_locked IN (0,1)) NOT NULL DEFAULT 0 , transaction_persistent INT CHECK (transaction_persistent IN (0,1)) NOT NULL DEFAULT 1 , fast_forward INT CHECK (fast_forward IN (0,1)) NOT NULL DEFAULT 0 , backend INT CHECK (backend IN (0,1)) NOT NULL DEFAULT 1 , frontend INT CHECK (frontend IN (0,1)) NOT NULL DEFAULT 1 , max_connections INT CHECK (max_connections >=0) NOT NULL DEFAULT 10000 , attributes JSON CHECK (JSON_VALID(attributes)) , comment VARCHAR NOT NULL DEFAULT '' , PRIMARY KEY (username, backend) , UNIQUE (username, frontend))" +#define ADMIN_SQLITE_TABLE_MYSQL_USERS ADMIN_SQLITE_TABLE_MYSQL_USERS_V2_1_0 -#define ADMIN_SQLITE_RUNTIME_MYSQL_USERS "CREATE TABLE runtime_mysql_users (username VARCHAR NOT NULL , password VARCHAR , active INT CHECK (active IN (0,1)) NOT NULL DEFAULT 1 , use_ssl INT CHECK (use_ssl IN (0,1)) NOT NULL DEFAULT 0 , default_hostgroup INT NOT NULL DEFAULT 0 , default_schema VARCHAR , schema_locked INT CHECK (schema_locked IN (0,1)) NOT NULL DEFAULT 0 , transaction_persistent INT CHECK (transaction_persistent IN (0,1)) NOT NULL DEFAULT 1 , fast_forward INT CHECK (fast_forward IN (0,1)) NOT NULL DEFAULT 0 , backend INT CHECK (backend IN (0,1)) NOT NULL DEFAULT 1 , frontend INT CHECK (frontend IN (0,1)) NOT NULL DEFAULT 1 , max_connections INT CHECK (max_connections >=0) NOT NULL DEFAULT 10000 , comment VARCHAR NOT NULL DEFAULT '' , PRIMARY KEY (username, backend) , UNIQUE (username, frontend))" +#define ADMIN_SQLITE_RUNTIME_MYSQL_USERS "CREATE TABLE runtime_mysql_users (username VARCHAR NOT NULL , password VARCHAR , active INT CHECK (active IN (0,1)) NOT NULL DEFAULT 1 , use_ssl INT CHECK (use_ssl IN (0,1)) NOT NULL DEFAULT 0 , default_hostgroup INT NOT NULL DEFAULT 0 , default_schema VARCHAR , schema_locked INT CHECK (schema_locked IN (0,1)) NOT NULL DEFAULT 0 , transaction_persistent INT CHECK (transaction_persistent IN (0,1)) NOT NULL DEFAULT 1 , fast_forward INT CHECK (fast_forward IN (0,1)) NOT NULL DEFAULT 0 , backend INT CHECK (backend IN (0,1)) NOT NULL DEFAULT 1 , frontend INT CHECK (frontend IN (0,1)) NOT NULL DEFAULT 1 , max_connections INT CHECK (max_connections >=0) NOT NULL DEFAULT 10000 , attributes JSON CHECK (JSON_VALID(attributes)) , comment VARCHAR NOT NULL DEFAULT '' , PRIMARY KEY (username, backend) , UNIQUE (username, frontend))" #define ADMIN_SQLITE_TABLE_MYSQL_LDAP_MAPPING_V2_0_0 "CREATE TABLE mysql_ldap_mapping (priority INTEGER CHECK (priority >= 1 AND priority <= 1000000) PRIMARY KEY , frontend_entity VARCHAR NOT NULL , backend_entity VARCHAR NOT NULL , comment VARCHAR NOT NULL DEFAULT '' , UNIQUE (frontend_entity))" #define ADMIN_SQLITE_TABLE_MYSQL_LDAP_MAPPING ADMIN_SQLITE_TABLE_MYSQL_LDAP_MAPPING_V2_0_0 @@ -6879,7 +6880,7 @@ void ProxySQL_Admin::add_credentials(char *credentials, int hostgroup_id) { c_split_2(token, ":", &user, &pass); proxy_debug(PROXY_DEBUG_ADMIN, 4, "Adding %s credential: \"%s\", user:%s, pass:%s\n", type, token, user, pass); if (GloMyAuth) { // this check if required if GloMyAuth doesn't exist yet - GloMyAuth->add(user,pass,USERNAME_FRONTEND,0,hostgroup_id,(char *)"main",0,0,0,1000,(char *)""); + GloMyAuth->add(user,pass,USERNAME_FRONTEND,0,hostgroup_id,(char *)"main",0,0,0,1000,(char*)"",(char *)""); } free(user); free(pass); @@ -9637,14 +9638,14 @@ void ProxySQL_Admin::__add_active_users(enum cred_username_type usertype, char * char *query=NULL; if (__user==NULL) { if (hash1) { - str=(char *)"SELECT username,password,use_ssl,default_hostgroup,default_schema,schema_locked,transaction_persistent,fast_forward,max_connections,comment FROM main.mysql_users WHERE %s=1 AND active=1 AND default_hostgroup>=0 ORDER BY username"; + str=(char *)"SELECT username,password,use_ssl,default_hostgroup,default_schema,schema_locked,transaction_persistent,fast_forward,max_connections,attributes,comment FROM main.mysql_users WHERE %s=1 AND active=1 AND default_hostgroup>=0 ORDER BY username"; } else { - str=(char *)"SELECT username,password,use_ssl,default_hostgroup,default_schema,schema_locked,transaction_persistent,fast_forward,max_connections,comment FROM main.mysql_users WHERE %s=1 AND active=1 AND default_hostgroup>=0"; + str=(char *)"SELECT username,password,use_ssl,default_hostgroup,default_schema,schema_locked,transaction_persistent,fast_forward,max_connections,attributes,comment FROM main.mysql_users WHERE %s=1 AND active=1 AND default_hostgroup>=0"; } query=(char *)malloc(strlen(str)+15); sprintf(query,str,(usertype==USERNAME_BACKEND ? "backend" : "frontend")); } else { - str=(char *)"SELECT username,password,use_ssl,default_hostgroup,default_schema,schema_locked,transaction_persistent,fast_forward,max_connections,comment FROM main.mysql_users WHERE %s=1 AND active=1 AND default_hostgroup>=0 AND username='%s'"; + str=(char *)"SELECT username,password,use_ssl,default_hostgroup,default_schema,schema_locked,transaction_persistent,fast_forward,max_connections,attributes,comment FROM main.mysql_users WHERE %s=1 AND active=1 AND default_hostgroup>=0 AND username='%s'"; query=(char *)malloc(strlen(str)+strlen(__user)+15); sprintf(query,str,(usertype==USERNAME_BACKEND ? "backend" : "frontend"),__user); } @@ -9715,7 +9716,8 @@ void ProxySQL_Admin::__add_active_users(enum cred_username_type usertype, char * (strcmp(r->fields[6],"1")==0 ? true : false) , // transaction_persistent (strcmp(r->fields[7],"1")==0 ? true : false), // fast_forward ( atoi(r->fields[8])>0 ? atoi(r->fields[8]) : 0), // max_connections - (r->fields[9]==NULL ? (char *)"" : r->fields[9]) //comment + (r->fields[9] == NULL ? (char *)"" : r->fields[9]), // attributes + (r->fields[10]==NULL ? (char *)"" : r->fields[10]) //comment ); if (variables.hash_passwords) { free(password); // because we always generate a new string @@ -9936,10 +9938,10 @@ void ProxySQL_Admin::save_mysql_users_runtime_to_database(bool _runtime) { // char *qfr=(char *)"REPLACE INTO runtime_mysql_users(username,password,active,use_ssl,default_hostgroup,default_schema,schema_locked,transaction_persistent,fast_forward,backend,frontend,max_connections) VALUES('%s','%s',1,%d,%d,'%s',%d,%d,%d,COALESCE((SELECT backend FROM runtime_mysql_users WHERE username='%s' AND frontend=1),0),1,%d)"; // char *qbr=(char *)"REPLACE INTO runtime_mysql_users(username,password,active,use_ssl,default_hostgroup,default_schema,schema_locked,transaction_persistent,fast_forward,backend,frontend,max_connections) VALUES('%s','%s',1,%d,%d,'%s',%d,%d,%d,1,COALESCE((SELECT frontend FROM runtime_mysql_users WHERE username='%s' AND backend=1),0),%d)"; - char *qf_stmt1=(char *)"REPLACE INTO mysql_users(username,password,active,use_ssl,default_hostgroup,default_schema,schema_locked,transaction_persistent,fast_forward,backend,frontend,max_connections,comment) VALUES(?1,?2,1,?3,?4,?5,?6,?7,?8,COALESCE((SELECT backend FROM mysql_users WHERE username=?9 AND frontend=1),0),1,?10,?11)"; - char *qb_stmt1=(char *)"REPLACE INTO mysql_users(username,password,active,use_ssl,default_hostgroup,default_schema,schema_locked,transaction_persistent,fast_forward,backend,frontend,max_connections,comment) VALUES(?1,?2,1,?3,?4,?5,?6,?7,?8,1,COALESCE((SELECT frontend FROM mysql_users WHERE username=?9 AND backend=1),0),?10,?11)"; - char *qfr_stmt1=(char *)"REPLACE INTO runtime_mysql_users(username,password,active,use_ssl,default_hostgroup,default_schema,schema_locked,transaction_persistent,fast_forward,backend,frontend,max_connections,comment) VALUES(?1,?2,1,?3,?4,?5,?6,?7,?8,COALESCE((SELECT backend FROM runtime_mysql_users WHERE username=?9 AND frontend=1),0),1,?10,?11)"; - char *qbr_stmt1=(char *)"REPLACE INTO runtime_mysql_users(username,password,active,use_ssl,default_hostgroup,default_schema,schema_locked,transaction_persistent,fast_forward,backend,frontend,max_connections,comment) VALUES(?1,?2,1,?3,?4,?5,?6,?7,?8,1,COALESCE((SELECT frontend FROM runtime_mysql_users WHERE username=?9 AND backend=1),0),?10,?11)"; + char *qf_stmt1=(char *)"REPLACE INTO mysql_users(username,password,active,use_ssl,default_hostgroup,default_schema,schema_locked,transaction_persistent,fast_forward,backend,frontend,max_connections,attributes,comment) VALUES(?1,?2,1,?3,?4,?5,?6,?7,?8,COALESCE((SELECT backend FROM mysql_users WHERE username=?9 AND frontend=1),0),1,?10,?11,?12)"; + char *qb_stmt1=(char *)"REPLACE INTO mysql_users(username,password,active,use_ssl,default_hostgroup,default_schema,schema_locked,transaction_persistent,fast_forward,backend,frontend,max_connections,attributes,comment) VALUES(?1,?2,1,?3,?4,?5,?6,?7,?8,1,COALESCE((SELECT frontend FROM mysql_users WHERE username=?9 AND backend=1),0),?10,?11,?12)"; + char *qfr_stmt1=(char *)"REPLACE INTO runtime_mysql_users(username,password,active,use_ssl,default_hostgroup,default_schema,schema_locked,transaction_persistent,fast_forward,backend,frontend,max_connections,attributes,comment) VALUES(?1,?2,1,?3,?4,?5,?6,?7,?8,COALESCE((SELECT backend FROM runtime_mysql_users WHERE username=?9 AND frontend=1),0),1,?10,?11,?12)"; + char *qbr_stmt1=(char *)"REPLACE INTO runtime_mysql_users(username,password,active,use_ssl,default_hostgroup,default_schema,schema_locked,transaction_persistent,fast_forward,backend,frontend,max_connections,attributes,comment) VALUES(?1,?2,1,?3,?4,?5,?6,?7,?8,1,COALESCE((SELECT frontend FROM runtime_mysql_users WHERE username=?9 AND backend=1),0),?10,?11,?12)"; num_users=GloMyAuth->dump_all_users(&ads); if (num_users==0) return; char *q_stmt1_f=NULL; @@ -10008,7 +10010,8 @@ void ProxySQL_Admin::save_mysql_users_runtime_to_database(bool _runtime) { rc=(*proxy_sqlite3_bind_int64)(statement1, 8, ad->fast_forward); ASSERT_SQLITE_OK(rc, admindb); rc=(*proxy_sqlite3_bind_text)(statement1, 9, ad->username, -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, admindb); rc=(*proxy_sqlite3_bind_int64)(statement1, 10, ad->max_connections); ASSERT_SQLITE_OK(rc, admindb); - rc=(*proxy_sqlite3_bind_text)(statement1, 11, ad->comment, -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, admindb); + rc=(*proxy_sqlite3_bind_text)(statement1, 11, ad->attributes, -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, admindb); + rc=(*proxy_sqlite3_bind_text)(statement1, 12, ad->comment, -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, admindb); SAFE_SQLITE3_STEP2(statement1); rc=(*proxy_sqlite3_clear_bindings)(statement1); ASSERT_SQLITE_OK(rc, admindb); rc=(*proxy_sqlite3_reset)(statement1); ASSERT_SQLITE_OK(rc, admindb); @@ -10017,6 +10020,7 @@ void ProxySQL_Admin::save_mysql_users_runtime_to_database(bool _runtime) { free(ad->password); // this is not initialized with dump_all_users( , false) free(ad->default_schema); // this is not initialized with dump_all_users( , false) free(ad->comment); + free(ad->attributes); free(ad); } if (_runtime) { @@ -10192,6 +10196,7 @@ void ProxySQL_Admin::save_clickhouse_users_runtime_to_database(bool _runtime) { free(ad->username); free(ad->password); // this is not initialized with dump_all_users( , false) free(ad->default_schema); // this is not initialized with dump_all_users( , false) + free(ad->attributes); free(ad); } if (_runtime) { @@ -11510,6 +11515,21 @@ void ProxySQL_Admin::disk_upgrade_mysql_users() { // copy fields from old table configdb->execute("INSERT INTO mysql_users(username,password,active,use_ssl,default_hostgroup,default_schema,schema_locked,transaction_persistent,fast_forward,backend,frontend,max_connections) SELECT * FROM mysql_users_v140"); } + // adding mysql_users.attributes. See #3083 + rci=configdb->check_table_structure((char *)"mysql_users",(char *)ADMIN_SQLITE_TABLE_MYSQL_USERS_V2_0_0); + if (rci) { + // upgrade is required + proxy_warning("Detected version pre-2.1.0 of table mysql_users\n"); + proxy_warning("ONLINE UPGRADE of table mysql_users in progress\n"); + // drop any existing table with suffix _v210 + configdb->execute("DROP TABLE IF EXISTS mysql_users_v200"); + // rename current table to add suffix _v210 + configdb->execute("ALTER TABLE mysql_users RENAME TO mysql_users_v200"); + // create new table + configdb->build_table((char *)"mysql_users",(char *)ADMIN_SQLITE_TABLE_MYSQL_USERS,false); + // copy fields from old table + configdb->execute("INSERT INTO mysql_users(username,password,active,use_ssl,default_hostgroup,default_schema,schema_locked,transaction_persistent,fast_forward,backend,frontend,max_connections,comment) SELECT * FROM mysql_users_v200"); + } configdb->execute("PRAGMA foreign_keys = ON"); } diff --git a/lib/ProxySQL_Cluster.cpp b/lib/ProxySQL_Cluster.cpp index 35c0aa5e3..3e9832808 100644 --- a/lib/ProxySQL_Cluster.cpp +++ b/lib/ProxySQL_Cluster.cpp @@ -837,12 +837,12 @@ void ProxySQL_Cluster::pull_mysql_users_from_peer() { proxy_info("Cluster: Fetching MySQL Users from peer %s:%d started\n", hostname, port); rc_conn = mysql_real_connect(conn, hostname, username, password, NULL, port, NULL, 0); if (rc_conn) { - rc_query = mysql_query(conn, "SELECT username, password, active, use_ssl, default_hostgroup, default_schema, schema_locked, transaction_persistent, fast_forward, backend, frontend, max_connections, comment FROM runtime_mysql_users"); + rc_query = mysql_query(conn, "SELECT username, password, active, use_ssl, default_hostgroup, default_schema, schema_locked, transaction_persistent, fast_forward, backend, frontend, max_connections, attributes, comment FROM runtime_mysql_users"); if ( rc_query == 0 ) { MYSQL_RES *result = mysql_store_result(conn); GloAdmin->admindb->execute("DELETE FROM mysql_users"); MYSQL_ROW row; - char *q = (char *)"INSERT INTO mysql_users (username, password, active, use_ssl, default_hostgroup, default_schema, schema_locked, transaction_persistent, fast_forward, backend, frontend, max_connections, comment) VALUES (?1 , ?2 , ?3 , ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13)"; + char *q = (char *)"INSERT INTO mysql_users (username, password, active, use_ssl, default_hostgroup, default_schema, schema_locked, transaction_persistent, fast_forward, backend, frontend, max_connections, attributes, comment) VALUES (?1 , ?2 , ?3 , ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14)"; sqlite3_stmt *statement1 = NULL; //sqlite3 *mydb3 = GloAdmin->admindb->get_db(); //rc=(*proxy_sqlite3_prepare_v2)(mydb3, q, -1, &statement1, 0); @@ -861,7 +861,8 @@ void ProxySQL_Cluster::pull_mysql_users_from_peer() { rc=(*proxy_sqlite3_bind_int64)(statement1, 10, atoll(row[9])); ASSERT_SQLITE_OK(rc, GloAdmin->admindb); // backend rc=(*proxy_sqlite3_bind_int64)(statement1, 11, atoll(row[10])); ASSERT_SQLITE_OK(rc, GloAdmin->admindb); // frontend rc=(*proxy_sqlite3_bind_int64)(statement1, 12, atoll(row[11])); ASSERT_SQLITE_OK(rc, GloAdmin->admindb); // max_connection - rc=(*proxy_sqlite3_bind_text)(statement1, 13, row[12], -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, GloAdmin->admindb); // comment + rc=(*proxy_sqlite3_bind_text)(statement1, 13, row[12], -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, GloAdmin->admindb); // attributes + rc=(*proxy_sqlite3_bind_text)(statement1, 14, row[13], -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, GloAdmin->admindb); // comment SAFE_SQLITE3_STEP2(statement1); rc=(*proxy_sqlite3_clear_bindings)(statement1); ASSERT_SQLITE_OK(rc, GloAdmin->admindb); diff --git a/lib/ProxySQL_Config.cpp b/lib/ProxySQL_Config.cpp index aeca63411..5a4a381a9 100644 --- a/lib/ProxySQL_Config.cpp +++ b/lib/ProxySQL_Config.cpp @@ -146,7 +146,7 @@ int ProxySQL_Config::Read_MySQL_Users_from_configfile() { int i; int rows=0; admindb->execute("PRAGMA foreign_keys = OFF"); - char *q=(char *)"INSERT OR REPLACE INTO mysql_users (username, password, active, use_ssl, default_hostgroup, default_schema, schema_locked, transaction_persistent, fast_forward, max_connections, comment) VALUES ('%s', '%s', %d, %d, %d, '%s', %d, %d, %d, %d, '%s')"; + char *q=(char *)"INSERT OR REPLACE INTO mysql_users (username, password, active, use_ssl, default_hostgroup, default_schema, schema_locked, transaction_persistent, fast_forward, max_connections, attributes, comment) VALUES ('%s', '%s', %d, %d, %d, '%s', %d, %d, %d, %d, '%s','%s')"; for (i=0; i< count; i++) { const Setting &user = mysql_users[i]; std::string username; @@ -160,6 +160,7 @@ int ProxySQL_Config::Read_MySQL_Users_from_configfile() { int fast_forward=0; int max_connections=10000; std::string comment=""; + std::string attributes=""; if (user.lookupValue("username", username)==false) { proxy_error("Admin: detected a mysql_users in config file without a mandatory username\n"); continue; @@ -174,11 +175,12 @@ int ProxySQL_Config::Read_MySQL_Users_from_configfile() { user.lookupValue("transaction_persistent", transaction_persistent); user.lookupValue("fast_forward", fast_forward); user.lookupValue("max_connections", max_connections); + user.lookupValue("attributes", attributes); user.lookupValue("comment", comment); char *o1=strdup(comment.c_str()); char *o=escape_string_single_quotes(o1, false); - char *query=(char *)malloc(strlen(q)+strlen(username.c_str())+strlen(password.c_str())+strlen(o)+128); - sprintf(query,q, username.c_str(), password.c_str(), active, use_ssl, default_hostgroup, default_schema.c_str(), schema_locked, transaction_persistent, fast_forward, max_connections, o); + char *query=(char *)malloc(strlen(q)+strlen(username.c_str())+strlen(password.c_str())+strlen(o)+strlen(attributes.c_str())+128); + sprintf(query,q, username.c_str(), password.c_str(), active, use_ssl, default_hostgroup, default_schema.c_str(), schema_locked, transaction_persistent, fast_forward, max_connections, attributes.c_str(), o); admindb->execute(query); if (o!=o1) free(o); free(o1);