Active Directory Service Interface

本页使用了标题或全文手工转换
维基百科,自由的百科全书

Active Directory Service Interface (ADSI) 是一组植基于 COM 技术上的应用程式开发接口,程序开发人员可以利用这些接口来连接并存取 Active Directory,并执行查询,更新或删除等管理功能,ADSI同时可支持以LDAP(轻量级目录存取协议)为主的目录服务(例如Novell Directory Service),以及以 Windows NT 网域为主所组成的 WinNT 网域目录。

接口结构[编辑]

ADSI 由 COM 以及原生函式库所组成,并封装在 activeds.dll 文件中,部分则被封装在 advaip32.dll 中,以 COM 原生接口方式呈现,以提供给 C/C++ 编程语言透过 COM 接口来取用,不过由于所有的原生接口均支持 COM Automation,因此 Visual Basic 或是 .NET Framework 的语言也可以利用 COM Interop 能力存取 ADSI 中的接口。

原生接口 (Native interfaces)[编辑]

activeds.dll 中封装了几个 ADSI 中最核心的接口:

  • IADs:作为所有 Active Directory 物件最顶层的接口,拥有最基础的功能,
  • IADsContainer:作为所有可收纳 Active Directory 物件的收纳器 (Container) 最顶层的接口,具有收纳器的基础功能。
  • IADsOpenDSObject:连接 Active Directory 之用(它只有 OpenDSObject() 一个方法),同时它会缓存住用来连接的安全资讯内容。
  • IADsNamespace:由目录服务提供者 (directory service provider) 提供,用来识别目录结构的命名空间之用。

activeds.dll 亦提供了几个依物件不同而实现的接口,像是:

  • IADsComputer:提供目录服务中的电脑 (computer) 物件。
  • IADsDomain:提供目录服务中的网域 (domain) 物件。
  • IADsUser:提供目录服务中的用户 (user) 物件。
  • IADsGroup:提供目录服务中的用户组 (group) 物件。
  • IADsOU:提供目录服务中的组织单元 (organization unit) 物件。
  • IADsCollection:提供目录服务物件集合。

在使用 ADSI 之时,有时会需要一些工具型功能,像是 DOMAIN\user 和 User Principal Name 间的转换,或是获取系统资讯等,ADSI 也提供了这类的接口:

  • IADsNameTranslate:在目录服务中在不同的名称间转换。
  • IADsWinNTSystemInfo:在目录服务中获取 Windows NT Directory Service 系统资讯。
  • IADsADSystemInfo:在目录服务中获取 LDAP Directory Service 系统资讯。
  • IADsPathname:剖析 X.500 名称与路径。

这些接口多是使用 C/C++ 编程语言来存取,若是使用 VB 或是 Scripting Language 时,则可以使用另外的方法来存取。

' Get user object from Active Directory.
Dim mach As IADsContainer
Dim usr as IADsUser

On Error GoTo Cleanup
Set mach = GetObject("WinNT://MyMachine,Computer")
Set usr = mach.Create("user","jeffsmith")
usr.SetInfo

Cleanup:
    If(Err.Number<>0) Then
        MsgBox("An error has occurred. " & Err.Number)
    End If
    Set mach = Nothing
    Set usr = Nothing
// binding Active Directory using C++ and native interface.
IADs *pObject;
HRESULT hr;

// Initialize COM.
CoInitialize(NULL);

hr = ADsGetObject(L"LDAP://CN=jeffsmith,DC=fabrikam,DC=com", 
        IID_IADs,
        (void**) &pObject);
if(SUCCEEDED(hr))
{
    // Use the object.

    // Release the object.
    pObject->Release()
}

// Uninitialize COM.
CoUninitialize();

函数[编辑]

ADSI 除了接口以外,也将部分功能使用函数方式显露,以简化调用原生接口需要处理的工作,较重要且经常被使用的有:

  • ADsOpenDSObject(),封装获取 IADs 或 IADsContainer 等物件的工作。
  • ADsGetObject(),封装利用已开启的 Active Directory Session 获取物件的工作。
  • ADsGetLastError(),获取在 ADSI 作业中,最后一个引发的错误。
  • AllocADsMem(), FreeADsMem(), AllocADsStr(), FreeADsStr(),配置与释放 ADSI 使用的资源。
  • ADsBuildEnumerator(), ADsEnumerateNext(), ADsFreeEnumerator():处理 ADSI 物件的枚举工作。

下列的例子,是使用 ADsOpenDSObject() 获取 IADs 物件的示例代码:

IADs *pObject;
LPWSTR szUsername = NULL;
LPWSTR szPassword = NULL
HRESULT hr;

// Insert code to securely retrieve the username and password.

hr = ADsOpenObject(L"LDAP://CN=Jeff,DC=Fabrikam,DC=com",
                   "jeffsmith",
                   "etercespot",
                   ADS_SECURE_AUTHENTICATION, 
                   IID_IADs,
                   (void**) &pObject);

.NET Framework 原生接口[编辑]

.NET Framework 中,另外提供了一个 .NET 专用的 ADSI 接口程序库 System.DirectoryService.dll,程序开发人员可以加入此程序库的参考来获取 ADSI 的功能,在这个原生类别库中,封装了两个类别,作为存取 Active Directory 的入口之用。

  • DirectoryEntry:此类别封装了 IADs 以及 IADsContainer 等原生接口,用来存取 Active Directory 的物件资料,以及 Schema 封装的资讯等等。
  • DirectorySearcher:此类别封装了 IDirectorySearch 接口,作为搜索 Active Directory 的主要工具,并使用 SearchResult 物件封装搜索结果,让 .NET 开发人员可以简化处理搜索结果的工作。

