[TUTO] Modifier les mots de passe Active Directory avec PHP
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
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é.
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.
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.
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
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
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
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
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.
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