Banner
Banner
Banner

[TUTO] Modifier les mots de passe Active Directory avec PHP

Par - le août 10th, 2010

adssl

Il m’a été demandé de créer un site Internet en PHP pour que les utilisateurs d’un domaine puissent réinitialiser leur mot de passe Active Directory (qui leur sert aussi pour leur adresse mail exchange). Ayant eu du mal à trouver les éléments pour cette réinitialisation, je vous propose un petit tuto qui j’espère pourra vous aider dans un cas similaire.

Commençons par définir la configuration appliquée pour ce tuto :

  • Serveur Windows 2003 Serveur R2 avec le rôle de contrôleur de domaine Active Directory
  • Serveur Debian 5.0 (mais la distribution n’a que peu d’importance) avec PHPMyadmin (PHP/Apache/MySQL). La librairie php5-ldap doit être installée sur le serveur. Si elle n’est pas installée, vous pouvez taper la commande suivante dans un terminal root :

apt-get install php5-ldap

(Remarque : sous Ubuntu, rajoutez sudo devant cette commande. Sinon, vous pouvez aussi utiliser synaptics)

Si la librairie php5-ldap permet, par défaut, de modifier les informations de base (nom, prénom, description), pour une modification de mot de passe il faut que la connexion ldap soit faite en SSL (LDAPS) sans quoi le serveur AD la refusera. Procédons donc à cette connexion SSL.

 

Préparation du serveur Active Directory

LogoAD

Pour préparer le serveur AD à recevoir une connexion ldap over ssl, on a besoin d’y installer un  certificat mis en forme à partir d’une autorité de certification Microsoft. Pour créer le certificat, sur le serveur créez un fichier Request.inf (dans mon cas, sur le bureau). Remplissez le serveur avec ce code :

;—————– request.inf —————–

[Version]

Signature="$Windows NT$

[NewRequest]

Subject = "CN=NOMDUSERVEUR.DOMAINE.FR" ; replacez avec le FQDN de votre DC
KeySpec = 1
KeyLength = 1024
; Can be 1024, 2048, 4096, 8192, or 16384.
; Larger key sizes are more secure, but have
; a greater impact on performance.
Exportable = TRUE
MachineKeySet = TRUE
SMIME = False
PrivateKeyArchive = FALSE
UserProtected = FALSE
UseExistingKeySet = FALSE
ProviderName = "Microsoft RSA SChannel Cryptographic Provider"
ProviderType = 12
RequestType = PKCS10
KeyUsage = 0xa0

[EnhancedKeyUsageExtension]

OID=1.3.6.1.5.5.7.3.1 ; this is for Server Authentication

[RequestAttributes]
CertificateTemplate = User;

;———————————————–

Puis dans une fenêtre DOS, tapez la commande :

certrep –new request.inf request.req

Cela va vous créer un fichier request.req. Maintenant, soumettez la demande de certificat en tapant la commande :

certreq –submit request.req request.crt

Validez la fenêtre qui va s’ouvrir. La fenêtre DOS devrait ensuite indiquer que le certificat a été délivré.

certif_req

Cela va créer un fichier request.crt que l’on va ouvrir dans un bloc-note. Maintenant, créez un fichier nommé Certnew.cer. Copier le contenu du fichier request.crt dans certnew.cer grâce au bloc-note.

Maintenant, on va accepter le certificat avec la commande :

certreq –accept certnew.cer

Le certificat devrait s’être installé dans le magasin personnel de l’ordinateur. Pour s’en assurer, on lance une console mmc (Démarrer>Exécuter>MMC). Dans celle-ci, ajoutez le composant Certificats.  Développez Certificats (Ordinateur local)>Personnel>Certificats. Vous devez alors retrouver votre certificat.

certif_req1

Pour s’assurer que l’authentification LDAP over SSL (ou LDAPS) est bien opérationnelle, on va la tester avec l’outil d’administration Active Directory (Démarrer>Exécuter>Ldp.exe). Dans le menu Connection, cliquez sur Connect. Indiquez le nom du contrôleur de domaine et le port 636. Cliquez sur OK et contrôler la connexion.

