Delphi访问基于LDAP的Active Directory

本文只介绍如何读取,写入域控信息,不对域控等相关概念作介绍。读写主要是对账户属性信息的介绍,其他属性类似,可以通过AD属性对照表去读写其他属性。

一、创建单元ActiveDs_TLB.pas

XE中的创建步骤:Component->Import Component->Import a Type Library->Active DS Type Libeaey下一步创建单元就可以了。

D7中的创建步骤:Component->Import ActiveX Control->Active DS Type Libeaey创建单元就可以了。

二、添加DLL接口

需要用到两个方法,一个是ADsOpenObject用来连接域控;一个是ADsGetObject用来获取域控对象。声明如下:

function ADsOpenObject(lpszPathName: PWideChar;  //第一个参数是对象的路径名
                       lpszUserName: PWideChar;    //第二个参数是调用者提供的用户名
                       lpszPassword: PWideChar;    //第三个参数是调用者提供的口令
                       dwReserved: LongInt;        //第四个参数是一个保留的 provider 标识,用来确定绑定的认证方法
                       const riid: TIID;           //第五个参数是请求接口的接口标识符,
                       out obj): HResult; stdcall; external 'activeds.dll'; //最后一个参数用来返回请求的接口指针。
 
  function ADsGetObject(lpszPathName: PWideChar;   //第一个参数是对象的路径名
                      const riid: TIID;          //第二个参数是对象的接口标识符
                      out obj): HResult; stdcall; external 'activeds.dll';// 第三个参数用于返回得到的被请求的接口指针

三、读取信息

1、读取组织单元,用户等信息。通过IADs接口返回信息。

// 使用用户登录的信息创建域对象
  OleCheck(AdsOpenObject(PWideChar(aDomainPath),
                          PWideChar(aUser),
                          PWideChar(aPass),
                          0,
                          IID_IADsContainer,
                          UnknownObject));
  // 设定域对象
  Domain := UnknownObject as IADsContainer;
 
  //获取枚举对象,并赋值给 Enum 变量
  Enum := (Domain._NewEnum) as IEnumVariant;
 
  //利用枚举对象查找,把每个子对象赋值给临时的 OLEVariant 对象
  while (Enum.Next(1, ADsTempObj, Value) = S_OK) do
  begin
    ADsObj := IUnknown(ADsTempObj) as IADs;  //获得临时对象:OLEVariant 变量赋值给 ADSI 对象

    RichEdit3.Lines.Add(AdsObj.Name+'('+AdsObj.Class_+')'); //对象类型

    if AdsObj.Class_ = 'organizationalUnit' then //如果是组织单元对象
    begin
      OUItem.Lines.Add(ADsObj.Name) ;
      AddDepToTreeView(ADsObj);
    end;
 
    if AdsObj.Class_ = 'user' then //如果是用户对象  displayName    sAMAccountName  objectSID
    begin
      UserItem.Lines.Add(ADsObj.Name+'(sAMAccountName='+ADsObj.Get('sAMAccountName')+') ' );
      UserItem.Lines.Add(ADsObj.Name+'(userPrincipalName='+ADsObj.Get('userPrincipalName')+')' );
      UserItem.Lines.Add(ADsObj.Name+'(userAccountControl='+intToStr( ADsObj.Get('userAccountControl') )+')' );

      UserItem.Lines.Add(ADsObj.Name+'(logonHours='+ByteToString(ADsObj.Get('logonHours') )+')' );
      UserItem.Lines.Add(ADsObj.Name+'(accountExpires='+datetimeToStr(VariantToDatetime(ADsObj.Get('accountExpires')))+')' );

      //showmessage(ADsObj.Get('ObjectSID'));
    end;
    //递归。得到组内相关用户。
    GetADInfo(aUser,aPass,ADsObj.ADsPath);

    ADsTempObj:=Null; //释放OLEVariant
  end;

通过IADs接口返回信息时在账户属性中需要注意的两个属性。

logonHours属性返回的是array byte ,接收返回值是要传相应的类型。

accountExpires属性返回的是Filetime的时间类型,可以通过转换成Localtime在转成datetime。

