diff --git a/docker/Dockerfile b/docker/Dockerfile index 41d2a1a8d..388710437 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -14,7 +14,7 @@ sqlite-libs tcl-dev util-linux-dev xz xz-dev" # Packages that can be removed after build ARG REM_PKGS="bison bash cmake flex gcc git gnutls-dev g++ jansson-dev \ libedit-dev libgcrypt-dev lua-dev make ncurses-dev openssl-dev perl sqlite-dev \ -tcl-dev util-linux-dev xz-dev" +tcl-dev xz-dev" # MaxScale-specific parameters ARG MS_DIR=/MaxScale_workdir diff --git a/maxscale-system-test/mxs729_maxadmin.cpp b/maxscale-system-test/mxs729_maxadmin.cpp index 07404efd5..2bd4e970e 100644 --- a/maxscale-system-test/mxs729_maxadmin.cpp +++ b/maxscale-system-test/mxs729_maxadmin.cpp @@ -21,7 +21,7 @@ const char * user_added = "The Linux user %s has successfully been enabled.\n"; const char * user_removed = "The Linux user %s has successfully been disabled.\n"; const char * remove_last_admin = "Cannot remove the last admin account"; const char * root_added = "User root has been successfully added.\n"; -const char * user_and_root = "Enabled Linux accounts (secure) : %s\n"; +const char * user_and_root = "Enabled Linux accounts (secure) : root, %s\n"; const char * user_only = "Enabled Linux accounts (secure) : root, %s\n"; void add_remove_maxadmin_user(TestConnections* Test) diff --git a/server/core/listener.cc b/server/core/listener.cc index 873173196..04f28b0ba 100644 --- a/server/core/listener.cc +++ b/server/core/listener.cc @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -234,23 +235,29 @@ RSA* create_rsa(int bits) #endif } -static thread_local std::string ssl_errbuf; +// thread-local non-POD types are not supported with older versions of GCC +static thread_local std::string* ssl_errbuf; static const char* get_ssl_errors() { + if (ssl_errbuf == NULL) + { + ssl_errbuf = new std::string; + } + char errbuf[200]; // Enough space according to OpenSSL documentation - ssl_errbuf.clear(); + ssl_errbuf->clear(); for (int err = ERR_get_error(); err; err = ERR_get_error()) { - if (!ssl_errbuf.empty()) + if (!ssl_errbuf->empty()) { - ssl_errbuf += ", "; + ssl_errbuf->append(", "); } - ssl_errbuf += ERR_error_string(err, errbuf); + ssl_errbuf->append(ERR_error_string(err, errbuf)); } - return ssl_errbuf.c_str(); + return ssl_errbuf->c_str(); } /** diff --git a/server/modules/filter/dbfwfilter/dbfwfilter.cc b/server/modules/filter/dbfwfilter/dbfwfilter.cc index cef0f4ef9..921c8ba9b 100644 --- a/server/modules/filter/dbfwfilter/dbfwfilter.cc +++ b/server/modules/filter/dbfwfilter/dbfwfilter.cc @@ -93,12 +93,14 @@ int dbfw_yyparse(void*); MXS_END_DECLS /** The rules and users for each thread */ -thread_local struct +struct DbfwThread { int rule_version; RuleList rules; UserMap users; -} this_thread; +}; + +thread_local DbfwThread* this_thread = NULL; bool parse_at_times(const char** tok, char** saveptr, Rule* ruledef); bool parse_limit_queries(Dbfw* instance, Rule* ruledef, const char* rule, char** saveptr); @@ -127,7 +129,7 @@ static json_t* rules_to_json(const RuleList& rules) { json_t* rval = json_array(); - for (RuleList::const_iterator it = this_thread.rules.begin(); it != this_thread.rules.end(); it++) + for (RuleList::const_iterator it = this_thread->rules.begin(); it != this_thread->rules.end(); it++) { const SRule& rule = *it; json_array_append_new(rval, rule_to_json(rule)); @@ -397,7 +399,7 @@ bool dbfw_show_rules(const MODULECMD_ARG *argv, json_t** output) dcb_printf(dcb, "Rule, Type, Times Matched\n"); - if (this_thread.rules.empty() || this_thread.users.empty()) + if (this_thread->rules.empty() || this_thread->users.empty()) { if (!replace_rules(inst)) { @@ -405,7 +407,7 @@ bool dbfw_show_rules(const MODULECMD_ARG *argv, json_t** output) } } - for (RuleList::const_iterator it = this_thread.rules.begin(); it != this_thread.rules.end(); it++) + for (RuleList::const_iterator it = this_thread->rules.begin(); it != this_thread->rules.end(); it++) { const SRule& rule = *it; char buf[rule->name().length() + 200]; // Some extra space @@ -423,7 +425,7 @@ bool dbfw_show_rules_json(const MODULECMD_ARG *argv, json_t** output) json_t* arr = json_array(); - if (this_thread.rules.empty() || this_thread.users.empty()) + if (this_thread->rules.empty() || this_thread->users.empty()) { if (!replace_rules(inst)) { @@ -431,7 +433,7 @@ bool dbfw_show_rules_json(const MODULECMD_ARG *argv, json_t** output) } } - for (RuleList::const_iterator it = this_thread.rules.begin(); it != this_thread.rules.end(); it++) + for (RuleList::const_iterator it = this_thread->rules.begin(); it != this_thread->rules.end(); it++) { const SRule& rule = *it; json_array_append_new(arr, rule_to_json(rule)); @@ -441,6 +443,24 @@ bool dbfw_show_rules_json(const MODULECMD_ARG *argv, json_t** output) return true; } +static int dbfw_thr_init() +{ + int rval = 0; + + if ((this_thread = new (std::nothrow) DbfwThread) == NULL) + { + MXS_OOM(); + rval = -1; + } + + return rval; +} + +static void dbfw_thr_finish() +{ + MXS_EXCEPTION_GUARD(delete this_thread); +} + static const MXS_ENUM_VALUE action_values[] = { {"allow", FW_ACTION_ALLOW}, @@ -501,8 +521,8 @@ MXS_MODULE* MXS_CREATE_MODULE() &Dbfw::s_object, NULL, /* Process init. */ NULL, /* Process finish. */ - NULL, /* Thread init. */ - NULL, /* Thread finish. */ + dbfw_thr_init, /* Thread init. */ + dbfw_thr_finish, /* Thread finish. */ { { "rules", @@ -658,24 +678,15 @@ void dbfw_yyerror(void* scanner, const char* error) */ static SRule find_rule_by_name(const RuleList& rules, std::string name) { - class RuleNameComparator + for (RuleList::const_iterator it = rules.begin(); it != rules.end(); it++) { - public: - RuleNameComparator(std::string name): - m_name(name) - {} - - bool operator()(const SRule& rule) + if ((*it)->name() == name) { - return rule->name() == m_name; + return *it; } + } - private: - std::string m_name; - }; - - RuleList::const_iterator it = std::find_if(rules.begin(), rules.end(), RuleNameComparator(name)); - return it != rules.end() ? *it : SRule(); + return SRule(); } bool set_rule_name(void* scanner, char* name) @@ -1079,11 +1090,11 @@ bool replace_rules(Dbfw* instance) if (process_rule_file(filename, &rules, &users)) { - this_thread.rules.swap(rules); - this_thread.users.swap(users); + this_thread->rules.swap(rules); + this_thread->users.swap(users); rval = true; } - else if (!this_thread.rules.empty() && !this_thread.users.empty()) + else if (!this_thread->rules.empty() && !this_thread->users.empty()) { MXS_ERROR("Failed to parse rules at '%s'. Old rules are still used.", filename.c_str()); @@ -1103,14 +1114,14 @@ static bool update_rules(Dbfw* my_instance) bool rval = true; int rule_version = my_instance->get_rule_version(); - if (this_thread.rule_version < rule_version) + if (this_thread->rule_version < rule_version) { if (!replace_rules(my_instance)) { rval = false; } - this_thread.rule_version = rule_version; + this_thread->rule_version = rule_version; } return rval; @@ -1395,7 +1406,7 @@ int DbfwSession::routeQuery(GWBUF* buffer) ss_dassert(analyzed_queue); } - SUser suser = find_user_data(this_thread.users, user(), remote()); + SUser suser = find_user_data(this_thread->users, user(), remote()); bool query_ok = false; if (command_is_mandatory(buffer)) @@ -1659,7 +1670,7 @@ void Dbfw::diagnostics(DCB *dcb) const dcb_printf(dcb, "Firewall Filter\n"); dcb_printf(dcb, "Rule, Type, Times Matched\n"); - for (RuleList::const_iterator it = this_thread.rules.begin(); it != this_thread.rules.end(); it++) + for (RuleList::const_iterator it = this_thread->rules.begin(); it != this_thread->rules.end(); it++) { const SRule& rule = *it; char buf[rule->name().length() + 200]; @@ -1680,5 +1691,5 @@ void Dbfw::diagnostics(DCB *dcb) const */ json_t* Dbfw::diagnostics_json() const { - return rules_to_json(this_thread.rules); + return rules_to_json(this_thread->rules); }