ADSI Linked Server: Por que eu posso consultar o AD no VBA, mas não como um servidor vinculado?

1

Depois de toda a leitura e pesquisa que fiz, esse parece ser o lugar mais lógico para postar essa pergunta:

Por que posso consultar o Active Directory usando o VBA, mas não um servidor vinculado no SQL Management Studio 2012?

Primeiro, eu consegui fazer isso antes, mas muitas luas atrás com o SQL Server 2005.

Aqui está a consulta que estou tentando:

SELECT * FROM OpenQuery(
ADSI,
'SELECT displayName, title, department, employeeID, userAccountControl
FROM ''LDAP://dc=testdomain''
WHERE objectCategory = ''Person'' AND
      objectClass = ''user'' AND
      userAccountControl=512')

Aqui está o erro que estou recebendo:

Msg 7321, Level 16, State 2, Line 1
An error occured while preparing the query "SELECT displayName, title, department, employeeID, userAccountControl
            FROM 'LDAP://dc=testdomain'
            WHERE objectCategory = 'Person' AND
                  objectClass = 'user' AND
            userAccountControl=512" for execution against OLE DB provider "ADsDSOObject" for linked server "ADSI".

O problema com essa mensagem de erro é que ela é muito genérica e aparentemente não gera nada útil. Tudo o que eu li parece ser um problema de permissão ou a sintaxe da consulta, e eu suponho que isso significa no contexto do meu login de instância do SQL e como a segurança é configurada no servidor vinculado. O código VBA abaixo funciona e está usando uma consulta muito semelhante e nem a mais simples das consultas funcionou no servidor vinculado. Eu também tenho acesso ao Active Directory que estou tentando vincular e isso é comprovado pelo trecho de código do VBA que tenho na parte inferior (apenas lá para referência). A coisa é, eu acredito que tenho todos os privilégios certos para que isso funcione.

No entanto, muito do que está sendo sugerido em sites diferentes envolve fazer modificações na instância SQL que não são prontamente óbvias de quais são os impactos a longo prazo, pois esse servidor ainda está sendo construído. Eu tenho privilégios elevados temporários para construí-lo.

Aqui estão os detalhes e os parâmetros em que configurei o servidor vinculado:

SQL Server 11.0.5058
Linked Server: ADSI
Provider: OLE DB Provider for Microsoft Directory Services
Product name: Active Directory Services 2.5
Data source: adsdatasource
Provider string: ADsDSOObject

Be made using the login's current security context

Ole DB Provider  Options:
Allow in process

No entanto, a única coisa que descobri que poderia me diferenciar de todos os outros blogs sobre esse erro é quando tento detalhar as tabelas de servidores vinculados e ver (Objetos do servidor > Servidores vinculados > ADSI > ; Catálogos > padrão > Tabelas). Depois que clico para expandir o nível de tabelas, obtenho o seguinte erro:

Failed to retreive data for this request. (Microsoft.SqlServer.Management.Sdk.Sfc)

Additional information:
    An exception occured while executing a Transact-SQL statement or batch.
    (Microsoft.SqlServer.ConnectionInfo)
        Cannot obtain the required interface ("IID_IDBSchemaRowset") from OLE DB provider "ADsDSOObject"
        for linked server "ADSI". (Microsoft SQL Server, Error: 7301)

Esse IID_IDBSchemaRowset parece ser minha única pista, mas parece ser um buraco de coelho escuro e profundo para baixo e não tenho certeza se é para lá que preciso ir. Ajuda!

Para referência

'References: Microsoft ActiveX Data Objects 2.8 Library
Public Sub testADSI()
    On Error Resume Next

    Dim cn As ADODB.Connection
    Dim cmd As ADODB.Command
    Dim rs as ADODB.Recordset
    Dim MySql as String
    Dim n as Integer

    Set cn = New ADODB.Connection
    Set cmd = New ADODB.Command
    Set rs = New ADODB.Recordset

    cn.Provider = "ADsDSOObject"
    cn.Open "Active Directory Provider"

    Set cmd.ActiveConnection = cn

    cmd.Properties("Page Size")= 1000

    MySql = "SELECT displayName, title, department, employeedID, userAccountControl " & _
            "FROM 'LDAP://dc=testdomain' " _ &
            "WHERE objectCategory = 'Person' AND " & _
                  "objectClass = 'user' AND " & _
                  "userAccountControl=512" 

    rs.Open MySql, cn, 1

    If rs.RecordCount > 0 Then
        MsgBox "Sucess! " & rs.RecordCount & " records found!"
    Else
        MsgBox "No records"
    End IF
End Sub
    
por Chad Harrison 06.03.2015 / 01:34

1 resposta

3

Isso pode acontecer se você usar a opção "Criar sem usar o contexto de segurança" na página Configurações de segurança do servidor vinculado. Isso resulta em fazer uma chamada LDAP anônima. Atualmente, as operações LDAP anônimas (Server 2008 ou posterior) não são permitidas por padrão.

Meus testes mostram que a opção "Seja feito usando o contexto de segurança do login" faz a chamada LDAP sob as credenciais das quais o serviço do servidor SQL está sendo executado.

Posso sugerir usar "Seja criado usando o contexto de segurança do login", mapeie o login local para o usuário remoto ou apenas insira as credenciais padrão (opção 4 na caixa de diálogo):

Em todos os casos, sugiro usar uma conta de usuário dedicada do AD para o servidor vinculado.

Por favor, note que você está consultando atributos sensíveis como userAccountControl. Por padrão, os usuários de domínio regular não podem ler esse atributo, ou seja, sua consulta pode não retornar um conjunto completo de resultados. Você pode superar isso usando uma conta do AD dedicada e conceder a permissão READ ao atributo userAccountControl, quando aplicável.

Além disso, sugiro não usar a ligação sem servidor. Especifique pelo menos o nome do domínio:

LDAP: //mydomain.local/dc=mydomain,dc=local

Isso pode ajudá-lo a evitar respostas LDAP lentas e / ou inconsistência de dados.

    
por 28.03.2015 / 00:38