mysql - MySQL + ODBC 为什么我可以在没有任何凭据的情况下连接 SQLConnect
问题描述
我正在尝试从带有 C 程序的 Windows 客户端连接到在 Ubuntu 18.04 上运行的 MySQL 数据库。
使用 SQLConnect ODBC API 连接时,即使我没有提供用户密码,连接也会成功。
- 执行 select current_user() 返回我是 admin@% (这是我创建的用户)
- 我可以运行 SELECT 查询、创建、删除表等等。
如果我尝试使用错误的密码连接,我无法连接,如果我尝试使用正确的密码,我可以连接(这显然是预期的行为)
如何在不提供密码的情况下连接到 MySQL 数据库?
我错过了与 MySQL 配置相关的内容吗?
这是我的环境:
MySQL 版本:服务器版本:5.7.29-0ubuntu0.18.04.1 (Ubuntu) ODBC 驱动程序版本:MySQL ODBC 8.0 Unicode 驱动程序 8.00.15.00 客户端:Win8.1 x64 pro
和代码:
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <sql.h>
#include <sqlext.h>
#define SUCCEEDED(x) (SQL_SUCCESS == x || SQL_SUCCESS_WITH_INFO == x)
void ShowError(SQLHANDLE env, SQLHANDLE dbc, SQLHANDLE stmt);
int _tmain(int argc, TCHAR* argv[])
{
SQLHANDLE env = NULL;
SQLHANDLE dbc = NULL;
SQLHANDLE stmt = NULL;
SQLSMALLINT fieldCount = 0;
SQLRETURN ret;
TCHAR bufWhereWeAre[1000];
LPCTSTR whereWeAre = _T("starting");
int currentLine = 0;
do
{
whereWeAre = _T("alloc env");
ret = SQLAllocHandle(SQL_HANDLE_ENV, NULL, &env);
if (!SUCCEEDED(ret))
break;
whereWeAre = _T("set env attr");
ret = SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, SQL_OV_ODBC3, SQL_NTS);
if (!SUCCEEDED(ret))
break;
whereWeAre = _T("alloc dbc");
ret = SQLAllocHandle(SQL_HANDLE_DBC, env, &dbc);
if (!SUCCEEDED(ret))
break;
whereWeAre = _T("connect");
// connection succeeds using the right credential
//ret = SQLConnect(dbc, _T("UBUNTU18"), SQL_NTS, _T("admin"), SQL_NTS, _T("The actual password for admin"), 0);
// connection succeeds if password is not provided (EXPECTING credential error)
//ret = SQLConnect(dbc, _T("UBUNTU18"), SQL_NTS, _T("admin"), SQL_NTS, NULL, 0);
// connection succeeds if no credential is provided (EXPECTING credential error)
//ret = SQLConnect(dbc, _T("UBUNTU18"), SQL_NTS, NULL, 0, NULL, 0);
// connection fails with wrong credential (expected behavior)
ret = SQLConnect(dbc, _T("UBUNTU18"), SQL_NTS, _T("admin"), SQL_NTS, _T("wrong password for admin"), 0);
if (!SUCCEEDED(ret))
break;
whereWeAre = _T("alloc stmt");
ret = SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt);
if (!SUCCEEDED(ret))
break;
whereWeAre = _T("execdirect");
ret = SQLExecDirect(stmt, _T("select current_user();"), SQL_NTS);
//ret = SQLExecDirect(stmt, _T("SELECT T.`term_id` AS term_id,T.`name` AS name,T.`slug` AS slug,T.`term_group` AS term_group FROM `wp_terms` T"), SQL_NTS);
if (!SUCCEEDED(ret))
break;
whereWeAre = _T("num result cols");
ret = SQLNumResultCols(stmt, &fieldCount);
if (!SUCCEEDED(ret))
break;
whereWeAre = _T("fetch data");
ret = SQLFetch(stmt);
currentLine = 0;
while (SUCCEEDED(ret))
{
TCHAR buf[1000];
int bufSize = sizeof(buf) / sizeof(TCHAR);
int i;
++currentLine;
for (i=1; i<=fieldCount; i++)
{
SQLLEN len = 0;
_stprintf_s(bufWhereWeAre, bufSize, _T("line %d, field %d"), currentLine, i);
whereWeAre = bufWhereWeAre;
ret = SQLGetData(stmt, i, SQL_C_TCHAR, buf, sizeof(buf)/sizeof(TCHAR)-1, &len);
if (!SUCCEEDED(ret))
break;
_tprintf(buf);
if (i == fieldCount)
_tprintf("\n");
else
_tprintf("\t");
}
ret = SQLFetch(stmt);
}
if (SQL_NO_DATA_FOUND != ret
&& !SUCCEEDED(ret))
break;
ret = SQLFreeStmt(stmt, SQL_DROP);
if (!SUCCEEDED(ret))
break;
stmt = NULL;
}
while (FALSE);
if (!SUCCEEDED(ret))
{
_tprintf(_T("%s\n"), whereWeAre);
ShowError(env, dbc, stmt);
}
if (NULL != stmt)
SQLFreeStmt(stmt, SQL_DROP);
if (NULL != dbc)
SQLFreeConnect(dbc);
if (NULL != env)
SQLFreeEnv(env);
return 0;
}
void ShowError(SQLHANDLE env, SQLHANDLE dbc, SQLHANDLE stmt)
{
SQLTCHAR state[100];
SQLINTEGER nativeError = 0;
SQLTCHAR errorMsg[1000];
int sizeErrorMsgInTCHAR = sizeof(errorMsg)/sizeof(TCHAR) - 1; // -1: for possibly buggy drivers...
SQLSMALLINT returnedErrorMsgSize = 0;
SQLRETURN ret = SQLError(env, dbc, stmt, state, &nativeError, errorMsg, sizeErrorMsgInTCHAR, &returnedErrorMsgSize);
if (!SUCCEEDED(ret))
_tprintf(_T("SQLError returned an error...: %d"), (int) ret);
else
{
returnedErrorMsgSize = min(max(0, returnedErrorMsgSize), sizeErrorMsgInTCHAR);
errorMsg[returnedErrorMsgSize] = 0;
_tprintf(_T("%s\n"), errorMsg);
}
}
解决方案
推荐阅读
- android - Dagger Hilt - What’s the point of @ApplicationContext and @ActivityContext?
- apache-spark - 为 pyspark udf 编写测试
- javascript - 如何检测它是否在 onbeforeunload 事件中重新加载?
- pip - 如何在使用 pip3 安装 mlpy 时修复 gcc 错误
- timezone - 如何显示时区缩写?
- react-native - 我们应该在 React Native 中使用 npm 在本地还是全局安装包?
- vlc - Display3 上的 VLC 全屏从 CMD 运行
- c++ - OSG:为什么有纹理坐标数组而没有纹理本身?
- mysql - 在Laravel中导出带有sql条件的excel表
- stripe-payments - 事件的条带顺序