После всего прочитанного и проведенного мною исследований это кажется наиболее логичным местом для размещения этого вопроса:
Почему я могу запрашивать 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 и / или несогласованности данных.