ldaps

Votre connexion sur l’active directory en SSL est maintenant possible. Effectuons à présent la connexion depuis notre serveur PHP.

 

Préparation du serveur PHP

php-logo

Copiez le certificat certnew.cert sur le serveur PHP, dans le dossier /etc/ssl/certs. Puis, modifier le fichier /etc/ldap/ldap.conf (avec la commande, lancée en tant qu’administrateur, vi /etc/ldap/ldap.conf  ou encore gedit /etc/ldap/ldap.conf) de sorte qu’il contienne les lignes :

#Pour ne pas vérifier les certificats

TLS_REQCERT never

#Pour connaitre le chemin du certificats LDAPS

TLS_CACERT /etc/ssl/certs/certnew.cer

Puis on redémarre le serveur apache avec la commande (lancée en tant qu’administrateur) :

/etc/init.d/apache2 restart

Il ne reste plus qu’à créer nos fichiers PHP.

 

Connexion LDAPS en PHP

adssl Une fois le serveur Active Directory préparé, il ne reste plus qu’à se connecter en SSL via son script PHP. Pour ce faire, exécutez dans un fichier php (reset.php) ce code :

#Paramètres AD – remplacez les valeurs par celles correspondantes à votre domaine

$hostAD = "ldaps://serveur.domaine.local";
$dn = "OU=toto, DC=domaine, dc=local";
$compteAD = moncomptead@mondomaine.local;
$mdpAD = "monmotdepasse";

$adConn = ldap_connect($hostAD, 636) or die("Echec : la connection AD a echouée!");
ldap_set_option($adConn, LDAP_OPT_PROTOCOL_VERSION, 3);
$bind = @ldap_bind($adConn, $compteAD, $mdpAD) or die ("Echec : erreur de binding");

A partir de là, vous êtes connecté à votre serveur AD en SSL. Si la connexion échoue, un message d’erreur vous le signifiera. Créons donc le mot de passe pour la réinitialisation.

 

Création du mot de passe

cadenas

L’objectif étant la réinitialisation automatique du mot de passe, on va le générer lui aussi en PHP. Pour cela, créez un fichier mdp.php (dans le même dossier que celui du site de réinitialisation de mot de passe). Remplissez le avec ce code :

<?php
$chaine = "abcdefghijklmnpqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ0123456789@*$!";
$nb_caract = 8;
$mdpaleatoire = "";
for($u = 1; $u <= $nb_caract; $u++) {
    $nb = strlen($chaine);
    $nb = mt_rand(0,($nb-1));
    $mdpaleatoire.=$chaine[$nb];
}
?>

Vous obtenez via ce code un mot de passe fort, aléatoire, de 8 caractères. Dans le fichier reset.php, vous n’avez plus qu’à appeler le script mdp.php avec la commande :

include(‘mdp.php’);

Maintenant, réinitialisons le mot de passe.

 

Réinitialisation du mot de passe

password

Puisque le mot de passe servira dans mon exemple à la réinitialisation du mot de passe de mail exchange, on va créer une recherche de compte AD par adresse mail. Pour cela, rajoutez dans le fichier reset.php :

$filter = "(mail=emailereset)"; # remplacez emailareset par l’adresse de la personne
if (!($search=@ldap_search($adConn, $dn, $filter)))  die("Echec : Recherche impossible");

$info = ldap_get_entries($adConn, $search);
if ($info) {
$entry = ldap_first_entry($adConn, $search);
$dnareset = ldap_get_dn($adConn, $entry);}

Vous avez maintenant une variable dnareset sur laquelle appliquer le changement de mot de passe. Pour cela nous allons utiliser la fonction php ldap_mod_replace. Toutefois, il faut respecter ici 2 conditions :

– le mot de passe doit être entre guillemets

– le mot de passe doit être encodé en UTF-16LE

Modifiez donc le mot de passe via ce code :

$mdpreset=""".$mdpaleatoire.""";
$userdata["unicodepwd"] = mb_convert_encoding($mdpreset, "UTF-16LE");

