【问题标题】:Delphi ADO query - how to search for AD users with specific bits in userAccountControlDelphi ADO 查询 - 如何在 userAccountControl 中搜索具有特定位的 AD 用户
【发布时间】:2023-02-14 12:48:29
【问题描述】:

我正在使用 delphi 10.4 并使用 TADOConnection 和 TADOCommand 组件来访问 Active Directory 数据。我需要搜索在 userAccountControl 文件中设置了特定位的用户帐户(即“必须在下次登录时更改密码”或“已禁用”等)。 我有一个工作查询将搜索 userAccountControl 具有特定值的用户帐户,但我需要一个仅返回具有特定位集的用户的查询。例如,“select sAMAccountName,userAccountControl from 'LDAP://DC=AD,DC=LOCAL' where userAccountControl='514'”将返回所有正常禁用的用户,但会遗漏已禁用但在“中设置了其他位”的用户用户账户控制”。我希望能够构建一个查询,该查询只能返回在 userAccountControl 中设置了特定位的用户 ID。
我看到了 Powershell、vbscript 等的示例代码,它们应该实现类似的功能:“(&(objectCategory=computer)(userAccountControl:1.2.840.113556.1.4.803:=8192))”但它在 Delphi 中不起作用。

非常感谢任何指针 谢谢

【问题讨论】:

  • 在 SQL 中,按位与是 &。因此,例如 userAccountControl & 2 = 2 将仅检查禁用标志。 & 部分屏蔽了所有其他位,但有问题的位和 = 确保设置了所需的位。
  • 谢谢 Brian,你是对的,正如你从我的问题中看到的那样,我的 SQL 语句的语法使用 & 并且该语句在 Powershell 中运行良好。但是它在 Delphi 中不起作用——这就是我想要解决的问题。谢谢

标签: sql delphi search bit-manipulation ado


【解决方案1】:

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

    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 标志。

【讨论】:

    猜你喜欢
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-27
    • 1970-01-01
    • 2016-01-29
    • 1970-01-01
    相关资源
    最近更新 更多