ldap_server = 'ldap://intranet.epul3a.local'; $this->service_dn = 'CN=Service LDAP Reader,CN=Users,DC=epul3a,DC=local'; $this->service_pwd = 'Test@123'; } public function connect() { $this->ad = ldap_connect($this->ldap_server) or die("❌ Impossible de se connecter au LDAP"); ldap_set_option($this->ad, LDAP_OPT_PROTOCOL_VERSION, 3); ldap_set_option($this->ad, LDAP_OPT_REFERRALS, 0); } public function getUserDN($sAMAccountName) { $this->connect(); // Connexion avec le compte service if (!@ldap_bind($this->ad, $this->service_dn, $this->service_pwd)) { die("❌ Erreur de connexion avec svc_ldap_read : " . ldap_error($this->ad)); } // 🔥 Utilisation correcte du sAMAccountName (alias de connexion) $search_base = "DC=epul3a,DC=local"; $search_filter = "(sAMAccountName=$sAMAccountName)"; // 🔥 Remplace ici $search_result = ldap_search($this->ad, $search_base, $search_filter); $entries = ldap_get_entries($this->ad, $search_result); if ($entries["count"] > 0) { return $entries[0]["dn"]; // ✅ Retourne le DN correct } return false; // ❌ Utilisateur non trouvé } public function authenticate($sAMAccountName, $user_password) { $user_dn = $this->getUserDN($sAMAccountName); if (!$user_dn) { return ['success' => false, 'message' => 'Utilisateur introuvable']; } if (@ldap_bind($this->ad, $user_dn, $user_password)) { // Vérifier si l'utilisateur est un administrateur $is_admin = $this->isUserAdmin($user_dn); // Récupérer les OUs sur lesquelles l'utilisateur a des droits d'administration $admin_ous = $this->getAdminOUs($user_dn); return [ 'success' => true, 'dn' => $user_dn, 'is_admin' => $is_admin, 'admin_ous' => $admin_ous, ]; } return ['success' => false, 'message' => 'Échec d\'authentification']; } private function isUserAdmin($user_dn) { $admin_groups = [ "CN=Domain Admins,CN=Users,DC=epul3a,DC=local", "CN=Enterprise Admins,CN=Users,DC=epul3a,DC=local", "CN=Schema Admins,CN=Users,DC=epul3a,DC=local", "CN=Group Policy Creator Owners,CN=Users,DC=epul3a,DC=local" ]; foreach ($admin_groups as $group_dn) { $filter = "(memberOf:1.2.840.113556.1.4.1941:=$group_dn)"; $result = ldap_read($this->ad, $user_dn, $filter, ["memberOf"]); if ($result && ldap_count_entries($this->ad, $result) > 0) { return true; } } return false; } public function getUserGroups($user_dn) { $this->connect(); $this->bindServiceAccount(); $filter = "(objectClass=*)"; $attributes = ["memberOf"]; $result = ldap_read($this->ad, $user_dn, $filter, $attributes); $entries = ldap_get_entries($this->ad, $result); return $entries[0]['memberof'] ?? []; } private function getAdminOUs($user_dn) { $this->connect(); $this->bindServiceAccount(); // Mappage explicite des groupes d'administration vers les OUs $admin_groups_with_ous = [ "CN=Domain Admins,CN=Users,DC=epul3a,DC=local" => "OU=3AFISA,DC=epul3a,DC=local", // Domain Admins → OU=3AFISA "CN=Enterprise Admins,CN=Users,DC=epul3a,DC=local" => "CN=Users,DC=epul3a,DC=local", // Ajoutez d'autres groupes si nécessaire ]; $admin_ous = []; foreach ($admin_groups_with_ous as $group_dn => $ou) { $filter = "(memberOf:1.2.840.113556.1.4.1941:=$group_dn)"; // Vérification récursive $result = ldap_read($this->ad, $user_dn, $filter, ["memberOf"]); if ($result && ldap_count_entries($this->ad, $result) > 0) { $admin_ous[] = $ou; } } return array_unique($admin_ous); } private function getOUACL($ou_dn) { $filter = "(objectClass=organizationalUnit)"; $attributes = ["nTSecurityDescriptor"]; $result = @ldap_read($this->ad, $ou_dn, $filter, $attributes); // Ajoutez @ pour supprimer les warnings if (!$result) { return null; // Retourne null si la lecture échoue } $entries = ldap_get_entries($this->ad, $result); if ($entries['count'] > 0 && isset($entries[0]['ntsecuritydescriptor'][0])) { return $entries[0]['ntsecuritydescriptor'][0]; // Retourne les ACL } return null; // Retourne null si aucune ACL n'est trouvée } private function hasAdminRights($acl, $user_dn) { // Si les ACL sont null, retourne false if ($acl === null) { return false; } // Convertir l'ACL en un format exploitable // Note : Cette partie dépend de la manière dont les ACL sont stockées dans votre AD // Vous devrez peut-être utiliser une bibliothèque pour parser l'ACL // Exemple simplifié : Vérifier si l'utilisateur a le droit "WriteProperty" ou "GenericAll" if (strpos($acl, $user_dn) !== false && (strpos($acl, "WriteProperty") !== false || strpos($acl, "GenericAll") !== false)) { return true; } return false; } public function getAllOUs() { $this->connect(); $this->bindServiceAccount(); $searchBase = "DC=epul3a,DC=local"; $filter = "(objectClass=organizationalUnit)"; $attributes = ["ou", "distinguishedName"]; $result = ldap_search($this->ad, $searchBase, $filter, $attributes); $entries = ldap_get_entries($this->ad, $result); $ous = []; if ($entries['count'] > 0) { foreach ($entries as $entry) { if (isset($entry['distinguishedname'][0])) { $ous[] = $entry['distinguishedname'][0]; } } } return $ous; } public function close() { if ($this->ad) { ldap_close($this->ad); } } public function bindServiceAccount() { if (!@ldap_bind($this->ad, $this->service_dn, $this->service_pwd)) { die("❌ Erreur de connexion avec le compte service : " . ldap_error($this->ad)); } } public function listAllOU() { $this->connect(); $this->bindServiceAccount(); $searchBase = "DC=epul3a,DC=local"; $filter = "(objectClass=organizationalUnit)"; $attributes = ["ou", "distinguishedName"]; $result = ldap_search($this->ad, $searchBase, $filter, $attributes); $entries = ldap_get_entries($this->ad, $result); $ous = []; if ($entries['count'] > 0) { foreach ($entries as $key => $entry) { if (is_numeric($key)) { $ous[] = $entry; } } } return $ous; } public function listAllUsers() { $this->connect(); $this->bindServiceAccount(); $searchBase = "DC=epul3a,DC=local"; $filter = "(objectClass=user)"; $attributes = ["cn", "sn", "givenName", "mail", "distinguishedName"]; $result = ldap_search($this->ad, $searchBase, $filter, $attributes); $entries = ldap_get_entries($this->ad, $result); $users = []; if ($entries['count'] > 0) { foreach ($entries as $key => $entry) { if (is_numeric($key)) { preg_match('/OU=([^,]+)/', $entry['distinguishedname'][0], $matches); $ou = isset($matches[1]) ? $matches[1] : 'Users'; $entry['ou'] = $ou; $users[] = $entry; } } } return $users; } public function getUserOU($username) { $this->connect(); $this->bindServiceAccount(); $searchBase = "DC=epul3a,DC=local"; $filter = "(sAMAccountName=$username)"; $attributes = ["distinguishedName"]; $result = ldap_search($this->ad, $searchBase, $filter, $attributes); $entries = ldap_get_entries($this->ad, $result); if ($entries['count'] > 0) { $dn = $entries[0]['distinguishedname'][0]; preg_match('/OU=([^,]+)/', $dn, $matches); return isset($matches[1]) ? $matches[1] : null; } return null; } public function listUsersByOUs(array $admin_ous) { $this->connect(); $this->bindServiceAccount(); $users = []; foreach ($admin_ous as $ou) { $searchBase = $ou; $filter = "(objectClass=user)"; $attributes = ["cn", "sn", "givenName", "mail", "distinguishedName"]; $result = ldap_search($this->ad, $searchBase, $filter, $attributes); $entries = ldap_get_entries($this->ad, $result); if ($entries['count'] > 0) { foreach ($entries as $key => $entry) { if (is_numeric($key)) { $users[] = $entry; } } } } return $users; } public function listUsersByOU($ou_dn) { $this->connect(); $this->bindServiceAccount(); $searchBase = $ou_dn; $filter = "(objectClass=user)"; $attributes = ["cn", "sn", "givenName", "mail", "distinguishedName"]; $result = @ldap_search($this->ad, $searchBase, $filter, $attributes); if (!$result) { return []; } $entries = ldap_get_entries($this->ad, $result); $users = []; if ($entries['count'] > 0) { for ($i = 0; $i < $entries['count']; $i++) { if (!empty($entries[$i]['distinguishedname'][0])) { $users[] = $entries[$i]; } } } return $users; } public function getUserDetails($username) { $this->connect(); $this->bindServiceAccount(); $filter = "(sAMAccountName=$username)"; $attributes = ["*"]; // Récupère tous les attributs $result = ldap_search($this->ad, "DC=epul3a,DC=local", $filter, $attributes); $entries = ldap_get_entries($this->ad, $result); if ($entries['count'] > 0) { return $this->cleanLdapEntries($entries[0]); } return []; } private function cleanLdapEntries($entry) { $clean = []; foreach ($entry as $key => $value) { if (!is_numeric($key) && is_array($value)) { $clean[$key] = $value[0]; } } return $clean; } public function getUserDetailsByDn($dn) { $this->connect(); $this->bindServiceAccount(); $filter = "(objectClass=user)"; $attributes = ["Name", "sn", "givenName","mail", "sAMAccountName"]; $result = ldap_read($this->ad, $dn, $filter, $attributes); $entries = ldap_get_entries($this->ad, $result); return $this->cleanLdapEntries($entries[0]); } public function updateUser($dn, $attributes) { $this->connect(); $this->bindServiceAccount(); return ldap_modify($this->ad, $dn, $attributes); } public function getUserOUFromDN($dn) { // Extraire l'OU ou le conteneur parent $parts = explode(',', $dn); foreach ($parts as $part) { if (strpos($part, 'OU=') === 0) { return $part . ",DC=epul3a,DC=local"; } } // Si l'utilisateur est dans CN=Users, retourner CN=Users if (strpos($dn, 'CN=Users,DC=epul3a,DC=local') !== false) { return "CN=Users,DC=epul3a,DC=local"; } return null; } public function getAdConnection() { return $this->ad; } /** * Supprime un utilisateur en utilisant les identifiants de l'admin connecté */ public function deleteUserWithAdminAuth($user_dn, $admin_username, $admin_password) { $this->connect(); $this->bindWithCredentials($admin_username, $admin_password); if (!@ldap_delete($this->ad, $user_dn)) { return false; } return true; } /** * Met à jour un utilisateur avec les identifiants de l'admin */ public function updateUserWithAdminAuth($user_dn, $attributes, $admin_username, $admin_password) { $this->connect(); $this->bindWithCredentials($admin_username, $admin_password); return ldap_modify($this->ad, $user_dn, $attributes); } /** * Ajoute un nouvel utilisateur avec les droits de l'admin */ public function addUserWithAdminAuth($dn, $entry, $admin_username, $admin_password) { $this->connect(); $this->bindWithCredentials($admin_username, $admin_password); return ldap_add($this->ad, $dn, $entry); } /** * Méthode générique pour lier la connexion avec des identifiants */ private function bindWithCredentials($username, $password) { $admin_dn = $this->getUserDN($username); // Récupérer le DN de l'admin if (!@ldap_bind($this->ad, $admin_dn, $password)) { throw new Exception("Erreur d'authentification : " . ldap_error($this->ad)); } } }