无法使用 ISQL 连接到 MS-SQL

Unable to connect to MS-SQL with ISQL

首先在 StackExchange 上 post - 请放轻松 :)

我在 Centos 6 中设置了 ODBC,以便从我的 Asterisk 安装执行 ms-sql 查询。

我的配置文件是:

/etc/odbc.ini

[asterisk-connector]
Description     = MS SQL connection to 'asterisk' database
Driver          = /usr/lib64/libtdsodbc.so
Setup           = /usr/lib64/libtdsS.so
Servername      = SQL2
Port            = 1433
Username        = MyUsername
Password        = MyPassword
TDS_Version     = 7.0

/etc/odbcinst.ini

[odbc-test]
Description = TDS connection
Driver = /usr/lib64/libtdsodbc.so
Setup = /usr/lib64/libtdsS.so
UsageCount = 1
FileUsage = 1

/etc/asterisk/res_odbc.conf

[asterisk-connector]
enabled => yes
dsn => asterisk-connector
username => MyUsername
password => MyPassword
pooling => no
limit =>
pre-connect => yes

当我输入密码和用户名时,我可以通过 ISQL 连接:

[root@TestVM etc]# isql -v asterisk-connector MyUsername MyPassword
+---------------------------------------+
| Connected!                            |
|                                       |
| sql-statement                         |
| help [tablename]                      |
| quit                                  |
|                                       |
+---------------------------------------+
SQL>

..但我应该可以在没有用户名/密码的情况下连接。所有 returns 是:

[root@TestVM etc]# isql -v asterisk-connector
[S1000][unixODBC][FreeTDS][SQL Server]Unable to connect to data source
[01000][unixODBC][FreeTDS][SQL Server]Adaptive Server connection failed
[ISQL]ERROR: Could not SQLConnect

好像我SQL无法从配置文件中读取用户名和密码。

我需要能够从 Asterisk 拨号方案中执行 MS-SQL 查找,但要做到这一点,我必须能够仅使用数据源名称调用 ISQL 和无法传入认证参数

我在网上阅读的所有指南都说我应该能够连接

isql -v asterisk-connector

命令,但这对我来说没有发生。

几天来我一直在为此苦苦思索,所以任何帮助或正确方向的指示都将不胜感激。

提前致谢。

编辑:

我已经打开了日志记录,可能会有一些线索。用户名和密码肯定没有传入。看:

[ODBC][27557][1455205133.129690][SQLConnect.c][3614]
                Entry:
                        Connection = 0xac3080
                        Server Name = [asterisk-connector][length = 18 (SQL_NTS)]
                        User Name = [NULL]
                        Authentication = [NULL]
                UNICODE Using encoding ASCII 'ISO8859-1' and UNICODE 'UCS-2LE'

                DIAG [01000] [FreeTDS][SQL Server]Adaptive Server connection failed

                DIAG [S1000] [FreeTDS][SQL Server]Unable to connect to data source

所以这里的用户名和身份验证是[NULL]。它显然不是在 odbc.ini 或 res_odbc.conf 中提取用户名/密码,但问题是为什么。我会继续调查:)

编辑2:

OSQL 实用程序 returns:

[root@TestVM etc]# osql -S SQL2 -U MyUsername -P MyPassword
checking shared odbc libraries linked to isql for default directories...
strings: '': No such file
        trying /tmp/sqlH ... no
        trying /tmp/sqlL ... no
        trying /etc ... OK
checking odbc.ini files
        reading /root/.odbc.ini
[SQL2] not found in /root/.odbc.ini
        reading /etc/odbc.ini
[SQL2] found in /etc/odbc.ini
found this section:
looking for driver for DSN [SQL2] in /etc/odbc.ini
  no driver mentioned for [SQL2] in odbc.ini
looking for driver for DSN [default] in /etc/odbc.ini
osql: error: no driver found for [SQL2] in odbc.ini

我会将您的 odbc.ini 中的“用户名”替换为“UID”,将“密码”替换为“PWD” .... 来自 FreeTDS Manual - Chapter 4 - Preparing ODBC:

The original ODBC solution to this conundrum employed the odbc.ini file. odbc.ini stored information about a server, known generically as a Data Source Name (DSN). ODBC applications connected to the server by calling the function SQLConnect(DSN, UID, PWD), where DSN is the Data Source Name entry in odbc.ini, UID is the username, and PWD the password. Any and all information about the DSN was kept in odbc.ini. And all was right with the world.

