Delphi深度探索:活动目录开发一

系统 Windows
ADSI 可以使 Windows NT 管理员的工作变得轻松,而ADSI即活动目录服务接口是想要使用活动目录服务的必要途径,本文就是介绍了对活动目录的使用。

活动目录是 Windows NT 4.0 和 Windows 2000 使用的目录服务。要想使用活动目录服务,需要调用 ADSI( 活动目录服务接口 ) 。 ADSI 是一组以 COM 接口的形式提供目录服务的,程序员可以通过 ADSI 存取四种网络目录结构: WinNT (Microsoft SAM 数据库 ) 、 LDAP ( 轻量目录存取协议 ) 、 NDS (NetWare 目录服务 ) 和 NWCOMPAT (Novell NetWare 3.x) 。

ADSI 可以使 Windows NT 管理员的工作变得轻松。 ADSI 支持管理员执行一些一般的管理任务,比如添加新用户、管理打印机、安全设定和控制 NT 域。因为 ADSI 使用 COM 接口,任何支持 COM 的编程语言像 Delphi 、 BCB 、 VB 、 VC 等都可以调用 ADSI 。

Delphi深度探索:活动目录开发一

图 1.111

 

活动目录运行在 Windows NT 4.0 和 Windows 2000 上。客户端程序可以运行在 Windows 95 、 Windows 98 、 Windows NT 4.0 和 Windows 2000 上。为了使用 ADSI ,必须安装 ADSI COM 接口。 ADSI 2.5 SDK 可以从 Microsoft ADSI 网址 http://www.microsoft.com/adsi 下载 。 SDK 包括文档、在线帮助和很多例子,不过不幸的是这些例子都是针对 VB 和 VC 的,这里我们将演示如何使用 Delphi 调用 ADSI 。

程序演示

图 1.111 所示的程序演示了如何调用 WinNT provider 提供的功能。演示程序用来连接到一个域,一旦连接到域,程序将会列出在 PDC 上找到的 NT 的用户和组以及域中的计算机。同时这个程序还演示了如何察看域中计算机上的服务和察看、添加、删除 NT 组中的用户。

使用 ADSI 控制 Windows NT/2000

ADSI 可以使我们控制用户、组、计算机、文件共享、打印任务、打印队列和服务等系统资源。要想在 Delphi 中调用 ADSI ,需要引入活动目录类型库,调用菜单 Project | Import Type Library 命令,选择 ActiveDs (Version 1.0) 点确认, Delphi 会生成相应的封装文件。

1.绑定 Win NT 目录服务

连接 Win NT 目录服务就是找到域控制器然后绑定到相应的对象上。绑定可以通过 ADsGetObject 或 ADsOpenObject 函数来实现。 ADsGetObject 函数声明如下:

function ADsGetObject(lpszPathName: PWideChar; const riid: TIID; out obj): HResult; stdcall; external 'activeds.dll';

第一个参数是对象的路径名,第二个参数是对象的接口标识符,第三个参数用于返回得到的被请求的接口指针。缺省条件下,函数根据当前用户进行安全认证。

ADsOpenObject 函数在不同的安全认证机制下绑定 ADSI 对象,它主要是通过调用参数返回的用户名和口令来认证的。函数声明如下:

function ADsOpenObject(lpszPathName: PWideChar; lpszUserName: PWideChar; lpszPassword: PWideChar; dwReserved: LongInt; const riid: TIID; out obj): HResult; stdcall; external 'activeds.dll';

第一个参数意义同上,第二、三个参数是调用者提供的用户名和口令,第四个参数是一个保留的 provider 标识,用来确定绑定的认证方法,第五个参数是请求接口的接口标识符,最后一个参数用来返回请求的接口指针。

第一个函数使用登录用户缺省的信任级别,而第二个函数允许开发者指定特殊的安全信任机制来绑定 ADSI 对象。下面代码演示了两种不同的绑定方式:

  1. procedure TMainFrm.actOpenWinNTExecute(Sender: TObject);   
  2.  
  3. var   
  4.  
  5. UnknownObject: IUnknown;   
  6.  
  7. DomainPath: WideString;   
  8.  
  9. Domain: IADsContainer;   
  10.  
  11. begin   
  12.  

// 指定域路径

  1. DomainPath :'WinNT://' + ADSIDomainName.Text;   
  2.  

// 如果使用用户登录了信息

  1. if cbUseLogin.Checked then   
  2.  

// 使用用户登录的信息创建域对象

  1. OleCheck(AdsOpenObject(PWideChar(DomainPath),   
  2.  
  3. PWideChar(ADSIUsername.Text),   
  4.  
  5. PWideChar(ADSIPassword.Text), 0, IID_IADsContainer,   
  6.  
  7. UnknownObject));   
  8.  
  9. else   
  10.  
  11. OleCheck(ADsGetObject(PWideChar(DomainPath),   
  12.  
  13. IID_IADsContainer, UnknownObject));   
  14.  
  15. // 设定域对象   
  16.  
  17. Domain :UnknownObject as IADsContainer;   
  18.  
  19. // 从域中获得信息列表   
  20.  
  21. GetDomainInformation(Domain);   
  22.  
  23. end;   
  24.  

下面我们需要声明三个变量 :

第一个是接口变量 , 用来绑定由指定的对象路径返回的函数。

UnknownObject: IUnknown;

第二个参数是 WideString 类型的变量 , 用来在绑定函数中产生一个对象路径。

DomainPath: WideString;

第三是一个 IADsContainer 接口类型变量 , 用来保存返回的接口变量。

Domain: IADsContainer;

