363 lines
11 KiB
PHP
363 lines
11 KiB
PHP
<?php
|
|
class LDAPAuth
|
|
{
|
|
private $ldap_server;
|
|
private $service_dn;
|
|
private $service_pwd;
|
|
private $ad;
|
|
|
|
public function __construct()
|
|
{
|
|
$this->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;
|
|
}
|
|
}
|