19

我正在使用 python 的 ldap 模块验证用户登录。当登录失败时,我得到一个 ldap.INVALID_CREDENTIALS 登录,但这可能是因为密码错误或帐户被锁定。帐户在第三次尝试后被锁定。

我想检测到该帐户已被锁定并将其报告给沮丧的用户,而不是相同的“无效登录”消息。

寻找我发现的解决方案:

  • AD 不使用 userAccountControl LOCKED 标志;
  • 应该使用 lockoutTime 属性

我应该用来查找锁定用户的 LDAP 查询是:

(&(objectClass=user)(lockoutTime>=1))

或者对于特定用户:

(&(objectClass=user)(sAMAccountName=jabberwocky)(lockoutTime>=1))

但这不起作用,查询每次都没有返回结果。

4

7 回答 7

13

in 值为零lockoutTime表示它没有被锁定。所以,你应该试试这个。

(&(objectClass=user)(!lockoutTime=0)) 

实际上,上面的查询仍然不是 100% 正确的。如果您阅读 MSDN 的细则,Microsoft 建议您将Lockout-Time属性添加到Lockout-Duration属性中,然后将其与当前时间进行比较。那是因为有一种叫做锁定持续时间的东西。一旦锁定持续时间过去,用户将自动解锁。归零Lockout-Duration意味着该帐户被永久锁定,直到管理员将其解锁。

请参阅此MSDN 文章

此属性值仅在帐户成功登录时才会重置。这意味着该值可能不为零,但该帐户并未被锁定。要准确确定帐户是否被锁定,您必须将 Lockout-Duration 添加到该时间并将结果与​​当前时间进行比较,同时考虑本地时区和夏令时。

于 2012-08-07T05:28:18.823 回答
4

lockoutTime是一个<not set>属性,所以最简单的方法是使用:

(&(objectClass=user)(lockoutDuration=*))) 

对于非空条目。

更新:

但是,当密码过期、密码需要更改等时也会设置此值。

所以需要过滤:

UserPrincipal userPrincipal = new UserPrincipal(context);
bool isLocked = userPrincipal.IsAccountLockedOut();

获取用户因违反密码策略而被锁定的情况,例如错误输入密码 5 次。

于 2013-06-04T21:07:10.747 回答
3

此外,我发现不能保证 AD 中所有用户的 lockoutTime(至少在我们的配置中),但会在达到锁定尝试失败的次数时创建。因此,在检查锁定帐户时,还需要检查 None 或等效项。

于 2012-08-24T20:01:21.153 回答
3

我还发现了这个属性标志列表:如何使用 UserAccountControl 标志

SCRIPT  0x0001  1
ACCOUNTDISABLE  0x0002  2
HOMEDIR_REQUIRED    0x0008  8
LOCKOUT 0x0010  16
PASSWD_NOTREQD  0x0020  32
PASSWD_CANT_CHANGE 0x0040   64
ENCRYPTED_TEXT_PWD_ALLOWED  0x0080  128
TEMP_DUPLICATE_ACCOUNT  0x0100  256
NORMAL_ACCOUNT  0x0200  512
INTERDOMAIN_TRUST_ACCOUNT   0x0800  2048
WORKSTATION_TRUST_ACCOUNT   0x1000  4096
SERVER_TRUST_ACCOUNT    0x2000  8192
DONT_EXPIRE_PASSWORD    0x10000 65536
MNS_LOGON_ACCOUNT   0x20000 131072
SMARTCARD_REQUIRED  0x40000 262144
TRUSTED_FOR_DELEGATION  0x80000 524288
NOT_DELEGATED   0x100000    1048576
USE_DES_KEY_ONLY    0x200000    2097152
DONT_REQ_PREAUTH    0x400000    4194304
PASSWORD_EXPIRED    0x800000    8388608
TRUSTED_TO_AUTH_FOR_DELEGATION  0x1000000   16777216
PARTIAL_SECRETS_ACCOUNT 0x04000000      67108864

您必须对属性进行二进制userAccountControl0x002. 为了获得所有锁定(即禁用)的帐户,您可以使用

(&(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=2))

对于操作员,1.2.840.113556.1.4.803请参阅LDAP 匹配规则

于 2016-03-16T12:39:26.560 回答
1

使用此查询以获得最佳结果,

Get-ADUser -LDAPFilter "(&(objectCategory=Person)(objectClass=User)(lockoutTime>=1))" -Properties LockedOut

于 2014-12-03T11:23:18.930 回答
1

像这样做:

def islocked(self, user, basedn, conn):

    search_filter = "(&(objectCategory=Person)(objectClass=User)(lockoutTime>=1))"
    search_attribute = ["sAMAccountName"]

    try:
        conn.search(basedn,
                        search_filter,
                        attributes=search_attribute)
        results = conn.entries
    except ldap3.core.exceptions.LDAPException as e:
        print(e)
    lockedaccounts = [x['sAMAccountName'] for x in results]
    lockedaccounts = [str(x) for x in lockedaccounts]
    lockedaccounts = [x for x in lockedaccounts]
    if user in lockedaccounts:
        return True
    else:
        return False
于 2020-08-27T02:00:14.660 回答
1

(&(objectClass=user)(&(lockoutTime=*)(!(lockoutTime=0))))

将返回用户对象,并且具有名为 lockoutTime 的当前属性,该属性不等于 0。

于 2016-11-21T08:23:30.740 回答