截至 .NET Framework 3.5 为止,ADSI 在 Managed Class Library 中有四个命名空间:

  • System.DirectoryServices:原生的 ADSI Managed 接口,封装 DirectoryEntry 和 DirectorySearcher 与工具类别。
  • System.DirectoryServices.AccountManagement:封装对 IADsUser, IADsComputer, IADsGroup 等接口,简化处理物件的工具。
  • System.DirectoryServices.ActiveDirectory:封装对 Active Directory 结构物件的工具。
  • System.DirectoryServices.Protocol:封装对 LDAP 协议与目录服务通讯的工具与基类。

下列为使用 C# 存取 DirectoryEntry 的示例代码:

DirectoryEntry ent = new DirectoryEntry();
DirectoryEntry ou = ent.Children.Find("OU=Consulting");

// Use the Add method to add a user to an organizational unit.
DirectoryEntry usr = ou.Children.Add("CN=New User","user");
// Set the samAccountName, then commit changes to the directory.
usr.Properties["samAccountName"].Value = "newuser"; 
usr.CommitChanges();

目录服务提供者 (directory service provider)[编辑]

ADSI 因为是使用了 LDAP 以及开放式目录等标准,因此只要目录服务的平台是以开放式目录标准实现 IADsNamespace 与其他目录服务提供者接口时,即可由 ADSI 来支持,目前 ADSI 有五种提供者:

  • ADSI LDAP Provider:Active Directory 官方主要的支持接口,连接字符串使用 LDAP:// 为主。
  • ADSI WinNT Provider:以 Windows NT 为主的支持接口,连接字符串使用 WinNT:// 为主。
  • ADSI NDS Provider:支持 Novell Directory Service,连接字符串使用 NDS:// 为主。
  • ADSI NWCOMPAT Provider:支持 Novell Netware 3.x 的网络服务,连接字符串使用 NWCOMPAT:// 为主。
  • ADSI IIS Provider:支持 IIS 内部的提供者,连接字符串以 IIS:// 为主,用于存取 IIS Metabase。

OLE DB Provider for Directory Services[编辑]

除了 ADSI 原生接口外,微软也为了 SQL Server 或是 ADO 应用程式开发人员发展了可使用 ADO 来存取 Active Directory 的驱动程式,此驱动程式使用 OLE DB 来开发,并且使用类似 SQL 指令的方式来存取 Active Directory,此驱动程式称为 OLE DB Provider for Directory Service,其 COM 的 Prog ID 为 ADsDSOObject

下例为使用 ADO 存取 Active Directory 的示例代码:

Dim Con As New Connection
Dim rs As New Recordset
Dim command As New Command
Dim usr As IADsUser

' Replace department for all users in OU=sales.
Set con = Server.CreateObject("ADODB.Connection")
con.Provider = "ADsDSOObject"
 
Set command = CreateObject("ADODB.Command")
Set command.ActiveConnection = con
 
command.CommandText = "SELECT AdsPath, cn FROM 'LDAP://OU=Sales,DC=Fabrikam,DC=com' WHERE objectClass = 'user'"
 
command.Properties("searchscope") = ADS_SCOPE_ONELEVEL
Set rs = command.Execute
While Not rs.EOF
    Set usr = GetObject(rs.Fields("AdsPath").Value)
    usr.Put "department", "1001"
    usr.SetInfo
    rs.MoveNext
Wend

下列指令为使用 SQL Server 查询来合并存取 Active Directory 的脚本[1]

-- create a linked server to active directory interface
EXEC sp_addlinkedserver 'ADSI', 'Active Directory Services 2.5', 'ADSDSOObject', 'adsdatasource' 

-- configure SQL Server to allow ad-hoc query and openquery statement.
EXEC sp_configure 'show advanced options', 1
reconfigure with override

EXEC sp_configure 'Ad Hoc Distributed Queries', 1 
reconfigure 

-- execute query via OpenQuery() statement
SELECT * FROM OpenQuery(ADSI, 'SELECT * FROM ''LDAP://DC=kodyaz,DC=com'' WHERE objectCategory=''user'' ') 

SELECT * FROM OpenQuery(ADSI, 'SELECT mail, displayName, userPrincipalName FROM ''LDAP://DC=kodyaz,DC=com'' WHERE objectCategory=''user'' ')

开发 Directory-Enabled 应用程式时可用的工具[编辑]

由于 ADSI 和 Active Directory 的特性,开发人员若没有使用适当的工具时,很难发展与目录服务链接 (directory-enabled) 的应用程式,因此微软为 Active Directory 提供了两种工具:

  • Active Directory Explorer:由 Sysinternals 团队所开发[2],现已并入 Microsoft TechNet 团队中,可用来浏览 AD 网域或树系的 LDAP 层次结构字符串,以及物件的属性资料。
  • ADSIEdit:在 Windows 2000 和 Windows Server 2003 时,由 Resource Kit Support Tools 安装包提供,到了 Windows Server 2008 时,则内建在系统中[3]

参考资料[编辑]

内容参考:

  1. ^ Running Active Directory Services Queries Using MS SQL Server OPENQUERY Command. [2009-01-01]. (原始内容存档于2009-01-05). 
  2. ^ AD Explorer. [2009-01-01]. (原始内容存档于2008-12-18). 
  3. ^ Adsiedit Overview: Active Directory. [2009-01-01]. (原始内容存档于2008-12-30). 

文章参考:

  1. MSDN Library: Active Directory Service Interface页面存档备份,存于互联网档案馆
  2. Directory Service in .NET Framework页面存档备份,存于互联网档案馆