Delphi ADO查询-如何在userAccountControl中使用特定位搜索AD用户

zed5wv10  于 2023-02-15  发布在  其他
关注(0)|答案(2)|浏览(123)

我正在使用 Delphi 10.4并使用TADOConnection和TADOCommand组件访问Active Directory数据。我需要搜索在userAccountControl字段中设置了特定位的用户帐户(即“下次登录时必须更改密码”或“禁用”等)。我有一个工作查询,将搜索userAccountControl具有特定值的用户帐户,但我需要一个仅返回设置了特定位的用户的查询。例如,“select sAMAccountName,userAccountControl from 'LDAP://DC=AD,DC=LOCAL' where userAccountControl ='514'“将返回所有正常禁用的用户,但将错过禁用但在“userAccountControl”中设置了其他位的用户。我希望能够构造一个仅返回在userAccountControl中设置了特定位的用户ID的查询。
我看过Powershell、vbscript等的示例代码,它们应该实现类似的功能:“(&(对象类别=计算机)(用户帐户控件:1. 2. 840. 113556. 1. 4. 803:=8192))"”但它在 Delphi 中不起作用。
有任何建议都非常感谢谢谢

1yjd4xko

1yjd4xko1#

我使用了TADOQuery而不是TADOCommand,添加了一个长度为200的计算TStringField(CalcUserAccountControl),并声明了以下类型和常量:

type
  TControlFlags = (  SCRIPT, ACCOUNTDISABLE, HOMEDIR_REQUIRED, LOCKOUT, PASSWD_NOTREQD,
                     PASSWD_CANT_CHANGE, ENCRYPTED_TEXT_PWD_ALLOWED, TEMP_DUPLICATE_ACCOUNT,
                     NORMAL_ACCOUNT, INTERDOMAIN_TRUST_ACCOUNT, WORKSTATION_TRUST_ACCOUNT,
                     SERVER_TRUST_ACCOUNT, DONT_EXPIRE_PASSWORD, MNS_LOGON_ACCOUNT,
                     SMARTCARD_REQUIRED, TRUSTED_FOR_DELEGATION, NOT_DELEGATED,
                     USE_DES_KEY_ONLY, DONT_REQ_PREAUTH, PASSWORD_EXPIRED,
                     TRUSTED_TO_AUTH_FOR_DELEGATION, PARTIAL_SECRETS_ACCOUNT);
...
const
  //Bit position of every flag
  BitControlFlag : Array [TControlFlags] of Integer =
  (0, 1, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 16, 17, 18, 19, 20, 21, 22, 23, 24, 26);
  //Description of every flag
  StrControlFlag : Array [TControlFlags] of string =
  ('|SCRIPT', '|ACCOUNTDISABLE', '|HOMEDIR_REQUIRED', '|LOCKOUT', '|PASSWD_NOTREQD',
   '|PASSWD_CANT_CHANGE', '|ENCRYPTED_TEXT_PWD_ALLOWED', '|TEMP_DUPLICATE_ACCOUNT',
   '|NORMAL_ACCOUNT', '|INTERDOMAIN_TRUST_ACCOUNT', '|WORKSTATION_TRUST_ACCOUNT',
   '|SERVER_TRUST_ACCOUNT', '|DONT_EXPIRE_PASSWORD', '|MNS_LOGON_ACCOUNT',
   '|SMARTCARD_REQUIRED', '|TRUSTED_FOR_DELEGATION', '|NOT_DELEGATED',
   '|USE_DES_KEY_ONLY', '|DONT_REQ_PREAUTH', '|PASSWORD_EXPIRED',
   '|TRUSTED_TO_AUTH_FOR_DELEGATION', '|PARTIAL_SECRETS_ACCOUNT');

...

之后,在TADOQuery的OnCalcFields方法中,只需要检查查询中UserAccountControl字段的位即可。

procedure TForm2.TADOQuery1CalcFields(DataSet: TDataSet);
var
  CurrentUAC : Integer;
  StrUAC : String;
  ControlFlags : TControlFlags;
begin
  CurrentUAC := TADOQuery1.FieldByName('userAccountControl').AsInteger;

  for var aControlFlag := low(ControlFlags) to high(ControlFlags) do
    if CurrentUAC and (1 shl BitControlFlag[aControlFlag]) <> 0 then
      strUAC := strUAC + StrControlFlag[aControlFlag];

  TADOQuery1.FieldByName('CalcUserAccountControl').Value := strUAC;
end;

在计算字段中,我得到了一个字符串,其中包含UserAccountControl的每个标志,如下所示:

|PASSWD_NOTREQD|WORKSTATION_TRUST_ACCOUNT
|WORKSTATION_TRUST_ACCOUNT|DONT_EXPIRE_PASSWORD
|ACCOUNTDISABLE|PASSWD_NOTREQD|WORKSTATION_TRUST_ACCOUNT

记住这一点,您可以使用CalculatedField值来筛选结果集,以便仅显示所需的UserAccountControl标志。

vulvrdjw

vulvrdjw2#

使用TADOQuery,您可以设置Filtered:= True并添加OnFilterRecord方法,以便仅获取UserAcountControl字段中具有特定位的记录,如以下代码所示:

procedure TForm2.TADOQuery1FilterRecord(DataSet: TDataSet; var Accept: Boolean);
var
  CurrentUAC : Integer;
const
  ACCOUNTDISABLE = 1; //the bit 1 has the ACCOUNTDISABLE flag 
begin
  CurrentUAC := TADOQuery1.FieldByName('userAccountControl').AsInteger;
  //Accept only those records without the ACCOUNTDISABLE flag
  Accept := CurrentUAC and (1 shl ACCOUNTDISABLE) = 0; 
end;

相关问题