私が行ったすべての読書と調査の後、これはこの質問を投稿するための最も論理的な場所のようです:
SQL Management Studio2012でリンクサーバーではなくVBAを使用してActiveDirectoryにクエリを実行できるのはなぜですか?
まず、私は以前にこれを行うことができましたが、何ヶ月も前にSQL Server2005を使用していました。
これが私が試みているクエリです:
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コードは機能し、非常によく似たクエリを使用しており、リンクサーバーでは最も単純なクエリでも機能していません。リンクしようとしているActiveDirectoryにもアクセスできます。これは、下部にある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操作はデフォルトで許可されていません。
私のテストでは、「ログインのセキュリティコンテキストを使用して作成する」オプションを使用すると、SQLサーバーサービスが実行されている資格情報でLDAP呼び出しが行われることが示されています。
「ログインのセキュリティコンテキストを使用して作成する」、ローカルログインをリモートユーザーにマップする、またはデフォルトの資格情報を入力する(ダイアログのオプション4)のいずれかを使用することをお勧めします。
すべての場合において、リンクサーバー専用のADユーザーアカウントを使用することをお勧めします。
UserAccountControlなどの機密属性をクエリしていることに注意してください。デフォルトでは、通常のドメインユーザーはこの属性を読み取ることができません。つまり、クエリが完全な結果セットを返さない場合があります。専用のADアカウントを使用してこれを克服し、該当する場合はuserAccountControl属性に対するREADアクセス許可を付与できます。
また、サーバーレスバインディングを使用しないことをお勧めします。少なくともドメイン名を指定します。
LDAP://mydomain.local/dc=mydomain,dc=local
これは、LDAP応答の遅延やデータの不整合を回避するのに役立ちます。