function VariantToDatetime(V: Variant): Tdatetime;
var
  LargeInteger: IADsLargeInteger;
  ft: TFileTime;
  LocalFileTime: TFileTime;
  SystemTime: TSystemTime;
  DateTime: TDateTime;
begin
  LargeInteger := IDispatch(v) as IADsLargeInteger;
  ft.dwLowDateTime := LargeInteger.LowPart;
  ft.dwHighDateTime := LargeInteger.HighPart;
  if Int64(ft) = 0 then
    Result := 0
  else
  begin
    //Memo1.Lines.Add('AccountExpiration:'+intToStr(Int64(ft)));
    FileTimeToLocalFileTime(ft, LocalFileTime);
    if FileTimeToSystemTime(LocalFileTime, SystemTime) then
      DateTime := SystemTimeToDateTime(SystemTime);
    Result := DateTime;
  end;
end;

2、读取信息通过IADsUser接口。

这种方式可以通过点属性的方式读取相应属性值。

User.AccountExpirationDate;

四、设置属性值。

主要介绍对账户的属性设置举例。

var
  UnknownObject: IUnknown;
  DomainPath,ADUser,ADPass: WideString;
  path:string;

  Container : IADsContainer;
  User : IADsUser;
  adate:Double;
begin
  OUItem.Clear;
  UserItem.Clear;
  TreeView1.Items.Clear;
  RichEdit3.Clear;
  DomainPath:='LDAP://';
  reorderstr(AreaName.Text,path);
  DomainPath:=DomainPath+serverName.Text+'/OU='+StringReplace(path,'/',',OU=',[rfReplaceAll])
    +',DC='+StringReplace(Edit1.Text,'.',',DC=',[rfReplaceAll]);
  if userName.Text<>'' then
    ADUser:=userName.Text+'@'+Edit1.Text;
  if passWord.Text<>'' then
    ADPass:=passWord.Text;

  OleCheck(AdsOpenObject(PWideChar(DomainPath),
                          PWideChar(ADUser),
                          PWideChar(ADPass),
                          0,
                          IID_IADsContainer,
                          UnknownObject));
  ADsGetObject(PWideChar(DomainPath),IADsContainer,Container);
  User:=Container.GetObject('user','CN='+Edit2.Text) as IADsUser;
  User.GetInfo;
  User.AccountDisabled:=false;
  User.Description:='wnjnfn';
  User.LoginHours:=StrToByte('//0/0');
  Memo1.Lines.Add('======'+datetimetostr(User.AccountExpirationDate));
  adate:=0;
  User.AccountExpirationDate:=strTodatetime('1601/1/1 8:00:00'); //设置永不过期 
  //如果设置其他过期时间就正常时间就可以了。这个 AccountExpirationDate是datetime类型。 
  User.SetInfo;
  Memo1.Lines.Add('编辑用户【'+Edit2.Text+'】成功');
end;

五、删除用户,组织单元,组等节点操作。

这里只以删除用户举例,其他类似,只是类型改下就可以。

var
  UnknownObject: IUnknown;
  DomainPath,ADUser,ADPass: WideString;
  path:string;

  Container : IADsContainer;
begin
  OUItem.Clear;
  UserItem.Clear;
  TreeView1.Items.Clear;
  RichEdit3.Clear;
  DomainPath:='LDAP://';
  reorderstr(AreaName.Text,path);
  DomainPath:=DomainPath+serverName.Text+'/OU='+StringReplace(path,'/',',OU=',[rfReplaceAll])
    +',DC='+StringReplace(Edit1.Text,'.',',DC=',[rfReplaceAll]);
  if userName.Text<>'' then
    ADUser:=userName.Text+'@'+Edit1.Text;
  if passWord.Text<>'' then
    ADPass:=passWord.Text;

  OleCheck(AdsOpenObject(PWideChar(DomainPath),
                          PWideChar(ADUser),
                          PWideChar(ADPass),
                          0,
                          IID_IADsContainer,
                          UnknownObject));
  ADsGetObject(PWideChar(DomainPath),IADsContainer,Container);
  //如果删除别的,只需要把user改成别的类型就可以
  Container.Delete('user','CN='+Edit2.Text);
  Memo1.Lines.Add('删除用户【'+Edit2.Text+'】成功');

end;

 

 

 

 

 

 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值