Назад | Перейти на главную страницу

Связанный сервер 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

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

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

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

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

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

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

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

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