The ODBC 3.0 specification introduced a new function: SQLDriverConnect. The connection attributes are provided as a single argument, a string of concatenated name-value pairs. SQLDriverConnect subsumed the functionality of SQLConnect, in that the name-value pair string allowed the caller to pass — in addition the the original DSN, UID, and PWD — any other parameters the driver could accept. Moreover, the application can specify which driver to use. In effect, it became possible to specify the entire set of DSN properties as parameters to SQLDriverConnect, obviating the need for odbc.ini. This led to the use of the so-called DSN-less configuration, a setup with no odbc.ini.

好的,所以我解决了(差不多)。我的 odbc 文件中的密码和用户名被忽略了。因为我是从 Asterisk 调用数据库查询,所以我也使用了一个名为 res_odbc.ini 的文件。这也包含我的用户名和密码,当我 运行 来自 Asterisk 的查询时,它连接 returns 正确的结果。

如果有帮助,这是我的最终工作配置。

odbc.ini

[asterisk-connector]
Description = MS SQL connection to asterisk database
driver = /usr/lib64/libtdsodbc.so
servername = SQL2
Port = 1433
User = MyUsername
Password = MyPassword

odbcinst.ini

[FreeTDS]
Description = TDS connection
Driver = /usr/lib64/libtdsodbc.so
UsageCount = 1

[ODBC]
trace           = Yes
TraceFile       = /tmp/sql.log
ForceTrace      = Yes

freetds.conf

#   $Id: freetds.conf,v 1.12 2007/12/25 06:02:36 jklowden Exp $
#
# This file is installed by FreeTDS if no file by the same
# name is found in the installation directory.
#
# For information about the layout of this file and its settings,
# see the freetds.conf manpage "man freetds.conf".

# Global settings are overridden by those in a database
# server specific section
[global]
        # TDS protocol version
;       tds version = 4.2

        # Whether to write a TDSDUMP file for diagnostic purposes
        # (setting this to /tmp is insecure on a multi-user system)
        dump file = /tmp/freetds.log
;       debug flags = 0xffff

        # Command and connection timeouts
;       timeout = 10
;       connect timeout = 10

        # If you get out-of-memory errors, it may mean that your client
        # is trying to allocate a huge buffer for a TEXT field.
        # Try setting 'text size' to a more reasonable limit
        text size = 64512

# A typical Sybase server
[egServer50]
        host = symachine.domain.com
        port = 5000
        tds version = 5.0

# A typical Microsoft server
[SQL2]
        host = 192.168.1.59
        port = 1433
        tds version = 8.0

res_odbc.conf

[asterisk-connector]
enabled = yes
dsn = asterisk-connector
username = MyUsername
password = MyPassword
pooling = no
limit = 1
pre-connect = yes

记得如果你用的是Centos 64位,修改驱动路径为lib64。大多数在线指南都有错误的(对于 64 位)路径。

祝你好运 - 很头疼:)

我就这个问题联系了 unixODBC 的开发者 Nick Gorham,他确认 isql 没有从配置文件中读取 username/password

Hi Nick,

I think unixODBC is a great project but I was surprised to see that it is insecure (or at least I don’t know how to use it properly).

When I connect to the database using the isql I have to type in the password. On a shared server this is insecure because the

$ ps –aux

Command shows the password in clear.

Is there a fix for that? Can I put the password in a file readable only by my user?

Thank you for your help.

答案:

Hi,

It depends on the driver. Some can read the user and password from the odbc.ini or ~/.odbc.ini file so you can store the password there.

isql is only designed as a simple test app, there is nothing stopping you from modifying ilsq to pull the user and password from a file of your choice, decrypting it if needed.

我遇到了一个稍微不同的问题,但我的 google 搜索将我引导到这里。尝试通过 isql 连接时,即使我在我的 odbc.ini 文件

中指定了一个用户,我仍然得到 Login failed for user ''
[SQLSERVER_SAMPLE]
Driver=ODBC Driver 17 for SQL Server
Server=SERVER
Database=DATABASE
Trusted_Connection=no
UID=USER
PWD=PASSWORD

我试了UIDUser,但都报了同样的错误。阅读 的解决方案后,我发现用户名和密码被忽略了。

我的解决方案是 运行 isql -v SQLSERVER_SAMPLE USER PASSWORD,即使在 odbc.ini 文件中指定了用户名和密码 - 而且它已连接。