From e71bd28f3fa74c257af62b064181e6fb93e4035a Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Tue, 31 Dec 2013 13:08:29 +0100 Subject: [PATCH] - Fix bug MDEV-5486 (fail to create or drop a table dbn.tbn when no default database) modified: storage/connect/ha_connect.cc storage/connect/ha_connect.h - Typo modified: storage/connect/odbconn.cpp storage/connect/user_connect.h --- storage/connect/ha_connect.cc | 51 ++++++++++++++++++++++++---------- storage/connect/ha_connect.h | 3 +- storage/connect/odbconn.cpp | 3 +- storage/connect/user_connect.h | 4 +-- 4 files changed, 42 insertions(+), 19 deletions(-) diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index 8b0e3a2b036..d051ef76698 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -2749,8 +2749,10 @@ int ha_connect::delete_all_rows() } // end of delete_all_rows -bool ha_connect::check_privileges(THD *thd, PTOS options) +bool ha_connect::check_privileges(THD *thd, PTOS options, char *dbn) { + const char *db= (dbn && *dbn) ? dbn : NULL; + if (!options->type) { if (options->srcdef) options->type= "MYSQL"; @@ -2800,7 +2802,7 @@ bool ha_connect::check_privileges(THD *thd, PTOS options) case TAB_MAC: case TAB_WMI: case TAB_OEM: - return check_access(thd, FILE_ACL, NULL, NULL, NULL, 0, 0); + return check_access(thd, FILE_ACL, db, NULL, NULL, 0, 0); // This is temporary until a solution is found case TAB_TBL: @@ -3026,12 +3028,6 @@ int ha_connect::external_lock(THD *thd, int lock_type) if (!g) DBUG_RETURN(HA_ERR_INTERNAL_ERROR); - if (lock_type != F_UNLCK && check_privileges(thd, options)) { - strcpy(g->Message, "This operation requires the FILE privilege"); - printf("%s\n", g->Message); - DBUG_RETURN(HA_ERR_INTERNAL_ERROR); - } // endif check_privileges - // Action will depend on lock_type switch (lock_type) { case F_WRLCK: @@ -3167,6 +3163,14 @@ int ha_connect::external_lock(THD *thd, int lock_type) DBUG_RETURN(rc); } // endif MODE_ANY + DBUG_ASSERT(table && table->s); + + if (check_privileges(thd, options, table->s->db.str)) { + strcpy(g->Message, "This operation requires the FILE privilege"); + printf("%s\n", g->Message); + DBUG_RETURN(HA_ERR_INTERNAL_ERROR); + } // endif check_privileges + // Table mode depends on the query type newmode= CheckMode(g, thd, newmode, &xcheck, &cras); @@ -3212,9 +3216,6 @@ int ha_connect::external_lock(THD *thd, int lock_type) xmod= newmode; - if (!table) - rc= 3; // Logical error - // Delay open until used fields are known } // endif tdbp @@ -3327,7 +3328,7 @@ filename_to_dbname_and_tablename(const char *filename, memcpy(database, d.str, d.length); database[d.length]= '\0'; return false; -} +} // end of filename_to_dbname_and_tablename /** @@ -3385,7 +3386,7 @@ int ha_connect::delete_or_rename_table(const char *name, const char *to) // Now we can work pos= share->option_struct; - if (check_privileges(thd, pos)) + if (check_privileges(thd, pos, db)) { free_table_share(share); DBUG_RETURN(HA_ERR_INTERNAL_ERROR); @@ -4360,6 +4361,28 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, return HA_ERR_INTERNAL_ERROR; } // end of connect_assisted_discovery +/** + Get the database name from a qualified table name. +*/ +char *ha_connect::GetDBfromName(const char *name) +{ + char *db, dbname[128], tbname[128]; + + if (filename_to_dbname_and_tablename(name, dbname, sizeof(dbname), + tbname, sizeof(tbname))) + *dbname= 0; + + if (*dbname) { + assert(xp && xp->g); + db= (char*)PlugSubAlloc(xp->g, NULL, strlen(dbname + 1)); + strcpy(db, dbname); + } else + db= NULL; + + return db; +} // end of GetDBfromName + + /** @brief create() is called to create a database. The variable name will have the name @@ -4418,7 +4441,7 @@ int ha_connect::create(const char *name, TABLE *table_arg, DBUG_RETURN(HA_ERR_INTERNAL_ERROR); } // endif ttp - if (check_privileges(thd, options)) + if (check_privileges(thd, options, GetDBfromName(name))) DBUG_RETURN(HA_ERR_INTERNAL_ERROR); if (options->data_charset) { diff --git a/storage/connect/ha_connect.h b/storage/connect/ha_connect.h index dd67773efc0..754e2e37a7f 100644 --- a/storage/connect/ha_connect.h +++ b/storage/connect/ha_connect.h @@ -445,8 +445,9 @@ const char *GetValStr(OPVAL vop, bool neg); int optimize(THD* thd, HA_CHECK_OPT* check_opt); protected: - bool check_privileges(THD *thd, PTOS options); + bool check_privileges(THD *thd, PTOS options, char *dbn); MODE CheckMode(PGLOBAL g, THD *thd, MODE newmode, bool *chk, bool *cras); + char *GetDBfromName(const char *name); // Members static ulong num; // Tracable handler number diff --git a/storage/connect/odbconn.cpp b/storage/connect/odbconn.cpp index a8a393d0ab7..a64dff76314 100644 --- a/storage/connect/odbconn.cpp +++ b/storage/connect/odbconn.cpp @@ -2023,7 +2023,6 @@ bool ODBConn::GetDrivers(PQRYRES qrp) return rv; } // end of GetDrivers - /***********************************************************************/ /* A helper class to split an optionally qualified table name into */ /* components. */ @@ -2042,7 +2041,7 @@ class SQLQualifiedName { S->str= str; S->length= length; - } // eend of lex_string_set + } // end of lex_string_set void lex_string_shorten_down(MYSQL_LEX_STRING *S, size_t offs) { diff --git a/storage/connect/user_connect.h b/storage/connect/user_connect.h index 386e678b138..ef17a958824 100644 --- a/storage/connect/user_connect.h +++ b/storage/connect/user_connect.h @@ -62,10 +62,10 @@ public: static PCONNECT to_users; // To the chain of users PCONNECT next; // Next user in chain PCONNECT previous; // Previous user in chain - PGLOBAL g; // The common handle to CONNECT + PGLOBAL g; // The common handle to CONNECT //char dbname[32]; // The DBCONNECT database query_id_t last_query_id; // the latest user query id - int count; // if used by several handlers + int count; // if used by several handlers // Statistics ulong nrd, fnd, nfd; ulonglong tb1;