web-dev-qa-db-fra.com

Détectez si un compte d'utilisateur Active Directory est verrouillé à l'aide de LDAP dans Python

Je valide les connexions utilisateur à l'aide du module LDAP de Python. Lorsque la connexion échoue, j'obtiens une connexion ldap.INVALID_CREDENTIALS, mais cela peut être dû à un mot de passe incorrect ou au fait que le compte est verrouillé. Le compte est verrouillé après le 3ème essai.

Je voudrais détecter que le compte est verrouillé et le signaler à l'utilisateur frustré, au lieu du même message "connexion invalide".

À la recherche d'une solution, j'ai trouvé:

  • L'indicateur userAccountControl LOCKED n'est pas utilisé par AD;
  • L'attribut lockoutTime doit être utilisé à la place

La requête LDAP que je devrais utiliser pour trouver des utilisateurs verrouillés est:

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

Ou pour un utilisateur spécifique:

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

Mais cela ne fonctionne pas, la requête ne renvoie aucun résultat à chaque fois.

17
Daniel Reis

Une valeur de zéro dans lockoutTime signifie qu'il n'est pas verrouillé. Donc, vous devriez essayer ça.

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

En fait, la requête ci-dessus n'est toujours pas correcte à 100%. Si vous lisez les petits caractères de MSDN, Microsoft vous suggère d'ajouter le Lockout-Time attribut à Lockout-Duration attribut, puis le comparer avec l'heure actuelle. C'est parce qu'il existe une telle chose appelée durée de verrouillage. Une fois la durée de verrouillage écoulée, l'utilisateur est déverrouillé automatiquement. Zéro en Lockout-Duration signifie que le compte est verrouillé pour toujours jusqu'à ce que l'administrateur le déverrouille.

Voir ceci article MSDN

Cette valeur d'attribut n'est réinitialisée que lorsque le compte est correctement connecté. Cela signifie que cette valeur peut être différente de zéro, mais que le compte n'est pas verrouillé. Pour déterminer avec précision si le compte est verrouillé, vous devez ajouter la durée de verrouillage à cette heure et comparer le résultat à l'heure actuelle, en tenant compte de l'heure locale. fuseaux horaires et heure d'été.

12
Harvey Kwok

lockoutTime est un <not set> attribut donc la façon la plus simple est d'utiliser:

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

pour les entrées non vides.

Mise à jour:

Cependant, cette valeur est également définie lorsque le mot de passe expire, le mot de passe doit changer, etc.

Il doit donc être filtré par:

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

pour obtenir les cas où l'utilisateur est verrouillé parce qu'il a violé la politique de mot de passe, par exemple, entré le mot de passe incorrectement 5 fois.

4
nzpcmad

De plus, j'ai trouvé que lockoutTime n'est pas garanti pour tous les utilisateurs dans AD (au moins dans notre configuration), mais sera créé lorsque le nombre de tentatives de verrouillage aura échoué. Ainsi, lors de la vérification des comptes verrouillés, la vérification de Aucun ou d'un équivalent sera également requise.

3
user917089

J'ai également trouvé cette liste d'indicateurs de propriété: Comment utiliser les indicateurs 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

Vous devez faire un ET binaire de la propriété userAccountControl avec 0x002. Afin d'obtenir tous les comptes verrouillés (c'est-à-dire désactivés), vous pouvez utiliser

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

Pour l'opérateur 1.2.840.113556.1.4.803 voir Règles de correspondance LDAP

2

utilisez cette requête pour obtenir les meilleurs résultats,

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

1
Rizwan Ranjha

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

Renvoie des objets qui sont des utilisateurs et ont un attribut actuel nommé lockoutTime qui n'est pas égal à 0.

0
Jonas