IADsContainer 变量将被用来从指定的 ADSI 对象中获得全部用户、组和计算机。当然也可以使用 IADsDomain 类型的变量,但它不适合枚举域中的子对象。

下面指定想要获得的对象路径 , 如果域名是 "PRISMA" , 要想获得 ADSI 对象 , 就需要指定路径为 "WinNT://PRISMA" :

// 设定域名路径

DomainPath := 'WinNT://' + ADSIDomainName.Text;

下面代码使用不同的安全认证方式:

// 如果使用登录信息

if cbUseLogin.Checked then

// 使用登录并创建域对象

  1. OleCheck(AdsOpenObject(PWideChar(DomainPath),   
  2.  
  3. PWideChar(ADSIUsername.Text),   
  4.  
  5. PWideChar(ADSIPassword.Text), 0, IID_IADsContainer,   
  6.  
  7. UnknownObject));   
  8.  
  9. else   
  10.  
  11. // 创建域对象   
  12.  
  13. OleCheck(ADsGetObject(PWideChar(DomainPath),   
  14.  
  15. IID_IADsContainer, UnknownObject));   
  16.  
  17. 然后我们获取 IADsContainer 指针,以便查询域中的子对象:   
  18.  
  19. // 获取域对象   
  20.  
  21. Domain :UnknownObject as IADsContainer;   
  22.  
  23. 最后 , 把 IADsContainer 接口指针作为参数调用来获得域中的子对象 :   
  24.  
  25. GetDomainInformation(Domain);   
  26.  

在域中查找

要想在域中查找子对象 , 可以使用 GetDomainInformation 过程 , 代码如下 :

// 获取域信息

  1. procedure TMainFrm.GetDomainInformation(   
  2.  
  3. Domain: IADsContainer);   
  4.  
  5. var   
  6.  
  7. Enum: IEnumVariant;   
  8.  
  9. ADsTempObj: OLEVariant;   
  10.  
  11. ADsObj: IADs;   
  12.  
  13. Value: LongWord;   
  14.  
  15. begin   
  16.  
  17. // 清空用户、组和计算机列表   
  18.  
  19. UserListView.Items.Clear;   
  20.  
  21. GroupListView.Items.Clear;   
  22.  
  23. ComputerListView.Items.Clear;   
  24.  
  25. // 获取枚举对象   
  26.  
  27. Enum := (Domain._NewEnum) as IEnumVariant;   
  28.  
  29. // 利用枚举对象查找   
  30.  
  31. while (Enum.Next(1, ADsTempObj, Value) = S_OK) do begin   
  32.  
  33. // 获得临时对象   
  34.  
  35. ADsObj :IUnknown(ADsTempObj) as IADs;   
  36.  
  37. // 如果是用户对象   
  38.  
  39. if AdsObj.Class_ = 'User' then   
  40.  
  41. AddUserToList(ADsObj);   
  42.  
  43. // 如果是组对象   
  44.  
  45. if AdsObj.Class_ = 'Group' then   
  46.  
  47. AddGroupToList(ADsObj);   
  48.  
  49. // 如果是计算机对象   
  50.  
  51. if AdsObj.Class_ = 'Computer' then   
  52.  
  53. AddComputerToList(ADsObj);   
  54.  
  55. end;   
  56.  
  57. end;   
  58.  

下面是对程序流程的详细说明,首先获得枚举对象,并赋值给 Enum 变量:

Enum := (Domain._NewEnum) as IEnumVariant;

然后利用枚举变量进行查找并把每个子对象赋值给临时的 OLEVariant 对象:

while (Enum.Next(1, ADsTempObj, Value) = S_OK) do begin

OLEVariant 变量赋值给 ADSI 对象

ADsObj := IUnknown(ADsTempObj) as IADs;

获得 ADSI 对象后,开始检查对象类,根据对象类别把 ADSI 分别处理,并把不同 ADSI 对象的属性添加到各自的列表视图中去:

// 如果是用户对象

if AdsObj.Class_ = 'User' then

AddUserToList(ADsObj);

// 如果是组对象

if AdsObj.Class_ = 'Group' then

AddGroupToList(ADsObj);

// 如果是计算机对象

Delphi深度探索:活动目录开发一

图 1.112 

if AdsObj.Class_ = 'Computer' then AddComputerToList(ADsObj);

运行结果如 图 1.112 所示。

更多内容点击Delphi深度探索:活动目录开发二

【编辑推荐】

  1. 活动目录用户如何管理?
  2. 活动目录中的对象如何操作?
  3. 活动目录灾难管理员应该如何应对
  4. 让活动目录在复制过程中更好地运行
  5. 用ADSI实现自动化的活动目录操作方法
责任编辑:韩亚珊 来源: 中科软件园
相关推荐

2011-07-19 16:34:21

活动目录ADSI

2010-11-01 05:54:41

2011-08-08 09:17:32

活动目录ActiveDirec

2011-08-18 09:46:40

活动目录验证原理

2010-04-15 11:39:22

微软活动目录基础

2024-07-20 00:00:00

2017-10-25 11:17:18

数据

2010-04-15 11:47:37

微软活动目录逻辑结构

2011-07-12 16:22:31

活动目录

2011-07-15 13:35:52

Windows 200

2010-08-30 15:57:25

2012-03-20 14:17:33

活动目录

2011-01-05 10:30:42

活动目录Powershell

2010-04-25 23:13:26

活动目录物理结构

2011-06-27 09:42:46

2011-07-15 10:20:34

活动目录

2010-10-22 11:01:42

Windows Pow

2009-07-16 09:48:29

数据库连接

2021-09-01 14:45:08

服务器数据PostgreSQL

2010-09-29 11:10:35

活动目录AD
点赞
收藏

51CTO技术栈公众号