Связанный сервер ADSI: почему я могу запрашивать AD в VBA, но не как связанный сервер?

После всех чтений и исследований, которые я провел, это кажется наиболее логичным местом для размещения этого вопроса:

Почему я могу запрашивать Active Directory, используя VBA, но не связанный сервер в SQL Management Studio 2012?

Во-первых, я мог сделать это раньше, но много месяцев назад с SQL Server 2005.

Вот запрос, который я пытаюсь:

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

Вот ошибка, которую я получаю:

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".

Проблема с этим сообщением об ошибке в том, что оно очень общее и, по-видимому, не дает ничего полезного. Все, что я прочитал, похоже, является проблемой с правами доступа или синтаксисом запроса, и я предполагаю, что это подразумевается в контексте моего имени входа экземпляра SQL и того, как настроена безопасность на Связанном сервере. Приведенный ниже код VBA работает и использует запрос, который очень похож, и даже не самые простые запросы работали на связанном сервере. У меня также есть доступ к Active Directory, на которую я пытаюсь ссылаться, и это подтверждается фрагментом кода VBA, который у меня есть внизу (только там для справки). Дело в том, я считаю, что у меня есть все необходимые привилегии для того, чтобы это работало.

Тем не менее, многое из того, что предлагается, относится к разным сайтам и включает в себя внесение изменений в экземпляр SQL, в которых не совсем очевидно, какие последствия окажутся долгосрочными, поскольку этот сервер все еще строится. У меня есть временные повышенные привилегии для его создания.

Вот детали и параметры, в которых я настроил связанный сервер:

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

Тем не менее, единственное, что я обнаружил, что может отличить меня от всех других блогов об этой ошибке, - это когда я пытаюсь развернуть таблицы и просмотреть связанные серверы (Объекты сервера> Связанные серверы> ADSI > Каталоги> по умолчанию> Таблицы). Как только я нажимаю, чтобы развернуть уровень таблиц, я получаю следующую ошибку:

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)

это IID_IDBSchemaRowset Кажется, это мое единственное руководство, но похоже, что это глубокая и темная кроличья нора вниз, и я не уверен, что мне нужно туда идти. Помогите!

Для справки

'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

1 ответ

Это может произойти, если вы используете параметр "Сделать без использования контекста безопасности" на странице настроек безопасности Связанного сервера. Это приводит к анонимному вызову LDAP. В наши дни (Server 2008 или более поздняя версия) анонимные операции LDAP по умолчанию запрещены.

Мои тесты показывают, что опция "Сделать с использованием контекста безопасности входа в систему" ​​делает вызов LDAP с учетными данными, из которых запущена служба сервера SQL.

Я могу предложить использовать "Сделать с использованием контекста безопасности входа в систему", сопоставить локальный вход в систему удаленному пользователю или просто ввести учетные данные по умолчанию (опция 4 в диалоговом окне):

введите описание здесь

Во всех случаях я бы предложил использовать выделенную учетную запись пользователя AD для связанного сервера.

Обратите внимание, что вы запрашиваете конфиденциальные атрибуты, такие как userAccountControl. По умолчанию обычные пользователи домена не могут прочитать этот атрибут, т. Е. Ваш запрос может не вернуть полный набор результатов. Вы можете преодолеть это, используя выделенную учетную запись AD и предоставив ей разрешение READ для атрибута userAccountControl, где это применимо.

Также я бы предложил не использовать привязку к серверу. Укажите хотя бы доменное имя:

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

Это может помочь вам избежать медленных ответов LDAP и / или несоответствия данных.

Другие вопросы по тегам