Freigeben über


一个没配置impersonate却和impersonate权限相关的linked server问题

当我们采用最简单的方法配置了一个SQL Server,如下图:

却出现了一个莫名奇妙的错误:

ERROR1:

TCP Provider: An attempt was made to access a socket in a way forbidden by its access permissions.

TCP Provider: No such host is known.

 

ERROR2:

SQL Network Interfaces: Error Locating Server/Instance Specified [xFFFFFFFF].

OLE DB provider "SQLNCLI" for linked server "AUHCM" returned message "Login timeout expired".

OLE DB provider "SQLNCLI" for linked server "AUHCM" returned message "An error has occurred while establishing a connection to the server. When connecting to SQL Server 2005, this failure may be caused by the fact that under the default settings SQL Server does not allow remote connections.". (.Net SqlClient Data Provider)

 

这两个错误并没有提供给我们任何有用的信息,有可能与权限有关,又没有说是哪里的权限,有可能是网络问题,又没有说是什么网络问题。

而这个错误的背景是这样的:

1. 使用最简单的remote SQL login和password来配置linked server(根据上图,显然我没有配置任何与impersonate相关的设置,并且第四个选项本来就会忽略这些设置。)

2. 我们通过management studio使用这个SQL login可以轻而易举地直连到远端的实例,但是创建linked server就是失败。

3. 我们创建一个ODBC datasource也可以轻而易举地连接到远端的实例,而且ODBC和linked server一样,都是利用同一个SQL native client provider的。

4. 互相都能ping通,也能telnet

5. 在netmon trace中我们甚至看不到这台SQL Server与远端的linked server做通讯,它似乎什么都没记录。

6. 我使用的是windows验证登陆的本地的local SQL Server。

7. 然后就发生了上述奇怪的错误

于是我尝试使用混合验证,并使用SQL账户登陆本地的local SQL Server,再使用上图完全一样的配置方法配置linked server,我发现我可以成功地配置linked server了。

然而,我再次换成windows验证时,还是失败!

首先,我们来解释一下这四个选项的区别:

For a login not defined in the list above, connection will:

Not be made – 说明如果login登录名不在上述的impersonate list(模拟列表)中,就不能登陆

Be made without using a security context – 说明如果login登录名不在上述的impersonate list(模拟列表)中,也可以登陆,而且不检查这个账户的安全权限。

Be made using the login’s current security context – 说明如果login登录名不在上述的impersonate list(模拟列表)中,会根据当前登陆本地实例的login登录名的安全权限进行linked server的远程连接。

Be made using this security context – 说明如果login登录名不在上述的impersonate list(模拟列表)中,会直接采用下述的这个login登录名的安全权限进行linked server的远程连接。

当我们采取第四项时,理论上,我们只检查这个login的权限,更何况我们通过这个login可以直连到远端实例。我们收集一下process monitor log来看看它究竟做了什么:

我们发现它要去访问注册表HKCU(HKey Current User),并且返回了一个结果“BAD IMPERSONATION”!这表明,虽然我们是通过SQL login去访问远端linked server,然而我们是通过windows验证访问地本地实例,无论我们是否设置过impersonate list(模拟列表),它都会固执地去检查当前用户的impersonate(模拟)权限!

这是为什么呢?

因为从windows角度来讲,也有一层impersonate模拟的权限管理叫做“impersonate a client after authentication”,而且我们的SQL Server 服务启动账户,也就是我们当前的这个windows account正好没有这个权限!而这个权限会在组策略或域策略中,如果当前的账户是域账户,并且当前的域策略中正好除去了这个权限,你可能要给你的DC工程师打电话了。

根据上图,你可以为某个用户或组赋予“impersonate a client after authentication”。之后,你再使用这个windows账户登陆SQL Server的时候,就可以顺利地配置linked server了。

Comments

  • Anonymous
    October 25, 2011
    呃,我的评论被吞了。这个案例比较有意思,还有一个类似的情况是用SQL Auth连远程SQL实例的时候,如果使用Named Pipes的方式,可能会遇到sspi context 或者连接错误,因为Named Pipes要求用当前客户端登录账号先打开远程服务器的smb share