if(!(ldap_mod_replace ($adConn, $dnareset, $userdata))) die("Echec : Impossible de changer le mot de passe")

Voila, vous avez maintenant un serveur PHP capable de modifier les comptes Microsoft Active Directory de votre domaine. Voici, à mon goût, un bel exemple d’interopérabilité. Cela est très pratique quand, comme dans mon cas, vous avez un frontal WEB PHP et le besoin de modifier vos mots de passe Active Directory via une interface web.binaire

Vous pouvez dans ce contexte également consulter ces divers sites qui m’ont aidé à la réalisation de cette manip et donc de ce tuto :

http://www.zeflip.com/?/PHP/Integration-Active-Directory

http://connaissances.fournier38.fr/display.php?id=113

https://sites.google.com/a/bousquie.fr/jerome/Home/php—modifier-le-mot-de-passe-windows-dans-active-directory

http://support.microsoft.com/kb/321051

http://php.net/manual/fr/function.ldap-mod-replace.php

Tags: , , , , , , ,

10 commentaires to “[TUTO] Modifier les mots de passe Active Directory avec PHP”

    TimCruz :

    Pour information, j’ai migré ma solution sur un frontal Ubuntu serveur. Ca marche nikel!

    Clément OUDOT :

    Bonjour,

    très bon tutoriel ! J’ai été confronté aux mêmes besoins, et j’ai développé un petit outil de changement de mot de passe qui peut peut-être servir à d’autres :
    http://ltb-project.org/wiki/documentation/self-service-password

    Clément

    TimCruz :

    Pas mal fait ton projet! Je vais me pencher dessus. Par contre, je déplore qu’il faille indiquer son ancien mot de passe. Dans mon cas, l’objectif est justement de réinitialiser son mot de passe si on l’a perdu.

    Clément OUDOT :

    Salut,

    pour réinitialiser ton mot de passe sans ton ancien mot de passe, tu peux utiliser un jeton envoyé par mail, ou une question/réponse. L’ancien mot de passe n’est demandé que pour un changement de mot de passe normal.

    lawl :

    « je déplore qu’il faille indiquer son ancien mot de passe. Dans mon cas, l’objectif est justement de ce passe si on l’a perdu. »

    Donc vous laissez la possibilité à n’importe qui de réinitialiser le mot de passe de n’importe qui !?!!
    C’est pas trés sécure !

    TimCruz :

    Vu sous cet angle,ce n’est pas sécurisé. Mais ce tuto donne la methode pas l’enrobage. Dans mon cas, la personne reset son mot de passe mail pro, le mdp reset ne lui est pas indiqué directement mais lui est envoyé sur sa bal perso (ayant une bdd de gestion du personnel contenant les bal perso). En gros, tu peux reset le mdp de ton voisin mais lui seul peut le connaitre! Après, on peut aussi imaginer un systeme de captcha et de question secrète.

    Samyb2313 :

    Et pour la création d’utilisateur en PHP, vous croyez que c’est possible ?

    firescalp :

    Bonjour,

    Merci pour ce tuto!

    Je rencontre des problèmes sur la partie création de certificat.

    Mon serveur AD est un 2008r2 en mode core.

    Premièrement, un paramètre ne passe pas dans le fichier request.inf:

    [RequestAttributes]
    CertificateTemplate = User;

    « Modèle introuvable »

    En enlevant ce paramètre, le fichier request.req est bien créé.

    Ensuite, certreq –submit request.req request.crt me renvoi cette erreur:

    « Le fichier spécifié est introuvable. 0x80070002 (WIN32: 2) »

    Je ne comprend pas, les fichiers sont bien présents et j’effectue les manipulations en admin du domaine.

    Une idée?

    jo :

    En réponse à firescalp
    j’ai eu le même problème, c’est tout bête il faut en commande msdos se trouver là ou est le fichier, dans notre exemple le bureau.

    Firescalp :

    Merci pour ta réponse, mais je suis passé sur OpenLDAP! plus de problèmes de ce genre et … beaucoup moins gourmand en ressources! lol

Laissez un commentaire

Catégorie(s): Software, Tutos