web-dev-qa-db-ja.com

ADSIリンクサーバー:リンクサーバーとしてではなく、VBAでADをクエリできるのはなぜですか?

私が行ったすべての読書と調査の後、これはこの質問を投稿するための最も論理的な場所のようです:

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
1
Chad Harrison

これは、リンクサーバーの[セキュリティ設定]ページで[セキュリティコンテキストを使用せずに作成する]オプションを使用した場合に発生する可能性があります。これにより、匿名のLDAP呼び出しが行われます。最近(Server 2008以降)の匿名LDAP操作はデフォルトで許可されていません。

私のテストでは、「ログインのセキュリティコンテキストを使用して作成する」オプションを使用すると、SQLサーバーサービスが実行されている資格情報でLDAP呼び出しが行われることが示されています。

「ログインのセキュリティコンテキストを使用して作成する」、ローカルログインをリモートユーザーにマップする、またはデフォルトの資格情報を入力する(ダイアログのオプション4)のいずれかを使用することをお勧めします。

enter image description here

すべての場合において、リンクサーバー専用のADユーザーアカウントを使用することをお勧めします。

UserAccountControlなどの機密属性をクエリしていることに注意してください。デフォルトでは、通常のドメインユーザーはこの属性を読み取ることができません。つまり、クエリが完全な結果セットを返さない場合があります。専用のADアカウントを使用してこれを克服し、該当する場合はuserAccountControl属性に対するREADアクセス許可を付与できます。

また、サーバーレスバインディングを使用しないことをお勧めします。少なくともドメイン名を指定します。

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

これは、LDAP応答の遅延やデータの不整合を回避するのに役立ちます。

3
iPath